mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-08-10 07:07:46 +02:00
6.0
This commit is contained in:
84
src/utils/local-db/base-presets-table.ts
Executable file
84
src/utils/local-db/base-presets-table.ts
Executable file
@@ -0,0 +1,84 @@
|
||||
import type { AllPresets, AllPresetsData, PresetRecord, PresetRecords } from "@/types/presets";
|
||||
import { deepClone } from "../global";
|
||||
import { BaseLocalTable } from "./base-table";
|
||||
|
||||
export abstract class BasePresetsTable<T extends PresetRecord> extends BaseLocalTable<T> {
|
||||
protected abstract TABLE_PRESETS: string;
|
||||
protected abstract DEFAULT_PRESETS: PresetRecords<T>;
|
||||
protected abstract readonly DEFAULT_PRESET_ID: number;
|
||||
|
||||
async newPreset(name: string, data: T['data']) {
|
||||
const newRecord = { name, data } as T;
|
||||
return await this.add(newRecord);
|
||||
}
|
||||
|
||||
async updatePreset(preset: T) {
|
||||
return await this.put(preset);
|
||||
}
|
||||
|
||||
async deletePreset(id: number) {
|
||||
return this.delete(id);
|
||||
}
|
||||
|
||||
async getPreset(id: number): Promise<T | null> {
|
||||
if (id === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (id < 0) {
|
||||
return this.DEFAULT_PRESETS[id];
|
||||
}
|
||||
|
||||
let preset = await this.get(id);
|
||||
if (!preset) {
|
||||
preset = this.DEFAULT_PRESETS[this.DEFAULT_PRESET_ID];
|
||||
}
|
||||
|
||||
return preset;
|
||||
}
|
||||
|
||||
async getPresets(): Promise<AllPresets<T>> {
|
||||
let all = deepClone(this.DEFAULT_PRESETS) as Record<string, T>;
|
||||
const presets: AllPresets<T> = {
|
||||
default: Object.keys(this.DEFAULT_PRESETS).map(key => parseInt(key)),
|
||||
custom: [],
|
||||
data: {},
|
||||
}
|
||||
|
||||
const count = await this.count();
|
||||
if (count > 0) {
|
||||
const items = await this.getAll();
|
||||
|
||||
let id: keyof typeof items;
|
||||
for (id in items) {
|
||||
const item = items[id]!;
|
||||
presets.custom.push(item.id!);
|
||||
all[item.id] = item;
|
||||
}
|
||||
}
|
||||
|
||||
presets.data = all;
|
||||
return presets;
|
||||
}
|
||||
|
||||
async getPresetsData(): Promise<AllPresetsData<T>> {
|
||||
const presetsData: AllPresetsData<T> = {}
|
||||
for (const id in this.DEFAULT_PRESETS) {
|
||||
const preset = this.DEFAULT_PRESETS[id];
|
||||
presetsData[id] = deepClone(preset.data);
|
||||
}
|
||||
|
||||
const count = await this.count();
|
||||
if (count > 0) {
|
||||
const items = await this.getAll();
|
||||
|
||||
let id: keyof typeof items;
|
||||
for (id in items) {
|
||||
const item = items[id]!;
|
||||
presetsData[item.id] = item.data;
|
||||
}
|
||||
}
|
||||
|
||||
return presetsData;
|
||||
}
|
||||
}
|
70
src/utils/local-db/base-table.ts
Executable file
70
src/utils/local-db/base-table.ts
Executable file
@@ -0,0 +1,70 @@
|
||||
import { LocalDb } from "./local-db";
|
||||
|
||||
export class BaseLocalTable<T extends BaseRecord> {
|
||||
private tableName: string;
|
||||
|
||||
constructor(tableName: string) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
protected async prepareTable(type: IDBTransactionMode = 'readonly'): Promise<IDBObjectStore> {
|
||||
const db = await LocalDb.getInstance().open();
|
||||
const transaction = db.transaction(this.tableName, type);
|
||||
const table = transaction.objectStore(this.tableName);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
// Convert IndexDB method to Promise
|
||||
protected call(method: any) {
|
||||
return new Promise(resolve => {
|
||||
const request = method.call(null, ...Array.from(arguments).slice(1));
|
||||
request.onsuccess = (e: Event) => {
|
||||
resolve((e.target as any).result);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async count(): Promise<number> {
|
||||
const table = await this.prepareTable();
|
||||
// @ts-ignore
|
||||
return this.call(table.count.bind(table));
|
||||
}
|
||||
|
||||
async add(data: T): Promise<number> {
|
||||
const table = await this.prepareTable('readwrite');
|
||||
// @ts-ignore
|
||||
return this.call(table.add.bind(table), ...arguments);
|
||||
}
|
||||
|
||||
async put(data: T): Promise<number> {
|
||||
const table = await this.prepareTable('readwrite');
|
||||
// @ts-ignore
|
||||
return this.call(table.put.bind(table), ...arguments);
|
||||
}
|
||||
|
||||
async delete(id: T['id']): Promise<number> {
|
||||
const table = await this.prepareTable('readwrite');
|
||||
// @ts-ignore
|
||||
return this.call(table.delete.bind(table), ...arguments);
|
||||
}
|
||||
|
||||
async get(id: T['id']): Promise<T> {
|
||||
const table = await this.prepareTable();
|
||||
// @ts-ignore
|
||||
return this.call(table.get.bind(table), ...arguments);
|
||||
}
|
||||
|
||||
async getAll(): Promise<{[key: string]: T}> {
|
||||
const table = await this.prepareTable();
|
||||
// @ts-ignore
|
||||
const all = await (this.call(table.getAll.bind(table), ...arguments) as Promise<T[]>);
|
||||
const results: {[key: string]: T} = {};
|
||||
|
||||
all.forEach(item => {
|
||||
results[item.id as T['id']] = item;
|
||||
});
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
38
src/utils/local-db/controller-settings-table.ts
Executable file
38
src/utils/local-db/controller-settings-table.ts
Executable file
@@ -0,0 +1,38 @@
|
||||
import { BaseLocalTable } from "./base-table";
|
||||
import { LocalDb } from "./local-db";
|
||||
import { ControllerShortcutDefaultId } from "./controller-shortcuts-table";
|
||||
import { deepClone } from "../global";
|
||||
|
||||
export class ControllerSettingsTable extends BaseLocalTable<ControllerSettingsRecord> {
|
||||
private static instance: ControllerSettingsTable;
|
||||
public static getInstance = () => ControllerSettingsTable.instance ?? (ControllerSettingsTable.instance = new ControllerSettingsTable(LocalDb.TABLE_CONTROLLER_SETTINGS));
|
||||
|
||||
static readonly DEFAULT_DATA: ControllerSettingsRecord['data'] = {
|
||||
shortcutPresetId: ControllerShortcutDefaultId.DEFAULT,
|
||||
vibrationIntensity: 50,
|
||||
};
|
||||
|
||||
async getControllerData(id: string): Promise<ControllerSettingsRecord['data']> {
|
||||
const setting = await this.get(id);
|
||||
if (!setting) {
|
||||
return deepClone(ControllerSettingsTable.DEFAULT_DATA);
|
||||
}
|
||||
|
||||
return setting.data;
|
||||
}
|
||||
|
||||
async getControllersData() {
|
||||
const all = await this.getAll();
|
||||
const results: {[key: string]: ControllerSettingsRecord['data']} = {};
|
||||
|
||||
for (const key in all) {
|
||||
const settings = all[key].data;
|
||||
// Pre-calculate virabtionIntensity
|
||||
settings.vibrationIntensity /= 100;
|
||||
|
||||
results[key] = settings;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
61
src/utils/local-db/controller-shortcuts-table.ts
Executable file
61
src/utils/local-db/controller-shortcuts-table.ts
Executable file
@@ -0,0 +1,61 @@
|
||||
import type { ControllerShortcutPresetRecord, PresetRecords } from "@/types/presets";
|
||||
import { BxLogger } from "../bx-logger";
|
||||
import { BasePresetsTable } from "./base-presets-table";
|
||||
import { LocalDb } from "./local-db";
|
||||
import { GamepadKey } from "@/enums/gamepad";
|
||||
import { ShortcutAction } from "@/enums/shortcut-actions";
|
||||
import { AppInterface } from "../global";
|
||||
|
||||
export enum ControllerShortcutDefaultId {
|
||||
TYPE_A = -1,
|
||||
TYPE_B = -2,
|
||||
|
||||
DEFAULT = TYPE_A,
|
||||
};
|
||||
|
||||
|
||||
export class ControllerShortcutsTable extends BasePresetsTable<ControllerShortcutPresetRecord> {
|
||||
private static instance: ControllerShortcutsTable;
|
||||
public static getInstance = () => ControllerShortcutsTable.instance ?? (ControllerShortcutsTable.instance = new ControllerShortcutsTable());
|
||||
private readonly LOG_TAG = 'ControllerShortcutsTable';
|
||||
|
||||
protected readonly TABLE_PRESETS: string = LocalDb.TABLE_CONTROLLER_SHORTCUTS;
|
||||
protected readonly DEFAULT_PRESETS: PresetRecords<ControllerShortcutPresetRecord> = {
|
||||
[ControllerShortcutDefaultId.TYPE_A]: {
|
||||
id: ControllerShortcutDefaultId.TYPE_A,
|
||||
name: 'Type A',
|
||||
data: {
|
||||
mapping: {
|
||||
[GamepadKey.Y]: AppInterface ? ShortcutAction.DEVICE_VOLUME_INC : ShortcutAction.STREAM_VOLUME_INC,
|
||||
[GamepadKey.A]: AppInterface ? ShortcutAction.DEVICE_VOLUME_DEC : ShortcutAction.STREAM_VOLUME_DEC,
|
||||
[GamepadKey.X]: ShortcutAction.STREAM_STATS_TOGGLE,
|
||||
[GamepadKey.B]: AppInterface ? ShortcutAction.DEVICE_SOUND_TOGGLE : ShortcutAction.STREAM_SOUND_TOGGLE,
|
||||
[GamepadKey.RB]: ShortcutAction.STREAM_SCREENSHOT_CAPTURE,
|
||||
[GamepadKey.START]: ShortcutAction.STREAM_MENU_SHOW,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
[ControllerShortcutDefaultId.TYPE_B]: {
|
||||
id: ControllerShortcutDefaultId.TYPE_B,
|
||||
name: 'Type B',
|
||||
data: {
|
||||
mapping: {
|
||||
[GamepadKey.UP]: AppInterface ? ShortcutAction.DEVICE_VOLUME_INC : ShortcutAction.STREAM_VOLUME_INC,
|
||||
[GamepadKey.DOWN]: AppInterface ? ShortcutAction.DEVICE_VOLUME_DEC : ShortcutAction.STREAM_VOLUME_DEC,
|
||||
[GamepadKey.RIGHT]: ShortcutAction.STREAM_STATS_TOGGLE,
|
||||
[GamepadKey.LEFT]: AppInterface ? ShortcutAction.DEVICE_SOUND_TOGGLE : ShortcutAction.STREAM_SOUND_TOGGLE,
|
||||
[GamepadKey.LB]: ShortcutAction.STREAM_SCREENSHOT_CAPTURE,
|
||||
[GamepadKey.SELECT]: ShortcutAction.STREAM_MENU_SHOW,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
protected readonly DEFAULT_PRESET_ID = ControllerShortcutDefaultId.DEFAULT;
|
||||
|
||||
private constructor() {
|
||||
super(LocalDb.TABLE_CONTROLLER_SHORTCUTS);
|
||||
BxLogger.info(this.LOG_TAG, 'constructor()');
|
||||
}
|
||||
}
|
45
src/utils/local-db/keyboard-shortcuts-table.ts
Executable file
45
src/utils/local-db/keyboard-shortcuts-table.ts
Executable file
@@ -0,0 +1,45 @@
|
||||
import type { KeyboardShortcutPresetRecord, PresetRecords } from "@/types/presets";
|
||||
import { BxLogger } from "../bx-logger";
|
||||
import { BasePresetsTable } from "./base-presets-table";
|
||||
import { LocalDb } from "./local-db";
|
||||
import { ShortcutAction } from "@/enums/shortcut-actions";
|
||||
import { t } from "../translation";
|
||||
|
||||
export enum KeyboardShortcutDefaultId {
|
||||
OFF = 0,
|
||||
STANDARD = -1,
|
||||
|
||||
DEFAULT = STANDARD,
|
||||
};
|
||||
|
||||
|
||||
export class KeyboardShortcutsTable extends BasePresetsTable<KeyboardShortcutPresetRecord> {
|
||||
private static instance: KeyboardShortcutsTable;
|
||||
public static getInstance = () => KeyboardShortcutsTable.instance ?? (KeyboardShortcutsTable.instance = new KeyboardShortcutsTable());
|
||||
private readonly LOG_TAG = 'KeyboardShortcutsTable';
|
||||
|
||||
protected readonly TABLE_PRESETS: string = LocalDb.TABLE_KEYBOARD_SHORTCUTS;
|
||||
protected readonly DEFAULT_PRESETS: PresetRecords<KeyboardShortcutPresetRecord> = {
|
||||
[KeyboardShortcutDefaultId.DEFAULT]: {
|
||||
id: KeyboardShortcutDefaultId.DEFAULT,
|
||||
name: t('standard'),
|
||||
data: {
|
||||
mapping: {
|
||||
[ShortcutAction.MKB_TOGGLE]: {
|
||||
code: 'F8',
|
||||
},
|
||||
[ShortcutAction.STREAM_SCREENSHOT_CAPTURE]: {
|
||||
code: 'Slash',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
protected readonly DEFAULT_PRESET_ID = KeyboardShortcutDefaultId.DEFAULT;
|
||||
|
||||
private constructor() {
|
||||
super(LocalDb.TABLE_KEYBOARD_SHORTCUTS);
|
||||
BxLogger.info(this.LOG_TAG, 'constructor()');
|
||||
}
|
||||
}
|
113
src/utils/local-db/local-db.ts
Normal file → Executable file
113
src/utils/local-db/local-db.ts
Normal file → Executable file
@@ -1,18 +1,65 @@
|
||||
export abstract class LocalDb {
|
||||
export class LocalDb {
|
||||
private static instance: LocalDb;
|
||||
public static getInstance = () => LocalDb.instance ?? (LocalDb.instance = new LocalDb());
|
||||
// private readonly LOG_TAG = 'LocalDb';
|
||||
|
||||
static readonly DB_NAME = 'BetterXcloud';
|
||||
static readonly DB_VERSION = 2;
|
||||
static readonly DB_VERSION = 3;
|
||||
|
||||
protected db!: IDBDatabase;
|
||||
static readonly TABLE_VIRTUAL_CONTROLLERS = 'virtual_controllers';
|
||||
static readonly TABLE_CONTROLLER_SHORTCUTS = 'controller_shortcuts';
|
||||
static readonly TABLE_CONTROLLER_SETTINGS = 'controller_settings';
|
||||
static readonly TABLE_KEYBOARD_SHORTCUTS = 'keyboard_shortcuts';
|
||||
|
||||
protected open() {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
private db!: IDBDatabase;
|
||||
|
||||
open() {
|
||||
return new Promise<IDBDatabase>((resolve, reject) => {
|
||||
if (this.db) {
|
||||
resolve();
|
||||
resolve(this.db);
|
||||
return;
|
||||
}
|
||||
|
||||
const request = window.indexedDB.open(LocalDb.DB_NAME, LocalDb.DB_VERSION);
|
||||
request.onupgradeneeded = this.onUpgradeNeeded.bind(this);
|
||||
request.onupgradeneeded = (e: IDBVersionChangeEvent) => {
|
||||
const db = (e.target! as any).result as IDBDatabase;
|
||||
|
||||
// Delete "undefined" table
|
||||
if (db.objectStoreNames.contains('undefined')) {
|
||||
db.deleteObjectStore('undefined');
|
||||
}
|
||||
|
||||
// Virtual controller
|
||||
if (!db.objectStoreNames.contains(LocalDb.TABLE_VIRTUAL_CONTROLLERS)) {
|
||||
db.createObjectStore(LocalDb.TABLE_VIRTUAL_CONTROLLERS, {
|
||||
keyPath: 'id',
|
||||
autoIncrement: true,
|
||||
});
|
||||
}
|
||||
|
||||
// Controller shortcuts
|
||||
if (!db.objectStoreNames.contains(LocalDb.TABLE_CONTROLLER_SHORTCUTS)) {
|
||||
db.createObjectStore(LocalDb.TABLE_CONTROLLER_SHORTCUTS, {
|
||||
keyPath: 'id',
|
||||
autoIncrement: true,
|
||||
});
|
||||
}
|
||||
|
||||
// Controller settings
|
||||
if (!db.objectStoreNames.contains(LocalDb.TABLE_CONTROLLER_SETTINGS)) {
|
||||
db.createObjectStore(LocalDb.TABLE_CONTROLLER_SETTINGS, {
|
||||
keyPath: 'id',
|
||||
});
|
||||
}
|
||||
|
||||
// Keyboard shortcuts
|
||||
if (!db.objectStoreNames.contains(LocalDb.TABLE_KEYBOARD_SHORTCUTS)) {
|
||||
db.createObjectStore(LocalDb.TABLE_KEYBOARD_SHORTCUTS, {
|
||||
keyPath: 'id',
|
||||
autoIncrement: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
request.onerror = e => {
|
||||
console.log(e);
|
||||
@@ -22,58 +69,8 @@ export abstract class LocalDb {
|
||||
|
||||
request.onsuccess = e => {
|
||||
this.db = (e.target as any).result;
|
||||
resolve();
|
||||
resolve(this.db);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract onUpgradeNeeded(e: IDBVersionChangeEvent): void;
|
||||
|
||||
protected table(name: string, type: IDBTransactionMode): Promise<IDBObjectStore> {
|
||||
const transaction = this.db.transaction(name, type || 'readonly');
|
||||
const table = transaction.objectStore(name);
|
||||
|
||||
return new Promise(resolve => resolve(table));
|
||||
}
|
||||
|
||||
// Convert IndexDB method to Promise
|
||||
protected call(method: any) {
|
||||
const table = arguments[1];
|
||||
return new Promise(resolve => {
|
||||
const request = method.call(table, ...Array.from(arguments).slice(2));
|
||||
request.onsuccess = (e: Event) => {
|
||||
resolve([table, (e.target as any).result]);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
protected count(table: IDBObjectStore): Promise<[IDBObjectStore, number]> {
|
||||
// @ts-ignore
|
||||
return this.call(table.count, ...arguments);
|
||||
}
|
||||
|
||||
protected add(table: IDBObjectStore, data: any): Promise<[IDBObjectStore, number]> {
|
||||
// @ts-ignore
|
||||
return this.call(table.add, ...arguments);
|
||||
}
|
||||
|
||||
protected put(table: IDBObjectStore, data: any): Promise<[IDBObjectStore, number]> {
|
||||
// @ts-ignore
|
||||
return this.call(table.put, ...arguments);
|
||||
}
|
||||
|
||||
protected delete(table: IDBObjectStore, data: any): Promise<[IDBObjectStore, number]> {
|
||||
// @ts-ignore
|
||||
return this.call(table.delete, ...arguments);
|
||||
}
|
||||
|
||||
protected get(table: IDBObjectStore, id: number): Promise<any> {
|
||||
// @ts-ignore
|
||||
return this.call(table.get, ...arguments);
|
||||
}
|
||||
|
||||
protected getAll(table: IDBObjectStore): Promise<[IDBObjectStore, any]> {
|
||||
// @ts-ignore
|
||||
return this.call(table.getAll, ...arguments);
|
||||
}
|
||||
}
|
||||
|
126
src/utils/local-db/mkb-mapping-presets-table.ts
Executable file
126
src/utils/local-db/mkb-mapping-presets-table.ts
Executable file
@@ -0,0 +1,126 @@
|
||||
import { LocalDb } from "./local-db";
|
||||
import { BxLogger } from "../bx-logger";
|
||||
import { BasePresetsTable } from "./base-presets-table";
|
||||
import type { MkbPresetRecord, PresetRecords } from "@/types/presets";
|
||||
import { MkbPresetKey, MouseMapTo, MouseButtonCode } from "@/enums/mkb";
|
||||
import { GamepadKey } from "@/enums/gamepad";
|
||||
import { t } from "../translation";
|
||||
|
||||
export const enum MkbMappingDefaultPresetId {
|
||||
OFF = 0,
|
||||
STANDARD = -1,
|
||||
SHOOTER = -2,
|
||||
|
||||
DEFAULT = STANDARD,
|
||||
};
|
||||
|
||||
export class MkbMappingPresetsTable extends BasePresetsTable<MkbPresetRecord> {
|
||||
private static instance: MkbMappingPresetsTable;
|
||||
public static getInstance = () => MkbMappingPresetsTable.instance ?? (MkbMappingPresetsTable.instance = new MkbMappingPresetsTable());
|
||||
private readonly LOG_TAG = 'MkbMappingPresetsTable';
|
||||
|
||||
protected readonly TABLE_PRESETS = LocalDb.TABLE_VIRTUAL_CONTROLLERS;
|
||||
protected readonly DEFAULT_PRESETS: PresetRecords<MkbPresetRecord> = {
|
||||
[MkbMappingDefaultPresetId.STANDARD]: {
|
||||
id: MkbMappingDefaultPresetId.STANDARD,
|
||||
name: t('standard'),
|
||||
data: {
|
||||
mapping: {
|
||||
[GamepadKey.HOME]: ['Backquote'],
|
||||
|
||||
[GamepadKey.UP]: ['ArrowUp', 'Digit1'],
|
||||
[GamepadKey.DOWN]: ['ArrowDown', 'Digit2'],
|
||||
[GamepadKey.LEFT]: ['ArrowLeft', 'Digit3'],
|
||||
[GamepadKey.RIGHT]: ['ArrowRight', 'Digit4'],
|
||||
|
||||
[GamepadKey.LS_UP]: ['KeyW'],
|
||||
[GamepadKey.LS_DOWN]: ['KeyS'],
|
||||
[GamepadKey.LS_LEFT]: ['KeyA'],
|
||||
[GamepadKey.LS_RIGHT]: ['KeyD'],
|
||||
|
||||
[GamepadKey.RS_UP]: ['KeyU'],
|
||||
[GamepadKey.RS_DOWN]: ['KeyJ'],
|
||||
[GamepadKey.RS_LEFT]: ['KeyH'],
|
||||
[GamepadKey.RS_RIGHT]: ['KeyK'],
|
||||
|
||||
[GamepadKey.A]: ['Space', 'KeyE'],
|
||||
[GamepadKey.X]: ['KeyR'],
|
||||
[GamepadKey.B]: ['KeyC', 'Backspace'],
|
||||
[GamepadKey.Y]: ['KeyE'],
|
||||
|
||||
[GamepadKey.START]: ['Enter'],
|
||||
[GamepadKey.SELECT]: ['Tab'],
|
||||
|
||||
[GamepadKey.LB]: ['KeyQ'],
|
||||
[GamepadKey.RB]: ['KeyF'],
|
||||
|
||||
[GamepadKey.RT]: [MouseButtonCode.LEFT_CLICK],
|
||||
[GamepadKey.LT]: [MouseButtonCode.RIGHT_CLICK],
|
||||
|
||||
[GamepadKey.L3]: ['KeyX'],
|
||||
[GamepadKey.R3]: ['KeyZ'],
|
||||
},
|
||||
mouse: {
|
||||
[MkbPresetKey.MOUSE_MAP_TO]: MouseMapTo.RS,
|
||||
[MkbPresetKey.MOUSE_SENSITIVITY_X]: 100,
|
||||
[MkbPresetKey.MOUSE_SENSITIVITY_Y]: 100,
|
||||
[MkbPresetKey.MOUSE_DEADZONE_COUNTERWEIGHT]: 20,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
[MkbMappingDefaultPresetId.SHOOTER]: {
|
||||
id: MkbMappingDefaultPresetId.SHOOTER,
|
||||
name: 'Shooter',
|
||||
data: {
|
||||
mapping: {
|
||||
[GamepadKey.HOME]: ['Backquote'],
|
||||
|
||||
[GamepadKey.UP]: ['ArrowUp'],
|
||||
[GamepadKey.DOWN]: ['ArrowDown'],
|
||||
[GamepadKey.LEFT]: ['ArrowLeft'],
|
||||
[GamepadKey.RIGHT]: ['ArrowRight'],
|
||||
|
||||
[GamepadKey.LS_UP]: ['KeyW'],
|
||||
[GamepadKey.LS_DOWN]: ['KeyS'],
|
||||
[GamepadKey.LS_LEFT]: ['KeyA'],
|
||||
[GamepadKey.LS_RIGHT]: ['KeyD'],
|
||||
|
||||
[GamepadKey.RS_UP]: ['KeyI'],
|
||||
[GamepadKey.RS_DOWN]: ['KeyK'],
|
||||
[GamepadKey.RS_LEFT]: ['KeyJ'],
|
||||
[GamepadKey.RS_RIGHT]: ['KeyL'],
|
||||
|
||||
[GamepadKey.A]: ['Space', 'KeyE'],
|
||||
[GamepadKey.X]: ['KeyR'],
|
||||
[GamepadKey.B]: ['ControlLeft', 'Backspace'],
|
||||
[GamepadKey.Y]: ['KeyV'],
|
||||
|
||||
[GamepadKey.START]: ['Enter'],
|
||||
[GamepadKey.SELECT]: ['Tab'],
|
||||
|
||||
[GamepadKey.LB]: ['KeyC', 'KeyG'],
|
||||
[GamepadKey.RB]: ['KeyQ'],
|
||||
|
||||
[GamepadKey.RT]: [MouseButtonCode.LEFT_CLICK],
|
||||
[GamepadKey.LT]: [MouseButtonCode.RIGHT_CLICK],
|
||||
|
||||
[GamepadKey.L3]: ['ShiftLeft'],
|
||||
[GamepadKey.R3]: ['KeyF'],
|
||||
},
|
||||
mouse: {
|
||||
[MkbPresetKey.MOUSE_MAP_TO]: MouseMapTo.RS,
|
||||
[MkbPresetKey.MOUSE_SENSITIVITY_X]: 100,
|
||||
[MkbPresetKey.MOUSE_SENSITIVITY_Y]: 100,
|
||||
[MkbPresetKey.MOUSE_DEADZONE_COUNTERWEIGHT]: 20,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
protected readonly DEFAULT_PRESET_ID = MkbMappingDefaultPresetId.DEFAULT;
|
||||
|
||||
private constructor() {
|
||||
super(LocalDb.TABLE_VIRTUAL_CONTROLLERS);
|
||||
BxLogger.info(this.LOG_TAG, 'constructor()');
|
||||
}
|
||||
}
|
@@ -1,102 +0,0 @@
|
||||
import { PrefKey } from "@/enums/pref-keys";
|
||||
import { MkbPreset } from "@/modules/mkb/mkb-preset";
|
||||
import type { MkbStoredPreset, MkbStoredPresets } from "@/types/mkb";
|
||||
import { setPref } from "../settings-storages/global-settings-storage";
|
||||
import { t } from "../translation";
|
||||
import { LocalDb } from "./local-db";
|
||||
import { BxLogger } from "../bx-logger";
|
||||
|
||||
export class MkbPresetsDb extends LocalDb {
|
||||
private static instance: MkbPresetsDb;
|
||||
public static getInstance = () => MkbPresetsDb.instance ?? (MkbPresetsDb.instance = new MkbPresetsDb());
|
||||
private readonly LOG_TAG = 'MkbPresetsDb';
|
||||
|
||||
private readonly TABLE_PRESETS = 'mkb_presets';
|
||||
|
||||
private constructor() {
|
||||
super();
|
||||
BxLogger.info(this.LOG_TAG, 'constructor()');
|
||||
}
|
||||
|
||||
private createTable(db: IDBDatabase) {
|
||||
const presets = db.createObjectStore(this.TABLE_PRESETS, {
|
||||
keyPath: 'id',
|
||||
autoIncrement: true,
|
||||
});
|
||||
presets.createIndex('name_idx', 'name');
|
||||
}
|
||||
|
||||
protected onUpgradeNeeded(e: IDBVersionChangeEvent): void {
|
||||
const db = (e.target! as any).result as IDBDatabase;
|
||||
|
||||
if (db.objectStoreNames.contains('undefined')) {
|
||||
db.deleteObjectStore('undefined');
|
||||
}
|
||||
|
||||
if (!db.objectStoreNames.contains(this.TABLE_PRESETS)) {
|
||||
this.createTable(db);
|
||||
}
|
||||
}
|
||||
|
||||
private async presetsTable() {
|
||||
await this.open();
|
||||
return await this.table(this.TABLE_PRESETS, 'readwrite');
|
||||
}
|
||||
|
||||
async newPreset(name: string, data: any) {
|
||||
const table = await this.presetsTable();
|
||||
const [, id] = await this.add(table, { name, data });
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
async updatePreset(preset: MkbStoredPreset) {
|
||||
const table = await this.presetsTable();
|
||||
const [, id] = await this.put(table, preset);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
async deletePreset(id: number) {
|
||||
const table = await this.presetsTable();
|
||||
await this.delete(table, id);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
async getPreset(id: number): Promise<MkbStoredPreset> {
|
||||
const table = await this.presetsTable();
|
||||
const [, preset] = await this.get(table, id);
|
||||
|
||||
return preset;
|
||||
}
|
||||
|
||||
async getPresets(): Promise<MkbStoredPresets> {
|
||||
const table = await this.presetsTable();
|
||||
const [, count] = await this.count(table);
|
||||
|
||||
// Return stored presets
|
||||
if (count > 0) {
|
||||
const [, items] = await this.getAll(table);
|
||||
const presets: MkbStoredPresets = {};
|
||||
items.forEach((item: MkbStoredPreset) => (presets[item.id!] = item));
|
||||
|
||||
return presets;
|
||||
}
|
||||
|
||||
// Create "Default" preset when the table is empty
|
||||
const preset: MkbStoredPreset = {
|
||||
name: t('default'),
|
||||
data: MkbPreset.DEFAULT_PRESET,
|
||||
};
|
||||
|
||||
const [, id] = await this.add(table, preset);
|
||||
|
||||
preset.id = id;
|
||||
setPref(PrefKey.MKB_DEFAULT_PRESET_ID, id);
|
||||
|
||||
return {
|
||||
[id]: preset,
|
||||
};
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user