Skip to content

Commit a3201f3

Browse files
author
cmd1152
committed
init
1 parent 839de2d commit a3201f3

File tree

3 files changed

+255
-0
lines changed

3 files changed

+255
-0
lines changed

HackChat-BotLib.js

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
let modules = {
2+
"WebSocket" : "ws"
3+
}
4+
for (let module in modules) {
5+
let module_name = module;
6+
let module_path = modules[module_name];
7+
try {
8+
require(module_path);
9+
} catch (e) {
10+
throw new Error(`导入${module_name}失败(位于${module_path})`)
11+
}
12+
global[module_name] = require(module_path);
13+
}
14+
15+
class Client {
16+
constructor(server_ip) {
17+
this._ws = new WebSocket(server_ip);
18+
this._ws.onopen = () => {
19+
this.onjoin();
20+
}
21+
this._ws.onclose = () => {
22+
this.joined = false;
23+
this.onclose(this._closereason);
24+
delete this._closereason;
25+
}
26+
this._ws.onmessage = (event) => {
27+
let hc = JSON.parse(event.data);
28+
if (hc.cmd == "onlineSet") {
29+
let tnick = [...hc.nicks];
30+
this.nick = tnick.pop();
31+
if (!this.joined) {
32+
setInterval(()=>{
33+
if (this.ping <= 0) return;
34+
let lastpingtime = this.pingtime || 0;
35+
if (lastpingtime + this.ping < (new Date()).getTime()) {
36+
this.pingtime = (new Date()).getTime();
37+
this.check = true;
38+
this._send({
39+
cmd: '' //rl最小
40+
})
41+
}
42+
43+
},1000)
44+
}
45+
this.joined = true;
46+
this.onjoined()
47+
}
48+
if (hc.cmd == "warn") {
49+
setTimeout(()=>{
50+
if (!this.joined) this.joinfailed(hc.text)
51+
},500);
52+
}
53+
if (hc.channel) {
54+
if (hc.channel != this.channel) {
55+
this.channel = hc.channel;
56+
this.onchangechannel(hc.channel);
57+
}
58+
}
59+
if (hc.cmd == "warn" && hc.text.startsWith(`Command not found, did you mean: `) && this.check) {
60+
this.check = false;
61+
return;
62+
}
63+
if (hc.cmd == "onlineSet") {
64+
this.users = hc.users
65+
this.nicks = hc.nicks
66+
}
67+
if (hc.cmd == "onlineAdd") {
68+
let payload = {...hc}
69+
delete payload.cmd
70+
this.users.push(payload)
71+
this.nicks.push(hc.nick)
72+
this.nicks=[...new Set(this.nicks)]
73+
}
74+
if (hc.cmd == "onlineRemove") {
75+
this.users = this.users.filter(function (item) {
76+
return item.nick !== hc.nick;
77+
});
78+
let index = this.nicks.indexOf(hc.nick);
79+
if (index !== -1) this.nicks.splice(index, 1);
80+
this.nicks=[...new Set(this.nicks)]
81+
}
82+
if (hc.cmd == "updateUser") {
83+
let payload = {...hc}
84+
delete payload.cmd
85+
this.users = this.users.filter(function (item) {
86+
return item.nick !== hc.nick;
87+
});
88+
this.users.push(payload)
89+
}
90+
if (hc.cmd == "info" && /^([a-zA-Z0-9_]{1,24}) is now ([a-zA-Z0-9_]{1,24})$/.test(hc.text)) {
91+
let changenickuser = hc.text.match(/^([a-zA-Z0-9_]{1,24}) is now ([a-zA-Z0-9_]{1,24})$/);
92+
if (changenickuser[1] == this.nick) {
93+
this.nick = changenickuser[2];
94+
}
95+
return this.onmessage(
96+
event.data,
97+
{
98+
cmd: 'changeNick',
99+
nick: changenickuser[1],
100+
to_nick: changenickuser[2]
101+
}
102+
)
103+
}
104+
if (hc.cmd == "emote") hc.msg = hc.text.substring(hc.nick.length+2);
105+
if (hc.cmd == "info" && hc.type == "whisper" && typeof hc.from == "string") {
106+
hc.nick = hc.from;
107+
hc.msg = hc.text.substring(hc.from.length+12);
108+
}
109+
this.onmessage(event.data,hc);
110+
}
111+
["onclose","onchangechannel","joinfailed","oncaptcha","onjoin","onjoined","onmessage"].forEach(func=>{
112+
this[func] = () => {}
113+
});
114+
["channel","nick","joined","ping","pingtime","check"].forEach(ve=>{
115+
this[ve] = false
116+
});
117+
this.customId = 0;
118+
}
119+
join(pack) {
120+
return new Promise(resolve => {
121+
if (this._ws.readyState !== 1) resolve(false); //连接没有打开,加入失败
122+
pack.cmd = "join";
123+
this.channel = pack.channel;
124+
this._send(pack);
125+
})
126+
}
127+
_send(obj) {
128+
this._ws.send(JSON.stringify(obj));
129+
}
130+
close(reason) {
131+
this._closereason = reason;
132+
this._ws.close();
133+
}
134+
chat(text,custom_id=false) {
135+
let pack = {
136+
cmd: 'chat',
137+
text: text
138+
}
139+
if (custom_id) pack.customId = custom_id;
140+
this._send(pack);
141+
return true;
142+
}
143+
updatemessage(custom_id,mode,text) {
144+
if (!custom_id.toString() || !mode) return false;
145+
if (!["overwrite","append","prepend","complete"].includes(mode)) return false;
146+
this._send({
147+
cmd: 'updateMessage',
148+
customId: custom_id.toString(),
149+
mode: mode,
150+
text: text
151+
})
152+
}
153+
getcustomId() {
154+
return customId.toString();
155+
customId += 1;
156+
}
157+
}
158+
159+
module.exports = Client

