[feature] first commit

This commit is contained in:
方而静 2021-03-25 13:57:12 +08:00
commit 3a870cb70d
No known key found for this signature in database
GPG Key ID: C4F2853BC3103681
11 changed files with 1438 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules/

717
package-lock.json generated Normal file
View File

@ -0,0 +1,717 @@
{
"name": "wschat-ng",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@types/body-parser": {
"version": "1.19.0",
"resolved": "https://registry.npm.taobao.org/@types/body-parser/download/@types/body-parser-1.19.0.tgz",
"integrity": "sha1-BoWzxH6zAG/+0RfN1VFkth+AU48=",
"dev": true,
"requires": {
"@types/connect": "*",
"@types/node": "*"
}
},
"@types/component-emitter": {
"version": "1.2.10",
"resolved": "https://registry.npm.taobao.org/@types/component-emitter/download/@types/component-emitter-1.2.10.tgz?cache=0&sync_timestamp=1613378698401&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fcomponent-emitter%2Fdownload%2F%40types%2Fcomponent-emitter-1.2.10.tgz",
"integrity": "sha1-71sVibnxZURkLkc9tepWORB+8+o="
},
"@types/connect": {
"version": "3.4.34",
"resolved": "https://registry.npm.taobao.org/@types/connect/download/@types/connect-3.4.34.tgz",
"integrity": "sha1-FwpAIjptZmAG2TyhKK8r6x2bGQE=",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/cookie": {
"version": "0.4.0",
"resolved": "https://registry.npm.taobao.org/@types/cookie/download/@types/cookie-0.4.0.tgz",
"integrity": "sha1-FPhUwPk9Mm452m47bzT303UT0Qg="
},
"@types/cors": {
"version": "2.8.10",
"resolved": "https://registry.npm.taobao.org/@types/cors/download/@types/cors-2.8.10.tgz",
"integrity": "sha1-YcyEaYSeW83QxwRBIiZcOc7BDPQ="
},
"@types/engine.io": {
"version": "3.1.5",
"resolved": "https://registry.npm.taobao.org/@types/engine.io/download/@types/engine.io-3.1.5.tgz",
"integrity": "sha1-7SgL7GHWImwL/LA/KCDE5lOR2sI=",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/express": {
"version": "4.17.11",
"resolved": "https://registry.npm.taobao.org/@types/express/download/@types/express-4.17.11.tgz",
"integrity": "sha1-3r48qm+OX82pa0e9VOL0DE7llUU=",
"dev": true,
"requires": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.18",
"@types/qs": "*",
"@types/serve-static": "*"
}
},
"@types/express-serve-static-core": {
"version": "4.17.19",
"resolved": "https://registry.npm.taobao.org/@types/express-serve-static-core/download/@types/express-serve-static-core-4.17.19.tgz?cache=0&sync_timestamp=1615830719275&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fexpress-serve-static-core%2Fdownload%2F%40types%2Fexpress-serve-static-core-4.17.19.tgz",
"integrity": "sha1-AKz8FjLnKaysTxUw6eFvbdFQih0=",
"dev": true,
"requires": {
"@types/node": "*",
"@types/qs": "*",
"@types/range-parser": "*"
}
},
"@types/mime": {
"version": "1.3.2",
"resolved": "https://registry.npm.taobao.org/@types/mime/download/@types/mime-1.3.2.tgz?cache=0&sync_timestamp=1613379359648&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fmime%2Fdownload%2F%40types%2Fmime-1.3.2.tgz",
"integrity": "sha1-k+Jb+e51/g/YC1lLxP6w6GIRG1o=",
"dev": true
},
"@types/node": {
"version": "14.14.35",
"resolved": "https://registry.npm.taobao.org/@types/node/download/@types/node-14.14.35.tgz?cache=0&sync_timestamp=1615834840617&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-14.14.35.tgz",
"integrity": "sha1-QslTpOKxirkx9yR35wEhcvT/oxM="
},
"@types/qs": {
"version": "6.9.6",
"resolved": "https://registry.npm.taobao.org/@types/qs/download/@types/qs-6.9.6.tgz?cache=0&sync_timestamp=1615109351276&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fqs%2Fdownload%2F%40types%2Fqs-6.9.6.tgz",
"integrity": "sha1-35w8izGiR+wxXmmWVmvjFx30s7E=",
"dev": true
},
"@types/range-parser": {
"version": "1.2.3",
"resolved": "https://registry.npm.taobao.org/@types/range-parser/download/@types/range-parser-1.2.3.tgz?cache=0&sync_timestamp=1613379955500&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Frange-parser%2Fdownload%2F%40types%2Frange-parser-1.2.3.tgz",
"integrity": "sha1-fuMwunyq+5gJC+zoal7kQRWQTCw=",
"dev": true
},
"@types/serve-static": {
"version": "1.13.9",
"resolved": "https://registry.npm.taobao.org/@types/serve-static/download/@types/serve-static-1.13.9.tgz?cache=0&sync_timestamp=1613384321618&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fserve-static%2Fdownload%2F%40types%2Fserve-static-1.13.9.tgz",
"integrity": "sha1-qs8oqFoF7imhH7fD6tk1rFbzPk4=",
"dev": true,
"requires": {
"@types/mime": "^1",
"@types/node": "*"
}
},
"@types/socket.io": {
"version": "2.1.13",
"resolved": "https://registry.npm.taobao.org/@types/socket.io/download/@types/socket.io-2.1.13.tgz",
"integrity": "sha1-ttaUI06ZlWyW/5nhl+2oJLb53Eg=",
"dev": true,
"requires": {
"@types/engine.io": "*",
"@types/node": "*",
"@types/socket.io-parser": "*"
}
},
"@types/socket.io-parser": {
"version": "2.2.1",
"resolved": "https://registry.npm.taobao.org/@types/socket.io-parser/download/@types/socket.io-parser-2.2.1.tgz",
"integrity": "sha1-3JSu0wODlIf0l1JJoypUgQnqNkc=",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"accepts": {
"version": "1.3.7",
"resolved": "https://registry.npm.taobao.org/accepts/download/accepts-1.3.7.tgz",
"integrity": "sha1-UxvHJlF6OytB+FACHGzBXqq1B80=",
"requires": {
"mime-types": "~2.1.24",
"negotiator": "0.6.2"
}
},
"arg": {
"version": "4.1.3",
"resolved": "https://registry.npm.taobao.org/arg/download/arg-4.1.3.tgz?cache=0&sync_timestamp=1605575100985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Farg%2Fdownload%2Farg-4.1.3.tgz",
"integrity": "sha1-Jp/HrVuOQstjyJbVZmAXJhwUQIk=",
"dev": true
},
"array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npm.taobao.org/array-flatten/download/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
},
"base64-arraybuffer": {
"version": "0.1.4",
"resolved": "https://registry.npm.taobao.org/base64-arraybuffer/download/base64-arraybuffer-0.1.4.tgz",
"integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI="
},
"base64id": {
"version": "2.0.0",
"resolved": "https://registry.npm.taobao.org/base64id/download/base64id-2.0.0.tgz",
"integrity": "sha1-J3Csa8R9MSr5eov5pjQ0LgzSXLY="
},
"body-parser": {
"version": "1.19.0",
"resolved": "https://registry.npm.taobao.org/body-parser/download/body-parser-1.19.0.tgz",
"integrity": "sha1-lrJwnlfJxOCab9Zqj9l5hE9p8Io=",
"requires": {
"bytes": "3.1.0",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "~1.1.2",
"http-errors": "1.7.2",
"iconv-lite": "0.4.24",
"on-finished": "~2.3.0",
"qs": "6.7.0",
"raw-body": "2.4.0",
"type-is": "~1.6.17"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1607566533140&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
"integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
"requires": {
"ms": "2.0.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&sync_timestamp=1607433842694&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npm.taobao.org/buffer-from/download/buffer-from-1.1.1.tgz",
"integrity": "sha1-MnE7wCj3XAL9txDXx7zsHyxgcO8=",
"dev": true
},
"bytes": {
"version": "3.1.0",
"resolved": "https://registry.npm.taobao.org/bytes/download/bytes-3.1.0.tgz?cache=0&sync_timestamp=1589682741197&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbytes%2Fdownload%2Fbytes-3.1.0.tgz",
"integrity": "sha1-9s95M6Ng4FiPqf3oVlHNx/gF0fY="
},
"component-emitter": {
"version": "1.3.0",
"resolved": "https://registry.npm.taobao.org/component-emitter/download/component-emitter-1.3.0.tgz",
"integrity": "sha1-FuQHD7qK4ptnnyIVhT7hgasuq8A="
},
"content-disposition": {
"version": "0.5.3",
"resolved": "https://registry.npm.taobao.org/content-disposition/download/content-disposition-0.5.3.tgz",
"integrity": "sha1-4TDK9+cnkIfFYWwgB9BIVpiYT70=",
"requires": {
"safe-buffer": "5.1.2"
}
},
"content-type": {
"version": "1.0.4",
"resolved": "https://registry.npm.taobao.org/content-type/download/content-type-1.0.4.tgz",
"integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js="
},
"cookie": {
"version": "0.4.1",
"resolved": "https://registry.npm.taobao.org/cookie/download/cookie-0.4.1.tgz?cache=0&sync_timestamp=1599054117231&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcookie%2Fdownload%2Fcookie-0.4.1.tgz",
"integrity": "sha1-r9cT/ibr0hupXOth+agRblClN9E="
},
"cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npm.taobao.org/cookie-signature/download/cookie-signature-1.0.6.tgz",
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
},
"cors": {
"version": "2.8.5",
"resolved": "https://registry.npm.taobao.org/cors/download/cors-2.8.5.tgz",
"integrity": "sha1-6sEdpRWS3Ya58G9uesKTs9+HXSk=",
"requires": {
"object-assign": "^4",
"vary": "^1"
}
},
"create-require": {
"version": "1.1.1",
"resolved": "https://registry.npm.taobao.org/create-require/download/create-require-1.1.1.tgz",
"integrity": "sha1-wdfo8eX2z8n/ZfnNNS03NIdWwzM=",
"dev": true
},
"debug": {
"version": "4.3.1",
"resolved": "https://registry.npm.taobao.org/debug/download/debug-4.3.1.tgz?cache=0&sync_timestamp=1607566533140&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.3.1.tgz",
"integrity": "sha1-8NIpxQXgxtjEmsVT0bE9wYP2su4=",
"requires": {
"ms": "2.1.2"
}
},
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npm.taobao.org/depd/download/depd-1.1.2.tgz",
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
},
"destroy": {
"version": "1.0.4",
"resolved": "https://registry.npm.taobao.org/destroy/download/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
"diff": {
"version": "4.0.2",
"resolved": "https://registry.npm.taobao.org/diff/download/diff-4.0.2.tgz?cache=0&sync_timestamp=1604803664325&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdiff%2Fdownload%2Fdiff-4.0.2.tgz",
"integrity": "sha1-YPOuy4nV+uUgwRqhnvwruYKq3n0=",
"dev": true
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npm.taobao.org/encodeurl/download/encodeurl-1.0.2.tgz",
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
},
"engine.io": {
"version": "5.0.0",
"resolved": "https://registry.npm.taobao.org/engine.io/download/engine.io-5.0.0.tgz",
"integrity": "sha1-Rw3JSopJB/pNLNH6ZhFCavzuYb8=",
"requires": {
"accepts": "~1.3.4",
"base64id": "2.0.0",
"cookie": "~0.4.1",
"cors": "~2.8.5",
"debug": "~4.3.1",
"engine.io-parser": "~4.0.0",
"ws": "~7.4.2"
}
},
"engine.io-parser": {
"version": "4.0.2",
"resolved": "https://registry.npm.taobao.org/engine.io-parser/download/engine.io-parser-4.0.2.tgz?cache=0&sync_timestamp=1607330719219&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fengine.io-parser%2Fdownload%2Fengine.io-parser-4.0.2.tgz",
"integrity": "sha1-5B0LP7Zve/SjZx0gOKFUAk7bUB4=",
"requires": {
"base64-arraybuffer": "0.1.4"
}
},
"escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npm.taobao.org/escape-html/download/escape-html-1.0.3.tgz",
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
},
"etag": {
"version": "1.8.1",
"resolved": "https://registry.npm.taobao.org/etag/download/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"express": {
"version": "4.17.1",
"resolved": "https://registry.npm.taobao.org/express/download/express-4.17.1.tgz?cache=0&sync_timestamp=1599054274660&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexpress%2Fdownload%2Fexpress-4.17.1.tgz",
"integrity": "sha1-RJH8OGBc9R+GKdOcK10Cb5ikwTQ=",
"requires": {
"accepts": "~1.3.7",
"array-flatten": "1.1.1",
"body-parser": "1.19.0",
"content-disposition": "0.5.3",
"content-type": "~1.0.4",
"cookie": "0.4.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "~1.1.2",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "~1.1.2",
"fresh": "0.5.2",
"merge-descriptors": "1.0.1",
"methods": "~1.1.2",
"on-finished": "~2.3.0",
"parseurl": "~1.3.3",
"path-to-regexp": "0.1.7",
"proxy-addr": "~2.0.5",
"qs": "6.7.0",
"range-parser": "~1.2.1",
"safe-buffer": "5.1.2",
"send": "0.17.1",
"serve-static": "1.14.1",
"setprototypeof": "1.1.1",
"statuses": "~1.5.0",
"type-is": "~1.6.18",
"utils-merge": "1.0.1",
"vary": "~1.1.2"
},
"dependencies": {
"cookie": {
"version": "0.4.0",
"resolved": "https://registry.npm.taobao.org/cookie/download/cookie-0.4.0.tgz?cache=0&sync_timestamp=1599054117231&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcookie%2Fdownload%2Fcookie-0.4.0.tgz",
"integrity": "sha1-vrQ35wIrO21JAZ0IhmUwPr6cFLo="
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1607566533140&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
"integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
"requires": {
"ms": "2.0.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&sync_timestamp=1607433842694&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"finalhandler": {
"version": "1.1.2",
"resolved": "https://registry.npm.taobao.org/finalhandler/download/finalhandler-1.1.2.tgz",
"integrity": "sha1-t+fQAP/RGTjQ/bBTUG9uur6fWH0=",
"requires": {
"debug": "2.6.9",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"on-finished": "~2.3.0",
"parseurl": "~1.3.3",
"statuses": "~1.5.0",
"unpipe": "~1.0.0"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1607566533140&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
"integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
"requires": {
"ms": "2.0.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&sync_timestamp=1607433842694&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"forwarded": {
"version": "0.1.2",
"resolved": "https://registry.npm.taobao.org/forwarded/download/forwarded-0.1.2.tgz",
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
},
"fresh": {
"version": "0.5.2",
"resolved": "https://registry.npm.taobao.org/fresh/download/fresh-0.5.2.tgz?cache=0&sync_timestamp=1589682752100&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffresh%2Fdownload%2Ffresh-0.5.2.tgz",
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
},
"http-errors": {
"version": "1.7.2",
"resolved": "https://registry.npm.taobao.org/http-errors/download/http-errors-1.7.2.tgz?cache=0&sync_timestamp=1593407858306&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-errors%2Fdownload%2Fhttp-errors-1.7.2.tgz",
"integrity": "sha1-T1ApzxMjnzEDblsuVSkrz7zIXI8=",
"requires": {
"depd": "~1.1.2",
"inherits": "2.0.3",
"setprototypeof": "1.1.1",
"statuses": ">= 1.5.0 < 2",
"toidentifier": "1.0.0"
}
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz?cache=0&sync_timestamp=1594184264130&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ficonv-lite%2Fdownload%2Ficonv-lite-0.4.24.tgz",
"integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=",
"requires": {
"safer-buffer": ">= 2.1.2 < 3"
}
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npm.taobao.org/ipaddr.js/download/ipaddr.js-1.9.1.tgz",
"integrity": "sha1-v/OFQ+64mEglB5/zoqjmy9RngbM="
},
"make-error": {
"version": "1.3.6",
"resolved": "https://registry.npm.taobao.org/make-error/download/make-error-1.3.6.tgz",
"integrity": "sha1-LrLjfqm2fEiR9oShOUeZr0hM96I=",
"dev": true
},
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npm.taobao.org/media-typer/download/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
},
"merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npm.taobao.org/merge-descriptors/download/merge-descriptors-1.0.1.tgz",
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
},
"methods": {
"version": "1.1.2",
"resolved": "https://registry.npm.taobao.org/methods/download/methods-1.1.2.tgz",
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
},
"mime": {
"version": "1.6.0",
"resolved": "https://registry.npm.taobao.org/mime/download/mime-1.6.0.tgz",
"integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE="
},
"mime-db": {
"version": "1.46.0",
"resolved": "https://registry.npm.taobao.org/mime-db/download/mime-db-1.46.0.tgz?cache=0&sync_timestamp=1613194712759&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime-db%2Fdownload%2Fmime-db-1.46.0.tgz",
"integrity": "sha1-Ymd0in95lZTePLyM3pHe80lmHO4="
},
"mime-types": {
"version": "2.1.29",
"resolved": "https://registry.npm.taobao.org/mime-types/download/mime-types-2.1.29.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime-types%2Fdownload%2Fmime-types-2.1.29.tgz",
"integrity": "sha1-HUq3faZLkfX3JInfKSNlY3VLsbI=",
"requires": {
"mime-db": "1.46.0"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz?cache=0&sync_timestamp=1607433842694&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.1.2.tgz",
"integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk="
},
"negotiator": {
"version": "0.6.2",
"resolved": "https://registry.npm.taobao.org/negotiator/download/negotiator-0.6.2.tgz?cache=0&sync_timestamp=1589682752355&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnegotiator%2Fdownload%2Fnegotiator-0.6.2.tgz",
"integrity": "sha1-/qz3zPUlp3rpY0Q2pkiD/+yjRvs="
},
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npm.taobao.org/object-assign/download/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npm.taobao.org/on-finished/download/on-finished-2.3.0.tgz",
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
"requires": {
"ee-first": "1.1.1"
}
},
"parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npm.taobao.org/parseurl/download/parseurl-1.3.3.tgz",
"integrity": "sha1-naGee+6NEt/wUT7Vt2lXeTvC6NQ="
},
"path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npm.taobao.org/path-to-regexp/download/path-to-regexp-0.1.7.tgz",
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
},
"proxy-addr": {
"version": "2.0.6",
"resolved": "https://registry.npm.taobao.org/proxy-addr/download/proxy-addr-2.0.6.tgz",
"integrity": "sha1-/cIzZQVEfT8vLGOO0nLK9hS7sr8=",
"requires": {
"forwarded": "~0.1.2",
"ipaddr.js": "1.9.1"
}
},
"qs": {
"version": "6.7.0",
"resolved": "https://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz?cache=0&sync_timestamp=1616096451342&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fqs%2Fdownload%2Fqs-6.7.0.tgz",
"integrity": "sha1-QdwaAV49WB8WIXdr4xr7KHapsbw="
},
"range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npm.taobao.org/range-parser/download/range-parser-1.2.1.tgz",
"integrity": "sha1-PPNwI9GZ4cJNGlW4SADC8+ZGgDE="
},
"raw-body": {
"version": "2.4.0",
"resolved": "https://registry.npm.taobao.org/raw-body/download/raw-body-2.4.0.tgz",
"integrity": "sha1-oc5vucm8NWylLoklarWQWeE9AzI=",
"requires": {
"bytes": "3.1.0",
"http-errors": "1.7.2",
"iconv-lite": "0.4.24",
"unpipe": "1.0.0"
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz?cache=0&sync_timestamp=1589682795646&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsafe-buffer%2Fdownload%2Fsafe-buffer-5.1.2.tgz",
"integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0="
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz?cache=0&sync_timestamp=1589682784154&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsafer-buffer%2Fdownload%2Fsafer-buffer-2.1.2.tgz",
"integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo="
},
"send": {
"version": "0.17.1",
"resolved": "https://registry.npm.taobao.org/send/download/send-0.17.1.tgz",
"integrity": "sha1-wdiwWfeQD3Rm3Uk4vcROEd2zdsg=",
"requires": {
"debug": "2.6.9",
"depd": "~1.1.2",
"destroy": "~1.0.4",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
"http-errors": "~1.7.2",
"mime": "1.6.0",
"ms": "2.1.1",
"on-finished": "~2.3.0",
"range-parser": "~1.2.1",
"statuses": "~1.5.0"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1607566533140&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
"integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
"requires": {
"ms": "2.0.0"
},
"dependencies": {
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&sync_timestamp=1607433842694&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.1.tgz?cache=0&sync_timestamp=1607433842694&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.1.1.tgz",
"integrity": "sha1-MKWGTrPrsKZvLr5tcnrwagnYbgo="
}
}
},
"serve-static": {
"version": "1.14.1",
"resolved": "https://registry.npm.taobao.org/serve-static/download/serve-static-1.14.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fserve-static%2Fdownload%2Fserve-static-1.14.1.tgz",
"integrity": "sha1-Zm5jbcTwEPfvKZcKiKZ0MgiYsvk=",
"requires": {
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"parseurl": "~1.3.3",
"send": "0.17.1"
}
},
"setprototypeof": {
"version": "1.1.1",
"resolved": "https://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.1.1.tgz",
"integrity": "sha1-fpWsskqpL1iF4KvvW6ExMw1K5oM="
},
"socket.io": {
"version": "4.0.0",
"resolved": "https://registry.npm.taobao.org/socket.io/download/socket.io-4.0.0.tgz",
"integrity": "sha1-7khKldxqOGmEkar2O27B887qwKg=",
"requires": {
"@types/cookie": "^0.4.0",
"@types/cors": "^2.8.8",
"@types/node": ">=10.0.0",
"accepts": "~1.3.4",
"base64id": "~2.0.0",
"debug": "~4.3.1",
"engine.io": "~5.0.0",
"socket.io-adapter": "~2.2.0",
"socket.io-parser": "~4.0.3"
}
},
"socket.io-adapter": {
"version": "2.2.0",
"resolved": "https://registry.npm.taobao.org/socket.io-adapter/download/socket.io-adapter-2.2.0.tgz",
"integrity": "sha1-Q6+RV8RgnnS4rdxoZ4c6x+tI/aI="
},
"socket.io-parser": {
"version": "4.0.4",
"resolved": "https://registry.npm.taobao.org/socket.io-parser/download/socket.io-parser-4.0.4.tgz?cache=0&sync_timestamp=1610669810516&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsocket.io-parser%2Fdownload%2Fsocket.io-parser-4.0.4.tgz",
"integrity": "sha1-nqIbDWFQjRgZbvBKLGuatjD0wrA=",
"requires": {
"@types/component-emitter": "^1.2.10",
"component-emitter": "~1.3.0",
"debug": "~4.3.1"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz?cache=0&sync_timestamp=1589682764497&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.6.1.tgz",
"integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
"dev": true
},
"source-map-support": {
"version": "0.5.19",
"resolved": "https://registry.npm.taobao.org/source-map-support/download/source-map-support-0.5.19.tgz?cache=0&sync_timestamp=1589682814927&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map-support%2Fdownload%2Fsource-map-support-0.5.19.tgz",
"integrity": "sha1-qYti+G3K9PZzmWSMCFKRq56P7WE=",
"dev": true,
"requires": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"statuses": {
"version": "1.5.0",
"resolved": "https://registry.npm.taobao.org/statuses/download/statuses-1.5.0.tgz?cache=0&sync_timestamp=1609654014762&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstatuses%2Fdownload%2Fstatuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
"toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.npm.taobao.org/toidentifier/download/toidentifier-1.0.0.tgz",
"integrity": "sha1-fhvjRw8ed5SLxD2Uo8j013UrpVM="
},
"ts-node": {
"version": "9.1.1",
"resolved": "https://registry.npm.taobao.org/ts-node/download/ts-node-9.1.1.tgz?cache=0&sync_timestamp=1607350719034&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fts-node%2Fdownload%2Fts-node-9.1.1.tgz",
"integrity": "sha1-UamkUKPpWUAb2l8ASnLVS5NtN20=",
"dev": true,
"requires": {
"arg": "^4.1.0",
"create-require": "^1.1.0",
"diff": "^4.0.1",
"make-error": "^1.1.1",
"source-map-support": "^0.5.17",
"yn": "3.1.1"
}
},
"type-is": {
"version": "1.6.18",
"resolved": "https://registry.npm.taobao.org/type-is/download/type-is-1.6.18.tgz",
"integrity": "sha1-TlUs0F3wlGfcvE73Od6J8s83wTE=",
"requires": {
"media-typer": "0.3.0",
"mime-types": "~2.1.24"
}
},
"typescript": {
"version": "4.2.3",
"resolved": "https://registry.npm.taobao.org/typescript/download/typescript-4.2.3.tgz",
"integrity": "sha1-OQYtgBmRLUNyYpjwlJPVmASMHOM=",
"dev": true
},
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npm.taobao.org/unpipe/download/unpipe-1.0.0.tgz?cache=0&sync_timestamp=1589682745059&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funpipe%2Fdownload%2Funpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
},
"utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npm.taobao.org/utils-merge/download/utils-merge-1.0.1.tgz",
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
},
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz",
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
},
"ws": {
"version": "7.4.4",
"resolved": "https://registry.npm.taobao.org/ws/download/ws-7.4.4.tgz?cache=0&sync_timestamp=1615063746103&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fws%2Fdownload%2Fws-7.4.4.tgz",
"integrity": "sha1-ODvJdCyyAikskHfOq29gR7F/LVk="
},
"yn": {
"version": "3.1.1",
"resolved": "https://registry.npm.taobao.org/yn/download/yn-3.1.1.tgz",
"integrity": "sha1-HodAGgnXZ8HV6rJqbkwYUYLS61A=",
"dev": true
}
}
}

