mirror of
https://github.com/SlimeVR/SlimeVR-Server.git
synced 2026-04-05 18:01:56 +02:00
Add settings reset & advanced section (#1154)
Co-authored-by: Uriel <imurx@proton.me> Co-authored-by: Butterscotch! <5095026+ButterscotchV@users.noreply.github.com> Co-authored-by: lucas lelievre <loucass003@gmail.com>
This commit is contained in:
@@ -280,6 +280,7 @@ settings-sidebar-utils = Utilities
|
||||
settings-sidebar-serial = Serial console
|
||||
settings-sidebar-appearance = Appearance
|
||||
settings-sidebar-notifications = Notifications
|
||||
settings-sidebar-advanced = Advanced
|
||||
|
||||
## SteamVR settings
|
||||
settings-general-steamvr = SteamVR
|
||||
@@ -603,6 +604,32 @@ settings-osc-vmc-mirror_tracking = Mirror tracking
|
||||
settings-osc-vmc-mirror_tracking-description = Mirror the tracking horizontally.
|
||||
settings-osc-vmc-mirror_tracking-label = Mirror tracking
|
||||
|
||||
## Advanced settings
|
||||
settings-utils-advanced = Advanced
|
||||
|
||||
settings-utils-advanced-reset-gui = Reset GUI settings
|
||||
settings-utils-advanced-reset-gui-description = Restore the default settings for the interface.
|
||||
settings-utils-advanced-reset-gui-label = Reset GUI
|
||||
settings-utils-advanced-reset-server = Reset tracking settings
|
||||
settings-utils-advanced-reset-server-description = Restore the default settings for the tracking.
|
||||
settings-utils-advanced-reset-server-label = Reset tracking
|
||||
settings-utils-advanced-reset-all = Reset all settings
|
||||
settings-utils-advanced-reset-all-description = Restore the default settings for both the interface and tracking.
|
||||
settings-utils-advanced-reset-all-label = Reset all
|
||||
settings-utils-advanced-reset_warning =
|
||||
<b>Warning:</b> This will reset { $type ->
|
||||
[gui] your GUI
|
||||
[server] your tracking
|
||||
*[all] all your
|
||||
} settings to the defaults.
|
||||
Are you sure you want to do this?
|
||||
settings-utils-advanced-reset_warning-reset = Reset settings
|
||||
settings-utils-advanced-reset_warning-cancel = Cancel
|
||||
|
||||
settings-utils-advanced-open_data = Data folder
|
||||
settings-utils-advanced-open_data-description = Open SlimeVR's data folder in file explorer, containing config and log files.
|
||||
settings-utils-advanced-open_data-label = Open folder
|
||||
|
||||
## Setup/onboarding menu
|
||||
onboarding-skip = Skip setup
|
||||
onboarding-continue = Continue
|
||||
@@ -810,11 +837,11 @@ onboarding-choose_mounting = What mounting calibration method to use?
|
||||
# Multiline text
|
||||
onboarding-choose_mounting-description = Mounting orientation corrects for the placement of trackers on your body.
|
||||
onboarding-choose_mounting-auto_mounting = Automatic mounting
|
||||
# Italized text
|
||||
# Italicized text
|
||||
onboarding-choose_mounting-auto_mounting-label-v2 = Recommended
|
||||
onboarding-choose_mounting-auto_mounting-description = This will automatically detect the mounting orientations for all of your trackers from 2 poses
|
||||
onboarding-choose_mounting-manual_mounting = Manual mounting
|
||||
# Italized text
|
||||
# Italicized text
|
||||
onboarding-choose_mounting-manual_mounting-label-v2 = Might not be precise enough
|
||||
onboarding-choose_mounting-manual_mounting-description = This will let you choose the mounting orientation manually for each tracker
|
||||
# Multiline text
|
||||
@@ -858,14 +885,14 @@ onboarding-choose_proportions-description-v1 = Body proportions are used to know
|
||||
When proportions of your body don't match the ones saved, your tracking precision will be worse and you will notice things like skating or sliding, or your body not matching your avatar well.
|
||||
<b>You only need to measure your body once!</b> Unless they are wrong or your body has changed, then you don't need to do them again.
|
||||
onboarding-choose_proportions-auto_proportions = Automatic proportions
|
||||
# Italized text
|
||||
# Italicized text
|
||||
onboarding-choose_proportions-auto_proportions-subtitle = Recommended
|
||||
onboarding-choose_proportions-auto_proportions-descriptionv3 =
|
||||
This will guess your proportions by recording a sample of your movements and passing it through an algorithm.
|
||||
|
||||
<b>This requires having your headset (HMD) connected to SlimeVR and on your head!</b>
|
||||
onboarding-choose_proportions-manual_proportions = Manual proportions
|
||||
# Italized text
|
||||
# Italicized text
|
||||
onboarding-choose_proportions-manual_proportions-subtitle = For small touches
|
||||
onboarding-choose_proportions-manual_proportions-description = This will let you adjust your proportions manually by modifying them directly
|
||||
onboarding-choose_proportions-export = Export proportions
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
"all": true
|
||||
},
|
||||
"shell": {
|
||||
"open": true
|
||||
"open": "^((https?://\\w+)|(file://)).+"
|
||||
},
|
||||
"window": {
|
||||
"close": true,
|
||||
|
||||
@@ -55,6 +55,7 @@ import { AppLayout } from './AppLayout';
|
||||
import { Preload } from './components/Preload';
|
||||
import { UnknownDeviceModal } from './components/UnknownDeviceModal';
|
||||
import { useDiscordPresence } from './hooks/discord-presence';
|
||||
import { AdvancedSettings } from './components/settings/pages/AdvancedSettings';
|
||||
|
||||
export const GH_REPO = 'SlimeVR/SlimeVR-Server';
|
||||
export const VersionContext = createContext('');
|
||||
@@ -110,6 +111,7 @@ function Layout() {
|
||||
<Route path="osc/vrchat" element={<VRCOSCSettings />} />
|
||||
<Route path="osc/vmc" element={<VMCSettings />} />
|
||||
<Route path="interface" element={<InterfaceSettings />} />
|
||||
<Route path="advanced" element={<AdvancedSettings />} />
|
||||
</Route>
|
||||
<Route
|
||||
path="/onboarding"
|
||||
|
||||
16
gui/src/components/commons/icon/BugIcon.tsx
Normal file
16
gui/src/components/commons/icon/BugIcon.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
export function BugIcon() {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
className="size-6"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M8.478 1.6a.75.75 0 0 1 .273 1.026 3.72 3.72 0 0 0-.425 1.121c.058.058.118.114.18.168A4.491 4.491 0 0 1 12 2.25c1.413 0 2.673.651 3.497 1.668.06-.054.12-.11.178-.167a3.717 3.717 0 0 0-.426-1.125.75.75 0 1 1 1.298-.752 5.22 5.22 0 0 1 .671 2.046.75.75 0 0 1-.187.582c-.241.27-.505.52-.787.749a4.494 4.494 0 0 1 .216 2.1c-.106.792-.753 1.295-1.417 1.403-.182.03-.364.057-.547.081.152.227.273.476.359.742a23.122 23.122 0 0 0 3.832-.803 23.241 23.241 0 0 0-.345-2.634.75.75 0 0 1 1.474-.28c.21 1.115.348 2.256.404 3.418a.75.75 0 0 1-.516.75c-1.527.499-3.119.854-4.76 1.049-.074.38-.22.735-.423 1.05 2.066.209 4.058.672 5.943 1.358a.75.75 0 0 1 .492.75 24.665 24.665 0 0 1-1.189 6.25.75.75 0 0 1-1.425-.47 23.14 23.14 0 0 0 1.077-5.306c-.5-.169-1.009-.32-1.524-.455.068.234.104.484.104.746 0 3.956-2.521 7.5-6 7.5-3.478 0-6-3.544-6-7.5 0-.262.037-.511.104-.746-.514.135-1.022.286-1.522.455.154 1.838.52 3.616 1.077 5.307a.75.75 0 1 1-1.425.468 24.662 24.662 0 0 1-1.19-6.25.75.75 0 0 1 .493-.749 24.586 24.586 0 0 1 4.964-1.24h.01c.321-.046.644-.085.969-.118a2.983 2.983 0 0 1-.424-1.05 24.614 24.614 0 0 1-4.76-1.05.75.75 0 0 1-.516-.75c.057-1.16.194-2.302.405-3.417a.75.75 0 0 1 1.474.28c-.164.862-.28 1.74-.345 2.634 1.237.371 2.517.642 3.832.803.085-.266.207-.515.359-.742a18.698 18.698 0 0 1-.547-.08c-.664-.11-1.311-.612-1.417-1.404a4.535 4.535 0 0 1 .217-2.103 6.788 6.788 0 0 1-.788-.751.75.75 0 0 1-.187-.583 5.22 5.22 0 0 1 .67-2.04.75.75 0 0 1 1.026-.273Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -19,14 +19,12 @@ export function HandsWarningModal({
|
||||
*/
|
||||
onClose: () => void;
|
||||
/**
|
||||
* Function when you press `i understand`
|
||||
* Function when you press `Yes`
|
||||
*/
|
||||
accept: () => void;
|
||||
} & ReactModal.Props) {
|
||||
const { l10n } = useLocalization();
|
||||
|
||||
// isOpen is checked by checking if the parent modal is opened + our bodyPart is the
|
||||
// neck and we havent showed this warning yet
|
||||
return (
|
||||
<BaseModal
|
||||
isOpen={isOpen}
|
||||
|
||||
@@ -40,6 +40,10 @@ export function SettingSelectorMobile() {
|
||||
label: l10n.getString('settings-sidebar-serial'),
|
||||
value: { url: '/settings/serial' },
|
||||
},
|
||||
{
|
||||
label: l10n.getString('settings-sidebar-advanced'),
|
||||
value: { url: '/settings/advanced' },
|
||||
},
|
||||
];
|
||||
|
||||
const { control, watch, handleSubmit, setValue } = useForm<{
|
||||
|
||||
73
gui/src/components/settings/SettingsResetModal.tsx
Normal file
73
gui/src/components/settings/SettingsResetModal.tsx
Normal file
@@ -0,0 +1,73 @@
|
||||
import { Button } from '@/components/commons/Button';
|
||||
import { WarningBox } from '@/components/commons/TipBox';
|
||||
import { Localized, useLocalization } from '@fluent/react';
|
||||
import { BaseModal } from '@/components/commons/BaseModal';
|
||||
import ReactModal from 'react-modal';
|
||||
|
||||
export function SettingsResetModal({
|
||||
isOpen = true,
|
||||
onClose,
|
||||
accept,
|
||||
variant,
|
||||
...props
|
||||
}: {
|
||||
/**
|
||||
* Is the parent/sibling component opened?
|
||||
*/
|
||||
isOpen: boolean;
|
||||
/**
|
||||
* Function to trigger when the warning hasn't been accepted
|
||||
*/
|
||||
onClose: () => void;
|
||||
/**
|
||||
* Function when you press `Reset settings`
|
||||
*/
|
||||
accept: () => void;
|
||||
/**
|
||||
* Type of reset
|
||||
*/
|
||||
variant: 'gui' | 'server' | 'all';
|
||||
} & ReactModal.Props) {
|
||||
const { l10n } = useLocalization();
|
||||
|
||||
return (
|
||||
<BaseModal
|
||||
isOpen={isOpen}
|
||||
shouldCloseOnOverlayClick
|
||||
onRequestClose={onClose}
|
||||
className={props.className}
|
||||
overlayClassName={props.overlayClassName}
|
||||
>
|
||||
<div className="flex w-full h-full flex-col ">
|
||||
<div className="flex flex-col flex-grow items-center gap-3">
|
||||
<Localized
|
||||
id="settings-utils-advanced-reset_warning"
|
||||
elems={{ b: <b></b> }}
|
||||
vars={{ type: variant }}
|
||||
>
|
||||
<WarningBox>
|
||||
<b>Warning:</b> This will reset your {variant} settings to the
|
||||
defaults.
|
||||
<br />
|
||||
Are you sure you want to do this?
|
||||
</WarningBox>
|
||||
</Localized>
|
||||
|
||||
<div className="flex flex-row gap-3 pt-5 place-content-center">
|
||||
<Button variant="primary" onClick={onClose}>
|
||||
{l10n.getString('settings-utils-advanced-reset_warning-cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="tertiary"
|
||||
onClick={() => {
|
||||
accept();
|
||||
}}
|
||||
>
|
||||
{l10n.getString('settings-utils-advanced-reset_warning-reset')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseModal>
|
||||
);
|
||||
}
|
||||
@@ -41,6 +41,7 @@ export function SettingsLink({
|
||||
|
||||
export function SettingsSidebar() {
|
||||
const { l10n } = useLocalization();
|
||||
|
||||
return (
|
||||
<div className="flex flex-col px-5 py-5 gap-3 overflow-y-auto bg-background-70 rounded-lg h-full">
|
||||
<Typography variant="main-title">
|
||||
@@ -100,6 +101,11 @@ export function SettingsSidebar() {
|
||||
{l10n.getString('settings-sidebar-serial')}
|
||||
</SettingsLink>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<SettingsLink to="/settings/advanced">
|
||||
{l10n.getString('settings-sidebar-advanced')}
|
||||
</SettingsLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
190
gui/src/components/settings/pages/AdvancedSettings.tsx
Normal file
190
gui/src/components/settings/pages/AdvancedSettings.tsx
Normal file
@@ -0,0 +1,190 @@
|
||||
import { useLocalization } from '@fluent/react';
|
||||
import { useState } from 'react';
|
||||
import { Typography } from '@/components/commons/Typography';
|
||||
import {
|
||||
SettingsPageLayout,
|
||||
SettingsPagePaneLayout,
|
||||
} from '@/components/settings/SettingsPageLayout';
|
||||
import { BugIcon } from '@/components/commons/icon/BugIcon';
|
||||
import { Button } from '@/components/commons/Button';
|
||||
import { SettingsResetModal } from '@/components/settings/SettingsResetModal';
|
||||
|
||||
import { open } from '@tauri-apps/plugin-shell';
|
||||
import { error } from '@/utils/logging';
|
||||
import { appConfigDir } from '@tauri-apps/api/path';
|
||||
import { defaultConfig as defaultGUIConfig, useConfig } from '@/hooks/config';
|
||||
import { defaultValues as defaultDevConfig } from '@/components/widgets/DeveloperModeWidget';
|
||||
import { RpcMessage, SettingsResetRequestT } from 'solarxr-protocol';
|
||||
import { useWebsocketAPI } from '@/hooks/websocket-api';
|
||||
|
||||
function guiDefaults() {
|
||||
// Destructure the properties to exclude "lang"
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { lang, ...guiDefaults } = defaultGUIConfig;
|
||||
|
||||
// Include "devSettings" which has all the properties of "defaultDevConfig"
|
||||
// @ts-expect-error "devSettings" is not in the "guiDefaults" object but we want to include it (from "defaultDevConfig")
|
||||
guiDefaults.devSettings = defaultDevConfig;
|
||||
|
||||
return guiDefaults;
|
||||
}
|
||||
|
||||
export function AdvancedSettings() {
|
||||
const { l10n } = useLocalization();
|
||||
const { setConfig } = useConfig();
|
||||
|
||||
const [showWarningGUI, setShowWarningGUI] = useState(false);
|
||||
const [showWarningServer, setShowWarningServer] = useState(false);
|
||||
const [showWarningAll, setShowWarningAll] = useState(false);
|
||||
const { sendRPCPacket } = useWebsocketAPI();
|
||||
|
||||
const openConfigFolder = async () => {
|
||||
try {
|
||||
const configPath = await appConfigDir();
|
||||
await open('file://' + configPath);
|
||||
} catch (err) {
|
||||
error('Failed to open config folder:', err);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<SettingsPageLayout>
|
||||
<form className="flex flex-col gap-2 w-full">
|
||||
<SettingsPagePaneLayout icon={<BugIcon></BugIcon>} id="advanced">
|
||||
<>
|
||||
<Typography variant="main-title">
|
||||
{l10n.getString('settings-utils-advanced')}
|
||||
</Typography>
|
||||
|
||||
<div className="grid gap-4 mobile:gap-6">
|
||||
<div className="sm:grid sm:grid-cols-[1.75fr,_1fr] items-center">
|
||||
<div>
|
||||
<Typography bold>
|
||||
{l10n.getString('settings-utils-advanced-reset-gui')}
|
||||
</Typography>
|
||||
<div className="flex flex-col pt-1">
|
||||
<Typography color="secondary">
|
||||
{l10n.getString(
|
||||
'settings-utils-advanced-reset-gui-description'
|
||||
)}
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => setShowWarningGUI(true)}
|
||||
>
|
||||
{l10n.getString('settings-utils-advanced-reset-gui-label')}
|
||||
</Button>
|
||||
<SettingsResetModal
|
||||
accept={() => {
|
||||
setConfig(guiDefaults());
|
||||
setShowWarningGUI(false);
|
||||
}}
|
||||
onClose={() => setShowWarningGUI(false)}
|
||||
isOpen={showWarningGUI}
|
||||
variant="gui"
|
||||
></SettingsResetModal>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="sm:grid sm:grid-cols-[1.75fr,_1fr] items-center">
|
||||
<div>
|
||||
<Typography bold>
|
||||
{l10n.getString('settings-utils-advanced-reset-server')}
|
||||
</Typography>
|
||||
<div className="flex flex-col pt-1">
|
||||
<Typography color="secondary">
|
||||
{l10n.getString(
|
||||
'settings-utils-advanced-reset-server-description'
|
||||
)}
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => setShowWarningServer(true)}
|
||||
>
|
||||
{l10n.getString(
|
||||
'settings-utils-advanced-reset-server-label'
|
||||
)}
|
||||
</Button>
|
||||
<SettingsResetModal
|
||||
accept={() => {
|
||||
sendRPCPacket(
|
||||
RpcMessage.SettingsResetRequest,
|
||||
new SettingsResetRequestT()
|
||||
);
|
||||
setShowWarningServer(false);
|
||||
}}
|
||||
onClose={() => setShowWarningServer(false)}
|
||||
isOpen={showWarningServer}
|
||||
variant="server"
|
||||
></SettingsResetModal>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="sm:grid sm:grid-cols-[1.75fr,_1fr] items-center">
|
||||
<div>
|
||||
<Typography bold>
|
||||
{l10n.getString('settings-utils-advanced-reset-all')}
|
||||
</Typography>
|
||||
<div className="flex flex-col pt-1">
|
||||
<Typography color="secondary">
|
||||
{l10n.getString(
|
||||
'settings-utils-advanced-reset-all-description'
|
||||
)}
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => setShowWarningAll(true)}
|
||||
>
|
||||
{l10n.getString('settings-utils-advanced-reset-all-label')}
|
||||
</Button>
|
||||
<SettingsResetModal
|
||||
accept={() => {
|
||||
sendRPCPacket(
|
||||
RpcMessage.SettingsResetRequest,
|
||||
new SettingsResetRequestT()
|
||||
);
|
||||
setConfig(guiDefaults());
|
||||
setShowWarningAll(false);
|
||||
}}
|
||||
onClose={() => setShowWarningAll(false)}
|
||||
isOpen={showWarningAll}
|
||||
variant="all"
|
||||
></SettingsResetModal>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="sm:grid sm:grid-cols-[1.75fr,_1fr] items-center">
|
||||
<div>
|
||||
<Typography bold>
|
||||
{l10n.getString('settings-utils-advanced-open_data')}
|
||||
</Typography>
|
||||
<div className="flex flex-col pt-1">
|
||||
<Typography color="secondary">
|
||||
{l10n.getString(
|
||||
'settings-utils-advanced-open_data-description'
|
||||
)}
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<Button variant="secondary" onClick={openConfigFolder}>
|
||||
{l10n.getString('settings-utils-advanced-open_data-label')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</SettingsPagePaneLayout>
|
||||
</form>
|
||||
</SettingsPageLayout>
|
||||
);
|
||||
}
|
||||
@@ -98,6 +98,7 @@ export function InterfaceSettings() {
|
||||
<SettingsPageLayout>
|
||||
<form
|
||||
className="flex flex-col gap-2 w-full"
|
||||
// Don't resize the font size for this page because you have access to font resizing on it and we don't want to break the layout just in case
|
||||
style={
|
||||
{
|
||||
'--font-size': '12rem',
|
||||
|
||||
@@ -16,6 +16,16 @@ export interface DeveloperModeWidgetForm {
|
||||
moreInfo: boolean;
|
||||
}
|
||||
|
||||
export const defaultValues: DeveloperModeWidgetForm = {
|
||||
highContrast: false,
|
||||
preciseRotation: false,
|
||||
fastDataFeed: false,
|
||||
filterSlimesAndHMD: false,
|
||||
sortByName: false,
|
||||
rawSlimeRotation: false,
|
||||
moreInfo: false,
|
||||
};
|
||||
|
||||
export function DeveloperModeWidget() {
|
||||
const { l10n } = useLocalization();
|
||||
const { config, setConfig } = useConfig();
|
||||
@@ -23,15 +33,7 @@ export function DeveloperModeWidget() {
|
||||
|
||||
const { reset, control, handleSubmit, watch } =
|
||||
useForm<DeveloperModeWidgetForm>({
|
||||
defaultValues: {
|
||||
highContrast: false,
|
||||
preciseRotation: false,
|
||||
fastDataFeed: false,
|
||||
filterSlimesAndHMD: false,
|
||||
sortByName: false,
|
||||
rawSlimeRotation: false,
|
||||
moreInfo: false,
|
||||
},
|
||||
defaultValues: defaultValues,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -139,6 +139,11 @@ public class ConfigManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void resetConfig() {
|
||||
this.vrConfig = new VRConfig();
|
||||
saveConfig();
|
||||
}
|
||||
|
||||
public VRConfig getVrConfig() {
|
||||
return vrConfig;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,9 @@ class RPCSettingsHandler(var rpcHandler: RPCHandler, var api: ProtocolAPI) {
|
||||
messageHeader,
|
||||
)
|
||||
}
|
||||
rpcHandler.registerPacketListener(RpcMessage.SettingsResetRequest) { conn: GenericConnection, messageHeader: RpcMessageHeader? ->
|
||||
this.onSettingsResetRequest(conn, messageHeader)
|
||||
}
|
||||
}
|
||||
|
||||
fun onSettingsRequest(conn: GenericConnection, messageHeader: RpcMessageHeader?) {
|
||||
@@ -345,6 +348,10 @@ class RPCSettingsHandler(var rpcHandler: RPCHandler, var api: ProtocolAPI) {
|
||||
api.server.configManager.saveConfig()
|
||||
}
|
||||
|
||||
fun onSettingsResetRequest(conn: GenericConnection, messageHeader: RpcMessageHeader?) {
|
||||
api.server.configManager.resetConfig()
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun sendSteamVRUpdatedSettings(api: ProtocolAPI, rpcHandler: RPCHandler) {
|
||||
val fbb = FlatBufferBuilder(32)
|
||||
|
||||
Submodule solarxr-protocol updated: 3a22ee6e5b...e4540a5129
Reference in New Issue
Block a user