VaKeR CYBER ARMY
Logo of a company Server : Apache/2.4.41 (Ubuntu)
System : Linux absol.cf 5.4.0-198-generic #218-Ubuntu SMP Fri Sep 27 20:18:53 UTC 2024 x86_64
User : www-data ( 33)
PHP Version : 7.4.33
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Directory :  /var/www/html/gadevoir/server/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /var/www/html/gadevoir/server/GDVServer.js
const Conversation = require("./Conversation");

const mediasoup = require('mediasoup');
const fs = require('fs');
const https = require('https');
const express = require('express');
const socketIO = require('socket.io');
var cors = require('cors');
const uuidv4 = require('uuid').v4;
const User = require('./User');

function GDVServer(config) {
    this.config = config;
    /***
     *
     * @type {User[]}
     */
    this.userList = [];
    this._setupMediaSoup()
        .then(this._setupExpress.bind(this))
        .then(this._setupWebServer.bind(this))
        .then(this._setupSocketSever.bind(this));
}

GDVServer.prototype._setupMediaSoup = function () {
    var server = this;
    return mediasoup.createWorker({
        logLevel: this.config.mediasoup.worker.logLevel,
        logTags: this.config.mediasoup.worker.logTags,
        rtcMinPort: this.config.mediasoup.worker.rtcMinPort,
        rtcMaxPort: this.config.mediasoup.worker.rtcMaxPort
    }).then(function (worker) {
        worker.on('died', () => {
            console.error('mediasoup worker died, exiting in 2 seconds... [pid:%d]', worker.pid);
            setTimeout(() => process.exit(1), 2000);
        });
        server.mediaSoupWorker = worker;
    });
};

GDVServer.prototype._setupExpress = function () {
    this.expressApp = express();
    this.expressApp.use(cors());
    this.expressApp.use(express.json());
    this.expressApp.use(express.static(__dirname));
    this.expressApp.use(this._expressRouteDefault.bind(this));
};

GDVServer.prototype._setupWebServer = function () {
    const config = this.config;
    const { sslKey, sslCrt } = config;
    if (!fs.existsSync(sslKey) || !fs.existsSync(sslCrt)) {
        console.error('SSL files are not found. check your config.js file');
        process.exit(0);
    }
    const tls = {
        cert: fs.readFileSync(sslCrt),
        key: fs.readFileSync(sslKey),
    };
    var webServer = https.createServer(tls, this.expressApp);
    this.webServer = webServer;
    this.webServer.on('error', (err) => {
        console.error('starting web server failed:', err.message);
    });
    return new Promise((resolve) => {
        const { ip, port, host } = config;
        webServer.listen(port, () => {
            console.log('server is running');
            console.log(`open https://${host}:${port} in your web browser`);
            resolve();
        });
    })
};

/***
 *
 * @param {Error} error
 * @param {Request} req
 * @param {Response}res
 * @param {NextFunction} next
 * @private
 */
GDVServer.prototype._expressRouteDefault = function (error, req, res, next) {

};


GDVServer.prototype._setupSocketSever = function () {
    var socketServer = socketIO(this.webServer, {
        serveClient: false,
        path: '/server',
        log: false,
    });
    this.socketServer = socketServer;
    socketServer.on('connection', this._socketClient.bind(this))
};

GDVServer.prototype._socketClient = function (clientSk) {
    clientSk.on('login', this._socketLogin.bind(this, clientSk));
    clientSk.on('disconnect', this._socketDisconnect.bind(this, clientSk));
    clientSk.on('getContactList', this._socketGetContactList.bind(this, clientSk));
    clientSk.on('callTo', this._socketCallTo.bind(this, clientSk));
    clientSk.on('getRouterRtpCapabilities', this._socketGetRouterRtpCapabilities.bind(this, clientSk));
};


GDVServer.prototype._socketLogin = function (clientSk, userData, resolveCb) {
    var userName = userData.userName;
    var password = userData.password;
    var token = userData.token;
    if (!userName || (!password && !token)) {
        resolveCb({
            error: "INVALID_LOGIN_PARAM"
        });
        return;
    }

    var user = this.findUserByName(userName);
    var isNew = false;
    if (user) {
        if (user.online && user.socket.id !== clientSk.id) {
            resolveCb({
                error: "LOGIN_IN_OTHER"
            });
            return;
        }
        else if (user.password === password || user.token === token) {
            user.socket = clientSk;
            user.online = true;
            user.token = Array(32).fill(0).map(function () {
                return '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'[Math.random() * 62 >> 0]
            }).join('');
            console.log("RELOGIN", user.name);
        }
        else {
            resolveCb({
                error: "LOGIN_FAIL"
            });
            return;
        }
    }
    else {
        isNew = true;
        user = new User({
            online: true,
            id: clientSk.id,
            name: userName,
            password: password,
            socket: clientSk,
            token: Array(32).fill(0).map(function () {
                return '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'[Math.random() * 62 >> 0]
            }).join('')
        });
        user.routerSync =  this.mediaSoupWorker.createRouter({ mediaCodecs: this.config.mediasoup.router.mediaCodecs })
            .then(function (router) {
            user.router = router;
            return router;
        });

        this.userList.push(user);
        console.log("NEW_USER", user.name);
    }
    this.notifyOnlineToOther(user);
    resolveCb({
        isNew: isNew,
        id: user.id,
        name: userName,
        token: user.token
    });
};


