RED.multiplayer = (function () { // sessionId - used to identify sessions across websocket reconnects let sessionId let headerWidget // Map of session id to { session:'', user:{}, location:{}} let connections = {} // Map of username to { user:{}, connections:[] } let users = {} function addUserConnection (connection) { if (connections[connection.session]) { // This is an existing connection that has been authenticated const existingConnection = connections[connection.session] if (existingConnection.user.username !== connection.user.username) { removeUserButton(users[existingConnection.user.username]) } } connections[connection.session] = connection const user = users[connection.user.username] = users[connection.user.username] || { user: connection.user, connections: [] } connection.location = connection.location || {} user.connections.push(connection) if (connection.user.username === RED.settings.user?.username || connection.session === sessionId ) { // This is the current user - do not add a extra button for them } else { if (user.connections.length === 1) { if (user.button) { clearTimeout(user.inactiveTimeout) clearTimeout(user.removeTimeout) user.button.removeClass('inactive') } else { addUserButton(user) } } } } function removeUserConnection (session, isDisconnected) { const connection = connections[session] delete connections[session] const user = users[connection.user.username] const i = user.connections.indexOf(connection) user.connections.splice(i, 1) if (isDisconnected) { removeUserButton(user) } else { if (user.connections.length === 0) { // Give the user 5s to reconnect before marking inactive user.inactiveTimeout = setTimeout(() => { user.button.addClass('inactive') // Give the user further 20 seconds to reconnect before removing them // from the user toolbar entirely user.removeTimeout = setTimeout(() => { removeUserButton(user) }, 20000) }, 5000) } } } function addUserButton (user) { user.button = $('
') .attr('data-username', user.user.username) .prependTo("#red-ui-multiplayer-user-list"); var button = user.button.find("button") button.on('click', function () { RED.popover.create({ target:button, trigger: 'modal', interactive: true, width: "250px", direction: 'bottom', content: () => { const content = $('