Add error message (#970)

- Error link not found
 - Error user was banned
 - Error access dinied on the world
This commit is contained in:
grégoire parant 2021-04-29 23:47:30 +02:00 committed by GitHub
parent 7cd7d22e8b
commit 925545d74f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 76 additions and 30 deletions

View File

@ -27,7 +27,8 @@ import {
SendJitsiJwtMessage, SendJitsiJwtMessage,
CharacterLayerMessage, CharacterLayerMessage,
PingMessage, PingMessage,
SendUserMessage, BanUserMessage SendUserMessage,
BanUserMessage
} from "../Messages/generated/messages_pb" } from "../Messages/generated/messages_pb"
import {UserSimplePeerInterface} from "../WebRtc/SimplePeer"; import {UserSimplePeerInterface} from "../WebRtc/SimplePeer";
@ -169,7 +170,10 @@ export class RoomConnection implements RoomConnection {
} else if (message.hasWorldfullmessage()) { } else if (message.hasWorldfullmessage()) {
worldFullMessageStream.onMessage(); worldFullMessageStream.onMessage();
this.closed = true; this.closed = true;
} else if (message.hasWebrtcsignaltoclientmessage()) { } else if (message.hasWorldconnexionmessage()) {
worldFullMessageStream.onMessage(message.getWorldconnexionmessage()?.getMessage());
this.closed = true;
}else if (message.hasWebrtcsignaltoclientmessage()) {
this.dispatch(EventMessage.WEBRTC_SIGNAL, message.getWebrtcsignaltoclientmessage()); this.dispatch(EventMessage.WEBRTC_SIGNAL, message.getWebrtcsignaltoclientmessage());
} else if (message.hasWebrtcscreensharingsignaltoclientmessage()) { } else if (message.hasWebrtcscreensharingsignaltoclientmessage()) {
this.dispatch(EventMessage.WEBRTC_SCREEN_SHARING_SIGNAL, message.getWebrtcscreensharingsignaltoclientmessage()); this.dispatch(EventMessage.WEBRTC_SCREEN_SHARING_SIGNAL, message.getWebrtcscreensharingsignaltoclientmessage());

View File

@ -2,12 +2,12 @@ import {Subject} from "rxjs";
class WorldFullMessageStream { class WorldFullMessageStream {
private _stream:Subject<void> = new Subject(); private _stream:Subject<string|null> = new Subject<string|null>();
public stream = this._stream.asObservable(); public stream = this._stream.asObservable();
onMessage() { onMessage(message? :string) {
this._stream.next(); this._stream.next(message);
} }
} }

View File

@ -372,7 +372,7 @@ export class GameScene extends ResizableScene implements CenterListener {
new PinchManager(this); new PinchManager(this);
} }
this.messageSubscription = worldFullMessageStream.stream.subscribe((message) => this.showWorldFullError()) this.messageSubscription = worldFullMessageStream.stream.subscribe((message) => this.showWorldFullError(message))
const playerName = gameManager.getPlayerName(); const playerName = gameManager.getPlayerName();
if (!playerName) { if (!playerName) {
@ -909,7 +909,7 @@ ${escapedMessage}
audioManager.unloadAudio(); audioManager.unloadAudio();
// We are completely destroying the current scene to avoid using a half-backed instance when coming back to the same map. // We are completely destroying the current scene to avoid using a half-backed instance when coming back to the same map.
this.connection?.closeConnection(); this.connection?.closeConnection();
this.simplePeer.closeAllConnections(); this.simplePeer?.closeAllConnections();
this.simplePeer?.unregister(); this.simplePeer?.unregister();
this.messageSubscription?.unsubscribe(); this.messageSubscription?.unsubscribe();
@ -1488,14 +1488,24 @@ ${escapedMessage}
} }
//todo: put this into an 'orchestrator' scene (EntryScene?) //todo: put this into an 'orchestrator' scene (EntryScene?)
private showWorldFullError(): void { private showWorldFullError(message: string|null): void {
this.cleanupClosingScene(); this.cleanupClosingScene();
this.scene.stop(ReconnectingSceneName); this.scene.stop(ReconnectingSceneName);
this.scene.remove(ReconnectingSceneName);
this.userInputManager.disableControls(); this.userInputManager.disableControls();
this.scene.start(ErrorSceneName, { //FIX ME to use status code
title: 'Connection rejected', if(message == undefined){
subTitle: 'The world you are trying to join is full. Try again later.', this.scene.start(ErrorSceneName, {
message: 'If you want more information, you may contact us at: workadventure@thecodingmachine.com' title: 'Connection rejected',
}); subTitle: 'The world you are trying to join is full. Try again later.',
message: 'If you want more information, you may contact us at: workadventure@thecodingmachine.com'
});
}else{
this.scene.start(ErrorSceneName, {
title: 'Connection rejected',
subTitle: 'You cannot join the World. Try again later. \n\r \n\r Error: '+message+'.',
message: 'If you want more information, you may contact administrator or contact us at: workadventure@thecodingmachine.com'
});
}
} }
} }

