I forgor to stage files

This commit is contained in:
HannahPadd
2026-03-04 18:15:59 +01:00
parent 3b40c9ec06
commit 81f50f39c5
9 changed files with 814 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
import { useLocalization } from '@fluent/react';
import { useState, forwardRef } from 'react';
export const KeybindRecorder = forwardRef<
HTMLInputElement,
{
keys: string[];
onKeysChange: (v: string[]) => void;
}
>(function KeybindRecorder({ keys, onKeysChange }, ref) {
const [isRecording, setIsRecording] = useState(false);
const [oldKeys, setOldKeys] = useState<string[]>([]);
const { l10n } = useLocalization();
return (
<div className="relative w-full">
<input
ref={ref}
className="opacity-0 absolute inset-0 cursor-pointer"
onFocus={() => {
setOldKeys(keys);
onKeysChange([]);
setIsRecording(true);
}}
onBlur={() => {
setIsRecording(false);
if (keys.length < 4) onKeysChange(oldKeys);
}}
onKeyDown={(e) => {
const key = e.key.toUpperCase();
if (!keys.includes(key) && keys.length < 4) {
onKeysChange([...keys, key]);
}
}}
/>
<div className="flex gap-2 min-h-[42px] items-center px-3 py-2 rounded-lg bg-background-80">
<div className="flex flex-grow gap-2 flex-wrap">
{keys.map((key, i) => (
<div
key={i}
className="bg-accent-background-50 px-3 py-1 rounded-md text-sm"
>
{key}
</div>
))}
</div>
<div className="text-accent-background-10 text-right text-sm font-medium">
{keys.length < 4 && isRecording ? l10n.getString('settings-sidebar_keybinds_now-recording') : l10n.getString('settings-sidebar_keybinds_record-keybind') }
</div>
</div>
</div>
);
});

View File

@@ -0,0 +1,73 @@
import { Controller, Control, UseFormResetField } from 'react-hook-form';
import { Button } from './Button';
import { NumberSelector } from './NumberSelector';
import { KeybindRecorder } from './KeybindRecorder';
import { useLocaleConfig } from '@/i18n/config';
export function KeybindRow({
label,
control,
resetField,
bindingName,
delayName,
}: {
label: string;
control: Control<any>;
resetField: UseFormResetField<any>;
bindingName: string;
delayName: string;
}) {
const { currentLocales } = useLocaleConfig();
const secondsFormat = new Intl.NumberFormat(currentLocales, {
style: 'unit',
unit: 'second',
unitDisplay: 'narrow',
maximumFractionDigits: 2,
});
return (
<tr className="border-b border-background-60 h-20">
<td className="px-6 py-4 pr-4">
<label className="text-sm font-medium text-background-10">
{label}
</label>
</td>
<td className="px-4">
<Controller
control={control}
name={bindingName}
render={({ field }) => (
<KeybindRecorder
keys={field.value ?? []}
onKeysChange={field.onChange}
ref={field.ref}
/>
)}
/>
</td>
<td className="px-4">
<NumberSelector
control={control}
name={delayName}
valueLabelFormat={(value) => secondsFormat.format(value)}
min={0}
max={10}
step={0.2}
/>
</td>
<td className="px-2">
<div className="flex gap-2 justify-center px-4">
<Button
variant="primary"
onClick={() => {
resetField(bindingName);
resetField(delayName);
}}
>
Reset
</Button>
</div>
</td>
</tr>
);
}

View File

@@ -0,0 +1,13 @@
export function ResetSettingIcon({ size = 24 }: { size?: number }) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size}
viewBox="0 -960 960 960"
width={size}
fill="#00000"
>
<path d="M520-330v-60h160v60H520Zm60 210v-50h-60v-60h60v-50h60v160h-60Zm100-50v-60h160v60H680Zm40-110v-160h60v50h60v60h-60v50h-60Zm111-280h-83q-26-88-99-144t-169-56q-117 0-198.5 81.5T200-480q0 72 32.5 132t87.5 98v-110h80v240H160v-80h94q-62-50-98-122.5T120-480q0-75 28.5-140.5t77-114q48.5-48.5 114-77T480-840q129 0 226.5 79.5T831-560Z" />
</svg>
);
}

View File

@@ -0,0 +1,313 @@
import { WrenchIcon } from '@/components/commons/icon/WrenchIcons';
import {
SettingsPageLayout,
SettingsPagePaneLayout,
} from '@/components/settings/SettingsPageLayout';
import { Typography } from '@/components/commons/Typography';
import { Localized, useLocalization } from '@fluent/react';
import { useForm } from 'react-hook-form';
import { ReactNode, useEffect } from 'react';
import { KeybindRow } from '@/components/commons/KeybindRow';
import { Button } from '@/components/commons/Button';
import { useWebsocketAPI } from '@/hooks/websocket-api';
import {
KeybindRequestT,
KeybindResponseT,
RpcMessage,
KeybindT,
KeybindName,
ChangeKeybindRequestT,
} from 'solarxr-protocol';
export type KeybindsForm = {
names: {
fullResetName: KeybindName;
yawResetName: KeybindName;
mountingResetName: KeybindName;
pauseTrackingName: KeybindName;
feetResetName: KeybindName;
};
bindings: {
fullResetBinding: string[];
yawResetBinding: string[];
mountingResetBinding: string[];
pauseTrackingBinding: string[];
feetResetBinding: string[];
};
delays: {
fullResetDelay: number;
yawResetDelay: number;
mountingResetDelay: number;
pauseTrackingDelay: number;
feetResetDelay: number;
};
};
const defaultValues: KeybindsForm = {
names: {
fullResetName: KeybindName.FULL_RESET,
yawResetName: KeybindName.YAW_RESET,
mountingResetName: KeybindName.MOUNTING_RESET,
pauseTrackingName: KeybindName.PAUSE_TRACKING,
feetResetName: KeybindName.FEET_MOUNTING_RESET,
},
bindings: {
fullResetBinding: ['CTRL', 'ALT', 'SHIFT', 'Y'],
yawResetBinding: ['CTRL', 'ALT', 'SHIFT', 'U'],
mountingResetBinding: ['CTRL', 'ALT', 'SHIFT', 'I'],
pauseTrackingBinding: ['CTRL', 'ALT', 'SHIFT', 'O'],
feetResetBinding: ['CTRL', 'ALT', 'SHIFT', 'P'],
},
delays: {
fullResetDelay: 0,
yawResetDelay: 0,
mountingResetDelay: 0,
pauseTrackingDelay: 0,
feetResetDelay: 0,
},
};
export function useKeybindsForm() {
const {
register,
reset,
handleSubmit,
formState,
control,
getValues,
resetField,
watch,
} = useForm<KeybindsForm>({
defaultValues,
});
return {
control,
register,
reset,
handleSubmit,
formState,
getValues,
resetField,
watch,
};
}
export function KeybindSettings() {
const { l10n } = useLocalization();
const { control, reset, handleSubmit, watch, getValues, resetField } =
useKeybindsForm();
const { sendRPCPacket, useRPCPacket } = useWebsocketAPI();
const onSubmit = (values: KeybindsForm) => {
const keybinds = new ChangeKeybindRequestT();
const fullResetKeybind = new KeybindT();
fullResetKeybind.keybindName = values.names.fullResetName;
fullResetKeybind.keybindValue = values.bindings.fullResetBinding.join('+');
fullResetKeybind.keybindDelay = values.delays.fullResetDelay;
keybinds.keybind.push(fullResetKeybind);
const yawResetKeybind = new KeybindT();
yawResetKeybind.keybindName = values.names.yawResetName;
yawResetKeybind.keybindValue = values.bindings.yawResetBinding.join('+');
yawResetKeybind.keybindDelay = values.delays.yawResetDelay;
keybinds.keybind.push(yawResetKeybind);
const mountingResetKeybind = new KeybindT();
mountingResetKeybind.keybindName = values.names.mountingResetName;
mountingResetKeybind.keybindValue =
values.bindings.mountingResetBinding.join('+');
mountingResetKeybind.keybindDelay = values.delays.mountingResetDelay;
keybinds.keybind.push(mountingResetKeybind);
const pauseTrackingKeybind = new KeybindT();
pauseTrackingKeybind.keybindName = values.names.pauseTrackingName;
pauseTrackingKeybind.keybindValue =
values.bindings.pauseTrackingBinding.join('+');
pauseTrackingKeybind.keybindDelay = values.delays.pauseTrackingDelay;
keybinds.keybind.push(pauseTrackingKeybind);
const feetResetKeybind = new KeybindT();
feetResetKeybind.keybindName = values.names.feetResetName;
feetResetKeybind.keybindValue = values.bindings.feetResetBinding.join('+');
feetResetKeybind.keybindDelay = values.delays.pauseTrackingDelay;
keybinds.keybind.push(feetResetKeybind);
console.log(`Delay ${Number(fullResetKeybind.keybindDelay)}`);
sendRPCPacket(RpcMessage.ChangeKeybindRequest, keybinds);
};
useEffect(() => {
const subscription = watch(() => handleSubmit(onSubmit)());
return () => subscription.unsubscribe();
}, []);
useEffect(() => {
sendRPCPacket(RpcMessage.KeybindRequest, new KeybindRequestT());
}, []);
useRPCPacket(RpcMessage.KeybindResponse, ({ keybind }: KeybindResponseT) => {
if (!keybind) return;
const keybindValues: KeybindsForm = {
names: {
fullResetName: KeybindName.FULL_RESET,
yawResetName: KeybindName.YAW_RESET,
mountingResetName: KeybindName.MOUNTING_RESET,
pauseTrackingName: KeybindName.PAUSE_TRACKING,
feetResetName: KeybindName.FEET_MOUNTING_RESET,
},
bindings: {
fullResetBinding:
(typeof keybind[KeybindName.FULL_RESET].keybindValue === 'string'
? keybind[KeybindName.FULL_RESET].keybindValue
: ''
).split('+') || defaultValues.bindings.fullResetBinding,
yawResetBinding:
(typeof keybind[KeybindName.YAW_RESET].keybindValue === 'string'
? keybind[KeybindName.YAW_RESET].keybindValue
: ''
).split('+') || defaultValues.bindings.yawResetBinding,
mountingResetBinding:
(typeof keybind[KeybindName.MOUNTING_RESET].keybindValue === 'string'
? keybind[KeybindName.MOUNTING_RESET].keybindValue
: ''
).split('+') || defaultValues.bindings.mountingResetBinding,
pauseTrackingBinding:
(typeof keybind[KeybindName.PAUSE_TRACKING].keybindValue === 'string'
? keybind[KeybindName.PAUSE_TRACKING].keybindValue
: ''
).split('+') || defaultValues.bindings.pauseTrackingBinding,
feetResetBinding:
(typeof keybind[KeybindName.FEET_MOUNTING_RESET].keybindValue ===
'string'
? keybind[KeybindName.FEET_MOUNTING_RESET].keybindValue
: ''
).split('+') || defaultValues.bindings.feetResetBinding,
},
delays: {
fullResetDelay:
keybind[KeybindName.FULL_RESET].keybindDelay ||
defaultValues.delays.fullResetDelay,
yawResetDelay:
keybind[KeybindName.YAW_RESET].keybindDelay ||
defaultValues.delays.yawResetDelay,
mountingResetDelay:
keybind[KeybindName.MOUNTING_RESET].keybindDelay ||
defaultValues.delays.mountingResetDelay,
pauseTrackingDelay:
keybind[KeybindName.PAUSE_TRACKING].keybindDelay ||
defaultValues.delays.mountingResetDelay,
feetResetDelay:
keybind[KeybindName.FEET_MOUNTING_RESET].keybindDelay ||
defaultValues.delays.feetResetDelay,
},
};
reset({ ...getValues(), ...keybindValues });
});
const handleResetButton = () => {
reset(defaultValues);
};
function Table({ children }: { children: ReactNode }) {
return (
<table className="min-w-full divide-y divide-background-50">
<thead>
<tr>
<th scope="col" className="px-6 py-3 text-start">
<Localized id={'keybind_config-keybind_name'}>
<Typography />
</Localized>
Keybind
</th>
<th scope="col" className="px-6 py-3 text-middle">
<Localized id={'keybind_config-keybind_value'}>
<Typography />
</Localized>
Combination
</th>
<th scope="col" className="px-6 py-3 text-middle">
<Localized id={'keybind_config-keybind_delay'}>
<Typography />
</Localized>
Delay before trigger (S)
</th>
</tr>
</thead>
<tbody>{children}</tbody>
</table>
);
}
return (
<SettingsPageLayout>
<form className="flex flex-col gap-2 w-full">
<SettingsPagePaneLayout icon={<WrenchIcon />} id="keybinds">
<>
<Typography variant="main-title" id="settings-keybinds" />
<div className="flex flex-col pt-2 pb-4">
{l10n
.getString('settings-keybinds-description')
.split('\n')
.map((line, i) => (
<Typography key={i}>{line}</Typography>
))}
</div>
<Table>
<KeybindRow
label="Full Reset"
control={control}
resetField={resetField}
bindingName="bindings.fullResetBinding"
delayName="delays.fullResetDelay"
/>
<KeybindRow
label="Yaw Reset"
control={control}
resetField={resetField}
bindingName="bindings.yawResetBinding"
delayName="delays.yawResetDelay"
/>
<KeybindRow
label="Mounting Reset"
control={control}
resetField={resetField}
bindingName="bindings.mountingResetBinding"
delayName="delays.mountingResetDelay"
/>
<KeybindRow
label="Feet Mounting Reset"
control={control}
resetField={resetField}
bindingName="bindings.feetResetBinding"
delayName="delays.feetResetDelay"
/>
<KeybindRow
label="Pause Tracking"
control={control}
resetField={resetField}
bindingName="bindings.pauseTrackingBinding"
delayName="delays.pauseTrackingDelay"
/>
</Table>
<div className="flex flex-col pt-4" />
<Button
className="flex flex-col"
onClick={handleResetButton}
variant="primary"
>
Reset All
</Button>
</>
</SettingsPagePaneLayout>
</form>
</SettingsPageLayout>
);
}

View File

@@ -0,0 +1,73 @@
package dev.slimevr.keybind
import dev.slimevr.VRServer
import dev.slimevr.config.KeybindingsConfig
import solarxr_protocol.rpc.Keybind
import solarxr_protocol.rpc.KeybindName
import solarxr_protocol.rpc.KeybindT
import java.util.concurrent.CopyOnWriteArrayList
class KeybindHandler(val vrServer: VRServer) {
private val listeners: MutableList<KeybindListener> = CopyOnWriteArrayList()
var keybinds: MutableList<KeybindT> = mutableListOf()
init {
createKeybinds()
}
fun sendKeybinds(KeybindName: String) {
this.listeners.forEach { it.sendKeybind()}
}
fun addListener(listener: KeybindListener) {
this.listeners.add(listener)
}
fun removeListener(listener: KeybindListener) {
listeners.removeIf { listener == it }
}
private fun createKeybinds() {
keybinds.clear()
keybinds.add(
KeybindT().apply {
keybindName = KeybindName.FULL_RESET
keybindValue = vrServer.configManager.vrConfig.keybindings.fullResetBinding
keybindDelay = vrServer.configManager.vrConfig.keybindings.fullResetDelay
},
)
keybinds.add(
KeybindT().apply {
keybindName = KeybindName.YAW_RESET
keybindValue = vrServer.configManager.vrConfig.keybindings.yawResetBinding
keybindDelay = vrServer.configManager.vrConfig.keybindings.yawResetDelay
},
)
keybinds.add(
KeybindT().apply {
keybindName = KeybindName.MOUNTING_RESET
keybindValue = vrServer.configManager.vrConfig.keybindings.mountingResetBinding
keybindDelay = vrServer.configManager.vrConfig.keybindings.mountingResetDelay
},
)
keybinds.add(
KeybindT().apply {
keybindName = KeybindName.PAUSE_TRACKING
keybindValue = vrServer.configManager.vrConfig.keybindings.pauseTrackingBinding
keybindDelay = vrServer.configManager.vrConfig.keybindings.pauseTrackingDelay
},
)
keybinds.add(
KeybindT().apply {
keybindName = KeybindName.PAUSE_TRACKING
keybindValue = vrServer.configManager.vrConfig.keybindings.feetMountingResetBinding
keybindDelay = vrServer.configManager.vrConfig.keybindings.feetMountingResetDelay
}
)
}
//TODO: Maybe recreating all the keybinds isn't the best idea?
fun updateKeybinds() {
createKeybinds()
}
}

View File

@@ -0,0 +1,6 @@
package dev.slimevr.keybind
interface KeybindListener {
fun sendKeybind()
fun onKeybindUpdate()
}

View File

@@ -0,0 +1,31 @@
package dev.slimevr.keybinding
import org.freedesktop.dbus.DBusPath
import org.freedesktop.dbus.annotations.DBusInterfaceName
import org.freedesktop.dbus.interfaces.DBusInterface
import org.freedesktop.dbus.messages.DBusSignal
import org.freedesktop.dbus.types.Variant
@DBusInterfaceName("org.freedesktop.portal.GlobalKeybinds")
interface GlobalKeybinds : DBusInterface {
// Creates a session for the shortcuts
fun CreateSession(options: Map<String, Variant<*>>): DBusPath
fun BindShortcuts(
sessionHandle: DBusPath,
shortcuts: Array<Shortcut>,
parentWindow: String,
options: Map<String, Variant<*>>
): DBusPath
class Activated(
path: String,
val sessionHandle: DBusPath,
val shortcutId: String,
val timestamp: Long,
val options: Map<String, Variant<*>>
) : DBusSignal(path, sessionHandle, shortcutId, timestamp, options)
}
data class Shortcut(val id: String, val properties: Map<String, Variant<*>>)

View File

