Compare commits
No commits in common. "2303880b8727870abdba8e021ae7d821ee783498" and "b0d8a33d5f7e13f3d7df495e648b09f2742e517e" have entirely different histories.
2303880b87
...
b0d8a33d5f
79 changed files with 4375 additions and 1084 deletions
|
@ -1,4 +1,4 @@
|
|||
FROM fedora:40
|
||||
FROM fedora:38
|
||||
|
||||
RUN dnf install -y \
|
||||
ccache \
|
|
@ -1,4 +1,4 @@
|
|||
FROM ubuntu:noble
|
||||
FROM ubuntu:lunar
|
||||
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
|
@ -15,11 +15,11 @@ include different targets -->
|
|||
- <kbd>Ubuntu 18.04 LTS</kbd> ("Bionic Beaver")
|
||||
- <kbd>Ubuntu 20.04 LTS</kbd> ("Focal Fossa")
|
||||
- <kbd>Ubuntu 22.04 LTS</kbd> ("Jammy Jellyfish")
|
||||
- <kbd>Ubuntu 24.04 LTS</kbd> ("Noble Numbat")
|
||||
- <kbd>Ubuntu 23.04</kbd> ("Lunar Lobster")
|
||||
- <kbd>Debian 11</kbd> ("Bullseye")
|
||||
- <kbd>Debian 12</kbd> ("Bookworm")
|
||||
- <kbd>Fedora 38</kbd>
|
||||
- <kbd>Fedora 39</kbd>
|
||||
- <kbd>Fedora 40</kbd>
|
||||
<kbd>We are also packaged in Arch Linux's official community repository, courtesy of @FFY00</kbd></i>
|
||||
<kbd>General Linux support is available via a flatpak package (Flathub)</kbd></i>
|
||||
</pre>
|
||||
|
|
6
.github/workflows/desktop-build.yml
vendored
6
.github/workflows/desktop-build.yml
vendored
|
@ -97,10 +97,10 @@ jobs:
|
|||
- distro: Debian12
|
||||
package: DEB
|
||||
|
||||
- distro: Fedora39
|
||||
- distro: Fedora38
|
||||
package: RPM
|
||||
|
||||
- distro: Fedora40
|
||||
- distro: Fedora39
|
||||
package: RPM
|
||||
|
||||
- distro: UbuntuBionic
|
||||
|
@ -114,7 +114,7 @@ jobs:
|
|||
package: DEB
|
||||
test: skip # running tests on all distros is superfluous
|
||||
|
||||
- distro: UbuntuNoble
|
||||
- distro: UbuntuLunar
|
||||
package: DEB
|
||||
|
||||
name: ${{matrix.distro}}
|
||||
|
|
2
.github/workflows/translations-pull.yml
vendored
2
.github/workflows/translations-pull.yml
vendored
|
@ -32,7 +32,7 @@ jobs:
|
|||
- name: Create pull request
|
||||
if: github.event_name != 'pull_request'
|
||||
id: create_pr
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
with:
|
||||
add-paths: |
|
||||
cockatrice/translations/*.ts
|
||||
|
|
2
.github/workflows/translations-push.yml
vendored
2
.github/workflows/translations-push.yml
vendored
|
@ -56,7 +56,7 @@ jobs:
|
|||
- name: Create pull request
|
||||
if: github.event_name != 'pull_request'
|
||||
id: create_pr
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
with:
|
||||
add-paths: |
|
||||
cockatrice/cockatrice_en@source.ts
|
||||
|
|
|
@ -74,7 +74,7 @@ endif()
|
|||
|
||||
# A project name is needed for CPack
|
||||
# Version can be overriden by git tags, see cmake/getversion.cmake
|
||||
project("Cockatrice" VERSION 2.9.1)
|
||||
project("Cockatrice" VERSION 2.9.0)
|
||||
|
||||
# Set release name if not provided via env/cmake var
|
||||
if(NOT DEFINED GIT_TAG_RELEASENAME)
|
||||
|
|
|
@ -32,7 +32,6 @@ RemoteClient::RemoteClient(QObject *parent)
|
|||
{
|
||||
|
||||
clearNewClientFeatures();
|
||||
maxTimeout = SettingsCache::instance().getTimeOut();
|
||||
int keepalive = SettingsCache::instance().getKeepAlive();
|
||||
timer = new QTimer(this);
|
||||
timer->setInterval(keepalive * 1000);
|
||||
|
|
|
@ -89,7 +89,7 @@ private slots:
|
|||
void submitForgotPasswordChallengeResponse(const Response &response);
|
||||
|
||||
private:
|
||||
int maxTimeout;
|
||||
static const int maxTimeout = 5;
|
||||
int timeRunning, lastDataReceived;
|
||||
QByteArray inputBuffer;
|
||||
bool messageInProgress;
|
||||
|
|
|
@ -195,7 +195,6 @@ SettingsCache::SettingsCache()
|
|||
|
||||
lang = settings->value("personal/lang").toString();
|
||||
keepalive = settings->value("personal/keepalive", 3).toInt();
|
||||
timeout = settings->value("personal/timeout", 5).toInt();
|
||||
|
||||
// tip of the day settings
|
||||
showTipsOnStartup = settings->value("tipOfDay/showTips", true).toBool();
|
||||
|
|
|
@ -134,7 +134,6 @@ private:
|
|||
bool spectatorsCanSeeEverything;
|
||||
bool createGameAsSpectator;
|
||||
int keepalive;
|
||||
int timeout;
|
||||
void translateLegacySettings();
|
||||
QString getSafeConfigPath(QString configEntry, QString defaultPath) const;
|
||||
QString getSafeConfigFilePath(QString configEntry, QString defaultPath) const;
|
||||
|
@ -435,10 +434,6 @@ public:
|
|||
{
|
||||
return keepalive;
|
||||
}
|
||||
int getTimeOut() const
|
||||
{
|
||||
return timeout;
|
||||
}
|
||||
int getMaxFontSize() const
|
||||
{
|
||||
return maxFontSize;
|
||||
|
|
|
@ -21,10 +21,6 @@ public:
|
|||
{
|
||||
return id;
|
||||
}
|
||||
void setId(int _id)
|
||||
{
|
||||
id = _id;
|
||||
}
|
||||
Server_Card *getStartCard() const
|
||||
{
|
||||
return startCard;
|
||||
|
|
|
@ -296,12 +296,6 @@ void Server_Player::addArrow(Server_Arrow *arrow)
|
|||
arrows.insert(arrow->getId(), arrow);
|
||||
}
|
||||
|
||||
void Server_Player::updateArrowId(int id)
|
||||
{
|
||||
auto *arrow = arrows.take(id);
|
||||
arrows.insert(arrow->getId(), arrow);
|
||||
}
|
||||
|
||||
bool Server_Player::deleteArrow(int arrowId)
|
||||
{
|
||||
Server_Arrow *arrow = arrows.value(arrowId, 0);
|
||||
|
@ -503,7 +497,9 @@ Response::ResponseCode Server_Player::moveCard(GameEventStorage &ges,
|
|||
const QList<Server_Player *> &players = game->getPlayers().values();
|
||||
for (auto player : players) {
|
||||
QList<int> arrowsToDelete;
|
||||
for (Server_Arrow *arrow : player->getArrows()) {
|
||||
QMapIterator<int, Server_Arrow *> arrowIterator(player->getArrows());
|
||||
while (arrowIterator.hasNext()) {
|
||||
Server_Arrow *arrow = arrowIterator.next().value();
|
||||
if ((arrow->getStartCard() == card) || (arrow->getTargetItem() == card))
|
||||
arrowsToDelete.append(arrow->getId());
|
||||
}
|
||||
|
@ -1482,8 +1478,9 @@ Server_Player::cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer
|
|||
// Copy Arrows
|
||||
const QList<Server_Player *> &players = game->getPlayers().values();
|
||||
for (auto player : players) {
|
||||
QList<int> changedArrowIds;
|
||||
for (Server_Arrow *arrow : player->getArrows()) {
|
||||
QMapIterator<int, Server_Arrow *> arrowIterator(player->getArrows());
|
||||
while (arrowIterator.hasNext()) {
|
||||
Server_Arrow *arrow = arrowIterator.next().value();
|
||||
bool sendGameEvent = false;
|
||||
const auto *startCard = arrow->getStartCard();
|
||||
if (startCard == targetCard) {
|
||||
|
@ -1500,10 +1497,7 @@ Server_Player::cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer
|
|||
if (sendGameEvent) {
|
||||
Event_CreateArrow _event;
|
||||
ServerInfo_Arrow *arrowInfo = _event.mutable_arrow_info();
|
||||
changedArrowIds.append(arrow->getId());
|
||||
int id = player->newArrowId();
|
||||
arrow->setId(id);
|
||||
arrowInfo->set_id(id);
|
||||
arrowInfo->set_id(arrow->getId());
|
||||
arrowInfo->set_start_player_id(player->getPlayerId());
|
||||
arrowInfo->set_start_zone(startCard->getZone()->getName().toStdString());
|
||||
arrowInfo->set_start_card_id(startCard->getId());
|
||||
|
@ -1520,9 +1514,6 @@ Server_Player::cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer
|
|||
ges.enqueueGameEvent(_event, player->getPlayerId());
|
||||
}
|
||||
}
|
||||
for (int id : changedArrowIds) {
|
||||
player->updateArrowId(id);
|
||||
}
|
||||
}
|
||||
|
||||
targetCard->resetState();
|
||||
|
@ -1588,7 +1579,9 @@ Server_Player::cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer
|
|||
return Response::RespNameNotFound;
|
||||
}
|
||||
|
||||
for (Server_Arrow *temp : arrows) {
|
||||
QMapIterator<int, Server_Arrow *> arrowIterator(arrows);
|
||||
while (arrowIterator.hasNext()) {
|
||||
Server_Arrow *temp = arrowIterator.next().value();
|
||||
if ((temp->getStartCard() == startCard) && (temp->getTargetItem() == targetItem)) {
|
||||
return Response::RespContextError;
|
||||
}
|
||||
|
|
|
@ -164,7 +164,6 @@ public:
|
|||
|
||||
void addZone(Server_CardZone *zone);
|
||||
void addArrow(Server_Arrow *arrow);
|
||||
void updateArrowId(int id);
|
||||
bool deleteArrow(int arrowId);
|
||||
void addCounter(Server_Counter *counter);
|
||||
|
||||
|
|
12
webclient/package-lock.json
generated
12
webclient/package-lock.json
generated
|
@ -7828,9 +7828,9 @@
|
|||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
||||
},
|
||||
"node_modules/ejs": {
|
||||
"version": "3.1.10",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
|
||||
"integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
|
||||
"version": "3.1.8",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz",
|
||||
"integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==",
|
||||
"dependencies": {
|
||||
"jake": "^10.8.5"
|
||||
},
|
||||
|
@ -25550,9 +25550,9 @@
|
|||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
||||
},
|
||||
"ejs": {
|
||||
"version": "3.1.10",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
|
||||
"integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
|
||||
"version": "3.1.8",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz",
|
||||
"integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==",
|
||||
"requires": {
|
||||
"jake": "^10.8.5"
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -20,7 +20,7 @@ import './Account.css';
|
|||
|
||||
const Account = (props: AccountProps) => {
|
||||
const { buddyList, ignoreList, serverName, serverVersion, user } = props;
|
||||
const { country, realName, name, userLevel, accountageSecs, avatarBmp } = user || {};
|
||||
const { country, realName, name, userLevel, accountageSecs, avatarBmp } = user;
|
||||
let url = URL.createObjectURL(new Blob([avatarBmp], { 'type': 'image/png' }));
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
|
|
@ -35,14 +35,13 @@ const LoginForm = ({ onSubmit, disableSubmitButton, onResetPassword }: LoginForm
|
|||
return errors;
|
||||
}
|
||||
|
||||
const useStoredPassword = (remember, password) => remember && host?.hashedPassword && !password;
|
||||
const useStoredPassword = (remember, password) => remember && host.hashedPassword && !password;
|
||||
const togglePasswordLabel = (useStoredLabel) => {
|
||||
setUseStoredPasswordLabel(useStoredLabel);
|
||||
};
|
||||
|
||||
const handleOnSubmit = ({ userName, ...values }) => {
|
||||
userName = userName?.trim();
|
||||
console.log(userName, values);
|
||||
|
||||
onSubmit({ userName, ...values });
|
||||
}
|
||||
|
@ -85,7 +84,7 @@ const LoginForm = ({ onSubmit, disableSubmitButton, onResetPassword }: LoginForm
|
|||
}, [host]);
|
||||
|
||||
const onUserNameChange = (userName) => {
|
||||
const fieldChanged = host?.userName?.toLowerCase() !== values.userName?.toLowerCase();
|
||||
const fieldChanged = host.userName?.toLowerCase() !== values.userName?.toLowerCase();
|
||||
if (useStoredPassword(values.remember, values.password) && fieldChanged) {
|
||||
setHost(({ hashedPassword, ...s }) => ({ ...s, userName }));
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,4 @@
|
|||
import { StatusEnum, WebSocketConnectOptions } from 'types';
|
||||
import { ServerStatus, StatusEnum, WebSocketConnectOptions } from 'types';
|
||||
|
||||
import { ProtobufService } from './services/ProtobufService';
|
||||
import { WebSocketService } from './services/WebSocketService';
|
||||
|
@ -37,7 +37,6 @@ export class WebClient {
|
|||
};
|
||||
|
||||
public options: WebSocketConnectOptions;
|
||||
public status: StatusEnum;
|
||||
|
||||
public connectionAttemptMade = false;
|
||||
|
||||
|
@ -46,6 +45,10 @@ export class WebClient {
|
|||
this.protobuf.handleMessageEvent(message);
|
||||
});
|
||||
|
||||
this.socket.statusChange$.subscribe((status: ServerStatus) => {
|
||||
this.handleStatusChange(status);
|
||||
});
|
||||
|
||||
if (process.env.NODE_ENV !== 'test') {
|
||||
console.log(this);
|
||||
}
|
||||
|
@ -65,8 +68,12 @@ export class WebClient {
|
|||
this.socket.disconnect();
|
||||
}
|
||||
|
||||
public updateStatus(status: StatusEnum) {
|
||||
this.status = status;
|
||||
public updateStatus(status: StatusEnum, description: string) {
|
||||
this.socket.updateStatus(status, description);
|
||||
}
|
||||
|
||||
public handleStatusChange({ status, description }: ServerStatus) {
|
||||
SessionPersistence.updateStatus(status, description);
|
||||
|
||||
if (status === StatusEnum.DISCONNECTED) {
|
||||
this.protobuf.resetCommands();
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { RoomPersistence } from '../../persistence';
|
||||
import webClient from '../../WebClient';
|
||||
import { RoomCommands } from './RoomCommands';
|
||||
|
||||
import { leaveRoom, roomSay } from './';
|
||||
import { RoomPersistence } from '../persistence';
|
||||
import webClient from '../WebClient';
|
||||
|
||||
describe.skip('RoomCommands', () => {
|
||||
describe('RoomCommands', () => {
|
||||
const roomId = 1;
|
||||
let sendRoomCommandSpy;
|
||||
|
||||
|
@ -25,7 +25,7 @@ describe.skip('RoomCommands', () => {
|
|||
it('should call protobuf controller methods and sendCommand', () => {
|
||||
const message = ' message ';
|
||||
|
||||
roomSay(roomId, message);
|
||||
RoomCommands.roomSay(roomId, message);
|
||||
|
||||
expect(webClient.protobuf.sendRoomCommand).toHaveBeenCalled();
|
||||
expect(webClient.protobuf.sendRoomCommand).toHaveBeenCalledWith(roomId, {
|
||||
|
@ -36,7 +36,7 @@ describe.skip('RoomCommands', () => {
|
|||
it('should not call sendRoomCommand if trimmed message is empty', () => {
|
||||
const message = ' ';
|
||||
|
||||
roomSay(roomId, message);
|
||||
RoomCommands.roomSay(roomId, message);
|
||||
|
||||
expect(webClient.protobuf.sendRoomCommand).not.toHaveBeenCalled();
|
||||
});
|
||||
|
@ -48,7 +48,7 @@ describe.skip('RoomCommands', () => {
|
|||
});
|
||||
|
||||
it('should call protobuf controller methods and sendCommand', () => {
|
||||
leaveRoom(roomId);
|
||||
RoomCommands.leaveRoom(roomId);
|
||||
|
||||
expect(webClient.protobuf.sendRoomCommand).toHaveBeenCalled();
|
||||
expect(webClient.protobuf.sendRoomCommand).toHaveBeenCalledWith(
|
||||
|
@ -67,7 +67,7 @@ describe.skip('RoomCommands', () => {
|
|||
|
||||
jest.spyOn(RoomPersistence, 'leaveRoom').mockImplementation(() => {});
|
||||
|
||||
leaveRoom(roomId);
|
||||
RoomCommands.leaveRoom(roomId);
|
||||
|
||||
expect(RoomPersistence.leaveRoom).toHaveBeenCalledWith(roomId);
|
||||
});
|
42
webclient/src/websocket/commands/RoomCommands.ts
Normal file
42
webclient/src/websocket/commands/RoomCommands.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
import { RoomPersistence } from '../persistence';
|
||||
import webClient from '../WebClient';
|
||||
|
||||
export class RoomCommands {
|
||||
static roomSay(roomId: number, message: string): void {
|
||||
const trimmed = message.trim();
|
||||
|
||||
if (!trimmed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const CmdRoomSay = webClient.protobuf.controller.Command_RoomSay.create({
|
||||
'message': trimmed
|
||||
});
|
||||
|
||||
const rc = webClient.protobuf.controller.RoomCommand.create({
|
||||
'.Command_RoomSay.ext': CmdRoomSay
|
||||
});
|
||||
|
||||
webClient.protobuf.sendRoomCommand(roomId, rc);
|
||||
}
|
||||
|
||||
static leaveRoom(roomId: number): void {
|
||||
const CmdLeaveRoom = webClient.protobuf.controller.Command_LeaveRoom.create();
|
||||
|
||||
const rc = webClient.protobuf.controller.RoomCommand.create({
|
||||
'.Command_LeaveRoom.ext': CmdLeaveRoom
|
||||
});
|
||||
|
||||
webClient.protobuf.sendRoomCommand(roomId, rc, (raw) => {
|
||||
const { responseCode } = raw;
|
||||
|
||||
switch (responseCode) {
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespOk:
|
||||
RoomPersistence.leaveRoom(roomId);
|
||||
break;
|
||||
default:
|
||||
console.log(`Failed to leave Room ${roomId} [${responseCode}] : `, raw);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
import { AccountActivationParams, ServerRegisterParams } from 'store';
|
||||
import { StatusEnum, WebSocketConnectOptions, WebSocketConnectReason } from 'types';
|
||||
|
||||
import webClient from '../../WebClient';
|
||||
import { RoomPersistence, SessionPersistence } from '../../persistence';
|
||||
import { SessionCommands } from './SessionCommands';
|
||||
|
||||
import * as SessionCommands from './';
|
||||
import { RoomPersistence, SessionPersistence } from '../persistence';
|
||||
import webClient from '../WebClient';
|
||||
import { AccountActivationParams, ServerRegisterParams } from '../../store';
|
||||
|
||||
describe.skip('SessionCommands', () => {
|
||||
describe('SessionCommands', () => {
|
||||
const roomId = 1;
|
||||
let sendModeratorCommandSpy;
|
||||
let sendSessionCommandSpy;
|
530
webclient/src/websocket/commands/SessionCommands.ts
Normal file
530
webclient/src/websocket/commands/SessionCommands.ts
Normal file
|
@ -0,0 +1,530 @@
|
|||
import { HostDTO } from 'services';
|
||||
import { StatusEnum, WebSocketConnectReason, WebSocketConnectOptions } from 'types';
|
||||
|
||||
import { RoomPersistence, SessionPersistence } from '../persistence';
|
||||
import webClient from '../WebClient';
|
||||
import { guid, hashPassword } from '../utils';
|
||||
import {
|
||||
AccountActivationParams,
|
||||
ForgotPasswordChallengeParams,
|
||||
ForgotPasswordParams,
|
||||
ForgotPasswordResetParams,
|
||||
RequestPasswordSaltParams,
|
||||
ServerRegisterParams
|
||||
} from '../../store';
|
||||
import NormalizeService from '../utils/NormalizeService';
|
||||
|
||||
export class SessionCommands {
|
||||
static connect(options: WebSocketConnectOptions, reason: WebSocketConnectReason): void {
|
||||
switch (reason) {
|
||||
case WebSocketConnectReason.LOGIN:
|
||||
case WebSocketConnectReason.REGISTER:
|
||||
case WebSocketConnectReason.ACTIVATE_ACCOUNT:
|
||||
case WebSocketConnectReason.PASSWORD_RESET_REQUEST:
|
||||
case WebSocketConnectReason.PASSWORD_RESET_CHALLENGE:
|
||||
case WebSocketConnectReason.PASSWORD_RESET:
|
||||
SessionCommands.updateStatus(StatusEnum.CONNECTING, 'Connecting...');
|
||||
break;
|
||||
case WebSocketConnectReason.TEST_CONNECTION:
|
||||
webClient.testConnect({ ...options });
|
||||
return;
|
||||
default:
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, 'Unknown Connection Attempt: ' + reason);
|
||||
return;
|
||||
}
|
||||
|
||||
webClient.connect({ ...options, reason });
|
||||
}
|
||||
|
||||
static disconnect(): void {
|
||||
webClient.disconnect();
|
||||
}
|
||||
|
||||
static login(options: WebSocketConnectOptions, passwordSalt?: string): void {
|
||||
const { userName, password, hashedPassword } = options;
|
||||
|
||||
const loginConfig: any = {
|
||||
...webClient.clientConfig,
|
||||
clientid: 'webatrice',
|
||||
userName,
|
||||
};
|
||||
|
||||
if (passwordSalt) {
|
||||
loginConfig.hashedPassword = hashedPassword || hashPassword(passwordSalt, password);
|
||||
} else {
|
||||
loginConfig.password = password;
|
||||
}
|
||||
|
||||
const CmdLogin = webClient.protobuf.controller.Command_Login.create(loginConfig);
|
||||
|
||||
const command = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_Login.ext': CmdLogin
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(command, raw => {
|
||||
const resp = raw['.Response_Login.ext'];
|
||||
|
||||
if (raw.responseCode === webClient.protobuf.controller.Response.ResponseCode.RespOk) {
|
||||
const { buddyList, ignoreList, userInfo } = resp;
|
||||
|
||||
SessionPersistence.updateBuddyList(buddyList);
|
||||
SessionPersistence.updateIgnoreList(ignoreList);
|
||||
SessionPersistence.updateUser(userInfo);
|
||||
SessionPersistence.loginSuccessful(loginConfig);
|
||||
|
||||
SessionCommands.listUsers();
|
||||
SessionCommands.listRooms();
|
||||
|
||||
SessionCommands.updateStatus(StatusEnum.LOGGED_IN, 'Logged in.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
switch (raw.responseCode) {
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespClientUpdateRequired:
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, 'Login failed: missing features');
|
||||
break;
|
||||
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespWrongPassword:
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespUsernameInvalid:
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, 'Login failed: incorrect username or password');
|
||||
break;
|
||||
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespWouldOverwriteOldSession:
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, 'Login failed: duplicated user session');
|
||||
break;
|
||||
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespUserIsBanned:
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, 'Login failed: banned user');
|
||||
break;
|
||||
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespRegistrationRequired:
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, 'Login failed: registration required');
|
||||
break;
|
||||
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespClientIdRequired:
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, 'Login failed: missing client ID');
|
||||
break;
|
||||
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespContextError:
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, 'Login failed: server error');
|
||||
break;
|
||||
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespAccountNotActivated:
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, 'Login failed: account not activated');
|
||||
SessionPersistence.accountAwaitingActivation(options);
|
||||
break;
|
||||
|
||||
default:
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, `Login failed: unknown error: ${raw.responseCode}`);
|
||||
}
|
||||
|
||||
SessionPersistence.loginFailed();
|
||||
SessionCommands.disconnect();
|
||||
});
|
||||
}
|
||||
|
||||
static requestPasswordSalt(options: WebSocketConnectOptions): void {
|
||||
const { userName } = options as RequestPasswordSaltParams;
|
||||
|
||||
const registerConfig = {
|
||||
...webClient.clientConfig,
|
||||
userName,
|
||||
};
|
||||
|
||||
const CmdRequestPasswordSalt = webClient.protobuf.controller.Command_RequestPasswordSalt.create(registerConfig);
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_RequestPasswordSalt.ext': CmdRequestPasswordSalt
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, raw => {
|
||||
switch (raw.responseCode) {
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespOk: {
|
||||
const passwordSalt = raw['.Response_PasswordSalt.ext']?.passwordSalt;
|
||||
|
||||
switch (options.reason) {
|
||||
case WebSocketConnectReason.ACTIVATE_ACCOUNT: {
|
||||
SessionCommands.activateAccount(options, passwordSalt);
|
||||
break;
|
||||
}
|
||||
|
||||
case WebSocketConnectReason.PASSWORD_RESET: {
|
||||
SessionCommands.resetPassword(options, passwordSalt);
|
||||
break;
|
||||
}
|
||||
|
||||
case WebSocketConnectReason.LOGIN:
|
||||
default: {
|
||||
SessionCommands.login(options, passwordSalt);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespRegistrationRequired: {
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, 'Login failed: registration required');
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, 'Login failed: Unknown Reason');
|
||||
}
|
||||
}
|
||||
|
||||
switch (options.reason) {
|
||||
case WebSocketConnectReason.ACTIVATE_ACCOUNT: {
|
||||
SessionPersistence.accountActivationFailed();
|
||||
break;
|
||||
}
|
||||
|
||||
case WebSocketConnectReason.PASSWORD_RESET: {
|
||||
SessionPersistence.resetPasswordFailed();
|
||||
break;
|
||||
}
|
||||
|
||||
case WebSocketConnectReason.LOGIN:
|
||||
default: {
|
||||
SessionPersistence.loginFailed();
|
||||
}
|
||||
}
|
||||
|
||||
SessionCommands.disconnect();
|
||||
});
|
||||
}
|
||||
|
||||
static register(options: WebSocketConnectOptions, passwordSalt?: string): void {
|
||||
const { userName, password, email, country, realName } = options as ServerRegisterParams;
|
||||
|
||||
const registerConfig: any = {
|
||||
...webClient.clientConfig,
|
||||
userName,
|
||||
email,
|
||||
country,
|
||||
realName,
|
||||
};
|
||||
|
||||
if (passwordSalt) {
|
||||
registerConfig.hashedPassword = hashPassword(passwordSalt, password);
|
||||
} else {
|
||||
registerConfig.password = password;
|
||||
}
|
||||
|
||||
const CmdRegister = webClient.protobuf.controller.Command_Register.create(registerConfig);
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_Register.ext': CmdRegister
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, raw => {
|
||||
if (raw.responseCode === webClient.protobuf.controller.Response.ResponseCode.RespRegistrationAccepted) {
|
||||
SessionCommands.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:
|
||||
console.error('ResponseCode.RespUsernameInvalid', raw.reasonStr);
|
||||
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(NormalizeService.normalizeBannedUserError(raw.reasonStr, raw.endTime));
|
||||
break;
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespRegistrationFailed:
|
||||
default:
|
||||
SessionPersistence.registrationFailed('Registration failed due to a server issue');
|
||||
break;
|
||||
}
|
||||
|
||||
SessionCommands.disconnect();
|
||||
});
|
||||
};
|
||||
|
||||
static activateAccount(options: WebSocketConnectOptions, passwordSalt?: string): void {
|
||||
const { userName, token } = options as unknown as AccountActivationParams;
|
||||
|
||||
const accountActivationConfig = {
|
||||
...webClient.clientConfig,
|
||||
userName,
|
||||
token,
|
||||
};
|
||||
|
||||
const CmdActivate = webClient.protobuf.controller.Command_Activate.create(accountActivationConfig);
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_Activate.ext': CmdActivate
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, raw => {
|
||||
if (raw.responseCode === webClient.protobuf.controller.Response.ResponseCode.RespActivationAccepted) {
|
||||
SessionPersistence.accountActivationSuccess();
|
||||
SessionCommands.login(options, passwordSalt);
|
||||
} else {
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, 'Account Activation Failed');
|
||||
SessionCommands.disconnect();
|
||||
SessionPersistence.accountActivationFailed();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static resetPasswordRequest(options: WebSocketConnectOptions): void {
|
||||
const { userName } = options as unknown as ForgotPasswordParams;
|
||||
|
||||
const forgotPasswordConfig = {
|
||||
...webClient.clientConfig,
|
||||
userName,
|
||||
};
|
||||
|
||||
const CmdForgotPasswordRequest = webClient.protobuf.controller.Command_ForgotPasswordRequest.create(forgotPasswordConfig);
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_ForgotPasswordRequest.ext': CmdForgotPasswordRequest
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, raw => {
|
||||
if (raw.responseCode === webClient.protobuf.controller.Response.ResponseCode.RespOk) {
|
||||
const resp = raw['.Response_ForgotPasswordRequest.ext'];
|
||||
|
||||
if (resp.challengeEmail) {
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPasswordChallenge();
|
||||
} else {
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPassword();
|
||||
}
|
||||
} else {
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPasswordFailed();
|
||||
}
|
||||
|
||||
SessionCommands.disconnect();
|
||||
});
|
||||
}
|
||||
|
||||
static resetPasswordChallenge(options: WebSocketConnectOptions): void {
|
||||
const { userName, email } = options as unknown as ForgotPasswordChallengeParams;
|
||||
|
||||
const forgotPasswordChallengeConfig = {
|
||||
...webClient.clientConfig,
|
||||
userName,
|
||||
email,
|
||||
};
|
||||
|
||||
const CmdForgotPasswordChallenge = webClient.protobuf.controller.Command_ForgotPasswordChallenge.create(forgotPasswordChallengeConfig);
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_ForgotPasswordChallenge.ext': CmdForgotPasswordChallenge
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, raw => {
|
||||
if (raw.responseCode === webClient.protobuf.controller.Response.ResponseCode.RespOk) {
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPassword();
|
||||
} else {
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPasswordFailed();
|
||||
}
|
||||
|
||||
SessionCommands.disconnect();
|
||||
});
|
||||
}
|
||||
|
||||
static resetPassword(options: WebSocketConnectOptions, passwordSalt?: string): void {
|
||||
const { userName, token, newPassword } = options as unknown as ForgotPasswordResetParams;
|
||||
|
||||
const forgotPasswordResetConfig: any = {
|
||||
...webClient.clientConfig,
|
||||
userName,
|
||||
token,
|
||||
};
|
||||
|
||||
if (passwordSalt) {
|
||||
forgotPasswordResetConfig.hashedNewPassword = hashPassword(passwordSalt, newPassword);
|
||||
} else {
|
||||
forgotPasswordResetConfig.newPassword = newPassword;
|
||||
}
|
||||
|
||||
const CmdForgotPasswordReset = webClient.protobuf.controller.Command_ForgotPasswordReset.create(forgotPasswordResetConfig);
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_ForgotPasswordReset.ext': CmdForgotPasswordReset
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, raw => {
|
||||
if (raw.responseCode === webClient.protobuf.controller.Response.ResponseCode.RespOk) {
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPasswordSuccess();
|
||||
} else {
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPasswordFailed();
|
||||
}
|
||||
|
||||
SessionCommands.disconnect();
|
||||
});
|
||||
}
|
||||
|
||||
static listUsers(): void {
|
||||
const CmdListUsers = webClient.protobuf.controller.Command_ListUsers.create();
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_ListUsers.ext': CmdListUsers
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, raw => {
|
||||
const { responseCode } = raw;
|
||||
const response = raw['.Response_ListUsers.ext'];
|
||||
|
||||
if (response) {
|
||||
switch (responseCode) {
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespOk:
|
||||
SessionPersistence.updateUsers(response.userList);
|
||||
break;
|
||||
default:
|
||||
console.log(`Failed to fetch Server Rooms [${responseCode}] : `, raw);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
static listRooms(): void {
|
||||
const CmdListRooms = webClient.protobuf.controller.Command_ListRooms.create();
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_ListRooms.ext': CmdListRooms
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc);
|
||||
}
|
||||
|
||||
static joinRoom(roomId: number): void {
|
||||
const CmdJoinRoom = webClient.protobuf.controller.Command_JoinRoom.create({ roomId });
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_JoinRoom.ext': CmdJoinRoom
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, (raw) => {
|
||||
const { responseCode } = raw;
|
||||
|
||||
let error;
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static addToBuddyList(userName: string): void {
|
||||
this.addToList('buddy', userName);
|
||||
}
|
||||
|
||||
static removeFromBuddyList(userName: string): void {
|
||||
this.removeFromList('buddy', userName);
|
||||
}
|
||||
|
||||
static addToIgnoreList(userName: string): void {
|
||||
this.addToList('ignore', userName);
|
||||
}
|
||||
|
||||
static removeFromIgnoreList(userName: string): void {
|
||||
this.removeFromList('ignore', userName);
|
||||
}
|
||||
|
||||
static addToList(list: string, userName: string): void {
|
||||
const CmdAddToList = webClient.protobuf.controller.Command_AddToList.create({ list, userName });
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_AddToList.ext': CmdAddToList
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, ({ responseCode }) => {
|
||||
// @TODO: filter responseCode, pop snackbar for error
|
||||
});
|
||||
}
|
||||
|
||||
static removeFromList(list: string, userName: string): void {
|
||||
const CmdRemoveFromList = webClient.protobuf.controller.Command_RemoveFromList.create({ list, userName });
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_RemoveFromList.ext': CmdRemoveFromList
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, ({ responseCode }) => {
|
||||
// @TODO: filter responseCode, pop snackbar for error
|
||||
});
|
||||
}
|
||||
|
||||
static viewLogHistory(filters): void {
|
||||
const CmdViewLogHistory = webClient.protobuf.controller.Command_ViewLogHistory.create(filters);
|
||||
|
||||
const sc = webClient.protobuf.controller.ModeratorCommand.create({
|
||||
'.Command_ViewLogHistory.ext': CmdViewLogHistory
|
||||
});
|
||||
|
||||
webClient.protobuf.sendModeratorCommand(sc, (raw) => {
|
||||
const { responseCode } = raw;
|
||||
|
||||
let error;
|
||||
|
||||
switch (responseCode) {
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespOk:
|
||||
const { logMessage } = raw['.Response_ViewLogHistory.ext'];
|
||||
SessionPersistence.viewLogs(logMessage)
|
||||
return;
|
||||
default:
|
||||
error = 'Failed to retrieve log history.';
|
||||
break;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
console.error(responseCode, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static updateStatus(status: StatusEnum, description: string): void {
|
||||
webClient.updateStatus(status, description);
|
||||
}
|
||||
}
|
|
@ -1,2 +1,2 @@
|
|||
export * as RoomCommands from './room';
|
||||
export * as SessionCommands from './session';
|
||||
export { RoomCommands } from './RoomCommands';
|
||||
export { SessionCommands } from './SessionCommands';
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
export * from './leaveRoom';
|
||||
export * from './roomSay';
|
|
@ -1,22 +0,0 @@
|
|||
import { RoomPersistence } from '../../persistence';
|
||||
import webClient from '../../WebClient';
|
||||
|
||||
export function leaveRoom(roomId: number): void {
|
||||
const CmdLeaveRoom = webClient.protobuf.controller.Command_LeaveRoom.create();
|
||||
|
||||
const rc = webClient.protobuf.controller.RoomCommand.create({
|
||||
'.Command_LeaveRoom.ext': CmdLeaveRoom
|
||||
});
|
||||
|
||||
webClient.protobuf.sendRoomCommand(roomId, rc, (raw) => {
|
||||
const { responseCode } = raw;
|
||||
|
||||
switch (responseCode) {
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespOk:
|
||||
RoomPersistence.leaveRoom(roomId);
|
||||
break;
|
||||
default:
|
||||
console.log(`Failed to leave Room ${roomId} [${responseCode}] : `, raw);
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
import webClient from '../../WebClient';
|
||||
|
||||
export function roomSay(roomId: number, message: string): void {
|
||||
const trimmed = message.trim();
|
||||
|
||||
if (!trimmed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const CmdRoomSay = webClient.protobuf.controller.Command_RoomSay.create({
|
||||
'message': trimmed
|
||||
});
|
||||
|
||||
const rc = webClient.protobuf.controller.RoomCommand.create({
|
||||
'.Command_RoomSay.ext': CmdRoomSay
|
||||
});
|
||||
|
||||
webClient.protobuf.sendRoomCommand(roomId, rc);
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
import { AccountActivationParams } from 'store';
|
||||
import { StatusEnum, WebSocketConnectOptions } from 'types';
|
||||
|
||||
import webClient from '../../WebClient';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
import { disconnect, login, updateStatus } from './';
|
||||
|
||||
export function activateAccount(options: WebSocketConnectOptions, passwordSalt?: string): void {
|
||||
const { userName, token } = options as unknown as AccountActivationParams;
|
||||
|
||||
const accountActivationConfig = {
|
||||
...webClient.clientConfig,
|
||||
userName,
|
||||
token,
|
||||
};
|
||||
|
||||
const CmdActivate = webClient.protobuf.controller.Command_Activate.create(accountActivationConfig);
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_Activate.ext': CmdActivate
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, raw => {
|
||||
if (raw.responseCode === webClient.protobuf.controller.Response.ResponseCode.RespActivationAccepted) {
|
||||
SessionPersistence.accountActivationSuccess();
|
||||
login(options, passwordSalt);
|
||||
} else {
|
||||
updateStatus(StatusEnum.DISCONNECTED, 'Account Activation Failed');
|
||||
disconnect();
|
||||
SessionPersistence.accountActivationFailed();
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
import webClient from '../../WebClient';
|
||||
|
||||
export function addToBuddyList(userName: string): void {
|
||||
addToList('buddy', userName);
|
||||
}
|
||||
|
||||
export function addToIgnoreList(userName: string): void {
|
||||
addToList('ignore', userName);
|
||||
}
|
||||
|
||||
export function addToList(list: string, userName: string): void {
|
||||
const CmdAddToList = webClient.protobuf.controller.Command_AddToList.create({ list, userName });
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_AddToList.ext': CmdAddToList
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, ({ responseCode }) => {
|
||||
// @TODO: filter responseCode, pop snackbar for error
|
||||
});
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
import { StatusEnum, WebSocketConnectOptions, WebSocketConnectReason } from 'types';
|
||||
import webClient from '../../WebClient';
|
||||
import { updateStatus } from './';
|
||||
|
||||
export function connect(options: WebSocketConnectOptions, reason: WebSocketConnectReason): void {
|
||||
switch (reason) {
|
||||
case WebSocketConnectReason.LOGIN:
|
||||
case WebSocketConnectReason.REGISTER:
|
||||
case WebSocketConnectReason.ACTIVATE_ACCOUNT:
|
||||
case WebSocketConnectReason.PASSWORD_RESET_REQUEST:
|
||||
case WebSocketConnectReason.PASSWORD_RESET_CHALLENGE:
|
||||
case WebSocketConnectReason.PASSWORD_RESET:
|
||||
updateStatus(StatusEnum.CONNECTING, 'Connecting...');
|
||||
break;
|
||||
case WebSocketConnectReason.TEST_CONNECTION:
|
||||
webClient.testConnect({ ...options });
|
||||
return;
|
||||
default:
|
||||
updateStatus(StatusEnum.DISCONNECTED, 'Unknown Connection Attempt: ' + reason);
|
||||
return;
|
||||
}
|
||||
|
||||
webClient.connect({ ...options, reason });
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
import webClient from '../../WebClient';
|
||||
|
||||
export function disconnect(): void {
|
||||
webClient.disconnect();
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
export * from './activateAccount';
|
||||
export * from './addToList';
|
||||
export * from './connect';
|
||||
export * from './disconnect';
|
||||
export * from './joinRoom';
|
||||
export * from './listRooms';
|
||||
export * from './listUsers';
|
||||
export * from './login';
|
||||
export * from './register';
|
||||
export * from './removeFromList';
|
||||
export * from './requestPasswordSalt';
|
||||
export * from './resetPassword';
|
||||
export * from './resetPasswordChallenge'
|
||||
export * from './resetPasswordRequest';
|
||||
export * from './updateStatus';
|
||||
export * from './viewLogHistory';
|
|
@ -1,40 +0,0 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { RoomPersistence } from '../../persistence';
|
||||
|
||||
export function joinRoom(roomId: number): void {
|
||||
const CmdJoinRoom = webClient.protobuf.controller.Command_JoinRoom.create({ roomId });
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_JoinRoom.ext': CmdJoinRoom
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, (raw) => {
|
||||
const { responseCode } = raw;
|
||||
|
||||
let error;
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
import webClient from '../../WebClient';
|
||||
|
||||
export function listRooms(): void {
|
||||
const CmdListRooms = webClient.protobuf.controller.Command_ListRooms.create();
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_ListRooms.ext': CmdListRooms
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc);
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
export function listUsers(): void {
|
||||
const CmdListUsers = webClient.protobuf.controller.Command_ListUsers.create();
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_ListUsers.ext': CmdListUsers
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, raw => {
|
||||
const { responseCode } = raw;
|
||||
const response = raw['.Response_ListUsers.ext'];
|
||||
|
||||
if (response) {
|
||||
switch (responseCode) {
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespOk:
|
||||
SessionPersistence.updateUsers(response.userList);
|
||||
break;
|
||||
default:
|
||||
console.log(`Failed to fetch Server Rooms [${responseCode}] : `, raw);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
import { StatusEnum, WebSocketConnectOptions } from 'types';
|
||||
import webClient from '../../WebClient';
|
||||
import { hashPassword } from '../../utils';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
import {
|
||||
disconnect,
|
||||
listUsers,
|
||||
listRooms,
|
||||
updateStatus,
|
||||
} from './';
|
||||
|
||||
export function login(options: WebSocketConnectOptions, passwordSalt?: string): void {
|
||||
const { userName, password, hashedPassword } = options;
|
||||
|
||||
const loginConfig: any = {
|
||||
...webClient.clientConfig,
|
||||
clientid: 'webatrice',
|
||||
userName,
|
||||
};
|
||||
|
||||
if (passwordSalt) {
|
||||
loginConfig.hashedPassword = hashedPassword || hashPassword(passwordSalt, password);
|
||||
} else {
|
||||
loginConfig.password = password;
|
||||
}
|
||||
|
||||
const CmdLogin = webClient.protobuf.controller.Command_Login.create(loginConfig);
|
||||
|
||||
const command = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_Login.ext': CmdLogin
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(command, raw => {
|
||||
const resp = raw['.Response_Login.ext'];
|
||||
|
||||
if (raw.responseCode === webClient.protobuf.controller.Response.ResponseCode.RespOk) {
|
||||
const { buddyList, ignoreList, userInfo } = resp;
|
||||
|
||||
SessionPersistence.updateBuddyList(buddyList);
|
||||
SessionPersistence.updateIgnoreList(ignoreList);
|
||||
SessionPersistence.updateUser(userInfo);
|
||||
SessionPersistence.loginSuccessful(loginConfig);
|
||||
|
||||
listUsers();
|
||||
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();
|
||||
});
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
import { ServerRegisterParams } from 'store';
|
||||
import { WebSocketConnectOptions } from 'types';
|
||||
|
||||
import webClient from '../../WebClient';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
import { hashPassword } from '../../utils';
|
||||
import NormalizeService from '../../utils/NormalizeService';
|
||||
|
||||
import { login, disconnect } from './';
|
||||
|
||||
export function register(options: WebSocketConnectOptions, passwordSalt?: string): void {
|
||||
const { userName, password, email, country, realName } = options as ServerRegisterParams;
|
||||
|
||||
const registerConfig: any = {
|
||||
...webClient.clientConfig,
|
||||
userName,
|
||||
email,
|
||||
country,
|
||||
realName,
|
||||
};
|
||||
|
||||
if (passwordSalt) {
|
||||
registerConfig.hashedPassword = hashPassword(passwordSalt, password);
|
||||
} else {
|
||||
registerConfig.password = password;
|
||||
}
|
||||
|
||||
const CmdRegister = webClient.protobuf.controller.Command_Register.create(registerConfig);
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_Register.ext': CmdRegister
|
||||
});
|
||||
|
||||
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:
|
||||
console.error('ResponseCode.RespUsernameInvalid', raw.reasonStr);
|
||||
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(NormalizeService.normalizeBannedUserError(raw.reasonStr, raw.endTime));
|
||||
break;
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespRegistrationFailed:
|
||||
default:
|
||||
SessionPersistence.registrationFailed('Registration failed due to a server issue');
|
||||
break;
|
||||
}
|
||||
|
||||
disconnect();
|
||||
});
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
import webClient from '../../WebClient';
|
||||
|
||||
export function removeFromBuddyList(userName: string): void {
|
||||
removeFromList('buddy', userName);
|
||||
}
|
||||
|
||||
export function removeFromIgnoreList(userName: string): void {
|
||||
removeFromList('ignore', userName);
|
||||
}
|
||||
|
||||
export function removeFromList(list: string, userName: string): void {
|
||||
const CmdRemoveFromList = webClient.protobuf.controller.Command_RemoveFromList.create({ list, userName });
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_RemoveFromList.ext': CmdRemoveFromList
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, ({ responseCode }) => {
|
||||
// @TODO: filter responseCode, pop snackbar for error
|
||||
});
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
import { RequestPasswordSaltParams } from 'store';
|
||||
import { StatusEnum, WebSocketConnectOptions, WebSocketConnectReason } from 'types';
|
||||
|
||||
import webClient from '../../WebClient';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
import {
|
||||
activateAccount,
|
||||
disconnect,
|
||||
login,
|
||||
resetPassword,
|
||||
updateStatus
|
||||
} from './';
|
||||
|
||||
export function requestPasswordSalt(options: WebSocketConnectOptions): void {
|
||||
const { userName } = options as RequestPasswordSaltParams;
|
||||
|
||||
const registerConfig = {
|
||||
...webClient.clientConfig,
|
||||
userName,
|
||||
};
|
||||
|
||||
const CmdRequestPasswordSalt = webClient.protobuf.controller.Command_RequestPasswordSalt.create(registerConfig);
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_RequestPasswordSalt.ext': CmdRequestPasswordSalt
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, raw => {
|
||||
switch (raw.responseCode) {
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespOk: {
|
||||
const passwordSalt = raw['.Response_PasswordSalt.ext']?.passwordSalt;
|
||||
|
||||
switch (options.reason) {
|
||||
case WebSocketConnectReason.ACTIVATE_ACCOUNT: {
|
||||
activateAccount(options, passwordSalt);
|
||||
break;
|
||||
}
|
||||
|
||||
case WebSocketConnectReason.PASSWORD_RESET: {
|
||||
resetPassword(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: {
|
||||
SessionPersistence.accountActivationFailed();
|
||||
break;
|
||||
}
|
||||
|
||||
case WebSocketConnectReason.PASSWORD_RESET: {
|
||||
SessionPersistence.resetPasswordFailed();
|
||||
break;
|
||||
}
|
||||
|
||||
case WebSocketConnectReason.LOGIN:
|
||||
default: {
|
||||
SessionPersistence.loginFailed();
|
||||
}
|
||||
}
|
||||
|
||||
disconnect();
|
||||
});
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
import { ForgotPasswordResetParams } from 'store';
|
||||
import { StatusEnum, WebSocketConnectOptions } from 'types';
|
||||
|
||||
import webClient from '../../WebClient';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
import { hashPassword } from '../../utils';
|
||||
|
||||
import { disconnect, updateStatus } from '.';
|
||||
|
||||
export function resetPassword(options: WebSocketConnectOptions, passwordSalt?: string): void {
|
||||
const { userName, token, newPassword } = options as unknown as ForgotPasswordResetParams;
|
||||
|
||||
const forgotPasswordResetConfig: any = {
|
||||
...webClient.clientConfig,
|
||||
userName,
|
||||
token,
|
||||
};
|
||||
|
||||
if (passwordSalt) {
|
||||
forgotPasswordResetConfig.hashedNewPassword = hashPassword(passwordSalt, newPassword);
|
||||
} else {
|
||||
forgotPasswordResetConfig.newPassword = newPassword;
|
||||
}
|
||||
|
||||
const CmdForgotPasswordReset = webClient.protobuf.controller.Command_ForgotPasswordReset.create(forgotPasswordResetConfig);
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_ForgotPasswordReset.ext': CmdForgotPasswordReset
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, raw => {
|
||||
if (raw.responseCode === webClient.protobuf.controller.Response.ResponseCode.RespOk) {
|
||||
updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPasswordSuccess();
|
||||
} else {
|
||||
updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPasswordFailed();
|
||||
}
|
||||
|
||||
disconnect();
|
||||
});
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
import { ForgotPasswordChallengeParams } from 'store';
|
||||
import { StatusEnum, WebSocketConnectOptions } from 'types';
|
||||
|
||||
import webClient from '../../WebClient';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
import { disconnect, updateStatus } from './';
|
||||
|
||||
export function resetPasswordChallenge(options: WebSocketConnectOptions): void {
|
||||
const { userName, email } = options as unknown as ForgotPasswordChallengeParams;
|
||||
|
||||
const forgotPasswordChallengeConfig = {
|
||||
...webClient.clientConfig,
|
||||
userName,
|
||||
email,
|
||||
};
|
||||
|
||||
const CmdForgotPasswordChallenge = webClient.protobuf.controller.Command_ForgotPasswordChallenge.create(forgotPasswordChallengeConfig);
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_ForgotPasswordChallenge.ext': CmdForgotPasswordChallenge
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, raw => {
|
||||
if (raw.responseCode === webClient.protobuf.controller.Response.ResponseCode.RespOk) {
|
||||
updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPassword();
|
||||
} else {
|
||||
updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPasswordFailed();
|
||||
}
|
||||
|
||||
disconnect();
|
||||
});
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
import { ForgotPasswordParams } from 'store';
|
||||
import { StatusEnum, WebSocketConnectOptions } from 'types';
|
||||
|
||||
import webClient from '../../WebClient';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
import { disconnect, updateStatus } from './';
|
||||
|
||||
export function resetPasswordRequest(options: WebSocketConnectOptions): void {
|
||||
const { userName } = options as unknown as ForgotPasswordParams;
|
||||
|
||||
const forgotPasswordConfig = {
|
||||
...webClient.clientConfig,
|
||||
userName,
|
||||
};
|
||||
|
||||
const CmdForgotPasswordRequest = webClient.protobuf.controller.Command_ForgotPasswordRequest.create(forgotPasswordConfig);
|
||||
|
||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||
'.Command_ForgotPasswordRequest.ext': CmdForgotPasswordRequest
|
||||
});
|
||||
|
||||
webClient.protobuf.sendSessionCommand(sc, raw => {
|
||||
if (raw.responseCode === webClient.protobuf.controller.Response.ResponseCode.RespOk) {
|
||||
const resp = raw['.Response_ForgotPasswordRequest.ext'];
|
||||
|
||||
if (resp.challengeEmail) {
|
||||
updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPasswordChallenge();
|
||||
} else {
|
||||
updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPassword();
|
||||
}
|
||||
} else {
|
||||
updateStatus(StatusEnum.DISCONNECTED, null);
|
||||
SessionPersistence.resetPasswordFailed();
|
||||
}
|
||||
|
||||
disconnect();
|
||||
});
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
import { StatusEnum } from 'types';
|
||||
import webClient from '../../WebClient';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
export function updateStatus(status: StatusEnum, description: string): void {
|
||||
SessionPersistence.updateStatus(status, description);
|
||||
|
||||
webClient.updateStatus(status);
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
export function viewLogHistory(filters): void {
|
||||
const CmdViewLogHistory = webClient.protobuf.controller.Command_ViewLogHistory.create(filters);
|
||||
|
||||
const sc = webClient.protobuf.controller.ModeratorCommand.create({
|
||||
'.Command_ViewLogHistory.ext': CmdViewLogHistory
|
||||
});
|
||||
|
||||
webClient.protobuf.sendModeratorCommand(sc, (raw) => {
|
||||
const { responseCode } = raw;
|
||||
|
||||
let error;
|
||||
|
||||
switch (responseCode) {
|
||||
case webClient.protobuf.controller.Response.ResponseCode.RespOk:
|
||||
const { logMessage } = raw['.Response_ViewLogHistory.ext'];
|
||||
SessionPersistence.viewLogs(logMessage)
|
||||
return;
|
||||
default:
|
||||
error = 'Failed to retrieve log history.';
|
||||
break;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
console.error(responseCode, error);
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,17 +1,15 @@
|
|||
import { Message } from 'types';
|
||||
|
||||
import { RoomPersistence } from '../../persistence';
|
||||
|
||||
import {
|
||||
RoomEvents,
|
||||
RoomEvent,
|
||||
JoinRoomData,
|
||||
LeaveRoomData,
|
||||
ListGamesData,
|
||||
} from './interfaces';
|
||||
} from './RoomEvents';
|
||||
import { RoomPersistence } from '../persistence/RoomPersistence';
|
||||
|
||||
import { RoomEvents } from '.';
|
||||
|
||||
describe.skip('RoomEvents', () => {
|
||||
describe('RoomEvents', () => {
|
||||
it('.Event_JoinRoom.ext should call RoomPersistence.userJoined', () => {
|
||||
jest.spyOn(RoomPersistence, 'userJoined').mockImplementation(() => {});
|
||||
const data: JoinRoomData = { userInfo: {} as any };
|
49
webclient/src/websocket/events/RoomEvents.ts
Normal file
49
webclient/src/websocket/events/RoomEvents.ts
Normal file
|
@ -0,0 +1,49 @@
|
|||
import { Game, Message, User } from 'types';
|
||||
import { RoomPersistence } from '../persistence/RoomPersistence';
|
||||
import { ProtobufEvents } from '../services/ProtobufService';
|
||||
|
||||
export const RoomEvents: ProtobufEvents = {
|
||||
'.Event_JoinRoom.ext': joinRoom,
|
||||
'.Event_LeaveRoom.ext': leaveRoom,
|
||||
'.Event_ListGames.ext': listGames,
|
||||
'.Event_RoomSay.ext': roomSay,
|
||||
};
|
||||
|
||||
function joinRoom({ userInfo }: JoinRoomData, { roomEvent }: RoomEvent) {
|
||||
const { roomId } = roomEvent;
|
||||
|
||||
RoomPersistence.userJoined(roomId, userInfo);
|
||||
}
|
||||
|
||||
function leaveRoom({ name }: LeaveRoomData, { roomEvent }: RoomEvent) {
|
||||
const { roomId } = roomEvent;
|
||||
RoomPersistence.userLeft(roomId, name);
|
||||
}
|
||||
|
||||
function listGames({ gameList }: ListGamesData, { roomEvent }: RoomEvent) {
|
||||
const { roomId } = roomEvent;
|
||||
RoomPersistence.updateGames(roomId, gameList);
|
||||
}
|
||||
|
||||
function roomSay(message: Message, { roomEvent }: RoomEvent) {
|
||||
const { roomId } = roomEvent;
|
||||
RoomPersistence.addMessage(roomId, message);
|
||||
}
|
||||
|
||||
export interface RoomEvent {
|
||||
roomEvent: {
|
||||
roomId: number;
|
||||
}
|
||||
}
|
||||
|
||||
export interface JoinRoomData {
|
||||
userInfo: User;
|
||||
}
|
||||
|
||||
export interface LeaveRoomData {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface ListGamesData {
|
||||
gameList: Game[];
|
||||
}
|
|
@ -1,9 +1,5 @@
|
|||
import { StatusEnum, WebSocketConnectReason } from 'types';
|
||||
|
||||
import { SessionCommands } from '../../commands';
|
||||
import { RoomPersistence, SessionPersistence } from '../../persistence';
|
||||
import webClient from '../../WebClient';
|
||||
|
||||
import {
|
||||
AddToListData,
|
||||
ConnectionClosedData,
|
||||
|
@ -11,13 +7,16 @@ import {
|
|||
RemoveFromListData,
|
||||
ServerIdentificationData,
|
||||
ServerMessageData,
|
||||
SessionEvents,
|
||||
UserJoinedData,
|
||||
UserLeftData,
|
||||
} from './interfaces';
|
||||
} from './SessionEvents';
|
||||
|
||||
import { SessionEvents } from '.';
|
||||
import { SessionCommands } from '../commands';
|
||||
import { RoomPersistence, SessionPersistence } from '../persistence';
|
||||
import webClient from '../WebClient';
|
||||
|
||||
describe.skip('SessionEvents', () => {
|
||||
describe('SessionEvents', () => {
|
||||
const roomId = 1;
|
||||
|
||||
beforeEach(() => {
|
230
webclient/src/websocket/events/SessionEvents.ts
Normal file
230
webclient/src/websocket/events/SessionEvents.ts
Normal file
|
@ -0,0 +1,230 @@
|
|||
import { Room, StatusEnum, User, WebSocketConnectReason } from 'types';
|
||||
|
||||
import { SessionCommands } from '../commands';
|
||||
import { RoomPersistence, SessionPersistence } from '../persistence';
|
||||
import { ProtobufEvents } from '../services/ProtobufService';
|
||||
import { generateSalt, passwordSaltSupported } from '../utils';
|
||||
import webClient from '../WebClient';
|
||||
|
||||
export const SessionEvents: ProtobufEvents = {
|
||||
'.Event_AddToList.ext': addToList,
|
||||
'.Event_ConnectionClosed.ext': connectionClosed,
|
||||
'.Event_ListRooms.ext': listRooms,
|
||||
'.Event_NotifyUser.ext': notifyUser,
|
||||
'.Event_PlayerPropertiesChanges.ext': playerPropertiesChanges,
|
||||
'.Event_RemoveFromList.ext': removeFromList,
|
||||
'.Event_ServerIdentification.ext': serverIdentification,
|
||||
'.Event_ServerMessage.ext': serverMessage,
|
||||
'.Event_ServerShutdown.ext': serverShutdown,
|
||||
'.Event_UserJoined.ext': userJoined,
|
||||
'.Event_UserLeft.ext': userLeft,
|
||||
'.Event_UserMessage.ext': userMessage,
|
||||
}
|
||||
|
||||
function addToList({ listName, userInfo }: AddToListData) {
|
||||
switch (listName) {
|
||||
case 'buddy': {
|
||||
SessionPersistence.addToBuddyList(userInfo);
|
||||
break;
|
||||
}
|
||||
case 'ignore': {
|
||||
SessionPersistence.addToIgnoreList(userInfo);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.log(`Attempted to add to unknown list: ${listName}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function connectionClosed({ reason, reasonStr }: ConnectionClosedData) {
|
||||
let message;
|
||||
|
||||
// @TODO (5)
|
||||
if (reasonStr) {
|
||||
message = reasonStr;
|
||||
} else {
|
||||
switch (reason) {
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.USER_LIMIT_REACHED:
|
||||
message = 'The server has reached its maximum user capacity';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.TOO_MANY_CONNECTIONS:
|
||||
message = 'There are too many concurrent connections from your address';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.BANNED:
|
||||
message = 'You are banned';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.DEMOTED:
|
||||
message = 'You were demoted';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.SERVER_SHUTDOWN:
|
||||
message = 'Scheduled server shutdown';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.USERNAMEINVALID:
|
||||
message = 'Invalid username';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.LOGGEDINELSEWERE:
|
||||
message = 'You have been logged out due to logging in at another location';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.OTHER:
|
||||
default:
|
||||
message = 'Unknown reason';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, message);
|
||||
}
|
||||
|
||||
function listRooms({ roomList }: ListRoomsData) {
|
||||
RoomPersistence.updateRooms(roomList);
|
||||
|
||||
if (webClient.clientOptions.autojoinrooms) {
|
||||
roomList.forEach(({ autoJoin, roomId }) => {
|
||||
if (autoJoin) {
|
||||
SessionCommands.joinRoom(roomId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function notifyUser(payload) {
|
||||
// console.info('Event_NotifyUser', payload);
|
||||
}
|
||||
|
||||
function playerPropertiesChanges(payload) {
|
||||
// console.info('Event_PlayerPropertiesChanges', payload);
|
||||
}
|
||||
|
||||
function removeFromList({ listName, userName }: RemoveFromListData) {
|
||||
switch (listName) {
|
||||
case 'buddy': {
|
||||
SessionPersistence.removeFromBuddyList(userName);
|
||||
break;
|
||||
}
|
||||
case 'ignore': {
|
||||
SessionPersistence.removeFromIgnoreList(userName);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.log(`Attempted to remove from unknown list: ${listName}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function serverIdentification(info: ServerIdentificationData) {
|
||||
const { serverName, serverVersion, protocolVersion, serverOptions } = info;
|
||||
if (protocolVersion !== webClient.protocolVersion) {
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, `Protocol version mismatch: ${protocolVersion}`);
|
||||
SessionCommands.disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
const getPasswordSalt = passwordSaltSupported(serverOptions, webClient);
|
||||
const { options } = webClient;
|
||||
|
||||
switch (options.reason) {
|
||||
case WebSocketConnectReason.LOGIN:
|
||||
SessionCommands.updateStatus(StatusEnum.LOGGING_IN, 'Logging In...');
|
||||
if (getPasswordSalt) {
|
||||
SessionCommands.requestPasswordSalt(options);
|
||||
} else {
|
||||
SessionCommands.login(options);
|
||||
}
|
||||
break;
|
||||
case WebSocketConnectReason.REGISTER:
|
||||
const passwordSalt = getPasswordSalt ? generateSalt() : null;
|
||||
SessionCommands.register(options, passwordSalt);
|
||||
break;
|
||||
case WebSocketConnectReason.ACTIVATE_ACCOUNT:
|
||||
if (getPasswordSalt) {
|
||||
SessionCommands.requestPasswordSalt(options);
|
||||
} else {
|
||||
SessionCommands.activateAccount(options);
|
||||
}
|
||||
break;
|
||||
case WebSocketConnectReason.PASSWORD_RESET_REQUEST:
|
||||
SessionCommands.resetPasswordRequest(options);
|
||||
break;
|
||||
case WebSocketConnectReason.PASSWORD_RESET_CHALLENGE:
|
||||
SessionCommands.resetPasswordChallenge(options);
|
||||
break;
|
||||
case WebSocketConnectReason.PASSWORD_RESET:
|
||||
if (getPasswordSalt) {
|
||||
SessionCommands.requestPasswordSalt(options);
|
||||
} else {
|
||||
SessionCommands.resetPassword(options);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, 'Unknown Connection Reason: ' + options.reason);
|
||||
SessionCommands.disconnect();
|
||||
break;
|
||||
}
|
||||
|
||||
webClient.options = {};
|
||||
SessionPersistence.updateInfo(serverName, serverVersion);
|
||||
}
|
||||
|
||||
function serverMessage({ message }: ServerMessageData) {
|
||||
SessionPersistence.serverMessage(message);
|
||||
}
|
||||
|
||||
function serverShutdown(payload) {
|
||||
// console.info('Event_ServerShutdown', payload);
|
||||
}
|
||||
|
||||
function userJoined({ userInfo }: UserJoinedData) {
|
||||
SessionPersistence.userJoined(userInfo);
|
||||
}
|
||||
|
||||
function userLeft({ name }: UserLeftData) {
|
||||
SessionPersistence.userLeft(name);
|
||||
}
|
||||
|
||||
function userMessage(payload) {
|
||||
// console.info('Event_UserMessage', payload);
|
||||
}
|
||||
|
||||
export interface SessionEvent {
|
||||
sessionEvent: {}
|
||||
}
|
||||
|
||||
export interface AddToListData {
|
||||
listName: string;
|
||||
userInfo: User;
|
||||
}
|
||||
|
||||
export interface ConnectionClosedData {
|
||||
endTime: number;
|
||||
reason: number;
|
||||
reasonStr: string;
|
||||
}
|
||||
|
||||
export interface ListRoomsData {
|
||||
roomList: Room[];
|
||||
}
|
||||
|
||||
export interface RemoveFromListData {
|
||||
listName: string;
|
||||
userName: string;
|
||||
}
|
||||
|
||||
export interface ServerIdentificationData {
|
||||
protocolVersion: number;
|
||||
serverName: string;
|
||||
serverVersion: string;
|
||||
serverOptions: number;
|
||||
}
|
||||
|
||||
export interface ServerMessageData {
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface UserJoinedData {
|
||||
userInfo: User;
|
||||
}
|
||||
|
||||
export interface UserLeftData {
|
||||
name: string;
|
||||
}
|
|
@ -1,2 +1,2 @@
|
|||
export * from './room';
|
||||
export * from './session';
|
||||
export * from './RoomEvents';
|
||||
export * from './SessionEvents';
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
import { ProtobufEvents } from '../../services/ProtobufService';
|
||||
|
||||
import { joinRoom } from './joinRoom';
|
||||
import { leaveRoom } from './leaveRoom';
|
||||
import { listGames } from './listGames';
|
||||
import { roomSay } from './roomSay';
|
||||
|
||||
export const RoomEvents: ProtobufEvents = {
|
||||
'.Event_JoinRoom.ext': joinRoom,
|
||||
'.Event_LeaveRoom.ext': leaveRoom,
|
||||
'.Event_ListGames.ext': listGames,
|
||||
'.Event_RoomSay.ext': roomSay,
|
||||
};
|
|
@ -1,19 +0,0 @@
|
|||
import { Game, User } from 'types';
|
||||
|
||||
export interface RoomEvent {
|
||||
roomEvent: {
|
||||
roomId: number;
|
||||
}
|
||||
}
|
||||
|
||||
export interface JoinRoomData {
|
||||
userInfo: User;
|
||||
}
|
||||
|
||||
export interface LeaveRoomData {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface ListGamesData {
|
||||
gameList: Game[];
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
import { RoomPersistence } from '../../persistence';
|
||||
import { JoinRoomData, RoomEvent } from './interfaces';
|
||||
|
||||
export function joinRoom({ userInfo }: JoinRoomData, { roomEvent }: RoomEvent) {
|
||||
const { roomId } = roomEvent;
|
||||
|
||||
RoomPersistence.userJoined(roomId, userInfo);
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
import { RoomPersistence } from '../../persistence';
|
||||
import { LeaveRoomData, RoomEvent } from './interfaces';
|
||||
|
||||
export function leaveRoom({ name }: LeaveRoomData, { roomEvent }: RoomEvent) {
|
||||
const { roomId } = roomEvent;
|
||||
RoomPersistence.userLeft(roomId, name);
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
import { RoomPersistence } from '../../persistence';
|
||||
import { ListGamesData, RoomEvent } from './interfaces';
|
||||
|
||||
export function listGames({ gameList }: ListGamesData, { roomEvent }: RoomEvent) {
|
||||
const { roomId } = roomEvent;
|
||||
RoomPersistence.updateGames(roomId, gameList);
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
import { Message } from 'types';
|
||||
|
||||
import { RoomPersistence } from '../../persistence';
|
||||
import { RoomEvent } from './interfaces';
|
||||
|
||||
export function roomSay(message: Message, { roomEvent }: RoomEvent) {
|
||||
const { roomId } = roomEvent;
|
||||
RoomPersistence.addMessage(roomId, message);
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
import { SessionPersistence } from '../../persistence';
|
||||
import { AddToListData } from './interfaces';
|
||||
|
||||
export function addToList({ listName, userInfo }: AddToListData) {
|
||||
switch (listName) {
|
||||
case 'buddy': {
|
||||
SessionPersistence.addToBuddyList(userInfo);
|
||||
break;
|
||||
}
|
||||
case 'ignore': {
|
||||
SessionPersistence.addToIgnoreList(userInfo);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.log(`Attempted to add to unknown list: ${listName}`);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
import { StatusEnum } from 'types';
|
||||
import webClient from '../../WebClient';
|
||||
import { updateStatus } from '../../commands/session';
|
||||
import { ConnectionClosedData } from './interfaces';
|
||||
|
||||
export function connectionClosed({ reason, reasonStr }: ConnectionClosedData) {
|
||||
let message;
|
||||
|
||||
// @TODO (5)
|
||||
if (reasonStr) {
|
||||
message = reasonStr;
|
||||
} else {
|
||||
switch (reason) {
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.USER_LIMIT_REACHED:
|
||||
message = 'The server has reached its maximum user capacity';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.TOO_MANY_CONNECTIONS:
|
||||
message = 'There are too many concurrent connections from your address';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.BANNED:
|
||||
message = 'You are banned';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.DEMOTED:
|
||||
message = 'You were demoted';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.SERVER_SHUTDOWN:
|
||||
message = 'Scheduled server shutdown';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.USERNAMEINVALID:
|
||||
message = 'Invalid username';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.LOGGEDINELSEWERE:
|
||||
message = 'You have been logged out due to logging in at another location';
|
||||
break;
|
||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.OTHER:
|
||||
default:
|
||||
message = 'Unknown reason';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
updateStatus(StatusEnum.DISCONNECTED, message);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
import { ProtobufEvents } from '../../services/ProtobufService';
|
||||
import { addToList } from './addToList';
|
||||
import { connectionClosed } from './connectionClosed';
|
||||
import { listRooms } from './listRooms';
|
||||
import { notifyUser } from './notifyUser';
|
||||
import { playerPropertiesChanges } from './playerPropertiesChanges';
|
||||
import { removeFromList } from './removeFromList';
|
||||
import { serverIdentification } from './serverIdentification';
|
||||
import { serverMessage } from './serverMessage';
|
||||
import { serverShutdown } from './serverShutdown';
|
||||
import { userJoined } from './userJoined';
|
||||
import { userLeft } from './userLeft';
|
||||
import { userMessage } from './userMessage';
|
||||
|
||||
export const SessionEvents: ProtobufEvents = {
|
||||
'.Event_AddToList.ext': addToList,
|
||||
'.Event_ConnectionClosed.ext': connectionClosed,
|
||||
'.Event_ListRooms.ext': listRooms,
|
||||
'.Event_NotifyUser.ext': notifyUser,
|
||||
'.Event_PlayerPropertiesChanges.ext': playerPropertiesChanges,
|
||||
'.Event_RemoveFromList.ext': removeFromList,
|
||||
'.Event_ServerIdentification.ext': serverIdentification,
|
||||
'.Event_ServerMessage.ext': serverMessage,
|
||||
'.Event_ServerShutdown.ext': serverShutdown,
|
||||
'.Event_UserJoined.ext': userJoined,
|
||||
'.Event_UserLeft.ext': userLeft,
|
||||
'.Event_UserMessage.ext': userMessage,
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
import { Room, User } from 'types';
|
||||
|
||||
export interface SessionEvent {
|
||||
sessionEvent: {}
|
||||
}
|
||||
|
||||
export interface AddToListData {
|
||||
listName: string;
|
||||
userInfo: User;
|
||||
}
|
||||
|
||||
export interface ConnectionClosedData {
|
||||
endTime: number;
|
||||
reason: number;
|
||||
reasonStr: string;
|
||||
}
|
||||
|
||||
export interface ListRoomsData {
|
||||
roomList: Room[];
|
||||
}
|
||||
|
||||
export interface RemoveFromListData {
|
||||
listName: string;
|
||||
userName: string;
|
||||
}
|
||||
|
||||
export interface ServerIdentificationData {
|
||||
protocolVersion: number;
|
||||
serverName: string;
|
||||
serverVersion: string;
|
||||
serverOptions: number;
|
||||
}
|
||||
|
||||
export interface ServerMessageData {
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface UserJoinedData {
|
||||
userInfo: User;
|
||||
}
|
||||
|
||||
export interface UserLeftData {
|
||||
name: string;
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
import webClient from '../../WebClient';
|
||||
import { joinRoom } from '../../commands/session';
|
||||
import { RoomPersistence } from '../../persistence';
|
||||
import { ListRoomsData } from './interfaces';
|
||||
|
||||
export function listRooms({ roomList }: ListRoomsData) {
|
||||
RoomPersistence.updateRooms(roomList);
|
||||
|
||||
if (webClient.clientOptions.autojoinrooms) {
|
||||
roomList.forEach(({ autoJoin, roomId }) => {
|
||||
if (autoJoin) {
|
||||
joinRoom(roomId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
export function notifyUser(payload) {
|
||||
console.info('Event_NotifyUser', payload);
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
export function playerPropertiesChanges(payload) {
|
||||
console.info('Event_PlayerPropertiesChanges', payload);
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
import { SessionPersistence } from '../../persistence';
|
||||
import { RemoveFromListData } from './interfaces';
|
||||
|
||||
export function removeFromList({ listName, userName }: RemoveFromListData) {
|
||||
switch (listName) {
|
||||
case 'buddy': {
|
||||
SessionPersistence.removeFromBuddyList(userName);
|
||||
break;
|
||||
}
|
||||
case 'ignore': {
|
||||
SessionPersistence.removeFromIgnoreList(userName);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.log(`Attempted to remove from unknown list: ${listName}`);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
import { StatusEnum, WebSocketConnectReason } from 'types';
|
||||
|
||||
import webClient from '../../WebClient';
|
||||
import {
|
||||
activateAccount,
|
||||
disconnect,
|
||||
login,
|
||||
register,
|
||||
requestPasswordSalt,
|
||||
resetPassword,
|
||||
resetPasswordChallenge,
|
||||
resetPasswordRequest,
|
||||
updateStatus,
|
||||
} from '../../commands/session';
|
||||
import { generateSalt, passwordSaltSupported } from '../../utils';
|
||||
import { ServerIdentificationData } from './interfaces';
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
export function serverIdentification(info: ServerIdentificationData) {
|
||||
const { serverName, serverVersion, protocolVersion, serverOptions } = info;
|
||||
if (protocolVersion !== webClient.protocolVersion) {
|
||||
updateStatus(StatusEnum.DISCONNECTED, `Protocol version mismatch: ${protocolVersion}`);
|
||||
disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
const getPasswordSalt = passwordSaltSupported(serverOptions, webClient);
|
||||
const { options } = webClient;
|
||||
|
||||
switch (options.reason) {
|
||||
case WebSocketConnectReason.LOGIN:
|
||||
updateStatus(StatusEnum.LOGGING_IN, 'Logging In...');
|
||||
if (getPasswordSalt) {
|
||||
requestPasswordSalt(options);
|
||||
} else {
|
||||
login(options);
|
||||
}
|
||||
break;
|
||||
case WebSocketConnectReason.REGISTER:
|
||||
const passwordSalt = getPasswordSalt ? generateSalt() : null;
|
||||
register(options, passwordSalt);
|
||||
break;
|
||||
case WebSocketConnectReason.ACTIVATE_ACCOUNT:
|
||||
if (getPasswordSalt) {
|
||||
requestPasswordSalt(options);
|
||||
} else {
|
||||
activateAccount(options);
|
||||
}
|
||||
break;
|
||||
case WebSocketConnectReason.PASSWORD_RESET_REQUEST:
|
||||
resetPasswordRequest(options);
|
||||
break;
|
||||
case WebSocketConnectReason.PASSWORD_RESET_CHALLENGE:
|
||||
resetPasswordChallenge(options);
|
||||
break;
|
||||
case WebSocketConnectReason.PASSWORD_RESET:
|
||||
if (getPasswordSalt) {
|
||||
requestPasswordSalt(options);
|
||||
} else {
|
||||
resetPassword(options);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
updateStatus(StatusEnum.DISCONNECTED, 'Unknown Connection Reason: ' + options.reason);
|
||||
disconnect();
|
||||
break;
|
||||
}
|
||||
|
||||
webClient.options = {};
|
||||
SessionPersistence.updateInfo(serverName, serverVersion);
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
import { SessionPersistence } from '../../persistence';
|
||||
import { ServerMessageData } from './interfaces';
|
||||
|
||||
export function serverMessage({ message }: ServerMessageData) {
|
||||
SessionPersistence.serverMessage(message);
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
export function serverShutdown(payload) {
|
||||
console.info('Event_ServerShutdown', payload);
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
import { SessionPersistence } from '../../persistence';
|
||||
import { UserJoinedData } from './interfaces';
|
||||
|
||||
export function userJoined({ userInfo }: UserJoinedData) {
|
||||
SessionPersistence.userJoined(userInfo);
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
import { SessionPersistence } from '../../persistence';
|
||||
import { UserLeftData } from './interfaces';
|
||||
|
||||
export function userLeft({ name }: UserLeftData) {
|
||||
SessionPersistence.userLeft(name);
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
export function userMessage(payload) {
|
||||
console.info('Event_UserMessage', payload);
|
||||
}
|
|
@ -1,14 +1,17 @@
|
|||
import { KeepAliveService } from './KeepAliveService';
|
||||
import { WebSocketService } from './WebSocketService';
|
||||
|
||||
import webClient from '../WebClient';
|
||||
|
||||
describe('KeepAliveService', () => {
|
||||
let service: KeepAliveService;
|
||||
let socket: WebSocketService;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
|
||||
service = new KeepAliveService(webClient.socket);
|
||||
socket = new WebSocketService(webClient);
|
||||
service = new KeepAliveService(socket);
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
|
@ -27,7 +30,7 @@ describe('KeepAliveService', () => {
|
|||
promise = new Promise(resolve => resolvePing = resolve);
|
||||
ping = (done) => promise.then(done);
|
||||
|
||||
checkReadyStateSpy = jest.spyOn(webClient.socket, 'checkReadyState');
|
||||
checkReadyStateSpy = jest.spyOn(socket, 'checkReadyState');
|
||||
checkReadyStateSpy.mockImplementation(() => true);
|
||||
|
||||
service.startPingLoop(interval, ping);
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import { Subject } from 'rxjs';
|
||||
|
||||
import { StatusEnum, WebSocketConnectOptions } from 'types';
|
||||
import { ServerStatus, StatusEnum, WebSocketConnectOptions } from 'types';
|
||||
|
||||
import { KeepAliveService } from './KeepAliveService';
|
||||
import { WebClient } from '../WebClient';
|
||||
import { SessionPersistence } from '../persistence';
|
||||
import { updateStatus } from '../commands/session';
|
||||
|
||||
export class WebSocketService {
|
||||
private socket: WebSocket;
|
||||
|
@ -15,7 +14,9 @@ export class WebSocketService {
|
|||
private keepAliveService: KeepAliveService;
|
||||
|
||||
public message$: Subject<MessageEvent> = new Subject();
|
||||
public statusChange$: Subject<ServerStatus> = new Subject();
|
||||
|
||||
private status: StatusEnum = StatusEnum.DISCONNECTED;
|
||||
private keepalive: number;
|
||||
|
||||
constructor(webClient: WebClient) {
|
||||
|
@ -24,7 +25,7 @@ export class WebSocketService {
|
|||
this.keepAliveService = new KeepAliveService(this);
|
||||
this.keepAliveService.disconnected$.subscribe(() => {
|
||||
this.disconnect();
|
||||
updateStatus(StatusEnum.DISCONNECTED, 'Connection timeout');
|
||||
this.updateStatus(StatusEnum.DISCONNECTED, 'Connection timeout');
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -63,6 +64,11 @@ export class WebSocketService {
|
|||
this.socket.send(message);
|
||||
}
|
||||
|
||||
public updateStatus(status: StatusEnum, description: string): void {
|
||||
this.status = status;
|
||||
this.statusChange$.next({ status, description });
|
||||
}
|
||||
|
||||
private createWebSocket(url: string): WebSocket {
|
||||
const socket = new WebSocket(url);
|
||||
socket.binaryType = 'arraybuffer';
|
||||
|
@ -71,7 +77,7 @@ export class WebSocketService {
|
|||
|
||||
socket.onopen = () => {
|
||||
clearTimeout(connectionTimer);
|
||||
updateStatus(StatusEnum.CONNECTED, 'Connected');
|
||||
this.updateStatus(StatusEnum.CONNECTED, 'Connected');
|
||||
|
||||
this.keepAliveService.startPingLoop(this.keepalive, (pingReceived: Function) => {
|
||||
this.webClient.keepAlive(pingReceived);
|
||||
|
@ -80,15 +86,15 @@ export class WebSocketService {
|
|||
|
||||
socket.onclose = () => {
|
||||
// dont overwrite failure messages
|
||||
if (this.webClient.status !== StatusEnum.DISCONNECTED) {
|
||||
updateStatus(StatusEnum.DISCONNECTED, 'Connection Closed');
|
||||
if (this.status !== StatusEnum.DISCONNECTED) {
|
||||
this.updateStatus(StatusEnum.DISCONNECTED, 'Connection Closed');
|
||||
}
|
||||
|
||||
this.keepAliveService.endPingLoop();
|
||||
};
|
||||
|
||||
socket.onerror = () => {
|
||||
updateStatus(StatusEnum.DISCONNECTED, 'Connection Failed');
|
||||
this.updateStatus(StatusEnum.DISCONNECTED, 'Connection Failed');
|
||||
SessionPersistence.connectionFailed();
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue