Skip to content

Commit d719d7a

Browse files
committed
Update Discord message with current players
1 parent 3df1395 commit d719d7a

File tree

4 files changed

+82
-22
lines changed

4 files changed

+82
-22
lines changed

game-api/src/index.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,13 @@ app.get("/control", async (request, response) => {
141141
);
142142
if (currentStatus !== "running") {
143143
currentStatus = "running";
144-
145-
const connectText = gameManager.getConnectUrl
146-
? `, ${gameManager.getConnectUrl()} `
147-
: "";
148-
sendSystemChat(`${gameName} is up${connectText}!`);
149144
}
150-
return response.json({ status: currentStatus, playerCount, players });
145+
return response.json({
146+
status: currentStatus,
147+
playerCount,
148+
players,
149+
connectUrl: gameManager.getConnectUrl(),
150+
});
151151
}
152152
}
153153
if ("unknown" === currentStatus) {

gateway/src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const {
4848
router: messagesRouter,
4949
sendMessage,
5050
initWebsocketListener,
51+
initPlayerStatusPoller,
5152
} = require("./routes/messages");
5253
app.use("/messages", messagesRouter);
5354

@@ -265,4 +266,5 @@ app.all("/:gameId/*", async (request, response) => {
265266
const httpServer = http.createServer(app);
266267
httpServer.listen(listenPort);
267268
initWebsocketListener(httpServer);
269+
initPlayerStatusPoller(knownGameApis);
268270
console.log(`Gateway listening on port ${listenPort}`);

gateway/src/routes/messages.js

Lines changed: 74 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const express = require("express");
22
const router = express.Router();
33
const WebSocket = require("ws");
44
const fs = require("fs");
5+
const axios = require("axios");
56

67
const ytdl = require("ytdl-core");
78
const Discord = require("discord.js");
@@ -40,7 +41,7 @@ async function getChannel(id) {
4041
return channels[id];
4142
}
4243

43-
client.on("message", async msg => {
44+
client.on("message", async (msg) => {
4445
msg = /** @type Message */ msg;
4546
if (msg.author.id === client.user.id) {
4647
return;
@@ -65,7 +66,7 @@ client.on("message", async msg => {
6566
const nickSearch = joinChannelMatch[1].toLowerCase();
6667
msg.guild.members
6768
.fetch({ query: nickSearch })
68-
.then(guildMembers => {
69+
.then((guildMembers) => {
6970
const target = findMember(guildMembers, nickSearch);
7071
if (target) {
7172
target.voice.setChannel(joinChannelMatch[2]);
@@ -109,7 +110,7 @@ client.on("message", async msg => {
109110
fs.writeFile(
110111
"/servers/gmod-docker-overrides/garrysmod/data/nextmap.txt",
111112
nextMapMatch[1],
112-
err => console.error("Failed to write nextmap.txt: ", err)
113+
(err) => console.error("Failed to write nextmap.txt: ", err)
113114
);
114115
msg.reply(`Next map queued: ${nextMapMatch[1]}`);
115116
}
@@ -118,7 +119,7 @@ client.on("message", async msg => {
118119
debugLog(
119120
`WS: Heard ${msg.author.username}: ${msg.content} (${wsConnections.length} clients)`
120121
);
121-
wsConnections.forEach(wsConnection => {
122+
wsConnections.forEach((wsConnection) => {
122123
wsConnection.send(
123124
JSON.stringify({
124125
type: "message",
@@ -134,18 +135,18 @@ client.on("message", async msg => {
134135

135136
client
136137
.login(discordToken)
137-
.catch(err => console.error("Discord: failed to login ", err));
138+
.catch((err) => console.error("Discord: failed to login ", err));
138139

139-
router.post("/", async function(req, response) {
140-
sendMessage(req.body.nick, req.body.message, req.body.channel).catch(err =>
140+
router.post("/", async function (req, response) {
141+
sendMessage(req.body.nick, req.body.message, req.body.channel).catch((err) =>
141142
console.log(
142143
`Discord: failed to send message ${req.body.nick}: ${req.body.message} because: ${err}`
143144
)
144145
);
145146
response.json({ status: "ok" });
146147
});
147148

148-
router.get("/send", async function(req, response) {
149+
router.get("/send", async function (req, response) {
149150
await sendMessage(req.query.nick, req.query.message);
150151
response.json({ status: "ok" });
151152
});
@@ -155,7 +156,8 @@ async function sendMessage(nickname, message, channelId) {
155156
const channel = channelId ? await getChannel(channelId) : mainChannel;
156157
debugLog(`Discord sending ${nickname}: ${message}`);
157158
if (!channel) {
158-
return console.warn("Discord: Not connected to channel", channelId);
159+
console.warn("Discord: Not connected to channel", channelId);
160+
return;
159161
}
160162
let discordNickname = "Gman";
161163
if (nickname && nickname !== "Gman") {
@@ -166,11 +168,11 @@ async function sendMessage(nickname, message, channelId) {
166168
lastNickname = discordNickname;
167169
await channel.guild.me.setNickname(discordNickname);
168170
}
169-
if (message.match(/]\(https?:\/\//)) {
171+
if (message.match && message.match(/]\(https?:\/\//)) {
170172
const embed = new Discord.MessageEmbed().setDescription(message);
171-
await channel.send(embed);
173+
return await channel.send(embed);
172174
} else {
173-
await channel.send(message);
175+
return await channel.send(message);
174176
}
175177
} catch (err) {
176178
console.error(`Discord sendMessage error: ${err}`);
@@ -180,8 +182,8 @@ async function sendMessage(nickname, message, channelId) {
180182
const wsServer = new WebSocket.Server({ noServer: true });
181183
const wsConnections = [];
182184

183-
wsServer.on("connection", ws => {
184-
ws.on("message", message => {
185+
wsServer.on("connection", (ws) => {
186+
ws.on("message", (message) => {
185187
console.debug(`WS Received: ${message}`);
186188
const request = JSON.parse(message);
187189
if (request.type === "message") {
@@ -206,10 +208,66 @@ wsServer.on("connection", ws => {
206208

207209
function initWebsocketListener(httpServer) {
208210
httpServer.on("upgrade", (req, socket, head) => {
209-
wsServer.handleUpgrade(req, socket, head, ws => {
211+
wsServer.handleUpgrade(req, socket, head, (ws) => {
210212
wsServer.emit("connection", ws, req);
211213
});
212214
});
213215
}
214216

215-
module.exports = { router, sendMessage, initWebsocketListener };
217+
function initPlayerStatusPoller(knownGameApis) {
218+
async function pollGameHealth({ id, name, url }) {
219+
if (id === 'valheim-zach') {
220+
return;
221+
}
222+
const { data } = await axios({
223+
method: "GET",
224+
url: `${url}/control`,
225+
timeout: 8000,
226+
});
227+
if (data.status === "running") {
228+
console.log("found running", data);
229+
const players = data.players || [];
230+
const embed = new Discord.MessageEmbed()
231+
.setTitle(`${name} is running`)
232+
.setDescription(data.connectUrl || "");
233+
if (data.playerCount > 0) {
234+
embed.addField(
235+
`Players: ${data.playerCount}`,
236+
players
237+
.map(({ name }) => name)
238+
.filter(Boolean)
239+
.join(", ") || "-",
240+
true
241+
);
242+
}
243+
try {
244+
if (!knownGameApis[id].message) {
245+
knownGameApis[id].message = await sendMessage("", embed);
246+
} else {
247+
knownGameApis[id].message = await knownGameApis[id].message.edit(embed);
248+
}
249+
} catch (err) {
250+
console.error("Failed to edit message: ", err);
251+
}
252+
} else if (["stopping", "stopped"].includes(data.status)) {
253+
if (knownGameApis[id].message) {
254+
const embed = new Discord.MessageEmbed().setTitle(
255+
`${name} was running`
256+
);
257+
await knownGameApis[id].message.edit(embed);
258+
delete knownGameApis[id].message;
259+
}
260+
}
261+
knownGameApis[id].lastStatus = data.status;
262+
}
263+
setInterval(() => {
264+
Object.values(knownGameApis).map(pollGameHealth);
265+
}, 10000);
266+
}
267+
268+
module.exports = {
269+
router,
270+
sendMessage,
271+
initWebsocketListener,
272+
initPlayerStatusPoller,
273+
};

ui/static/icons/terraria.png

11.3 KB
Loading

0 commit comments

Comments
 (0)