@@ -0,0 +1,148 @@
package dev.slimevr.keybinding
import com.melloware.jintellitype.HotkeyListener
import com.melloware.jintellitype.JIntellitype
import dev.slimevr.VRServer
import dev.slimevr.config.KeybindingsConfig
import dev.slimevr.tracking.trackers.TrackerUtils
import io.eiren.util.OperatingSystem
import io.eiren.util.ann.AWTThread
import io.eiren.util.logging.LogManager
class Keybinding @AWTThread constructor(val server: VRServer) : HotkeyListener {
val config: KeybindingsConfig = server.configManager.vrConfig.keybindings
init {
if (OperatingSystem.Companion.currentPlatform != OperatingSystem.WINDOWS) {
LogManager
.info(
"[Keybinding] Currently only supported on Windows. Keybindings will be disabled.",
)
/*
try {
val connection = DBusConnectionBuilder.forSessionBus().build()
// 1. Get the Portal object
val portal = connection.getRemoteObject(
"org.freedesktop.portal.Desktop",
"/org/freedesktop/portal/desktop",
GlobalKeybinds::class.java
)
// 2. Setup the Signal Listener
connection.addSigHandler(GlobalKeybinds.Activated::class.java) { signal ->
when (signal.shortcutId) {
"my_cool_action" -> println("🚀 Hotkey Triggered!")
}
}
// 3. Create Session & Bind (Simplified)
// Note: In a real app, you'd handle the ObjectPath callbacks
// for CreateSession before calling BindShortcuts.
val shortcuts = arrayOf(
Shortcut(
"my_cool_action",
mapOf("description" to Variant("Open My App"))
)
)
// This triggers the OS permissions popup
portal.BindShortcuts(, shortcuts, "", emptyMap())
} catch (e: Error) {
println("Dbus error: ${e}")
}
*/
} else {
try {
if (JIntellitype.getInstance() != null) {
JIntellitype.getInstance().addHotKeyListener(this)
val fullResetBinding = config.fullResetBinding
JIntellitype.getInstance()
.registerHotKey(FULL_RESET, fullResetBinding)
LogManager.info("[Keybinding] Bound full reset to $fullResetBinding")
val yawResetBinding = config.yawResetBinding
JIntellitype.getInstance()
.registerHotKey(YAW_RESET, yawResetBinding)
LogManager.info("[Keybinding] Bound yaw reset to $yawResetBinding")
val mountingResetBinding = config.mountingResetBinding
JIntellitype.getInstance()
.registerHotKey(MOUNTING_RESET, mountingResetBinding)
LogManager.info("[Keybinding] Bound reset mounting to $mountingResetBinding")
val feetMountingResetBinding = config.feetMountingResetBinding
JIntellitype.getInstance()
.registerHotKey(FEET_MOUNTING_RESET, feetMountingResetBinding)
LogManager.info("[Keybinding] Bound feet reset mounting to $feetMountingResetBinding")
val pauseTrackingBinding = config.pauseTrackingBinding
JIntellitype.getInstance()
.registerHotKey(PAUSE_TRACKING, pauseTrackingBinding)
LogManager.info("[Keybinding] Bound pause tracking to $pauseTrackingBinding")
}
} catch (e: Throwable) {
LogManager
.warning(
"[Keybinding] JIntellitype initialization failed. Keybindings will be disabled. Try restarting your computer.",
)
}
}
}
@AWTThread
override fun onHotKey(identifier: Int) {
when (identifier) {
FULL_RESET -> server.scheduleResetTrackersFull(
RESET_SOURCE_NAME,
(config.fullResetDelay * 1000).toLong()
)
YAW_RESET -> server.scheduleResetTrackersYaw(
RESET_SOURCE_NAME,
(config.yawResetDelay * 1000).toLong()
)
MOUNTING_RESET -> server.scheduleResetTrackersMounting(
RESET_SOURCE_NAME,
(config.mountingResetDelay * 1000).toLong()
)
FEET_MOUNTING_RESET -> server.scheduleResetTrackersMounting(
RESET_SOURCE_NAME,
(config.feetMountingResetDelay * 1000).toLong(),
TrackerUtils.feetsBodyParts,
)
PAUSE_TRACKING ->
server
.scheduleTogglePauseTracking(
RESET_SOURCE_NAME,
(config.pauseTrackingDelay * 1000).toLong(),
)
}
}
enum class KeybindName {
FULL_RESET,
YAW_RESET,
MOUNTING_RESET,
PAUSE_TRACKING
}
companion object {
private const val RESET_SOURCE_NAME = "Keybinding"
private const val FULL_RESET = 1
private const val YAW_RESET = 2
private const val MOUNTING_RESET = 3
private const val FEET_MOUNTING_RESET = 4
private const val PAUSE_TRACKING = 5
}
}