View File

@ -21,7 +21,10 @@ export class EntryScene extends Scene {
this.scene.start(nextSceneName); this.scene.start(nextSceneName);
}).catch((err) => { }).catch((err) => {
if (err.response && err.response.status == 404) { if (err.response && err.response.status == 404) {
ErrorScene.showError(new WAError('Page Not Found', 'Could not find map', window.location.pathname), this.scene); ErrorScene.showError(new WAError(
'Access link incorrect',
'Could not find map. Please check your access link.',
'If you want more information, you may contact administrator or contact us at: workadventure@thecodingmachine.com'), this.scene);
} else { } else {
ErrorScene.showError(err, this.scene); ErrorScene.showError(err, this.scene);
} }

View File

@ -52,7 +52,7 @@ export class ErrorScene extends Phaser.Scene {
this.subTitleField = new TextField(this, this.game.renderer.width / 2, this.game.renderer.height / 2 + 24, this.subTitle); this.subTitleField = new TextField(this, this.game.renderer.width / 2, this.game.renderer.height / 2 + 24, this.subTitle);
this.messageField = this.add.text(this.game.renderer.width / 2, this.game.renderer.height / 2 + 38, this.message, { this.messageField = this.add.text(this.game.renderer.width / 2, this.game.renderer.height / 2 + 48, this.message, {
fontFamily: 'Georgia, "Goudy Bookletter 1911", Times, serif', fontFamily: 'Georgia, "Goudy Bookletter 1911", Times, serif',
fontSize: '10px' fontSize: '10px'
}); });

View File

@ -218,6 +218,10 @@ message RefreshRoomMessage{
message WorldFullMessage{ message WorldFullMessage{
} }
message WorldConnexionMessage{
string message = 2;
}
message BanUserMessage{ message BanUserMessage{
string type = 1; string type = 1;
string message = 2; string message = 2;
@ -242,6 +246,7 @@ message ServerToClientMessage {
WorldFullWarningMessage worldFullWarningMessage = 15; WorldFullWarningMessage worldFullWarningMessage = 15;
WorldFullMessage worldFullMessage = 16; WorldFullMessage worldFullMessage = 16;
RefreshRoomMessage refreshRoomMessage = 17; RefreshRoomMessage refreshRoomMessage = 17;
WorldConnexionMessage worldConnexionMessage = 18;
} }
} }

View File

@ -117,15 +117,15 @@ export class IoSocketController {
upgradeAborted.aborted = true; upgradeAborted.aborted = true;
}); });
try { const url = req.getUrl();
const url = req.getUrl(); const query = parse(req.getQuery());
const query = parse(req.getQuery()); const websocketKey = req.getHeader('sec-websocket-key');
const websocketKey = req.getHeader('sec-websocket-key'); const websocketProtocol = req.getHeader('sec-websocket-protocol');
const websocketProtocol = req.getHeader('sec-websocket-protocol'); const websocketExtensions = req.getHeader('sec-websocket-extensions');
const websocketExtensions = req.getHeader('sec-websocket-extensions'); const IPAddress = req.getHeader('x-forwarded-for');
const IPAddress = req.getHeader('x-forwarded-for');
const roomId = query.roomId; const roomId = query.roomId;
try {
if (typeof roomId !== 'string') { if (typeof roomId !== 'string') {
throw new Error('Undefined room ID: '); throw new Error('Undefined room ID: ');
} }
@ -184,13 +184,14 @@ export class IoSocketController {
} else if(err?.response?.status == 403) { } else if(err?.response?.status == 403) {
// If we get an HTTP 404, the world is full. We need to broadcast a special error to the client. // If we get an HTTP 404, the world is full. We need to broadcast a special error to the client.
// we finish immediatly the upgrade then we will close the socket as soon as it starts opening. // we finish immediatly the upgrade then we will close the socket as soon as it starts opening.
res.upgrade({ return res.upgrade({
rejected: true, rejected: true,
message: err?.response?.data.message,
status: err?.response?.status
}, websocketKey, }, websocketKey,
websocketProtocol, websocketProtocol,
websocketExtensions, websocketExtensions,
context); context);
return;
}else{ }else{
throw err; throw err;
} }
@ -207,7 +208,7 @@ export class IoSocketController {
} catch (e) { } catch (e) {
console.log('access not granted for user '+userUuid+' and room '+roomId); console.log('access not granted for user '+userUuid+' and room '+roomId);
console.error(e); console.error(e);
throw new Error('Client cannot acces this ressource.') throw new Error('User cannot acces on this world')
} }
} }
@ -254,21 +255,33 @@ export class IoSocketController {
context); context);
} catch (e) { } catch (e) {
if (e instanceof Error) { /*if (e instanceof Error) {
console.log(e.message); console.log(e.message);
res.writeStatus("401 Unauthorized").end(e.message); res.writeStatus("401 Unauthorized").end(e.message);
} else { } else {
res.writeStatus("500 Internal Server Error").end('An error occurred'); res.writeStatus("500 Internal Server Error").end('An error occurred');
} }*/
return; return res.upgrade({
rejected: true,
message: e.message ? e.message : '500 Internal Server Error'
}, websocketKey,
websocketProtocol,
websocketExtensions,
context);
} }
})(); })();
}, },
/* Handlers */ /* Handlers */
open: (ws) => { open: (ws) => {
if(ws.rejected === true) { if(ws.rejected === true) {
socketManager.emitWorldFullMessage(ws); //FIX ME to use status code
if(ws.message === 'World is full'){
socketManager.emitWorldFullMessage(ws);
}else{
socketManager.emitConnexionErrorMessage(ws, ws.message as string);
}
ws.close(); ws.close();
return;
} }
// Let's join the room // Let's join the room

View File

@ -20,6 +20,7 @@ import {
CharacterLayerMessage, CharacterLayerMessage,
PusherToBackMessage, PusherToBackMessage,
WorldFullMessage, WorldFullMessage,
WorldConnexionMessage,
AdminPusherToBackMessage, AdminPusherToBackMessage,
ServerToAdminClientMessage, ServerToAdminClientMessage,
UserJoinedRoomMessage, UserLeftRoomMessage, AdminMessage, BanMessage, RefreshRoomMessage UserJoinedRoomMessage, UserLeftRoomMessage, AdminMessage, BanMessage, RefreshRoomMessage
@ -560,6 +561,16 @@ export class SocketManager implements ZoneEventListener {
client.send(serverToClientMessage.serializeBinary().buffer, true); client.send(serverToClientMessage.serializeBinary().buffer, true);
} }
public emitConnexionErrorMessage(client: WebSocket, message: string) {
const errorMessage = new WorldConnexionMessage();
errorMessage.setMessage(message);
const serverToClientMessage = new ServerToClientMessage();
serverToClientMessage.setWorldconnexionmessage(errorMessage);
client.send(serverToClientMessage.serializeBinary().buffer, true);
}
private refreshRoomData(roomId: string, versionNumber: number): void { private refreshRoomData(roomId: string, versionNumber: number): void {
const room = this.rooms.get(roomId); const room = this.rooms.get(roomId);
//this function is run for every users connected to the room, so we need to make sure the room wasn't already refreshed. //this function is run for every users connected to the room, so we need to make sure the room wasn't already refreshed.