280 lines
7.7 KiB
JavaScript
280 lines
7.7 KiB
JavaScript
const client = require("./client")
|
|
const axios = require('axios');
|
|
const http = require('http');
|
|
const fs = require('fs');
|
|
const { once } = require("node:events");
|
|
const dateformat = require('@matteo.collina/dateformat');
|
|
const WebSocket = require('ws');
|
|
|
|
const logger = client.logger
|
|
const steamUser = client.steamUser
|
|
|
|
fs.mkdir("./logs", { recursive: true }, (err) => {
|
|
if (err) {
|
|
logger.error("an error occurred while creating the logs directory: " + err);
|
|
}
|
|
});
|
|
|
|
async function sendMsg(req, res) {
|
|
let body = '';
|
|
req.on('data', chunk => {
|
|
body += chunk.toString(); // 将Buffer转换为字符串
|
|
});
|
|
|
|
await once(req, 'end');
|
|
|
|
let requests = JSON.parse(body);
|
|
|
|
console.log(requests)
|
|
|
|
try {
|
|
let resp = await sendFriendMessage(requests.id, requests.msg);
|
|
res.statusCode = 200;
|
|
res.setHeader('Content-Type', 'text/plain');
|
|
let messageEncoded = await messageToJson(resp, true);
|
|
res.end(messageEncoded);
|
|
} catch (err) {
|
|
logger.error("failed to send friend message", err);
|
|
res.statusCode = 500;
|
|
res.setHeader('Content-Type', 'text/plain');
|
|
res.end('Internal Server Error\n');
|
|
}
|
|
}
|
|
|
|
function sendFriendMessage(uid, msg) {
|
|
return new Promise((resolve, reject) => {
|
|
client.steamUser.chat.sendFriendMessage(uid, msg, (err, response) => {
|
|
if (err) {
|
|
reject(err);
|
|
return
|
|
}
|
|
|
|
client.getUserInfo(client.steamUser.steamID).then((sender) => {
|
|
fs.appendFile("./logs/chat.jsonl", JSON.stringify({
|
|
date: dateToString(response.server_timestamp),
|
|
echo: true,
|
|
id: uid,
|
|
name: sender.player_name,
|
|
message: response.modified_message,
|
|
ordinal: response.ordinal,
|
|
}) + "\n", (e) => {
|
|
if (e) {
|
|
logger.error("an error occurred while writing chat log file: " + e);
|
|
}
|
|
});
|
|
})
|
|
|
|
resp = {
|
|
server_timestamp: response.server_timestamp,
|
|
steamid_friend: uid,
|
|
message: response.modified_message,
|
|
ordinal: response.ordinal,
|
|
}
|
|
onSteamMessage(resp, true);
|
|
resolve(resp);
|
|
})
|
|
});
|
|
}
|
|
|
|
function logSendMsg(uid, response) {
|
|
client.getUserInfo(client.steamUser.steamID).then((sender) => {
|
|
fs.appendFile("./logs/chat.jsonl", JSON.stringify({
|
|
date: dateToString(response.server_timestamp),
|
|
echo: true,
|
|
id: uid,
|
|
name: sender.player_name,
|
|
message: response.modified_message,
|
|
ordinal: response.ordinal,
|
|
}) + "\n", (e) => {
|
|
if (e) {
|
|
logger.error("an error occurred while writing chat log file: " + e);
|
|
}
|
|
});
|
|
})
|
|
}
|
|
|
|
async function sendImg(req, res) {
|
|
let body = '';
|
|
req.on('data', chunk => {
|
|
body += chunk.toString(); // 将Buffer转换为字符串
|
|
});
|
|
|
|
await once(req, 'end');
|
|
|
|
let requests = JSON.parse(body);
|
|
|
|
res.setHeader('Content-Type', 'text/plain');
|
|
try {
|
|
let url = await sendImageToUser(requests.id, requests.img, requests.url);
|
|
res.statusCode = 200;
|
|
res.end(url);
|
|
} catch (err) {
|
|
const { code = 500, message = "Internal Server Error" } = err;
|
|
res.statusCode = code;
|
|
res.end(message);
|
|
}
|
|
}
|
|
|
|
function sendImageToUser(uid, img, url) {
|
|
return new Promise(async (resolve, reject) => {
|
|
if (img) {
|
|
console.log({
|
|
uid: uid,
|
|
img: img.length,
|
|
});
|
|
} else {
|
|
console.log({
|
|
uid: uid,
|
|
url: url,
|
|
});
|
|
}
|
|
|
|
if (url) {
|
|
img = await readUrlAsBuffer(url)
|
|
} else if (img) {
|
|
img = Buffer.from(img, 'base64');
|
|
} else {
|
|
reject({ code: 400, message: "Bad Request" });
|
|
return;
|
|
}
|
|
|
|
client.steamCommunity.sendImageToUser(uid, img, function (err, imageUrl) {
|
|
if (err) {
|
|
logger.error("an error occurred while sending image: ", err);
|
|
client.steamUser.webLogOn();
|
|
reject({});
|
|
return
|
|
}
|
|
|
|
resolve(imageUrl);
|
|
});
|
|
})
|
|
}
|
|
|
|
async function readUrlAsBuffer(url) {
|
|
try {
|
|
const response = await axios.get(url, { responseType: 'arraybuffer' });
|
|
return Buffer.from(response.data);
|
|
} catch (err) {
|
|
throw new Error(`Failed to fetch URL: ${err.message}`);
|
|
}
|
|
}
|
|
|
|
function readFileAsBuffer(filePath) {
|
|
return new Promise((resolve, reject) => {
|
|
fs.readFile(filePath, (err, data) => {
|
|
if (err) {
|
|
return reject(err);
|
|
}
|
|
resolve(data);
|
|
});
|
|
});
|
|
}
|
|
|
|
function dateToString(date) {
|
|
return dateformat(date, "yyyy-mm-dd HH:MM:ss.l");
|
|
}
|
|
|
|
async function handleHttp(req, res) {
|
|
try {
|
|
if (req.url == "/img") {
|
|
await sendImg(req, res);
|
|
} else {
|
|
await sendMsg(req, res);
|
|
}
|
|
} catch (e) {
|
|
console.error("An error occurred while processing the request: ", e);
|
|
res.statusCode = 500;
|
|
res.setHeader('Content-Type', 'text/plain');
|
|
res.end('Internal Server Error\n');
|
|
}
|
|
}
|
|
|
|
function handleWs(ws) {
|
|
console.log('WebSocket connection established.');
|
|
|
|
ws.on('message', (message) => {
|
|
let data;
|
|
try {
|
|
data = JSON.parse(message);
|
|
} catch {
|
|
ws.close(1003, 'Invalid JSON');
|
|
return;
|
|
}
|
|
logger.info('Received message:', data);
|
|
|
|
switch (data.type) {
|
|
case "msg":
|
|
sendFriendMessage(data.id, data.msg);
|
|
break;
|
|
case "img":
|
|
sendImageToUser(data.id, data.img, data.url);
|
|
break
|
|
}
|
|
});
|
|
|
|
ws.on('close', () => {
|
|
logger.info('WebSocket connection closed.');
|
|
});
|
|
|
|
ws.on('error', (err) => {
|
|
logger.error('WebSocket error:', err);
|
|
});
|
|
}
|
|
|
|
async function messageToJson(message, echo) {
|
|
let friendId = message.steamid_friend
|
|
if (typeof friendId !== 'string') {
|
|
friendId = friendId.getSteamID64();
|
|
}
|
|
|
|
let sender = await client.getUserInfo(echo ? steamUser.steamID : friendId, (ignore) => { });
|
|
|
|
return JSON.stringify({
|
|
date: dateToString(message.server_timestamp),
|
|
echo: echo,
|
|
id: friendId,
|
|
name: sender.player_name,
|
|
message: message.message,
|
|
ordinal: message.ordinal,
|
|
})
|
|
}
|
|
|
|
async function onSteamMessage(message, echo) {
|
|
let messageEncoded = await messageToJson(message, echo);
|
|
|
|
wss.clients.forEach((client) => {
|
|
if (client.readyState === WebSocket.OPEN) {
|
|
client.send(messageEncoded);
|
|
}
|
|
});
|
|
}
|
|
|
|
client.steamLoginPromise.then(() => {
|
|
steamUser.chat.on("friendMessage", (message) => {
|
|
// noinspection JSIgnoredPromiseFromCall
|
|
onSteamMessage(message, false);
|
|
});
|
|
|
|
steamUser.chat.on("friendMessageEcho", (message) => {
|
|
// noinspection JSIgnoredPromiseFromCall
|
|
onSteamMessage(message, true);
|
|
});
|
|
|
|
try {
|
|
const server = http.createServer(handleHttp);
|
|
|
|
// 创建 WebSocket 服务器,并限制路径为 /ws
|
|
globalThis.wss = new WebSocket.Server({ server, path: '/ws' });
|
|
|
|
wss.on('connection', handleWs);
|
|
|
|
server.listen(3000, '0.0.0.0', () => {
|
|
console.log('Server running at http://0.0.0.0:3000/');
|
|
console.log('WebSocket server is also running.');
|
|
});
|
|
} catch (err) {
|
|
console.error('Error during initialization:', err);
|
|
}
|
|
});
|