index.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
let Client = require("./HackChat-BotLib.js");
2+
let client = new Client("wss://hack.chat/chat-ws"); //创建一个客户端,连接到服务器
3+
let join_channel = "lounge"
4+
5+
/*** 连接断开处理 ***/
6+
client.onclose = (reason) => {
7+
//你可以手动使用 client.close(reason) 断开
8+
console.log(`连接断开`,reason) //重新创建客户端或者提示内容
9+
process.exit(0);
10+
}
11+
12+
/*** 发现机器人被移动或者踢出了处理 ***/
13+
client.onchangechannel = (channel) => {
14+
client.close("被踢出或者移动到了"+channel)
15+
}
16+
17+
18+
/*** 加入成功后 ***/
19+
client.onjoined = () => {
20+
client.chat("Hello, world!");
21+
//你可以使用 client.chat(text,customId) 来发送一个带有customID的消息,这可以让你通过
22+
// client.updatemessage(customId,mode,text) 来修改你的消息
23+
// mode 支持4种: overwrite append prepend complete
24+
// 覆盖文本 添加文本到末尾 添加文本到前面 完成更新(这会让这个消息不能再被upDateMessage)
25+
// customId建议使用 client.getcustomId() 来生成一个不重复的id
26+
console.log("加入成功");
27+
//client.updatemessage和client.chat都返回一个布尔值代表这个操作是否初步执行成功(如果出现了RL导致不能执行,那么还是会返回true)
28+
}
29+
30+
/*** 加入失败 ***/
31+
client.joinfailed = (reason) => {
32+
console.log("加入失败",reason);
33+
client.close();
34+
}
35+
/*** 验证码 ***/
36+
client.oncaptcha = () => {
37+
console.log("频道要求验证码!");
38+
//你可以使用 client._send({cmd:'chat',text:'验证码'}) 来通过验证码,但这一般不常用
39+
client.close()
40+
}
41+
42+
43+
44+
/*** 加入频道 ***/
45+
client.onjoin = () => {
46+
client.join({ //发送加入数据包,这个返回一个 Promise ,告诉你是否加入成功
47+
channel: join_channel,
48+
nick: 'my_bot',
49+
password: '123456'
50+
})
51+
//也可以读取 joined 判断有没有加入频道
52+
}
53+
54+
client.ping = 10000 //检测频率(单位ms),可以检测是否被踢出,设置为0不检查,越大越久才检测到,越小越容易rl,最小为1000
55+
56+
57+
//你可以读取 client.users 和 client.nicks ,包含了详细的在线列表
58+
//client.nick 是机器人的名称(理论上实时更新)
59+
60+
61+
/*** client.onmessage 才是重头戏! ***/
62+
client.onmessage = (raw,data) => {
63+
//raw为服务器发送的原始json,data为经过优化并解析的json
64+
//data优化了名称修改和emote识别
65+
//添加 changeNick 的cmd:
66+
/*
67+
if (data.cmd == "changeNick") {
68+
client.chat(`${data.nick}刚刚改名为${data.to_nick}`)
69+
}
70+
*/
71+
//修改了 emote 的cmd,添加了个 msg参数,显示用户原内容
72+
/*
73+
if (data.cmd == "emote") {
74+
client.chat(`${data.nick}刚刚用emote说${data.msg}`)
75+
}
76+
*/
77+
//修改了 whisper 的cmd,添加了个 msg参数,显示用户私信的内容,如果是机器人私信用户,就没有这个
78+
//还添加了nick
79+
/*
80+
if (data.cmd == "emote") {
81+
client.chat(`${data.nick}刚刚私信我说${data.msg}`)
82+
}
83+
*/
84+
console.log(raw);
85+
}

package.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "hackchatbotlib",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"author": "",
10+
"license": "ISC"
11+
}

0 commit comments

Comments
 (0)