21
package.json Normal file
View File

@ -0,0 +1,21 @@
{
"name": "wschat-ng",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "szdytom <szdytom@163.com>",
"license": "MIT",
"devDependencies": {
"@types/express": "^4.17.11",
"@types/socket.io": "^2.1.13",
"ts-node": "^9.1.1",
"typescript": "^4.2.3"
},
"dependencies": {
"express": "^4.17.1",
"socket.io": "^4.0.0"
}
}

2
public/asset/jquery.js vendored Normal file

File diff suppressed because one or more lines are too long

28
public/index.html Normal file
View File

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>
<title>WebSocket Chat Room</title>
<link rel="stylesheet" type="text/css" href="./style.css" />
</head>
<body>
<div id="message"></div>
<textarea id="send" placeholder="Say something" spellcheck="false"></textarea>
<div class="top-box">
<button class="send-button" onclick="clear_message()">Clear</button>
<p><input id="scroll-option" type="checkbox" checked /> Enable auto scroll</p>
<p>Version: WS_1.2</p>
</div>
<div class="bottom-box">
<span class="note">Press Ctrl + Enter to send </span>
<button class="send-button" onclick="send()">Send</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/socket.io-client@4.0.0/dist/socket.io.min.js"></script>
<script src="./asset/jquery.js"></script>
<script src="./script.js"></script>
</body>
</html>

200
public/script.js Normal file
View File

@ -0,0 +1,200 @@
let username;
let is_reconnection = false;
let last_command = null;
const server = `ws://${location.host}`;
const ws = init();
function clear_message() {
$('#message').empty();
}
function clear_send() {
$('#send').val('');
}
function format_time(time) {
return `${time.getMonth() + 1}-${time.getDate()} ${time.getHours()}:${time.getMinutes()}:${time.getSeconds()}`;
}
if (String.prototype.replaceAll === undefined) {
String.prototype.replaceAll = function(before, after) {
let res = '';
let matched = 0;
for (let i = 0; i < this.length; i += 1) {
if (this[i] === before[matched]) {
matched += 1;
if (matched === before.length) {
res += after;
matched = 0;
}
} else {
for (let j = i - matched; j <= i; j += 1) {
res += this[j];
}
matched = 0;
}
}
for (let i = this.length - matched; i < this.length; ++i) {
res += this[i];
}
return res;
};
}
function write_message(data) {
const message = data.msg;
let message_class = '';
let message_source = data.from;
if (data.type === 'system-message') {
message_class = 'msg-from-info';
message_source = 'SYSTEM INFO';
} else if (data.type === 'command-block') {
message_class = 'msg-from-cb';
message_source = 'COMMAND BLOCK';
}
$('#message').append(
`
<div class="msg">
<span class="msg-from ${message_class} ${(data.is_private ? 'msg-private' : '')}">
${message_source}
<span class="msg-time">${format_time(new Date())}</span>
</span>
<br>
<span class="msg-content">
<pre>${message}</pre>
</span>
</div>
`
);
scroll_to_bottom();
}
function init() {
clear_message();
login_name();
const ws = new io(server);
console.log('ws: ', ws);
ws.on('connect', () => {
if (is_reconnection) {
write_message({
from: 'INFO',
msg: 'Reconnected.',
is_private: true,
});
} else {
write_message({
from: 'INFO',
msg: 'Connected.',
is_private: true,
});
is_reconnection = true;
}
ws.emit('set-name', username);
});
ws.on('system-message', evt => {
let msg;
if (evt.type === 'join-room') {
msg = `${evt.data.user} joined room ${evt.data.room}.`;
}
write_message({
type: 'system-message',
msg: msg,
is_private: true,
});
});
ws.on('new message', evt => {
write_message({
type: 'normal',
from: evt.sender,
msg: evt.data,
});
});
ws.on('command-block-reply', data => {
write_message({
type: 'command-block',
msg: `>> ${last_command}\n<- ${data}`,
is_private: true,
});
});
ws.on('disconnect', () => {
write_message({
type: 'system-message',
msg: 'Disconnected.',
is_private: true,
});
});
return ws;
}
function open_prompt(content, tilte) {
return window.prompt(content);
}
function login_name() {
username = open_prompt('[Login] Input your name');
}
function send() {
let data = $('#send').val();
if (data === '') {
return;
}
if (data === '/clear' || data === '/cls') {
clear_message();
clear_send();
return;
}
if (data.startsWith('/')) {
// a command
last_command = data;
}
if (data.startsWith('/su')) {
// a administrator login command.
// now ask for passcode
const code = open_prompt('Please input the passcode');
data = `/su ${code}`;
}
if (ws.connected) {
ws.emit('message', data);
} else {
write_message({
type: 'system-message',
msg: 'Socket not connected or has already disconnected. Failed to send.',
is_private: true,
});
}
clear_send();
}
function scroll_to_bottom() {
if ($('#scroll-option').is(':checked')) {
document.getElementById('message').scrollTop = document.getElementById('message').scrollHeight;
}
}
document.addEventListener('keydown', function(key_event) {
if (key_event.code === 'Enter' && key_event.ctrlKey) {
key_event.preventDefault();
send();
}
});

103
public/style.css Normal file
View File

@ -0,0 +1,103 @@
body {
font-family: sans-serif;
margin: 0;
overflow: hidden;
}
textarea {
border: none;
}
input {
background-color: #fcd363;
}
button {
border: none;
padding: 10px;
border-radius: 5px;
background-color: #5bb2ec;
color: #fff;
}
pre {
margin: 0;
}
.note {
margin-right: 5px;
color: #888888;
}
#message {
background-color: #f2f2f2;
margin: 0;
font-size: 20px;
padding: 20px;
height: 70vh;
width: calc(100vw - 20px);
color: #000;
font-family: 'Fira Code', Consolas, monospace;
overflow-y: scroll;
word-wrap: break-word;
}
#send {
background-color: #fff;
margin: 0;
font-size: 20px;
padding: 30px;
width: 100vw;
height: 30vh;
}
.send-button {
font-size: 20px;
}
.bottom-box {
position: absolute;
bottom: 30px;
right: 30px;
}
.top-box {
position: absolute;
top: 20px;
right: 20px;
}
.msg {
margin-top: 15px;
}
.msg-content {
color: #606266;
}
.msg-private::after {
content: " PRIVATE";
color: #F7BA2A;
}
.msg-from {
font-weight: 600;
color: #303133;
}
.msg-time {
font-weight: normal;
color: #C0C4CC;
}
.msg-from::before {
content: "@ ";
}
.msg-from-info {
color: #5bb2ec;
}
.msg-from-cb {
color: #000000;
}

124
src/command.ts Normal file
View File

@ -0,0 +1,124 @@
import { User, validate_username, kill_username, register_username, grant_access, find_user } from './user';
import { Server as SocketServer, Socket } from 'socket.io';
import { set_room, all_rooms } from './room';
export function is_command(cmd: string) {
return cmd.startsWith('/');
};
function command_reply(msg: string, socket: Socket) {
socket.emit('command-block-reply', msg);
}
function mask_room_name(name: string) {
if (name === 'global') {
return name;
}
return `costum-room#${name}`;
}
function unmask_room_name(name: string) {
if (name === 'global') {
return name;
}
if (name.startsWith('costum-room#')) {
return name.substring(12);
}
return null;
}
export function run_command(cmd: string, uid: string, users: Map<string, User>, io: SocketServer, silent: boolean = false) {
if (!is_command(cmd)) { return; }
const user = users.get(uid);
const socket = user.socket;
const command_reply = (msg: string) => {
if (silent) { return; }
socket.emit('command-block-reply', msg);
};
const cmd_set = cmd.split(/\s+/);
if (cmd.startsWith('/disconnect')) {
command_reply('Diconnecting. Bye!',);
socket.disconnect();
return;
}
if (cmd.startsWith('/join')) {
const room_name = cmd_set[1];
set_room(room_name);
const masked_name = mask_room_name(room_name);
socket.join(masked_name);
command_reply('OK.');
return;
}
if (cmd.startsWith('/ls')) {
if (cmd_set[1] === 'own') {
command_reply(JSON.stringify(
Array
.from(socket.rooms)
.map(x => unmask_room_name(x))
.filter(x => x !== null)
));
return;
}
command_reply(JSON.stringify(all_rooms()));
return;
}
if (cmd.startsWith('/rename')) {
const new_name = cmd_set[1].toString();
if (validate_username(new_name)) {
kill_username(user.name);
register_username(new_name, user.id);
user.name = new_name;
command_reply(`Renamed to ${new_name}.`);
} else {
command_reply('Failed to rename.');
}
return;
}
if (cmd.startsWith('/whoami')) {
command_reply(JSON.stringify({
name: user.name,
id: user.id,
is_administrator: user.is_administrator,
}));
return;
}
if (cmd.startsWith('/ps')) {
let result = '[';
users.forEach(user => {
result += `"${user.name}",`;
});
result = result.substring(0, result.length - 1) + ']';
command_reply(result);
return;
}
if (cmd.startsWith('/su')) {
const code = cmd_set[1];
grant_access(user, code);
command_reply('You are administartor now.');
return;
}
if (cmd.startsWith('/resign')) {
user.is_administrator = false;
command_reply('OK.');
return;
}
if (cmd.startsWith('/filter')) {
const filter_string = cmd.substring('/filter'.length);
command_reply(JSON.stringify(find_user(filter_string, users, uid)));
return;
}
};

65
src/index.ts Normal file
View File

@ -0,0 +1,65 @@
import SocketIO = require('socket.io');
import Express = require('express');
import http_server = require('http');
import path = require('path');
import { kill_username, register_username, User } from './user';
import { is_command, run_command } from './command';
const app = Express();
const http = new http_server.Server(app);
const io = new SocketIO.Server(http);
const users = new Map<string, User>();
io.on('connection', socket => {
const user: User = {
id: socket.id,
name: socket.id,
socket: socket,
is_administrator: false,
};
users.set(socket.id, user);
register_username(user.name, user.id);
socket.on('message', msg => {
if (is_command(msg)) {
run_command(msg, user.id, users, io);
return;
}
io.in(Array.from(socket.rooms)).emit('new message', {
type: 'text-message',
data: msg,
sender: user.name,
});
});
socket.on('set-name', name => {
run_command(`/rename ${name}`, user.id, users, io, true);
});
socket.on('disconnect', () => {
kill_username(user.name);
users.delete(user.id);
});
});
app.use('/', Express.static(path.join(__dirname, '../public')));
const server_port = parseInt(process.env.PORT) | 4412;
http.listen(server_port, () => {
console.log(`Server started on port ${server_port}.`);
});
process.on('SIGINT', () => {
console.log('\nShutting server...');
users.forEach(u => {
u.socket.disconnect();
console.log(`Disconnected user ${u.name}.`);
});
http.close(() => {
console.log('Closed.');
process.exit(0);
});
});

