Skip to content

Commit ed8cc04

Browse files
committed
✨ add gather town presence
1 parent 74cc3f8 commit ed8cc04

File tree

3 files changed

+148
-0
lines changed

3 files changed

+148
-0
lines changed

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import dixtPluginReportsOptions from "./options/reports";
1515
import dixtPluginRolesOptions from "./options/roles";
1616
import dixtPluginTwitchOptions from "./options/twitch";
1717
import dixtPluginWorktimeOptions from "./options/worktime";
18+
import dixtPluginGather from "./plugins/gather";
1819

1920
const main = async () => {
2021
const instance = new dixt({
@@ -24,6 +25,7 @@ const main = async () => {
2425
},
2526
plugins: [
2627
dixtPluginLogs,
28+
dixtPluginGather,
2729
[dixtPluginAffix, dixtPluginAffixOptions],
2830
[dixtPluginReact, dixtPluginReactOptions],
2931
[dixtPluginPresence, dixtPluginPresenceOptions],

src/options/presence.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { ActivityType } from "discord.js";
22
import { DixtPluginPresenceOptions } from "dixt-plugin-presence";
33

4+
import { getGatherCount } from "../plugins/gather";
5+
46
const dixtPluginPresenceOptions: DixtPluginPresenceOptions = {
57
presences: [
68
{
@@ -19,6 +21,14 @@ const dixtPluginPresenceOptions: DixtPluginPresenceOptions = {
1921
},
2022
],
2123
},
24+
() => ({
25+
activities: [
26+
{
27+
name: `${getGatherCount()} gathers`,
28+
type: ActivityType.Watching,
29+
},
30+
],
31+
}),
2232
],
2333
};
2434

src/plugins/gather.ts

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import { Game } from "@gathertown/gather-game-client";
2+
import dixt, { DixtPlugin, Log, merge } from "dixt";
3+
import * as cron from "node-cron";
4+
5+
const name = "dixt-plugin-gather";
6+
7+
let globalPlayerCount = 0;
8+
9+
export const getGatherCount = () => globalPlayerCount;
10+
11+
export interface DixtPluginGatherOptions {
12+
spaceId?: string;
13+
apiKey?: string;
14+
tasks?: {
15+
update?: string;
16+
};
17+
}
18+
19+
export const optionsDefaults: DixtPluginGatherOptions = {
20+
spaceId: process.env.DIXT_PLUGIN_GATHER_SPACE_ID || "",
21+
apiKey: process.env.DIXT_PLUGIN_GATHER_API_KEY || "",
22+
tasks: {
23+
update: process.env.DIXT_PLUGIN_GATHER_UPDATE_TASK || "*/30 * * * * *",
24+
},
25+
};
26+
27+
const dixtPluginGather: DixtPlugin<DixtPluginGatherOptions> = (
28+
instance: dixt,
29+
optionsValue?: DixtPluginGatherOptions,
30+
) => {
31+
const options = merge({}, optionsDefaults, optionsValue);
32+
const { client } = instance;
33+
const { spaceId, apiKey } = options;
34+
35+
let game: Game | null = null;
36+
let playerCount = 0;
37+
let updateTask: cron.ScheduledTask | null = null;
38+
39+
const updatePlayerCount = () => {
40+
if (game?.players) {
41+
const allPlayers = Object.values(game.players);
42+
const realPlayers = allPlayers.filter(
43+
(player) => player.name && player.name !== "Unknown",
44+
);
45+
const newPlayerCount = realPlayers.length;
46+
47+
if (newPlayerCount !== playerCount) {
48+
const playerNames = realPlayers.map((player) => player.name).join(", ");
49+
50+
Log.info(
51+
`Players online (${newPlayerCount}): ${playerNames || "None"}`,
52+
);
53+
54+
playerCount = newPlayerCount;
55+
globalPlayerCount = newPlayerCount;
56+
}
57+
}
58+
};
59+
60+
if (!spaceId) {
61+
Log.error(`${name} - spaceId is required`);
62+
throw new Error(`${name} - spaceId is required`);
63+
}
64+
65+
if (!apiKey) {
66+
Log.error(`${name} - apiKey is required`);
67+
throw new Error(`${name} - apiKey is required`);
68+
}
69+
70+
client.once("ready", () => {
71+
const formattedSpaceId = spaceId.replace(/\//g, "\\");
72+
game = new Game(formattedSpaceId, () => Promise.resolve({ apiKey }));
73+
74+
game.subscribeToConnection((connected) => {
75+
if (connected) {
76+
Log.ready("Connected to Gather");
77+
updatePlayerCount();
78+
79+
if (game?.players) {
80+
const allPlayers = Object.values(game.players);
81+
const realPlayers = allPlayers.filter(
82+
(player) => player.name && player.name !== "Unknown",
83+
);
84+
const initialPlayerCount = realPlayers.length;
85+
const playerNames = realPlayers
86+
.map((player) => player.name)
87+
.join(", ");
88+
89+
Log.info(
90+
`Initial players online (${initialPlayerCount}): ${
91+
playerNames || "None"
92+
}`,
93+
);
94+
}
95+
} else {
96+
Log.warn("Disconnected from Gather");
97+
}
98+
});
99+
100+
game.subscribeToEvent("playerJoins", () => {
101+
updatePlayerCount();
102+
});
103+
104+
game.subscribeToEvent("playerExits", () => {
105+
updatePlayerCount();
106+
});
107+
108+
try {
109+
game.connect();
110+
} catch (error) {
111+
Log.error("Failed to connect to Gather:", error);
112+
}
113+
114+
if (options.tasks?.update) {
115+
updateTask = cron.schedule(options.tasks.update, () => {
116+
updatePlayerCount();
117+
});
118+
updateTask.start();
119+
}
120+
});
121+
122+
client.once("destroy", () => {
123+
if (game) {
124+
game.disconnect();
125+
}
126+
if (updateTask) {
127+
updateTask.stop();
128+
}
129+
});
130+
131+
return {
132+
name,
133+
};
134+
};
135+
136+
export default dixtPluginGather;

0 commit comments

Comments
 (0)