View File

@@ -0,0 +1,102 @@
package dev.slimevr.protocol.rpc.keybinds
import com.google.flatbuffers.FlatBufferBuilder
import dev.slimevr.keybinding.Keybinding
import dev.slimevr.keybind.KeybindListener
import dev.slimevr.protocol.GenericConnection
import dev.slimevr.protocol.rpc.RPCHandler
import dev.slimevr.protocol.ProtocolAPI
import jdk.internal.joptsimple.internal.Messages.message
import solarxr_protocol.rpc.ChangeKeybindRequest
import solarxr_protocol.rpc.KeybindName
import solarxr_protocol.rpc.KeybindRequest
import solarxr_protocol.rpc.KeybindResponse
import solarxr_protocol.rpc.KeybindResponseT
import solarxr_protocol.rpc.KeybindT
import solarxr_protocol.rpc.RpcMessage
import solarxr_protocol.rpc.RpcMessageHeader
class RPCKeybindHandler(
var rpcHandler: RPCHandler,
var api: ProtocolAPI
) : KeybindListener {
val keybindingConfig = api.server.configManager.vrConfig.keybindings
init {
this.api.server.keybindHandler.addListener(this)
rpcHandler.registerPacketListener(RpcMessage.KeybindRequest, ::onKeybindRequest)
rpcHandler.registerPacketListener(RpcMessage.ChangeKeybindRequest, ::onChangeKeybindRequest)
}
//TODO: Figure out a way to "refresh" the keybind array here.
private fun buildKeybindResponse(fbb: FlatBufferBuilder) : Int = KeybindResponse.pack(
fbb,
KeybindResponseT().apply {
keybind = api.server.keybindHandler.keybinds.toTypedArray()
}
)
private fun onKeybindRequest(conn: GenericConnection, messageHeader: RpcMessageHeader) {
val fbb = FlatBufferBuilder(32)
val response = buildKeybindResponse(fbb)
val outbound = rpcHandler.createRPCMessage(
fbb,
RpcMessage.KeybindResponse,
response,
)
fbb.finish(outbound)
conn.send(fbb.dataBuffer())
}
private fun onChangeKeybindRequest(conn: GenericConnection, messageHeader: RpcMessageHeader) {
val req = (messageHeader.message(ChangeKeybindRequest()) as ChangeKeybindRequest).unpack()
keybindingConfig.fullResetBinding = req.keybind[KeybindName.FULL_RESET].keybindValue
keybindingConfig.fullResetDelay = req.keybind[KeybindName.FULL_RESET].keybindDelay
keybindingConfig.yawResetBinding = req.keybind[KeybindName.YAW_RESET].keybindValue
keybindingConfig.yawResetDelay = req.keybind[KeybindName.YAW_RESET].keybindDelay
keybindingConfig.mountingResetBinding = req.keybind[KeybindName.MOUNTING_RESET].keybindValue
keybindingConfig.mountingResetDelay = req.keybind[KeybindName.MOUNTING_RESET].keybindDelay
keybindingConfig.pauseTrackingBinding = req.keybind[KeybindName.PAUSE_TRACKING].keybindValue
keybindingConfig.pauseTrackingDelay = req.keybind[KeybindName.PAUSE_TRACKING].keybindDelay
keybindingConfig.feetMountingResetBinding = req.keybind[KeybindName.FEET_MOUNTING_RESET].keybindValue
keybindingConfig.feetMountingResetDelay = req.keybind[KeybindName.FEET_MOUNTING_RESET].keybindDelay
api.server.configManager.saveConfig()
api.server.keybindHandler.updateKeybinds()
}
override fun onKeybindUpdate() {
/*
val fbb = FlatBufferBuilder(32)
val response = buildKeybindResponse(fbb)
val outbound = rpcHandler.createRPCMessage(
fbb,
RpcMessage.KeybindResponse,
response
)
fbb.finish(outbound)
*/
}
override fun sendKeybind() {
}
companion object {
const val FULL_RESET = KeybindName.FULL_RESET
const val YAW_RESET = KeybindName.YAW_RESET
const val MOUNTING_RESET = KeybindName.MOUNTING_RESET
const val PAUSE_TRACKING = KeybindName.PAUSE_TRACKING
const val FEET_MOUNTING_RESET = KeybindName.FEET_MOUNTING_RESET
}
}