15
src/room.ts Normal file
View File

@ -0,0 +1,15 @@
const room_list = new Array();
export function set_room(name: string) {
if (!check_room(name)) {
room_list.push(name);
}
};
export function check_room(name: string) {
return room_list.includes(name);
};
export function all_rooms() {
return room_list;
};

162
src/user.ts Normal file
View File

@ -0,0 +1,162 @@
import { Socket } from 'socket.io';
export interface User {
socket: Socket
id: string
name: string
is_administrator: boolean
};
let username_to_id_map = new Map<string, string>();
export function register_username(name: string, id: string) {
if (!validate_username(name)) {
return false;
}
username_to_id_map.set(name, id);
return true;
};
export function kill_username(name: string) {
username_to_id_map.delete(name);
}
export function validate_username(name: string) {
return !username_to_id_map.has(name) && /^[a-zA-Z0-9_][a-zA-Z0-9_\@\-\.\#]{2,}$/.test(name);
};
export function find_user_by_name(name: string) {
return username_to_id_map.get(name);
};
function splite_toplevel_concat(filter_string: string) {
let matched = 0;
let buf = '';
let res: string[] = [];
for (let c of filter_string) {
if (c === '(') {
matched += 1;
} else if (c === ')') {
matched -= 1;
}
if (c === '+' && matched === 0) {
res.push(buf);
buf = '';
} else {
buf += c;
}
}
if (buf !== '') { res.push(buf); }
return res;
}
export function find_user(filter_string_raw: string, users: Map<string, User>, owner_id: string): string[] {
const parse_lower = (filter: string) => {
return find_user(filter, users, owner_id);
};
// trim spaces (start and end)
const filter_string = filter_string_raw.replace(/(^\s*)|(\s*$)/g, '');
const arrayed_map = Array.from(username_to_id_map);
const id_list = arrayed_map.map(v => v[1]);
const toplevel_concated = splite_toplevel_concat(filter_string);
if (toplevel_concated.length > 1) {
return toplevel_concated.reduce((acc: string[], sub_filter: string): string[] => {
return acc.concat(parse_lower(sub_filter));
}, []);
}
if (!filter_string.startsWith('@')) {
const res = find_user_by_name(filter_string);
if (res) { return [res]; }
return [];
}
if (filter_string === '@1') { return parse_lower('@1(@a)'); }
if (filter_string === '@A') { return parse_lower('@A(@a)'); }
if (filter_string === '@a') {
return id_list;
}
if (filter_string === '@o') {
return id_list.filter(id => id !== owner_id);
}
if (filter_string === '@i') {
return [owner_id];
}
if (/^\@1\(.*\)$/.test(filter_string)) {
const sub_filter = filter_string.match(/^\@1\((.*)\)$/)[1];
const res = parse_lower(sub_filter);
return [res[Math.floor(res.length * Math.random())]];
}
if (/^\@I\(.*\)$/.test(filter_string)) {
const sub_filter = filter_string.match(/^\@I\((.*)\)$/)[1];
if (users.get(sub_filter)) { return [sub_filter]; }
return [];
}
if (/^\@A\(.*\)$/.test(filter_string)) {
const sub_filter = filter_string.match(/^\@A\((.*)\)$/)[1];
const res = parse_lower(sub_filter);
return res.filter(id => users.get(id).is_administrator);
}
if (/^\@R\([^\&]*\)\&\(.*\)$/.test(filter_string)) {
const [, regex_filter, sub_filter] = filter_string.match(/^\@R\(([^\&]*)\)\&\((.*)\)$/);
const target_regex = new RegExp(regex_filter);
const sub_res = parse_lower(sub_filter);
return sub_res
.map(id => [users.get(id).name, id])
.filter(([name,]) => target_regex.test(name))
.map(([,id]) => id);
}
if (/^\@r\([^\&]*\)\&\(.*\)$/.test(filter_string)) {
const [, regex_filter, sub_filter] = filter_string.match(/^\@r\(([^\&]*)\)\&\((.*)\)$/);
return parse_lower(`@R(^${regex_filter}$)&(${sub_filter})`);
}
if (/^\@r\(.*\)$/.test(filter_string)) {
return parse_lower(`${filter_string}&(@a)`);
}
if (/^\@R\(.*\)$/.test(filter_string)) {
return parse_lower(`${filter_string}&(@a)`);
}
if (/^\@-\([^\&]*\)\&\(.*\)$/.test(filter_string)) {
const [, full_expr, sub_expr] = filter_string.match(/^\@-\(([^\&]*)\)\&\((.*)\)$/);
const full_res = parse_lower(full_expr);
const sub_res = parse_lower(sub_expr);
return full_res.filter(id => !sub_res.includes(id));
}
return [];
}
let admin_passcode: string;
function refreash_admin_passcode() {
admin_passcode = Math.random().toString();
console.log('Admin passcode is:', admin_passcode);
return admin_passcode;
}
refreash_admin_passcode();
export function grant_access(user: User, code: string) {
if (admin_passcode === code) {
user.is_administrator = true;
}
};