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 \
|
RUN dnf install -y \
|
||||||
ccache \
|
ccache \
|
|
@ -1,4 +1,4 @@
|
||||||
FROM ubuntu:noble
|
FROM ubuntu:lunar
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
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 18.04 LTS</kbd> ("Bionic Beaver")
|
||||||
- <kbd>Ubuntu 20.04 LTS</kbd> ("Focal Fossa")
|
- <kbd>Ubuntu 20.04 LTS</kbd> ("Focal Fossa")
|
||||||
- <kbd>Ubuntu 22.04 LTS</kbd> ("Jammy Jellyfish")
|
- <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 11</kbd> ("Bullseye")
|
||||||
- <kbd>Debian 12</kbd> ("Bookworm")
|
- <kbd>Debian 12</kbd> ("Bookworm")
|
||||||
|
- <kbd>Fedora 38</kbd>
|
||||||
- <kbd>Fedora 39</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>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>
|
<kbd>General Linux support is available via a flatpak package (Flathub)</kbd></i>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
6
.github/workflows/desktop-build.yml
vendored
6
.github/workflows/desktop-build.yml
vendored
|
@ -97,10 +97,10 @@ jobs:
|
||||||
- distro: Debian12
|
- distro: Debian12
|
||||||
package: DEB
|
package: DEB
|
||||||
|
|
||||||
- distro: Fedora39
|
- distro: Fedora38
|
||||||
package: RPM
|
package: RPM
|
||||||
|
|
||||||
- distro: Fedora40
|
- distro: Fedora39
|
||||||
package: RPM
|
package: RPM
|
||||||
|
|
||||||
- distro: UbuntuBionic
|
- distro: UbuntuBionic
|
||||||
|
@ -114,7 +114,7 @@ jobs:
|
||||||
package: DEB
|
package: DEB
|
||||||
test: skip # running tests on all distros is superfluous
|
test: skip # running tests on all distros is superfluous
|
||||||
|
|
||||||
- distro: UbuntuNoble
|
- distro: UbuntuLunar
|
||||||
package: DEB
|
package: DEB
|
||||||
|
|
||||||
name: ${{matrix.distro}}
|
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
|
- name: Create pull request
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
id: create_pr
|
id: create_pr
|
||||||
uses: peter-evans/create-pull-request@v6
|
uses: peter-evans/create-pull-request@v5
|
||||||
with:
|
with:
|
||||||
add-paths: |
|
add-paths: |
|
||||||
cockatrice/translations/*.ts
|
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
|
- name: Create pull request
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
id: create_pr
|
id: create_pr
|
||||||
uses: peter-evans/create-pull-request@v6
|
uses: peter-evans/create-pull-request@v5
|
||||||
with:
|
with:
|
||||||
add-paths: |
|
add-paths: |
|
||||||
cockatrice/cockatrice_en@source.ts
|
cockatrice/cockatrice_en@source.ts
|
||||||
|
|
|
@ -74,7 +74,7 @@ endif()
|
||||||
|
|
||||||
# A project name is needed for CPack
|
# A project name is needed for CPack
|
||||||
# Version can be overriden by git tags, see cmake/getversion.cmake
|
# 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
|
# Set release name if not provided via env/cmake var
|
||||||
if(NOT DEFINED GIT_TAG_RELEASENAME)
|
if(NOT DEFINED GIT_TAG_RELEASENAME)
|
||||||
|
|
|
@ -32,7 +32,6 @@ RemoteClient::RemoteClient(QObject *parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
clearNewClientFeatures();
|
clearNewClientFeatures();
|
||||||
maxTimeout = SettingsCache::instance().getTimeOut();
|
|
||||||
int keepalive = SettingsCache::instance().getKeepAlive();
|
int keepalive = SettingsCache::instance().getKeepAlive();
|
||||||
timer = new QTimer(this);
|
timer = new QTimer(this);
|
||||||
timer->setInterval(keepalive * 1000);
|
timer->setInterval(keepalive * 1000);
|
||||||
|
|
|
@ -89,7 +89,7 @@ private slots:
|
||||||
void submitForgotPasswordChallengeResponse(const Response &response);
|
void submitForgotPasswordChallengeResponse(const Response &response);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int maxTimeout;
|
static const int maxTimeout = 5;
|
||||||
int timeRunning, lastDataReceived;
|
int timeRunning, lastDataReceived;
|
||||||
QByteArray inputBuffer;
|
QByteArray inputBuffer;
|
||||||
bool messageInProgress;
|
bool messageInProgress;
|
||||||
|
|
|
@ -195,7 +195,6 @@ SettingsCache::SettingsCache()
|
||||||
|
|
||||||
lang = settings->value("personal/lang").toString();
|
lang = settings->value("personal/lang").toString();
|
||||||
keepalive = settings->value("personal/keepalive", 3).toInt();
|
keepalive = settings->value("personal/keepalive", 3).toInt();
|
||||||
timeout = settings->value("personal/timeout", 5).toInt();
|
|
||||||
|
|
||||||
// tip of the day settings
|
// tip of the day settings
|
||||||
showTipsOnStartup = settings->value("tipOfDay/showTips", true).toBool();
|
showTipsOnStartup = settings->value("tipOfDay/showTips", true).toBool();
|
||||||
|
|
|
@ -134,7 +134,6 @@ private:
|
||||||
bool spectatorsCanSeeEverything;
|
bool spectatorsCanSeeEverything;
|
||||||
bool createGameAsSpectator;
|
bool createGameAsSpectator;
|
||||||
int keepalive;
|
int keepalive;
|
||||||
int timeout;
|
|
||||||
void translateLegacySettings();
|
void translateLegacySettings();
|
||||||
QString getSafeConfigPath(QString configEntry, QString defaultPath) const;
|
QString getSafeConfigPath(QString configEntry, QString defaultPath) const;
|
||||||
QString getSafeConfigFilePath(QString configEntry, QString defaultPath) const;
|
QString getSafeConfigFilePath(QString configEntry, QString defaultPath) const;
|
||||||
|
@ -435,10 +434,6 @@ public:
|
||||||
{
|
{
|
||||||
return keepalive;
|
return keepalive;
|
||||||
}
|
}
|
||||||
int getTimeOut() const
|
|
||||||
{
|
|
||||||
return timeout;
|
|
||||||
}
|
|
||||||
int getMaxFontSize() const
|
int getMaxFontSize() const
|
||||||
{
|
{
|
||||||
return maxFontSize;
|
return maxFontSize;
|
||||||
|
|
|
@ -21,10 +21,6 @@ public:
|
||||||
{
|
{
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
void setId(int _id)
|
|
||||||
{
|
|
||||||
id = _id;
|
|
||||||
}
|
|
||||||
Server_Card *getStartCard() const
|
Server_Card *getStartCard() const
|
||||||
{
|
{
|
||||||
return startCard;
|
return startCard;
|
||||||
|
|
|
@ -296,12 +296,6 @@ void Server_Player::addArrow(Server_Arrow *arrow)
|
||||||
arrows.insert(arrow->getId(), 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)
|
bool Server_Player::deleteArrow(int arrowId)
|
||||||
{
|
{
|
||||||
Server_Arrow *arrow = arrows.value(arrowId, 0);
|
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();
|
const QList<Server_Player *> &players = game->getPlayers().values();
|
||||||
for (auto player : players) {
|
for (auto player : players) {
|
||||||
QList<int> arrowsToDelete;
|
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))
|
if ((arrow->getStartCard() == card) || (arrow->getTargetItem() == card))
|
||||||
arrowsToDelete.append(arrow->getId());
|
arrowsToDelete.append(arrow->getId());
|
||||||
}
|
}
|
||||||
|
@ -1482,8 +1478,9 @@ Server_Player::cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer
|
||||||
// Copy Arrows
|
// Copy Arrows
|
||||||
const QList<Server_Player *> &players = game->getPlayers().values();
|
const QList<Server_Player *> &players = game->getPlayers().values();
|
||||||
for (auto player : players) {
|
for (auto player : players) {
|
||||||
QList<int> changedArrowIds;
|
QMapIterator<int, Server_Arrow *> arrowIterator(player->getArrows());
|
||||||
for (Server_Arrow *arrow : player->getArrows()) {
|
while (arrowIterator.hasNext()) {
|
||||||
|
Server_Arrow *arrow = arrowIterator.next().value();
|
||||||
bool sendGameEvent = false;
|
bool sendGameEvent = false;
|
||||||
const auto *startCard = arrow->getStartCard();
|
const auto *startCard = arrow->getStartCard();
|
||||||
if (startCard == targetCard) {
|
if (startCard == targetCard) {
|
||||||
|
@ -1500,10 +1497,7 @@ Server_Player::cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer
|
||||||
if (sendGameEvent) {
|
if (sendGameEvent) {
|
||||||
Event_CreateArrow _event;
|
Event_CreateArrow _event;
|
||||||
ServerInfo_Arrow *arrowInfo = _event.mutable_arrow_info();
|
ServerInfo_Arrow *arrowInfo = _event.mutable_arrow_info();
|
||||||
changedArrowIds.append(arrow->getId());
|
arrowInfo->set_id(arrow->getId());
|
||||||
int id = player->newArrowId();
|
|
||||||
arrow->setId(id);
|
|
||||||
arrowInfo->set_id(id);
|
|
||||||
arrowInfo->set_start_player_id(player->getPlayerId());
|
arrowInfo->set_start_player_id(player->getPlayerId());
|
||||||
arrowInfo->set_start_zone(startCard->getZone()->getName().toStdString());
|
arrowInfo->set_start_zone(startCard->getZone()->getName().toStdString());
|
||||||
arrowInfo->set_start_card_id(startCard->getId());
|
arrowInfo->set_start_card_id(startCard->getId());
|
||||||
|
@ -1520,9 +1514,6 @@ Server_Player::cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer
|
||||||
ges.enqueueGameEvent(_event, player->getPlayerId());
|
ges.enqueueGameEvent(_event, player->getPlayerId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int id : changedArrowIds) {
|
|
||||||
player->updateArrowId(id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
targetCard->resetState();
|
targetCard->resetState();
|
||||||
|
@ -1588,7 +1579,9 @@ Server_Player::cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer
|
||||||
return Response::RespNameNotFound;
|
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)) {
|
if ((temp->getStartCard() == startCard) && (temp->getTargetItem() == targetItem)) {
|
||||||
return Response::RespContextError;
|
return Response::RespContextError;
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,7 +164,6 @@ public:
|
||||||
|
|
||||||
void addZone(Server_CardZone *zone);
|
void addZone(Server_CardZone *zone);
|
||||||
void addArrow(Server_Arrow *arrow);
|
void addArrow(Server_Arrow *arrow);
|
||||||
void updateArrowId(int id);
|
|
||||||
bool deleteArrow(int arrowId);
|
bool deleteArrow(int arrowId);
|
||||||
void addCounter(Server_Counter *counter);
|
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=="
|
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
||||||
},
|
},
|
||||||
"node_modules/ejs": {
|
"node_modules/ejs": {
|
||||||
"version": "3.1.10",
|
"version": "3.1.8",
|
||||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
|
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz",
|
||||||
"integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
|
"integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jake": "^10.8.5"
|
"jake": "^10.8.5"
|
||||||
},
|
},
|
||||||
|
@ -25550,9 +25550,9 @@
|
||||||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
||||||
},
|
},
|
||||||
"ejs": {
|
"ejs": {
|
||||||
"version": "3.1.10",
|
"version": "3.1.8",
|
||||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
|
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz",
|
||||||
"integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
|
"integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"jake": "^10.8.5"
|
"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 Account = (props: AccountProps) => {
|
||||||
const { buddyList, ignoreList, serverName, serverVersion, user } = props;
|
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' }));
|
let url = URL.createObjectURL(new Blob([avatarBmp], { 'type': 'image/png' }));
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
|
@ -35,14 +35,13 @@ const LoginForm = ({ onSubmit, disableSubmitButton, onResetPassword }: LoginForm
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
const useStoredPassword = (remember, password) => remember && host?.hashedPassword && !password;
|
const useStoredPassword = (remember, password) => remember && host.hashedPassword && !password;
|
||||||
const togglePasswordLabel = (useStoredLabel) => {
|
const togglePasswordLabel = (useStoredLabel) => {
|
||||||
setUseStoredPasswordLabel(useStoredLabel);
|
setUseStoredPasswordLabel(useStoredLabel);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOnSubmit = ({ userName, ...values }) => {
|
const handleOnSubmit = ({ userName, ...values }) => {
|
||||||
userName = userName?.trim();
|
userName = userName?.trim();
|
||||||
console.log(userName, values);
|
|
||||||
|
|
||||||
onSubmit({ userName, ...values });
|
onSubmit({ userName, ...values });
|
||||||
}
|
}
|
||||||
|
@ -85,7 +84,7 @@ const LoginForm = ({ onSubmit, disableSubmitButton, onResetPassword }: LoginForm
|
||||||
}, [host]);
|
}, [host]);
|
||||||
|
|
||||||
const onUserNameChange = (userName) => {
|
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) {
|
if (useStoredPassword(values.remember, values.password) && fieldChanged) {
|
||||||
setHost(({ hashedPassword, ...s }) => ({ ...s, userName }));
|
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 { ProtobufService } from './services/ProtobufService';
|
||||||
import { WebSocketService } from './services/WebSocketService';
|
import { WebSocketService } from './services/WebSocketService';
|
||||||
|
@ -37,7 +37,6 @@ export class WebClient {
|
||||||
};
|
};
|
||||||
|
|
||||||
public options: WebSocketConnectOptions;
|
public options: WebSocketConnectOptions;
|
||||||
public status: StatusEnum;
|
|
||||||
|
|
||||||
public connectionAttemptMade = false;
|
public connectionAttemptMade = false;
|
||||||
|
|
||||||
|
@ -46,6 +45,10 @@ export class WebClient {
|
||||||
this.protobuf.handleMessageEvent(message);
|
this.protobuf.handleMessageEvent(message);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.socket.statusChange$.subscribe((status: ServerStatus) => {
|
||||||
|
this.handleStatusChange(status);
|
||||||
|
});
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'test') {
|
if (process.env.NODE_ENV !== 'test') {
|
||||||
console.log(this);
|
console.log(this);
|
||||||
}
|
}
|
||||||
|
@ -65,8 +68,12 @@ export class WebClient {
|
||||||
this.socket.disconnect();
|
this.socket.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateStatus(status: StatusEnum) {
|
public updateStatus(status: StatusEnum, description: string) {
|
||||||
this.status = status;
|
this.socket.updateStatus(status, description);
|
||||||
|
}
|
||||||
|
|
||||||
|
public handleStatusChange({ status, description }: ServerStatus) {
|
||||||
|
SessionPersistence.updateStatus(status, description);
|
||||||
|
|
||||||
if (status === StatusEnum.DISCONNECTED) {
|
if (status === StatusEnum.DISCONNECTED) {
|
||||||
this.protobuf.resetCommands();
|
this.protobuf.resetCommands();
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { RoomPersistence } from '../../persistence';
|
import { RoomCommands } from './RoomCommands';
|
||||||
import webClient from '../../WebClient';
|
|
||||||
|
|
||||||
import { leaveRoom, roomSay } from './';
|
import { RoomPersistence } from '../persistence';
|
||||||
|
import webClient from '../WebClient';
|
||||||
|
|
||||||
describe.skip('RoomCommands', () => {
|
describe('RoomCommands', () => {
|
||||||
const roomId = 1;
|
const roomId = 1;
|
||||||
let sendRoomCommandSpy;
|
let sendRoomCommandSpy;
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ describe.skip('RoomCommands', () => {
|
||||||
it('should call protobuf controller methods and sendCommand', () => {
|
it('should call protobuf controller methods and sendCommand', () => {
|
||||||
const message = ' message ';
|
const message = ' message ';
|
||||||
|
|
||||||
roomSay(roomId, message);
|
RoomCommands.roomSay(roomId, message);
|
||||||
|
|
||||||
expect(webClient.protobuf.sendRoomCommand).toHaveBeenCalled();
|
expect(webClient.protobuf.sendRoomCommand).toHaveBeenCalled();
|
||||||
expect(webClient.protobuf.sendRoomCommand).toHaveBeenCalledWith(roomId, {
|
expect(webClient.protobuf.sendRoomCommand).toHaveBeenCalledWith(roomId, {
|
||||||
|
@ -36,7 +36,7 @@ describe.skip('RoomCommands', () => {
|
||||||
it('should not call sendRoomCommand if trimmed message is empty', () => {
|
it('should not call sendRoomCommand if trimmed message is empty', () => {
|
||||||
const message = ' ';
|
const message = ' ';
|
||||||
|
|
||||||
roomSay(roomId, message);
|
RoomCommands.roomSay(roomId, message);
|
||||||
|
|
||||||
expect(webClient.protobuf.sendRoomCommand).not.toHaveBeenCalled();
|
expect(webClient.protobuf.sendRoomCommand).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
@ -48,7 +48,7 @@ describe.skip('RoomCommands', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call protobuf controller methods and sendCommand', () => {
|
it('should call protobuf controller methods and sendCommand', () => {
|
||||||
leaveRoom(roomId);
|
RoomCommands.leaveRoom(roomId);
|
||||||
|
|
||||||
expect(webClient.protobuf.sendRoomCommand).toHaveBeenCalled();
|
expect(webClient.protobuf.sendRoomCommand).toHaveBeenCalled();
|
||||||
expect(webClient.protobuf.sendRoomCommand).toHaveBeenCalledWith(
|
expect(webClient.protobuf.sendRoomCommand).toHaveBeenCalledWith(
|
||||||
|
@ -67,7 +67,7 @@ describe.skip('RoomCommands', () => {
|
||||||
|
|
||||||
jest.spyOn(RoomPersistence, 'leaveRoom').mockImplementation(() => {});
|
jest.spyOn(RoomPersistence, 'leaveRoom').mockImplementation(() => {});
|
||||||
|
|
||||||
leaveRoom(roomId);
|
RoomCommands.leaveRoom(roomId);
|
||||||
|
|
||||||
expect(RoomPersistence.leaveRoom).toHaveBeenCalledWith(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 { StatusEnum, WebSocketConnectOptions, WebSocketConnectReason } from 'types';
|
||||||
|
|
||||||
import webClient from '../../WebClient';
|
import { SessionCommands } from './SessionCommands';
|
||||||
import { RoomPersistence, SessionPersistence } from '../../persistence';
|
|
||||||
|
|
||||||
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;
|
const roomId = 1;
|
||||||
let sendModeratorCommandSpy;
|
let sendModeratorCommandSpy;
|
||||||
let sendSessionCommandSpy;
|
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 { RoomCommands } from './RoomCommands';
|
||||||
export * as SessionCommands from './session';
|
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 { Message } from 'types';
|
||||||
|
|
||||||
import { RoomPersistence } from '../../persistence';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
RoomEvents,
|
||||||
RoomEvent,
|
RoomEvent,
|
||||||
JoinRoomData,
|
JoinRoomData,
|
||||||
LeaveRoomData,
|
LeaveRoomData,
|
||||||
ListGamesData,
|
ListGamesData,
|
||||||
} from './interfaces';
|
} from './RoomEvents';
|
||||||
|
import { RoomPersistence } from '../persistence/RoomPersistence';
|
||||||
|
|
||||||
import { RoomEvents } from '.';
|
describe('RoomEvents', () => {
|
||||||
|
|
||||||
describe.skip('RoomEvents', () => {
|
|
||||||
it('.Event_JoinRoom.ext should call RoomPersistence.userJoined', () => {
|
it('.Event_JoinRoom.ext should call RoomPersistence.userJoined', () => {
|
||||||
jest.spyOn(RoomPersistence, 'userJoined').mockImplementation(() => {});
|
jest.spyOn(RoomPersistence, 'userJoined').mockImplementation(() => {});
|
||||||
const data: JoinRoomData = { userInfo: {} as any };
|
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 { StatusEnum, WebSocketConnectReason } from 'types';
|
||||||
|
|
||||||
import { SessionCommands } from '../../commands';
|
|
||||||
import { RoomPersistence, SessionPersistence } from '../../persistence';
|
|
||||||
import webClient from '../../WebClient';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AddToListData,
|
AddToListData,
|
||||||
ConnectionClosedData,
|
ConnectionClosedData,
|
||||||
|
@ -11,13 +7,16 @@ import {
|
||||||
RemoveFromListData,
|
RemoveFromListData,
|
||||||
ServerIdentificationData,
|
ServerIdentificationData,
|
||||||
ServerMessageData,
|
ServerMessageData,
|
||||||
|
SessionEvents,
|
||||||
UserJoinedData,
|
UserJoinedData,
|
||||||
UserLeftData,
|
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;
|
const roomId = 1;
|
||||||
|
|
||||||
beforeEach(() => {
|
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 './RoomEvents';
|
||||||
export * from './session';
|
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 { KeepAliveService } from './KeepAliveService';
|
||||||
|
import { WebSocketService } from './WebSocketService';
|
||||||
|
|
||||||
import webClient from '../WebClient';
|
import webClient from '../WebClient';
|
||||||
|
|
||||||
describe('KeepAliveService', () => {
|
describe('KeepAliveService', () => {
|
||||||
let service: KeepAliveService;
|
let service: KeepAliveService;
|
||||||
|
let socket: WebSocketService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
|
|
||||||
service = new KeepAliveService(webClient.socket);
|
socket = new WebSocketService(webClient);
|
||||||
|
service = new KeepAliveService(socket);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
it('should create', () => {
|
||||||
|
@ -27,7 +30,7 @@ describe('KeepAliveService', () => {
|
||||||
promise = new Promise(resolve => resolvePing = resolve);
|
promise = new Promise(resolve => resolvePing = resolve);
|
||||||
ping = (done) => promise.then(done);
|
ping = (done) => promise.then(done);
|
||||||
|
|
||||||
checkReadyStateSpy = jest.spyOn(webClient.socket, 'checkReadyState');
|
checkReadyStateSpy = jest.spyOn(socket, 'checkReadyState');
|
||||||
checkReadyStateSpy.mockImplementation(() => true);
|
checkReadyStateSpy.mockImplementation(() => true);
|
||||||
|
|
||||||
service.startPingLoop(interval, ping);
|
service.startPingLoop(interval, ping);
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
|
|
||||||
import { StatusEnum, WebSocketConnectOptions } from 'types';
|
import { ServerStatus, StatusEnum, WebSocketConnectOptions } from 'types';
|
||||||
|
|
||||||
import { KeepAliveService } from './KeepAliveService';
|
import { KeepAliveService } from './KeepAliveService';
|
||||||
import { WebClient } from '../WebClient';
|
import { WebClient } from '../WebClient';
|
||||||
import { SessionPersistence } from '../persistence';
|
import { SessionPersistence } from '../persistence';
|
||||||
import { updateStatus } from '../commands/session';
|
|
||||||
|
|
||||||
export class WebSocketService {
|
export class WebSocketService {
|
||||||
private socket: WebSocket;
|
private socket: WebSocket;
|
||||||
|
@ -15,7 +14,9 @@ export class WebSocketService {
|
||||||
private keepAliveService: KeepAliveService;
|
private keepAliveService: KeepAliveService;
|
||||||
|
|
||||||
public message$: Subject<MessageEvent> = new Subject();
|
public message$: Subject<MessageEvent> = new Subject();
|
||||||
|
public statusChange$: Subject<ServerStatus> = new Subject();
|
||||||
|
|
||||||
|
private status: StatusEnum = StatusEnum.DISCONNECTED;
|
||||||
private keepalive: number;
|
private keepalive: number;
|
||||||
|
|
||||||
constructor(webClient: WebClient) {
|
constructor(webClient: WebClient) {
|
||||||
|
@ -24,7 +25,7 @@ export class WebSocketService {
|
||||||
this.keepAliveService = new KeepAliveService(this);
|
this.keepAliveService = new KeepAliveService(this);
|
||||||
this.keepAliveService.disconnected$.subscribe(() => {
|
this.keepAliveService.disconnected$.subscribe(() => {
|
||||||
this.disconnect();
|
this.disconnect();
|
||||||
updateStatus(StatusEnum.DISCONNECTED, 'Connection timeout');
|
this.updateStatus(StatusEnum.DISCONNECTED, 'Connection timeout');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +64,11 @@ export class WebSocketService {
|
||||||
this.socket.send(message);
|
this.socket.send(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public updateStatus(status: StatusEnum, description: string): void {
|
||||||
|
this.status = status;
|
||||||
|
this.statusChange$.next({ status, description });
|
||||||
|
}
|
||||||
|
|
||||||
private createWebSocket(url: string): WebSocket {
|
private createWebSocket(url: string): WebSocket {
|
||||||
const socket = new WebSocket(url);
|
const socket = new WebSocket(url);
|
||||||
socket.binaryType = 'arraybuffer';
|
socket.binaryType = 'arraybuffer';
|
||||||
|
@ -71,7 +77,7 @@ export class WebSocketService {
|
||||||
|
|
||||||
socket.onopen = () => {
|
socket.onopen = () => {
|
||||||
clearTimeout(connectionTimer);
|
clearTimeout(connectionTimer);
|
||||||
updateStatus(StatusEnum.CONNECTED, 'Connected');
|
this.updateStatus(StatusEnum.CONNECTED, 'Connected');
|
||||||
|
|
||||||
this.keepAliveService.startPingLoop(this.keepalive, (pingReceived: Function) => {
|
this.keepAliveService.startPingLoop(this.keepalive, (pingReceived: Function) => {
|
||||||
this.webClient.keepAlive(pingReceived);
|
this.webClient.keepAlive(pingReceived);
|
||||||
|
@ -80,15 +86,15 @@ export class WebSocketService {
|
||||||
|
|
||||||
socket.onclose = () => {
|
socket.onclose = () => {
|
||||||
// dont overwrite failure messages
|
// dont overwrite failure messages
|
||||||
if (this.webClient.status !== StatusEnum.DISCONNECTED) {
|
if (this.status !== StatusEnum.DISCONNECTED) {
|
||||||
updateStatus(StatusEnum.DISCONNECTED, 'Connection Closed');
|
this.updateStatus(StatusEnum.DISCONNECTED, 'Connection Closed');
|
||||||
}
|
}
|
||||||
|
|
||||||
this.keepAliveService.endPingLoop();
|
this.keepAliveService.endPingLoop();
|
||||||
};
|
};
|
||||||
|
|
||||||
socket.onerror = () => {
|
socket.onerror = () => {
|
||||||
updateStatus(StatusEnum.DISCONNECTED, 'Connection Failed');
|
this.updateStatus(StatusEnum.DISCONNECTED, 'Connection Failed');
|
||||||
SessionPersistence.connectionFailed();
|
SessionPersistence.connectionFailed();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue