From 8f57ef2de409c240be88a97cce8c13d8522fe454 Mon Sep 17 00:00:00 2001 From: Maya Date: Wed, 14 Jan 2026 17:50:04 +0300 Subject: [PATCH] Migrate core/dev.slimevr.protocol to Kotlin (#1688) Co-authored-by: Butterscotch! --- .../slimevr/protocol/ConnectionContext.java | 49 -- .../dev/slimevr/protocol/ConnectionContext.kt | 10 + .../java/dev/slimevr/protocol/DataFeed.java | 26 - .../java/dev/slimevr/protocol/DataFeed.kt | 7 + .../slimevr/protocol/GenericConnection.java | 14 - .../dev/slimevr/protocol/GenericConnection.kt | 12 + .../dev/slimevr/protocol/ProtocolAPI.java | 69 --- .../java/dev/slimevr/protocol/ProtocolAPI.kt | 48 ++ .../slimevr/protocol/ProtocolAPIServer.java | 9 - .../dev/slimevr/protocol/ProtocolAPIServer.kt | 7 + .../protocol/datafeed/DataFeedBuilder.java | 425 --------------- .../protocol/datafeed/DataFeedBuilder.kt | 503 ++++++++++++++++++ .../datafeed/DataFeedBuilderKotlin.kt | 50 -- .../protocol/datafeed/DataFeedHandler.java | 192 ------- .../protocol/datafeed/DataFeedHandler.kt | 177 ++++++ .../protocol/pubsub/HashedTopicId.java | 45 -- .../slimevr/protocol/pubsub/HashedTopicId.kt | 29 + .../protocol/pubsub/PubSubHandler.java | 185 ------- .../slimevr/protocol/pubsub/PubSubHandler.kt | 170 ++++++ .../dev/slimevr/protocol/rpc/RPCBuilder.java | 28 - .../dev/slimevr/protocol/rpc/RPCHandler.kt | 12 +- .../rpc/autobone/RPCAutoBoneHandler.kt | 10 +- .../protocol/rpc/reset/RPCResetHandler.kt | 8 +- .../rpc/serial/RPCProvisioningHandler.java | 87 --- .../rpc/serial/RPCProvisioningHandler.kt | 68 +++ .../protocol/rpc/serial/RPCSerialHandler.java | 303 ----------- .../protocol/rpc/serial/RPCSerialHandler.kt | 263 +++++++++ .../rpc/settings/RPCSettingsBuilder.java | 423 --------------- .../rpc/settings/RPCSettingsBuilder.kt | 458 ++++++++++++++++ .../rpc/settings/RPCSettingsBuilderKotlin.kt | 43 -- .../rpc/settings/RPCSettingsHandler.kt | 25 +- .../protocol/rpc/setup/RPCTapSetupHandler.kt | 4 +- .../slimevr/websocketapi/WebsocketAPI.java | 3 +- .../platform/linux/UnixSocketRpcBridge.java | 2 +- 34 files changed, 1777 insertions(+), 1987 deletions(-) delete mode 100644 server/core/src/main/java/dev/slimevr/protocol/ConnectionContext.java create mode 100644 server/core/src/main/java/dev/slimevr/protocol/ConnectionContext.kt delete mode 100644 server/core/src/main/java/dev/slimevr/protocol/DataFeed.java create mode 100644 server/core/src/main/java/dev/slimevr/protocol/DataFeed.kt delete mode 100644 server/core/src/main/java/dev/slimevr/protocol/GenericConnection.java create mode 100644 server/core/src/main/java/dev/slimevr/protocol/GenericConnection.kt delete mode 100644 server/core/src/main/java/dev/slimevr/protocol/ProtocolAPI.java create mode 100644 server/core/src/main/java/dev/slimevr/protocol/ProtocolAPI.kt delete mode 100644 server/core/src/main/java/dev/slimevr/protocol/ProtocolAPIServer.java create mode 100644 server/core/src/main/java/dev/slimevr/protocol/ProtocolAPIServer.kt delete mode 100644 server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedBuilder.java create mode 100644 server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedBuilder.kt delete mode 100644 server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedBuilderKotlin.kt delete mode 100644 server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedHandler.java create mode 100644 server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedHandler.kt delete mode 100644 server/core/src/main/java/dev/slimevr/protocol/pubsub/HashedTopicId.java create mode 100644 server/core/src/main/java/dev/slimevr/protocol/pubsub/HashedTopicId.kt delete mode 100644 server/core/src/main/java/dev/slimevr/protocol/pubsub/PubSubHandler.java create mode 100644 server/core/src/main/java/dev/slimevr/protocol/pubsub/PubSubHandler.kt delete mode 100644 server/core/src/main/java/dev/slimevr/protocol/rpc/RPCBuilder.java delete mode 100644 server/core/src/main/java/dev/slimevr/protocol/rpc/serial/RPCProvisioningHandler.java create mode 100644 server/core/src/main/java/dev/slimevr/protocol/rpc/serial/RPCProvisioningHandler.kt delete mode 100644 server/core/src/main/java/dev/slimevr/protocol/rpc/serial/RPCSerialHandler.java create mode 100644 server/core/src/main/java/dev/slimevr/protocol/rpc/serial/RPCSerialHandler.kt delete mode 100644 server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilder.java create mode 100644 server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilder.kt delete mode 100644 server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilderKotlin.kt diff --git a/server/core/src/main/java/dev/slimevr/protocol/ConnectionContext.java b/server/core/src/main/java/dev/slimevr/protocol/ConnectionContext.java deleted file mode 100644 index 265a675e5..000000000 --- a/server/core/src/main/java/dev/slimevr/protocol/ConnectionContext.java +++ /dev/null @@ -1,49 +0,0 @@ -package dev.slimevr.protocol; - -import java.util.ArrayList; -import java.util.List; - - -public class ConnectionContext { - - private final List dataFeedList = new ArrayList<>(); - - private final List subscribedTopics = new ArrayList<>(); - - private boolean useSerial = false; - - private boolean useProvisioning = false; - private boolean useAutoBone = false; - - public List getDataFeedList() { - return dataFeedList; - } - - public List getSubscribedTopics() { - return subscribedTopics; - } - - public boolean useSerial() { - return useSerial; - } - - public void setUseSerial(boolean useSerial) { - this.useSerial = useSerial; - } - - public boolean useAutoBone() { - return useAutoBone; - } - - public void setUseAutoBone(boolean useAutoBone) { - this.useAutoBone = useAutoBone; - } - - public boolean useProvisioning() { - return useProvisioning; - } - - public void setUseProvisioning(boolean useProvisioning) { - this.useProvisioning = useProvisioning; - } -} diff --git a/server/core/src/main/java/dev/slimevr/protocol/ConnectionContext.kt b/server/core/src/main/java/dev/slimevr/protocol/ConnectionContext.kt new file mode 100644 index 000000000..ea72472db --- /dev/null +++ b/server/core/src/main/java/dev/slimevr/protocol/ConnectionContext.kt @@ -0,0 +1,10 @@ +package dev.slimevr.protocol + +class ConnectionContext { + val dataFeedList: MutableList = mutableListOf() + val subscribedTopics: MutableList = mutableListOf() + + var useSerial: Boolean = false + var useProvisioning: Boolean = false + var useAutoBone: Boolean = false +} diff --git a/server/core/src/main/java/dev/slimevr/protocol/DataFeed.java b/server/core/src/main/java/dev/slimevr/protocol/DataFeed.java deleted file mode 100644 index d30b17f84..000000000 --- a/server/core/src/main/java/dev/slimevr/protocol/DataFeed.java +++ /dev/null @@ -1,26 +0,0 @@ -package dev.slimevr.protocol; - -import solarxr_protocol.data_feed.DataFeedConfigT; - - -public class DataFeed { - private DataFeedConfigT config; - private Long timeLastSent; - - public DataFeed(DataFeedConfigT config) { - this.config = config; - this.timeLastSent = System.currentTimeMillis(); - } - - public DataFeedConfigT getConfig() { - return config; - } - - public Long getTimeLastSent() { - return timeLastSent; - } - - public void setTimeLastSent(Long timeLastSent) { - this.timeLastSent = timeLastSent; - } -} diff --git a/server/core/src/main/java/dev/slimevr/protocol/DataFeed.kt b/server/core/src/main/java/dev/slimevr/protocol/DataFeed.kt new file mode 100644 index 000000000..8e72f31ab --- /dev/null +++ b/server/core/src/main/java/dev/slimevr/protocol/DataFeed.kt @@ -0,0 +1,7 @@ +package dev.slimevr.protocol + +import solarxr_protocol.data_feed.DataFeedConfigT + +class DataFeed(val config: DataFeedConfigT) { + var timeLastSent: Long = System.currentTimeMillis() +} diff --git a/server/core/src/main/java/dev/slimevr/protocol/GenericConnection.java b/server/core/src/main/java/dev/slimevr/protocol/GenericConnection.java deleted file mode 100644 index b11e8f463..000000000 --- a/server/core/src/main/java/dev/slimevr/protocol/GenericConnection.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.slimevr.protocol; - -import java.nio.ByteBuffer; -import java.util.UUID; - - -public interface GenericConnection { - - UUID getConnectionId(); - - ConnectionContext getContext(); - - void send(ByteBuffer bytes); -} diff --git a/server/core/src/main/java/dev/slimevr/protocol/GenericConnection.kt b/server/core/src/main/java/dev/slimevr/protocol/GenericConnection.kt new file mode 100644 index 000000000..c857157d9 --- /dev/null +++ b/server/core/src/main/java/dev/slimevr/protocol/GenericConnection.kt @@ -0,0 +1,12 @@ +package dev.slimevr.protocol + +import java.nio.ByteBuffer +import java.util.UUID + +interface GenericConnection { + val connectionId: UUID + + val context: ConnectionContext + + fun send(bytes: ByteBuffer) +} diff --git a/server/core/src/main/java/dev/slimevr/protocol/ProtocolAPI.java b/server/core/src/main/java/dev/slimevr/protocol/ProtocolAPI.java deleted file mode 100644 index 7908ecc3a..000000000 --- a/server/core/src/main/java/dev/slimevr/protocol/ProtocolAPI.java +++ /dev/null @@ -1,69 +0,0 @@ -package dev.slimevr.protocol; - -import dev.slimevr.VRServer; -import dev.slimevr.protocol.datafeed.DataFeedHandler; -import dev.slimevr.protocol.pubsub.PubSubHandler; -import dev.slimevr.protocol.rpc.RPCHandler; -import solarxr_protocol.MessageBundle; -import solarxr_protocol.data_feed.DataFeedMessageHeader; -import solarxr_protocol.pub_sub.PubSubHeader; -import solarxr_protocol.rpc.RpcMessageHeader; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; - - -public class ProtocolAPI { - - public final VRServer server; - public final RPCHandler rpcHandler; - public final DataFeedHandler dataFeedHandler; - public final PubSubHandler pubSubHandler; - - private final List servers = new ArrayList<>(); - - public ProtocolAPI(VRServer server) { - this.server = server; - this.rpcHandler = new RPCHandler(this); - this.dataFeedHandler = new DataFeedHandler(this); - this.pubSubHandler = new PubSubHandler(this); - } - - public void onMessage(GenericConnection conn, ByteBuffer message) { - MessageBundle messageBundle = MessageBundle.getRootAsMessageBundle(message); - - try { - for (int index = 0; index < messageBundle.dataFeedMsgsLength(); index++) { - DataFeedMessageHeader header = messageBundle.dataFeedMsgsVector().get(index); - this.dataFeedHandler.onMessage(conn, header); - } - - for (int index = 0; index < messageBundle.rpcMsgsLength(); index++) { - RpcMessageHeader header = messageBundle.rpcMsgsVector().get(index); - this.rpcHandler.onMessage(conn, header); - } - - for (int index = 0; index < messageBundle.pubSubMsgsLength(); index++) { - PubSubHeader header = messageBundle.pubSubMsgsVector().get(index); - this.pubSubHandler.onMessage(conn, header); - } - } catch (AssertionError e) { - // Catch flatbuffer errors - e.printStackTrace(); - } - } - - public List getAPIServers() { - return servers; - } - - public void registerAPIServer(ProtocolAPIServer server) { - this.servers.add(server); - } - - public void removeAPIServer(ProtocolAPIServer server) { - this.servers.remove(server); - } - -} diff --git a/server/core/src/main/java/dev/slimevr/protocol/ProtocolAPI.kt b/server/core/src/main/java/dev/slimevr/protocol/ProtocolAPI.kt new file mode 100644 index 000000000..2ffd3c83d --- /dev/null +++ b/server/core/src/main/java/dev/slimevr/protocol/ProtocolAPI.kt @@ -0,0 +1,48 @@ +package dev.slimevr.protocol + +import dev.slimevr.VRServer +import dev.slimevr.protocol.datafeed.DataFeedHandler +import dev.slimevr.protocol.pubsub.PubSubHandler +import dev.slimevr.protocol.rpc.RPCHandler +import solarxr_protocol.MessageBundle +import java.nio.ByteBuffer + +class ProtocolAPI(val server: VRServer) { + val rpcHandler: RPCHandler = RPCHandler(this) + val dataFeedHandler: DataFeedHandler = DataFeedHandler(this) + val pubSubHandler: PubSubHandler = PubSubHandler(this) + + val apiServers: MutableList = ArrayList() + + fun onMessage(conn: GenericConnection, message: ByteBuffer) { + val messageBundle = MessageBundle.getRootAsMessageBundle(message) + + try { + for (index in 0.. getAPIConnections(); -} diff --git a/server/core/src/main/java/dev/slimevr/protocol/ProtocolAPIServer.kt b/server/core/src/main/java/dev/slimevr/protocol/ProtocolAPIServer.kt new file mode 100644 index 000000000..1005c9e1b --- /dev/null +++ b/server/core/src/main/java/dev/slimevr/protocol/ProtocolAPIServer.kt @@ -0,0 +1,7 @@ +package dev.slimevr.protocol + +import java.util.stream.Stream + +interface ProtocolAPIServer { + val apiConnections: Stream +} diff --git a/server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedBuilder.java b/server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedBuilder.java deleted file mode 100644 index b0e61f57f..000000000 --- a/server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedBuilder.java +++ /dev/null @@ -1,425 +0,0 @@ -package dev.slimevr.protocol.datafeed; - -import com.google.flatbuffers.FlatBufferBuilder; -import dev.slimevr.tracking.trackers.Device; -import dev.slimevr.tracking.trackers.Tracker; -import dev.slimevr.tracking.trackers.udp.MagnetometerStatus; -import dev.slimevr.tracking.trackers.udp.UDPDevice; -import io.github.axisangles.ktmath.Quaternion; -import io.github.axisangles.ktmath.Vector3; -import solarxr_protocol.data_feed.Bone; -import solarxr_protocol.data_feed.DataFeedUpdate; -import solarxr_protocol.data_feed.device_data.DeviceData; -import solarxr_protocol.data_feed.device_data.DeviceDataMaskT; -import solarxr_protocol.data_feed.tracker.TrackerData; -import solarxr_protocol.data_feed.tracker.TrackerDataMaskT; -import solarxr_protocol.data_feed.tracker.TrackerInfo; -import solarxr_protocol.datatypes.DeviceId; -import solarxr_protocol.datatypes.Ipv4Address; -import solarxr_protocol.datatypes.Temperature; -import solarxr_protocol.datatypes.TrackerId; -import solarxr_protocol.datatypes.hardware_info.HardwareInfo; -import solarxr_protocol.datatypes.hardware_info.HardwareStatus; -import solarxr_protocol.datatypes.math.Quat; -import solarxr_protocol.datatypes.math.Vec3f; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; - - -public class DataFeedBuilder { - - public static int createHardwareInfo(FlatBufferBuilder fbb, Device device) { - int nameOffset = device.getFirmwareVersion() != null - ? fbb.createString(device.getFirmwareVersion()) - : 0; - - int manufacturerOffset = device.getManufacturer() != null - ? fbb.createString(device.getManufacturer()) - : 0; - - int firmwareDateOffset = device.getFirmwareDate() != null - ? fbb.createString(device.getFirmwareDate()) - : 0; - - int hardwareIdentifierOffset = fbb.createString(device.getHardwareIdentifier()); - - HardwareInfo.startHardwareInfo(fbb); - HardwareInfo.addFirmwareVersion(fbb, nameOffset); - HardwareInfo.addManufacturer(fbb, manufacturerOffset); - HardwareInfo.addHardwareIdentifier(fbb, hardwareIdentifierOffset); - - HardwareInfo.addFirmwareDate(fbb, firmwareDateOffset); - - if (device instanceof UDPDevice udpDevice) { - var address = udpDevice.getIpAddress().getAddress(); - HardwareInfo - .addIpAddress( - fbb, - Ipv4Address - .createIpv4Address( - fbb, - ByteBuffer.wrap(address).getInt() - ) - ); - - HardwareInfo.addNetworkProtocolVersion(fbb, udpDevice.protocolVersion); - } - - // BRUH MOMENT - // TODO need support: HardwareInfo.addHardwareRevision(fbb, - // hardwareRevisionOffset); - // TODO need support: HardwareInfo.addDisplayName(fbb, de); - - HardwareInfo.addMcuId(fbb, device.getMcuType().getSolarType()); - HardwareInfo.addOfficialBoardType(fbb, device.getBoardType().getSolarType()); - - return HardwareInfo.endHardwareInfo(fbb); - } - - public static int createTrackerId(FlatBufferBuilder fbb, Tracker tracker) { - TrackerId.startTrackerId(fbb); - - TrackerId.addTrackerNum(fbb, tracker.getTrackerNum()); - if (tracker.getDevice() != null) - TrackerId.addDeviceId(fbb, DeviceId.createDeviceId(fbb, tracker.getDevice().getId())); - - return TrackerId.endTrackerId(fbb); - } - - public static int createVec3(FlatBufferBuilder fbb, Vector3 vec) { - return Vec3f - .createVec3f( - fbb, - vec.getX(), - vec.getY(), - vec.getZ() - ); - } - - public static int createQuat(FlatBufferBuilder fbb, Quaternion quaternion) { - return Quat - .createQuat( - fbb, - quaternion.getX(), - quaternion.getY(), - quaternion.getZ(), - quaternion.getW() - ); - } - - public static int createTrackerInfos( - FlatBufferBuilder fbb, - boolean infoMask, - Tracker tracker - ) { - - if (!infoMask) - return 0; - - int displayNameOffset = fbb.createString(tracker.getDisplayName()); - int customNameOffset = tracker.getCustomName() != null - ? fbb.createString(tracker.getCustomName()) - : 0; - - TrackerInfo.startTrackerInfo(fbb); - if (tracker.getTrackerPosition() != null) - TrackerInfo.addBodyPart(fbb, tracker.getTrackerPosition().getBodyPart()); - TrackerInfo.addEditable(fbb, tracker.getUserEditable()); - TrackerInfo.addIsComputed(fbb, tracker.isComputed()); - TrackerInfo.addDisplayName(fbb, displayNameOffset); - TrackerInfo.addCustomName(fbb, customNameOffset); - if (tracker.getImuType() != null) { - TrackerInfo.addImuType(fbb, tracker.getImuType().getSolarType()); - } - - // TODO need support: TrackerInfo.addPollRate(fbb, tracker.); - - if (tracker.isImu()) { - TrackerInfo.addIsImu(fbb, true); - TrackerInfo - .addAllowDriftCompensation( - fbb, - tracker.getResetsHandler().getAllowDriftCompensation() - ); - } else { - TrackerInfo.addIsImu(fbb, false); - TrackerInfo.addAllowDriftCompensation(fbb, false); - } - - if (tracker.getAllowMounting()) { - Quaternion quaternion = tracker.getResetsHandler().getMountingOrientation(); - Quaternion mountResetFix = tracker.getResetsHandler().getMountRotFix(); - TrackerInfo.addMountingOrientation(fbb, createQuat(fbb, quaternion)); - TrackerInfo.addMountingResetOrientation(fbb, createQuat(fbb, mountResetFix)); - } - - TrackerInfo.addMagnetometer(fbb, tracker.getMagStatus().getSolarType()); - TrackerInfo.addIsHmd(fbb, tracker.isHmd()); - - TrackerInfo.addDataSupport(fbb, tracker.getTrackerDataType().getSolarType()); - - return TrackerInfo.endTrackerInfo(fbb); - } - - public static int createTrackerPosition(FlatBufferBuilder fbb, Tracker tracker) { - return createVec3(fbb, tracker.getPosition()); - } - - public static int createTrackerRotation(FlatBufferBuilder fbb, Tracker tracker) { - return createQuat(fbb, tracker.getRawRotation()); - } - - public static int createTrackerAcceleration(FlatBufferBuilder fbb, Tracker tracker) { - return createVec3(fbb, tracker.getAcceleration()); - } - - public static int createTrackerMagneticVector(FlatBufferBuilder fbb, Tracker tracker) { - return createVec3(fbb, tracker.getMagVector()); - } - - public static int createTrackerTemperature(FlatBufferBuilder fbb, Tracker tracker) { - if (tracker.getTemperature() == null) - return 0; - return Temperature.createTemperature(fbb, tracker.getTemperature()); - } - - public static int createTrackerData( - FlatBufferBuilder fbb, - TrackerDataMaskT mask, - Tracker tracker - ) { - int trackerInfosOffset = DataFeedBuilder.createTrackerInfos(fbb, mask.getInfo(), tracker); - int trackerIdOffset = DataFeedBuilder.createTrackerId(fbb, tracker); - - int stayAlignedOffset = 0; - if (mask.getStayAligned()) { - stayAlignedOffset = DataFeedBuilderKotlin.INSTANCE - .createTrackerStayAlignedTracker(fbb, tracker.getStayAligned()); - } - - TrackerData.startTrackerData(fbb); - - TrackerData.addTrackerId(fbb, trackerIdOffset); - - if (trackerInfosOffset != 0) - TrackerData.addInfo(fbb, trackerInfosOffset); - if (mask.getStatus()) - TrackerData.addStatus(fbb, tracker.getStatus().getId() + 1); - if (mask.getPosition() && tracker.getHasPosition()) - TrackerData.addPosition(fbb, DataFeedBuilder.createTrackerPosition(fbb, tracker)); - if (mask.getRotation() && tracker.getHasRotation()) - TrackerData.addRotation(fbb, DataFeedBuilder.createTrackerRotation(fbb, tracker)); - if (mask.getLinearAcceleration() && tracker.getHasAcceleration()) - TrackerData - .addLinearAcceleration( - fbb, - DataFeedBuilder.createTrackerAcceleration(fbb, tracker) - ); - if (mask.getTemp()) { - int trackerTemperatureOffset = DataFeedBuilder.createTrackerTemperature(fbb, tracker); - if (trackerTemperatureOffset != 0) - TrackerData.addTemp(fbb, trackerTemperatureOffset); - } - if (tracker.getAllowMounting() && tracker.getHasRotation()) { - if (mask.getRotationReferenceAdjusted()) { - TrackerData - .addRotationReferenceAdjusted(fbb, createQuat(fbb, tracker.getRotation())); - } - if (mask.getRotationIdentityAdjusted()) { - TrackerData - .addRotationIdentityAdjusted( - fbb, - createQuat(fbb, tracker.getIdentityAdjustedRotation()) - ); - } - } else if (tracker.getAllowReset() && tracker.getHasRotation()) { - if (mask.getRotationReferenceAdjusted()) { - TrackerData - .addRotationReferenceAdjusted(fbb, createQuat(fbb, tracker.getRotation())); - } - if (mask.getRotationIdentityAdjusted()) { - TrackerData - .addRotationIdentityAdjusted(fbb, createQuat(fbb, tracker.getRawRotation())); - } - } - if (mask.getTps()) { - TrackerData.addTps(fbb, (int) tracker.getTps()); - } - if (mask.getRawMagneticVector() && tracker.getMagStatus() == MagnetometerStatus.ENABLED) { - TrackerData.addRawMagneticVector(fbb, createTrackerMagneticVector(fbb, tracker)); - } - if (mask.getStayAligned()) { - TrackerData.addStayAligned(fbb, stayAlignedOffset); - } - - return TrackerData.endTrackerData(fbb); - } - - public static int createTrackersData( - FlatBufferBuilder fbb, - DeviceDataMaskT mask, - Device device - ) { - if (mask.getTrackerData() == null) - return 0; - - List trackersOffsets = new ArrayList<>(); - - device - .getTrackers() - .forEach( - (key, value) -> trackersOffsets - .add(DataFeedBuilder.createTrackerData(fbb, mask.getTrackerData(), value)) - ); - - DeviceData.startTrackersVector(fbb, trackersOffsets.size()); - trackersOffsets.forEach(offset -> DeviceData.addTrackers(fbb, offset)); - return fbb.endVector(); - } - - public static int createDeviceData( - FlatBufferBuilder fbb, - int id, - DeviceDataMaskT mask, - Device device - ) { - if (!mask.getDeviceData()) - return 0; - - if (device.getTrackers().size() <= 0) - return 0; - - Tracker firstTracker = device.getTrackers().get(0); - if (firstTracker == null) { - // Not actually the "first" tracker, but do we care? - firstTracker = device.getTrackers().entrySet().iterator().next().getValue(); - } - - Tracker tracker = firstTracker; - if (tracker == null) - return 0; - - HardwareStatus.startHardwareStatus(fbb); - HardwareStatus.addErrorStatus(fbb, tracker.getStatus().getId()); - - if (tracker.getBatteryVoltage() != null) { - HardwareStatus.addBatteryVoltage(fbb, tracker.getBatteryVoltage()); - } - if (tracker.getBatteryLevel() != null) { - HardwareStatus.addBatteryPctEstimate(fbb, (int) tracker.getBatteryLevel().floatValue()); - } - if (tracker.getPing() != null) { - HardwareStatus.addPing(fbb, tracker.getPing()); - } - if (tracker.getSignalStrength() != null) { - HardwareStatus.addRssi(fbb, (short) tracker.getSignalStrength().floatValue()); - } - - if (tracker.getPacketLoss() != null) { - HardwareStatus.addPacketLoss(fbb, tracker.getPacketLoss()); - } - - if (tracker.getPacketsLost() != null) { - HardwareStatus.addPacketsLost(fbb, tracker.getPacketsLost()); - } - - if (tracker.getPacketsReceived() != null) { - HardwareStatus.addPacketsReceived(fbb, tracker.getPacketsReceived()); - } - - if (tracker.getBatteryRemainingRuntime() != null) { - HardwareStatus.addBatteryRuntimeEstimate(fbb, tracker.getBatteryRemainingRuntime()); - } - - int hardwareDataOffset = HardwareStatus.endHardwareStatus(fbb); - int hardwareInfoOffset = DataFeedBuilder.createHardwareInfo(fbb, device); - int trackersOffset = DataFeedBuilder.createTrackersData(fbb, mask, device); - - int nameOffset = device.getName() != null - ? fbb.createString(device.getName()) - : 0; - - DeviceData.startDeviceData(fbb); - DeviceData.addCustomName(fbb, nameOffset); - DeviceData.addId(fbb, DeviceId.createDeviceId(fbb, id)); - DeviceData.addHardwareStatus(fbb, hardwareDataOffset); - DeviceData.addHardwareInfo(fbb, hardwareInfoOffset); - DeviceData.addTrackers(fbb, trackersOffset); - - return DeviceData.endDeviceData(fbb); - } - - public static int createSyntheticTrackersData( - FlatBufferBuilder fbb, - TrackerDataMaskT trackerDataMaskT, - List trackers - ) { - if (trackerDataMaskT == null) - return 0; - - List trackerOffsets = new ArrayList<>(); - - trackers - .forEach( - (tracker) -> trackerOffsets - .add(DataFeedBuilder.createTrackerData(fbb, trackerDataMaskT, tracker)) - ); - - DataFeedUpdate.startSyntheticTrackersVector(fbb, trackerOffsets.size()); - trackerOffsets.forEach((tracker -> DataFeedUpdate.addSyntheticTrackers(fbb, tracker))); - return fbb.endVector(); - } - - public static int createDevicesData( - FlatBufferBuilder fbb, - DeviceDataMaskT deviceDataMaskT, - List devices - ) { - if (deviceDataMaskT == null) - return 0; - - int[] devicesDataOffsets = new int[devices.size()]; - for (int i = 0; i < devices.size(); i++) { - Device device = devices.get(i); - devicesDataOffsets[i] = DataFeedBuilder - .createDeviceData(fbb, device.getId(), deviceDataMaskT, device); - } - - return DataFeedUpdate.createDevicesVector(fbb, devicesDataOffsets); - } - - public static int createBonesData( - FlatBufferBuilder fbb, - boolean shouldSend, - List bones - ) { - if (!shouldSend) { - return 0; - } - - var boneOffsets = new int[bones.size()]; - for (var i = 0; i < bones.size(); ++i) { - var bi = bones.get(i); - - var headPosG = bi.getPosition(); - var rotG = bi.getGlobalRotation(); - var length = bi.getLength(); - - Bone.startBone(fbb); - - var rotGOffset = createQuat(fbb, rotG); - Bone.addRotationG(fbb, rotGOffset); - var headPosGOffset = Vec3f - .createVec3f(fbb, headPosG.getX(), headPosG.getY(), headPosG.getZ()); - Bone.addHeadPositionG(fbb, headPosGOffset); - Bone.addBodyPart(fbb, bi.getBoneType().bodyPart); - Bone.addBoneLength(fbb, length); - - boneOffsets[i] = Bone.endBone(fbb); - } - - return DataFeedUpdate.createBonesVector(fbb, boneOffsets); - } -} diff --git a/server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedBuilder.kt b/server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedBuilder.kt new file mode 100644 index 000000000..baf712491 --- /dev/null +++ b/server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedBuilder.kt @@ -0,0 +1,503 @@ +package dev.slimevr.protocol.datafeed + +import com.google.flatbuffers.FlatBufferBuilder +import dev.slimevr.guards.ServerGuards +import dev.slimevr.tracking.processor.Bone +import dev.slimevr.tracking.processor.skeleton.HumanSkeleton +import dev.slimevr.tracking.processor.stayaligned.poses.RelaxedPose +import dev.slimevr.tracking.processor.stayaligned.trackers.RestDetector +import dev.slimevr.tracking.processor.stayaligned.trackers.StayAlignedTrackerState +import dev.slimevr.tracking.trackers.Device +import dev.slimevr.tracking.trackers.Tracker +import dev.slimevr.tracking.trackers.udp.MagnetometerStatus +import dev.slimevr.tracking.trackers.udp.UDPDevice +import io.github.axisangles.ktmath.Quaternion +import io.github.axisangles.ktmath.Vector3 +import solarxr_protocol.data_feed.DataFeedUpdate +import solarxr_protocol.data_feed.device_data.DeviceData +import solarxr_protocol.data_feed.device_data.DeviceDataMaskT +import solarxr_protocol.data_feed.stay_aligned.StayAlignedPose +import solarxr_protocol.data_feed.stay_aligned.StayAlignedTracker +import solarxr_protocol.data_feed.tracker.TrackerData +import solarxr_protocol.data_feed.tracker.TrackerDataMaskT +import solarxr_protocol.data_feed.tracker.TrackerInfo +import solarxr_protocol.datatypes.DeviceId +import solarxr_protocol.datatypes.Ipv4Address +import solarxr_protocol.datatypes.Temperature +import solarxr_protocol.datatypes.TrackerId +import solarxr_protocol.datatypes.hardware_info.HardwareInfo +import solarxr_protocol.datatypes.hardware_info.HardwareStatus +import solarxr_protocol.datatypes.math.Quat +import solarxr_protocol.datatypes.math.Vec3f +import java.nio.ByteBuffer +import java.util.function.Consumer + +fun createHardwareInfo(fbb: FlatBufferBuilder, device: Device): Int { + val nameOffset = if (device.firmwareVersion != null) { + fbb.createString(device.firmwareVersion) + } else { + 0 + } + + val manufacturerOffset = if (device.manufacturer != null) { + fbb.createString(device.manufacturer) + } else { + 0 + } + + val firmwareDateOffset = if (device.firmwareDate != null) { + fbb.createString(device.firmwareDate) + } else { + 0 + } + + val hardwareIdentifierOffset = fbb.createString(device.hardwareIdentifier) + + HardwareInfo.startHardwareInfo(fbb) + HardwareInfo.addFirmwareVersion(fbb, nameOffset) + HardwareInfo.addFirmwareDate(fbb, firmwareDateOffset) + HardwareInfo.addManufacturer(fbb, manufacturerOffset) + HardwareInfo.addHardwareIdentifier(fbb, hardwareIdentifierOffset) + + if (device is UDPDevice) { + val address = device.ipAddress.address + HardwareInfo + .addIpAddress( + fbb, + Ipv4Address + .createIpv4Address( + fbb, + ByteBuffer.wrap(address).getInt().toLong(), + ), + ) + + HardwareInfo.addNetworkProtocolVersion(fbb, device.protocolVersion) + } + + // BRUH MOMENT + // TODO need support: HardwareInfo.addHardwareRevision(fbb, + // hardwareRevisionOffset); + // TODO need support: HardwareInfo.addDisplayName(fbb, de); + HardwareInfo.addMcuId(fbb, device.mcuType.getSolarType()) + HardwareInfo.addOfficialBoardType(fbb, device.boardType.getSolarType()) + return HardwareInfo.endHardwareInfo(fbb) +} + +fun createTrackerId(fbb: FlatBufferBuilder, tracker: Tracker): Int { + TrackerId.startTrackerId(fbb) + + TrackerId.addTrackerNum(fbb, tracker.trackerNum) + if (tracker.device != null) { + TrackerId.addDeviceId( + fbb, + DeviceId.createDeviceId(fbb, tracker.device.id), + ) + } + + return TrackerId.endTrackerId(fbb) +} + +fun createVec3(fbb: FlatBufferBuilder, vec: Vector3): Int = Vec3f + .createVec3f( + fbb, + vec.x, + vec.y, + vec.z, + ) + +fun createQuat(fbb: FlatBufferBuilder, quaternion: Quaternion): Int = Quat + .createQuat( + fbb, + quaternion.x, + quaternion.y, + quaternion.z, + quaternion.w, + ) + +fun createTrackerInfos( + fbb: FlatBufferBuilder, + infoMask: Boolean, + tracker: Tracker, +): Int { + if (!infoMask) return 0 + + val displayNameOffset = fbb.createString(tracker.displayName) + val customNameOffset = if (tracker.customName != null) { + fbb.createString(tracker.customName) + } else { + 0 + } + + TrackerInfo.startTrackerInfo(fbb) + if (tracker.trackerPosition != null) { + TrackerInfo.addBodyPart( + fbb, + tracker.trackerPosition!!.bodyPart, + ) + } + TrackerInfo.addEditable(fbb, tracker.userEditable) + TrackerInfo.addIsComputed(fbb, tracker.isComputed) + TrackerInfo.addDisplayName(fbb, displayNameOffset) + TrackerInfo.addCustomName(fbb, customNameOffset) + if (tracker.imuType != null) { + TrackerInfo.addImuType(fbb, tracker.imuType.getSolarType()) + } + + // TODO need support: TrackerInfo.addPollRate(fbb, tracker.); + if (tracker.isImu()) { + TrackerInfo.addIsImu(fbb, true) + TrackerInfo + .addAllowDriftCompensation( + fbb, + tracker.resetsHandler.allowDriftCompensation, + ) + } else { + TrackerInfo.addIsImu(fbb, false) + TrackerInfo.addAllowDriftCompensation(fbb, false) + } + + if (tracker.allowMounting) { + val quaternion = tracker.resetsHandler.mountingOrientation + val mountResetFix = tracker.resetsHandler.mountRotFix + TrackerInfo.addMountingOrientation(fbb, createQuat(fbb, quaternion)) + TrackerInfo.addMountingResetOrientation(fbb, createQuat(fbb, mountResetFix)) + } + + TrackerInfo.addMagnetometer(fbb, tracker.magStatus.getSolarType()) + TrackerInfo.addIsHmd(fbb, tracker.isHmd) + + TrackerInfo.addDataSupport(fbb, tracker.trackerDataType.getSolarType()) + + return TrackerInfo.endTrackerInfo(fbb) +} + +fun createTrackerPosition(fbb: FlatBufferBuilder, tracker: Tracker): Int = createVec3(fbb, tracker.position) + +fun createTrackerRotation(fbb: FlatBufferBuilder, tracker: Tracker): Int = createQuat(fbb, tracker.getRawRotation()) + +fun createTrackerAcceleration(fbb: FlatBufferBuilder, tracker: Tracker): Int = createVec3(fbb, tracker.getAcceleration()) + +fun createTrackerMagneticVector(fbb: FlatBufferBuilder, tracker: Tracker): Int = createVec3(fbb, tracker.getMagVector()) + +fun createTrackerTemperature(fbb: FlatBufferBuilder, tracker: Tracker): Int { + if (tracker.temperature == null) return 0 + return Temperature.createTemperature(fbb, tracker.temperature!!) +} + +fun createTrackerData( + fbb: FlatBufferBuilder, + mask: TrackerDataMaskT, + tracker: Tracker, +): Int { + val trackerInfosOffset = createTrackerInfos(fbb, mask.info, tracker) + val trackerIdOffset = createTrackerId(fbb, tracker) + + var stayAlignedOffset = 0 + if (mask.stayAligned) { + stayAlignedOffset = + createTrackerStayAlignedTracker(fbb, tracker.stayAligned) + } + + TrackerData.startTrackerData(fbb) + + TrackerData.addTrackerId(fbb, trackerIdOffset) + + if (trackerInfosOffset != 0) TrackerData.addInfo(fbb, trackerInfosOffset) + if (mask.status) TrackerData.addStatus(fbb, tracker.status.id + 1) + if (mask.position && tracker.hasPosition) { + TrackerData.addPosition( + fbb, + createTrackerPosition(fbb, tracker), + ) + } + if (mask.rotation && tracker.hasRotation) { + TrackerData.addRotation( + fbb, + createTrackerRotation(fbb, tracker), + ) + } + if (mask.linearAcceleration && tracker.hasAcceleration) { + TrackerData + .addLinearAcceleration( + fbb, + createTrackerAcceleration(fbb, tracker), + ) + } + if (mask.temp) { + val trackerTemperatureOffset = createTrackerTemperature(fbb, tracker) + if (trackerTemperatureOffset != 0) { + TrackerData.addTemp( + fbb, + trackerTemperatureOffset, + ) + } + } + if (tracker.allowMounting && tracker.hasRotation) { + if (mask.rotationReferenceAdjusted) { + TrackerData + .addRotationReferenceAdjusted( + fbb, + createQuat(fbb, tracker.getRotation()), + ) + } + if (mask.rotationIdentityAdjusted) { + TrackerData + .addRotationIdentityAdjusted( + fbb, + createQuat(fbb, tracker.getIdentityAdjustedRotation()), + ) + } + } else if (tracker.allowReset && tracker.hasRotation) { + if (mask.rotationReferenceAdjusted) { + TrackerData + .addRotationReferenceAdjusted( + fbb, + createQuat(fbb, tracker.getRotation()), + ) + } + if (mask.rotationIdentityAdjusted) { + TrackerData + .addRotationIdentityAdjusted( + fbb, + createQuat(fbb, tracker.getRawRotation()), + ) + } + } + if (mask.tps) { + TrackerData.addTps(fbb, tracker.tps.toInt()) + } + if (mask.rawMagneticVector && tracker.magStatus == MagnetometerStatus.ENABLED) { + TrackerData.addRawMagneticVector( + fbb, + createTrackerMagneticVector(fbb, tracker), + ) + } + if (mask.stayAligned) { + TrackerData.addStayAligned(fbb, stayAlignedOffset) + } + + return TrackerData.endTrackerData(fbb) +} + +fun createTrackersData( + fbb: FlatBufferBuilder, + mask: DeviceDataMaskT, + device: Device, +): Int { + if (mask.trackerData == null) return 0 + + val trackersOffsets: MutableList = ArrayList() + + device + .trackers + .forEach { (_: Int, value: Tracker) -> + trackersOffsets + .add(createTrackerData(fbb, mask.trackerData, value)) + } + + DeviceData.startTrackersVector(fbb, trackersOffsets.size) + trackersOffsets.forEach( + Consumer { offset: Int -> + DeviceData.addTrackers( + fbb, + offset, + ) + }, + ) + return fbb.endVector() +} + +fun createDeviceData( + fbb: FlatBufferBuilder, + id: Int, + mask: DeviceDataMaskT, + device: Device, +): Int { + if (!mask.deviceData) return 0 + + if (device.trackers.isEmpty()) return 0 + + var firstTracker = device.trackers[0] + if (firstTracker == null) { + // Not actually the "first" tracker, but do we care? + firstTracker = device.trackers.entries.iterator().next().value + } + + val tracker: Tracker = firstTracker + + HardwareStatus.startHardwareStatus(fbb) + HardwareStatus.addErrorStatus(fbb, tracker.status.id) + + if (tracker.batteryVoltage != null) { + HardwareStatus.addBatteryVoltage(fbb, tracker.batteryVoltage!!) + } + if (tracker.batteryLevel != null) { + HardwareStatus.addBatteryPctEstimate(fbb, tracker.batteryLevel!!.toInt()) + } + if (tracker.ping != null) { + HardwareStatus.addPing(fbb, tracker.ping!!) + } + if (tracker.signalStrength != null) { + HardwareStatus.addRssi(fbb, tracker.signalStrength!!.toShort()) + } + if (tracker.packetLoss != null) { + HardwareStatus.addPacketLoss(fbb, tracker.packetLoss!!) + } + if (tracker.packetsLost != null) { + HardwareStatus.addPacketsLost(fbb, tracker.packetsLost!!) + } + if (tracker.packetsReceived != null) { + HardwareStatus.addPacketsReceived(fbb, tracker.packetsReceived!!) + } + + val hardwareDataOffset = HardwareStatus.endHardwareStatus(fbb) + val hardwareInfoOffset = createHardwareInfo(fbb, device) + val trackersOffset = createTrackersData(fbb, mask, device) + + val nameOffset = if (device.name != null) { + fbb.createString(device.name) + } else { + 0 + } + + DeviceData.startDeviceData(fbb) + DeviceData.addCustomName(fbb, nameOffset) + DeviceData.addId(fbb, DeviceId.createDeviceId(fbb, id)) + DeviceData.addHardwareStatus(fbb, hardwareDataOffset) + DeviceData.addHardwareInfo(fbb, hardwareInfoOffset) + DeviceData.addTrackers(fbb, trackersOffset) + + return DeviceData.endDeviceData(fbb) +} + +fun createSyntheticTrackersData( + fbb: FlatBufferBuilder, + trackerDataMaskT: TrackerDataMaskT?, + trackers: MutableList, +): Int { + if (trackerDataMaskT == null) return 0 + + val trackerOffsets: MutableList = ArrayList() + + trackers + .forEach( + Consumer { tracker: Tracker -> + trackerOffsets + .add(createTrackerData(fbb, trackerDataMaskT, tracker)) + }, + ) + + DataFeedUpdate.startSyntheticTrackersVector(fbb, trackerOffsets.size) + trackerOffsets.forEach( + ( + Consumer { tracker: Int -> + DataFeedUpdate.addSyntheticTrackers( + fbb, + tracker, + ) + } + ), + ) + return fbb.endVector() +} + +fun createDevicesData( + fbb: FlatBufferBuilder, + deviceDataMaskT: DeviceDataMaskT?, + devices: MutableList, +): Int { + if (deviceDataMaskT == null) return 0 + + val devicesDataOffsets = IntArray(devices.size) + for (i in devices.indices) { + val device = devices[i] + devicesDataOffsets[i] = + createDeviceData(fbb, device.id, deviceDataMaskT, device) + } + + return DataFeedUpdate.createDevicesVector(fbb, devicesDataOffsets) +} + +fun createBonesData( + fbb: FlatBufferBuilder, + shouldSend: Boolean, + bones: MutableList, +): Int { + if (!shouldSend) { + return 0 + } + + val boneOffsets = IntArray(bones.size) + for (i in bones.indices) { + val bi = bones[i] + + val headPosG = + bi.getPosition() + val rotG = + bi.getGlobalRotation() + val length = bi.length + + solarxr_protocol.data_feed.Bone.startBone(fbb) + + val rotGOffset = createQuat(fbb, rotG) + solarxr_protocol.data_feed.Bone.addRotationG(fbb, rotGOffset) + val headPosGOffset = Vec3f + .createVec3f(fbb, headPosG.x, headPosG.y, headPosG.z) + solarxr_protocol.data_feed.Bone.addHeadPositionG(fbb, headPosGOffset) + solarxr_protocol.data_feed.Bone.addBodyPart(fbb, bi.boneType.bodyPart) + solarxr_protocol.data_feed.Bone.addBoneLength(fbb, length) + + boneOffsets[i] = solarxr_protocol.data_feed.Bone.endBone(fbb) + } + + return DataFeedUpdate.createBonesVector(fbb, boneOffsets) +} + +fun createStayAlignedPose( + fbb: FlatBufferBuilder, + humanSkeleton: HumanSkeleton, +): Int { + val relaxedPose = RelaxedPose.fromTrackers(humanSkeleton) + + StayAlignedPose.startStayAlignedPose(fbb) + + StayAlignedPose.addUpperLegAngleInDeg(fbb, relaxedPose.upperLeg.toDeg()) + StayAlignedPose.addLowerLegAngleInDeg(fbb, relaxedPose.lowerLeg.toDeg()) + StayAlignedPose.addFootAngleInDeg(fbb, relaxedPose.foot.toDeg()) + + return StayAlignedPose.endStayAlignedPose(fbb) +} + +fun createTrackerStayAlignedTracker( + fbb: FlatBufferBuilder, + state: StayAlignedTrackerState, +): Int { + StayAlignedTracker.startStayAlignedTracker(fbb) + + StayAlignedTracker.addYawCorrectionInDeg(fbb, state.yawCorrection.toDeg()) + StayAlignedTracker.addLockedErrorInDeg( + fbb, + state.yawErrors.lockedError.toL2Norm().toDeg(), + ) + StayAlignedTracker.addCenterErrorInDeg( + fbb, + state.yawErrors.centerError.toL2Norm().toDeg(), + ) + StayAlignedTracker.addNeighborErrorInDeg( + fbb, + state.yawErrors.neighborError.toL2Norm().toDeg(), + ) + StayAlignedTracker.addLocked( + fbb, + state.restDetector.state == RestDetector.State.AT_REST, + ) + + return StayAlignedTracker.endStayAlignedTracker(fbb) +} + +fun createServerGuard(fbb: FlatBufferBuilder, serverGuards: ServerGuards): Int = solarxr_protocol.data_feed.server.ServerGuards.createServerGuards( + fbb, + serverGuards.canDoMounting, + serverGuards.canDoYawReset, + serverGuards.canDoUserHeightCalibration, +) diff --git a/server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedBuilderKotlin.kt b/server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedBuilderKotlin.kt deleted file mode 100644 index 8600da05a..000000000 --- a/server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedBuilderKotlin.kt +++ /dev/null @@ -1,50 +0,0 @@ -package dev.slimevr.protocol.datafeed - -import com.google.flatbuffers.FlatBufferBuilder -import dev.slimevr.guards.ServerGuards -import dev.slimevr.tracking.processor.skeleton.HumanSkeleton -import dev.slimevr.tracking.processor.stayaligned.poses.RelaxedPose -import dev.slimevr.tracking.processor.stayaligned.trackers.RestDetector -import dev.slimevr.tracking.processor.stayaligned.trackers.StayAlignedTrackerState -import solarxr_protocol.data_feed.stay_aligned.StayAlignedPose -import solarxr_protocol.data_feed.stay_aligned.StayAlignedTracker - -object DataFeedBuilderKotlin { - - fun createStayAlignedPose( - fbb: FlatBufferBuilder, - humanSkeleton: HumanSkeleton, - ): Int { - val relaxedPose = RelaxedPose.fromTrackers(humanSkeleton) - - StayAlignedPose.startStayAlignedPose(fbb) - - StayAlignedPose.addUpperLegAngleInDeg(fbb, relaxedPose.upperLeg.toDeg()) - StayAlignedPose.addLowerLegAngleInDeg(fbb, relaxedPose.lowerLeg.toDeg()) - StayAlignedPose.addFootAngleInDeg(fbb, relaxedPose.foot.toDeg()) - - return StayAlignedPose.endStayAlignedPose(fbb) - } - - fun createTrackerStayAlignedTracker( - fbb: FlatBufferBuilder, - state: StayAlignedTrackerState, - ): Int { - StayAlignedTracker.startStayAlignedTracker(fbb) - - StayAlignedTracker.addYawCorrectionInDeg(fbb, state.yawCorrection.toDeg()) - StayAlignedTracker.addLockedErrorInDeg(fbb, state.yawErrors.lockedError.toL2Norm().toDeg()) - StayAlignedTracker.addCenterErrorInDeg(fbb, state.yawErrors.centerError.toL2Norm().toDeg()) - StayAlignedTracker.addNeighborErrorInDeg(fbb, state.yawErrors.neighborError.toL2Norm().toDeg()) - StayAlignedTracker.addLocked(fbb, state.restDetector.state == RestDetector.State.AT_REST) - - return StayAlignedTracker.endStayAlignedTracker(fbb) - } - - fun createServerGuard(fbb: FlatBufferBuilder, serverGuards: ServerGuards): Int = solarxr_protocol.data_feed.server.ServerGuards.createServerGuards( - fbb, - serverGuards.canDoMounting, - serverGuards.canDoYawReset, - serverGuards.canDoUserHeightCalibration, - ) -} diff --git a/server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedHandler.java b/server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedHandler.java deleted file mode 100644 index 90ff7b7c7..000000000 --- a/server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedHandler.java +++ /dev/null @@ -1,192 +0,0 @@ -package dev.slimevr.protocol.datafeed; - -import com.google.flatbuffers.FlatBufferBuilder; -import dev.slimevr.protocol.DataFeed; -import dev.slimevr.protocol.GenericConnection; -import dev.slimevr.protocol.ProtocolAPI; -import dev.slimevr.protocol.ProtocolHandler; -import dev.slimevr.tracking.trackers.Tracker; -import io.eiren.util.logging.LogManager; -import solarxr_protocol.MessageBundle; -import solarxr_protocol.data_feed.*; - -import java.util.List; -import java.util.function.BiConsumer; -import java.util.stream.Collectors; - - -public class DataFeedHandler extends ProtocolHandler { - private final ProtocolAPI api; - - public DataFeedHandler(ProtocolAPI api) { - this.api = api; - - registerPacketListener(DataFeedMessage.StartDataFeed, this::onStartDataFeed); - registerPacketListener(DataFeedMessage.PollDataFeed, this::onPollDataFeedRequest); - - this.api.server.addOnTick(this::sendDataFeedUpdate); - } - - private void onStartDataFeed(GenericConnection conn, DataFeedMessageHeader header) { - StartDataFeed req = (StartDataFeed) header.message(new StartDataFeed()); - if (req == null) - return; - int dataFeeds = req.dataFeedsLength(); - - List feedList = conn.getContext().getDataFeedList(); - synchronized (feedList) { - feedList.clear(); - for (int i = 0; i < dataFeeds; i++) { - // Using the object api here because we - // need to copy from the buffer, anyway let's - // do it from here and send the reference to an arraylist - DataFeedConfigT config = req.dataFeeds(i).unpack(); - feedList.add(new DataFeed(config)); - } - } - } - - private void onPollDataFeedRequest( - GenericConnection conn, - DataFeedMessageHeader messageHeader - ) { - - PollDataFeed req = (PollDataFeed) messageHeader.message(new PollDataFeed()); - if (req == null) - return; - - FlatBufferBuilder fbb = new FlatBufferBuilder(300); - - int messageOffset = this.buildDatafeed(fbb, req.config().unpack(), 0); - - DataFeedMessageHeader.startDataFeedMessageHeader(fbb); - DataFeedMessageHeader.addMessage(fbb, messageOffset); - DataFeedMessageHeader.addMessageType(fbb, DataFeedMessage.DataFeedUpdate); - int headerOffset = DataFeedMessageHeader.endDataFeedMessageHeader(fbb); - - MessageBundle.startDataFeedMsgsVector(fbb, 1); - MessageBundle.addDataFeedMsgs(fbb, headerOffset); - int datafeedMessagesOffset = fbb.endVector(); - - int packet = createMessage(fbb, datafeedMessagesOffset); - fbb.finish(packet); - conn.send(fbb.dataBuffer()); - } - - public int buildDatafeed(FlatBufferBuilder fbb, DataFeedConfigT config, int index) { - int devicesOffset = DataFeedBuilder - .createDevicesData( - fbb, - config.getDataMask(), - this.api.server.deviceManager - .getDevices() - ); - // Synthetic tracker is computed tracker apparently - int trackersOffset = DataFeedBuilder - .createSyntheticTrackersData( - fbb, - config.getSyntheticTrackersMask(), - this.api.server - .getAllTrackers() - .stream() - .filter(Tracker::isComputed) - .collect(Collectors.toList()) - ); - - var h = this.api.server.humanPoseManager; - int bonesOffset = DataFeedBuilder - .createBonesData( - fbb, - config.getBoneMask(), - h.getAllBones() - ); - - int stayAlignedPoseOffset = 0; - if (config.getStayAlignedPoseMask()) { - stayAlignedPoseOffset = DataFeedBuilderKotlin.INSTANCE - .createStayAlignedPose(fbb, this.api.server.humanPoseManager.skeleton); - } - - int serverGuardsOffset = 0; - if (config.getServerGuardsMask()) { - serverGuardsOffset = DataFeedBuilderKotlin.INSTANCE - .createServerGuard(fbb, this.api.server.getServerGuards()); - } - - return DataFeedUpdate - .createDataFeedUpdate( - fbb, - devicesOffset, - trackersOffset, - bonesOffset, - stayAlignedPoseOffset, - index, - serverGuardsOffset - ); - } - - public void sendDataFeedUpdate() { - long currTime = System.currentTimeMillis(); - - this.api.getAPIServers().forEach((server) -> server.getAPIConnections().forEach((conn) -> { - FlatBufferBuilder fbb = null; - - List feedList = conn.getContext().getDataFeedList(); - synchronized (feedList) { - int configsCount = feedList.size(); - - int[] data = new int[configsCount]; - - for (int index = 0; index < configsCount; index++) { - DataFeed feed = feedList.get(index); - Long lastTimeSent = feed.getTimeLastSent(); - DataFeedConfigT configT = feed.getConfig(); - if (currTime - lastTimeSent > configT.getMinimumTimeSinceLast()) { - if (fbb == null) { - // That way we create a buffer only when needed - fbb = new FlatBufferBuilder(300); - } - - int messageOffset = this.buildDatafeed(fbb, configT, index); - - DataFeedMessageHeader.startDataFeedMessageHeader(fbb); - DataFeedMessageHeader.addMessage(fbb, messageOffset); - DataFeedMessageHeader.addMessageType(fbb, DataFeedMessage.DataFeedUpdate); - data[index] = DataFeedMessageHeader.endDataFeedMessageHeader(fbb); - - feed.setTimeLastSent(currTime); - int messages = MessageBundle.createDataFeedMsgsVector(fbb, data); - int packet = createMessage(fbb, messages); - fbb.finish(packet); - conn.send(fbb.dataBuffer()); - } - } - } - })); - } - - @Override - public void onMessage(GenericConnection conn, DataFeedMessageHeader message) { - BiConsumer consumer = this.handlers[message - .messageType()]; - if (consumer != null) - consumer.accept(conn, message); - else - LogManager - .info( - "[ProtocolAPI] Unhandled Datafeed packet received id: " + message.messageType() - ); - } - - @Override - public int messagesCount() { - return DataFeedMessage.names.length; - } - - public int createMessage(FlatBufferBuilder fbb, int datafeedMessagesOffset) { - MessageBundle.startMessageBundle(fbb); - if (datafeedMessagesOffset > -1) - MessageBundle.addDataFeedMsgs(fbb, datafeedMessagesOffset); - return MessageBundle.endMessageBundle(fbb); - } -} diff --git a/server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedHandler.kt b/server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedHandler.kt new file mode 100644 index 000000000..dfb3d5dd6 --- /dev/null +++ b/server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedHandler.kt @@ -0,0 +1,177 @@ +package dev.slimevr.protocol.datafeed + +import com.google.flatbuffers.FlatBufferBuilder +import dev.slimevr.protocol.DataFeed +import dev.slimevr.protocol.GenericConnection +import dev.slimevr.protocol.ProtocolAPI +import dev.slimevr.protocol.ProtocolAPIServer +import dev.slimevr.protocol.ProtocolHandler +import dev.slimevr.tracking.trackers.Tracker +import io.eiren.util.logging.LogManager +import solarxr_protocol.MessageBundle +import solarxr_protocol.data_feed.DataFeedConfigT +import solarxr_protocol.data_feed.DataFeedMessage +import solarxr_protocol.data_feed.DataFeedMessageHeader +import solarxr_protocol.data_feed.DataFeedUpdate +import solarxr_protocol.data_feed.PollDataFeed +import solarxr_protocol.data_feed.StartDataFeed +import java.util.function.Consumer +import java.util.stream.Collectors + +class DataFeedHandler(private val api: ProtocolAPI) : ProtocolHandler() { + init { + registerPacketListener(DataFeedMessage.StartDataFeed, ::onStartDataFeed) + registerPacketListener(DataFeedMessage.PollDataFeed, ::onPollDataFeedRequest) + this.api.server.addOnTick { this.sendDataFeedUpdate() } + } + + private fun onStartDataFeed(conn: GenericConnection, header: DataFeedMessageHeader) { + val req = header.message(StartDataFeed()) as StartDataFeed? ?: return + val dataFeeds = req.dataFeedsLength() + + val feedList = conn.context.dataFeedList + synchronized(feedList) { + feedList.clear() + for (i in 0.. + server.apiConnections.forEach { conn: GenericConnection -> + var fbb: FlatBufferBuilder? = null + val feedList = conn.context.dataFeedList + synchronized(feedList) { + val configsCount = feedList.size + val data = IntArray(configsCount) + for (index in 0.. configT.minimumTimeSinceLast) { + if (fbb == null) { + // That way we create a buffer only when needed + fbb = FlatBufferBuilder(300) + } + + val messageOffset = this.buildDatafeed(fbb, configT, index) + + DataFeedMessageHeader.startDataFeedMessageHeader(fbb) + DataFeedMessageHeader.addMessage(fbb, messageOffset) + DataFeedMessageHeader.addMessageType(fbb, DataFeedMessage.DataFeedUpdate) + data[index] = DataFeedMessageHeader.endDataFeedMessageHeader(fbb) + + feed.timeLastSent = currTime + val messages = MessageBundle.createDataFeedMsgsVector(fbb, data) + val packet = createMessage(fbb, messages) + fbb.finish(packet) + conn.send(fbb.dataBuffer()) + } + } + } + } + }, + ) + } + + override fun onMessage(conn: GenericConnection, message: DataFeedMessageHeader) { + val consumer = this.handlers[message.messageType().toInt()] + if (consumer != null) { + consumer.accept(conn, message) + } else { + LogManager + .info( + "[ProtocolAPI] Unhandled Datafeed packet received id: " + message.messageType(), + ) + } + } + + override fun messagesCount(): Int = DataFeedMessage.names.size + + fun createMessage(fbb: FlatBufferBuilder, datafeedMessagesOffset: Int): Int { + MessageBundle.startMessageBundle(fbb) + if (datafeedMessagesOffset > -1) MessageBundle.addDataFeedMsgs(fbb, datafeedMessagesOffset) + return MessageBundle.endMessageBundle(fbb) + } +} diff --git a/server/core/src/main/java/dev/slimevr/protocol/pubsub/HashedTopicId.java b/server/core/src/main/java/dev/slimevr/protocol/pubsub/HashedTopicId.java deleted file mode 100644 index f43f7cd9f..000000000 --- a/server/core/src/main/java/dev/slimevr/protocol/pubsub/HashedTopicId.java +++ /dev/null @@ -1,45 +0,0 @@ -package dev.slimevr.protocol.pubsub; - -import solarxr_protocol.pub_sub.TopicIdT; - -import java.util.Objects; - - -// This class is so the HashMap referencing the TopicId as key works -// it needs a unique hashcode based on the topicId and also an equals function -// because equals hashcode does not mean equals strings -public class HashedTopicId { - - private final TopicIdT inner; - private final int hashcode; - - public HashedTopicId(TopicIdT topicIdT) { - this.inner = topicIdT; - this.hashcode = (inner.getAppName() - + "." - + inner.getOrganization() - + "." - + inner.getTopic()).hashCode(); - } - - public TopicIdT getInner() { - return inner; - } - - @Override - public int hashCode() { - return hashcode; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - HashedTopicId that = (HashedTopicId) o; - return Objects.equals(inner.getOrganization(), that.getInner().getOrganization()) - && Objects.equals(inner.getAppName(), that.getInner().getAppName()) - && Objects.equals(inner.getTopic(), that.getInner().getTopic()); - } -} diff --git a/server/core/src/main/java/dev/slimevr/protocol/pubsub/HashedTopicId.kt b/server/core/src/main/java/dev/slimevr/protocol/pubsub/HashedTopicId.kt new file mode 100644 index 000000000..44fccae15 --- /dev/null +++ b/server/core/src/main/java/dev/slimevr/protocol/pubsub/HashedTopicId.kt @@ -0,0 +1,29 @@ +package dev.slimevr.protocol.pubsub + +import solarxr_protocol.pub_sub.TopicIdT + +// This class is so the HashMap referencing the TopicId as key works +// it needs a unique hashcode based on the topicId and also an equals function +// because equals hashcode does not mean equals strings +class HashedTopicId(val inner: TopicIdT) { + private val hashcode: Int = ( + ( + inner.appName + + "." + + inner.organization + + "." + + inner.topic + ) + ).hashCode() + + override fun hashCode(): Int = hashcode + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || javaClass != other.javaClass) return false + val that = other as HashedTopicId + return inner.organization == that.inner.organization && + inner.appName == that.inner.appName && + inner.topic == that.inner.topic + } +} diff --git a/server/core/src/main/java/dev/slimevr/protocol/pubsub/PubSubHandler.java b/server/core/src/main/java/dev/slimevr/protocol/pubsub/PubSubHandler.java deleted file mode 100644 index 2de358dd8..000000000 --- a/server/core/src/main/java/dev/slimevr/protocol/pubsub/PubSubHandler.java +++ /dev/null @@ -1,185 +0,0 @@ -package dev.slimevr.protocol.pubsub; - -import com.google.flatbuffers.FlatBufferBuilder; -import dev.slimevr.protocol.GenericConnection; -import dev.slimevr.protocol.ProtocolAPI; -import dev.slimevr.protocol.ProtocolHandler; -import io.eiren.util.logging.LogManager; -import solarxr_protocol.MessageBundle; -import solarxr_protocol.pub_sub.*; - -import java.util.HashMap; -import java.util.Optional; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.BiConsumer; - - -public class PubSubHandler extends ProtocolHandler { - - private final ProtocolAPI api; - - // Two ways maps for faster reading when handling lots of packets - public HashMap topicsHandle = new HashMap<>(); - public HashMap handleTopics = new HashMap<>(); - - public AtomicInteger nextLocalHandle = new AtomicInteger(); - - public PubSubHandler(ProtocolAPI api) { - super(); - this.api = api; - - registerPacketListener(PubSubUnion.SubscriptionRequest, this::onSubscriptionRequest); - registerPacketListener(PubSubUnion.TopicHandleRequest, this::onTopicHandleRequest); - registerPacketListener(PubSubUnion.Message, this::onTopicMessage); - } - - private int getTopicHandle(TopicIdT topicIdT) { - HashedTopicId hashedTopicId = new HashedTopicId(topicIdT); - Integer handleT = topicsHandle.get(hashedTopicId); - // if no handle exists for this topic id we create one and return it - // anyway - if (handleT == null) { - handleT = nextLocalHandle.incrementAndGet(); - topicsHandle.put(hashedTopicId, handleT); - handleTopics.put(handleT, hashedTopicId); - } - - return handleT; - } - - public void onSubscriptionRequest(GenericConnection conn, PubSubHeader messageHeader) { - SubscriptionRequest req = (SubscriptionRequest) messageHeader.u(new SubscriptionRequest()); - - if (req == null) - return; - - int subHandle = -1; - if (req.topicType() == Topic.TopicHandle) { - TopicHandle handle = (TopicHandle) req.topic(new TopicHandle()); - if (handle != null && handleTopics.containsKey(handle.id())) - subHandle = handle.id(); - } else if (req.topicType() == Topic.TopicId) { - TopicId topicId = (TopicId) req.topic(new TopicId()); - if (topicId != null) - subHandle = getTopicHandle(topicId.unpack()); - } - - assert subHandle != -1; - - final int finalSubHandle = subHandle; - Optional first = conn - .getContext() - .getSubscribedTopics() - .stream() - .filter((handle) -> handle == finalSubHandle) - .findFirst(); - if (!first.isPresent()) { - conn.getContext().getSubscribedTopics().add(finalSubHandle); - } - - - FlatBufferBuilder fbb = new FlatBufferBuilder(32); - int topicIdOffset = TopicId.pack(fbb, handleTopics.get(finalSubHandle).getInner()); - int topicHandleOffset = TopicHandle.createTopicHandle(fbb, finalSubHandle); - - int outbound = createMessage( - fbb, - PubSubUnion.TopicMapping, - TopicMapping.createTopicMapping(fbb, topicIdOffset, topicHandleOffset) - ); - fbb.finish(outbound); - conn.send(fbb.dataBuffer()); - } - - public void onTopicHandleRequest(GenericConnection conn, PubSubHeader messageHeader) { - - TopicHandleRequest req = (TopicHandleRequest) messageHeader.u(new TopicHandleRequest()); - - if (req == null) - return; - - TopicHandleRequestT topicRequest = req.unpack(); - int handle = getTopicHandle(topicRequest.getId()); - - FlatBufferBuilder fbb = new FlatBufferBuilder(32); - int topicIdOffset = TopicId.pack(fbb, topicRequest.getId()); - int topicHandleOffset = TopicHandle.createTopicHandle(fbb, handle); - - int outbound = createMessage( - fbb, - PubSubUnion.TopicMapping, - TopicMapping.createTopicMapping(fbb, topicIdOffset, topicHandleOffset) - ); - fbb.finish(outbound); - conn.send(fbb.dataBuffer()); - } - - - public void onTopicMessage(GenericConnection c, PubSubHeader messageHeader) { - Message req = (Message) messageHeader.u(new Message()); - - if (req == null) - return; - - MessageT messageT = req.unpack(); - - int subHandle = 1; - if (messageT.getTopic().getType() == Topic.TopicHandle) { - subHandle = messageT.getTopic().asTopicHandle().getId(); - } else if (messageT.getTopic().getType() == Topic.TopicId) { - subHandle = getTopicHandle(messageT.getTopic().asTopicId()); - } - - - assert subHandle != -1; - - int finalSubHandle = subHandle; - - this.api.getAPIServers().forEach((server) -> { - server.getAPIConnections().forEach((conn) -> { - // Make sure that we are not sending a message to ourselves - // And check that the receiver has subscribed to the topic - if ( - !conn.getConnectionId().equals(c.getConnectionId()) - && conn.getContext().getSubscribedTopics().contains(finalSubHandle) - ) { - FlatBufferBuilder fbb = new FlatBufferBuilder(32); - int outbound = createMessage( - fbb, - PubSubUnion.Message, - Message.pack(fbb, messageT) - ); - fbb.finish(outbound); - conn.send(fbb.dataBuffer()); - } - }); - }); - } - - @Override - public void onMessage(GenericConnection conn, PubSubHeader message) { - BiConsumer consumer = this.handlers[message.uType()]; - if (consumer != null) - consumer.accept(conn, message); - else - LogManager - .info("[ProtocolAPI] Unhandled PubSub packet received id: " + message.uType()); - } - - @Override - public int messagesCount() { - return PubSubUnion.names.length; - } - - public int createMessage(FlatBufferBuilder fbb, byte messageType, int messageOffset) { - int[] data = new int[1]; - - data[0] = PubSubHeader.createPubSubHeader(fbb, messageType, messageOffset); - - int messages = MessageBundle.createPubSubMsgsVector(fbb, data); - - MessageBundle.startMessageBundle(fbb); - MessageBundle.addPubSubMsgs(fbb, messages); - return MessageBundle.endMessageBundle(fbb); - } -} diff --git a/server/core/src/main/java/dev/slimevr/protocol/pubsub/PubSubHandler.kt b/server/core/src/main/java/dev/slimevr/protocol/pubsub/PubSubHandler.kt new file mode 100644 index 000000000..fe9d24f8d --- /dev/null +++ b/server/core/src/main/java/dev/slimevr/protocol/pubsub/PubSubHandler.kt @@ -0,0 +1,170 @@ +package dev.slimevr.protocol.pubsub + +import com.google.flatbuffers.FlatBufferBuilder +import dev.slimevr.protocol.GenericConnection +import dev.slimevr.protocol.ProtocolAPI +import dev.slimevr.protocol.ProtocolAPIServer +import dev.slimevr.protocol.ProtocolHandler +import io.eiren.util.logging.LogManager +import solarxr_protocol.MessageBundle +import solarxr_protocol.pub_sub.Message +import solarxr_protocol.pub_sub.PubSubHeader +import solarxr_protocol.pub_sub.PubSubUnion +import solarxr_protocol.pub_sub.SubscriptionRequest +import solarxr_protocol.pub_sub.Topic +import solarxr_protocol.pub_sub.TopicHandle +import solarxr_protocol.pub_sub.TopicHandleRequest +import solarxr_protocol.pub_sub.TopicId +import solarxr_protocol.pub_sub.TopicIdT +import solarxr_protocol.pub_sub.TopicMapping +import java.util.concurrent.atomic.AtomicInteger +import java.util.function.Consumer + +class PubSubHandler(private val api: ProtocolAPI) : ProtocolHandler() { + // Two ways maps for faster reading when handling lots of packets + var topicsHandle: HashMap = HashMap() + var handleTopics: HashMap = HashMap() + + var nextLocalHandle: AtomicInteger = AtomicInteger() + + init { + registerPacketListener(PubSubUnion.SubscriptionRequest, ::onSubscriptionRequest) + registerPacketListener(PubSubUnion.TopicHandleRequest, ::onTopicHandleRequest) + registerPacketListener(PubSubUnion.Message, ::onTopicMessage) + } + + private fun getTopicHandle(topicIdT: TopicIdT): Int { + val hashedTopicId = HashedTopicId(topicIdT) + var handleT = topicsHandle.get(hashedTopicId) + // if no handle exists for this topic id we create one and return it + // anyway + if (handleT == null) { + handleT = nextLocalHandle.incrementAndGet() + topicsHandle[hashedTopicId] = handleT + handleTopics[handleT] = hashedTopicId + } + + return handleT + } + + fun onSubscriptionRequest(conn: GenericConnection, messageHeader: PubSubHeader) { + val req = + messageHeader.u(SubscriptionRequest()) as SubscriptionRequest? ?: return + + var subHandle = -1 + if (req.topicType() == Topic.TopicHandle) { + val handle = req.topic(TopicHandle()) as TopicHandle? + if (handle != null && handleTopics.containsKey(handle.id())) subHandle = handle.id() + } else if (req.topicType() == Topic.TopicId) { + val topicId = req.topic(TopicId()) as TopicId? + if (topicId != null) subHandle = getTopicHandle(topicId.unpack()) + } + + assert(subHandle != -1) + + val finalSubHandle = subHandle + val first = conn + .context + .subscribedTopics + .stream() + .filter { handle: Int -> handle == finalSubHandle } + .findFirst() + if (!first.isPresent) { + conn.context.subscribedTopics.add(finalSubHandle) + } + + val fbb = FlatBufferBuilder(32) + val topicIdOffset = TopicId.pack(fbb, handleTopics.get(finalSubHandle)!!.inner) + val topicHandleOffset = TopicHandle.createTopicHandle(fbb, finalSubHandle) + + val outbound = createMessage( + fbb, + PubSubUnion.TopicMapping, + TopicMapping.createTopicMapping(fbb, topicIdOffset, topicHandleOffset), + ) + fbb.finish(outbound) + conn.send(fbb.dataBuffer()) + } + + fun onTopicHandleRequest(conn: GenericConnection, messageHeader: PubSubHeader) { + val req = messageHeader.u(TopicHandleRequest()) as TopicHandleRequest? ?: return + + val topicRequest = req.unpack() + val handle = getTopicHandle(topicRequest.id) + + val fbb = FlatBufferBuilder(32) + val topicIdOffset = TopicId.pack(fbb, topicRequest.id) + val topicHandleOffset = TopicHandle.createTopicHandle(fbb, handle) + + val outbound = createMessage( + fbb, + PubSubUnion.TopicMapping, + TopicMapping.createTopicMapping(fbb, topicIdOffset, topicHandleOffset), + ) + fbb.finish(outbound) + conn.send(fbb.dataBuffer()) + } + + fun onTopicMessage(c: GenericConnection, messageHeader: PubSubHeader) { + val req = messageHeader.u(Message()) as Message? ?: return + + val messageT = req.unpack() + + var subHandle = 1 + if (messageT.topic.type == Topic.TopicHandle) { + subHandle = messageT.topic.asTopicHandle().id + } else if (messageT.topic.type == Topic.TopicId) { + subHandle = getTopicHandle(messageT.topic.asTopicId()) + } + + assert(subHandle != -1) + + val finalSubHandle = subHandle + + this.api.apiServers.forEach( + Consumer { server: ProtocolAPIServer -> + server.apiConnections.forEach { conn: GenericConnection -> + // Make sure that we are not sending a message to ourselves + // And check that the receiver has subscribed to the topic + if (conn.connectionId != c.connectionId && + conn.context.subscribedTopics + .contains(finalSubHandle) + ) { + val fbb = FlatBufferBuilder(32) + val outbound = createMessage( + fbb, + PubSubUnion.Message, + Message.pack(fbb, messageT), + ) + fbb.finish(outbound) + conn.send(fbb.dataBuffer()) + } + } + }, + ) + } + + override fun onMessage(conn: GenericConnection, message: PubSubHeader) { + val consumer = this.handlers[message.uType().toInt()] + if (consumer != null) { + consumer.accept(conn, message) + } else { + LogManager + .info("[ProtocolAPI] Unhandled PubSub packet received id: " + message.uType()) + } + } + + override fun messagesCount(): Int = PubSubUnion.names.size + + fun createMessage(fbb: FlatBufferBuilder, messageType: Byte, messageOffset: Int): Int { + val data = IntArray(1) + + data[0] = PubSubHeader.createPubSubHeader(fbb, messageType, messageOffset) + + val messages = MessageBundle.createPubSubMsgsVector(fbb, data) + + MessageBundle.startMessageBundle(fbb) + MessageBundle.addPubSubMsgs(fbb, messages) + return MessageBundle.endMessageBundle(fbb) + } +} diff --git a/server/core/src/main/java/dev/slimevr/protocol/rpc/RPCBuilder.java b/server/core/src/main/java/dev/slimevr/protocol/rpc/RPCBuilder.java deleted file mode 100644 index ccbcf948c..000000000 --- a/server/core/src/main/java/dev/slimevr/protocol/rpc/RPCBuilder.java +++ /dev/null @@ -1,28 +0,0 @@ -package dev.slimevr.protocol.rpc; - -import com.google.flatbuffers.FlatBufferBuilder; -import dev.slimevr.tracking.processor.HumanPoseManager; -import dev.slimevr.tracking.processor.config.SkeletonConfigOffsets; -import solarxr_protocol.rpc.SkeletonConfigResponse; -import solarxr_protocol.rpc.SkeletonPart; - - -public class RPCBuilder { - - public static int createSkeletonConfig( - FlatBufferBuilder fbb, - HumanPoseManager humanPoseManager - ) { - int[] partsOffsets = new int[SkeletonConfigOffsets.values().length]; - - for (int index = 0; index < SkeletonConfigOffsets.values().length; index++) { - SkeletonConfigOffsets val = SkeletonConfigOffsets.values[index]; - int part = SkeletonPart - .createSkeletonPart(fbb, val.id, humanPoseManager.getOffset(val)); - partsOffsets[index] = part; - } - - int parts = SkeletonConfigResponse.createSkeletonPartsVector(fbb, partsOffsets); - return SkeletonConfigResponse.createSkeletonConfigResponse(fbb, parts, 0); - } -} diff --git a/server/core/src/main/java/dev/slimevr/protocol/rpc/RPCHandler.kt b/server/core/src/main/java/dev/slimevr/protocol/rpc/RPCHandler.kt index cb246da09..d1c63d76f 100644 --- a/server/core/src/main/java/dev/slimevr/protocol/rpc/RPCHandler.kt +++ b/server/core/src/main/java/dev/slimevr/protocol/rpc/RPCHandler.kt @@ -6,15 +6,15 @@ import dev.slimevr.config.config import dev.slimevr.protocol.GenericConnection import dev.slimevr.protocol.ProtocolAPI import dev.slimevr.protocol.ProtocolHandler -import dev.slimevr.protocol.datafeed.DataFeedBuilder +import dev.slimevr.protocol.datafeed.createTrackerId import dev.slimevr.protocol.rpc.autobone.RPCAutoBoneHandler import dev.slimevr.protocol.rpc.firmware.RPCFirmwareUpdateHandler import dev.slimevr.protocol.rpc.games.vrchat.RPCVRChatHandler import dev.slimevr.protocol.rpc.reset.RPCResetHandler import dev.slimevr.protocol.rpc.serial.RPCProvisioningHandler import dev.slimevr.protocol.rpc.serial.RPCSerialHandler -import dev.slimevr.protocol.rpc.settings.RPCSettingsBuilder import dev.slimevr.protocol.rpc.settings.RPCSettingsHandler +import dev.slimevr.protocol.rpc.settings.createSettingsResponse import dev.slimevr.protocol.rpc.setup.RPCHandshakeHandler import dev.slimevr.protocol.rpc.setup.RPCTapSetupHandler import dev.slimevr.protocol.rpc.setup.RPCUtil.getLocalIp @@ -460,7 +460,7 @@ class RPCHandler(private val api: ProtocolAPI) : ProtocolHandler - if (!conn.context.useAutoBone()) { + if (!conn.context.useAutoBone) { return@forAllListeners } @@ -95,7 +95,7 @@ class RPCAutoBoneHandler( fbb.finish(outbound) conn.send(fbb.dataBuffer()) if (completed) { - conn.context.setUseAutoBone(false) + conn.context.useAutoBone = false } } } @@ -106,7 +106,7 @@ class RPCAutoBoneHandler( override fun onAutoBoneEpoch(epoch: Epoch) { forAllListeners { conn -> - if (!conn.context.useAutoBone()) { + if (!conn.context.useAutoBone) { return@forAllListeners } diff --git a/server/core/src/main/java/dev/slimevr/protocol/rpc/reset/RPCResetHandler.kt b/server/core/src/main/java/dev/slimevr/protocol/rpc/reset/RPCResetHandler.kt index fd9e598ae..6132823f4 100644 --- a/server/core/src/main/java/dev/slimevr/protocol/rpc/reset/RPCResetHandler.kt +++ b/server/core/src/main/java/dev/slimevr/protocol/rpc/reset/RPCResetHandler.kt @@ -108,11 +108,11 @@ class RPCResetHandler(var rpcHandler: RPCHandler, var api: ProtocolAPI) : ResetL fun forAllListeners(action: Consumer?) { this.api - .getAPIServers() + .apiServers .forEach( - Consumer { server: ProtocolAPIServer? -> - server!! - .getAPIConnections() + Consumer { server: ProtocolAPIServer -> + server + .apiConnections .forEach(action) }, ) diff --git a/server/core/src/main/java/dev/slimevr/protocol/rpc/serial/RPCProvisioningHandler.java b/server/core/src/main/java/dev/slimevr/protocol/rpc/serial/RPCProvisioningHandler.java deleted file mode 100644 index 0231e4a00..000000000 --- a/server/core/src/main/java/dev/slimevr/protocol/rpc/serial/RPCProvisioningHandler.java +++ /dev/null @@ -1,87 +0,0 @@ -package dev.slimevr.protocol.rpc.serial; - -import com.google.flatbuffers.FlatBufferBuilder; -import dev.slimevr.protocol.GenericConnection; -import dev.slimevr.protocol.ProtocolAPI; -import dev.slimevr.protocol.rpc.RPCHandler; -import dev.slimevr.serial.ProvisioningListener; -import dev.slimevr.serial.ProvisioningStatus; -import dev.slimevr.serial.SerialPort; -import solarxr_protocol.rpc.*; - -import java.util.function.Consumer; - - -public class RPCProvisioningHandler implements ProvisioningListener { - - public RPCHandler rpcHandler; - public ProtocolAPI api; - - public RPCProvisioningHandler(RPCHandler rpcHandler, ProtocolAPI api) { - this.rpcHandler = rpcHandler; - this.api = api; - - rpcHandler - .registerPacketListener( - RpcMessage.StartWifiProvisioningRequest, - this::onStartWifiProvisioningRequest - ); - rpcHandler - .registerPacketListener( - RpcMessage.StopWifiProvisioningRequest, - this::onStopWifiProvisioningRequest - ); - - this.api.server.provisioningHandler.addListener(this); - } - - public void onStartWifiProvisioningRequest( - GenericConnection conn, - RpcMessageHeader messageHeader - ) { - StartWifiProvisioningRequest req = (StartWifiProvisioningRequest) messageHeader - .message(new StartWifiProvisioningRequest()); - if (req == null) - return; - this.api.server.provisioningHandler.start(req.ssid(), req.password(), req.port()); - conn.getContext().setUseProvisioning(true); - } - - public void onStopWifiProvisioningRequest( - GenericConnection conn, - RpcMessageHeader messageHeader - ) { - StopWifiProvisioningRequest req = (StopWifiProvisioningRequest) messageHeader - .message(new StopWifiProvisioningRequest()); - if (req == null) - return; - conn.getContext().setUseProvisioning(false); - this.api.server.provisioningHandler.stop(); - } - - @Override - public void onProvisioningStatusChange(ProvisioningStatus status, SerialPort port) { - - FlatBufferBuilder fbb = new FlatBufferBuilder(32); - - WifiProvisioningStatusResponse.startWifiProvisioningStatusResponse(fbb); - WifiProvisioningStatusResponse.addStatus(fbb, status.id); - int update = WifiProvisioningStatusResponse.endWifiProvisioningStatusResponse(fbb); - int outbound = rpcHandler - .createRPCMessage(fbb, RpcMessage.WifiProvisioningStatusResponse, update); - fbb.finish(outbound); - - this.forAllListeners((conn) -> conn.send(fbb.dataBuffer())); - } - - private void forAllListeners(Consumer action) { - this.api - .getAPIServers() - .forEach( - (server) -> server - .getAPIConnections() - .filter(conn -> conn.getContext().useProvisioning()) - .forEach(action) - ); - } -} diff --git a/server/core/src/main/java/dev/slimevr/protocol/rpc/serial/RPCProvisioningHandler.kt b/server/core/src/main/java/dev/slimevr/protocol/rpc/serial/RPCProvisioningHandler.kt new file mode 100644 index 000000000..b1cd0387f --- /dev/null +++ b/server/core/src/main/java/dev/slimevr/protocol/rpc/serial/RPCProvisioningHandler.kt @@ -0,0 +1,68 @@ +package dev.slimevr.protocol.rpc.serial + +import com.google.flatbuffers.FlatBufferBuilder +import dev.slimevr.protocol.GenericConnection +import dev.slimevr.protocol.ProtocolAPI +import dev.slimevr.protocol.ProtocolAPIServer +import dev.slimevr.protocol.rpc.RPCHandler +import dev.slimevr.serial.ProvisioningListener +import dev.slimevr.serial.ProvisioningStatus +import dev.slimevr.serial.SerialPort +import solarxr_protocol.rpc.* +import java.util.function.Consumer + +class RPCProvisioningHandler(var rpcHandler: RPCHandler, var api: ProtocolAPI) : ProvisioningListener { + init { + rpcHandler.registerPacketListener(RpcMessage.StartWifiProvisioningRequest, ::onStartWifiProvisioningRequest) + rpcHandler.registerPacketListener(RpcMessage.StopWifiProvisioningRequest, ::onStopWifiProvisioningRequest) + this.api.server.provisioningHandler.addListener(this) + } + + fun onStartWifiProvisioningRequest( + conn: GenericConnection, + messageHeader: RpcMessageHeader, + ) { + val req = messageHeader + .message(StartWifiProvisioningRequest()) as StartWifiProvisioningRequest? + if (req == null) return + this.api.server.provisioningHandler.start(req.ssid(), req.password(), req.port()) + conn.context.useProvisioning = true + } + + fun onStopWifiProvisioningRequest( + conn: GenericConnection, + messageHeader: RpcMessageHeader, + ) { + val req = messageHeader + .message(StopWifiProvisioningRequest()) as StopWifiProvisioningRequest? + if (req == null) return + conn.context.useProvisioning = false + this.api.server.provisioningHandler.stop() + } + + override fun onProvisioningStatusChange(status: ProvisioningStatus, port: SerialPort?) { + val fbb = FlatBufferBuilder(32) + + WifiProvisioningStatusResponse.startWifiProvisioningStatusResponse(fbb) + WifiProvisioningStatusResponse.addStatus(fbb, status.id) + val update = WifiProvisioningStatusResponse.endWifiProvisioningStatusResponse(fbb) + val outbound = rpcHandler + .createRPCMessage(fbb, RpcMessage.WifiProvisioningStatusResponse, update) + fbb.finish(outbound) + + this.forAllListeners(Consumer { conn: GenericConnection -> conn.send(fbb.dataBuffer()) }) + } + + private fun forAllListeners(action: Consumer?) { + this.api + .apiServers + .forEach( + Consumer { server: ProtocolAPIServer -> + server + .apiConnections + .filter { conn: GenericConnection -> conn.context.useProvisioning } + .forEach(action) + }, + ) + } +} diff --git a/server/core/src/main/java/dev/slimevr/protocol/rpc/serial/RPCSerialHandler.java b/server/core/src/main/java/dev/slimevr/protocol/rpc/serial/RPCSerialHandler.java deleted file mode 100644 index 9e7a0ed07..000000000 --- a/server/core/src/main/java/dev/slimevr/protocol/rpc/serial/RPCSerialHandler.java +++ /dev/null @@ -1,303 +0,0 @@ -package dev.slimevr.protocol.rpc.serial; - -import com.google.flatbuffers.FlatBufferBuilder; -import dev.slimevr.protocol.GenericConnection; -import dev.slimevr.protocol.ProtocolAPI; -import dev.slimevr.protocol.rpc.RPCHandler; -import dev.slimevr.serial.SerialListener; -import dev.slimevr.serial.SerialPort; -import io.eiren.util.logging.LogManager; -import org.jetbrains.annotations.NotNull; -import solarxr_protocol.rpc.*; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.function.Consumer; - - -public class RPCSerialHandler implements SerialListener { - - public RPCHandler rpcHandler; - public ProtocolAPI api; - - public RPCSerialHandler(RPCHandler rpcHandler, ProtocolAPI api) { - this.rpcHandler = rpcHandler; - this.api = api; - - rpcHandler - .registerPacketListener( - RpcMessage.SerialTrackerRebootRequest, - this::onSerialTrackerRebootRequest - ); - rpcHandler - .registerPacketListener( - RpcMessage.SerialTrackerGetInfoRequest, - this::onSerialTrackerGetInfoRequest - ); - rpcHandler - .registerPacketListener( - RpcMessage.SerialTrackerFactoryResetRequest, - this::onSerialTrackerFactoryResetRequest - ); - rpcHandler - .registerPacketListener( - RpcMessage.SerialTrackerGetWifiScanRequest, - this::onSerialTrackerGetWifiScanRequest - ); - rpcHandler - .registerPacketListener( - RpcMessage.SerialTrackerCustomCommandRequest, - this::onSerialTrackerCustomCommandRequest - ); - rpcHandler.registerPacketListener(RpcMessage.SetWifiRequest, this::onSetWifiRequest); - rpcHandler.registerPacketListener(RpcMessage.OpenSerialRequest, this::onOpenSerialRequest); - rpcHandler - .registerPacketListener(RpcMessage.CloseSerialRequest, this::onCloseSerialRequest); - rpcHandler - .registerPacketListener(RpcMessage.SerialDevicesRequest, this::onRequestSerialDevices); - this.api.server.serialHandler.addListener(this); - } - - @Override - public void onSerialDisconnected() { - - FlatBufferBuilder fbb = new FlatBufferBuilder(32); - - SerialUpdateResponse.startSerialUpdateResponse(fbb); - SerialUpdateResponse.addClosed(fbb, true); - int update = SerialUpdateResponse.endSerialUpdateResponse(fbb); - int outbound = rpcHandler.createRPCMessage(fbb, RpcMessage.SerialUpdateResponse, update); - fbb.finish(outbound); - - this.forAllListeners((conn) -> { - conn.send(fbb.dataBuffer()); - conn.getContext().setUseSerial(false); - }); - } - - @Override - public void onSerialLog(String str, boolean server) { - FlatBufferBuilder fbb = new FlatBufferBuilder(32); - - int logOffset = fbb.createString(str); - - SerialUpdateResponse.startSerialUpdateResponse(fbb); - SerialUpdateResponse.addLog(fbb, logOffset); - int update = SerialUpdateResponse.endSerialUpdateResponse(fbb); - int outbound = rpcHandler.createRPCMessage(fbb, RpcMessage.SerialUpdateResponse, update); - fbb.finish(outbound); - - this.forAllListeners((conn) -> { - conn.send(fbb.dataBuffer()); - }); - } - - @Override - public void onNewSerialDevice(SerialPort port) { - FlatBufferBuilder fbb = new FlatBufferBuilder(32); - - int portOffset = fbb.createString(port.getPortLocation()); - int nameOffset = fbb.createString(port.getDescriptivePortName()); - int deviceOffset = SerialDevice.createSerialDevice(fbb, portOffset, nameOffset); - int newSerialOffset = NewSerialDeviceResponse - .createNewSerialDeviceResponse(fbb, deviceOffset); - int outbound = rpcHandler - .createRPCMessage(fbb, RpcMessage.NewSerialDeviceResponse, newSerialOffset); - fbb.finish(outbound); - - - this.api - .getAPIServers() - .forEach( - (server) -> server - .getAPIConnections() - .forEach((conn) -> { - conn.send(fbb.dataBuffer()); - }) - ); - } - - @Override - public void onSerialConnected(SerialPort port) { - - FlatBufferBuilder fbb = new FlatBufferBuilder(32); - - SerialUpdateResponse.startSerialUpdateResponse(fbb); - SerialUpdateResponse.addClosed(fbb, false); - int update = SerialUpdateResponse.endSerialUpdateResponse(fbb); - int outbound = rpcHandler.createRPCMessage(fbb, RpcMessage.SerialUpdateResponse, update); - fbb.finish(outbound); - - this.forAllListeners((conn) -> { - conn.send(fbb.dataBuffer()); - }); - } - - public void onSerialTrackerRebootRequest( - GenericConnection conn, - RpcMessageHeader messageHeader - ) { - SerialTrackerRebootRequest req = (SerialTrackerRebootRequest) messageHeader - .message(new SerialTrackerRebootRequest()); - if (req == null) - return; - - this.api.server.serialHandler.rebootRequest(); - } - - public void onSerialTrackerGetInfoRequest( - GenericConnection conn, - RpcMessageHeader messageHeader - ) { - SerialTrackerGetInfoRequest req = (SerialTrackerGetInfoRequest) messageHeader - .message(new SerialTrackerGetInfoRequest()); - if (req == null) - return; - - this.api.server.serialHandler.infoRequest(); - } - - public void onSerialTrackerFactoryResetRequest( - GenericConnection conn, - RpcMessageHeader messageHeader - ) { - SerialTrackerFactoryResetRequest req = (SerialTrackerFactoryResetRequest) messageHeader - .message(new SerialTrackerFactoryResetRequest()); - if (req == null) - return; - - this.api.server.serialHandler.factoryResetRequest(); - } - - public void onSerialTrackerGetWifiScanRequest( - GenericConnection conn, - RpcMessageHeader messageHeader - ) { - SerialTrackerGetWifiScanRequest req = (SerialTrackerGetWifiScanRequest) messageHeader - .message(new SerialTrackerGetWifiScanRequest()); - if (req == null) - return; - - this.api.server.serialHandler.wifiScanRequest(); - } - - public void onSerialTrackerCustomCommandRequest( - GenericConnection conn, - RpcMessageHeader messageHeader - ) { - SerialTrackerCustomCommandRequest req = (SerialTrackerCustomCommandRequest) messageHeader - .message(new SerialTrackerCustomCommandRequest()); - - if (req == null || req.command() == null) - return; - - this.api.server.serialHandler.customCommandRequest(Objects.requireNonNull(req.command())); - } - - private void onRequestSerialDevices(GenericConnection conn, RpcMessageHeader messageHeader) { - SerialDevicesRequest req = (SerialDevicesRequest) messageHeader - .message(new SerialDevicesRequest()); - if (req == null) - return; - - FlatBufferBuilder fbb = new FlatBufferBuilder(32); - - - List devicesOffsets = new ArrayList<>(); - - try { - this.api.server.serialHandler.getKnownPorts().forEach((port) -> { - int portOffset = fbb.createString(port.getPortLocation()); - int nameOffset = fbb.createString(port.getDescriptivePortName()); - devicesOffsets.add(SerialDevice.createSerialDevice(fbb, portOffset, nameOffset)); - }); - } catch (Throwable e) { - LogManager.severe("Using serial ports is not supported on this platform", e); - } - - SerialDevicesResponse.startDevicesVector(fbb, devicesOffsets.size()); - devicesOffsets.forEach(offset -> SerialDevicesResponse.addDevices(fbb, offset)); - int devices = fbb.endVector(); - int serialDeviceOffsets = SerialDevicesResponse.createSerialDevicesResponse(fbb, devices); - int outbound = rpcHandler - .createRPCMessage(fbb, RpcMessage.SerialDevicesResponse, serialDeviceOffsets); - fbb.finish(outbound); - conn.send(fbb.dataBuffer()); - } - - public void onSetWifiRequest(GenericConnection conn, RpcMessageHeader messageHeader) { - SetWifiRequest req = (SetWifiRequest) messageHeader.message(new SetWifiRequest()); - if (req == null) - return; - - if ( - req.password() == null - || req.ssid() == null - || !this.api.server.serialHandler.isConnected() - ) - return; - this.api.server.serialHandler.setWifi(req.ssid(), req.password()); - } - - public void onOpenSerialRequest(GenericConnection conn, RpcMessageHeader messageHeader) { - OpenSerialRequest req = (OpenSerialRequest) messageHeader.message(new OpenSerialRequest()); - if (req == null) - return; - - conn.getContext().setUseSerial(true); - - this.api.server.queueTask(() -> { - try { - this.api.server.serialHandler.openSerial(req.port(), req.auto()); - } catch (Exception e) { - LogManager.severe("Unable to open serial port", e); - } catch (Throwable e) { - LogManager.severe("Using serial ports is not supported on this platform", e); - } - - FlatBufferBuilder fbb = new FlatBufferBuilder(32); - SerialUpdateResponse.startSerialUpdateResponse(fbb); - SerialUpdateResponse.addClosed(fbb, !this.api.server.serialHandler.isConnected()); - int update = SerialUpdateResponse.endSerialUpdateResponse(fbb); - int outbound = rpcHandler - .createRPCMessage(fbb, RpcMessage.SerialUpdateResponse, update); - fbb.finish(outbound); - conn.send(fbb.dataBuffer()); - }); - } - - public void onCloseSerialRequest(GenericConnection conn, RpcMessageHeader messageHeader) { - CloseSerialRequest req = (CloseSerialRequest) messageHeader - .message(new CloseSerialRequest()); - if (req == null) - return; - - conn.getContext().setUseSerial(false); - - this.api.server.serialHandler.closeSerial(); - - FlatBufferBuilder fbb = new FlatBufferBuilder(32); - SerialUpdateResponse.startSerialUpdateResponse(fbb); - SerialUpdateResponse.addClosed(fbb, !this.api.server.serialHandler.isConnected()); - int update = SerialUpdateResponse.endSerialUpdateResponse(fbb); - int outbound = rpcHandler.createRPCMessage(fbb, RpcMessage.SerialUpdateResponse, update); - fbb.finish(outbound); - conn.send(fbb.dataBuffer()); - } - - public void forAllListeners(Consumer action) { - this.api - .getAPIServers() - .forEach( - (server) -> server - .getAPIConnections() - .filter(conn -> conn.getContext().useSerial()) - .forEach(action) - ); - } - - @Override - public void onSerialDeviceDeleted(@NotNull SerialPort port) { - } -} diff --git a/server/core/src/main/java/dev/slimevr/protocol/rpc/serial/RPCSerialHandler.kt b/server/core/src/main/java/dev/slimevr/protocol/rpc/serial/RPCSerialHandler.kt new file mode 100644 index 000000000..e621390af --- /dev/null +++ b/server/core/src/main/java/dev/slimevr/protocol/rpc/serial/RPCSerialHandler.kt @@ -0,0 +1,263 @@ +package dev.slimevr.protocol.rpc.serial + +import com.google.flatbuffers.FlatBufferBuilder +import dev.slimevr.protocol.GenericConnection +import dev.slimevr.protocol.ProtocolAPI +import dev.slimevr.protocol.ProtocolAPIServer +import dev.slimevr.protocol.rpc.RPCHandler +import dev.slimevr.serial.SerialListener +import dev.slimevr.serial.SerialPort +import io.eiren.util.logging.LogManager +import solarxr_protocol.rpc.* +import java.util.* +import java.util.function.Consumer + +class RPCSerialHandler(var rpcHandler: RPCHandler, var api: ProtocolAPI) : SerialListener { + init { + rpcHandler.registerPacketListener(RpcMessage.SerialTrackerRebootRequest, ::onSerialTrackerRebootRequest) + rpcHandler.registerPacketListener(RpcMessage.SerialTrackerGetInfoRequest, ::onSerialTrackerGetInfoRequest) + rpcHandler.registerPacketListener(RpcMessage.SerialTrackerFactoryResetRequest, ::onSerialTrackerFactoryResetRequest) + rpcHandler.registerPacketListener(RpcMessage.SerialTrackerGetWifiScanRequest, ::onSerialTrackerGetWifiScanRequest) + rpcHandler.registerPacketListener(RpcMessage.SerialTrackerCustomCommandRequest, ::onSerialTrackerCustomCommandRequest) + rpcHandler.registerPacketListener(RpcMessage.SetWifiRequest, ::onSetWifiRequest) + rpcHandler.registerPacketListener(RpcMessage.OpenSerialRequest, ::onOpenSerialRequest) + rpcHandler.registerPacketListener(RpcMessage.CloseSerialRequest, ::onCloseSerialRequest) + rpcHandler.registerPacketListener(RpcMessage.SerialDevicesRequest, ::onRequestSerialDevices) + this.api.server.serialHandler.addListener(this) + } + + override fun onSerialDisconnected() { + val fbb = FlatBufferBuilder(32) + + SerialUpdateResponse.startSerialUpdateResponse(fbb) + SerialUpdateResponse.addClosed(fbb, true) + val update = SerialUpdateResponse.endSerialUpdateResponse(fbb) + val outbound = rpcHandler.createRPCMessage(fbb, RpcMessage.SerialUpdateResponse, update) + fbb.finish(outbound) + + this.forAllListeners( + Consumer { conn: GenericConnection -> + conn.send(fbb.dataBuffer()) + conn.context.useSerial = false + }, + ) + } + + override fun onSerialLog(str: String, server: Boolean) { + val fbb = FlatBufferBuilder(32) + + val logOffset = fbb.createString(str) + + SerialUpdateResponse.startSerialUpdateResponse(fbb) + SerialUpdateResponse.addLog(fbb, logOffset) + val update = SerialUpdateResponse.endSerialUpdateResponse(fbb) + val outbound = rpcHandler.createRPCMessage(fbb, RpcMessage.SerialUpdateResponse, update) + fbb.finish(outbound) + + this.forAllListeners( + Consumer { conn: GenericConnection -> + conn.send(fbb.dataBuffer()) + }, + ) + } + + override fun onNewSerialDevice(port: SerialPort) { + val fbb = FlatBufferBuilder(32) + + val portOffset = fbb.createString(port.portLocation) + val nameOffset = fbb.createString(port.descriptivePortName) + val deviceOffset = SerialDevice.createSerialDevice(fbb, portOffset, nameOffset) + val newSerialOffset = NewSerialDeviceResponse + .createNewSerialDeviceResponse(fbb, deviceOffset) + val outbound = rpcHandler + .createRPCMessage(fbb, RpcMessage.NewSerialDeviceResponse, newSerialOffset) + fbb.finish(outbound) + + this.api + .apiServers + .forEach( + Consumer { server: ProtocolAPIServer -> + server + .apiConnections + .forEach { conn: GenericConnection -> + conn.send(fbb.dataBuffer()) + } + }, + ) + } + + override fun onSerialConnected(port: SerialPort) { + val fbb = FlatBufferBuilder(32) + + SerialUpdateResponse.startSerialUpdateResponse(fbb) + SerialUpdateResponse.addClosed(fbb, false) + val update = SerialUpdateResponse.endSerialUpdateResponse(fbb) + val outbound = rpcHandler.createRPCMessage(fbb, RpcMessage.SerialUpdateResponse, update) + fbb.finish(outbound) + + this.forAllListeners( + Consumer { conn: GenericConnection -> + conn.send(fbb.dataBuffer()) + }, + ) + } + + fun onSerialTrackerRebootRequest( + conn: GenericConnection, + messageHeader: RpcMessageHeader, + ) { + val req = messageHeader + .message(SerialTrackerRebootRequest()) as SerialTrackerRebootRequest? + if (req == null) return + + this.api.server.serialHandler.rebootRequest() + } + + fun onSerialTrackerGetInfoRequest( + conn: GenericConnection, + messageHeader: RpcMessageHeader, + ) { + val req = messageHeader + .message(SerialTrackerGetInfoRequest()) as SerialTrackerGetInfoRequest? + if (req == null) return + + this.api.server.serialHandler.infoRequest() + } + + fun onSerialTrackerFactoryResetRequest( + conn: GenericConnection, + messageHeader: RpcMessageHeader, + ) { + val req = messageHeader + .message(SerialTrackerFactoryResetRequest()) as SerialTrackerFactoryResetRequest? + if (req == null) return + + this.api.server.serialHandler.factoryResetRequest() + } + + fun onSerialTrackerGetWifiScanRequest( + conn: GenericConnection, + messageHeader: RpcMessageHeader, + ) { + val req = messageHeader + .message(SerialTrackerGetWifiScanRequest()) as SerialTrackerGetWifiScanRequest? + if (req == null) return + + this.api.server.serialHandler.wifiScanRequest() + } + + fun onSerialTrackerCustomCommandRequest( + conn: GenericConnection, + messageHeader: RpcMessageHeader, + ) { + val req = messageHeader + .message(SerialTrackerCustomCommandRequest()) as SerialTrackerCustomCommandRequest? + + if (req == null || req.command() == null) return + + this.api.server.serialHandler.customCommandRequest(Objects.requireNonNull(req.command())) + } + + private fun onRequestSerialDevices(conn: GenericConnection, messageHeader: RpcMessageHeader) { + val req = messageHeader + .message(SerialDevicesRequest()) as SerialDevicesRequest? + if (req == null) return + + val fbb = FlatBufferBuilder(32) + + val devicesOffsets: MutableList = ArrayList() + + try { + this.api.server.serialHandler.knownPorts.forEach { port: SerialPort -> + val portOffset = fbb.createString(port.portLocation) + val nameOffset = fbb.createString(port.descriptivePortName) + devicesOffsets.add(SerialDevice.createSerialDevice(fbb, portOffset, nameOffset)) + } + } catch (e: Throwable) { + LogManager.severe("Using serial ports is not supported on this platform", e) + } + + SerialDevicesResponse.startDevicesVector(fbb, devicesOffsets.size) + devicesOffsets.forEach(Consumer { offset: Int -> SerialDevicesResponse.addDevices(fbb, offset) }) + val devices = fbb.endVector() + val serialDeviceOffsets = SerialDevicesResponse.createSerialDevicesResponse(fbb, devices) + val outbound = rpcHandler + .createRPCMessage(fbb, RpcMessage.SerialDevicesResponse, serialDeviceOffsets) + fbb.finish(outbound) + conn.send(fbb.dataBuffer()) + } + + fun onSetWifiRequest(conn: GenericConnection, messageHeader: RpcMessageHeader) { + val req = messageHeader.message(SetWifiRequest()) as SetWifiRequest? ?: return + + if (req.password() == null || req.ssid() == null || !this.api.server.serialHandler.isConnected) { + return + } + this.api.server.serialHandler.setWifi(req.ssid(), req.password()) + } + + fun onOpenSerialRequest(conn: GenericConnection, messageHeader: RpcMessageHeader) { + val req = + messageHeader.message(OpenSerialRequest()) as OpenSerialRequest? ?: return + + conn.context.useSerial = true + + this.api.server.queueTask { + try { + this.api.server.serialHandler.openSerial(req.port(), req.auto()) + } catch (e: Exception) { + LogManager.severe("Unable to open serial port", e) + } catch (e: Throwable) { + LogManager.severe( + "Using serial ports is not supported on this platform", + e, + ) + } + val fbb = FlatBufferBuilder(32) + SerialUpdateResponse.startSerialUpdateResponse(fbb) + SerialUpdateResponse.addClosed( + fbb, + !this.api.server.serialHandler.isConnected, + ) + val update = SerialUpdateResponse.endSerialUpdateResponse(fbb) + val outbound = rpcHandler + .createRPCMessage(fbb, RpcMessage.SerialUpdateResponse, update) + fbb.finish(outbound) + conn.send(fbb.dataBuffer()) + } + } + + fun onCloseSerialRequest(conn: GenericConnection, messageHeader: RpcMessageHeader) { + val req = messageHeader + .message(CloseSerialRequest()) as CloseSerialRequest? + if (req == null) return + + conn.context.useSerial = false + + this.api.server.serialHandler.closeSerial() + + val fbb = FlatBufferBuilder(32) + SerialUpdateResponse.startSerialUpdateResponse(fbb) + SerialUpdateResponse.addClosed(fbb, !this.api.server.serialHandler.isConnected) + val update = SerialUpdateResponse.endSerialUpdateResponse(fbb) + val outbound = rpcHandler.createRPCMessage(fbb, RpcMessage.SerialUpdateResponse, update) + fbb.finish(outbound) + conn.send(fbb.dataBuffer()) + } + + fun forAllListeners(action: Consumer?) { + this.api + .apiServers + .forEach( + Consumer { server: ProtocolAPIServer -> + server + .apiConnections + .filter { conn: GenericConnection -> conn.context.useSerial } + .forEach(action) + }, + ) + } + + override fun onSerialDeviceDeleted(port: SerialPort) { + } +} diff --git a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilder.java b/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilder.java deleted file mode 100644 index a06870e9f..000000000 --- a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilder.java +++ /dev/null @@ -1,423 +0,0 @@ -package dev.slimevr.protocol.rpc.settings; - -import com.google.flatbuffers.FlatBufferBuilder; -import dev.slimevr.VRServer; -import dev.slimevr.bridge.ISteamVRBridge; -import dev.slimevr.config.*; -import dev.slimevr.filtering.TrackerFilters; -import dev.slimevr.tracking.processor.HumanPoseManager; -import dev.slimevr.tracking.processor.config.SkeletonConfigToggles; -import dev.slimevr.tracking.processor.config.SkeletonConfigValues; -import dev.slimevr.tracking.trackers.TrackerRole; -import solarxr_protocol.rpc.*; -import solarxr_protocol.rpc.settings.*; - - -public class RPCSettingsBuilder { - - public static int createOSCRouterSettings( - FlatBufferBuilder fbb, - OSCConfig config - ) { - int addressStringOffset = fbb.createString(config.getAddress()); - - int oscSettingOffset = OSCSettings - .createOSCSettings( - fbb, - config.getEnabled(), - config.getPortIn(), - config.getPortOut(), - addressStringOffset - ); - - OSCRouterSettings.startOSCRouterSettings(fbb); - OSCRouterSettings.addOscSettings(fbb, oscSettingOffset); - - return OSCRouterSettings.endOSCRouterSettings(fbb); - } - - public static int createVRCOSCSettings( - FlatBufferBuilder fbb, - VRCOSCConfig config - ) { - int addressStringOffset = fbb.createString(config.getAddress()); - int generalSettingOffset = OSCSettings - .createOSCSettings( - fbb, - config.getEnabled(), - config.getPortIn(), - config.getPortOut(), - addressStringOffset - ); - int oscSettingOffset = OSCTrackersSetting - .createOSCTrackersSetting( - fbb, - config.getOSCTrackerRole(TrackerRole.HEAD, false), - config.getOSCTrackerRole(TrackerRole.CHEST, false), - config.getOSCTrackerRole(TrackerRole.WAIST, false), - config.getOSCTrackerRole(TrackerRole.LEFT_KNEE, false) - && config.getOSCTrackerRole(TrackerRole.RIGHT_KNEE, false), - config.getOSCTrackerRole(TrackerRole.LEFT_FOOT, false) - && config.getOSCTrackerRole(TrackerRole.RIGHT_FOOT, false), - config.getOSCTrackerRole(TrackerRole.LEFT_ELBOW, false) - && config.getOSCTrackerRole(TrackerRole.RIGHT_ELBOW, false), - config.getOSCTrackerRole(TrackerRole.LEFT_HAND, false) - && config.getOSCTrackerRole(TrackerRole.RIGHT_HAND, false) - ); - VRCOSCSettings.startVRCOSCSettings(fbb); - VRCOSCSettings.addOscSettings(fbb, generalSettingOffset); - VRCOSCSettings.addTrackers(fbb, oscSettingOffset); - VRCOSCSettings.addOscqueryEnabled(fbb, config.getOscqueryEnabled()); - - return VRCOSCSettings.endVRCOSCSettings(fbb); - } - - public static int createVMCOSCSettings( - FlatBufferBuilder fbb, - VMCConfig config - ) { - int addressStringOffset = fbb.createString(config.getAddress()); - int generalSettingOffset = OSCSettings - .createOSCSettings( - fbb, - config.getEnabled(), - config.getPortIn(), - config.getPortOut(), - addressStringOffset - ); - - String vrmJson = config.getVrmJson(); - int vrmJsonOffset = 0; - if (vrmJson != null) - vrmJsonOffset = fbb.createString(vrmJson); - - VMCOSCSettings.startVMCOSCSettings(fbb); - VMCOSCSettings.addOscSettings(fbb, generalSettingOffset); - if (vrmJson != null) - VMCOSCSettings.addVrmJson(fbb, vrmJsonOffset); - VMCOSCSettings.addAnchorHip(fbb, config.getAnchorHip()); - VMCOSCSettings.addMirrorTracking(fbb, config.getMirrorTracking()); - - return VMCOSCSettings.endVMCOSCSettings(fbb); - } - - public static int createFilterSettings( - FlatBufferBuilder fbb, - FiltersConfig filtersConfig - ) { - return FilteringSettings - .createFilteringSettings( - fbb, - TrackerFilters.getByConfigkey(filtersConfig.getType()).getId(), - filtersConfig.getAmount() - ); - } - - public static int createDriftCompensationSettings( - FlatBufferBuilder fbb, - DriftCompensationConfig driftCompensationConfig - ) { - return DriftCompensationSettings - .createDriftCompensationSettings( - fbb, - driftCompensationConfig.getEnabled(), - driftCompensationConfig.getPrediction(), - driftCompensationConfig.getAmount(), - driftCompensationConfig.getMaxResets() - ); - } - - public static int createTapDetectionSettings( - FlatBufferBuilder fbb, - TapDetectionConfig tapDetectionConfig - ) { - return TapDetectionSettings - .createTapDetectionSettings( - fbb, - tapDetectionConfig.getFullResetDelay(), - tapDetectionConfig.getFullResetEnabled(), - tapDetectionConfig.getFullResetTaps(), - tapDetectionConfig.getYawResetDelay(), - tapDetectionConfig.getYawResetEnabled(), - tapDetectionConfig.getYawResetTaps(), - tapDetectionConfig.getMountingResetDelay(), - tapDetectionConfig.getMountingResetEnabled(), - tapDetectionConfig.getMountingResetTaps(), - tapDetectionConfig.getSetupMode(), - tapDetectionConfig.getNumberTrackersOverThreshold() - ); - } - - public static int createSteamVRSettings(FlatBufferBuilder fbb, ISteamVRBridge bridge) { - int steamvrTrackerSettings = 0; - if (bridge != null) { - steamvrTrackerSettings = SteamVRTrackersSetting - .createSteamVRTrackersSetting( - fbb, - bridge.getShareSetting(TrackerRole.WAIST), - bridge.getShareSetting(TrackerRole.CHEST), - bridge.getAutomaticSharedTrackers(), - - bridge.getShareSetting(TrackerRole.LEFT_FOOT), - bridge.getShareSetting(TrackerRole.RIGHT_FOOT), - bridge.getShareSetting(TrackerRole.LEFT_KNEE), - bridge.getShareSetting(TrackerRole.RIGHT_KNEE), - bridge.getShareSetting(TrackerRole.LEFT_ELBOW), - bridge.getShareSetting(TrackerRole.RIGHT_ELBOW), - bridge.getShareSetting(TrackerRole.LEFT_HAND), - bridge.getShareSetting(TrackerRole.RIGHT_HAND) - ); - } - return steamvrTrackerSettings; - } - - public static int createModelSettings( - FlatBufferBuilder fbb, - HumanPoseManager humanPoseManager, - LegTweaksConfig legTweaksConfig, - SkeletonConfig skeletonConfig - ) { - int togglesOffset = ModelToggles - .createModelToggles( - fbb, - humanPoseManager.getToggle(SkeletonConfigToggles.EXTENDED_SPINE_MODEL), - humanPoseManager.getToggle(SkeletonConfigToggles.EXTENDED_PELVIS_MODEL), - humanPoseManager.getToggle(SkeletonConfigToggles.EXTENDED_KNEE_MODEL), - humanPoseManager.getToggle(SkeletonConfigToggles.FORCE_ARMS_FROM_HMD), - humanPoseManager.getToggle(SkeletonConfigToggles.FLOOR_CLIP), - humanPoseManager.getToggle(SkeletonConfigToggles.SKATING_CORRECTION), - humanPoseManager.getToggle(SkeletonConfigToggles.TOE_SNAP), - humanPoseManager.getToggle(SkeletonConfigToggles.FOOT_PLANT), - humanPoseManager.getToggle(SkeletonConfigToggles.SELF_LOCALIZATION), - humanPoseManager.getToggle(SkeletonConfigToggles.USE_POSITION), - humanPoseManager.getToggle(SkeletonConfigToggles.ENFORCE_CONSTRAINTS), - humanPoseManager.getToggle(SkeletonConfigToggles.CORRECT_CONSTRAINTS) - ); - int ratiosOffset = ModelRatios - .createModelRatios( - fbb, - humanPoseManager.getValue(SkeletonConfigValues.WAIST_FROM_CHEST_HIP_AVERAGING), - humanPoseManager.getValue(SkeletonConfigValues.WAIST_FROM_CHEST_LEGS_AVERAGING), - humanPoseManager.getValue(SkeletonConfigValues.HIP_FROM_CHEST_LEGS_AVERAGING), - humanPoseManager.getValue(SkeletonConfigValues.HIP_FROM_WAIST_LEGS_AVERAGING), - humanPoseManager.getValue(SkeletonConfigValues.HIP_LEGS_AVERAGING), - humanPoseManager.getValue(SkeletonConfigValues.KNEE_TRACKER_ANKLE_AVERAGING), - humanPoseManager.getValue(SkeletonConfigValues.KNEE_ANKLE_AVERAGING) - ); - int legTweaksOffset = LegTweaksSettings - .createLegTweaksSettings( - fbb, - legTweaksConfig.getCorrectionStrength() - ); - int skeletonConfigOffset = SkeletonHeight - .createSkeletonHeight( - fbb, - skeletonConfig.getHmdHeight(), - skeletonConfig.getFloorHeight() - ); - return ModelSettings - .createModelSettings( - fbb, - togglesOffset, - ratiosOffset, - legTweaksOffset, - skeletonConfigOffset - ); - } - - public static int createAutoBoneSettings(FlatBufferBuilder fbb, AutoBoneConfig autoBoneConfig) { - return AutoBoneSettings - .createAutoBoneSettings( - fbb, - autoBoneConfig.getCursorIncrement(), - autoBoneConfig.getMinDataDistance(), - autoBoneConfig.getMaxDataDistance(), - autoBoneConfig.getNumEpochs(), - autoBoneConfig.getPrintEveryNumEpochs(), - autoBoneConfig.getInitialAdjustRate(), - autoBoneConfig.getAdjustRateDecay(), - autoBoneConfig.getSlideErrorFactor(), - autoBoneConfig.getOffsetSlideErrorFactor(), - autoBoneConfig.getFootHeightOffsetErrorFactor(), - autoBoneConfig.getBodyProportionErrorFactor(), - autoBoneConfig.getHeightErrorFactor(), - autoBoneConfig.getPositionErrorFactor(), - autoBoneConfig.getPositionOffsetErrorFactor(), - autoBoneConfig.getCalcInitError(), - autoBoneConfig.getRandomizeFrameOrder(), - autoBoneConfig.getScaleEachStep(), - autoBoneConfig.getSampleCount(), - autoBoneConfig.getSampleRateMs(), - autoBoneConfig.getSaveRecordings(), - autoBoneConfig.getUseSkeletonHeight(), - autoBoneConfig.getRandSeed() - ); - } - - - /** - * Writes values from AutoBoneSettings to an AutoBoneConfig. - * - * @param autoBoneSettings The settings to read from. - * @param autoBoneConfig The config to write to. - * @return The autoBoneConfig parameter. - */ - public static AutoBoneConfig readAutoBoneSettings( - AutoBoneSettings autoBoneSettings, - AutoBoneConfig autoBoneConfig - ) { - if (autoBoneSettings.hasCursorIncrement()) { - autoBoneConfig.setCursorIncrement(autoBoneSettings.cursorIncrement()); - } - if (autoBoneSettings.hasMinDataDistance()) { - autoBoneConfig.setMinDataDistance(autoBoneSettings.minDataDistance()); - } - if (autoBoneSettings.hasMaxDataDistance()) { - autoBoneConfig.setMaxDataDistance(autoBoneSettings.maxDataDistance()); - } - if (autoBoneSettings.hasNumEpochs()) { - autoBoneConfig.setNumEpochs(autoBoneSettings.numEpochs()); - } - if (autoBoneSettings.hasPrintEveryNumEpochs()) { - autoBoneConfig.setPrintEveryNumEpochs(autoBoneSettings.printEveryNumEpochs()); - } - if (autoBoneSettings.hasInitialAdjustRate()) { - autoBoneConfig.setInitialAdjustRate(autoBoneSettings.initialAdjustRate()); - } - if (autoBoneSettings.hasAdjustRateDecay()) { - autoBoneConfig.setAdjustRateDecay(autoBoneSettings.adjustRateDecay()); - } - if (autoBoneSettings.hasSlideErrorFactor()) { - autoBoneConfig.setSlideErrorFactor(autoBoneSettings.slideErrorFactor()); - } - if (autoBoneSettings.hasOffsetSlideErrorFactor()) { - autoBoneConfig.setOffsetSlideErrorFactor(autoBoneSettings.offsetSlideErrorFactor()); - } - if (autoBoneSettings.hasFootHeightOffsetErrorFactor()) { - autoBoneConfig - .setFootHeightOffsetErrorFactor(autoBoneSettings.footHeightOffsetErrorFactor()); - } - if (autoBoneSettings.hasBodyProportionErrorFactor()) { - autoBoneConfig - .setBodyProportionErrorFactor(autoBoneSettings.bodyProportionErrorFactor()); - } - if (autoBoneSettings.hasHeightErrorFactor()) { - autoBoneConfig.setHeightErrorFactor(autoBoneSettings.heightErrorFactor()); - } - if (autoBoneSettings.hasPositionErrorFactor()) { - autoBoneConfig.setPositionErrorFactor(autoBoneSettings.positionErrorFactor()); - } - if (autoBoneSettings.hasPositionOffsetErrorFactor()) { - autoBoneConfig - .setPositionOffsetErrorFactor(autoBoneSettings.positionOffsetErrorFactor()); - } - if (autoBoneSettings.hasCalcInitError()) { - autoBoneConfig.setCalcInitError(autoBoneSettings.calcInitError()); - } - if (autoBoneSettings.hasRandomizeFrameOrder()) { - autoBoneConfig.setRandomizeFrameOrder(autoBoneSettings.randomizeFrameOrder()); - } - if (autoBoneSettings.hasScaleEachStep()) { - autoBoneConfig.setScaleEachStep(autoBoneSettings.scaleEachStep()); - } - if (autoBoneSettings.hasSampleCount()) { - autoBoneConfig.setSampleCount(autoBoneSettings.sampleCount()); - } - if (autoBoneSettings.hasSampleRateMs()) { - autoBoneConfig.setSampleRateMs(autoBoneSettings.sampleRateMs()); - } - if (autoBoneSettings.hasSaveRecordings()) { - autoBoneConfig.setSaveRecordings(autoBoneSettings.saveRecordings()); - } - if (autoBoneSettings.hasUseSkeletonHeight()) { - autoBoneConfig.setUseSkeletonHeight(autoBoneSettings.useSkeletonHeight()); - } - if (autoBoneSettings.hasRandSeed()) { - autoBoneConfig.setRandSeed(autoBoneSettings.randSeed()); - } - - return autoBoneConfig; - } - - public static int createArmsResetModeSettings( - FlatBufferBuilder fbb, - ResetsConfig resetsConfig - ) { - return ResetsSettings - .createResetsSettings( - fbb, - resetsConfig.getResetMountingFeet(), - resetsConfig.getMode().getId(), - resetsConfig.getYawResetSmoothTime(), - resetsConfig.getSaveMountingReset(), - resetsConfig.getResetHmdPitch() - ); - } - - public static int createSettingsResponse(FlatBufferBuilder fbb, VRServer server) { - ISteamVRBridge bridge = server.getVRBridge(ISteamVRBridge.class); - - return SettingsResponse - .createSettingsResponse( - fbb, - RPCSettingsBuilder.createSteamVRSettings(fbb, bridge), - RPCSettingsBuilder - .createFilterSettings( - fbb, - server.configManager.getVrConfig().getFilters() - ), - RPCSettingsBuilder - .createDriftCompensationSettings( - fbb, - server.configManager.getVrConfig().getDriftCompensation() - ), - RPCSettingsBuilder - .createOSCRouterSettings( - fbb, - server.configManager.getVrConfig().getOscRouter() - ), - RPCSettingsBuilder - .createVRCOSCSettings( - fbb, - server.configManager.getVrConfig().getVrcOSC() - ), - RPCSettingsBuilder - .createVMCOSCSettings( - fbb, - server.configManager.getVrConfig().getVMC() - ), - RPCSettingsBuilder - .createModelSettings( - fbb, - server.humanPoseManager, - server.configManager.getVrConfig().getLegTweaks(), - server.configManager.getVrConfig().getSkeleton() - ), - RPCSettingsBuilder - .createTapDetectionSettings( - fbb, - server.configManager.getVrConfig().getTapDetection() - ), - RPCSettingsBuilder - .createAutoBoneSettings( - fbb, - server.configManager.getVrConfig().getAutoBone() - ), - RPCSettingsBuilder - .createArmsResetModeSettings( - fbb, - server.configManager.getVrConfig().getResetsConfig() - ), - RPCSettingsBuilderKotlin.INSTANCE - .createStayAlignedSettings( - fbb, - server.configManager.getVrConfig().getStayAlignedConfig() - ), - RPCSettingsBuilderKotlin.INSTANCE - .createHIDSettings( - fbb, - server.configManager.getVrConfig().getHidConfig() - ) - ); - } -} diff --git a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilder.kt b/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilder.kt new file mode 100644 index 000000000..a933bf193 --- /dev/null +++ b/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilder.kt @@ -0,0 +1,458 @@ +package dev.slimevr.protocol.rpc.settings + +import com.google.flatbuffers.FlatBufferBuilder +import dev.slimevr.VRServer +import dev.slimevr.bridge.ISteamVRBridge +import dev.slimevr.config.AutoBoneConfig +import dev.slimevr.config.DriftCompensationConfig +import dev.slimevr.config.FiltersConfig +import dev.slimevr.config.HIDConfig +import dev.slimevr.config.LegTweaksConfig +import dev.slimevr.config.OSCConfig +import dev.slimevr.config.ResetsConfig +import dev.slimevr.config.SkeletonConfig +import dev.slimevr.config.StayAlignedConfig +import dev.slimevr.config.TapDetectionConfig +import dev.slimevr.config.VMCConfig +import dev.slimevr.config.VRCOSCConfig +import dev.slimevr.filtering.TrackerFilters.Companion.getByConfigkey +import dev.slimevr.tracking.processor.HumanPoseManager +import dev.slimevr.tracking.processor.config.SkeletonConfigToggles +import dev.slimevr.tracking.processor.config.SkeletonConfigValues +import dev.slimevr.tracking.trackers.TrackerRole +import solarxr_protocol.rpc.AutoBoneSettings +import solarxr_protocol.rpc.DriftCompensationSettings +import solarxr_protocol.rpc.FilteringSettings +import solarxr_protocol.rpc.HIDSettings +import solarxr_protocol.rpc.OSCRouterSettings +import solarxr_protocol.rpc.OSCSettings +import solarxr_protocol.rpc.OSCTrackersSetting +import solarxr_protocol.rpc.ResetsSettings +import solarxr_protocol.rpc.SettingsResponse +import solarxr_protocol.rpc.StayAlignedSettings +import solarxr_protocol.rpc.SteamVRTrackersSetting +import solarxr_protocol.rpc.TapDetectionSettings +import solarxr_protocol.rpc.VMCOSCSettings +import solarxr_protocol.rpc.VRCOSCSettings +import solarxr_protocol.rpc.settings.LegTweaksSettings +import solarxr_protocol.rpc.settings.ModelRatios +import solarxr_protocol.rpc.settings.ModelSettings +import solarxr_protocol.rpc.settings.ModelToggles +import solarxr_protocol.rpc.settings.SkeletonHeight + +fun createOSCRouterSettings( + fbb: FlatBufferBuilder, + config: OSCConfig, +): Int { + val addressStringOffset = fbb.createString(config.address) + + val oscSettingOffset = OSCSettings + .createOSCSettings( + fbb, + config.enabled, + config.portIn, + config.portOut, + addressStringOffset, + ) + + OSCRouterSettings.startOSCRouterSettings(fbb) + OSCRouterSettings.addOscSettings(fbb, oscSettingOffset) + + return OSCRouterSettings.endOSCRouterSettings(fbb) +} + +fun createVRCOSCSettings( + fbb: FlatBufferBuilder, + config: VRCOSCConfig, +): Int { + val addressStringOffset = fbb.createString(config.address) + val generalSettingOffset = OSCSettings + .createOSCSettings( + fbb, + config.enabled, + config.portIn, + config.portOut, + addressStringOffset, + ) + val oscSettingOffset = OSCTrackersSetting + .createOSCTrackersSetting( + fbb, + config.getOSCTrackerRole(TrackerRole.HEAD, false), + config.getOSCTrackerRole(TrackerRole.CHEST, false), + config.getOSCTrackerRole(TrackerRole.WAIST, false), + config.getOSCTrackerRole(TrackerRole.LEFT_KNEE, false) && + config.getOSCTrackerRole(TrackerRole.RIGHT_KNEE, false), + config.getOSCTrackerRole(TrackerRole.LEFT_FOOT, false) && + config.getOSCTrackerRole(TrackerRole.RIGHT_FOOT, false), + config.getOSCTrackerRole(TrackerRole.LEFT_ELBOW, false) && + config.getOSCTrackerRole(TrackerRole.RIGHT_ELBOW, false), + config.getOSCTrackerRole(TrackerRole.LEFT_HAND, false) && + config.getOSCTrackerRole(TrackerRole.RIGHT_HAND, false), + ) + VRCOSCSettings.startVRCOSCSettings(fbb) + VRCOSCSettings.addOscSettings(fbb, generalSettingOffset) + VRCOSCSettings.addTrackers(fbb, oscSettingOffset) + VRCOSCSettings.addOscqueryEnabled(fbb, config.oscqueryEnabled) + + return VRCOSCSettings.endVRCOSCSettings(fbb) +} + +fun createVMCOSCSettings( + fbb: FlatBufferBuilder, + config: VMCConfig, +): Int { + val addressStringOffset = fbb.createString(config.address) + val generalSettingOffset = OSCSettings + .createOSCSettings( + fbb, + config.enabled, + config.portIn, + config.portOut, + addressStringOffset, + ) + + val vrmJson = config.vrmJson + var vrmJsonOffset = 0 + if (vrmJson != null) vrmJsonOffset = fbb.createString(vrmJson) + + VMCOSCSettings.startVMCOSCSettings(fbb) + VMCOSCSettings.addOscSettings(fbb, generalSettingOffset) + if (vrmJson != null) VMCOSCSettings.addVrmJson(fbb, vrmJsonOffset) + VMCOSCSettings.addAnchorHip(fbb, config.anchorHip) + VMCOSCSettings.addMirrorTracking(fbb, config.mirrorTracking) + + return VMCOSCSettings.endVMCOSCSettings(fbb) +} + +fun createFilterSettings( + fbb: FlatBufferBuilder, + filtersConfig: FiltersConfig, +): Int = FilteringSettings + .createFilteringSettings( + fbb, + getByConfigkey(filtersConfig.type)!!.id, + filtersConfig.amount, + ) + +fun createDriftCompensationSettings( + fbb: FlatBufferBuilder, + driftCompensationConfig: DriftCompensationConfig, +): Int = DriftCompensationSettings + .createDriftCompensationSettings( + fbb, + driftCompensationConfig.enabled, + driftCompensationConfig.prediction, + driftCompensationConfig.amount, + driftCompensationConfig.maxResets, + ) + +fun createTapDetectionSettings( + fbb: FlatBufferBuilder, + tapDetectionConfig: TapDetectionConfig, +): Int = TapDetectionSettings + .createTapDetectionSettings( + fbb, + tapDetectionConfig.fullResetDelay, + tapDetectionConfig.fullResetEnabled, + tapDetectionConfig.fullResetTaps, + tapDetectionConfig.yawResetDelay, + tapDetectionConfig.yawResetEnabled, + tapDetectionConfig.yawResetTaps, + tapDetectionConfig.mountingResetDelay, + tapDetectionConfig.mountingResetEnabled, + tapDetectionConfig.mountingResetTaps, + tapDetectionConfig.setupMode, + tapDetectionConfig.numberTrackersOverThreshold, + ) + +fun createSteamVRSettings(fbb: FlatBufferBuilder, bridge: ISteamVRBridge?): Int { + var steamvrTrackerSettings = 0 + if (bridge != null) { + steamvrTrackerSettings = SteamVRTrackersSetting + .createSteamVRTrackersSetting( + fbb, + bridge.getShareSetting(TrackerRole.WAIST), + bridge.getShareSetting(TrackerRole.CHEST), + bridge.getAutomaticSharedTrackers(), + + bridge.getShareSetting(TrackerRole.LEFT_FOOT), + bridge.getShareSetting(TrackerRole.RIGHT_FOOT), + bridge.getShareSetting(TrackerRole.LEFT_KNEE), + bridge.getShareSetting(TrackerRole.RIGHT_KNEE), + bridge.getShareSetting(TrackerRole.LEFT_ELBOW), + bridge.getShareSetting(TrackerRole.RIGHT_ELBOW), + bridge.getShareSetting(TrackerRole.LEFT_HAND), + bridge.getShareSetting(TrackerRole.RIGHT_HAND), + ) + } + return steamvrTrackerSettings +} + +fun createModelSettings( + fbb: FlatBufferBuilder, + humanPoseManager: HumanPoseManager, + legTweaksConfig: LegTweaksConfig, + skeletonConfig: SkeletonConfig, +): Int { + val togglesOffset = ModelToggles + .createModelToggles( + fbb, + humanPoseManager.getToggle(SkeletonConfigToggles.EXTENDED_SPINE_MODEL), + humanPoseManager.getToggle(SkeletonConfigToggles.EXTENDED_PELVIS_MODEL), + humanPoseManager.getToggle(SkeletonConfigToggles.EXTENDED_KNEE_MODEL), + humanPoseManager.getToggle(SkeletonConfigToggles.FORCE_ARMS_FROM_HMD), + humanPoseManager.getToggle(SkeletonConfigToggles.FLOOR_CLIP), + humanPoseManager.getToggle(SkeletonConfigToggles.SKATING_CORRECTION), + humanPoseManager.getToggle(SkeletonConfigToggles.TOE_SNAP), + humanPoseManager.getToggle(SkeletonConfigToggles.FOOT_PLANT), + humanPoseManager.getToggle(SkeletonConfigToggles.SELF_LOCALIZATION), + humanPoseManager.getToggle(SkeletonConfigToggles.USE_POSITION), + humanPoseManager.getToggle(SkeletonConfigToggles.ENFORCE_CONSTRAINTS), + humanPoseManager.getToggle(SkeletonConfigToggles.CORRECT_CONSTRAINTS), + ) + val ratiosOffset = ModelRatios + .createModelRatios( + fbb, + humanPoseManager.getValue(SkeletonConfigValues.WAIST_FROM_CHEST_HIP_AVERAGING), + humanPoseManager.getValue(SkeletonConfigValues.WAIST_FROM_CHEST_LEGS_AVERAGING), + humanPoseManager.getValue(SkeletonConfigValues.HIP_FROM_CHEST_LEGS_AVERAGING), + humanPoseManager.getValue(SkeletonConfigValues.HIP_FROM_WAIST_LEGS_AVERAGING), + humanPoseManager.getValue(SkeletonConfigValues.HIP_LEGS_AVERAGING), + humanPoseManager.getValue(SkeletonConfigValues.KNEE_TRACKER_ANKLE_AVERAGING), + humanPoseManager.getValue(SkeletonConfigValues.KNEE_ANKLE_AVERAGING), + ) + val legTweaksOffset = LegTweaksSettings + .createLegTweaksSettings( + fbb, + legTweaksConfig.correctionStrength, + ) + val skeletonConfigOffset = SkeletonHeight + .createSkeletonHeight( + fbb, + skeletonConfig.hmdHeight, + skeletonConfig.floorHeight, + ) + return ModelSettings + .createModelSettings( + fbb, + togglesOffset, + ratiosOffset, + legTweaksOffset, + skeletonConfigOffset, + ) +} + +fun createAutoBoneSettings( + fbb: FlatBufferBuilder, + autoBoneConfig: AutoBoneConfig, +): Int = AutoBoneSettings + .createAutoBoneSettings( + fbb, + autoBoneConfig.cursorIncrement, + autoBoneConfig.minDataDistance, + autoBoneConfig.maxDataDistance, + autoBoneConfig.numEpochs, + autoBoneConfig.printEveryNumEpochs, + autoBoneConfig.initialAdjustRate, + autoBoneConfig.adjustRateDecay, + autoBoneConfig.slideErrorFactor, + autoBoneConfig.offsetSlideErrorFactor, + autoBoneConfig.footHeightOffsetErrorFactor, + autoBoneConfig.bodyProportionErrorFactor, + autoBoneConfig.heightErrorFactor, + autoBoneConfig.positionErrorFactor, + autoBoneConfig.positionOffsetErrorFactor, + autoBoneConfig.calcInitError, + autoBoneConfig.randomizeFrameOrder, + autoBoneConfig.scaleEachStep, + autoBoneConfig.sampleCount, + autoBoneConfig.sampleRateMs, + autoBoneConfig.saveRecordings, + autoBoneConfig.useSkeletonHeight, + autoBoneConfig.randSeed, + ) + +/** + * Writes values from AutoBoneSettings to an AutoBoneConfig. + * + * @param autoBoneSettings The settings to read from. + * @param autoBoneConfig The config to write to. + * @return The autoBoneConfig parameter. + */ +fun readAutoBoneSettings( + autoBoneSettings: AutoBoneSettings, + autoBoneConfig: AutoBoneConfig, +): AutoBoneConfig { + if (autoBoneSettings.hasCursorIncrement()) { + autoBoneConfig.cursorIncrement = autoBoneSettings.cursorIncrement() + } + if (autoBoneSettings.hasMinDataDistance()) { + autoBoneConfig.minDataDistance = autoBoneSettings.minDataDistance() + } + if (autoBoneSettings.hasMaxDataDistance()) { + autoBoneConfig.maxDataDistance = autoBoneSettings.maxDataDistance() + } + if (autoBoneSettings.hasNumEpochs()) { + autoBoneConfig.numEpochs = autoBoneSettings.numEpochs() + } + if (autoBoneSettings.hasPrintEveryNumEpochs()) { + autoBoneConfig.printEveryNumEpochs = autoBoneSettings.printEveryNumEpochs() + } + if (autoBoneSettings.hasInitialAdjustRate()) { + autoBoneConfig.initialAdjustRate = autoBoneSettings.initialAdjustRate() + } + if (autoBoneSettings.hasAdjustRateDecay()) { + autoBoneConfig.adjustRateDecay = autoBoneSettings.adjustRateDecay() + } + if (autoBoneSettings.hasSlideErrorFactor()) { + autoBoneConfig.slideErrorFactor = autoBoneSettings.slideErrorFactor() + } + if (autoBoneSettings.hasOffsetSlideErrorFactor()) { + autoBoneConfig.offsetSlideErrorFactor = + autoBoneSettings.offsetSlideErrorFactor() + } + if (autoBoneSettings.hasFootHeightOffsetErrorFactor()) { + autoBoneConfig + .footHeightOffsetErrorFactor = + autoBoneSettings.footHeightOffsetErrorFactor() + } + if (autoBoneSettings.hasBodyProportionErrorFactor()) { + autoBoneConfig + .bodyProportionErrorFactor = autoBoneSettings.bodyProportionErrorFactor() + } + if (autoBoneSettings.hasHeightErrorFactor()) { + autoBoneConfig.heightErrorFactor = autoBoneSettings.heightErrorFactor() + } + if (autoBoneSettings.hasPositionErrorFactor()) { + autoBoneConfig.positionErrorFactor = autoBoneSettings.positionErrorFactor() + } + if (autoBoneSettings.hasPositionOffsetErrorFactor()) { + autoBoneConfig + .positionOffsetErrorFactor = autoBoneSettings.positionOffsetErrorFactor() + } + if (autoBoneSettings.hasCalcInitError()) { + autoBoneConfig.calcInitError = autoBoneSettings.calcInitError() + } + if (autoBoneSettings.hasRandomizeFrameOrder()) { + autoBoneConfig.randomizeFrameOrder = autoBoneSettings.randomizeFrameOrder() + } + if (autoBoneSettings.hasScaleEachStep()) { + autoBoneConfig.scaleEachStep = autoBoneSettings.scaleEachStep() + } + if (autoBoneSettings.hasSampleCount()) { + autoBoneConfig.sampleCount = autoBoneSettings.sampleCount() + } + if (autoBoneSettings.hasSampleRateMs()) { + autoBoneConfig.sampleRateMs = autoBoneSettings.sampleRateMs() + } + if (autoBoneSettings.hasSaveRecordings()) { + autoBoneConfig.saveRecordings = autoBoneSettings.saveRecordings() + } + if (autoBoneSettings.hasUseSkeletonHeight()) { + autoBoneConfig.useSkeletonHeight = autoBoneSettings.useSkeletonHeight() + } + if (autoBoneSettings.hasRandSeed()) { + autoBoneConfig.randSeed = autoBoneSettings.randSeed() + } + + return autoBoneConfig +} + +fun createArmsResetModeSettings( + fbb: FlatBufferBuilder, + resetsConfig: ResetsConfig, +): Int = ResetsSettings + .createResetsSettings( + fbb, + resetsConfig.resetMountingFeet, + resetsConfig.mode.id, + resetsConfig.yawResetSmoothTime, + resetsConfig.saveMountingReset, + resetsConfig.resetHmdPitch, + ) + +fun createSettingsResponse(fbb: FlatBufferBuilder, server: VRServer): Int { + val bridge = server.getVRBridge(ISteamVRBridge::class.java) + + return SettingsResponse + .createSettingsResponse( + fbb, + createSteamVRSettings(fbb, bridge), + createFilterSettings( + fbb, + server.configManager.vrConfig.filters, + ), + createDriftCompensationSettings( + fbb, + server.configManager.vrConfig.driftCompensation, + ), + createOSCRouterSettings( + fbb, + server.configManager.vrConfig.oscRouter, + ), + createVRCOSCSettings( + fbb, + server.configManager.vrConfig.vrcOSC, + ), + createVMCOSCSettings( + fbb, + server.configManager.vrConfig.vmc, + ), + createModelSettings( + fbb, + server.humanPoseManager, + server.configManager.vrConfig.legTweaks, + server.configManager.vrConfig.skeleton, + ), + createTapDetectionSettings( + fbb, + server.configManager.vrConfig.tapDetection, + ), + createAutoBoneSettings( + fbb, + server.configManager.vrConfig.autoBone, + ), + createArmsResetModeSettings( + fbb, + server.configManager.vrConfig.resetsConfig, + ), + createStayAlignedSettings( + fbb, + server.configManager.vrConfig.stayAlignedConfig, + ), + createHIDSettings(fbb, server.configManager.vrConfig.hidConfig), + ) +} + +fun createStayAlignedSettings( + fbb: FlatBufferBuilder, + config: StayAlignedConfig, +): Int = StayAlignedSettings + .createStayAlignedSettings( + fbb, + config.enabled, + false, // deprecated + config.hideYawCorrection, + config.standingRelaxedPose.enabled, + config.standingRelaxedPose.upperLegAngleInDeg, + config.standingRelaxedPose.lowerLegAngleInDeg, + config.standingRelaxedPose.footAngleInDeg, + config.sittingRelaxedPose.enabled, + config.sittingRelaxedPose.upperLegAngleInDeg, + config.sittingRelaxedPose.lowerLegAngleInDeg, + config.sittingRelaxedPose.footAngleInDeg, + config.flatRelaxedPose.enabled, + config.flatRelaxedPose.upperLegAngleInDeg, + config.flatRelaxedPose.lowerLegAngleInDeg, + config.flatRelaxedPose.footAngleInDeg, + config.setupComplete, + ) + +fun createHIDSettings( + fbb: FlatBufferBuilder, + config: HIDConfig, +): Int = HIDSettings + .createHIDSettings( + fbb, + config.trackersOverHID, + ) diff --git a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilderKotlin.kt b/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilderKotlin.kt deleted file mode 100644 index 3efe9d48e..000000000 --- a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilderKotlin.kt +++ /dev/null @@ -1,43 +0,0 @@ -package dev.slimevr.protocol.rpc.settings - -import com.google.flatbuffers.FlatBufferBuilder -import dev.slimevr.config.HIDConfig -import dev.slimevr.config.StayAlignedConfig -import solarxr_protocol.rpc.HIDSettings -import solarxr_protocol.rpc.StayAlignedSettings - -object RPCSettingsBuilderKotlin { - - fun createStayAlignedSettings( - fbb: FlatBufferBuilder, - config: StayAlignedConfig, - ): Int = StayAlignedSettings - .createStayAlignedSettings( - fbb, - config.enabled, - false, // deprecated - config.hideYawCorrection, - config.standingRelaxedPose.enabled, - config.standingRelaxedPose.upperLegAngleInDeg, - config.standingRelaxedPose.lowerLegAngleInDeg, - config.standingRelaxedPose.footAngleInDeg, - config.sittingRelaxedPose.enabled, - config.sittingRelaxedPose.upperLegAngleInDeg, - config.sittingRelaxedPose.lowerLegAngleInDeg, - config.sittingRelaxedPose.footAngleInDeg, - config.flatRelaxedPose.enabled, - config.flatRelaxedPose.upperLegAngleInDeg, - config.flatRelaxedPose.lowerLegAngleInDeg, - config.flatRelaxedPose.footAngleInDeg, - config.setupComplete, - ) - - fun createHIDSettings( - fbb: FlatBufferBuilder, - config: HIDConfig, - ): Int = HIDSettings - .createHIDSettings( - fbb, - config.trackersOverHID, - ) -} diff --git a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsHandler.kt b/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsHandler.kt index f2c882a04..5f0453107 100644 --- a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsHandler.kt +++ b/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsHandler.kt @@ -18,24 +18,9 @@ import kotlin.math.* class RPCSettingsHandler(var rpcHandler: RPCHandler, var api: ProtocolAPI) { init { - rpcHandler.registerPacketListener(RpcMessage.SettingsRequest) { conn: GenericConnection, messageHeader: RpcMessageHeader? -> - this.onSettingsRequest( - conn, - messageHeader, - ) - } - rpcHandler - .registerPacketListener( - RpcMessage.ChangeSettingsRequest, - ) { conn: GenericConnection?, messageHeader: RpcMessageHeader -> - this.onChangeSettingsRequest( - conn, - messageHeader, - ) - } - rpcHandler.registerPacketListener(RpcMessage.SettingsResetRequest) { conn: GenericConnection, messageHeader: RpcMessageHeader? -> - this.onSettingsResetRequest(conn, messageHeader) - } + rpcHandler.registerPacketListener(RpcMessage.SettingsRequest, ::onSettingsRequest) + rpcHandler.registerPacketListener(RpcMessage.ChangeSettingsRequest, ::onChangeSettingsRequest) + rpcHandler.registerPacketListener(RpcMessage.SettingsResetRequest, ::onSettingsResetRequest) } fun onSettingsRequest(conn: GenericConnection, messageHeader: RpcMessageHeader?) { @@ -331,7 +316,7 @@ class RPCSettingsHandler(var rpcHandler: RPCHandler, var api: ProtocolAPI) { .vrConfig .autoBone - RPCSettingsBuilder.readAutoBoneSettings(autoBoneSettings, autoBoneConfig) + readAutoBoneSettings(autoBoneSettings, autoBoneConfig) } if (req.resetsSettings() != null) { @@ -391,7 +376,7 @@ class RPCSettingsHandler(var rpcHandler: RPCHandler, var api: ProtocolAPI) { val settings = SettingsResponse .createSettingsResponse( fbb, - RPCSettingsBuilder.createSteamVRSettings(fbb, bridge), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + createSteamVRSettings(fbb, bridge), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ) val outbound = rpcHandler.createRPCMessage(fbb, RpcMessage.SettingsResponse, settings) diff --git a/server/core/src/main/java/dev/slimevr/protocol/rpc/setup/RPCTapSetupHandler.kt b/server/core/src/main/java/dev/slimevr/protocol/rpc/setup/RPCTapSetupHandler.kt index 3d3d44962..ea5ac3adc 100644 --- a/server/core/src/main/java/dev/slimevr/protocol/rpc/setup/RPCTapSetupHandler.kt +++ b/server/core/src/main/java/dev/slimevr/protocol/rpc/setup/RPCTapSetupHandler.kt @@ -3,7 +3,7 @@ package dev.slimevr.protocol.rpc.setup import com.google.flatbuffers.FlatBufferBuilder import dev.slimevr.protocol.GenericConnection import dev.slimevr.protocol.ProtocolAPI -import dev.slimevr.protocol.datafeed.DataFeedBuilder +import dev.slimevr.protocol.datafeed.createTrackerId import dev.slimevr.protocol.rpc.RPCHandler import dev.slimevr.setup.TapSetupListener import dev.slimevr.tracking.trackers.Tracker @@ -20,7 +20,7 @@ class RPCTapSetupHandler( override fun onStarted(tracker: Tracker) { val fbb = FlatBufferBuilder(32) - val idOffset = DataFeedBuilder.createTrackerId(fbb, tracker) + val idOffset = createTrackerId(fbb, tracker) val update = TapDetectionSetupNotification.createTapDetectionSetupNotification(fbb, idOffset) val outbound = rpcHandler.createRPCMessage(fbb, RpcMessage.TapDetectionSetupNotification, update) diff --git a/server/core/src/main/java/dev/slimevr/websocketapi/WebsocketAPI.java b/server/core/src/main/java/dev/slimevr/websocketapi/WebsocketAPI.java index 2dee9f5a3..0e3cf870e 100644 --- a/server/core/src/main/java/dev/slimevr/websocketapi/WebsocketAPI.java +++ b/server/core/src/main/java/dev/slimevr/websocketapi/WebsocketAPI.java @@ -9,6 +9,7 @@ import org.java_websocket.WebSocket; import org.java_websocket.drafts.Draft_6455; import org.java_websocket.handshake.ClientHandshake; import org.java_websocket.server.WebSocketServer; +import org.jetbrains.annotations.NotNull; import java.net.InetSocketAddress; import java.nio.ByteBuffer; @@ -101,7 +102,7 @@ public class WebsocketAPI extends WebSocketServer implements ProtocolAPIServer { } @Override - public Stream getAPIConnections() { + public @NotNull Stream getApiConnections() { return this.getConnections().stream().map(conn -> { var c = conn.getAttachment(); return (GenericConnection) c; diff --git a/server/desktop/src/main/java/dev/slimevr/desktop/platform/linux/UnixSocketRpcBridge.java b/server/desktop/src/main/java/dev/slimevr/desktop/platform/linux/UnixSocketRpcBridge.java index 198ab3e51..42dab98fb 100644 --- a/server/desktop/src/main/java/dev/slimevr/desktop/platform/linux/UnixSocketRpcBridge.java +++ b/server/desktop/src/main/java/dev/slimevr/desktop/platform/linux/UnixSocketRpcBridge.java @@ -141,7 +141,7 @@ public class UnixSocketRpcBridge implements dev.slimevr.bridge.Bridge, } @Override - public java.util.stream.Stream getAPIConnections() { + public java.util.stream.Stream getApiConnections() { return this.selector .keys() .stream()