GDVServer.prototype._socketGetContactList = function (clientSk, data, resolveCb) {
    var user = this.findUserBySocketId(clientSk.id);
    if (user)
        resolveCb(this.getUserInfoList().filter(function (item) {
            return item.name !== user.name;
        }));
    else resolveCb({
        error: "NO_LOGIN"
    })
};

GDVServer.prototype._socketCallTo = function (socketSk, data) {
    var server = this;
    var user = this.findUserBySocketId(socketSk.id);
    var destUser = this.findUserByName(data.userName);
    var destUserName = data.userName;
    var conversationId = data.conversationId;
    var timeout;
    if (user) {
        if (destUser) {
            if (destUser.online && destUser.socket) {
                timeout = setTimeout(function () {
                    socketSk.emit("outcome_response", { error: "USER_NOT_RESPONSE", userName: destUserName })
                }, 20000);

                function incomeResponseCb(data) {
                    if (data.conversationId === conversationId) {
                        clearTimeout(timeout);
                        destUser.socket.off('income_response', incomeResponseCb);
                        user.socket.off('outgoing_cancel', outgoingCancelCb);
                        if (data.answer === "ACCEPT") {
                            var conversation = new Conversation(server, {
                                outgoingUser: user,
                                incomeUser: destUser,
                                conversationId: conversationId
                            });
                            conversation.start();
                        }
                        else {

                        }
                        socketSk.emit("outgoing_response", {
                            answer: data.answer,
                            userName: destUserName,
                            conversationId: conversationId
                        });
                    }
                }

                function outgoingCancelCb(data) {
                    if (data.conversationId === conversationId) {
                        clearTimeout(timeout);
                        destUser.socket.off('income_response', incomeResponseCb);
                        user.socket.off('outgoing_cancel', outgoingCancelCb);
                        destUser.socket.emit('income_cancel', { conversationId: conversationId });
                    }
                }

                destUser.socket.on('income_response', incomeResponseCb);
                user.socket.on('outgoing_cancel', outgoingCancelCb);
                destUser.socket.emit('income', {
                    userName: user.name,
                    type: data.type,
                    conversationId: conversationId
                });
            }
            else {
                socketSk.emit('outgoing_response', {
                    error: "USER_OFFLINE",
                    userName: destUserName,
                    conversationId: conversationId
                });
            }
        }
        else {
            socketSk.emit("outgoing_response", {
                error: "USER_NOT_EXIST",
                userName: destUserName,
                conversationId: conversationId
            });
        }
    }
    else socketSk.emit('outgoing_response', {
        error: "NOT_LOGIN",
        userName: destUserName,
        conversationId: conversationId
    });
};

GDVServer.prototype._socketGetRouterRtpCapabilities = function (clientSk, data, resolveCb) {
    var user = this.findUserBySocketId(clientSk.id);
    user.routerSync.then(function (router) {
        resolveCb(router.rtpCapabilities);
    })
};

GDVServer.prototype._socketDisconnect = function (clientSk) {
    var user = this.findUserBySocketId(clientSk.id);
    if (user) {
        user.online = false;
        user.socket = null;
        this.notifyOfflineToOther(user);
        console.log("OFFLINE", user.name);
    }
};


GDVServer.prototype.createWebRtcTransport = function (user) {
    const {
        maxIncomingBitrate,
        initialAvailableOutgoingBitrate
    } = this.config.mediasoup.webRtcTransport;

    const res = {};
    var server = this;
    return user.routerSync.then(function (router) {
        return router.createWebRtcTransport({
            listenIps: server.config.mediasoup.webRtcTransport.listenIps,
            enableUdp: true,
            enableTcp: true,
            preferUdp: true,
            initialAvailableOutgoingBitrate,
        }).then(function (transport) {
            res.transport = transport;
            if (maxIncomingBitrate) {
                try {
                    return transport.setMaxIncomingBitrate(maxIncomingBitrate);
                } catch (error) {
                }
            }
        }).then(function () {
            res.params = {
                id: res.transport.id,
                iceParameters: res.transport.iceParameters,
                iceCandidates: res.transport.iceCandidates,
                dtlsParameters: res.transport.dtlsParameters
            }
            return res;
        });
    });
};


GDVServer.prototype.findUserByName = function (name) {
    return this.userList.find(function (item) {
        return item.name === name;
    });
};


GDVServer.prototype.findUserById = function (id) {
    return this.userList.find(function (item) {
        return item.id = id;
    });
};

GDVServer.prototype.findUserBySocketId = function (socketId) {
    return this.userList.find(function (item) {
        return item.socket && item.socket.id === socketId;
    });
};

GDVServer.prototype.notifyOnlineToOther = function (user) {
    var userInfo = user.toPublicInfo();
    this.userList.forEach(function (item) {
        if (item.id === user.id) return;
        if (item.online && item.socket) {
            item.socket.emit('other_online', userInfo)
        }
    });
};

GDVServer.prototype.notifyOfflineToOther = function (user) {
    this.userList.forEach(function (item) {
        var userInfo = user.toPublicInfo();
        if (item.id === user.id) return;
        if (item.online && item.socket) {
            item.socket.emit('other_offline', userInfo);
        }
    });
};

GDVServer.prototype.getUserInfoList = function () {
    return this.userList.map(function (item) {
        return item.toPublicInfo();
    })
}


module.exports = GDVServer;

VaKeR 2022