MAJOR OVERHAUL: Working WebSocket client! No translation server, yet.
This commit is contained in:
parent
e7b9836df6
commit
394eb42fbc
3
.babelrc
3
.babelrc
@ -1,3 +1,4 @@
|
|||||||
{
|
{
|
||||||
"presets": ["@babel/preset-env"]
|
"presets": ["@babel/preset-env"],
|
||||||
|
"plugins": ["@babel/plugin-transform-runtime"]
|
||||||
}
|
}
|
||||||
|
2
LICENSE
2
LICENSE
@ -1,5 +1,5 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
Copyright (c) 2016 Evert Prants
|
Copyright (c) 2016-2020 Evert Prants
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
19
globals.js
Normal file
19
globals.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
const fs = require('fs')
|
||||||
|
const path = require('path')
|
||||||
|
const toml = require('toml')
|
||||||
|
const filename = path.join(__dirname, 'client.config.toml')
|
||||||
|
const pkg = require(path.join(__dirname, 'package.json'))
|
||||||
|
|
||||||
|
let config
|
||||||
|
|
||||||
|
try {
|
||||||
|
config = toml.parse(fs.readFileSync(filename))
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
config.client.version = pkg.version
|
||||||
|
config.client.description = pkg.description
|
||||||
|
|
||||||
|
module.exports = config
|
4744
package-lock.json
generated
4744
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
34
package.json
34
package.json
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "teemantirc",
|
"name": "teemantirc",
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"description": "Web-based IRC client",
|
"description": "A Web-based IRC client",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
@ -22,30 +22,32 @@
|
|||||||
"author": "Evert",
|
"author": "Evert",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"express": "^4.16.4",
|
"express": "^4.17.1",
|
||||||
"seedrandom": "^2.4.4",
|
"toml": "^2.3.6",
|
||||||
"socket.io": "^2.2.0",
|
"ws": "^7.2.1"
|
||||||
"toml": "^2.3.5"
|
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git://gitlab.icynet.eu/IcyNetwork/teemant.git"
|
"url": "git://gitlab.icynet.eu/IcyNetwork/teemant.git"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/cli": "^7.2.3",
|
"@babel/cli": "^7.8.4",
|
||||||
"@babel/core": "^7.2.2",
|
"@babel/core": "^7.8.4",
|
||||||
"@babel/preset-env": "^7.2.3",
|
"@babel/plugin-transform-runtime": "^7.8.3",
|
||||||
"babel-loader": "^8.0.5",
|
"@babel/preset-env": "^7.8.4",
|
||||||
"concurrently": "^4.1.0",
|
"@babel/runtime": "^7.8.4",
|
||||||
"copy-webpack-plugin": "^4.6.0",
|
"babel-loader": "^8.0.6",
|
||||||
"css-loader": "^2.1.0",
|
"concurrently": "^4.1.2",
|
||||||
|
"copy-webpack-plugin": "^5.1.1",
|
||||||
|
"css-loader": "^2.1.1",
|
||||||
"file-loader": "^3.0.1",
|
"file-loader": "^3.0.1",
|
||||||
"html-webpack-plugin": "^3.2.0",
|
"html-webpack-plugin": "^3.2.0",
|
||||||
"mini-css-extract-plugin": "^0.5.0",
|
"mini-css-extract-plugin": "^0.5.0",
|
||||||
"standard": "^12.0.1",
|
"standard": "^12.0.1",
|
||||||
"stylus": "^0.54.5",
|
"stylus": "^0.54.7",
|
||||||
"stylus-loader": "^3.0.2",
|
"stylus-loader": "^3.0.2",
|
||||||
"webpack": "^4.28.1",
|
"webpack": "^4.41.5",
|
||||||
"webpack-command": "^0.4.2"
|
"webpack-cli": "^3.3.10",
|
||||||
|
"seedrandom": "^2.4.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,14 +3,8 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
<title>TeemantIRC</title>
|
<title>TeemantIRC</title>
|
||||||
|
|
||||||
<script src="//twemoji.maxcdn.com/2/twemoji.min.js?11.2"></script>
|
<script src="//twemoji.maxcdn.com/2/twemoji.min.js?11.2"></script>
|
||||||
|
|
||||||
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
|
|
||||||
<script type="text/javascript" src="main.js"></script>
|
|
||||||
|
|
||||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" type="text/css">
|
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" type="text/css">
|
||||||
<link rel="stylesheet" type="text/css" href="style/layout.css">
|
<link rel="stylesheet" type="text/css" href="style/layout.css">
|
||||||
<link rel="stylesheet" type="text/css" href="style/theme_default.css" id="theme_stylesheet">
|
<link rel="stylesheet" type="text/css" href="style/theme_default.css" id="theme_stylesheet">
|
||||||
|
@ -1,8 +1,134 @@
|
|||||||
|
/* global WebSocket */
|
||||||
import { EventEmitter } from 'events'
|
import { EventEmitter } from 'events'
|
||||||
import net from 'net'
|
|
||||||
import tls from 'tls'
|
|
||||||
import util from 'util'
|
|
||||||
import parse from './parser'
|
import parse from './parser'
|
||||||
|
import { format } from 'util'
|
||||||
|
|
||||||
|
let translatorSocket
|
||||||
|
|
||||||
|
class FakeSocket {
|
||||||
|
constructor (server, socket) {
|
||||||
|
this.open = true
|
||||||
|
this.server = server
|
||||||
|
this.socket = socket
|
||||||
|
this.handlers = []
|
||||||
|
this.socket.addEventListener('message', (msg) => {
|
||||||
|
let tm = msg.split(' ')
|
||||||
|
if (tm[0] === 'TRANSLATOR') {
|
||||||
|
if ((tm[1] === 'CLOSE' || tm[1] === 'ERROR') && tm[2] === this.server) {
|
||||||
|
return this._socketClosed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tm[0] === server) {
|
||||||
|
this._handle('message', tm.slice(1).join(' '))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.socket.addEventListener('close', () => {
|
||||||
|
this._socketClosed()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
send () {
|
||||||
|
if (!this.open) return
|
||||||
|
this.socket.send(this.server + ' ' + format.apply(Array.prototype.slice.call(arguments)))
|
||||||
|
}
|
||||||
|
|
||||||
|
addEventListener (type, fn) {
|
||||||
|
this.handlers.push({ target: type, fn })
|
||||||
|
}
|
||||||
|
|
||||||
|
_socketClosed () {
|
||||||
|
this.open = false
|
||||||
|
for (let a in this.handlers) {
|
||||||
|
let at = this.handlers[a]
|
||||||
|
if (at.target === 'close') {
|
||||||
|
at.fn.apply(this, [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_handle (ev) {
|
||||||
|
if (!this.open) return
|
||||||
|
for (let a in this.handlers) {
|
||||||
|
let ap = this.handlers[a]
|
||||||
|
if (ap.target === ev) {
|
||||||
|
ap.fn.apply(this.socket, Array.prototype.slice.call(arguments, 1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close () {
|
||||||
|
this.open = false
|
||||||
|
this.socket.send('TRANSLATOR DISCONNECT ' + this.server)
|
||||||
|
}
|
||||||
|
|
||||||
|
static addListenerPassthrough (fs, type) {
|
||||||
|
fs.socket.addEventListener(type, () => {
|
||||||
|
this._handle.apply(this, [type].concat(arguments))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function _waitOpen (s) {
|
||||||
|
let o
|
||||||
|
let c
|
||||||
|
|
||||||
|
try {
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
o = function () {
|
||||||
|
console.log('removing events', o, c)
|
||||||
|
s.removeEventListener('close', c)
|
||||||
|
s.removeEventListener('open', o)
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
s.addEventListener('open', o)
|
||||||
|
c = function (err) {
|
||||||
|
reject(err)
|
||||||
|
}
|
||||||
|
s.addEventListener('close', c)
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
async function _trySocket (address, port, ssl, useTranslator) {
|
||||||
|
// Attempt a direct ws connection
|
||||||
|
let proto = 'ws'
|
||||||
|
if (ssl) proto = 'wss'
|
||||||
|
|
||||||
|
if (!useTranslator) {
|
||||||
|
let conn = address
|
||||||
|
if (port && (port < 6000 || port > 7000)) {
|
||||||
|
conn = address + ':' + port
|
||||||
|
}
|
||||||
|
let tSock = new WebSocket(proto + '://' + conn)
|
||||||
|
try {
|
||||||
|
console.log('Waiting to open')
|
||||||
|
await _waitOpen(tSock)
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
console.error('Waiting to open failed')
|
||||||
|
return _trySocket(address, port, ssl, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
tSock.open = true
|
||||||
|
tSock.addEventListener('close', () => { tSock.open = false })
|
||||||
|
|
||||||
|
return tSock
|
||||||
|
}
|
||||||
|
|
||||||
|
if (translatorSocket) {
|
||||||
|
translatorSocket.send('TRANSLATOR SERVER ' + address + ' ' + port + (ssl ? ' SSL' : ''))
|
||||||
|
return new FakeSocket(address, translatorSocket)
|
||||||
|
}
|
||||||
|
|
||||||
|
translatorSocket = new WebSocket(`ws${window.location.protocol === 'https:' ? 's' : ''}://${window.location.host}`)
|
||||||
|
console.log('Opening translator socket')
|
||||||
|
await _waitOpen(translatorSocket)
|
||||||
|
return new FakeSocket(address, translatorSocket)
|
||||||
|
}
|
||||||
|
|
||||||
class IRCConnectionHandler {
|
class IRCConnectionHandler {
|
||||||
constructor (connection) {
|
constructor (connection) {
|
||||||
@ -122,11 +248,11 @@ class IRCConnectionHandler {
|
|||||||
let resp = '\x01' + line[0] + ' %s\x01'
|
let resp = '\x01' + line[0] + ' %s\x01'
|
||||||
|
|
||||||
if (line[0] === 'PING' && line[1] != null && line[1] !== '') {
|
if (line[0] === 'PING' && line[1] != null && line[1] !== '') {
|
||||||
resp = util.format(resp, line.slice(1).join(' '))
|
resp = format(resp, line.slice(1).join(' '))
|
||||||
} else if (line[0] === 'CLIENTINFO') {
|
} else if (line[0] === 'CLIENTINFO') {
|
||||||
resp = util.format(resp, 'CLIENTINFO PING ' + Object.keys(this.conn.extras.ctcps).join(' '))
|
resp = format(resp, 'CLIENTINFO PING ' + Object.keys(this.conn.extras.ctcps).join(' '))
|
||||||
} else if (this.conn.extras.ctcps && this.conn.extras.ctcps[line[0]] != null) {
|
} else if (this.conn.extras.ctcps && this.conn.extras.ctcps[line[0]] != null) {
|
||||||
resp = util.format(resp, this.conn.extras.ctcps[line[0]](data, this.conn))
|
resp = format(resp, this.conn.extras.ctcps[line[0]](data, this.conn))
|
||||||
} else {
|
} else {
|
||||||
resp = null
|
resp = null
|
||||||
}
|
}
|
||||||
@ -376,6 +502,7 @@ class IRCConnectionHandler {
|
|||||||
case '323':
|
case '323':
|
||||||
case '351':
|
case '351':
|
||||||
case '381':
|
case '381':
|
||||||
|
case '489':
|
||||||
this.conn.emit('pass_to_client', {
|
this.conn.emit('pass_to_client', {
|
||||||
type: 'server_message', messageType: 'regular', message: line.trailing, server: serverName, from: realServerName
|
type: 'server_message', messageType: 'regular', message: line.trailing, server: serverName, from: realServerName
|
||||||
})
|
})
|
||||||
@ -471,7 +598,7 @@ class IRCConnectionHandler {
|
|||||||
// start whois queue
|
// start whois queue
|
||||||
list = {
|
list = {
|
||||||
nickname: line.arguments[1],
|
nickname: line.arguments[1],
|
||||||
hostmask: util.format('%s!%s@%s', line.arguments[1], line.arguments[2], line.arguments[3]),
|
hostmask: format('%s!%s@%s', line.arguments[1], line.arguments[2], line.arguments[3]),
|
||||||
realname: line.trailing || ''
|
realname: line.trailing || ''
|
||||||
}
|
}
|
||||||
this.whoisManage(line.arguments[1], list)
|
this.whoisManage(line.arguments[1], list)
|
||||||
@ -620,39 +747,19 @@ class IRCConnection extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
connect () {
|
connect () {
|
||||||
this.socket = (this.config.secure ? tls : net).connect({
|
async function wrapped (argument) {
|
||||||
port: this.config.port,
|
try {
|
||||||
host: this.config.server,
|
this.socket = await _trySocket(this.config.server, this.config.port, this.config.secure)
|
||||||
rejectUnauthorized: this.config.rejectUnauthorized
|
} catch (e) {
|
||||||
}, () => {
|
this.emit('connerror', { type: 'sock_error', message: 'A socket error occured.' })
|
||||||
this.connected = true
|
throw e
|
||||||
this.authenticate()
|
|
||||||
})
|
|
||||||
|
|
||||||
this.socket.setEncoding(this.globalConfig.encoding)
|
|
||||||
this.socket.setTimeout(this.globalConfig.timeout)
|
|
||||||
|
|
||||||
this.socket.on('error', (data) => {
|
|
||||||
this.emit('connerror', { type: 'sock_error', message: 'A socket error occured.', raw: data })
|
|
||||||
})
|
|
||||||
|
|
||||||
this.socket.on('lookup', (err, address, family, host) => {
|
|
||||||
if (err) {
|
|
||||||
this.emit('connerror', { type: 'resolve_error', message: 'Failed to resolve host.' })
|
|
||||||
} else {
|
|
||||||
this.emit('lookup', { address: address, family: address, host: host })
|
|
||||||
this.config.address = address
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
let buffer = ''
|
this.socket.addEventListener('message', (e) => {
|
||||||
this.socket.on('data', (chunk) => {
|
let line = e.data
|
||||||
buffer += chunk
|
|
||||||
let data = buffer.split('\r\n')
|
|
||||||
buffer = data.pop()
|
|
||||||
data.forEach((line) => {
|
|
||||||
if (line.indexOf('PING') === 0) {
|
if (line.indexOf('PING') === 0) {
|
||||||
this.write('PONG %s\r\n', line.substring(4))
|
console.log('%s server pinged us (%s)', new Date(), line)
|
||||||
|
this.write('PONG %s', line.substring(4))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -668,9 +775,8 @@ class IRCConnection extends EventEmitter {
|
|||||||
console.error(e.stack)
|
console.error(e.stack)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
|
||||||
|
|
||||||
this.socket.on('close', (data) => {
|
this.socket.addEventListener('close', (data) => {
|
||||||
if (!this.queue['close']) {
|
if (!this.queue['close']) {
|
||||||
this.emit('closed', { type: 'sock_closed', raw: data, message: 'Connection closed.' })
|
this.emit('closed', { type: 'sock_closed', raw: data, message: 'Connection closed.' })
|
||||||
}
|
}
|
||||||
@ -678,11 +784,17 @@ class IRCConnection extends EventEmitter {
|
|||||||
this.connected = false
|
this.connected = false
|
||||||
this.authenticated = false
|
this.authenticated = false
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.connected = true
|
||||||
|
this.authenticate()
|
||||||
|
}
|
||||||
|
|
||||||
|
return wrapped.call(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
authenticate () {
|
authenticate () {
|
||||||
if (this.config.password) {
|
if (this.config.password) {
|
||||||
this.write('PASS %s\r\n', this.config.password)
|
this.write('PASS %s', this.config.password)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.extras.authenticationSteps) {
|
if (this.extras.authenticationSteps) {
|
||||||
@ -692,8 +804,23 @@ class IRCConnection extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.write('USER %s 8 * :%s\r\n', this.config.username, this.config.realname)
|
this.write('USER %s 8 * :%s', this.config.username, this.config.realname)
|
||||||
this.write('NICK %s\r\n', this.config.nickname)
|
this.write('NICK %s', this.config.nickname)
|
||||||
|
|
||||||
|
this.bindFinal()
|
||||||
|
this.sendPing()
|
||||||
|
}
|
||||||
|
|
||||||
|
bindFinal () {
|
||||||
|
this.on('userinput', (data) => {
|
||||||
|
return this.handler.handleUserLine(data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
sendPing () {
|
||||||
|
if (!this.connected) return
|
||||||
|
this.write('PING :' + this.data.actualServer)
|
||||||
|
setTimeout(() => this.sendPing(), 5000)
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnect (message) {
|
disconnect (message) {
|
||||||
@ -703,17 +830,17 @@ class IRCConnection extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.queue['close'] = true
|
this.queue['close'] = true
|
||||||
this.write('QUIT :%s\r\n', (message != null ? message : this.globalConfig.default_quit_msg))
|
this.write('QUIT :%s', (message != null ? message : this.globalConfig.default_quit_msg))
|
||||||
}
|
}
|
||||||
|
|
||||||
write () {
|
write () {
|
||||||
let message = util.format.apply(null, arguments)
|
let message = format.apply(null, arguments)
|
||||||
if (!this.connected) {
|
if (!this.connected) {
|
||||||
return this.emit('connerror', { type: 'sock_closed', message: 'Connection is closed.' })
|
return this.emit('connerror', { type: 'sock_closed', message: 'Connection is closed.' })
|
||||||
}
|
}
|
||||||
|
|
||||||
this.socket.write(message + '\r\n')
|
this.socket.send(message + '\r\n')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = IRCConnection
|
export { IRCConnection }
|
396
src/js/main.js
396
src/js/main.js
@ -1,13 +1,16 @@
|
|||||||
/* global irc, twemoji, io */
|
/* global irc, twemoji, globalConfig */
|
||||||
/* eslint-disable no-useless-escape, no-control-regex */
|
/* eslint-disable no-useless-escape, no-control-regex */
|
||||||
import { el, span, sf, formatDate, removeStr, match, serialize, objectGetKey, rand, addClass, removeClass, toggleClass } from './utility'
|
|
||||||
import stylize from './colorparser'
|
|
||||||
import seedrandom from 'seedrandom'
|
import seedrandom from 'seedrandom'
|
||||||
|
|
||||||
const themes = require('./theme.js')
|
import { el, span, sf, formatDate, removeStr, match, serialize, objectGetKey, rand, addClass, removeClass, toggleClass } from './utility'
|
||||||
|
import stylize from './colorparser'
|
||||||
|
import themes from './theme'
|
||||||
|
import { IRCConnection } from './irc'
|
||||||
|
|
||||||
|
const gcfg = Object.assign({}, globalConfig)
|
||||||
|
|
||||||
window.irc = {
|
window.irc = {
|
||||||
socketUp: false,
|
|
||||||
primaryFrame: null,
|
primaryFrame: null,
|
||||||
config: {
|
config: {
|
||||||
colors: true,
|
colors: true,
|
||||||
@ -25,7 +28,17 @@ window.irc = {
|
|||||||
serverData: {},
|
serverData: {},
|
||||||
serverChatQueue: {},
|
serverChatQueue: {},
|
||||||
chatType: 'simple',
|
chatType: 'simple',
|
||||||
documentTitle: 'TeemantIRC'
|
documentTitle: 'TeemantIRC',
|
||||||
|
handler: null
|
||||||
|
}
|
||||||
|
|
||||||
|
const customCTCPs = {
|
||||||
|
VERSION: function (data, connection) {
|
||||||
|
return `TeemantIRC - ${gcfg.description} ver. ${gcfg.version} - https://teemant.icynet.eu/`
|
||||||
|
},
|
||||||
|
SOURCE: function (data, connection) {
|
||||||
|
return 'https://gitlab.icynet.eu/IcyNetwork/teemant'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const clientdom = { connector: {}, settings: {} }
|
const clientdom = { connector: {}, settings: {} }
|
||||||
@ -302,12 +315,18 @@ let composer = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sendToServer (server, obj) {
|
||||||
|
let i = irc.handler.getClientByActualServer(server)
|
||||||
|
if (!i) throw new Error('Invalid connection ' + server)
|
||||||
|
i.emit('userinput', obj)
|
||||||
|
}
|
||||||
|
|
||||||
// onclick food
|
// onclick food
|
||||||
window.irc.joinChannel = (channel) => {
|
window.irc.joinChannel = (channel) => {
|
||||||
let buf = irc.chat.getActiveChatBuffer()
|
let buf = irc.chat.getActiveChatBuffer()
|
||||||
if (!buf || !buf.server) return
|
if (!buf || !buf.server) return
|
||||||
|
|
||||||
irc.socket.emit('userinput', { command: 'join', server: buf.server, message: '', arguments: [channel] })
|
sendToServer(buf.server, { command: 'join', message: '', arguments: [channel] })
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,12 +352,12 @@ let commands = {
|
|||||||
execute: function (buffer, handler, command, message, listargs) {
|
execute: function (buffer, handler, command, message, listargs) {
|
||||||
if (!listargs[1]) {
|
if (!listargs[1]) {
|
||||||
if (!buffer.alive) {
|
if (!buffer.alive) {
|
||||||
irc.socket.emit('userinput', { command: 'join', server: buffer.server, message: '', arguments: [buffer.name] })
|
sendToServer(buffer.server, { command: 'join', message: '', arguments: [buffer.name] })
|
||||||
} else {
|
} else {
|
||||||
handler.commandError(buffer, listargs[0].toUpperCase() + ': Missing parameters!')
|
handler.commandError(buffer, listargs[0].toUpperCase() + ': Missing parameters!')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
irc.socket.emit('userinput', { command: 'join', server: buffer.server, message: '', arguments: [listargs[1]] })
|
sendToServer(buffer.server, { command: 'join', message: '', arguments: [listargs[1]] })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
description: '<channel> - Join a channel'
|
description: '<channel> - Join a channel'
|
||||||
@ -347,7 +366,7 @@ let commands = {
|
|||||||
part: {
|
part: {
|
||||||
execute: function (buffer, handler, command, message, listargs) {
|
execute: function (buffer, handler, command, message, listargs) {
|
||||||
if (!listargs[1] && buffer.type === 'channel') {
|
if (!listargs[1] && buffer.type === 'channel') {
|
||||||
irc.socket.emit('userinput', { command: 'part', server: buffer.server, message: '', arguments: [buffer.name] })
|
sendToServer(buffer.server, { command: 'part', message: '', arguments: [buffer.name] })
|
||||||
} else if (buffer.type !== 'channel') {
|
} else if (buffer.type !== 'channel') {
|
||||||
handler.commandError(buffer, listargs[0].toUpperCase() + ': Buffer is not a channel.')
|
handler.commandError(buffer, listargs[0].toUpperCase() + ': Buffer is not a channel.')
|
||||||
} else if (listargs[1]) {
|
} else if (listargs[1]) {
|
||||||
@ -356,10 +375,10 @@ let commands = {
|
|||||||
if (listargs[2]) {
|
if (listargs[2]) {
|
||||||
msg = listargs.slice(2).join(' ')
|
msg = listargs.slice(2).join(' ')
|
||||||
}
|
}
|
||||||
irc.socket.emit('userinput', { command: 'part', server: buffer.server, message: msg, arguments: [listargs[1]] })
|
sendToServer(buffer.server, { command: 'part', message: msg, arguments: [listargs[1]] })
|
||||||
} else {
|
} else {
|
||||||
if (buffer.type === 'channel') {
|
if (buffer.type === 'channel') {
|
||||||
irc.socket.emit('userinput', { command: 'part', server: buffer.server, message: listargs.slice(1).join(' '), arguments: [buffer.name] })
|
sendToServer(buffer.server, { command: 'part', message: listargs.slice(1).join(' '), arguments: [buffer.name] })
|
||||||
} else {
|
} else {
|
||||||
handler.commandError(buffer, listargs[0].toUpperCase() + ': Buffer is not a channel.')
|
handler.commandError(buffer, listargs[0].toUpperCase() + ': Buffer is not a channel.')
|
||||||
}
|
}
|
||||||
@ -373,7 +392,7 @@ let commands = {
|
|||||||
topic: {
|
topic: {
|
||||||
execute: function (buffer, handler, command, message, listargs) {
|
execute: function (buffer, handler, command, message, listargs) {
|
||||||
if (!listargs[1] && buffer.type === 'channel') {
|
if (!listargs[1] && buffer.type === 'channel') {
|
||||||
irc.socket.emit('userinput', { command: 'topic', server: buffer.server, message: '', arguments: [buffer.name] })
|
sendToServer(buffer.server, { command: 'topic', message: '', arguments: [buffer.name] })
|
||||||
} else if (buffer.type !== 'channel') {
|
} else if (buffer.type !== 'channel') {
|
||||||
handler.commandError(buffer, listargs[0].toUpperCase() + ': Buffer is not a channel.')
|
handler.commandError(buffer, listargs[0].toUpperCase() + ': Buffer is not a channel.')
|
||||||
} else if (listargs[1]) {
|
} else if (listargs[1]) {
|
||||||
@ -382,10 +401,10 @@ let commands = {
|
|||||||
if (listargs[2]) {
|
if (listargs[2]) {
|
||||||
msg = listargs.slice(2).join(' ')
|
msg = listargs.slice(2).join(' ')
|
||||||
}
|
}
|
||||||
irc.socket.emit('userinput', { command: 'topic', server: buffer.server, message: msg, arguments: [listargs[1]] })
|
sendToServer(buffer.server, { command: 'topic', message: msg, arguments: [listargs[1]] })
|
||||||
} else {
|
} else {
|
||||||
if (buffer.type === 'channel') {
|
if (buffer.type === 'channel') {
|
||||||
irc.socket.emit('userinput', { command: 'topic', server: buffer.server, message: listargs.slice(1).join(' '), arguments: [buffer.name] })
|
sendToServer(buffer.server, { command: 'topic', message: listargs.slice(1).join(' '), arguments: [buffer.name] })
|
||||||
} else {
|
} else {
|
||||||
handler.commandError(buffer, listargs[0].toUpperCase() + ': Buffer is not a channel.')
|
handler.commandError(buffer, listargs[0].toUpperCase() + ': Buffer is not a channel.')
|
||||||
}
|
}
|
||||||
@ -406,9 +425,8 @@ let commands = {
|
|||||||
return handler.commandError(buffer, listargs[0].toUpperCase() + ': Missing parameter <user>!')
|
return handler.commandError(buffer, listargs[0].toUpperCase() + ': Missing parameter <user>!')
|
||||||
}
|
}
|
||||||
|
|
||||||
irc.socket.emit('userinput', {
|
sendToServer(buffer.server, {
|
||||||
command: 'kick',
|
command: 'kick',
|
||||||
server: buffer.server,
|
|
||||||
message: listargs.slice(2).join(' '),
|
message: listargs.slice(2).join(' '),
|
||||||
arguments: [buffer.name, listargs[1]]
|
arguments: [buffer.name, listargs[1]]
|
||||||
})
|
})
|
||||||
@ -418,7 +436,7 @@ let commands = {
|
|||||||
|
|
||||||
quit: {
|
quit: {
|
||||||
execute: function (buffer, handler, command, message, listargs) {
|
execute: function (buffer, handler, command, message, listargs) {
|
||||||
irc.socket.emit('userinput', { command: 'quit', server: buffer.server, message: listargs.slice(1).join(' '), arguments: [] })
|
sendToServer(buffer.server, { command: 'quit', message: listargs.slice(1).join(' '), arguments: [] })
|
||||||
},
|
},
|
||||||
description: '[<message>] - Quit the current server with message.',
|
description: '[<message>] - Quit the current server with message.',
|
||||||
aliases: ['exit']
|
aliases: ['exit']
|
||||||
@ -426,7 +444,7 @@ let commands = {
|
|||||||
|
|
||||||
mode: {
|
mode: {
|
||||||
execute: function (buffer, handler, command, message, listargs) {
|
execute: function (buffer, handler, command, message, listargs) {
|
||||||
irc.socket.emit('userinput', { command: 'mode', server: buffer.server, message: listargs.slice(1).join(' '), arguments: [] })
|
sendToServer(buffer.server, { command: 'mode', message: listargs.slice(1).join(' '), arguments: [] })
|
||||||
},
|
},
|
||||||
description: '[target] [mode] - Set/remove mode of target.'
|
description: '[target] [mode] - Set/remove mode of target.'
|
||||||
},
|
},
|
||||||
@ -441,7 +459,7 @@ let commands = {
|
|||||||
listargs[1] = buffer.name
|
listargs[1] = buffer.name
|
||||||
}
|
}
|
||||||
|
|
||||||
irc.socket.emit('userinput', { command: 'privmsg', server: buffer.server, message: listargs.slice(2).join(' '), arguments: [listargs[1]] })
|
sendToServer(buffer.server, { command: 'privmsg', message: listargs.slice(2).join(' '), arguments: [listargs[1]] })
|
||||||
},
|
},
|
||||||
description: '<target> <message> - Sends a message to target.',
|
description: '<target> <message> - Sends a message to target.',
|
||||||
aliases: ['privmsg', 'q', 'query', 'say']
|
aliases: ['privmsg', 'q', 'query', 'say']
|
||||||
@ -459,7 +477,7 @@ let commands = {
|
|||||||
|
|
||||||
listargs[2] = listargs[2].toUpperCase()
|
listargs[2] = listargs[2].toUpperCase()
|
||||||
|
|
||||||
irc.socket.emit('userinput', { command: 'ctcp', server: buffer.server, message: listargs.slice(2).join(' '), arguments: listargs.slice(1) })
|
sendToServer(buffer.server, { command: 'ctcp', message: listargs.slice(2).join(' '), arguments: listargs.slice(1) })
|
||||||
},
|
},
|
||||||
description: '<target> <type> [arguments] - Sends a CTCP request to target.'
|
description: '<target> <type> [arguments] - Sends a CTCP request to target.'
|
||||||
},
|
},
|
||||||
@ -474,9 +492,8 @@ let commands = {
|
|||||||
listargs[1] = buffer.name
|
listargs[1] = buffer.name
|
||||||
}
|
}
|
||||||
|
|
||||||
irc.socket.emit('userinput', {
|
sendToServer(buffer.server, {
|
||||||
command: 'notice',
|
command: 'notice',
|
||||||
server: buffer.server,
|
|
||||||
message: listargs.slice(2).join(' '),
|
message: listargs.slice(2).join(' '),
|
||||||
arguments: [listargs[1]]
|
arguments: [listargs[1]]
|
||||||
})
|
})
|
||||||
@ -486,9 +503,8 @@ let commands = {
|
|||||||
|
|
||||||
action: {
|
action: {
|
||||||
execute: function (buffer, handler, command, message, listargs) {
|
execute: function (buffer, handler, command, message, listargs) {
|
||||||
irc.socket.emit('userinput', {
|
sendToServer(buffer.server, {
|
||||||
command: 'privmsg',
|
command: 'privmsg',
|
||||||
server: buffer.server,
|
|
||||||
message: '\x01ACTION ' + message.substring(command.length + 2) + '\x01',
|
message: '\x01ACTION ' + message.substring(command.length + 2) + '\x01',
|
||||||
arguments: [buffer.name]
|
arguments: [buffer.name]
|
||||||
})
|
})
|
||||||
@ -499,7 +515,7 @@ let commands = {
|
|||||||
|
|
||||||
list: {
|
list: {
|
||||||
execute: function (buffer, handler, command, message, listargs) {
|
execute: function (buffer, handler, command, message, listargs) {
|
||||||
irc.socket.emit('userinput', { command: 'list', server: buffer.server, message: '', arguments: listargs.splice(1) })
|
sendToServer(buffer.server, { command: 'list', message: '', arguments: listargs.splice(1) })
|
||||||
},
|
},
|
||||||
description: '- List all channels on the current server.'
|
description: '- List all channels on the current server.'
|
||||||
},
|
},
|
||||||
@ -513,7 +529,7 @@ let commands = {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
irc.socket.emit('userinput', { command: 'nick', server: buffer.server, message: '', arguments: listargs.splice(1) })
|
sendToServer(buffer.server, { command: 'nick', message: '', arguments: listargs.splice(1) })
|
||||||
},
|
},
|
||||||
description: '- List all channels on the current server.',
|
description: '- List all channels on the current server.',
|
||||||
aliases: ['nickname']
|
aliases: ['nickname']
|
||||||
@ -533,7 +549,7 @@ let commands = {
|
|||||||
} else {
|
} else {
|
||||||
return handler.commandError(buffer, '/' + command.toUpperCase() + ': Invalid channel name!')
|
return handler.commandError(buffer, '/' + command.toUpperCase() + ': Invalid channel name!')
|
||||||
}
|
}
|
||||||
irc.socket.emit('userinput', { command: 'names', server: buffer.server, message: '', arguments: [channel] })
|
sendToServer(buffer.server, { command: 'names', message: '', arguments: [channel] })
|
||||||
},
|
},
|
||||||
description: '- List all users on the current channel.',
|
description: '- List all users on the current channel.',
|
||||||
aliases: ['nicknames']
|
aliases: ['nicknames']
|
||||||
@ -541,9 +557,8 @@ let commands = {
|
|||||||
|
|
||||||
quote: {
|
quote: {
|
||||||
execute: function (buffer, handler, command, message, listargs) {
|
execute: function (buffer, handler, command, message, listargs) {
|
||||||
irc.socket.emit('userinput', {
|
sendToServer(buffer.server, {
|
||||||
command: listargs[1],
|
command: listargs[1],
|
||||||
server: buffer.server,
|
|
||||||
message: listargs.slice(2).join(' '),
|
message: listargs.slice(2).join(' '),
|
||||||
arguments: listargs.splice(2)
|
arguments: listargs.splice(2)
|
||||||
})
|
})
|
||||||
@ -558,7 +573,7 @@ let commands = {
|
|||||||
return handler.commandError(buffer, listargs[0].toUpperCase() + ': Missing parameters!')
|
return handler.commandError(buffer, listargs[0].toUpperCase() + ': Missing parameters!')
|
||||||
}
|
}
|
||||||
|
|
||||||
irc.socket.emit('userinput', { command: 'whois', server: buffer.server, message: '', arguments: [listargs[1]] })
|
sendToServer(buffer.server, { command: 'whois', message: '', arguments: [listargs[1]] })
|
||||||
},
|
},
|
||||||
description: '<nickname> - Display information about a user.'
|
description: '<nickname> - Display information about a user.'
|
||||||
},
|
},
|
||||||
@ -1269,6 +1284,147 @@ class Settings extends AppletChatBuffer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ConnectionHandler {
|
||||||
|
constructor () {
|
||||||
|
this.clients = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
getClientByActualServer (actual) {
|
||||||
|
for (let i in this.clients) {
|
||||||
|
let a = this.clients[i]
|
||||||
|
if (a.data.actualServer === actual) return a
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
createConnection (data) {
|
||||||
|
let client = new IRCConnection(data, gcfg, { ctcps: customCTCPs })
|
||||||
|
irc.auther.authMessage('Connecting to server...', false)
|
||||||
|
client.on('authenticated', () => {
|
||||||
|
irc.auther.authComplete()
|
||||||
|
|
||||||
|
this.clients[data.server] = client
|
||||||
|
this.bindAll(data.server, client)
|
||||||
|
|
||||||
|
irc.chat.newServerChatBuffer(client)
|
||||||
|
irc.chat.joinChannels(client.data.actualServer, data.channels)
|
||||||
|
})
|
||||||
|
client.connect().catch(e => {
|
||||||
|
console.error(e)
|
||||||
|
irc.auther.authMessage('Socket connection failed!', true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
bindAll (srv, client) {
|
||||||
|
let server = client.data.actualServer
|
||||||
|
client.on('closed', () => {
|
||||||
|
this.clients[srv] = null
|
||||||
|
})
|
||||||
|
|
||||||
|
client.on('pass_to_client', (data) => {
|
||||||
|
switch (data.type) {
|
||||||
|
case 'event_join_channel':
|
||||||
|
if (data.user.nickname === irc.serverData[server].my_nick) {
|
||||||
|
irc.chat.createChatBuffer(server, data.channel, 'channel', true)
|
||||||
|
}
|
||||||
|
irc.chat.handleJoin(server, data.user, data.channel)
|
||||||
|
break
|
||||||
|
case 'event_kick_channel':
|
||||||
|
irc.chat.handleLeave(server, data.kickee, data.channel, data.reason, data.user)
|
||||||
|
break
|
||||||
|
case 'event_part_channel':
|
||||||
|
irc.chat.handleLeave(server, data.user, data.channel, data.reason)
|
||||||
|
break
|
||||||
|
case 'event_quit':
|
||||||
|
irc.chat.handleQuit(server, data.user, data.reason)
|
||||||
|
break
|
||||||
|
case 'message':
|
||||||
|
if (data.to === irc.serverData[server].my_nick) {
|
||||||
|
irc.chat.messageChatBuffer(data.user.nickname, server, { message: data.message, type: data.messageType, from: data.user.nickname })
|
||||||
|
} else if (data.to == null) {
|
||||||
|
let atest = irc.chat.getActiveChatBuffer()
|
||||||
|
|
||||||
|
if (atest.server !== server) {
|
||||||
|
atest = irc.chat.getServerChatBuffer(server)
|
||||||
|
}
|
||||||
|
|
||||||
|
atest.addMessage(data.message, data.user.nickname, data.messageType)
|
||||||
|
} else {
|
||||||
|
irc.chat.messageChatBuffer(data.to, server, { message: data.message, type: data.messageType, from: data.user.nickname })
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'channel_nicks':
|
||||||
|
irc.chat.buildNicklist(data.channel, server, data.nicks)
|
||||||
|
break
|
||||||
|
case 'channel_topic':
|
||||||
|
if (data['topic'] && data['set_by']) {
|
||||||
|
irc.chat.topicChange(data.channel, server, data.topic, data['set_by'])
|
||||||
|
} else if (data['topic']) {
|
||||||
|
irc.chat.topicChange(data.channel, server, data.topic, null)
|
||||||
|
} else if (data['set_by']) {
|
||||||
|
irc.chat.messageChatBuffer(data.channel, server, {
|
||||||
|
message: 'Topic set by ' + data.set_by + ' on ' + (new Date(data.time * 1000)),
|
||||||
|
type: 'topic',
|
||||||
|
from: null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'nick_change':
|
||||||
|
irc.chat.nickChange(server, data.nick, data.newNick)
|
||||||
|
break
|
||||||
|
case 'mode_add':
|
||||||
|
case 'mode_del':
|
||||||
|
case 'mode':
|
||||||
|
irc.chat.handleMode(server, data)
|
||||||
|
break
|
||||||
|
case 'server_message':
|
||||||
|
if (data['error']) data.messageType = 'error'
|
||||||
|
if (irc.chat.getServerChatBuffer(server) == null) {
|
||||||
|
if (!irc.serverChatQueue[server]) {
|
||||||
|
irc.serverChatQueue[server] = []
|
||||||
|
} else {
|
||||||
|
irc.serverChatQueue[server].push({ type: data.messageType, message: data.message, from: data.from || null, time: new Date() })
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
irc.chat.messageChatBuffer(server, server, { message: data.message, type: data.messageType, from: data.from || null })
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'connect_message':
|
||||||
|
irc.auther.authMessage(data.message, data.error)
|
||||||
|
break
|
||||||
|
case 'whoisResponse':
|
||||||
|
whoisMessage(data.whois, irc.chat.getActiveChatBuffer())
|
||||||
|
break
|
||||||
|
case 'listedchan':
|
||||||
|
irc.chat.messageChatBuffer(server, server,
|
||||||
|
{
|
||||||
|
message: span(data.channel, ['channel']) + ' ' +
|
||||||
|
span(data.users, ['usercount']) + ' ' +
|
||||||
|
span(data.topic, ['topic']),
|
||||||
|
type: 'listentry',
|
||||||
|
from: data.from
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
client.on('closed', () => {
|
||||||
|
let serverz = irc.chat.getChatBuffersByServer(server)
|
||||||
|
for (let a in serverz) {
|
||||||
|
let serv = serverz[a]
|
||||||
|
serv.addMessage('You are no longer talking on this server.', null, 'error')
|
||||||
|
serv.setAliveStatus(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (irc.serverData[server]) {
|
||||||
|
delete irc.serverData[server]
|
||||||
|
}
|
||||||
|
|
||||||
|
stopWarnings()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class IRCConnector {
|
class IRCConnector {
|
||||||
constructor () {
|
constructor () {
|
||||||
this.formLocked = false
|
this.formLocked = false
|
||||||
@ -1318,7 +1474,7 @@ class IRCConnector {
|
|||||||
case 'nick':
|
case 'nick':
|
||||||
case 'nickname':
|
case 'nickname':
|
||||||
if (validators.nickname(value)) {
|
if (validators.nickname(value)) {
|
||||||
clientdom.connector.nickname.value = value.replace(/\?/g, rand(10000, 99999))
|
clientdom.connector.nickname.value = value.replace(/\?/g, rand(seedrandom(1), 10000, 99999))
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'secure':
|
case 'secure':
|
||||||
@ -1438,7 +1594,7 @@ class IRCConnector {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
nickname: nickname,
|
nickname: nickname,
|
||||||
autojoin: channel,
|
channels: channel,
|
||||||
server: server,
|
server: server,
|
||||||
port: port,
|
port: port,
|
||||||
password: password,
|
password: password,
|
||||||
@ -1452,7 +1608,8 @@ class IRCConnector {
|
|||||||
let data = this.getDataFromForm()
|
let data = this.getDataFromForm()
|
||||||
if (!data) return
|
if (!data) return
|
||||||
|
|
||||||
irc.socket.emit('irc_create', data)
|
irc.handler.createConnection(data)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1633,7 +1790,7 @@ class InputHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
irc.socket.emit('userinput', { command: 'privmsg', server: buffer.server, message: message, arguments: [buffer.name] })
|
sendToServer(buffer.server, { command: 'privmsg', message: message, arguments: [buffer.name] })
|
||||||
}
|
}
|
||||||
|
|
||||||
this.history.push(message)
|
this.history.push(message)
|
||||||
@ -1757,29 +1914,29 @@ class IRCChatWindow {
|
|||||||
|
|
||||||
let prefixes = ''
|
let prefixes = ''
|
||||||
|
|
||||||
for (let v in serverinfo.supportedModes) {
|
for (let v in serverinfo.data.supportedModes) {
|
||||||
prefixes += serverinfo.supportedModes[v]
|
prefixes += serverinfo.data.supportedModes[v]
|
||||||
}
|
}
|
||||||
|
|
||||||
irc.serverData[serverinfo.address] = {
|
irc.serverData[serverinfo.data.actualServer] = {
|
||||||
modeTranslation: serverinfo.supportedModes,
|
modeTranslation: serverinfo.data.supportedModes,
|
||||||
supportedPrefixes: prefixes,
|
supportedPrefixes: prefixes,
|
||||||
network: serverinfo.network,
|
network: serverinfo.data.network,
|
||||||
my_nick: serverinfo.nickname,
|
my_nick: serverinfo.config.nickname,
|
||||||
max_channel_length: serverinfo.max_channel_length
|
max_channel_length: serverinfo.data.max_channel_length
|
||||||
}
|
}
|
||||||
|
|
||||||
let newServer = new ChatBuffer(serverinfo.address, serverinfo.address, serverinfo.network, 'server')
|
let newServer = new ChatBuffer(serverinfo.data.actualServer, serverinfo.data.actualServer, serverinfo.data.network, 'server')
|
||||||
this.buffers.push(newServer)
|
this.buffers.push(newServer)
|
||||||
this.render(newServer)
|
this.render(newServer)
|
||||||
this.firstServer = false
|
this.firstServer = false
|
||||||
|
|
||||||
if (irc.serverChatQueue[serverinfo.address]) {
|
if (irc.serverChatQueue[serverinfo.data.actualServer]) {
|
||||||
for (let a in irc.serverChatQueue[serverinfo.address]) {
|
for (let a in irc.serverChatQueue[serverinfo.data.actualServer]) {
|
||||||
let mesg = irc.serverChatQueue[serverinfo.address][a]
|
let mesg = irc.serverChatQueue[serverinfo.data.actualServer][a]
|
||||||
newServer.addMessage(mesg.message, mesg.from, mesg.type, mesg.time)
|
newServer.addMessage(mesg.message, mesg.from, mesg.type, mesg.time)
|
||||||
}
|
}
|
||||||
delete irc.serverChatQueue[serverinfo.address]
|
delete irc.serverChatQueue[serverinfo.data.actualServer]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1804,9 +1961,9 @@ class IRCChatWindow {
|
|||||||
|
|
||||||
closeChatBuffer (buffer) {
|
closeChatBuffer (buffer) {
|
||||||
if (buffer.type === 'server') {
|
if (buffer.type === 'server') {
|
||||||
irc.socket.emit('userinput', { command: 'quit', server: buffer.server, message: 'Server tab closed', arguments: [] })
|
sendToServer(buffer.server, { command: 'quit', message: 'Server tab closed', arguments: [] })
|
||||||
} else if (buffer.type === 'channel' && buffer.alive) {
|
} else if (buffer.type === 'channel' && buffer.alive) {
|
||||||
irc.socket.emit('userinput', { command: 'part', server: buffer.server, message: 'Tab closed', arguments: [buffer.name] })
|
sendToServer(buffer.server, { command: 'part', message: 'Tab closed', arguments: [buffer.name] })
|
||||||
}
|
}
|
||||||
|
|
||||||
let bufIndex = this.buffers.indexOf(buffer)
|
let bufIndex = this.buffers.indexOf(buffer)
|
||||||
@ -1971,12 +2128,12 @@ class IRCChatWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMode (data) {
|
handleMode (server, data) {
|
||||||
let buf = null
|
let buf = null
|
||||||
if (data.target === irc.serverData[data.server].my_nick) {
|
if (data.target === irc.serverData[server].my_nick) {
|
||||||
buf = this.getServerChatBuffer(data.server)
|
buf = this.getServerChatBuffer(server)
|
||||||
} else {
|
} else {
|
||||||
buf = this.getChatBufferByServerName(data.server, data.target)
|
buf = this.getChatBufferByServerName(server, data.target)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!buf) return
|
if (!buf) return
|
||||||
@ -1996,6 +2153,7 @@ class IRCChatWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
joinChannels (server, channel) {
|
joinChannels (server, channel) {
|
||||||
|
if (typeof channel !== 'object') {
|
||||||
if (channel.indexOf(',') !== -1) {
|
if (channel.indexOf(',') !== -1) {
|
||||||
channel = channel.trim().split(',')
|
channel = channel.trim().split(',')
|
||||||
|
|
||||||
@ -2017,8 +2175,9 @@ class IRCChatWindow {
|
|||||||
} else {
|
} else {
|
||||||
channel = []
|
channel = []
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
irc.socket.emit('userinput', { command: 'join', server: server, message: '', arguments: channel })
|
sendToServer(server, { command: 'join', message: '', arguments: channel })
|
||||||
}
|
}
|
||||||
|
|
||||||
changeTitle (title) {
|
changeTitle (title) {
|
||||||
@ -2104,140 +2263,13 @@ window.onload = function () {
|
|||||||
clientdom['smsctrig'] = clientdom.chat.querySelector('.smsc-nicklistbtn')
|
clientdom['smsctrig'] = clientdom.chat.querySelector('.smsc-nicklistbtn')
|
||||||
clientdom.settings['open'] = irc.primaryFrame.querySelector('.open_settings')
|
clientdom.settings['open'] = irc.primaryFrame.querySelector('.open_settings')
|
||||||
|
|
||||||
irc.socket = io.connect()
|
|
||||||
|
|
||||||
irc.settings = new Settings()
|
irc.settings = new Settings()
|
||||||
|
irc.handler = new ConnectionHandler()
|
||||||
irc.auther = new IRCConnector()
|
irc.auther = new IRCConnector()
|
||||||
irc.chat = new IRCChatWindow()
|
irc.chat = new IRCChatWindow()
|
||||||
|
|
||||||
irc.settings.setInitialValues()
|
irc.settings.setInitialValues()
|
||||||
|
|
||||||
irc.socket.on('defaults', function (data) {
|
|
||||||
irc.auther.defaultTo(data)
|
|
||||||
parseURL()
|
parseURL()
|
||||||
window.onpopstate = parseURL
|
window.onpopstate = parseURL
|
||||||
})
|
|
||||||
|
|
||||||
irc.socket.on('connect', function (data) {
|
|
||||||
irc.socketUp = true
|
|
||||||
})
|
|
||||||
|
|
||||||
irc.socket.on('disconnect', function (data) {
|
|
||||||
irc.socketUp = false
|
|
||||||
irc.chat.destroyAllChatBuffers()
|
|
||||||
clientdom.connector.frame.style.display = 'block'
|
|
||||||
})
|
|
||||||
|
|
||||||
// Does everything
|
|
||||||
irc.socket.on('act_client', function (data) {
|
|
||||||
if (data['message']) {
|
|
||||||
data.message = validators.escapeHTML(data.message)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data['reason']) {
|
|
||||||
data.reason = validators.escapeHTML(data.reason)
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (data.type) {
|
|
||||||
case 'event_connect':
|
|
||||||
irc.auther.authComplete()
|
|
||||||
irc.chat.newServerChatBuffer(data)
|
|
||||||
break
|
|
||||||
case 'event_join_channel':
|
|
||||||
if (data.user.nickname === irc.serverData[data.server].my_nick) {
|
|
||||||
irc.chat.createChatBuffer(data.server, data.channel, 'channel', true)
|
|
||||||
}
|
|
||||||
irc.chat.handleJoin(data.server, data.user, data.channel)
|
|
||||||
break
|
|
||||||
case 'event_kick_channel':
|
|
||||||
irc.chat.handleLeave(data.server, data.kickee, data.channel, data.reason, data.user)
|
|
||||||
break
|
|
||||||
case 'event_part_channel':
|
|
||||||
irc.chat.handleLeave(data.server, data.user, data.channel, data.reason)
|
|
||||||
break
|
|
||||||
case 'event_quit':
|
|
||||||
irc.chat.handleQuit(data.server, data.user, data.reason)
|
|
||||||
break
|
|
||||||
case 'event_server_quit':
|
|
||||||
let serverz = irc.chat.getChatBuffersByServer(data.server)
|
|
||||||
for (let a in serverz) {
|
|
||||||
let serv = serverz[a]
|
|
||||||
serv.addMessage('You are no longer talking on this server.', null, 'error')
|
|
||||||
serv.setAliveStatus(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (irc.serverData[data.server]) {
|
|
||||||
delete irc.serverData[data.server]
|
|
||||||
}
|
|
||||||
stopWarnings()
|
|
||||||
break
|
|
||||||
case 'message':
|
|
||||||
if (data.to === irc.serverData[data.server].my_nick) {
|
|
||||||
irc.chat.messageChatBuffer(data.user.nickname, data.server, { message: data.message, type: data.messageType, from: data.user.nickname })
|
|
||||||
} else if (data.to == null) {
|
|
||||||
let atest = irc.chat.getActiveChatBuffer()
|
|
||||||
|
|
||||||
if (atest.server !== data.server) {
|
|
||||||
atest = irc.chat.getServerChatBuffer(data.server)
|
|
||||||
}
|
|
||||||
|
|
||||||
atest.addMessage(data.message, data.user.nickname, data.messageType)
|
|
||||||
} else {
|
|
||||||
irc.chat.messageChatBuffer(data.to, data.server, { message: data.message, type: data.messageType, from: data.user.nickname })
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case 'channel_nicks':
|
|
||||||
irc.chat.buildNicklist(data.channel, data.server, data.nicks)
|
|
||||||
break
|
|
||||||
case 'channel_topic':
|
|
||||||
if (data['topic'] && data['set_by']) {
|
|
||||||
irc.chat.topicChange(data.channel, data.server, data.topic, data['set_by'])
|
|
||||||
} else if (data['topic']) {
|
|
||||||
irc.chat.topicChange(data.channel, data.server, data.topic, null)
|
|
||||||
} else if (data['set_by']) {
|
|
||||||
irc.chat.messageChatBuffer(data.channel, data.server, {
|
|
||||||
message: 'Topic set by ' + data.set_by + ' on ' + (new Date(data.time * 1000)),
|
|
||||||
type: 'topic',
|
|
||||||
from: null
|
|
||||||
})
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case 'nick_change':
|
|
||||||
irc.chat.nickChange(data.server, data.nick, data.newNick)
|
|
||||||
break
|
|
||||||
case 'mode_add':
|
|
||||||
case 'mode_del':
|
|
||||||
case 'mode':
|
|
||||||
irc.chat.handleMode(data)
|
|
||||||
break
|
|
||||||
case 'server_message':
|
|
||||||
if (data['error']) data.messageType = 'error'
|
|
||||||
if (irc.chat.getServerChatBuffer(data.server) == null) {
|
|
||||||
if (!irc.serverChatQueue[data.server]) {
|
|
||||||
irc.serverChatQueue[data.server] = []
|
|
||||||
} else {
|
|
||||||
irc.serverChatQueue[data.server].push({ type: data.messageType, message: data.message, from: data.from || null, time: new Date() })
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
irc.chat.messageChatBuffer(data.server, data.server, { message: data.message, type: data.messageType, from: data.from || null })
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case 'connect_message':
|
|
||||||
irc.auther.authMessage(data.message, data.error)
|
|
||||||
break
|
|
||||||
case 'whoisResponse':
|
|
||||||
whoisMessage(data.whois, irc.chat.getActiveChatBuffer())
|
|
||||||
break
|
|
||||||
case 'listedchan':
|
|
||||||
irc.chat.messageChatBuffer(data.server, data.server,
|
|
||||||
{
|
|
||||||
message: span(data.channel, ['channel']) + ' ' +
|
|
||||||
span(data.users, ['usercount']) + ' ' +
|
|
||||||
span(data.topic, ['topic']),
|
|
||||||
type: 'listentry',
|
|
||||||
from: data.from
|
|
||||||
})
|
|
||||||
break
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
73
src/js/previews.js
Normal file
73
src/js/previews.js
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
const imgs = ['.png', '.jpg', '.jpeg', '.svg']
|
||||||
|
const embeds = [
|
||||||
|
{
|
||||||
|
match: /youtu.?be\//is,
|
||||||
|
exec: function (pgurl) {
|
||||||
|
let dat = pgurl.match(/(?:be|com)\/([^?&#]+)/i)
|
||||||
|
if (!dat) {
|
||||||
|
dat = pgurl.match('[\\?&]v=([^&#]*)')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dat) return null
|
||||||
|
|
||||||
|
return 'https://www.youtube.com/embed/' + dat[1] + '?autoplay=1'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
export function handleUrlElement (elem) {
|
||||||
|
let cover = null
|
||||||
|
let ext = elem.href.split('.')
|
||||||
|
ext = ext[ext.length - 1]
|
||||||
|
|
||||||
|
if (ext && imgs.indexOf(ext) !== -1) {
|
||||||
|
cover = document.createElement('img')
|
||||||
|
cover.src = elem.href
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cover) {
|
||||||
|
for (let a in embeds) {
|
||||||
|
if (cover) break
|
||||||
|
let fn = embeds[a]
|
||||||
|
if (elem.href.match(fn.match)) {
|
||||||
|
let r = fn.exec(elem.href)
|
||||||
|
if (r) {
|
||||||
|
cover = document.createElement('iframe')
|
||||||
|
cover.src = r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cover) {
|
||||||
|
cover.className = 'preview'
|
||||||
|
|
||||||
|
let contelem = document.createElement('span')
|
||||||
|
contelem.className = 'preview-box'
|
||||||
|
|
||||||
|
let contbutton = document.createElement('button')
|
||||||
|
contbutton.className = 'preview-btn'
|
||||||
|
contbutton.innerHTML = 'Show Preview'
|
||||||
|
|
||||||
|
elem.parentNode.appendChild(contelem)
|
||||||
|
|
||||||
|
contelem.appendChild(elem)
|
||||||
|
contelem.appendChild(contbutton)
|
||||||
|
|
||||||
|
contbutton.addEventListener('click', function (e) {
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
if (cover.parentNode) {
|
||||||
|
cover.remove()
|
||||||
|
contbutton.innerHTML = 'Show Preview'
|
||||||
|
} else {
|
||||||
|
contelem.appendChild(cover)
|
||||||
|
contbutton.innerHTML = 'Hide Preview'
|
||||||
|
}
|
||||||
|
}, false)
|
||||||
|
|
||||||
|
return contelem
|
||||||
|
}
|
||||||
|
|
||||||
|
return elem
|
||||||
|
}
|
@ -1,15 +0,0 @@
|
|||||||
import fs from 'fs'
|
|
||||||
import path from 'path'
|
|
||||||
import toml from 'toml'
|
|
||||||
|
|
||||||
const filename = path.join(__dirname, '..', 'client.config.toml')
|
|
||||||
|
|
||||||
let config
|
|
||||||
|
|
||||||
try {
|
|
||||||
config = toml.parse(fs.readFileSync(filename))
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error('config.toml parse error: ', e.message)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = config
|
|
@ -1,14 +1,8 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
import express from 'express'
|
import express from 'express'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import sockio from 'socket.io'
|
|
||||||
import dns from 'dns'
|
|
||||||
|
|
||||||
import pkginfo from '../package.json'
|
import config from '../globals'
|
||||||
import irclib from './irc'
|
|
||||||
import webirc from './webirc'
|
|
||||||
|
|
||||||
import config from './config'
|
|
||||||
import logger from './logger'
|
import logger from './logger'
|
||||||
|
|
||||||
const app = express()
|
const app = express()
|
||||||
@ -17,21 +11,6 @@ const pubdir = path.join(__dirname, 'public')
|
|||||||
const port = config.server.port || 8080
|
const port = config.server.port || 8080
|
||||||
const cacheAge = 365 * 24 * 60 * 60 * 1000
|
const cacheAge = 365 * 24 * 60 * 60 * 1000
|
||||||
|
|
||||||
let runtimeStats = {
|
|
||||||
connectionsMade: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
let connections = {}
|
|
||||||
|
|
||||||
let customCTCPs = {
|
|
||||||
VERSION: function (data, connection) {
|
|
||||||
return `TeemantIRC ver. ${pkginfo.version} - ${pkginfo.description} - https://teemant.icynet.eu/`
|
|
||||||
},
|
|
||||||
SOURCE: function (data, connection) {
|
|
||||||
return 'https://gitlab.icynet.eu/IcyNetwork/teemant'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
process.stdin.resume()
|
process.stdin.resume()
|
||||||
|
|
||||||
router.get('/', function (req, res) {
|
router.get('/', function (req, res) {
|
||||||
@ -51,186 +30,6 @@ app.use('/:server', express.static(path.join(pubdir, 'icons'), { maxAge: cacheAg
|
|||||||
app.use('/:server', express.static(path.join(pubdir, 'static'), { maxAge: cacheAge }))
|
app.use('/:server', express.static(path.join(pubdir, 'static'), { maxAge: cacheAge }))
|
||||||
|
|
||||||
app.use('/', router)
|
app.use('/', router)
|
||||||
|
app.listen(port, function () {
|
||||||
const io = sockio.listen(app.listen(port, function () {
|
|
||||||
logger.log(`*** Listening on http://localhost:${port}/`)
|
logger.log(`*** Listening on http://localhost:${port}/`)
|
||||||
|
|
||||||
setInterval(() => {
|
|
||||||
logger.printRuntimeStats(runtimeStats, connections)
|
|
||||||
}, 3600000)
|
|
||||||
}))
|
|
||||||
|
|
||||||
function resolveHostname (ipaddr) {
|
|
||||||
return new Promise(function (resolve, reject) {
|
|
||||||
dns.reverse(ipaddr, function (err, hostnames) {
|
|
||||||
if (err != null) return reject(err)
|
|
||||||
resolve(hostnames)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
io.sockets.on('connection', function (socket) {
|
|
||||||
let userip = socket.handshake.headers['x-real-ip'] || socket.handshake.headers['x-forwarded-for'] ||
|
|
||||||
socket.request.connection._peername.address || '127.0.0.1'
|
|
||||||
|
|
||||||
if (userip.indexOf('::ffff:') === 0) {
|
|
||||||
userip = userip.substring(7)
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.debugLog(`clientID: ${socket.id} from: ${userip}`)
|
|
||||||
|
|
||||||
socket.emit('defaults', {
|
|
||||||
server: config.client.default_server,
|
|
||||||
port: config.client.default_port,
|
|
||||||
ssl: config.client.secure_by_default
|
|
||||||
})
|
|
||||||
|
|
||||||
// New object for connections
|
|
||||||
connections[socket.id] = {
|
|
||||||
host: {
|
|
||||||
ipaddr: userip,
|
|
||||||
hostname: userip
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the hostname of the connecting user
|
|
||||||
let hostQuery = resolveHostname(userip)
|
|
||||||
hostQuery.then((arr) => {
|
|
||||||
if (arr.length > 0) {
|
|
||||||
connections[socket.id].host.hostname = arr[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.debugLog(`Hostname of ${socket.id} was determined to be ${connections[socket.id].host.hostname}`)
|
|
||||||
}).catch((err) => {
|
|
||||||
logger.debugLog(`Host resolve for ${socket.id} failed:`, err.message)
|
|
||||||
})
|
|
||||||
|
|
||||||
socket.on('disconnect', function () {
|
|
||||||
for (let d in connections[socket.id]) {
|
|
||||||
if (connections[socket.id][d].ipaddr) continue
|
|
||||||
if (connections[socket.id][d].connected === true) {
|
|
||||||
connections[socket.id][d].disconnect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete connections[socket.id]
|
|
||||||
|
|
||||||
logger.debugLog(`clientID: ${socket.id} disconnect`)
|
|
||||||
})
|
|
||||||
|
|
||||||
socket.on('error', (e) => {
|
|
||||||
logger.errorLog(e, 'Socket error')
|
|
||||||
})
|
|
||||||
|
|
||||||
socket.on('userinput', (data) => {
|
|
||||||
let serv = connections[socket.id][data.server]
|
|
||||||
if (!serv) return
|
|
||||||
if (serv.authenticated === false) return
|
|
||||||
|
|
||||||
logger.debugLog(`[${socket.id}] ->`, data)
|
|
||||||
|
|
||||||
try {
|
|
||||||
serv.handler.handleUserLine(data)
|
|
||||||
} catch (e) {
|
|
||||||
console.error('An error occured while handling message from client', data)
|
|
||||||
console.error(e.stack)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
socket.on('irc_create', function (connectiondata) {
|
|
||||||
logger.debugLog(`${socket.id} created irc connection: `, connectiondata)
|
|
||||||
|
|
||||||
socket.emit('act_client', { type: 'connect_message', message: 'Connecting to server..', error: false })
|
|
||||||
|
|
||||||
if (connectiondata.port === null || connectiondata.server === null) {
|
|
||||||
return socket.emit('act_client', {
|
|
||||||
type: 'connect_message',
|
|
||||||
server: connectiondata.server,
|
|
||||||
message: 'Failed to connect to the server!',
|
|
||||||
error: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
let newConnection = new irclib.IRCConnection(connectiondata, config.client,
|
|
||||||
{
|
|
||||||
authenticationSteps: [
|
|
||||||
new webirc.Authenticator(connections[socket.id].host)
|
|
||||||
],
|
|
||||||
ctcps: customCTCPs
|
|
||||||
})
|
|
||||||
|
|
||||||
newConnection.connect()
|
|
||||||
|
|
||||||
connections[socket.id][connectiondata.server] = newConnection
|
|
||||||
|
|
||||||
newConnection.on('authenticated', () => {
|
|
||||||
socket.emit('act_client', {
|
|
||||||
type: 'event_connect',
|
|
||||||
address: connectiondata.server,
|
|
||||||
network: newConnection.data.network,
|
|
||||||
supportedModes: newConnection.data.supportedModes,
|
|
||||||
nickname: newConnection.config.nickname,
|
|
||||||
max_channel_length: newConnection.data.max_channel_length
|
|
||||||
})
|
|
||||||
|
|
||||||
runtimeStats.connectionsMade += 1
|
|
||||||
})
|
|
||||||
|
|
||||||
if (config.server.debug) {
|
|
||||||
newConnection.on('line', function (line) {
|
|
||||||
logger.debugLog(`[${socket.id}] <-`, line)
|
|
||||||
})
|
|
||||||
|
|
||||||
newConnection.on('debug_log', function (data) {
|
|
||||||
logger.debugLog(`[${socket.id}] <-`, data)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
newConnection.on('connerror', (data) => {
|
|
||||||
logger.debugLog(data)
|
|
||||||
|
|
||||||
if (newConnection.authenticated === false) {
|
|
||||||
socket.emit('act_client', {
|
|
||||||
type: 'connect_message',
|
|
||||||
server: connectiondata.server,
|
|
||||||
message: 'Failed to connect to the server!',
|
|
||||||
error: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
newConnection.on('pass_to_client', (data) => {
|
|
||||||
socket.emit('act_client', data)
|
|
||||||
})
|
|
||||||
|
|
||||||
newConnection.on('closed', (data) => {
|
|
||||||
logger.debugLog(data)
|
|
||||||
|
|
||||||
if (newConnection.authenticated === false) {
|
|
||||||
socket.emit('act_client', {
|
|
||||||
type: 'connect_message',
|
|
||||||
server: connectiondata.server,
|
|
||||||
message: 'Failed to connect to the server!',
|
|
||||||
error: true
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
socket.emit('act_client', {
|
|
||||||
type: 'event_server_quit',
|
|
||||||
server: connectiondata.server
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
process.on('SIGINT', () => {
|
|
||||||
logger.log('!!! Received SIGINT; Terminating all IRC connections and exiting.. !!!')
|
|
||||||
logger.printRuntimeStats(runtimeStats, connections)
|
|
||||||
for (let c in connections) {
|
|
||||||
for (let ircconn in connections[c]) {
|
|
||||||
if (connections[c][ircconn].ipaddr) continue
|
|
||||||
connections[c][ircconn].disconnect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
process.exit(0)
|
|
||||||
})
|
})
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
import connector from './irc.js'
|
|
||||||
import parser from './parser.js'
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
IRCConnection: connector,
|
|
||||||
Parser: parser
|
|
||||||
}
|
|
@ -3,8 +3,11 @@
|
|||||||
const webpack = require('webpack')
|
const webpack = require('webpack')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||||
|
const glb = require(path.join(__dirname, 'globals'))
|
||||||
|
|
||||||
module.exports = {
|
module.exports = (env, options) => {
|
||||||
|
return {
|
||||||
entry: {
|
entry: {
|
||||||
main: './src/js/main'
|
main: './src/js/main'
|
||||||
},
|
},
|
||||||
@ -31,14 +34,17 @@ module.exports = {
|
|||||||
// Detect and inject
|
// Detect and inject
|
||||||
_: 'underscore'
|
_: 'underscore'
|
||||||
}),
|
}),
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
template: 'src/document/index.html'
|
||||||
|
}),
|
||||||
new CopyWebpackPlugin([{
|
new CopyWebpackPlugin([{
|
||||||
from: 'src/document/index.html',
|
|
||||||
to: '.'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: 'static',
|
from: 'static',
|
||||||
to: 'static'
|
to: 'static'
|
||||||
}])
|
}]),
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
globalConfig: JSON.stringify(glb.client)
|
||||||
|
})
|
||||||
],
|
],
|
||||||
devtool: 'inline-source-map'
|
devtool: (options.mode === 'development' ? 'inline-source-map' : undefined)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user