mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-04-27 07:48:01 -07:00
Initial implementation completion and refactor (#6806)
Some checks failed
Build Desktop / Configure (push) Has been cancelled
Build Docker Image / amd64 & arm64 (push) Has been cancelled
Build Web / React (Node 16) (push) Has been cancelled
Build Web / React (Node lts/*) (push) Has been cancelled
Build Desktop / Debian 11 (push) Has been cancelled
Build Desktop / Debian 13 (push) Has been cancelled
Build Desktop / Debian 12 (push) Has been cancelled
Build Desktop / Fedora 43 (push) Has been cancelled
Build Desktop / Fedora 42 (push) Has been cancelled
Build Desktop / Servatrice_Debian 11 (push) Has been cancelled
Build Desktop / Ubuntu 24.04 (push) Has been cancelled
Build Desktop / Ubuntu 26.04 (push) Has been cancelled
Build Desktop / Ubuntu 22.04 (push) Has been cancelled
Build Desktop / Arch (push) Has been cancelled
Build Desktop / macOS 14 (push) Has been cancelled
Build Desktop / macOS 15 (push) Has been cancelled
Build Desktop / macOS 13 Intel (push) Has been cancelled
Build Desktop / macOS 15 Debug (push) Has been cancelled
Build Desktop / Windows 10 (push) Has been cancelled
Some checks failed
Build Desktop / Configure (push) Has been cancelled
Build Docker Image / amd64 & arm64 (push) Has been cancelled
Build Web / React (Node 16) (push) Has been cancelled
Build Web / React (Node lts/*) (push) Has been cancelled
Build Desktop / Debian 11 (push) Has been cancelled
Build Desktop / Debian 13 (push) Has been cancelled
Build Desktop / Debian 12 (push) Has been cancelled
Build Desktop / Fedora 43 (push) Has been cancelled
Build Desktop / Fedora 42 (push) Has been cancelled
Build Desktop / Servatrice_Debian 11 (push) Has been cancelled
Build Desktop / Ubuntu 24.04 (push) Has been cancelled
Build Desktop / Ubuntu 26.04 (push) Has been cancelled
Build Desktop / Ubuntu 22.04 (push) Has been cancelled
Build Desktop / Arch (push) Has been cancelled
Build Desktop / macOS 14 (push) Has been cancelled
Build Desktop / macOS 15 (push) Has been cancelled
Build Desktop / macOS 13 Intel (push) Has been cancelled
Build Desktop / macOS 15 Debug (push) Has been cancelled
Build Desktop / Windows 10 (push) Has been cancelled
This commit is contained in:
parent
2e10b2f5d5
commit
8cc65b8967
76 changed files with 897 additions and 890 deletions
|
|
@ -1,5 +1,6 @@
|
|||
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 {
|
||||
|
|
@ -39,7 +40,7 @@ export class AuthenticationService {
|
|||
}
|
||||
|
||||
static isModerator(user: User): boolean {
|
||||
const moderatorLevel = webClient.protobuf.controller.ServerInfo_User.UserLevelFlag.IsModerator;
|
||||
const moderatorLevel = ProtoController.root.ServerInfo_User.UserLevelFlag.IsModerator;
|
||||
// @TODO tell cockatrice not to do this so shittily
|
||||
return (user.userLevel & moderatorLevel) === moderatorLevel;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ export class ModeratorService {
|
|||
ModeratorCommands.viewLogHistory(filters);
|
||||
}
|
||||
|
||||
static warnUser(userName: string, reason: string, clientid?: string, removeMessage?: boolean): void {
|
||||
ModeratorCommands.warnUser(userName, reason, clientid, removeMessage);
|
||||
static warnUser(userName: string, reason: string, clientid?: string, removeMessages?: number): void {
|
||||
ModeratorCommands.warnUser(userName, reason, clientid, removeMessages);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
import { SessionCommands } from 'websocket';
|
||||
import { common } from 'protobufjs';
|
||||
import IBytesValue = common.IBytesValue;
|
||||
|
||||
export class SessionService {
|
||||
static addToBuddyList(userName: string) {
|
||||
|
|
@ -27,7 +25,7 @@ export class SessionService {
|
|||
SessionCommands.accountEdit(passwordCheck, realName, email, country);
|
||||
}
|
||||
|
||||
static changeAccountImage(image: IBytesValue): void {
|
||||
static changeAccountImage(image: Uint8Array): void {
|
||||
SessionCommands.accountImage(image);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { WebSocketConnectOptions } from 'types';
|
||||
import { DeckList, DeckStorageTreeItem, ReplayMatch, WebSocketConnectOptions } from 'types';
|
||||
import { Types } from './server.types';
|
||||
|
||||
export const Actions = {
|
||||
|
|
@ -210,4 +210,33 @@ 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 }),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { reset } from 'redux-form';
|
||||
import { Actions } from './server.actions';
|
||||
import { store } from 'store';
|
||||
import { WebSocketConnectOptions } from 'types';
|
||||
import { DeckList, DeckStorageTreeItem, ReplayMatch, WebSocketConnectOptions } from 'types';
|
||||
|
||||
export const Dispatch = {
|
||||
initialized: () => {
|
||||
|
|
@ -177,4 +177,43 @@ 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));
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import { WarnHistoryItem, BanHistoryItem, LogItem, SortBy, User, UserSortField, WebSocketConnectOptions, WarnListItem } from 'types';
|
||||
import {
|
||||
WarnHistoryItem, BanHistoryItem, DeckList, LogItem, ReplayMatch, SortBy, User, UserSortField, WebSocketConnectOptions, WarnListItem
|
||||
} from 'types';
|
||||
import { NotifyUserData, ServerShutdownData, UserMessageData } from 'websocket/events/session/interfaces';
|
||||
|
||||
export interface ServerConnectParams {
|
||||
|
|
@ -67,6 +69,9 @@ export interface ServerState {
|
|||
};
|
||||
warnListOptions: WarnListItem[];
|
||||
warnUser: string;
|
||||
adminNotes: { [userName: string]: string };
|
||||
replays: ReplayMatch[];
|
||||
backendDecks: DeckList | null;
|
||||
}
|
||||
|
||||
export interface ServerStateStatus {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,60 @@
|
|||
import { SortDirection, StatusEnum, UserLevelFlag, UserSortField } from 'types';
|
||||
import { DeckStorageFolder, DeckStorageTreeItem, 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: [],
|
||||
|
|
@ -40,6 +90,9 @@ const initialState: ServerState = {
|
|||
warnHistory: {},
|
||||
warnListOptions: [],
|
||||
warnUser: '',
|
||||
adminNotes: {},
|
||||
replays: [],
|
||||
backendDecks: null,
|
||||
};
|
||||
|
||||
export const serverReducer = (state = initialState, action: any) => {
|
||||
|
|
@ -247,7 +300,7 @@ export const serverReducer = (state = initialState, action: any) => {
|
|||
messages: {
|
||||
...state.messages,
|
||||
[userName]: [
|
||||
...state.messages[userName],
|
||||
...(state.messages[userName] ?? []),
|
||||
action.messageData,
|
||||
],
|
||||
}
|
||||
|
|
@ -328,6 +381,17 @@ 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;
|
||||
|
||||
|
|
@ -346,6 +410,71 @@ 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,5 +16,7 @@ export const Selectors = {
|
|||
getUsers: ({ server }: State) => server.users,
|
||||
getLogs: ({ server }: State) => server.logs,
|
||||
getBuddyList: ({ server }: State) => server.buddyList,
|
||||
getIgnoreList: ({ server }: State) => server.ignoreList
|
||||
getIgnoreList: ({ server }: State) => server.ignoreList,
|
||||
getReplays: ({ server }: State) => server.replays,
|
||||
getBackendDecks: ({ server }: State) => server.backendDecks,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,4 +54,19 @@ 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',
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,6 +13,6 @@ export interface DeckStorageFile {
|
|||
export interface DeckStorageTreeItem {
|
||||
id: number;
|
||||
name: string;
|
||||
file: DeckStorageFile;
|
||||
folder: DeckStorageFolder;
|
||||
file: DeckStorageFile | null;
|
||||
folder: DeckStorageFolder | null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,3 +16,4 @@ export * from './logs';
|
|||
export * from './session';
|
||||
export * from './deckList';
|
||||
export * from './moderator';
|
||||
export * from './replay';
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
export interface LogFilters {
|
||||
userName: string;
|
||||
ipAddress: string;
|
||||
gameName: string;
|
||||
gameId: string;
|
||||
message: string;
|
||||
logLocation: string;
|
||||
userName?: string;
|
||||
ipAddress?: string;
|
||||
gameName?: string;
|
||||
gameId?: string;
|
||||
message?: string;
|
||||
logLocation?: string[];
|
||||
dateRange: number;
|
||||
maximumResults?: number;
|
||||
}
|
||||
|
|
|
|||
16
webclient/src/types/replay.ts
Normal file
16
webclient/src/types/replay.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
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;
|
||||
}
|
||||
|
|
@ -1,26 +1,10 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { AdminPersistence } from '../../persistence';
|
||||
|
||||
export function adjustMod(userName: string, shouldBeMod?: boolean, shouldBeJudge?: boolean): void {
|
||||
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:
|
||||
BackendService.sendAdminCommand('Command_AdjustMod', { userName, shouldBeMod, shouldBeJudge }, {
|
||||
onSuccess: () => {
|
||||
AdminPersistence.adjustMod(userName, shouldBeMod, shouldBeJudge);
|
||||
return;
|
||||
default:
|
||||
error = 'Failed to reload config.';
|
||||
break;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
console.error(responseCode, error);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,10 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { AdminPersistence } from '../../persistence';
|
||||
|
||||
export function reloadConfig(): void {
|
||||
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:
|
||||
BackendService.sendAdminCommand('Command_ReloadConfig', {}, {
|
||||
onSuccess: () => {
|
||||
AdminPersistence.reloadConfig();
|
||||
return;
|
||||
default:
|
||||
error = 'Failed to reload config.';
|
||||
break;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
console.error(responseCode, error);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,10 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { AdminPersistence } from '../../persistence';
|
||||
|
||||
export function shutdownServer(reason: string, minutes: number): void {
|
||||
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:
|
||||
BackendService.sendAdminCommand('Command_ShutdownServer', { reason, minutes }, {
|
||||
onSuccess: () => {
|
||||
AdminPersistence.shutdownServer();
|
||||
return;
|
||||
default:
|
||||
error = 'Failed to update server message.';
|
||||
break;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
console.error(responseCode, error);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,10 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { AdminPersistence } from '../../persistence';
|
||||
|
||||
export function updateServerMessage(): void {
|
||||
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:
|
||||
BackendService.sendAdminCommand('Command_UpdateServerMessage', {}, {
|
||||
onSuccess: () => {
|
||||
AdminPersistence.updateServerMessage();
|
||||
return;
|
||||
default:
|
||||
error = 'Failed to update server message.';
|
||||
break;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
console.error(responseCode, error);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,13 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { ModeratorPersistence } from '../../persistence';
|
||||
|
||||
export function banFromServer(minutes: number, userName?: string, address?: string, reason?: string,
|
||||
visibleReason?: string, clientid?: string, removeMessages?: number): void {
|
||||
const command = webClient.protobuf.controller.Command_BanFromServer.create({
|
||||
BackendService.sendModeratorCommand('Command_BanFromServer', {
|
||||
minutes, userName, address, reason, visibleReason, clientid, removeMessages
|
||||
});
|
||||
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:
|
||||
}, {
|
||||
onSuccess: () => {
|
||||
ModeratorPersistence.banFromServer(userName);
|
||||
return;
|
||||
default:
|
||||
error = 'Failed to ban user.';
|
||||
break;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
console.error(responseCode, error);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
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);
|
||||
},
|
||||
});
|
||||
}
|
||||
11
webclient/src/websocket/commands/moderator/getAdminNotes.ts
Normal file
11
webclient/src/websocket/commands/moderator/getAdminNotes.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
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);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -1,27 +1,11 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { ModeratorPersistence } from '../../persistence';
|
||||
|
||||
export function getBanHistory(userName: string): void {
|
||||
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);
|
||||
}
|
||||
BackendService.sendModeratorCommand('Command_GetBanHistory', { userName }, {
|
||||
responseName: 'Response_BanHistory',
|
||||
onSuccess: (response) => {
|
||||
ModeratorPersistence.banHistory(userName, response.banList);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,11 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { ModeratorPersistence } from '../../persistence';
|
||||
|
||||
export function getWarnHistory(userName: string): void {
|
||||
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);
|
||||
}
|
||||
BackendService.sendModeratorCommand('Command_GetWarnHistory', { userName }, {
|
||||
responseName: 'Response_WarnHistory',
|
||||
onSuccess: (response) => {
|
||||
ModeratorPersistence.warnHistory(userName, response.warnList);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,11 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { ModeratorPersistence } from '../../persistence';
|
||||
|
||||
export function getWarnList(modName: string, userName: string, userClientid: string): void {
|
||||
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);
|
||||
}
|
||||
BackendService.sendModeratorCommand('Command_GetWarnList', { modName, userName, userClientid }, {
|
||||
responseName: 'Response_WarnList',
|
||||
onSuccess: (response) => {
|
||||
ModeratorPersistence.warnListOptions(response.warning);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
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);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -1,6 +1,10 @@
|
|||
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';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
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);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -1,28 +1,12 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { ModeratorPersistence } from '../../persistence';
|
||||
import { LogFilters } from 'types';
|
||||
|
||||
export function viewLogHistory(filters: LogFilters): void {
|
||||
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);
|
||||
}
|
||||
BackendService.sendModeratorCommand('Command_ViewLogHistory', filters, {
|
||||
responseName: 'Response_ViewLogHistory',
|
||||
onSuccess: (response) => {
|
||||
ModeratorPersistence.viewLogs(response.logMessage);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,10 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { ModeratorPersistence } from '../../persistence';
|
||||
|
||||
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:
|
||||
export function warnUser(userName: string, reason: string, clientid?: string, removeMessages?: number): void {
|
||||
BackendService.sendModeratorCommand('Command_WarnUser', { userName, reason, clientid, removeMessages }, {
|
||||
onSuccess: () => {
|
||||
ModeratorPersistence.warnUser(userName);
|
||||
return;
|
||||
default:
|
||||
error = 'Failed to warn user.';
|
||||
break;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
console.error(responseCode, error);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,11 @@
|
|||
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 {
|
||||
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:
|
||||
BackendService.sendRoomCommand(roomId, 'Command_CreateGame', gameConfig, {
|
||||
onSuccess: () => {
|
||||
RoomPersistence.gameCreated(roomId);
|
||||
break;
|
||||
default:
|
||||
console.log('Failed to do the thing');
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,11 @@
|
|||
import { BackendService } from '../../services/BackendService';
|
||||
import { RoomPersistence } from '../../persistence';
|
||||
import webClient from '../../WebClient';
|
||||
import { GameConfig, JoinGameParams } from 'types';
|
||||
import { JoinGameParams } from 'types';
|
||||
|
||||
export function joinGame(roomId: number, joinGameParams: JoinGameParams): void {
|
||||
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:
|
||||
BackendService.sendRoomCommand(roomId, 'Command_JoinGame', joinGameParams, {
|
||||
onSuccess: () => {
|
||||
RoomPersistence.joinedGame(roomId, joinGameParams.gameId);
|
||||
break;
|
||||
default:
|
||||
console.log('Failed to do the thing');
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +1,10 @@
|
|||
import { BackendService } from '../../services/BackendService';
|
||||
import { RoomPersistence } from '../../persistence';
|
||||
import webClient from '../../WebClient';
|
||||
|
||||
export function leaveRoom(roomId: number): void {
|
||||
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:
|
||||
BackendService.sendRoomCommand(roomId, 'Command_LeaveRoom', {}, {
|
||||
onSuccess: () => {
|
||||
RoomPersistence.leaveRoom(roomId);
|
||||
break;
|
||||
default:
|
||||
console.log(`Failed to leave Room ${roomId} [${responseCode}] : `, raw);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
|
||||
export function roomSay(roomId: number, message: string): void {
|
||||
const trimmed = message.trim();
|
||||
|
|
@ -7,8 +7,5 @@ export function roomSay(roomId: number, message: string): void {
|
|||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
BackendService.sendRoomCommand(roomId, 'Command_RoomSay', { message: trimmed }, {});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,10 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
export function accountEdit(passwordCheck: string, realName?: string, email?: string, country?: string): void {
|
||||
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:
|
||||
BackendService.sendSessionCommand('Command_AccountEdit', { passwordCheck, realName, email, country }, {
|
||||
onSuccess: () => {
|
||||
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');
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,10 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
import { common } from 'protobufjs';
|
||||
import IBytesValue = common.IBytesValue;
|
||||
|
||||
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:
|
||||
export function accountImage(image: Uint8Array): void {
|
||||
BackendService.sendSessionCommand('Command_AccountImage', { image }, {
|
||||
onSuccess: () => {
|
||||
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');
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,10 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
export function accountPassword(oldPassword: string, newPassword: string, hashedNewPassword: string): void {
|
||||
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:
|
||||
BackendService.sendSessionCommand('Command_AccountPassword', { oldPassword, newPassword, hashedNewPassword }, {
|
||||
onSuccess: () => {
|
||||
SessionPersistence.accountPasswordChange();
|
||||
break;
|
||||
default:
|
||||
console.log('Failed to change password');
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ 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 './';
|
||||
|
|
@ -9,23 +11,21 @@ import { disconnect, login, updateStatus } from './';
|
|||
export function activate(options: WebSocketConnectOptions, passwordSalt?: string): void {
|
||||
const { userName, token } = options as unknown as AccountActivationParams;
|
||||
|
||||
const accountActivationConfig = {
|
||||
BackendService.sendSessionCommand('Command_Activate', {
|
||||
...webClient.clientConfig,
|
||||
userName,
|
||||
token,
|
||||
};
|
||||
|
||||
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) {
|
||||
}, {
|
||||
onResponseCode: {
|
||||
[ProtoController.root.Response.ResponseCode.RespActivationAccepted]: () => {
|
||||
SessionPersistence.accountActivationSuccess();
|
||||
login(options, passwordSalt);
|
||||
} else {
|
||||
},
|
||||
},
|
||||
onError: () => {
|
||||
updateStatus(StatusEnum.DISCONNECTED, 'Account Activation Failed');
|
||||
disconnect();
|
||||
SessionPersistence.accountActivationFailed();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
export function addToBuddyList(userName: string): void {
|
||||
|
|
@ -10,16 +10,9 @@ export function addToIgnoreList(userName: string): void {
|
|||
}
|
||||
|
||||
export function addToList(list: string, userName: string): void {
|
||||
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:
|
||||
BackendService.sendSessionCommand('Command_AddToList', { list, userName }, {
|
||||
onSuccess: () => {
|
||||
SessionPersistence.addToList(list, userName);
|
||||
break;
|
||||
default:
|
||||
console.error('Failed to add to list', responseCode);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,10 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
export function deckDel(deckId: number): void {
|
||||
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');
|
||||
}
|
||||
BackendService.sendSessionCommand('Command_DeckDel', { deckId }, {
|
||||
onSuccess: () => {
|
||||
SessionPersistence.deleteServerDeck(deckId);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,10 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
export function deckDelDir(path: string): void {
|
||||
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');
|
||||
}
|
||||
BackendService.sendSessionCommand('Command_DeckDelDir', { path }, {
|
||||
onSuccess: () => {
|
||||
SessionPersistence.deleteServerDeckDir(path);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
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');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -1,22 +1,11 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
export function deckList(): void {
|
||||
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');
|
||||
}
|
||||
}
|
||||
BackendService.sendSessionCommand('Command_DeckList', {}, {
|
||||
responseName: 'Response_DeckList',
|
||||
onSuccess: (response) => {
|
||||
SessionPersistence.updateServerDecks(response);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,10 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
export function deckNewDir(path: string, dirName: string): void {
|
||||
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');
|
||||
}
|
||||
BackendService.sendSessionCommand('Command_DeckNewDir', { path, dirName }, {
|
||||
onSuccess: () => {
|
||||
SessionPersistence.createServerDeckDir(path, dirName);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,11 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
export function deckUpload(path: string, deckId: number, deckList: string): void {
|
||||
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');
|
||||
}
|
||||
}
|
||||
|
||||
BackendService.sendSessionCommand('Command_DeckUpload', { path, deckId, deckList }, {
|
||||
responseName: 'Response_DeckUpload',
|
||||
onSuccess: (response) => {
|
||||
SessionPersistence.uploadServerDeck(path, response.newFile);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,30 +2,27 @@ 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;
|
||||
|
||||
const forgotPasswordChallengeConfig = {
|
||||
BackendService.sendSessionCommand('Command_ForgotPasswordChallenge', {
|
||||
...webClient.clientConfig,
|
||||
userName,
|
||||
email,
|
||||
};
|
||||
|
||||
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) {
|
||||
}, {
|
||||
onSuccess: () => {
|
||||
updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPassword();
|
||||
} else {
|
||||
disconnect();
|
||||
},
|
||||
onError: () => {
|
||||
updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPasswordFailed();
|
||||
}
|
||||
|
||||
disconnect();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ 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 './';
|
||||
|
|
@ -9,30 +10,25 @@ import { disconnect, updateStatus } from './';
|
|||
export function forgotPasswordRequest(options: WebSocketConnectOptions): void {
|
||||
const { userName } = options as unknown as ForgotPasswordParams;
|
||||
|
||||
const forgotPasswordConfig = {
|
||||
BackendService.sendSessionCommand('Command_ForgotPasswordRequest', {
|
||||
...webClient.clientConfig,
|
||||
userName,
|
||||
};
|
||||
|
||||
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) {
|
||||
}, {
|
||||
responseName: 'Response_ForgotPasswordRequest',
|
||||
onSuccess: (resp) => {
|
||||
if (resp?.challengeEmail) {
|
||||
updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPasswordChallenge();
|
||||
} else {
|
||||
updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPassword();
|
||||
}
|
||||
} else {
|
||||
disconnect();
|
||||
},
|
||||
onError: () => {
|
||||
updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPasswordFailed();
|
||||
}
|
||||
|
||||
disconnect();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ 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';
|
||||
|
||||
|
|
@ -10,30 +11,28 @@ import { disconnect, updateStatus } from '.';
|
|||
export function forgotPasswordReset(options: WebSocketConnectOptions, passwordSalt?: string): void {
|
||||
const { userName, token, newPassword } = options as unknown as ForgotPasswordResetParams;
|
||||
|
||||
const forgotPasswordResetConfig: any = {
|
||||
const params: any = {
|
||||
...webClient.clientConfig,
|
||||
userName,
|
||||
token,
|
||||
};
|
||||
|
||||
if (passwordSalt) {
|
||||
forgotPasswordResetConfig.hashedNewPassword = hashPassword(passwordSalt, newPassword);
|
||||
params.hashedNewPassword = hashPassword(passwordSalt, newPassword);
|
||||
} else {
|
||||
forgotPasswordResetConfig.newPassword = newPassword;
|
||||
params.newPassword = newPassword;
|
||||
}
|
||||
|
||||
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) {
|
||||
BackendService.sendSessionCommand('Command_ForgotPasswordReset', params, {
|
||||
onSuccess: () => {
|
||||
updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPasswordSuccess();
|
||||
} else {
|
||||
disconnect();
|
||||
},
|
||||
onError: () => {
|
||||
updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPasswordFailed();
|
||||
}
|
||||
|
||||
disconnect();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,11 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
export function getGamesOfUser(userName: string): void {
|
||||
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:
|
||||
BackendService.sendSessionCommand('Command_GetGamesOfUser', { userName }, {
|
||||
responseName: 'Response_GetGamesOfUser',
|
||||
onSuccess: (response) => {
|
||||
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');
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,11 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
export function getUserInfo(userName: string): void {
|
||||
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');
|
||||
}
|
||||
BackendService.sendSessionCommand('Command_GetUserInfo', { userName }, {
|
||||
responseName: 'Response_GetUserInfo',
|
||||
onSuccess: (response) => {
|
||||
SessionPersistence.getUserInfo(response.userInfo);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,12 +6,11 @@ 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';
|
||||
|
|
@ -24,12 +23,8 @@ 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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,37 +1,11 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { RoomPersistence } from '../../persistence';
|
||||
|
||||
export function joinRoom(roomId: number): void {
|
||||
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);
|
||||
}
|
||||
BackendService.sendSessionCommand('Command_JoinRoom', { roomId }, {
|
||||
responseName: 'Response_JoinRoom',
|
||||
onSuccess: (response) => {
|
||||
RoomPersistence.joinRoom(response.roomInfo);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
|
||||
export function listRooms(): void {
|
||||
const command = webClient.protobuf.controller.Command_ListRooms.create();
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_ListRooms.ext': command });
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc);
|
||||
BackendService.sendSessionCommand('Command_ListRooms', {}, {});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,11 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
export function listUsers(): void {
|
||||
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:
|
||||
BackendService.sendSessionCommand('Command_ListUsers', {}, {
|
||||
responseName: 'Response_ListUsers',
|
||||
onSuccess: (response) => {
|
||||
SessionPersistence.updateUsers(response.userList);
|
||||
break;
|
||||
default:
|
||||
console.log(`Failed to fetch Server Rooms [${responseCode}] : `, raw);
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
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';
|
||||
|
||||
|
|
@ -25,13 +27,18 @@ export function login(options: WebSocketConnectOptions, passwordSalt?: string):
|
|||
loginConfig.password = password;
|
||||
}
|
||||
|
||||
const command = webClient.protobuf.controller.Command_Login.create(loginConfig);
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_Login.ext': command });
|
||||
const { ResponseCode } = ProtoController.root.Response;
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, raw => {
|
||||
const resp = raw['.Response_Login.ext'];
|
||||
const onLoginError = (message: string, extra?: () => void) => {
|
||||
updateStatus(StatusEnum.DISCONNECTED, message);
|
||||
extra?.();
|
||||
SessionPersistence.loginFailed();
|
||||
disconnect();
|
||||
};
|
||||
|
||||
if (raw.responseCode === webClient.protobuf.controller.Response.ResponseCode.RespOk) {
|
||||
BackendService.sendSessionCommand('Command_Login', loginConfig, {
|
||||
responseName: 'Response_Login',
|
||||
onSuccess: (resp) => {
|
||||
const { buddyList, ignoreList, userInfo } = resp;
|
||||
|
||||
SessionPersistence.updateBuddyList(buddyList);
|
||||
|
|
@ -43,50 +50,30 @@ export function login(options: WebSocketConnectOptions, passwordSalt?: string):
|
|||
listRooms();
|
||||
|
||||
updateStatus(StatusEnum.LOGGED_IN, 'Logged in.');
|
||||
|
||||
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();
|
||||
},
|
||||
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}`),
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +1,10 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
export function message(userName: string, message: string): void {
|
||||
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:
|
||||
BackendService.sendSessionCommand('Command_Message', { userName, message }, {
|
||||
onSuccess: () => {
|
||||
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');
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
|
||||
export function ping(pingReceived: Function): void {
|
||||
const command = webClient.protobuf.controller.Command_Ping.create();
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_Ping.ext': command });
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, pingReceived);
|
||||
BackendService.sendSessionCommand('Command_Ping', {}, {
|
||||
onResponse: (raw) => pingReceived(raw),
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
import { ServerRegisterParams } from 'store';
|
||||
import { WebSocketConnectOptions } from 'types';
|
||||
import { StatusEnum, 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 } from './';
|
||||
import { login, disconnect, updateStatus } from './';
|
||||
|
||||
export function register(options: WebSocketConnectOptions, passwordSalt?: string): void {
|
||||
const { userName, password, email, country, realName } = options as ServerRegisterParams;
|
||||
|
||||
const registerConfig: any = {
|
||||
const params: any = {
|
||||
...webClient.clientConfig,
|
||||
userName,
|
||||
email,
|
||||
|
|
@ -20,55 +21,57 @@ export function register(options: WebSocketConnectOptions, passwordSalt?: string
|
|||
};
|
||||
|
||||
if (passwordSalt) {
|
||||
registerConfig.hashedPassword = hashPassword(passwordSalt, password);
|
||||
params.hashedPassword = hashPassword(passwordSalt, password);
|
||||
} else {
|
||||
registerConfig.password = password;
|
||||
params.password = password;
|
||||
}
|
||||
|
||||
const command = webClient.protobuf.controller.Command_Register.create(registerConfig);
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({ '.Command_Register.ext': command });
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, raw => {
|
||||
if (raw.responseCode === webClient.protobuf.controller.Response.ResponseCode.RespRegistrationAccepted) {
|
||||
login(options, passwordSalt);
|
||||
SessionPersistence.registrationSuccess()
|
||||
return;
|
||||
}
|
||||
|
||||
switch (raw.responseCode) {
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespRegistrationAcceptedNeedsActivation:
|
||||
SessionPersistence.accountAwaitingActivation(options);
|
||||
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;
|
||||
}
|
||||
const { ResponseCode } = ProtoController.root.Response;
|
||||
|
||||
const onRegistrationError = (action: () => void) => {
|
||||
action();
|
||||
updateStatus(StatusEnum.DISCONNECTED, 'Registration failed');
|
||||
disconnect();
|
||||
};
|
||||
|
||||
BackendService.sendSessionCommand('Command_Register', params, {
|
||||
onResponseCode: {
|
||||
[ResponseCode.RespRegistrationAccepted]: () => {
|
||||
login(options, passwordSalt);
|
||||
SessionPersistence.registrationSuccess();
|
||||
},
|
||||
[ResponseCode.RespRegistrationAcceptedNeedsActivation]: () => {
|
||||
updateStatus(StatusEnum.DISCONNECTED, 'Registration accepted, awaiting activation');
|
||||
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')
|
||||
),
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { BackendService } from '../../services/BackendService';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
export function removeFromBuddyList(userName: string): void {
|
||||
|
|
@ -10,16 +10,9 @@ export function removeFromIgnoreList(userName: string): void {
|
|||
}
|
||||
|
||||
export function removeFromList(list: string, userName: string): void {
|
||||
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:
|
||||
BackendService.sendSessionCommand('Command_RemoveFromList', { list, userName }, {
|
||||
onSuccess: () => {
|
||||
SessionPersistence.removeFromList(list, userName);
|
||||
break;
|
||||
default:
|
||||
console.error('Failed to remove from list', responseCode);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
import { BackendService } from '../../services/BackendService';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
export function replayDeleteMatch(gameId: number): void {
|
||||
BackendService.sendSessionCommand('Command_ReplayDeleteMatch', { gameId }, {
|
||||
onSuccess: () => {
|
||||
SessionPersistence.replayDeleteMatch(gameId);
|
||||
},
|
||||
});
|
||||
}
|
||||
11
webclient/src/websocket/commands/session/replayList.ts
Normal file
11
webclient/src/websocket/commands/session/replayList.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
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);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
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);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@ 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 {
|
||||
|
|
@ -15,64 +17,48 @@ import {
|
|||
export function requestPasswordSalt(options: WebSocketConnectOptions): void {
|
||||
const { userName } = options as RequestPasswordSaltParams;
|
||||
|
||||
const registerConfig = {
|
||||
...webClient.clientConfig,
|
||||
userName,
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
const onFailure = () => {
|
||||
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;
|
||||
}
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespRegistrationRequired: {
|
||||
updateStatus(StatusEnum.DISCONNECTED, 'Login failed: registration required');
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
updateStatus(StatusEnum.DISCONNECTED, 'Login failed: Unknown Reason');
|
||||
}
|
||||
}
|
||||
|
||||
switch (options.reason) {
|
||||
case WebSocketConnectReason.ACTIVATE_ACCOUNT: {
|
||||
case WebSocketConnectReason.ACTIVATE_ACCOUNT:
|
||||
SessionPersistence.accountActivationFailed();
|
||||
break;
|
||||
}
|
||||
|
||||
case WebSocketConnectReason.PASSWORD_RESET: {
|
||||
case WebSocketConnectReason.PASSWORD_RESET:
|
||||
SessionPersistence.resetPasswordFailed();
|
||||
break;
|
||||
}
|
||||
|
||||
case WebSocketConnectReason.LOGIN:
|
||||
default: {
|
||||
default:
|
||||
SessionPersistence.loginFailed();
|
||||
}
|
||||
}
|
||||
|
||||
disconnect();
|
||||
};
|
||||
|
||||
BackendService.sendSessionCommand('Command_RequestPasswordSalt', {
|
||||
...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);
|
||||
}
|
||||
},
|
||||
onResponseCode: {
|
||||
[ProtoController.root.Response.ResponseCode.RespRegistrationRequired]: () => {
|
||||
updateStatus(StatusEnum.DISCONNECTED, 'Login failed: registration required');
|
||||
onFailure();
|
||||
},
|
||||
},
|
||||
onError: () => {
|
||||
updateStatus(StatusEnum.DISCONNECTED, 'Login failed: Unknown Reason');
|
||||
onFailure();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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'),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { StatusEnum } from 'types';
|
||||
import webClient from '../../WebClient';
|
||||
import { ProtoController } from '../../services/ProtoController';
|
||||
import { updateStatus } from '../../commands/session';
|
||||
import { ConnectionClosedData } from './interfaces';
|
||||
|
||||
|
|
@ -10,29 +10,30 @@ export function connectionClosed({ reason, reasonStr }: ConnectionClosedData): v
|
|||
if (reasonStr) {
|
||||
message = reasonStr;
|
||||
} else {
|
||||
const { CloseReason } = ProtoController.root.Event_ConnectionClosed;
|
||||
switch (reason) {
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.USER_LIMIT_REACHED:
|
||||
case CloseReason.USER_LIMIT_REACHED:
|
||||
message = 'The server has reached its maximum user capacity';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.TOO_MANY_CONNECTIONS:
|
||||
case CloseReason.TOO_MANY_CONNECTIONS:
|
||||
message = 'There are too many concurrent connections from your address';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.BANNED:
|
||||
case CloseReason.BANNED:
|
||||
message = 'You are banned';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.DEMOTED:
|
||||
case CloseReason.DEMOTED:
|
||||
message = 'You were demoted';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.SERVER_SHUTDOWN:
|
||||
case CloseReason.SERVER_SHUTDOWN:
|
||||
message = 'Scheduled server shutdown';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.USERNAMEINVALID:
|
||||
case CloseReason.USERNAMEINVALID:
|
||||
message = 'Invalid username';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.LOGGEDINELSEWERE:
|
||||
case CloseReason.LOGGEDINELSEWERE:
|
||||
message = 'You have been logged out due to logging in at another location';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.OTHER:
|
||||
case CloseReason.OTHER:
|
||||
default:
|
||||
message = 'Unknown reason';
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ 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';
|
||||
|
|
@ -20,8 +21,8 @@ export const SessionEvents: ProtobufEvents = {
|
|||
'.Event_ListRooms.ext': listRooms,
|
||||
'.Event_NotifyUser.ext': notifyUser,
|
||||
'.Event_RemoveFromList.ext': removeFromList,
|
||||
'.Event_ReplayAdded.ext': () => console.log('Event_ReplayAdded'),
|
||||
'.Event_ServerCompleteList.ext': () => console.log('Event_ServerCompleteList'),
|
||||
'.Event_ReplayAdded.ext': replayAdded,
|
||||
'.Event_ServerCompleteList.ext': serverCompleteList,
|
||||
'.Event_ServerIdentification.ext': serverIdentification,
|
||||
'.Event_ServerMessage.ext': serverMessage,
|
||||
'.Event_ServerShutdown.ext': serverShutdown,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Game, NotificationType, Room, User } from 'types';
|
||||
import { Game, NotificationType, ReplayMatch, Room, User } from 'types';
|
||||
|
||||
export interface AddToListData {
|
||||
listName: string;
|
||||
|
|
@ -13,6 +13,8 @@ export interface ConnectionClosedData {
|
|||
|
||||
export interface GameJoinedData {
|
||||
gameInfo: Game;
|
||||
gameTypes: any[];
|
||||
hostId: number;
|
||||
playerId: number;
|
||||
spectator: boolean;
|
||||
resuming: boolean;
|
||||
|
|
@ -76,3 +78,13 @@ export interface UserMessageData {
|
|||
receiverName: string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface ReplayAddedData {
|
||||
matchInfo: ReplayMatch;
|
||||
}
|
||||
|
||||
export interface ServerCompleteListData {
|
||||
serverId: number;
|
||||
userList: User[];
|
||||
roomList: Room[];
|
||||
}
|
||||
|
|
|
|||
6
webclient/src/websocket/events/session/replayAdded.ts
Normal file
6
webclient/src/websocket/events/session/replayAdded.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import { SessionPersistence } from '../../persistence';
|
||||
import { ReplayAddedData } from './interfaces';
|
||||
|
||||
export function replayAdded({ matchInfo }: ReplayAddedData): void {
|
||||
SessionPersistence.replayAdded(matchInfo);
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import { RoomPersistence, SessionPersistence } from '../../persistence';
|
||||
import { ServerCompleteListData } from './interfaces';
|
||||
|
||||
export function serverCompleteList({ userList, roomList }: ServerCompleteListData): void {
|
||||
SessionPersistence.updateUsers(userList);
|
||||
RoomPersistence.updateRooms(roomList);
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { StatusEnum, WebSocketConnectReason } from 'types';
|
||||
import { StatusEnum, WebSocketConnectOptions, WebSocketConnectReason } from 'types';
|
||||
|
||||
import webClient from '../../WebClient';
|
||||
import {
|
||||
|
|
@ -24,48 +24,48 @@ export function serverIdentification(info: ServerIdentificationData): void {
|
|||
return;
|
||||
}
|
||||
|
||||
const getPasswordSalt = passwordSaltSupported(serverOptions, webClient);
|
||||
const { options } = webClient;
|
||||
const getPasswordSalt = passwordSaltSupported(serverOptions);
|
||||
const connectOptions = { ...webClient.options };
|
||||
|
||||
switch (options.reason) {
|
||||
switch (connectOptions.reason) {
|
||||
case WebSocketConnectReason.LOGIN:
|
||||
updateStatus(StatusEnum.LOGGING_IN, 'Logging In...');
|
||||
if (getPasswordSalt) {
|
||||
requestPasswordSalt(options);
|
||||
requestPasswordSalt(connectOptions);
|
||||
} else {
|
||||
login(options);
|
||||
login(connectOptions);
|
||||
}
|
||||
break;
|
||||
case WebSocketConnectReason.REGISTER:
|
||||
const passwordSalt = getPasswordSalt ? generateSalt() : null;
|
||||
register(options, passwordSalt);
|
||||
register(connectOptions, passwordSalt);
|
||||
break;
|
||||
case WebSocketConnectReason.ACTIVATE_ACCOUNT:
|
||||
if (getPasswordSalt) {
|
||||
requestPasswordSalt(options);
|
||||
requestPasswordSalt(connectOptions);
|
||||
} else {
|
||||
activate(options);
|
||||
activate(connectOptions);
|
||||
}
|
||||
break;
|
||||
case WebSocketConnectReason.PASSWORD_RESET_REQUEST:
|
||||
forgotPasswordRequest(options);
|
||||
forgotPasswordRequest(connectOptions);
|
||||
break;
|
||||
case WebSocketConnectReason.PASSWORD_RESET_CHALLENGE:
|
||||
forgotPasswordChallenge(options);
|
||||
forgotPasswordChallenge(connectOptions);
|
||||
break;
|
||||
case WebSocketConnectReason.PASSWORD_RESET:
|
||||
if (getPasswordSalt) {
|
||||
requestPasswordSalt(options);
|
||||
requestPasswordSalt(connectOptions);
|
||||
} else {
|
||||
forgotPasswordReset(options);
|
||||
forgotPasswordReset(connectOptions);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
updateStatus(StatusEnum.DISCONNECTED, 'Unknown Connection Reason: ' + options.reason);
|
||||
updateStatus(StatusEnum.DISCONNECTED, 'Unknown Connection Reason: ' + connectOptions.reason);
|
||||
disconnect();
|
||||
break;
|
||||
}
|
||||
|
||||
webClient.options = {};
|
||||
webClient.options = {} as WebSocketConnectOptions;
|
||||
SessionPersistence.updateInfo(serverName, serverVersion);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,4 +27,20 @@ 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { ServerDispatch } from 'store';
|
||||
import { DeckStorageTreeItem, StatusEnum, User, WebSocketConnectOptions } from 'types';
|
||||
import { DeckList, DeckStorageTreeItem, ReplayMatch, StatusEnum, User, WebSocketConnectOptions } from 'types';
|
||||
|
||||
import { sanitizeHtml } from 'websocket/utils';
|
||||
import {
|
||||
|
|
@ -10,9 +10,6 @@ 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() {
|
||||
|
|
@ -165,7 +162,7 @@ export class SessionPersistence {
|
|||
ServerDispatch.accountEditChanged({ realName, email, country });
|
||||
}
|
||||
|
||||
static accountImageChanged(avatarBmp: IBytesValue): void {
|
||||
static accountImageChanged(avatarBmp: Uint8Array): void {
|
||||
ServerDispatch.accountImageChanged({ avatarBmp });
|
||||
}
|
||||
|
||||
|
|
@ -178,7 +175,8 @@ export class SessionPersistence {
|
|||
}
|
||||
|
||||
static getGamesOfUser(userName: string, response: any): void {
|
||||
console.log('getGamesOfUser');
|
||||
// Response_GetGamesOfUser contains a gameList field — log for now until game layer is complete
|
||||
console.log('getGamesOfUser', userName, response);
|
||||
}
|
||||
|
||||
static gameJoined(gameJoinedData: GameJoinedData): void {
|
||||
|
|
@ -209,28 +207,40 @@ export class SessionPersistence {
|
|||
ServerDispatch.removeFromList(list, userName);
|
||||
}
|
||||
|
||||
static deckDelete(deckId: number): void {
|
||||
console.log('deckDelete', deckId);
|
||||
static deleteServerDeck(deckId: number): void {
|
||||
ServerDispatch.deckDelete(deckId);
|
||||
}
|
||||
|
||||
static deckDeleteDir(path: string): void {
|
||||
console.log('deckDeleteDir', path);
|
||||
static updateServerDecks(deckList: DeckList): void {
|
||||
ServerDispatch.backendDecks(deckList);
|
||||
}
|
||||
|
||||
static deckDownload(deckId: number): void {
|
||||
console.log('deckDownload', deckId);
|
||||
static uploadServerDeck(path: string, treeItem: DeckStorageTreeItem): void {
|
||||
ServerDispatch.deckUpload(path, treeItem);
|
||||
}
|
||||
|
||||
static deckList(deckList: DeckList): void {
|
||||
console.log('deckList', deckList);
|
||||
static createServerDeckDir(path: string, dirName: string): void {
|
||||
ServerDispatch.deckNewDir(path, dirName);
|
||||
}
|
||||
|
||||
static deckNewDir(path: string, dirName: string): void {
|
||||
console.log('deckNewDir', path, dirName);
|
||||
static deleteServerDeckDir(path: string): void {
|
||||
ServerDispatch.deckDelDir(path);
|
||||
}
|
||||
|
||||
static deckUpload(treeItem: DeckStorageTreeItem): void {
|
||||
console.log('deckUpload', treeItem);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
export { AdminPersistence } from './AdminPresistence';
|
||||
export { AdminPersistence } from './AdminPersistence';
|
||||
export { RoomPersistence } from './RoomPersistence';
|
||||
export { SessionPersistence } from './SessionPersistence';
|
||||
export { ModeratorPersistence } from './ModeratorPresistence';
|
||||
export { ModeratorPersistence } from './ModeratorPersistence';
|
||||
export { GamePersistence } from './GamePersistence';
|
||||
|
|
|
|||
82
webclient/src/websocket/services/BackendService.ts
Normal file
82
webclient/src/websocket/services/BackendService.ts
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
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}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
24
webclient/src/websocket/services/ProtoController.ts
Normal file
24
webclient/src/websocket/services/ProtoController.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
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();
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
@ -1,19 +1,13 @@
|
|||
import protobuf from 'protobufjs';
|
||||
|
||||
import { CommonEvents, GameEvents, RoomEvents, SessionEvents } from '../events';
|
||||
import { SessionPersistence } from '../persistence';
|
||||
import { WebClient } from '../WebClient';
|
||||
import { SessionCommands } from 'websocket';
|
||||
import ProtoFiles from '../../proto-files.json';
|
||||
import { ProtoController } from './ProtoController';
|
||||
|
||||
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 } = {};
|
||||
|
||||
|
|
@ -21,8 +15,7 @@ export class ProtobufService {
|
|||
|
||||
constructor(webClient: WebClient) {
|
||||
this.webClient = webClient;
|
||||
|
||||
this.loadProtobufFiles();
|
||||
ProtoController.load();
|
||||
}
|
||||
|
||||
public resetCommands() {
|
||||
|
|
@ -30,8 +23,8 @@ export class ProtobufService {
|
|||
this.pendingCommands = {};
|
||||
}
|
||||
|
||||
public sendRoomCommand(roomId: number, roomCmd: number, callback?: Function) {
|
||||
const cmd = this.controller.CommandContainer.create({
|
||||
public sendRoomCommand(roomId: number, roomCmd: any, callback?: Function) {
|
||||
const cmd = ProtoController.root.CommandContainer.create({
|
||||
'roomId': roomId,
|
||||
'roomCommand': [roomCmd]
|
||||
});
|
||||
|
|
@ -39,38 +32,38 @@ export class ProtobufService {
|
|||
this.sendCommand(cmd, raw => callback && callback(raw));
|
||||
}
|
||||
|
||||
public sendSessionCommand(sesCmd: number, callback?: Function) {
|
||||
const cmd = this.controller.CommandContainer.create({
|
||||
public sendSessionCommand(sesCmd: any, callback?: Function) {
|
||||
const cmd = ProtoController.root.CommandContainer.create({
|
||||
'sessionCommand': [sesCmd]
|
||||
});
|
||||
|
||||
this.sendCommand(cmd, (raw) => callback && callback(raw));
|
||||
}
|
||||
|
||||
public sendModeratorCommand(modCmd: number, callback?: Function) {
|
||||
const cmd = this.controller.CommandContainer.create({
|
||||
public sendModeratorCommand(modCmd: any, callback?: Function) {
|
||||
const cmd = ProtoController.root.CommandContainer.create({
|
||||
'moderatorCommand': [modCmd]
|
||||
});
|
||||
|
||||
this.sendCommand(cmd, (raw) => callback && callback(raw));
|
||||
}
|
||||
|
||||
public sendAdminCommand(adminCmd: number, callback?: Function) {
|
||||
const cmd = this.controller.CommandContainer.create({
|
||||
public sendAdminCommand(adminCmd: any, callback?: Function) {
|
||||
const cmd = ProtoController.root.CommandContainer.create({
|
||||
'adminCommand': [adminCmd]
|
||||
});
|
||||
|
||||
this.sendCommand(cmd, (raw) => callback && callback(raw));
|
||||
}
|
||||
|
||||
public sendCommand(cmd: number, callback: Function) {
|
||||
public sendCommand(cmd: any, callback: Function) {
|
||||
this.cmdId++;
|
||||
|
||||
cmd['cmdId'] = this.cmdId;
|
||||
this.pendingCommands[this.cmdId] = callback;
|
||||
|
||||
if (this.webClient.socket.checkReadyState(WebSocket.OPEN)) {
|
||||
this.webClient.socket.send(this.controller.CommandContainer.encode(cmd).finish());
|
||||
this.webClient.socket.send(ProtoController.root.CommandContainer.encode(cmd).finish());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -81,20 +74,20 @@ export class ProtobufService {
|
|||
public handleMessageEvent({ data }: MessageEvent): void {
|
||||
try {
|
||||
const uint8msg = new Uint8Array(data);
|
||||
const msg = this.controller.ServerMessage.decode(uint8msg);
|
||||
const msg = ProtoController.root.ServerMessage.decode(uint8msg);
|
||||
|
||||
if (msg) {
|
||||
switch (msg.messageType) {
|
||||
case this.controller.ServerMessage.MessageType.RESPONSE:
|
||||
case ProtoController.root.ServerMessage.MessageType.RESPONSE:
|
||||
this.processServerResponse(msg.response);
|
||||
break;
|
||||
case this.controller.ServerMessage.MessageType.ROOM_EVENT:
|
||||
case ProtoController.root.ServerMessage.MessageType.ROOM_EVENT:
|
||||
this.processRoomEvent(msg.roomEvent, msg);
|
||||
break;
|
||||
case this.controller.ServerMessage.MessageType.SESSION_EVENT:
|
||||
case ProtoController.root.ServerMessage.MessageType.SESSION_EVENT:
|
||||
this.processSessionEvent(msg.sessionEvent, msg);
|
||||
break;
|
||||
case this.controller.ServerMessage.MessageType.GAME_EVENT_CONTAINER:
|
||||
case ProtoController.root.ServerMessage.MessageType.GAME_EVENT_CONTAINER:
|
||||
this.processGameEvent(msg.gameEvent, msg);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -142,17 +135,4 @@ 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();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
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;
|
||||
|
|
@ -25,7 +26,7 @@ export const generateSalt = (): string => {
|
|||
return salt;
|
||||
}
|
||||
|
||||
export const passwordSaltSupported = (serverOptions, webClient): number => {
|
||||
export const passwordSaltSupported = (serverOptions: number): number => {
|
||||
// Intentional use of Bitwise operator b/c of how Servatrice Enums work
|
||||
return serverOptions & webClient.protobuf.controller.Event_ServerIdentification.ServerOptions.SupportsPasswordHash;
|
||||
return serverOptions & ProtoController.root.Event_ServerIdentification.ServerOptions.SupportsPasswordHash;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue