diff --git a/.github/workflows/desktop-build.yml b/.github/workflows/desktop-build.yml index aeed5da81..efd2acb9b 100644 --- a/.github/workflows/desktop-build.yml +++ b/.github/workflows/desktop-build.yml @@ -220,10 +220,7 @@ jobs: continue-on-error: true env: GH_TOKEN: ${{ github.token }} - run: | - if gh cache delete --repo ${{ github.repository }} ${{ steps.ccache_restore.outputs.cache-primary-key }}; then - echo "Cache deleted successfully" - fi + run: gh cache delete --repo ${{ github.repository }} ${{ steps.ccache_restore.outputs.cache-primary-key }} - name: Save updated compiler cache (ccache) if: github.ref == 'refs/heads/master' @@ -472,10 +469,7 @@ jobs: continue-on-error: true env: GH_TOKEN: ${{ github.token }} - run: | - if gh cache delete --repo ${{ github.repository }} ${{ steps.ccache_restore.outputs.cache-primary-key }}; then - echo "Cache deleted successfully" - fi + run: gh cache delete --repo ${{ github.repository }} ${{ steps.ccache_restore.outputs.cache-primary-key }} - name: Save updated compiler cache (ccache) if: github.ref == 'refs/heads/master' && matrix.use_ccache == 1 diff --git a/cockatrice/src/game/player/player_event_handler.cpp b/cockatrice/src/game/player/player_event_handler.cpp index 6fb1ff19a..5571010d1 100644 --- a/cockatrice/src/game/player/player_event_handler.cpp +++ b/cockatrice/src/game/player/player_event_handler.cpp @@ -60,6 +60,7 @@ void PlayerEventHandler::eventShuffle(const Event_Shuffle &event) // we want to close empty views as well if (length == 0 || length > absStart) { // note this assumes views always start at the top of the library view->close(); + break; } } else { qWarning() << zone->getName() << "of" << player->getPlayerInfo()->getName() << "holds empty zoneview!"; @@ -594,4 +595,4 @@ void PlayerEventHandler::processGameEvent(GameEvent::GameEventType type, qWarning() << "unhandled game event" << type; } } -} +} \ No newline at end of file diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_settings.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_settings.cpp index 6238bc80b..e3bf209dc 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_settings.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_settings.cpp @@ -1785,7 +1785,7 @@ DlgSettings::DlgSettings(QWidget *parent) : QDialog(parent) contentsWidget->setSpacing(5); pagesWidget = new QStackedWidget; - pagesWidget->addWidget(makeScrollable(new GeneralSettingsPage)); + pagesWidget->addWidget(new GeneralSettingsPage); pagesWidget->addWidget(makeScrollable(new AppearanceSettingsPage)); pagesWidget->addWidget(makeScrollable(new UserInterfaceSettingsPage)); pagesWidget->addWidget(new DeckEditorSettingsPage); diff --git a/webclient/src/api/AuthenticationService.tsx b/webclient/src/api/AuthenticationService.tsx index 7b3a46988..368390708 100644 --- a/webclient/src/api/AuthenticationService.tsx +++ b/webclient/src/api/AuthenticationService.tsx @@ -1,6 +1,5 @@ import { StatusEnum, User, WebSocketConnectReason, WebSocketConnectOptions } from 'types'; import { SessionCommands, webClient } from 'websocket'; -import { ProtoController } from 'websocket/services/ProtoController'; export class AuthenticationService { static login(options: WebSocketConnectOptions): void { @@ -40,7 +39,7 @@ export class AuthenticationService { } static isModerator(user: User): boolean { - const moderatorLevel = ProtoController.root.ServerInfo_User.UserLevelFlag.IsModerator; + const moderatorLevel = webClient.protobuf.controller.ServerInfo_User.UserLevelFlag.IsModerator; // @TODO tell cockatrice not to do this so shittily return (user.userLevel & moderatorLevel) === moderatorLevel; } diff --git a/webclient/src/api/ModeratorService.tsx b/webclient/src/api/ModeratorService.tsx index 6c22ee55e..e7c8822e8 100644 --- a/webclient/src/api/ModeratorService.tsx +++ b/webclient/src/api/ModeratorService.tsx @@ -23,7 +23,7 @@ export class ModeratorService { ModeratorCommands.viewLogHistory(filters); } - static warnUser(userName: string, reason: string, clientid?: string, removeMessages?: number): void { - ModeratorCommands.warnUser(userName, reason, clientid, removeMessages); + static warnUser(userName: string, reason: string, clientid?: string, removeMessage?: boolean): void { + ModeratorCommands.warnUser(userName, reason, clientid, removeMessage); } } diff --git a/webclient/src/api/SessionService.tsx b/webclient/src/api/SessionService.tsx index 2787f098d..051954f93 100644 --- a/webclient/src/api/SessionService.tsx +++ b/webclient/src/api/SessionService.tsx @@ -1,4 +1,6 @@ import { SessionCommands } from 'websocket'; +import { common } from 'protobufjs'; +import IBytesValue = common.IBytesValue; export class SessionService { static addToBuddyList(userName: string) { @@ -25,7 +27,7 @@ export class SessionService { SessionCommands.accountEdit(passwordCheck, realName, email, country); } - static changeAccountImage(image: Uint8Array): void { + static changeAccountImage(image: IBytesValue): void { SessionCommands.accountImage(image); } diff --git a/webclient/src/store/server/server.actions.ts b/webclient/src/store/server/server.actions.ts index 8af5adb75..ed1f06977 100644 --- a/webclient/src/store/server/server.actions.ts +++ b/webclient/src/store/server/server.actions.ts @@ -1,4 +1,4 @@ -import { DeckList, DeckStorageTreeItem, ReplayMatch, WebSocketConnectOptions } from 'types'; +import { WebSocketConnectOptions } from 'types'; import { Types } from './server.types'; export const Actions = { @@ -210,33 +210,4 @@ export const Actions = { type: Types.WARN_USER, userName, }), - grantReplayAccess: (replayId: number, moderatorName: string) => ({ - type: Types.GRANT_REPLAY_ACCESS, - replayId, - moderatorName, - }), - forceActivateUser: (usernameToActivate: string, moderatorName: string) => ({ - type: Types.FORCE_ACTIVATE_USER, - usernameToActivate, - moderatorName, - }), - getAdminNotes: (userName: string, notes: string) => ({ - type: Types.GET_ADMIN_NOTES, - userName, - notes, - }), - updateAdminNotes: (userName: string, notes: string) => ({ - type: Types.UPDATE_ADMIN_NOTES, - userName, - notes, - }), - replayList: (matchList: ReplayMatch[]) => ({ type: Types.REPLAY_LIST, matchList }), - replayAdded: (matchInfo: ReplayMatch) => ({ type: Types.REPLAY_ADDED, matchInfo }), - replayModifyMatch: (gameId: number, doNotHide: boolean) => ({ type: Types.REPLAY_MODIFY_MATCH, gameId, doNotHide }), - replayDeleteMatch: (gameId: number) => ({ type: Types.REPLAY_DELETE_MATCH, gameId }), - backendDecks: (deckList: DeckList) => ({ type: Types.BACKEND_DECKS, deckList }), - deckNewDir: (path: string, dirName: string) => ({ type: Types.DECK_NEW_DIR, path, dirName }), - deckDelDir: (path: string) => ({ type: Types.DECK_DEL_DIR, path }), - deckUpload: (path: string, treeItem: DeckStorageTreeItem) => ({ type: Types.DECK_UPLOAD, path, treeItem }), - deckDelete: (deckId: number) => ({ type: Types.DECK_DELETE, deckId }), } diff --git a/webclient/src/store/server/server.dispatch.ts b/webclient/src/store/server/server.dispatch.ts index 3d3b6d360..3a958043a 100644 --- a/webclient/src/store/server/server.dispatch.ts +++ b/webclient/src/store/server/server.dispatch.ts @@ -1,7 +1,7 @@ import { reset } from 'redux-form'; import { Actions } from './server.actions'; import { store } from 'store'; -import { DeckList, DeckStorageTreeItem, ReplayMatch, WebSocketConnectOptions } from 'types'; +import { WebSocketConnectOptions } from 'types'; export const Dispatch = { initialized: () => { @@ -177,43 +177,4 @@ export const Dispatch = { warnUser: (userName) => { store.dispatch(Actions.warnUser(userName)) }, - grantReplayAccess: (replayId: number, moderatorName: string) => { - store.dispatch(Actions.grantReplayAccess(replayId, moderatorName)); - }, - forceActivateUser: (usernameToActivate: string, moderatorName: string) => { - store.dispatch(Actions.forceActivateUser(usernameToActivate, moderatorName)); - }, - getAdminNotes: (userName: string, notes: string) => { - store.dispatch(Actions.getAdminNotes(userName, notes)); - }, - updateAdminNotes: (userName: string, notes: string) => { - store.dispatch(Actions.updateAdminNotes(userName, notes)); - }, - replayList: (matchList: ReplayMatch[]) => { - store.dispatch(Actions.replayList(matchList)); - }, - replayAdded: (matchInfo: ReplayMatch) => { - store.dispatch(Actions.replayAdded(matchInfo)); - }, - replayModifyMatch: (gameId: number, doNotHide: boolean) => { - store.dispatch(Actions.replayModifyMatch(gameId, doNotHide)); - }, - replayDeleteMatch: (gameId: number) => { - store.dispatch(Actions.replayDeleteMatch(gameId)); - }, - backendDecks: (deckList: DeckList) => { - store.dispatch(Actions.backendDecks(deckList)); - }, - deckNewDir: (path: string, dirName: string) => { - store.dispatch(Actions.deckNewDir(path, dirName)); - }, - deckDelDir: (path: string) => { - store.dispatch(Actions.deckDelDir(path)); - }, - deckUpload: (path: string, treeItem: DeckStorageTreeItem) => { - store.dispatch(Actions.deckUpload(path, treeItem)); - }, - deckDelete: (deckId: number) => { - store.dispatch(Actions.deckDelete(deckId)); - }, } diff --git a/webclient/src/store/server/server.interfaces.ts b/webclient/src/store/server/server.interfaces.ts index 97e9d99da..499197852 100644 --- a/webclient/src/store/server/server.interfaces.ts +++ b/webclient/src/store/server/server.interfaces.ts @@ -1,6 +1,4 @@ -import { - WarnHistoryItem, BanHistoryItem, DeckList, LogItem, ReplayMatch, SortBy, User, UserSortField, WebSocketConnectOptions, WarnListItem -} from 'types'; +import { WarnHistoryItem, BanHistoryItem, LogItem, SortBy, User, UserSortField, WebSocketConnectOptions, WarnListItem } from 'types'; import { NotifyUserData, ServerShutdownData, UserMessageData } from 'websocket/events/session/interfaces'; export interface ServerConnectParams { @@ -69,9 +67,6 @@ export interface ServerState { }; warnListOptions: WarnListItem[]; warnUser: string; - adminNotes: { [userName: string]: string }; - replays: ReplayMatch[]; - backendDecks: DeckList | null; } export interface ServerStateStatus { diff --git a/webclient/src/store/server/server.reducer.ts b/webclient/src/store/server/server.reducer.ts index a63418eeb..46daa4007 100644 --- a/webclient/src/store/server/server.reducer.ts +++ b/webclient/src/store/server/server.reducer.ts @@ -1,60 +1,10 @@ -import { DeckStorageFolder, DeckStorageTreeItem, SortDirection, StatusEnum, UserLevelFlag, UserSortField } from 'types'; +import { SortDirection, StatusEnum, UserLevelFlag, UserSortField } from 'types'; import { SortUtil } from '../common'; import { ServerState } from './server.interfaces' import { Types } from './server.types'; -function splitPath(path: string): string[] { - return path ? path.split('/') : []; -} - -function insertAtPath(folder: DeckStorageFolder, pathSegments: string[], item: DeckStorageTreeItem): DeckStorageFolder { - if (pathSegments.length === 0 || (pathSegments.length === 1 && pathSegments[0] === '')) { - return { items: [...folder.items, item] }; - } - const [head, ...tail] = pathSegments; - const match = folder.items.find(child => child.name === head && child.folder); - if (match) { - return { - items: folder.items.map(child => - child === match - ? { ...child, folder: insertAtPath(child.folder!, tail, item) } - : child - ), - }; - } - const created: DeckStorageTreeItem = { id: 0, name: head, file: null, folder: insertAtPath({ items: [] }, tail, item) }; - return { items: [...folder.items, created] }; -} - -function removeById(folder: DeckStorageFolder, id: number): DeckStorageFolder { - return { - items: folder.items - .filter(item => item.id !== id) - .map(item => - item.folder ? { ...item, folder: removeById(item.folder, id) } : item - ), - }; -} - -function removeByPath(folder: DeckStorageFolder, pathSegments: string[]): DeckStorageFolder { - if (pathSegments.length === 0 || (pathSegments.length === 1 && pathSegments[0] === '')) { - return folder; - } - const [head, ...tail] = pathSegments; - if (tail.length === 0) { - return { items: folder.items.filter(item => !(item.name === head && item.folder !== null)) }; - } - return { - items: folder.items.map(item => - item.name === head && item.folder - ? { ...item, folder: removeByPath(item.folder, tail) } - : item - ), - }; -} - const initialState: ServerState = { initialized: false, buddyList: [], @@ -90,9 +40,6 @@ const initialState: ServerState = { warnHistory: {}, warnListOptions: [], warnUser: '', - adminNotes: {}, - replays: [], - backendDecks: null, }; export const serverReducer = (state = initialState, action: any) => { @@ -300,7 +247,7 @@ export const serverReducer = (state = initialState, action: any) => { messages: { ...state.messages, [userName]: [ - ...(state.messages[userName] ?? []), + ...state.messages[userName], action.messageData, ], } @@ -381,17 +328,6 @@ export const serverReducer = (state = initialState, action: any) => { warnUser: userName, }; } - case Types.GET_ADMIN_NOTES: - case Types.UPDATE_ADMIN_NOTES: { - const { userName, notes } = action; - return { - ...state, - adminNotes: { - ...state.adminNotes, - [userName]: notes, - } - }; - } case Types.ADJUST_MOD: { const { userName, shouldBeMod, shouldBeJudge } = action; @@ -410,71 +346,6 @@ export const serverReducer = (state = initialState, action: any) => { }) }; } - case Types.REPLAY_LIST: { - return { ...state, replays: [...action.matchList] }; - } - case Types.REPLAY_ADDED: { - return { ...state, replays: [...state.replays, action.matchInfo] }; - } - case Types.REPLAY_MODIFY_MATCH: { - return { - ...state, - replays: state.replays.map(r => - r.gameId === action.gameId ? { ...r, doNotHide: action.doNotHide } : r - ), - }; - } - case Types.REPLAY_DELETE_MATCH: { - return { ...state, replays: state.replays.filter(r => r.gameId !== action.gameId) }; - } - case Types.BACKEND_DECKS: { - return { ...state, backendDecks: action.deckList }; - } - case Types.DECK_UPLOAD: { - if (!state.backendDecks) { - return state; - } - return { - ...state, - backendDecks: { - root: insertAtPath(state.backendDecks.root, splitPath(action.path), action.treeItem), - }, - }; - } - case Types.DECK_DELETE: { - if (!state.backendDecks) { - return state; - } - return { - ...state, - backendDecks: { - root: removeById(state.backendDecks.root, action.deckId), - }, - }; - } - case Types.DECK_NEW_DIR: { - if (!state.backendDecks) { - return state; - } - const newFolder: DeckStorageTreeItem = { id: 0, name: action.dirName, file: null, folder: { items: [] } }; - return { - ...state, - backendDecks: { - root: insertAtPath(state.backendDecks.root, splitPath(action.path), newFolder), - }, - }; - } - case Types.DECK_DEL_DIR: { - if (!state.backendDecks) { - return state; - } - return { - ...state, - backendDecks: { - root: removeByPath(state.backendDecks.root, splitPath(action.path)), - }, - }; - } default: return state; } diff --git a/webclient/src/store/server/server.selectors.ts b/webclient/src/store/server/server.selectors.ts index fa9f82297..263946425 100644 --- a/webclient/src/store/server/server.selectors.ts +++ b/webclient/src/store/server/server.selectors.ts @@ -16,7 +16,5 @@ export const Selectors = { getUsers: ({ server }: State) => server.users, getLogs: ({ server }: State) => server.logs, getBuddyList: ({ server }: State) => server.buddyList, - getIgnoreList: ({ server }: State) => server.ignoreList, - getReplays: ({ server }: State) => server.replays, - getBackendDecks: ({ server }: State) => server.backendDecks, + getIgnoreList: ({ server }: State) => server.ignoreList } diff --git a/webclient/src/store/server/server.types.ts b/webclient/src/store/server/server.types.ts index fb4249011..ab9307295 100644 --- a/webclient/src/store/server/server.types.ts +++ b/webclient/src/store/server/server.types.ts @@ -54,19 +54,4 @@ export const Types = { WARN_HISTORY: '[Server] Warn History', WARN_LIST_OPTIONS: '[Server] Warn List Options', WARN_USER: '[Server] Warn User', - GRANT_REPLAY_ACCESS: '[Server] Grant Replay Access', - FORCE_ACTIVATE_USER: '[Server] Force Activate User', - GET_ADMIN_NOTES: '[Server] Get Admin Notes', - UPDATE_ADMIN_NOTES: '[Server] Update Admin Notes', - // Replay - REPLAY_LIST: '[Server] Replay List', - REPLAY_ADDED: '[Server] Replay Added', - REPLAY_MODIFY_MATCH: '[Server] Replay Modify Match', - REPLAY_DELETE_MATCH: '[Server] Replay Delete Match', - // Deck Storage - BACKEND_DECKS: '[Server] Backend Decks', - DECK_NEW_DIR: '[Server] Deck New Dir', - DECK_DEL_DIR: '[Server] Deck Del Dir', - DECK_UPLOAD: '[Server] Deck Upload', - DECK_DELETE: '[Server] Deck Delete', }; diff --git a/webclient/src/types/deckList.ts b/webclient/src/types/deckList.ts index 9d7d792a6..18212079e 100644 --- a/webclient/src/types/deckList.ts +++ b/webclient/src/types/deckList.ts @@ -13,6 +13,6 @@ export interface DeckStorageFile { export interface DeckStorageTreeItem { id: number; name: string; - file: DeckStorageFile | null; - folder: DeckStorageFolder | null; + file: DeckStorageFile; + folder: DeckStorageFolder; } diff --git a/webclient/src/types/index.ts b/webclient/src/types/index.ts index ded9962e5..00838a16d 100644 --- a/webclient/src/types/index.ts +++ b/webclient/src/types/index.ts @@ -16,4 +16,3 @@ export * from './logs'; export * from './session'; export * from './deckList'; export * from './moderator'; -export * from './replay'; diff --git a/webclient/src/types/logs.ts b/webclient/src/types/logs.ts index 3cf34b486..4c2f0364e 100644 --- a/webclient/src/types/logs.ts +++ b/webclient/src/types/logs.ts @@ -1,10 +1,8 @@ export interface LogFilters { - userName?: string; - ipAddress?: string; - gameName?: string; - gameId?: string; - message?: string; - logLocation?: string[]; - dateRange: number; - maximumResults?: number; + userName: string; + ipAddress: string; + gameName: string; + gameId: string; + message: string; + logLocation: string; } diff --git a/webclient/src/types/replay.ts b/webclient/src/types/replay.ts deleted file mode 100644 index dfa78538a..000000000 --- a/webclient/src/types/replay.ts +++ /dev/null @@ -1,16 +0,0 @@ -export interface Replay { - replayId: number; - replayName: string; - duration: number; -} - -export interface ReplayMatch { - replayList: Replay[]; - gameId: number; - roomName: string; - timeStarted: number; - length: number; - gameName: string; - playerNames: string[]; - doNotHide: boolean; -} diff --git a/webclient/src/websocket/commands/admin/adjustMod.ts b/webclient/src/websocket/commands/admin/adjustMod.ts index fd71fece1..5e8a83153 100644 --- a/webclient/src/websocket/commands/admin/adjustMod.ts +++ b/webclient/src/websocket/commands/admin/adjustMod.ts @@ -1,10 +1,26 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { AdminPersistence } from '../../persistence'; export function adjustMod(userName: string, shouldBeMod?: boolean, shouldBeJudge?: boolean): void { - BackendService.sendAdminCommand('Command_AdjustMod', { userName, shouldBeMod, shouldBeJudge }, { - onSuccess: () => { - AdminPersistence.adjustMod(userName, shouldBeMod, shouldBeJudge); - }, + const command = webClient.protobuf.controller.Command_AdjustMod.create({ userName, shouldBeMod, shouldBeJudge }); + const sc = webClient.protobuf.controller.AdminCommand.create({ '.Command_AdjustMod.ext': command }); + + webClient.protobuf.sendAdminCommand(sc, (raw) => { + const { responseCode } = raw; + + let error: string; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + AdminPersistence.adjustMod(userName, shouldBeMod, shouldBeJudge); + return; + default: + error = 'Failed to reload config.'; + break; + } + + if (error) { + console.error(responseCode, error); + } }); } diff --git a/webclient/src/websocket/commands/admin/reloadConfig.ts b/webclient/src/websocket/commands/admin/reloadConfig.ts index 979f3ec73..16d2a574b 100644 --- a/webclient/src/websocket/commands/admin/reloadConfig.ts +++ b/webclient/src/websocket/commands/admin/reloadConfig.ts @@ -1,10 +1,26 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { AdminPersistence } from '../../persistence'; export function reloadConfig(): void { - BackendService.sendAdminCommand('Command_ReloadConfig', {}, { - onSuccess: () => { - AdminPersistence.reloadConfig(); - }, + const command = webClient.protobuf.controller.Command_ReloadConfig.create(); + const sc = webClient.protobuf.controller.AdminCommand.create({ '.Command_ReloadConfig.ext': command }); + + webClient.protobuf.sendAdminCommand(sc, (raw) => { + const { responseCode } = raw; + + let error: string; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + AdminPersistence.reloadConfig(); + return; + default: + error = 'Failed to reload config.'; + break; + } + + if (error) { + console.error(responseCode, error); + } }); } diff --git a/webclient/src/websocket/commands/admin/shutdownServer.ts b/webclient/src/websocket/commands/admin/shutdownServer.ts index e65c900db..0624e823d 100644 --- a/webclient/src/websocket/commands/admin/shutdownServer.ts +++ b/webclient/src/websocket/commands/admin/shutdownServer.ts @@ -1,10 +1,26 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { AdminPersistence } from '../../persistence'; export function shutdownServer(reason: string, minutes: number): void { - BackendService.sendAdminCommand('Command_ShutdownServer', { reason, minutes }, { - onSuccess: () => { - AdminPersistence.shutdownServer(); - }, + const command = webClient.protobuf.controller.Command_ShutdownServer.create({ reason, minutes }); + const sc = webClient.protobuf.controller.AdminCommand.create({ '.Command_ShutdownServer.ext': command }); + + webClient.protobuf.sendAdminCommand(sc, (raw) => { + const { responseCode } = raw; + + let error: string; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + AdminPersistence.shutdownServer(); + return; + default: + error = 'Failed to update server message.'; + break; + } + + if (error) { + console.error(responseCode, error); + } }); } diff --git a/webclient/src/websocket/commands/admin/updateServerMessage.ts b/webclient/src/websocket/commands/admin/updateServerMessage.ts index e2b194514..cb025f5a9 100644 --- a/webclient/src/websocket/commands/admin/updateServerMessage.ts +++ b/webclient/src/websocket/commands/admin/updateServerMessage.ts @@ -1,10 +1,26 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { AdminPersistence } from '../../persistence'; export function updateServerMessage(): void { - BackendService.sendAdminCommand('Command_UpdateServerMessage', {}, { - onSuccess: () => { - AdminPersistence.updateServerMessage(); - }, + const command = webClient.protobuf.controller.Command_UpdateServerMessage.create(); + const sc = webClient.protobuf.controller.AdminCommand.create({ '.Command_UpdateServerMessage.ext': command }); + + webClient.protobuf.sendAdminCommand(sc, (raw) => { + const { responseCode } = raw; + + let error: string; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + AdminPersistence.updateServerMessage(); + return; + default: + error = 'Failed to update server message.'; + break; + } + + if (error) { + console.error(responseCode, error); + } }); } diff --git a/webclient/src/websocket/commands/moderator/banFromServer.ts b/webclient/src/websocket/commands/moderator/banFromServer.ts index e45e34504..028eb4606 100644 --- a/webclient/src/websocket/commands/moderator/banFromServer.ts +++ b/webclient/src/websocket/commands/moderator/banFromServer.ts @@ -1,13 +1,29 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { ModeratorPersistence } from '../../persistence'; export function banFromServer(minutes: number, userName?: string, address?: string, reason?: string, visibleReason?: string, clientid?: string, removeMessages?: number): void { - BackendService.sendModeratorCommand('Command_BanFromServer', { + const command = webClient.protobuf.controller.Command_BanFromServer.create({ minutes, userName, address, reason, visibleReason, clientid, removeMessages - }, { - onSuccess: () => { - ModeratorPersistence.banFromServer(userName); - }, + }); + const sc = webClient.protobuf.controller.ModeratorCommand.create({ '.Command_BanFromServer.ext': command }); + + webClient.protobuf.sendModeratorCommand(sc, (raw) => { + const { responseCode } = raw; + + let error: string; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + ModeratorPersistence.banFromServer(userName); + return; + default: + error = 'Failed to ban user.'; + break; + } + + if (error) { + console.error(responseCode, error); + } }); } diff --git a/webclient/src/websocket/commands/moderator/forceActivateUser.ts b/webclient/src/websocket/commands/moderator/forceActivateUser.ts deleted file mode 100644 index d4138a015..000000000 --- a/webclient/src/websocket/commands/moderator/forceActivateUser.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { BackendService } from '../../services/BackendService'; -import { ModeratorPersistence } from '../../persistence'; - -export function forceActivateUser(usernameToActivate: string, moderatorName: string): void { - BackendService.sendModeratorCommand('Command_ForceActivateUser', { usernameToActivate, moderatorName }, { - onSuccess: () => { - ModeratorPersistence.forceActivateUser(usernameToActivate, moderatorName); - }, - }); -} diff --git a/webclient/src/websocket/commands/moderator/getAdminNotes.ts b/webclient/src/websocket/commands/moderator/getAdminNotes.ts deleted file mode 100644 index d4f626aa2..000000000 --- a/webclient/src/websocket/commands/moderator/getAdminNotes.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { BackendService } from '../../services/BackendService'; -import { ModeratorPersistence } from '../../persistence'; - -export function getAdminNotes(userName: string): void { - BackendService.sendModeratorCommand('Command_GetAdminNotes', { userName }, { - responseName: 'Response_GetAdminNotes', - onSuccess: (response) => { - ModeratorPersistence.getAdminNotes(userName, response.notes); - }, - }); -} diff --git a/webclient/src/websocket/commands/moderator/getBanHistory.ts b/webclient/src/websocket/commands/moderator/getBanHistory.ts index dd4e90eda..3378f5842 100644 --- a/webclient/src/websocket/commands/moderator/getBanHistory.ts +++ b/webclient/src/websocket/commands/moderator/getBanHistory.ts @@ -1,11 +1,27 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { ModeratorPersistence } from '../../persistence'; export function getBanHistory(userName: string): void { - BackendService.sendModeratorCommand('Command_GetBanHistory', { userName }, { - responseName: 'Response_BanHistory', - onSuccess: (response) => { - ModeratorPersistence.banHistory(userName, response.banList); - }, + const command = webClient.protobuf.controller.Command_GetBanHistory.create({ userName }); + const sc = webClient.protobuf.controller.ModeratorCommand.create({ '.Command_GetBanHistory.ext': command }); + + webClient.protobuf.sendModeratorCommand(sc, (raw) => { + const { responseCode } = raw; + + let error: string; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + const { banList } = raw['.Response_BanHistory.ext']; + ModeratorPersistence.banHistory(userName, banList); + return; + default: + error = 'Failed to get ban history.'; + break; + } + + if (error) { + console.error(responseCode, error); + } }); } diff --git a/webclient/src/websocket/commands/moderator/getWarnHistory.ts b/webclient/src/websocket/commands/moderator/getWarnHistory.ts index c47e2c6e4..fce008eec 100644 --- a/webclient/src/websocket/commands/moderator/getWarnHistory.ts +++ b/webclient/src/websocket/commands/moderator/getWarnHistory.ts @@ -1,11 +1,27 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { ModeratorPersistence } from '../../persistence'; export function getWarnHistory(userName: string): void { - BackendService.sendModeratorCommand('Command_GetWarnHistory', { userName }, { - responseName: 'Response_WarnHistory', - onSuccess: (response) => { - ModeratorPersistence.warnHistory(userName, response.warnList); - }, + const command = webClient.protobuf.controller.Command_GetWarnHistory.create({ userName }); + const sc = webClient.protobuf.controller.ModeratorCommand.create({ '.Command_GetWarnHistory.ext': command }); + + webClient.protobuf.sendModeratorCommand(sc, (raw) => { + const { responseCode } = raw; + + let error: string; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + const { warnList } = raw['.Response_WarnHistory.ext']; + ModeratorPersistence.warnHistory(userName, warnList); + return; + default: + error = 'Failed to get warn history.'; + break; + } + + if (error) { + console.error(responseCode, error); + } }); } diff --git a/webclient/src/websocket/commands/moderator/getWarnList.ts b/webclient/src/websocket/commands/moderator/getWarnList.ts index 412aee09e..f83e5eb1b 100644 --- a/webclient/src/websocket/commands/moderator/getWarnList.ts +++ b/webclient/src/websocket/commands/moderator/getWarnList.ts @@ -1,11 +1,27 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { ModeratorPersistence } from '../../persistence'; export function getWarnList(modName: string, userName: string, userClientid: string): void { - BackendService.sendModeratorCommand('Command_GetWarnList', { modName, userName, userClientid }, { - responseName: 'Response_WarnList', - onSuccess: (response) => { - ModeratorPersistence.warnListOptions(response.warning); - }, + const command = webClient.protobuf.controller.Command_GetWarnList.create({ modName, userName, userClientid }); + const sc = webClient.protobuf.controller.ModeratorCommand.create({ '.Command_GetWarnList.ext': command }); + + webClient.protobuf.sendModeratorCommand(sc, (raw) => { + const { responseCode } = raw; + + let error: string; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + const { warning } = raw['.Response_WarnList.ext']; + ModeratorPersistence.warnListOptions(warning); + return; + default: + error = 'Failed to get warn list.'; + break; + } + + if (error) { + console.error(responseCode, error); + } }); } diff --git a/webclient/src/websocket/commands/moderator/grantReplayAccess.ts b/webclient/src/websocket/commands/moderator/grantReplayAccess.ts deleted file mode 100644 index 74d64d17a..000000000 --- a/webclient/src/websocket/commands/moderator/grantReplayAccess.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { BackendService } from '../../services/BackendService'; -import { ModeratorPersistence } from '../../persistence'; - -export function grantReplayAccess(replayId: number, moderatorName: string): void { - BackendService.sendModeratorCommand('Command_GrantReplayAccess', { replayId, moderatorName }, { - onSuccess: () => { - ModeratorPersistence.grantReplayAccess(replayId, moderatorName); - }, - }); -} diff --git a/webclient/src/websocket/commands/moderator/index.ts b/webclient/src/websocket/commands/moderator/index.ts index 10bb0e1c6..cb4f2455c 100644 --- a/webclient/src/websocket/commands/moderator/index.ts +++ b/webclient/src/websocket/commands/moderator/index.ts @@ -1,10 +1,6 @@ export * from './banFromServer'; -export * from './forceActivateUser'; -export * from './getAdminNotes'; export * from './getBanHistory'; export * from './getWarnHistory'; export * from './getWarnList'; -export * from './grantReplayAccess'; -export * from './updateAdminNotes'; export * from './viewLogHistory'; export * from './warnUser'; diff --git a/webclient/src/websocket/commands/moderator/updateAdminNotes.ts b/webclient/src/websocket/commands/moderator/updateAdminNotes.ts deleted file mode 100644 index c7ac315c5..000000000 --- a/webclient/src/websocket/commands/moderator/updateAdminNotes.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { BackendService } from '../../services/BackendService'; -import { ModeratorPersistence } from '../../persistence'; - -export function updateAdminNotes(userName: string, notes: string): void { - BackendService.sendModeratorCommand('Command_UpdateAdminNotes', { userName, notes }, { - onSuccess: () => { - ModeratorPersistence.updateAdminNotes(userName, notes); - }, - }); -} diff --git a/webclient/src/websocket/commands/moderator/viewLogHistory.ts b/webclient/src/websocket/commands/moderator/viewLogHistory.ts index 19a930608..29e3c4bd6 100644 --- a/webclient/src/websocket/commands/moderator/viewLogHistory.ts +++ b/webclient/src/websocket/commands/moderator/viewLogHistory.ts @@ -1,12 +1,28 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { ModeratorPersistence } from '../../persistence'; import { LogFilters } from 'types'; export function viewLogHistory(filters: LogFilters): void { - BackendService.sendModeratorCommand('Command_ViewLogHistory', filters, { - responseName: 'Response_ViewLogHistory', - onSuccess: (response) => { - ModeratorPersistence.viewLogs(response.logMessage); - }, + const command = webClient.protobuf.controller.Command_ViewLogHistory.create(filters); + const sc = webClient.protobuf.controller.ModeratorCommand.create({ '.Command_ViewLogHistory.ext': command }); + + webClient.protobuf.sendModeratorCommand(sc, (raw) => { + const { responseCode } = raw; + + let error: string; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + const { logMessage } = raw['.Response_ViewLogHistory.ext']; + ModeratorPersistence.viewLogs(logMessage) + return; + default: + error = 'Failed to retrieve log history.'; + break; + } + + if (error) { + console.error(responseCode, error); + } }); } diff --git a/webclient/src/websocket/commands/moderator/warnUser.ts b/webclient/src/websocket/commands/moderator/warnUser.ts index 0e0271d4b..bef9ee003 100644 --- a/webclient/src/websocket/commands/moderator/warnUser.ts +++ b/webclient/src/websocket/commands/moderator/warnUser.ts @@ -1,10 +1,26 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { ModeratorPersistence } from '../../persistence'; -export function warnUser(userName: string, reason: string, clientid?: string, removeMessages?: number): void { - BackendService.sendModeratorCommand('Command_WarnUser', { userName, reason, clientid, removeMessages }, { - onSuccess: () => { - ModeratorPersistence.warnUser(userName); - }, +export function warnUser(userName: string, reason: string, clientid?: string, removeMessage?: boolean): void { + const command = webClient.protobuf.controller.Command_WarnUser.create({ userName, reason, clientid, removeMessage }); + const sc = webClient.protobuf.controller.ModeratorCommand.create({ '.Command_WarnUser.ext': command }); + + webClient.protobuf.sendModeratorCommand(sc, (raw) => { + const { responseCode } = raw; + + let error: string; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + ModeratorPersistence.warnUser(userName); + return; + default: + error = 'Failed to warn user.'; + break; + } + + if (error) { + console.error(responseCode, error); + } }); } diff --git a/webclient/src/websocket/commands/room/createGame.ts b/webclient/src/websocket/commands/room/createGame.ts index 62565e0e6..e5fd66f80 100644 --- a/webclient/src/websocket/commands/room/createGame.ts +++ b/webclient/src/websocket/commands/room/createGame.ts @@ -1,11 +1,21 @@ -import { BackendService } from '../../services/BackendService'; import { RoomPersistence } from '../../persistence'; +import webClient from '../../WebClient'; import { GameConfig } from 'types'; export function createGame(roomId: number, gameConfig: GameConfig): void { - BackendService.sendRoomCommand(roomId, 'Command_CreateGame', gameConfig, { - onSuccess: () => { - RoomPersistence.gameCreated(roomId); - }, + const command = webClient.protobuf.controller.Command_CreateGame.create(gameConfig); + const rc = webClient.protobuf.controller.RoomCommand.create({ '.Command_CreateGame.ext': command }); + + webClient.protobuf.sendRoomCommand(roomId, rc, (raw) => { + const { responseCode } = raw; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + RoomPersistence.gameCreated(roomId); + break; + default: + console.log('Failed to do the thing'); + } }); } + diff --git a/webclient/src/websocket/commands/room/joinGame.ts b/webclient/src/websocket/commands/room/joinGame.ts index ef4b1fff2..19a672924 100644 --- a/webclient/src/websocket/commands/room/joinGame.ts +++ b/webclient/src/websocket/commands/room/joinGame.ts @@ -1,11 +1,21 @@ -import { BackendService } from '../../services/BackendService'; import { RoomPersistence } from '../../persistence'; -import { JoinGameParams } from 'types'; +import webClient from '../../WebClient'; +import { GameConfig, JoinGameParams } from 'types'; export function joinGame(roomId: number, joinGameParams: JoinGameParams): void { - BackendService.sendRoomCommand(roomId, 'Command_JoinGame', joinGameParams, { - onSuccess: () => { - RoomPersistence.joinedGame(roomId, joinGameParams.gameId); - }, + const command = webClient.protobuf.controller.Command_JoinGame.create(joinGameParams); + const rc = webClient.protobuf.controller.RoomCommand.create({ '.Command_JoinGame.ext': command }); + + webClient.protobuf.sendRoomCommand(roomId, rc, (raw) => { + const { responseCode } = raw; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + RoomPersistence.joinedGame(roomId, joinGameParams.gameId); + break; + default: + console.log('Failed to do the thing'); + } }); } + diff --git a/webclient/src/websocket/commands/room/leaveRoom.ts b/webclient/src/websocket/commands/room/leaveRoom.ts index 7cd64a0e2..477ee39a0 100644 --- a/webclient/src/websocket/commands/room/leaveRoom.ts +++ b/webclient/src/websocket/commands/room/leaveRoom.ts @@ -1,10 +1,19 @@ -import { BackendService } from '../../services/BackendService'; import { RoomPersistence } from '../../persistence'; +import webClient from '../../WebClient'; export function leaveRoom(roomId: number): void { - BackendService.sendRoomCommand(roomId, 'Command_LeaveRoom', {}, { - onSuccess: () => { - RoomPersistence.leaveRoom(roomId); - }, + const command = webClient.protobuf.controller.Command_LeaveRoom.create(); + const rc = webClient.protobuf.controller.RoomCommand.create({ '.Command_LeaveRoom.ext': command }); + + webClient.protobuf.sendRoomCommand(roomId, rc, (raw) => { + const { responseCode } = raw; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + RoomPersistence.leaveRoom(roomId); + break; + default: + console.log(`Failed to leave Room ${roomId} [${responseCode}] : `, raw); + } }); } diff --git a/webclient/src/websocket/commands/room/roomSay.ts b/webclient/src/websocket/commands/room/roomSay.ts index a429845be..c06abd3ab 100644 --- a/webclient/src/websocket/commands/room/roomSay.ts +++ b/webclient/src/websocket/commands/room/roomSay.ts @@ -1,4 +1,4 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; export function roomSay(roomId: number, message: string): void { const trimmed = message.trim(); @@ -7,5 +7,8 @@ export function roomSay(roomId: number, message: string): void { return; } - BackendService.sendRoomCommand(roomId, 'Command_RoomSay', { message: trimmed }, {}); + const command = webClient.protobuf.controller.Command_RoomSay.create({ 'message': trimmed }); + const rc = webClient.protobuf.controller.RoomCommand.create({ '.Command_RoomSay.ext': command }); + + webClient.protobuf.sendRoomCommand(roomId, rc); } diff --git a/webclient/src/websocket/commands/session/accountEdit.ts b/webclient/src/websocket/commands/session/accountEdit.ts index 31bf2d3f6..f9210cb9c 100644 --- a/webclient/src/websocket/commands/session/accountEdit.ts +++ b/webclient/src/websocket/commands/session/accountEdit.ts @@ -1,10 +1,25 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { SessionPersistence } from '../../persistence'; export function accountEdit(passwordCheck: string, realName?: string, email?: string, country?: string): void { - BackendService.sendSessionCommand('Command_AccountEdit', { passwordCheck, realName, email, country }, { - onSuccess: () => { - SessionPersistence.accountEditChanged(realName, email, country); - }, + const command = webClient.protobuf.controller.Command_AccountEdit.create({ passwordCheck, realName, email, country }); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_AccountEdit.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, raw => { + const { responseCode } = raw; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + SessionPersistence.accountEditChanged(realName, email, country); + break; + case webClient.protobuf.controller.Response.ResponseCode.RespFunctionNotAllowed: + console.log('Not allowed'); + break; + case webClient.protobuf.controller.Response.ResponseCode.RespWrongPassword: + console.log('Wrong password'); + break; + default: + console.log('Failed to update information'); + } }); } diff --git a/webclient/src/websocket/commands/session/accountImage.ts b/webclient/src/websocket/commands/session/accountImage.ts index cd0e24403..b735696a9 100644 --- a/webclient/src/websocket/commands/session/accountImage.ts +++ b/webclient/src/websocket/commands/session/accountImage.ts @@ -1,10 +1,27 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { SessionPersistence } from '../../persistence'; +import { common } from 'protobufjs'; +import IBytesValue = common.IBytesValue; -export function accountImage(image: Uint8Array): void { - BackendService.sendSessionCommand('Command_AccountImage', { image }, { - onSuccess: () => { - SessionPersistence.accountImageChanged(image); - }, +export function accountImage(image: IBytesValue): void { + const command = webClient.protobuf.controller.Command_AccountImage.create({ image }); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_AccountImage.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, raw => { + const { responseCode } = raw; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + SessionPersistence.accountImageChanged(image); + break; + case webClient.protobuf.controller.Response.ResponseCode.RespFunctionNotAllowed: + console.log('Not allowed'); + break; + case webClient.protobuf.controller.Response.ResponseCode.RespWrongPassword: + console.log('Wrong password'); + break; + default: + console.log('Failed to update information'); + } }); } diff --git a/webclient/src/websocket/commands/session/accountPassword.ts b/webclient/src/websocket/commands/session/accountPassword.ts index 81c7a993b..0b5ef0111 100644 --- a/webclient/src/websocket/commands/session/accountPassword.ts +++ b/webclient/src/websocket/commands/session/accountPassword.ts @@ -1,10 +1,19 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { SessionPersistence } from '../../persistence'; export function accountPassword(oldPassword: string, newPassword: string, hashedNewPassword: string): void { - BackendService.sendSessionCommand('Command_AccountPassword', { oldPassword, newPassword, hashedNewPassword }, { - onSuccess: () => { - SessionPersistence.accountPasswordChange(); - }, + const command = webClient.protobuf.controller.Command_AccountPassword.create({ oldPassword, newPassword, hashedNewPassword }); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_AccountPassword.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, raw => { + const { responseCode } = raw; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + SessionPersistence.accountPasswordChange(); + break; + default: + console.log('Failed to change password'); + } }); } diff --git a/webclient/src/websocket/commands/session/activate.ts b/webclient/src/websocket/commands/session/activate.ts index 4cd0e8c4e..74e41afeb 100644 --- a/webclient/src/websocket/commands/session/activate.ts +++ b/webclient/src/websocket/commands/session/activate.ts @@ -2,8 +2,6 @@ import { AccountActivationParams } from 'store'; import { StatusEnum, WebSocketConnectOptions } from 'types'; import webClient from '../../WebClient'; -import { BackendService } from '../../services/BackendService'; -import { ProtoController } from '../../services/ProtoController'; import { SessionPersistence } from '../../persistence'; import { disconnect, login, updateStatus } from './'; @@ -11,21 +9,23 @@ import { disconnect, login, updateStatus } from './'; export function activate(options: WebSocketConnectOptions, passwordSalt?: string): void { const { userName, token } = options as unknown as AccountActivationParams; - BackendService.sendSessionCommand('Command_Activate', { + const accountActivationConfig = { ...webClient.clientConfig, userName, token, - }, { - onResponseCode: { - [ProtoController.root.Response.ResponseCode.RespActivationAccepted]: () => { - SessionPersistence.accountActivationSuccess(); - login(options, passwordSalt); - }, - }, - onError: () => { + }; + + const command = webClient.protobuf.controller.Command_Activate.create(accountActivationConfig); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_Activate.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, raw => { + if (raw.responseCode === webClient.protobuf.controller.Response.ResponseCode.RespActivationAccepted) { + SessionPersistence.accountActivationSuccess(); + login(options, passwordSalt); + } else { updateStatus(StatusEnum.DISCONNECTED, 'Account Activation Failed'); disconnect(); SessionPersistence.accountActivationFailed(); - }, + } }); } diff --git a/webclient/src/websocket/commands/session/addToList.ts b/webclient/src/websocket/commands/session/addToList.ts index c5bc3c5f0..6696d39d4 100644 --- a/webclient/src/websocket/commands/session/addToList.ts +++ b/webclient/src/websocket/commands/session/addToList.ts @@ -1,4 +1,4 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { SessionPersistence } from '../../persistence'; export function addToBuddyList(userName: string): void { @@ -10,9 +10,16 @@ export function addToIgnoreList(userName: string): void { } export function addToList(list: string, userName: string): void { - BackendService.sendSessionCommand('Command_AddToList', { list, userName }, { - onSuccess: () => { - SessionPersistence.addToList(list, userName); - }, + const command = webClient.protobuf.controller.Command_AddToList.create({ list, userName }); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_AddToList.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, ({ responseCode }) => { + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + SessionPersistence.addToList(list, userName); + break; + default: + console.error('Failed to add to list', responseCode); + } }); } diff --git a/webclient/src/websocket/commands/session/deckDel.ts b/webclient/src/websocket/commands/session/deckDel.ts index 752ce78d5..c77d89aa3 100644 --- a/webclient/src/websocket/commands/session/deckDel.ts +++ b/webclient/src/websocket/commands/session/deckDel.ts @@ -1,10 +1,19 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { SessionPersistence } from '../../persistence'; export function deckDel(deckId: number): void { - BackendService.sendSessionCommand('Command_DeckDel', { deckId }, { - onSuccess: () => { - SessionPersistence.deleteServerDeck(deckId); - }, + const command = webClient.protobuf.controller.Command_DeckDel.create({ deckId }); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_DeckDel.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, raw => { + const { responseCode } = raw; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + SessionPersistence.deckDelete(deckId); + break; + default: + console.log('Failed to do the thing'); + } }); } diff --git a/webclient/src/websocket/commands/session/deckDelDir.ts b/webclient/src/websocket/commands/session/deckDelDir.ts index df5bbc223..ff4b25ec3 100644 --- a/webclient/src/websocket/commands/session/deckDelDir.ts +++ b/webclient/src/websocket/commands/session/deckDelDir.ts @@ -1,10 +1,19 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { SessionPersistence } from '../../persistence'; export function deckDelDir(path: string): void { - BackendService.sendSessionCommand('Command_DeckDelDir', { path }, { - onSuccess: () => { - SessionPersistence.deleteServerDeckDir(path); - }, + const command = webClient.protobuf.controller.Command_DeckDelDir.create({ path }); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_DeckDelDir.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, raw => { + const { responseCode } = raw; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + SessionPersistence.deckDeleteDir(path); + break; + default: + console.log('Failed to do the thing'); + } }); } diff --git a/webclient/src/websocket/commands/session/deckDownload.ts b/webclient/src/websocket/commands/session/deckDownload.ts new file mode 100644 index 000000000..a0c4bd461 --- /dev/null +++ b/webclient/src/websocket/commands/session/deckDownload.ts @@ -0,0 +1,19 @@ +import webClient from '../../WebClient'; +import { SessionPersistence } from '../../persistence'; + +export function deckDownload(deckId: number): void { + const command = webClient.protobuf.controller.Command_DeckDownload.create({ deckId }); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_DeckDownload.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, raw => { + const { responseCode } = raw; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + SessionPersistence.deckDownload(deckId); + break; + default: + console.log('Failed to do the thing'); + } + }); +} diff --git a/webclient/src/websocket/commands/session/deckList.ts b/webclient/src/websocket/commands/session/deckList.ts index 3d5a3499a..e84b8efb3 100644 --- a/webclient/src/websocket/commands/session/deckList.ts +++ b/webclient/src/websocket/commands/session/deckList.ts @@ -1,11 +1,22 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { SessionPersistence } from '../../persistence'; export function deckList(): void { - BackendService.sendSessionCommand('Command_DeckList', {}, { - responseName: 'Response_DeckList', - onSuccess: (response) => { - SessionPersistence.updateServerDecks(response); - }, + const command = webClient.protobuf.controller.Command_DeckList.create(); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_DeckList.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, raw => { + const { responseCode } = raw; + const response = raw['.Response_DeckList.ext']; + + if (response) { + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + SessionPersistence.deckList(response); + break; + default: + console.log('Failed to do the thing'); + } + } }); } diff --git a/webclient/src/websocket/commands/session/deckNewDir.ts b/webclient/src/websocket/commands/session/deckNewDir.ts index 85ab16afb..b9bca6208 100644 --- a/webclient/src/websocket/commands/session/deckNewDir.ts +++ b/webclient/src/websocket/commands/session/deckNewDir.ts @@ -1,10 +1,19 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { SessionPersistence } from '../../persistence'; export function deckNewDir(path: string, dirName: string): void { - BackendService.sendSessionCommand('Command_DeckNewDir', { path, dirName }, { - onSuccess: () => { - SessionPersistence.createServerDeckDir(path, dirName); - }, + const command = webClient.protobuf.controller.Command_DeckNewDir.create({ path, dirName }); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_DeckNewDir.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, raw => { + const { responseCode } = raw; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + SessionPersistence.deckNewDir(path, dirName); + break; + default: + console.log('Failed to do the thing'); + } }); } diff --git a/webclient/src/websocket/commands/session/deckUpload.ts b/webclient/src/websocket/commands/session/deckUpload.ts index 2679c4e8e..af526c8fc 100644 --- a/webclient/src/websocket/commands/session/deckUpload.ts +++ b/webclient/src/websocket/commands/session/deckUpload.ts @@ -1,11 +1,23 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { SessionPersistence } from '../../persistence'; export function deckUpload(path: string, deckId: number, deckList: string): void { - BackendService.sendSessionCommand('Command_DeckUpload', { path, deckId, deckList }, { - responseName: 'Response_DeckUpload', - onSuccess: (response) => { - SessionPersistence.uploadServerDeck(path, response.newFile); - }, + const command = webClient.protobuf.controller.Command_DeckUpload.create({ path, deckId, deckList }); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_DeckUpload.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, raw => { + const { responseCode } = raw; + const response = raw['.Response_DeckUpload.ext']; + + if (response) { + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + SessionPersistence.deckUpload(response); + break; + default: + console.log('Failed to do the thing'); + } + } + }); } diff --git a/webclient/src/websocket/commands/session/forgotPasswordChallenge.ts b/webclient/src/websocket/commands/session/forgotPasswordChallenge.ts index 05af1ccf9..f6399e6a7 100644 --- a/webclient/src/websocket/commands/session/forgotPasswordChallenge.ts +++ b/webclient/src/websocket/commands/session/forgotPasswordChallenge.ts @@ -2,27 +2,30 @@ import { ForgotPasswordChallengeParams } from 'store'; import { StatusEnum, WebSocketConnectOptions } from 'types'; import webClient from '../../WebClient'; -import { BackendService } from '../../services/BackendService'; import { SessionPersistence } from '../../persistence'; import { disconnect, updateStatus } from './'; export function forgotPasswordChallenge(options: WebSocketConnectOptions): void { const { userName, email } = options as unknown as ForgotPasswordChallengeParams; - BackendService.sendSessionCommand('Command_ForgotPasswordChallenge', { + const forgotPasswordChallengeConfig = { ...webClient.clientConfig, userName, email, - }, { - onSuccess: () => { + }; + + const command = webClient.protobuf.controller.Command_ForgotPasswordChallenge.create(forgotPasswordChallengeConfig); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_ForgotPasswordChallenge.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, raw => { + if (raw.responseCode === webClient.protobuf.controller.Response.ResponseCode.RespOk) { updateStatus(StatusEnum.DISCONNECTED, null); SessionPersistence.resetPassword(); - disconnect(); - }, - onError: () => { + } else { updateStatus(StatusEnum.DISCONNECTED, null); SessionPersistence.resetPasswordFailed(); - disconnect(); - }, + } + + disconnect(); }); } diff --git a/webclient/src/websocket/commands/session/forgotPasswordRequest.ts b/webclient/src/websocket/commands/session/forgotPasswordRequest.ts index 23d301450..5e5fe3bbd 100644 --- a/webclient/src/websocket/commands/session/forgotPasswordRequest.ts +++ b/webclient/src/websocket/commands/session/forgotPasswordRequest.ts @@ -2,7 +2,6 @@ import { ForgotPasswordParams } from 'store'; import { StatusEnum, WebSocketConnectOptions } from 'types'; import webClient from '../../WebClient'; -import { BackendService } from '../../services/BackendService'; import { SessionPersistence } from '../../persistence'; import { disconnect, updateStatus } from './'; @@ -10,25 +9,30 @@ import { disconnect, updateStatus } from './'; export function forgotPasswordRequest(options: WebSocketConnectOptions): void { const { userName } = options as unknown as ForgotPasswordParams; - BackendService.sendSessionCommand('Command_ForgotPasswordRequest', { + const forgotPasswordConfig = { ...webClient.clientConfig, userName, - }, { - responseName: 'Response_ForgotPasswordRequest', - onSuccess: (resp) => { - if (resp?.challengeEmail) { + }; + + const command = webClient.protobuf.controller.Command_ForgotPasswordRequest.create(forgotPasswordConfig); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_ForgotPasswordRequest.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, raw => { + if (raw.responseCode === webClient.protobuf.controller.Response.ResponseCode.RespOk) { + const resp = raw['.Response_ForgotPasswordRequest.ext']; + + if (resp.challengeEmail) { updateStatus(StatusEnum.DISCONNECTED, null); SessionPersistence.resetPasswordChallenge(); } else { updateStatus(StatusEnum.DISCONNECTED, null); SessionPersistence.resetPassword(); } - disconnect(); - }, - onError: () => { + } else { updateStatus(StatusEnum.DISCONNECTED, null); SessionPersistence.resetPasswordFailed(); - disconnect(); - }, + } + + disconnect(); }); } diff --git a/webclient/src/websocket/commands/session/forgotPasswordReset.ts b/webclient/src/websocket/commands/session/forgotPasswordReset.ts index d9a775816..9312b71af 100644 --- a/webclient/src/websocket/commands/session/forgotPasswordReset.ts +++ b/webclient/src/websocket/commands/session/forgotPasswordReset.ts @@ -2,7 +2,6 @@ import { ForgotPasswordResetParams } from 'store'; import { StatusEnum, WebSocketConnectOptions } from 'types'; import webClient from '../../WebClient'; -import { BackendService } from '../../services/BackendService'; import { SessionPersistence } from '../../persistence'; import { hashPassword } from '../../utils'; @@ -11,28 +10,30 @@ import { disconnect, updateStatus } from '.'; export function forgotPasswordReset(options: WebSocketConnectOptions, passwordSalt?: string): void { const { userName, token, newPassword } = options as unknown as ForgotPasswordResetParams; - const params: any = { + const forgotPasswordResetConfig: any = { ...webClient.clientConfig, userName, token, }; if (passwordSalt) { - params.hashedNewPassword = hashPassword(passwordSalt, newPassword); + forgotPasswordResetConfig.hashedNewPassword = hashPassword(passwordSalt, newPassword); } else { - params.newPassword = newPassword; + forgotPasswordResetConfig.newPassword = newPassword; } - BackendService.sendSessionCommand('Command_ForgotPasswordReset', params, { - onSuccess: () => { + const command = webClient.protobuf.controller.Command_ForgotPasswordReset.create(forgotPasswordResetConfig); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_ForgotPasswordReset.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, raw => { + if (raw.responseCode === webClient.protobuf.controller.Response.ResponseCode.RespOk) { updateStatus(StatusEnum.DISCONNECTED, null); SessionPersistence.resetPasswordSuccess(); - disconnect(); - }, - onError: () => { + } else { updateStatus(StatusEnum.DISCONNECTED, null); SessionPersistence.resetPasswordFailed(); - disconnect(); - }, + } + + disconnect(); }); } diff --git a/webclient/src/websocket/commands/session/getGamesOfUser.ts b/webclient/src/websocket/commands/session/getGamesOfUser.ts index 8fb8aeb5b..507ba3e20 100644 --- a/webclient/src/websocket/commands/session/getGamesOfUser.ts +++ b/webclient/src/websocket/commands/session/getGamesOfUser.ts @@ -1,11 +1,26 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { SessionPersistence } from '../../persistence'; export function getGamesOfUser(userName: string): void { - BackendService.sendSessionCommand('Command_GetGamesOfUser', { userName }, { - responseName: 'Response_GetGamesOfUser', - onSuccess: (response) => { - SessionPersistence.getGamesOfUser(userName, response); - }, + const command = webClient.protobuf.controller.Command_GetGamesOfUser.create({ userName }); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_GetGamesOfUser.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, raw => { + const { responseCode } = raw; + const response = raw['.Response_GetGamesOfUser.ext']; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + SessionPersistence.getGamesOfUser(userName, response); + break; + case webClient.protobuf.controller.Response.ResponseCode.RespFunctionNotAllowed: + console.log('Not allowed'); + break; + case webClient.protobuf.controller.Response.ResponseCode.RespWrongPassword: + console.log('Wrong password'); + break; + default: + console.log('Failed to update information'); + } }); } diff --git a/webclient/src/websocket/commands/session/getUserInfo.ts b/webclient/src/websocket/commands/session/getUserInfo.ts index 5b0f178ae..709cc0baa 100644 --- a/webclient/src/websocket/commands/session/getUserInfo.ts +++ b/webclient/src/websocket/commands/session/getUserInfo.ts @@ -1,11 +1,26 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { SessionPersistence } from '../../persistence'; export function getUserInfo(userName: string): void { - BackendService.sendSessionCommand('Command_GetUserInfo', { userName }, { - responseName: 'Response_GetUserInfo', - onSuccess: (response) => { - SessionPersistence.getUserInfo(response.userInfo); - }, + const command = webClient.protobuf.controller.Command_GetUserInfo.create({ userName }); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_GetUserInfo.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, raw => { + const { responseCode } = raw; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + const { userInfo } = raw['.Response_GetUserInfo.ext']; + SessionPersistence.getUserInfo(userInfo); + break; + case webClient.protobuf.controller.Response.ResponseCode.RespFunctionNotAllowed: + console.log('Not allowed'); + break; + case webClient.protobuf.controller.Response.ResponseCode.RespWrongPassword: + console.log('Wrong password'); + break; + default: + console.log('Failed to update information'); + } }); } diff --git a/webclient/src/websocket/commands/session/index.ts b/webclient/src/websocket/commands/session/index.ts index 74d0d062c..829a74b71 100644 --- a/webclient/src/websocket/commands/session/index.ts +++ b/webclient/src/websocket/commands/session/index.ts @@ -6,11 +6,12 @@ export * from './addToList'; export * from './connect'; export * from './deckDel'; export * from './deckDelDir'; +export * from './deckDownload'; export * from './deckList'; export * from './deckNewDir'; export * from './deckUpload'; export * from './disconnect'; -export * from './forgotPasswordChallenge'; +export * from './forgotPasswordChallenge' export * from './forgotPasswordRequest'; export * from './forgotPasswordReset'; export * from './getGamesOfUser'; @@ -23,8 +24,12 @@ export * from './message'; export * from './ping'; export * from './register'; export * from './removeFromList'; -export * from './replayDeleteMatch'; -export * from './replayList'; -export * from './replayModifyMatch'; export * from './requestPasswordSalt'; export * from './updateStatus'; + +/** TODO + * REPLAY_DELETE_MATCH + * REPLAY_DOWNLOAD + * REPLAY_LIST + * REPLAY_MODIFY_MATCH + */ diff --git a/webclient/src/websocket/commands/session/joinRoom.ts b/webclient/src/websocket/commands/session/joinRoom.ts index be79976a0..9f4699708 100644 --- a/webclient/src/websocket/commands/session/joinRoom.ts +++ b/webclient/src/websocket/commands/session/joinRoom.ts @@ -1,11 +1,37 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { RoomPersistence } from '../../persistence'; export function joinRoom(roomId: number): void { - BackendService.sendSessionCommand('Command_JoinRoom', { roomId }, { - responseName: 'Response_JoinRoom', - onSuccess: (response) => { - RoomPersistence.joinRoom(response.roomInfo); - }, + const command = webClient.protobuf.controller.Command_JoinRoom.create({ roomId }); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_JoinRoom.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, (raw) => { + const { responseCode } = raw; + + let error: string; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + const { roomInfo } = raw['.Response_JoinRoom.ext']; + + RoomPersistence.joinRoom(roomInfo); + return; + case webClient.protobuf.controller.Response.ResponseCode.RespNameNotFound: + error = 'Failed to join the room: it doesn\'t exist on the server.'; + break; + case webClient.protobuf.controller.Response.ResponseCode.RespContextError: + error = 'The server thinks you are in the room but Cockatrice is unable to display it. Try restarting Cockatrice.'; + break; + case webClient.protobuf.controller.Response.ResponseCode.RespUserLevelTooLow: + error = 'You do not have the required permission to join this room.'; + break; + default: + error = 'Failed to join the room due to an unknown error.'; + break; + } + + if (error) { + console.error(responseCode, error); + } }); } diff --git a/webclient/src/websocket/commands/session/listRooms.ts b/webclient/src/websocket/commands/session/listRooms.ts index 367dada9b..b1e31621f 100644 --- a/webclient/src/websocket/commands/session/listRooms.ts +++ b/webclient/src/websocket/commands/session/listRooms.ts @@ -1,5 +1,8 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; export function listRooms(): void { - BackendService.sendSessionCommand('Command_ListRooms', {}, {}); + const command = webClient.protobuf.controller.Command_ListRooms.create(); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_ListRooms.ext': command }); + + webClient.protobuf.sendSessionCommand(sc); } diff --git a/webclient/src/websocket/commands/session/listUsers.ts b/webclient/src/websocket/commands/session/listUsers.ts index 9b95c1344..027a251d4 100644 --- a/webclient/src/websocket/commands/session/listUsers.ts +++ b/webclient/src/websocket/commands/session/listUsers.ts @@ -1,11 +1,23 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { SessionPersistence } from '../../persistence'; export function listUsers(): void { - BackendService.sendSessionCommand('Command_ListUsers', {}, { - responseName: 'Response_ListUsers', - onSuccess: (response) => { - SessionPersistence.updateUsers(response.userList); - }, + const command = webClient.protobuf.controller.Command_ListUsers.create(); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_ListUsers.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, raw => { + const { responseCode } = raw; + const response = raw['.Response_ListUsers.ext']; + + if (response) { + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + SessionPersistence.updateUsers(response.userList); + break; + default: + console.log(`Failed to fetch Server Rooms [${responseCode}] : `, raw); + } + } + }); } diff --git a/webclient/src/websocket/commands/session/login.ts b/webclient/src/websocket/commands/session/login.ts index 6f3ec5ef5..db24b4f46 100644 --- a/webclient/src/websocket/commands/session/login.ts +++ b/webclient/src/websocket/commands/session/login.ts @@ -1,7 +1,5 @@ import { StatusEnum, WebSocketConnectOptions } from 'types'; import webClient from '../../WebClient'; -import { BackendService } from '../../services/BackendService'; -import { ProtoController } from '../../services/ProtoController'; import { hashPassword } from '../../utils'; import { SessionPersistence } from '../../persistence'; @@ -27,18 +25,13 @@ export function login(options: WebSocketConnectOptions, passwordSalt?: string): loginConfig.password = password; } - const { ResponseCode } = ProtoController.root.Response; + const command = webClient.protobuf.controller.Command_Login.create(loginConfig); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_Login.ext': command }); - const onLoginError = (message: string, extra?: () => void) => { - updateStatus(StatusEnum.DISCONNECTED, message); - extra?.(); - SessionPersistence.loginFailed(); - disconnect(); - }; + webClient.protobuf.sendSessionCommand(sc, raw => { + const resp = raw['.Response_Login.ext']; - BackendService.sendSessionCommand('Command_Login', loginConfig, { - responseName: 'Response_Login', - onSuccess: (resp) => { + if (raw.responseCode === webClient.protobuf.controller.Response.ResponseCode.RespOk) { const { buddyList, ignoreList, userInfo } = resp; SessionPersistence.updateBuddyList(buddyList); @@ -50,30 +43,50 @@ export function login(options: WebSocketConnectOptions, passwordSalt?: string): listRooms(); updateStatus(StatusEnum.LOGGED_IN, 'Logged in.'); - }, - onResponseCode: { - [ResponseCode.RespClientUpdateRequired]: () => - onLoginError('Login failed: missing features'), - [ResponseCode.RespWrongPassword]: () => - onLoginError('Login failed: incorrect username or password'), - [ResponseCode.RespUsernameInvalid]: () => - onLoginError('Login failed: incorrect username or password'), - [ResponseCode.RespWouldOverwriteOldSession]: () => - onLoginError('Login failed: duplicated user session'), - [ResponseCode.RespUserIsBanned]: () => - onLoginError('Login failed: banned user'), - [ResponseCode.RespRegistrationRequired]: () => - onLoginError('Login failed: registration required'), - [ResponseCode.RespClientIdRequired]: () => - onLoginError('Login failed: missing client ID'), - [ResponseCode.RespContextError]: () => - onLoginError('Login failed: server error'), - [ResponseCode.RespAccountNotActivated]: () => - onLoginError('Login failed: account not activated', - () => SessionPersistence.accountAwaitingActivation(options) - ), - }, - onError: (responseCode) => - onLoginError(`Login failed: unknown error: ${responseCode}`), + + return; + } + + switch (raw.responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespClientUpdateRequired: + updateStatus(StatusEnum.DISCONNECTED, 'Login failed: missing features'); + break; + + case webClient.protobuf.controller.Response.ResponseCode.RespWrongPassword: + case webClient.protobuf.controller.Response.ResponseCode.RespUsernameInvalid: + updateStatus(StatusEnum.DISCONNECTED, 'Login failed: incorrect username or password'); + break; + + case webClient.protobuf.controller.Response.ResponseCode.RespWouldOverwriteOldSession: + updateStatus(StatusEnum.DISCONNECTED, 'Login failed: duplicated user session'); + break; + + case webClient.protobuf.controller.Response.ResponseCode.RespUserIsBanned: + updateStatus(StatusEnum.DISCONNECTED, 'Login failed: banned user'); + break; + + case webClient.protobuf.controller.Response.ResponseCode.RespRegistrationRequired: + updateStatus(StatusEnum.DISCONNECTED, 'Login failed: registration required'); + break; + + case webClient.protobuf.controller.Response.ResponseCode.RespClientIdRequired: + updateStatus(StatusEnum.DISCONNECTED, 'Login failed: missing client ID'); + break; + + case webClient.protobuf.controller.Response.ResponseCode.RespContextError: + updateStatus(StatusEnum.DISCONNECTED, 'Login failed: server error'); + break; + + case webClient.protobuf.controller.Response.ResponseCode.RespAccountNotActivated: + updateStatus(StatusEnum.DISCONNECTED, 'Login failed: account not activated'); + SessionPersistence.accountAwaitingActivation(options); + break; + + default: + updateStatus(StatusEnum.DISCONNECTED, `Login failed: unknown error: ${raw.responseCode}`); + } + + SessionPersistence.loginFailed(); + disconnect(); }); } diff --git a/webclient/src/websocket/commands/session/message.ts b/webclient/src/websocket/commands/session/message.ts index 075fc3c4b..99b615562 100644 --- a/webclient/src/websocket/commands/session/message.ts +++ b/webclient/src/websocket/commands/session/message.ts @@ -1,10 +1,31 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { SessionPersistence } from '../../persistence'; export function message(userName: string, message: string): void { - BackendService.sendSessionCommand('Command_Message', { userName, message }, { - onSuccess: () => { - SessionPersistence.directMessageSent(userName, message); - }, + const command = webClient.protobuf.controller.Command_Message.create({ userName, message }); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_Message.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, raw => { + const { responseCode } = raw; + + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + SessionPersistence.directMessageSent(userName, message); + break; + case webClient.protobuf.controller.Response.ResponseCode.RespNameNotFound: + console.log('Name not found'); + break; + case webClient.protobuf.controller.Response.ResponseCode.RespInIgnoreList: + console.log('On ignore list'); + break; + case webClient.protobuf.controller.Response.ResponseCode.RespChatFlood: + console.log('Flooding chat'); + break; + case webClient.protobuf.controller.Response.ResponseCode.RespWrongPassword: + console.log('Wrong password'); + break; + default: + console.log('Failed to send direct message'); + } }); } diff --git a/webclient/src/websocket/commands/session/ping.ts b/webclient/src/websocket/commands/session/ping.ts index fea2784a2..795e0f71f 100644 --- a/webclient/src/websocket/commands/session/ping.ts +++ b/webclient/src/websocket/commands/session/ping.ts @@ -1,7 +1,8 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; export function ping(pingReceived: Function): void { - BackendService.sendSessionCommand('Command_Ping', {}, { - onResponse: (raw) => pingReceived(raw), - }); + const command = webClient.protobuf.controller.Command_Ping.create(); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_Ping.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, pingReceived); } diff --git a/webclient/src/websocket/commands/session/register.ts b/webclient/src/websocket/commands/session/register.ts index a25b85868..45b2fa977 100644 --- a/webclient/src/websocket/commands/session/register.ts +++ b/webclient/src/websocket/commands/session/register.ts @@ -1,18 +1,17 @@ import { ServerRegisterParams } from 'store'; -import { StatusEnum, WebSocketConnectOptions } from 'types'; +import { WebSocketConnectOptions } from 'types'; import webClient from '../../WebClient'; -import { BackendService } from '../../services/BackendService'; -import { ProtoController } from '../../services/ProtoController'; import { SessionPersistence } from '../../persistence'; import { hashPassword } from '../../utils'; +import NormalizeService from '../../utils/NormalizeService'; -import { login, disconnect, updateStatus } from './'; +import { login, disconnect } from './'; export function register(options: WebSocketConnectOptions, passwordSalt?: string): void { const { userName, password, email, country, realName } = options as ServerRegisterParams; - const params: any = { + const registerConfig: any = { ...webClient.clientConfig, userName, email, @@ -21,57 +20,55 @@ export function register(options: WebSocketConnectOptions, passwordSalt?: string }; if (passwordSalt) { - params.hashedPassword = hashPassword(passwordSalt, password); + registerConfig.hashedPassword = hashPassword(passwordSalt, password); } else { - params.password = password; + registerConfig.password = password; } - const { ResponseCode } = ProtoController.root.Response; + const command = webClient.protobuf.controller.Command_Register.create(registerConfig); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_Register.ext': command }); - const onRegistrationError = (action: () => void) => { - action(); - updateStatus(StatusEnum.DISCONNECTED, 'Registration failed'); - disconnect(); - }; + webClient.protobuf.sendSessionCommand(sc, raw => { + if (raw.responseCode === webClient.protobuf.controller.Response.ResponseCode.RespRegistrationAccepted) { + login(options, passwordSalt); + SessionPersistence.registrationSuccess() + return; + } - BackendService.sendSessionCommand('Command_Register', params, { - onResponseCode: { - [ResponseCode.RespRegistrationAccepted]: () => { - login(options, passwordSalt); - SessionPersistence.registrationSuccess(); - }, - [ResponseCode.RespRegistrationAcceptedNeedsActivation]: () => { - updateStatus(StatusEnum.DISCONNECTED, 'Registration accepted, awaiting activation'); + switch (raw.responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespRegistrationAcceptedNeedsActivation: SessionPersistence.accountAwaitingActivation(options); - disconnect(); - }, - [ResponseCode.RespUserAlreadyExists]: () => onRegistrationError( - () => SessionPersistence.registrationUserNameError('Username is taken') - ), - [ResponseCode.RespUsernameInvalid]: () => onRegistrationError( - () => SessionPersistence.registrationUserNameError('Invalid username') - ), - [ResponseCode.RespPasswordTooShort]: () => onRegistrationError( - () => SessionPersistence.registrationPasswordError('Your password was too short') - ), - [ResponseCode.RespEmailRequiredToRegister]: () => onRegistrationError( - () => SessionPersistence.registrationRequiresEmail() - ), - [ResponseCode.RespEmailBlackListed]: () => onRegistrationError( - () => SessionPersistence.registrationEmailError('This email provider has been blocked') - ), - [ResponseCode.RespTooManyRequests]: () => onRegistrationError( - () => SessionPersistence.registrationEmailError('Max accounts reached for this email') - ), - [ResponseCode.RespRegistrationDisabled]: () => onRegistrationError( - () => SessionPersistence.registrationFailed('Registration is currently disabled') - ), - [ResponseCode.RespUserIsBanned]: (raw) => onRegistrationError( - () => SessionPersistence.registrationFailed(raw.reasonStr, raw.endTime) - ), - }, - onError: () => onRegistrationError( - () => SessionPersistence.registrationFailed('Registration failed due to a server issue') - ), + break; + case webClient.protobuf.controller.Response.ResponseCode.RespUserAlreadyExists: + SessionPersistence.registrationUserNameError('Username is taken'); + break; + case webClient.protobuf.controller.Response.ResponseCode.RespUsernameInvalid: + SessionPersistence.registrationUserNameError('Invalid username'); + break; + case webClient.protobuf.controller.Response.ResponseCode.RespPasswordTooShort: + SessionPersistence.registrationPasswordError('Your password was too short'); + break; + case webClient.protobuf.controller.Response.ResponseCode.RespEmailRequiredToRegister: + SessionPersistence.registrationRequiresEmail(); + break; + case webClient.protobuf.controller.Response.ResponseCode.RespEmailBlackListed: + SessionPersistence.registrationEmailError('This email provider has been blocked'); + break; + case webClient.protobuf.controller.Response.ResponseCode.RespTooManyRequests: + SessionPersistence.registrationEmailError('Max accounts reached for this email'); + break; + case webClient.protobuf.controller.Response.ResponseCode.RespRegistrationDisabled: + SessionPersistence.registrationFailed('Registration is currently disabled'); + break; + case webClient.protobuf.controller.Response.ResponseCode.RespUserIsBanned: + SessionPersistence.registrationFailed(raw.reasonStr, raw.endTime); + break; + case webClient.protobuf.controller.Response.ResponseCode.RespRegistrationFailed: + default: + SessionPersistence.registrationFailed('Registration failed due to a server issue'); + break; + } + + disconnect(); }); } diff --git a/webclient/src/websocket/commands/session/removeFromList.ts b/webclient/src/websocket/commands/session/removeFromList.ts index aede49c49..222d9c57d 100644 --- a/webclient/src/websocket/commands/session/removeFromList.ts +++ b/webclient/src/websocket/commands/session/removeFromList.ts @@ -1,4 +1,4 @@ -import { BackendService } from '../../services/BackendService'; +import webClient from '../../WebClient'; import { SessionPersistence } from '../../persistence'; export function removeFromBuddyList(userName: string): void { @@ -10,9 +10,16 @@ export function removeFromIgnoreList(userName: string): void { } export function removeFromList(list: string, userName: string): void { - BackendService.sendSessionCommand('Command_RemoveFromList', { list, userName }, { - onSuccess: () => { - SessionPersistence.removeFromList(list, userName); - }, + const command = webClient.protobuf.controller.Command_RemoveFromList.create({ list, userName }); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_RemoveFromList.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, ({ responseCode }) => { + switch (responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: + SessionPersistence.removeFromList(list, userName); + break; + default: + console.error('Failed to remove from list', responseCode); + } }); } diff --git a/webclient/src/websocket/commands/session/replayDeleteMatch.ts b/webclient/src/websocket/commands/session/replayDeleteMatch.ts deleted file mode 100644 index 24ac48f1c..000000000 --- a/webclient/src/websocket/commands/session/replayDeleteMatch.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { BackendService } from '../../services/BackendService'; -import { SessionPersistence } from '../../persistence'; - -export function replayDeleteMatch(gameId: number): void { - BackendService.sendSessionCommand('Command_ReplayDeleteMatch', { gameId }, { - onSuccess: () => { - SessionPersistence.replayDeleteMatch(gameId); - }, - }); -} diff --git a/webclient/src/websocket/commands/session/replayList.ts b/webclient/src/websocket/commands/session/replayList.ts deleted file mode 100644 index f39eb279f..000000000 --- a/webclient/src/websocket/commands/session/replayList.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { BackendService } from '../../services/BackendService'; -import { SessionPersistence } from '../../persistence'; - -export function replayList(): void { - BackendService.sendSessionCommand('Command_ReplayList', {}, { - responseName: 'Response_ReplayList', - onSuccess: (response) => { - SessionPersistence.replayList(response.matchList); - }, - }); -} diff --git a/webclient/src/websocket/commands/session/replayModifyMatch.ts b/webclient/src/websocket/commands/session/replayModifyMatch.ts deleted file mode 100644 index 9825047f3..000000000 --- a/webclient/src/websocket/commands/session/replayModifyMatch.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { BackendService } from '../../services/BackendService'; -import { SessionPersistence } from '../../persistence'; - -export function replayModifyMatch(gameId: number, doNotHide: boolean): void { - BackendService.sendSessionCommand('Command_ReplayModifyMatch', { gameId, doNotHide }, { - onSuccess: () => { - SessionPersistence.replayModifyMatch(gameId, doNotHide); - }, - }); -} diff --git a/webclient/src/websocket/commands/session/requestPasswordSalt.ts b/webclient/src/websocket/commands/session/requestPasswordSalt.ts index a3d1fc05c..b7ab5ef92 100644 --- a/webclient/src/websocket/commands/session/requestPasswordSalt.ts +++ b/webclient/src/websocket/commands/session/requestPasswordSalt.ts @@ -2,8 +2,6 @@ import { RequestPasswordSaltParams } from 'store'; import { StatusEnum, WebSocketConnectOptions, WebSocketConnectReason } from 'types'; import webClient from '../../WebClient'; -import { BackendService } from '../../services/BackendService'; -import { ProtoController } from '../../services/ProtoController'; import { SessionPersistence } from '../../persistence'; import { @@ -17,48 +15,64 @@ import { export function requestPasswordSalt(options: WebSocketConnectOptions): void { const { userName } = options as RequestPasswordSaltParams; - const onFailure = () => { - switch (options.reason) { - case WebSocketConnectReason.ACTIVATE_ACCOUNT: - SessionPersistence.accountActivationFailed(); - break; - case WebSocketConnectReason.PASSWORD_RESET: - SessionPersistence.resetPasswordFailed(); - break; - default: - SessionPersistence.loginFailed(); - } - disconnect(); - }; - - BackendService.sendSessionCommand('Command_RequestPasswordSalt', { + const registerConfig = { ...webClient.clientConfig, userName, - }, { - responseName: 'Response_PasswordSalt', - onSuccess: (resp) => { - const passwordSalt = resp?.passwordSalt; + }; - switch (options.reason) { - case WebSocketConnectReason.ACTIVATE_ACCOUNT: - activate(options, passwordSalt); - break; - case WebSocketConnectReason.PASSWORD_RESET: - forgotPasswordReset(options, passwordSalt); - break; - default: - login(options, passwordSalt); + const command = webClient.protobuf.controller.Command_RequestPasswordSalt.create(registerConfig); + const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_RequestPasswordSalt.ext': command }); + + webClient.protobuf.sendSessionCommand(sc, raw => { + switch (raw.responseCode) { + case webClient.protobuf.controller.Response.ResponseCode.RespOk: { + const passwordSalt = raw['.Response_PasswordSalt.ext']?.passwordSalt; + + switch (options.reason) { + case WebSocketConnectReason.ACTIVATE_ACCOUNT: { + activate(options, passwordSalt); + break; + } + + case WebSocketConnectReason.PASSWORD_RESET: { + forgotPasswordReset(options, passwordSalt); + break; + } + + case WebSocketConnectReason.LOGIN: + default: { + login(options, passwordSalt); + } + } + + return; } - }, - onResponseCode: { - [ProtoController.root.Response.ResponseCode.RespRegistrationRequired]: () => { + case webClient.protobuf.controller.Response.ResponseCode.RespRegistrationRequired: { updateStatus(StatusEnum.DISCONNECTED, 'Login failed: registration required'); - onFailure(); - }, - }, - onError: () => { - updateStatus(StatusEnum.DISCONNECTED, 'Login failed: Unknown Reason'); - onFailure(); - }, + break; + } + default: { + updateStatus(StatusEnum.DISCONNECTED, 'Login failed: Unknown Reason'); + } + } + + switch (options.reason) { + case WebSocketConnectReason.ACTIVATE_ACCOUNT: { + SessionPersistence.accountActivationFailed(); + break; + } + + case WebSocketConnectReason.PASSWORD_RESET: { + SessionPersistence.resetPasswordFailed(); + break; + } + + case WebSocketConnectReason.LOGIN: + default: { + SessionPersistence.loginFailed(); + } + } + + disconnect(); }); } diff --git a/webclient/src/websocket/events/game/index.ts b/webclient/src/websocket/events/game/index.ts index a7b3277a5..895eadfef 100644 --- a/webclient/src/websocket/events/game/index.ts +++ b/webclient/src/websocket/events/game/index.ts @@ -4,8 +4,8 @@ import { leaveGame } from './leaveGame'; export const GameEvents: ProtobufEvents = { - '.Event_Join.ext': joinGame, - '.Event_Leave.ext': leaveGame, + '.Event_Join.ext': () => joinGame, + '.Event_Leave.ext': () => leaveGame, '.Event_GameClosed.ext': () => console.log('Event_GameClosed.ext'), '.Event_GameHostChanged.ext': () => console.log('Event_GameHostChanged.ext'), '.Event_Kicked.ext': () => console.log('Event_Kicked.ext'), diff --git a/webclient/src/websocket/events/session/connectionClosed.ts b/webclient/src/websocket/events/session/connectionClosed.ts index 227113059..9c39db940 100644 --- a/webclient/src/websocket/events/session/connectionClosed.ts +++ b/webclient/src/websocket/events/session/connectionClosed.ts @@ -1,5 +1,5 @@ import { StatusEnum } from 'types'; -import { ProtoController } from '../../services/ProtoController'; +import webClient from '../../WebClient'; import { updateStatus } from '../../commands/session'; import { ConnectionClosedData } from './interfaces'; @@ -10,30 +10,29 @@ export function connectionClosed({ reason, reasonStr }: ConnectionClosedData): v if (reasonStr) { message = reasonStr; } else { - const { CloseReason } = ProtoController.root.Event_ConnectionClosed; switch (reason) { - case CloseReason.USER_LIMIT_REACHED: + case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.USER_LIMIT_REACHED: message = 'The server has reached its maximum user capacity'; break; - case CloseReason.TOO_MANY_CONNECTIONS: + case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.TOO_MANY_CONNECTIONS: message = 'There are too many concurrent connections from your address'; break; - case CloseReason.BANNED: + case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.BANNED: message = 'You are banned'; break; - case CloseReason.DEMOTED: + case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.DEMOTED: message = 'You were demoted'; break; - case CloseReason.SERVER_SHUTDOWN: + case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.SERVER_SHUTDOWN: message = 'Scheduled server shutdown'; break; - case CloseReason.USERNAMEINVALID: + case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.USERNAMEINVALID: message = 'Invalid username'; break; - case CloseReason.LOGGEDINELSEWERE: + case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.LOGGEDINELSEWERE: message = 'You have been logged out due to logging in at another location'; break; - case CloseReason.OTHER: + case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.OTHER: default: message = 'Unknown reason'; break; diff --git a/webclient/src/websocket/events/session/index.ts b/webclient/src/websocket/events/session/index.ts index 5b3ab198e..9fe7bb1da 100644 --- a/webclient/src/websocket/events/session/index.ts +++ b/webclient/src/websocket/events/session/index.ts @@ -3,9 +3,8 @@ import { addToList } from './addToList'; import { connectionClosed } from './connectionClosed'; import { listRooms } from './listRooms'; import { notifyUser } from './notifyUser'; +import { playerPropertiesChanged } from '../common/playerPropertiesChanged'; import { removeFromList } from './removeFromList'; -import { replayAdded } from './replayAdded'; -import { serverCompleteList } from './serverCompleteList'; import { serverIdentification } from './serverIdentification'; import { serverMessage } from './serverMessage'; import { serverShutdown } from './serverShutdown'; @@ -21,8 +20,8 @@ export const SessionEvents: ProtobufEvents = { '.Event_ListRooms.ext': listRooms, '.Event_NotifyUser.ext': notifyUser, '.Event_RemoveFromList.ext': removeFromList, - '.Event_ReplayAdded.ext': replayAdded, - '.Event_ServerCompleteList.ext': serverCompleteList, + '.Event_ReplayAdded.ext': () => console.log('Event_ReplayAdded'), + '.Event_ServerCompleteList.ext': () => console.log('Event_ServerCompleteList'), '.Event_ServerIdentification.ext': serverIdentification, '.Event_ServerMessage.ext': serverMessage, '.Event_ServerShutdown.ext': serverShutdown, diff --git a/webclient/src/websocket/events/session/interfaces.ts b/webclient/src/websocket/events/session/interfaces.ts index ddc10d103..8a1827cbd 100644 --- a/webclient/src/websocket/events/session/interfaces.ts +++ b/webclient/src/websocket/events/session/interfaces.ts @@ -1,4 +1,4 @@ -import { Game, NotificationType, ReplayMatch, Room, User } from 'types'; +import { Game, NotificationType, Room, User } from 'types'; export interface AddToListData { listName: string; @@ -13,8 +13,6 @@ export interface ConnectionClosedData { export interface GameJoinedData { gameInfo: Game; - gameTypes: any[]; - hostId: number; playerId: number; spectator: boolean; resuming: boolean; @@ -78,13 +76,3 @@ export interface UserMessageData { receiverName: string; message: string; } - -export interface ReplayAddedData { - matchInfo: ReplayMatch; -} - -export interface ServerCompleteListData { - serverId: number; - userList: User[]; - roomList: Room[]; -} diff --git a/webclient/src/websocket/events/session/replayAdded.ts b/webclient/src/websocket/events/session/replayAdded.ts deleted file mode 100644 index 18a4ea82d..000000000 --- a/webclient/src/websocket/events/session/replayAdded.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { SessionPersistence } from '../../persistence'; -import { ReplayAddedData } from './interfaces'; - -export function replayAdded({ matchInfo }: ReplayAddedData): void { - SessionPersistence.replayAdded(matchInfo); -} diff --git a/webclient/src/websocket/events/session/serverCompleteList.ts b/webclient/src/websocket/events/session/serverCompleteList.ts deleted file mode 100644 index 77d37a31e..000000000 --- a/webclient/src/websocket/events/session/serverCompleteList.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { RoomPersistence, SessionPersistence } from '../../persistence'; -import { ServerCompleteListData } from './interfaces'; - -export function serverCompleteList({ userList, roomList }: ServerCompleteListData): void { - SessionPersistence.updateUsers(userList); - RoomPersistence.updateRooms(roomList); -} diff --git a/webclient/src/websocket/events/session/serverIdentification.ts b/webclient/src/websocket/events/session/serverIdentification.ts index 87ae79453..ce89e1f3c 100644 --- a/webclient/src/websocket/events/session/serverIdentification.ts +++ b/webclient/src/websocket/events/session/serverIdentification.ts @@ -1,4 +1,4 @@ -import { StatusEnum, WebSocketConnectOptions, WebSocketConnectReason } from 'types'; +import { StatusEnum, WebSocketConnectReason } from 'types'; import webClient from '../../WebClient'; import { @@ -24,48 +24,48 @@ export function serverIdentification(info: ServerIdentificationData): void { return; } - const getPasswordSalt = passwordSaltSupported(serverOptions); - const connectOptions = { ...webClient.options }; + const getPasswordSalt = passwordSaltSupported(serverOptions, webClient); + const { options } = webClient; - switch (connectOptions.reason) { + switch (options.reason) { case WebSocketConnectReason.LOGIN: updateStatus(StatusEnum.LOGGING_IN, 'Logging In...'); if (getPasswordSalt) { - requestPasswordSalt(connectOptions); + requestPasswordSalt(options); } else { - login(connectOptions); + login(options); } break; case WebSocketConnectReason.REGISTER: const passwordSalt = getPasswordSalt ? generateSalt() : null; - register(connectOptions, passwordSalt); + register(options, passwordSalt); break; case WebSocketConnectReason.ACTIVATE_ACCOUNT: if (getPasswordSalt) { - requestPasswordSalt(connectOptions); + requestPasswordSalt(options); } else { - activate(connectOptions); + activate(options); } break; case WebSocketConnectReason.PASSWORD_RESET_REQUEST: - forgotPasswordRequest(connectOptions); + forgotPasswordRequest(options); break; case WebSocketConnectReason.PASSWORD_RESET_CHALLENGE: - forgotPasswordChallenge(connectOptions); + forgotPasswordChallenge(options); break; case WebSocketConnectReason.PASSWORD_RESET: if (getPasswordSalt) { - requestPasswordSalt(connectOptions); + requestPasswordSalt(options); } else { - forgotPasswordReset(connectOptions); + forgotPasswordReset(options); } break; default: - updateStatus(StatusEnum.DISCONNECTED, 'Unknown Connection Reason: ' + connectOptions.reason); + updateStatus(StatusEnum.DISCONNECTED, 'Unknown Connection Reason: ' + options.reason); disconnect(); break; } - webClient.options = {} as WebSocketConnectOptions; + webClient.options = {}; SessionPersistence.updateInfo(serverName, serverVersion); } diff --git a/webclient/src/websocket/persistence/AdminPersistence.ts b/webclient/src/websocket/persistence/AdminPresistence.ts similarity index 100% rename from webclient/src/websocket/persistence/AdminPersistence.ts rename to webclient/src/websocket/persistence/AdminPresistence.ts diff --git a/webclient/src/websocket/persistence/ModeratorPersistence.ts b/webclient/src/websocket/persistence/ModeratorPresistence.ts similarity index 61% rename from webclient/src/websocket/persistence/ModeratorPersistence.ts rename to webclient/src/websocket/persistence/ModeratorPresistence.ts index d1b991fa0..e6a57f601 100644 --- a/webclient/src/websocket/persistence/ModeratorPersistence.ts +++ b/webclient/src/websocket/persistence/ModeratorPresistence.ts @@ -27,20 +27,4 @@ export class ModeratorPersistence { static warnUser(userName: string): void { ServerDispatch.warnUser(userName); } - - static grantReplayAccess(replayId: number, moderatorName: string): void { - ServerDispatch.grantReplayAccess(replayId, moderatorName); - } - - static forceActivateUser(usernameToActivate: string, moderatorName: string): void { - ServerDispatch.forceActivateUser(usernameToActivate, moderatorName); - } - - static getAdminNotes(userName: string, notes: string): void { - ServerDispatch.getAdminNotes(userName, notes); - } - - static updateAdminNotes(userName: string, notes: string): void { - ServerDispatch.updateAdminNotes(userName, notes); - } } diff --git a/webclient/src/websocket/persistence/SessionPersistence.ts b/webclient/src/websocket/persistence/SessionPersistence.ts index 9962af968..c9248745c 100644 --- a/webclient/src/websocket/persistence/SessionPersistence.ts +++ b/webclient/src/websocket/persistence/SessionPersistence.ts @@ -1,5 +1,5 @@ import { ServerDispatch } from 'store'; -import { DeckList, DeckStorageTreeItem, ReplayMatch, StatusEnum, User, WebSocketConnectOptions } from 'types'; +import { DeckStorageTreeItem, StatusEnum, User, WebSocketConnectOptions } from 'types'; import { sanitizeHtml } from 'websocket/utils'; import { @@ -10,6 +10,9 @@ import { UserMessageData } from '../events/session/interfaces'; import NormalizeService from '../utils/NormalizeService'; +import { DeckList } from 'types'; +import { common } from 'protobufjs'; +import IBytesValue = common.IBytesValue; export class SessionPersistence { static initialized() { @@ -162,7 +165,7 @@ export class SessionPersistence { ServerDispatch.accountEditChanged({ realName, email, country }); } - static accountImageChanged(avatarBmp: Uint8Array): void { + static accountImageChanged(avatarBmp: IBytesValue): void { ServerDispatch.accountImageChanged({ avatarBmp }); } @@ -175,8 +178,7 @@ export class SessionPersistence { } static getGamesOfUser(userName: string, response: any): void { - // Response_GetGamesOfUser contains a gameList field — log for now until game layer is complete - console.log('getGamesOfUser', userName, response); + console.log('getGamesOfUser'); } static gameJoined(gameJoinedData: GameJoinedData): void { @@ -207,40 +209,28 @@ export class SessionPersistence { ServerDispatch.removeFromList(list, userName); } - static deleteServerDeck(deckId: number): void { - ServerDispatch.deckDelete(deckId); + static deckDelete(deckId: number): void { + console.log('deckDelete', deckId); } - static updateServerDecks(deckList: DeckList): void { - ServerDispatch.backendDecks(deckList); + static deckDeleteDir(path: string): void { + console.log('deckDeleteDir', path); } - static uploadServerDeck(path: string, treeItem: DeckStorageTreeItem): void { - ServerDispatch.deckUpload(path, treeItem); + static deckDownload(deckId: number): void { + console.log('deckDownload', deckId); } - static createServerDeckDir(path: string, dirName: string): void { - ServerDispatch.deckNewDir(path, dirName); + static deckList(deckList: DeckList): void { + console.log('deckList', deckList); } - static deleteServerDeckDir(path: string): void { - ServerDispatch.deckDelDir(path); + static deckNewDir(path: string, dirName: string): void { + console.log('deckNewDir', path, dirName); } - static replayList(matchList: ReplayMatch[]): void { - ServerDispatch.replayList(matchList); - } - - static replayAdded(matchInfo: ReplayMatch): void { - ServerDispatch.replayAdded(matchInfo); - } - - static replayModifyMatch(gameId: number, doNotHide: boolean): void { - ServerDispatch.replayModifyMatch(gameId, doNotHide); - } - - static replayDeleteMatch(gameId: number): void { - ServerDispatch.replayDeleteMatch(gameId); + static deckUpload(treeItem: DeckStorageTreeItem): void { + console.log('deckUpload', treeItem); } } diff --git a/webclient/src/websocket/persistence/index.ts b/webclient/src/websocket/persistence/index.ts index a1e34fffa..f4df52645 100644 --- a/webclient/src/websocket/persistence/index.ts +++ b/webclient/src/websocket/persistence/index.ts @@ -1,5 +1,5 @@ -export { AdminPersistence } from './AdminPersistence'; +export { AdminPersistence } from './AdminPresistence'; export { RoomPersistence } from './RoomPersistence'; export { SessionPersistence } from './SessionPersistence'; -export { ModeratorPersistence } from './ModeratorPersistence'; +export { ModeratorPersistence } from './ModeratorPresistence'; export { GamePersistence } from './GamePersistence'; diff --git a/webclient/src/websocket/services/BackendService.ts b/webclient/src/websocket/services/BackendService.ts deleted file mode 100644 index fce741d35..000000000 --- a/webclient/src/websocket/services/BackendService.ts +++ /dev/null @@ -1,82 +0,0 @@ -import webClient from '../WebClient'; -import { ProtoController } from './ProtoController'; - -export interface CommandOptions { - responseName?: string; - onSuccess?: (response: any, raw: any) => void; - onError?: (responseCode: number, raw: any) => void; - onResponseCode?: { [code: number]: (raw: any) => void }; - onResponse?: (raw: any) => void; -} - -export class BackendService { - static sendSessionCommand(commandName: string, params: any, options: CommandOptions): void { - const command = ProtoController.root[commandName].create(params || {}); - const sc = ProtoController.root.SessionCommand.create({ - [`.${commandName}.ext`]: command, - }); - webClient.protobuf.sendSessionCommand(sc, raw => { - BackendService.handleResponse(commandName, raw, options); - }); - } - - static sendRoomCommand(roomId: number, commandName: string, params: any, options: CommandOptions): void { - const command = ProtoController.root[commandName].create(params || {}); - const rc = ProtoController.root.RoomCommand.create({ - [`.${commandName}.ext`]: command, - }); - webClient.protobuf.sendRoomCommand(roomId, rc, raw => { - BackendService.handleResponse(commandName, raw, options); - }); - } - - static sendModeratorCommand(commandName: string, params: any, options: CommandOptions): void { - const command = ProtoController.root[commandName].create(params || {}); - const mc = ProtoController.root.ModeratorCommand.create({ - [`.${commandName}.ext`]: command, - }); - webClient.protobuf.sendModeratorCommand(mc, raw => { - BackendService.handleResponse(commandName, raw, options); - }); - } - - static sendAdminCommand(commandName: string, params: any, options: CommandOptions): void { - const command = ProtoController.root[commandName].create(params || {}); - const ac = ProtoController.root.AdminCommand.create({ - [`.${commandName}.ext`]: command, - }); - webClient.protobuf.sendAdminCommand(ac, raw => { - BackendService.handleResponse(commandName, raw, options); - }); - } - - private static handleResponse(commandName: string, raw: any, options: CommandOptions): void { - if (options.onResponse) { - options.onResponse(raw); - return; - } - - const { responseCode } = raw; - - if (responseCode === ProtoController.root.Response.ResponseCode.RespOk) { - if (options.onSuccess) { - const response = options.responseName - ? raw[`.${options.responseName}.ext`] - : raw; - options.onSuccess(response, raw); - } - return; - } - - if (options.onResponseCode?.[responseCode]) { - options.onResponseCode[responseCode](raw); - return; - } - - if (options.onError) { - options.onError(responseCode, raw); - } else { - console.error(`${commandName} failed with response code: ${responseCode}`); - } - } -} diff --git a/webclient/src/websocket/services/ProtoController.ts b/webclient/src/websocket/services/ProtoController.ts deleted file mode 100644 index 130d5e196..000000000 --- a/webclient/src/websocket/services/ProtoController.ts +++ /dev/null @@ -1,24 +0,0 @@ -import protobuf from 'protobufjs'; - -import { SessionPersistence } from '../persistence'; -import ProtoFiles from '../../proto-files.json'; - -const PB_FILE_DIR = `${process.env.PUBLIC_URL}/pb`; - -// Leaf module — no imports from the websocket layer other than persistence. -// Both BackendService and ProtobufService import this; neither should import -// the other for controller access, avoiding circular dependency cycles. -export const ProtoController = { - root: null as any, - - load(): void { - const files = ProtoFiles.map(file => `${PB_FILE_DIR}/${file}`); - ProtoController.root = new protobuf.Root(); - ProtoController.root.load(files, { keepCase: false }, (err: Error) => { - if (err) { - throw err; - } - SessionPersistence.initialized(); - }); - }, -}; diff --git a/webclient/src/websocket/services/ProtobufService.ts b/webclient/src/websocket/services/ProtobufService.ts index 20c4e8599..341bbeae3 100644 --- a/webclient/src/websocket/services/ProtobufService.ts +++ b/webclient/src/websocket/services/ProtobufService.ts @@ -1,13 +1,19 @@ +import protobuf from 'protobufjs'; + import { CommonEvents, GameEvents, RoomEvents, SessionEvents } from '../events'; +import { SessionPersistence } from '../persistence'; import { WebClient } from '../WebClient'; import { SessionCommands } from 'websocket'; -import { ProtoController } from './ProtoController'; +import ProtoFiles from '../../proto-files.json'; export interface ProtobufEvents { [event: string]: Function; } export class ProtobufService { + static PB_FILE_DIR = `${process.env.PUBLIC_URL}/pb`; + + public controller; private cmdId = 0; private pendingCommands: { [cmdId: string]: Function } = {}; @@ -15,7 +21,8 @@ export class ProtobufService { constructor(webClient: WebClient) { this.webClient = webClient; - ProtoController.load(); + + this.loadProtobufFiles(); } public resetCommands() { @@ -23,8 +30,8 @@ export class ProtobufService { this.pendingCommands = {}; } - public sendRoomCommand(roomId: number, roomCmd: any, callback?: Function) { - const cmd = ProtoController.root.CommandContainer.create({ + public sendRoomCommand(roomId: number, roomCmd: number, callback?: Function) { + const cmd = this.controller.CommandContainer.create({ 'roomId': roomId, 'roomCommand': [roomCmd] }); @@ -32,38 +39,38 @@ export class ProtobufService { this.sendCommand(cmd, raw => callback && callback(raw)); } - public sendSessionCommand(sesCmd: any, callback?: Function) { - const cmd = ProtoController.root.CommandContainer.create({ + public sendSessionCommand(sesCmd: number, callback?: Function) { + const cmd = this.controller.CommandContainer.create({ 'sessionCommand': [sesCmd] }); this.sendCommand(cmd, (raw) => callback && callback(raw)); } - public sendModeratorCommand(modCmd: any, callback?: Function) { - const cmd = ProtoController.root.CommandContainer.create({ + public sendModeratorCommand(modCmd: number, callback?: Function) { + const cmd = this.controller.CommandContainer.create({ 'moderatorCommand': [modCmd] }); this.sendCommand(cmd, (raw) => callback && callback(raw)); } - public sendAdminCommand(adminCmd: any, callback?: Function) { - const cmd = ProtoController.root.CommandContainer.create({ + public sendAdminCommand(adminCmd: number, callback?: Function) { + const cmd = this.controller.CommandContainer.create({ 'adminCommand': [adminCmd] }); this.sendCommand(cmd, (raw) => callback && callback(raw)); } - public sendCommand(cmd: any, callback: Function) { + public sendCommand(cmd: number, callback: Function) { this.cmdId++; cmd['cmdId'] = this.cmdId; this.pendingCommands[this.cmdId] = callback; if (this.webClient.socket.checkReadyState(WebSocket.OPEN)) { - this.webClient.socket.send(ProtoController.root.CommandContainer.encode(cmd).finish()); + this.webClient.socket.send(this.controller.CommandContainer.encode(cmd).finish()); } } @@ -74,20 +81,20 @@ export class ProtobufService { public handleMessageEvent({ data }: MessageEvent): void { try { const uint8msg = new Uint8Array(data); - const msg = ProtoController.root.ServerMessage.decode(uint8msg); + const msg = this.controller.ServerMessage.decode(uint8msg); if (msg) { switch (msg.messageType) { - case ProtoController.root.ServerMessage.MessageType.RESPONSE: + case this.controller.ServerMessage.MessageType.RESPONSE: this.processServerResponse(msg.response); break; - case ProtoController.root.ServerMessage.MessageType.ROOM_EVENT: + case this.controller.ServerMessage.MessageType.ROOM_EVENT: this.processRoomEvent(msg.roomEvent, msg); break; - case ProtoController.root.ServerMessage.MessageType.SESSION_EVENT: + case this.controller.ServerMessage.MessageType.SESSION_EVENT: this.processSessionEvent(msg.sessionEvent, msg); break; - case ProtoController.root.ServerMessage.MessageType.GAME_EVENT_CONTAINER: + case this.controller.ServerMessage.MessageType.GAME_EVENT_CONTAINER: this.processGameEvent(msg.gameEvent, msg); break; default: @@ -135,4 +142,17 @@ export class ProtobufService { } } } + + private loadProtobufFiles() { + const files = ProtoFiles.map(file => `${ProtobufService.PB_FILE_DIR}/${file}`); + + this.controller = new protobuf.Root(); + this.controller.load(files, { keepCase: false }, (err, root) => { + if (err) { + throw err; + } + + SessionPersistence.initialized(); + }); + } } diff --git a/webclient/src/websocket/utils/passwordHasher.ts b/webclient/src/websocket/utils/passwordHasher.ts index 164a91823..77645694f 100644 --- a/webclient/src/websocket/utils/passwordHasher.ts +++ b/webclient/src/websocket/utils/passwordHasher.ts @@ -1,6 +1,5 @@ import sha512 from 'crypto-js/sha512'; import Base64 from 'crypto-js/enc-base64'; -import { ProtoController } from '../services/ProtoController'; const HASH_ROUNDS = 1_000; const SALT_LENGTH = 16; @@ -26,7 +25,7 @@ export const generateSalt = (): string => { return salt; } -export const passwordSaltSupported = (serverOptions: number): number => { +export const passwordSaltSupported = (serverOptions, webClient): number => { // Intentional use of Bitwise operator b/c of how Servatrice Enums work - return serverOptions & ProtoController.root.Event_ServerIdentification.ServerOptions.SupportsPasswordHash; + return serverOptions & webClient.protobuf.controller.Event_ServerIdentification.ServerOptions.SupportsPasswordHash; }