Skip to content

add in-game tracker management commands and i18n support #424

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ In-Game Command | Description
[**timer**](commands.md#timer) | Set custom timers that will notify whenever the timer have expired.
[**tr**](commands.md#tr) | Translate a text to another language.
[**trf**](commands.md#trf) | Translate a text from one language to another.
[**tracker**](commands.md#tracker) | Manage trackers by adding or removing players directly from the in-game chat.
[**tts**](commands.md#tts) | Send a Text-To-Speech message to the Discord teamchat channel.
[**unmute**](commands.md#unmute) | Unmute the bot from the In-Game Team Chat.
[**upkeep**](commands.md#upkeep) | Get the upkeep time of all connected tool cupboard monitors.
Expand Down Expand Up @@ -684,6 +685,22 @@ Subcommand | Description | Required

![In-Game Command translateFrom Image](images/ingame_commands/translateFrom_ingame.png)


## **tracker**

> **Manage player trackers directly from the in-game chat.**
<br>Use the `tracker` command to create, add, or remove players to/from specific trackers.
<br>If no `trackerId` is provided, the most recently created tracker for the current server will be used automatically.

Subcommand | Description | Required
---------- | ----------- | --------
`create` | Create a new tracker. You can optionally provide a custom `trackerId`<br>`!tracker create [trackerId]` | `false`
`add` | Add a player to a tracker using steamID or BattlemetricsID<br>`!tracker add <steamID or battlemetricsID> [trackerId]` | `false`
`remove` | Remove a player from a tracker using steamID or BattlemetricsID<br>`!tracker remove <steamID or battlemetricsID> [trackerId]` | `false`

![In-Game Command tracker Image](images/ingame_commands/tracker_ingame.png)


## **tts**

> **Send a Text-To-Speech message to the Discord teamchat channel.** To execute a Text-To-Speech command run `!tts <text>`.
Expand Down
Binary file added docs/images/ingame_commands/tracker_ingame.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion src/discordTools/discordEmbeds.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ module.exports = {
const serverStatus = !successful ? Constants.NOT_FOUND_EMOJI :
(bmInstance.server_status ? Constants.ONLINE_EMOJI : Constants.OFFLINE_EMOJI);

let description = `__**Battlemetrics ID:**__ ${battlemetricsLink}\n`;
let description = `__**Tracker ID:**__ \`${tracker.trackerId}\`\n`;
description += `__**Battlemetrics ID:**__ ${battlemetricsLink}\n`;
description += `__**${Client.client.intlGet(guildId, 'serverId')}:**__ ${tracker.serverId}\n`;
description += `__**${Client.client.intlGet(guildId, 'serverStatus')}:**__ ${serverStatus}\n`;
description += `__**${Client.client.intlGet(guildId, 'streamerMode')}:**__ `;
Expand Down
15 changes: 11 additions & 4 deletions src/discordTools/discordModals.js
Original file line number Diff line number Diff line change
Expand Up @@ -264,14 +264,14 @@ module.exports = {
const instance = Client.client.getInstance(guildId);
const tracker = instance.trackers[trackerId];
const identifier = JSON.stringify({ "trackerId": trackerId });

const modal = module.exports.getModal({
customId: `TrackerEdit${identifier}`,
title: Client.client.intlGet(guildId, 'editingOf', {
entity: tracker.name.length > 18 ? `${tracker.name.slice(0, 18)}..` : tracker.name
})
});

modal.addComponents(
new Discord.ActionRowBuilder().addComponents(TextInput.getTextInput({
customId: 'TrackerName',
Expand All @@ -292,11 +292,18 @@ module.exports = {
style: Discord.TextInputStyle.Short,
required: false,
minLength: 0
}))
})),
new Discord.ActionRowBuilder().addComponents(TextInput.getTextInput({
customId: 'TrackerId',
label: Client.client.intlGet(guildId, 'trackerId'),
value: String(tracker.trackerId),
style: Discord.TextInputStyle.Short
}))
);

return modal;
},


getTrackerAddPlayerModal(guildId, trackerId) {
const instance = Client.client.getInstance(guildId);
Expand Down
26 changes: 5 additions & 21 deletions src/handlers/buttonHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -528,32 +528,16 @@ module.exports = async (client, interaction) => {
}
else if (interaction.customId.startsWith('CreateTracker')) {
const ids = JSON.parse(interaction.customId.replace('CreateTracker', ''));
const trackerId = await client.createTrackerInstance(guildId, ids.serverId);
const server = instance.serverList[ids.serverId];

if (!server) {
if (!server || !trackerId) {
await interaction.message.delete();
return;
}

interaction.deferUpdate();

/* Find an available tracker id */
const trackerId = client.findAvailableTrackerId(guildId);

instance.trackers[trackerId] = {
name: 'Tracker',
serverId: ids.serverId,
battlemetricsId: server.battlemetricsId,
title: server.title,
img: server.img,
clanTag: '',
everyone: false,
inGame: true,
players: [],
messageId: null
}
client.setInstance(guildId, instance);

await interaction.deferUpdate();

await DiscordMessages.sendTrackerMessage(guildId, trackerId);
}
else if (interaction.customId.startsWith('CreateGroup')) {
Expand Down
3 changes: 3 additions & 0 deletions src/handlers/inGameCommandHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ module.exports = {
else if (commandLowerCase === `${prefix}${client.intlGet('en', 'commandSyntaxTravelingVendor')}` ||
commandLowerCase === `${prefix}${client.intlGet(guildId, 'commandSyntaxTravelingVendor')}`) {
rustplus.sendInGameMessage(rustplus.getCommandTravelingVendor());
} else if (commandLowerCase.startsWith(`${prefix}${client.intlGet('en', 'commandSyntaxTracker')}`) ||
commandLowerCase.startsWith(`${prefix}${client.intlGet(guildId, 'commandSyntaxTracker')}`)) {
rustplus.sendInGameMessage(await rustplus.getCommandTracker(commandLowerCase));
}
else {
/* Maybe a custom command? */
Expand Down
42 changes: 33 additions & 9 deletions src/handlers/modalHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

const Discord = require('discord.js');

const DiscordEmbeds = require('../discordTools/discordEmbeds');

const Battlemetrics = require('../structures/Battlemetrics');
const Constants = require('../util/constants.js');
const DiscordMessages = require('../discordTools/discordMessages.js');
Expand Down Expand Up @@ -263,32 +265,35 @@ module.exports = async (client, interaction) => {
else if (interaction.customId.startsWith('TrackerEdit')) {
const ids = JSON.parse(interaction.customId.replace('TrackerEdit', ''));
const tracker = instance.trackers[ids.trackerId];

const trackerName = interaction.fields.getTextInputValue('TrackerName');
const trackerBattlemetricsId = interaction.fields.getTextInputValue('TrackerBattlemetricsId');
const trackerClanTag = interaction.fields.getTextInputValue('TrackerClanTag');

const trackerNewId = interaction.fields.getTextInputValue('TrackerId');

if (!tracker) {
interaction.deferUpdate();
return;
}

tracker.name = trackerName;

if (trackerClanTag !== tracker.clanTag) {
tracker.clanTag = trackerClanTag;
client.battlemetricsIntervalCounter = 0;
}

if (trackerBattlemetricsId !== tracker.battlemetricsId) {
if (client.battlemetricsInstances.hasOwnProperty(trackerBattlemetricsId)) {
const bmInstance = client.battlemetricsInstances[trackerBattlemetricsId];
tracker.battlemetricsId = trackerBattlemetricsId;
tracker.serverId = `${bmInstance.server_ip}-${bmInstance.server_port}`;
tracker.img = Constants.DEFAULT_SERVER_IMG;
tracker.title = bmInstance.server_name;
}
else {
} else {
const bmInstance = new Battlemetrics(trackerBattlemetricsId);
await bmInstance.setup();

if (bmInstance.lastUpdateSuccessful) {
client.battlemetricsInstances[trackerBattlemetricsId] = bmInstance;
tracker.battlemetricsId = trackerBattlemetricsId;
Expand All @@ -298,14 +303,33 @@ module.exports = async (client, interaction) => {
}
}
}

const isTrackerIdChanged = trackerNewId && trackerNewId !== ids.trackerId;

if (isTrackerIdChanged) {
if (instance.trackers.hasOwnProperty(trackerNewId)) {
const str = client.intlGet(interaction.guildId, 'trackerIdAlreadyExists', { trackerId: trackerNewId });
await client.interactionReply(interaction, DiscordEmbeds.getActionInfoEmbed(1, str));
client.log(client.intlGet(null, 'warningCap'), str);
return;
}

tracker.trackerId = trackerNewId;
instance.trackers[trackerNewId] = tracker;

delete instance.trackers[ids.trackerId];

await DiscordMessages.sendTrackerMessage(interaction.guildId, trackerNewId);
} else {
await DiscordMessages.sendTrackerMessage(interaction.guildId, ids.trackerId);
}

client.setInstance(guildId, instance);

client.log(client.intlGet(null, 'infoCap'), client.intlGet(null, 'modalValueChange', {
id: `${verifyId}`,
value: `${trackerName}, ${tracker.battlemetricsId}, ${tracker.clanTag}`
value: `${trackerName}, ${tracker.battlemetricsId}, ${tracker.clanTag}, ${tracker.trackerId}`
}));

await DiscordMessages.sendTrackerMessage(interaction.guildId, ids.trackerId);
}
else if (interaction.customId.startsWith('TrackerAddPlayer')) {
const ids = JSON.parse(interaction.customId.replace('TrackerAddPlayer', ''));
Expand Down
11 changes: 11 additions & 0 deletions src/languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"abandonedCabins": "Abandoned Cabins",
"abandonedMilitaryBase": "Abandoned Military Base",
"abandonedSupermarket": "Abandoned Supermarket",
"activeRustServerNotFound": "Could not find an active server.",
"addPlayerCap": "ADD PLAYER",
"addSwitchCap": "ADD SWITCH",
"afkCap": "AFK",
Expand Down Expand Up @@ -158,6 +159,7 @@
"commandSyntaxTime": "time",
"commandSyntaxTimer": "timer",
"commandSyntaxTimers": "timers",
"commandSyntaxTracker": "tracker",
"commandSyntaxTranslateFromTo": "trf",
"commandSyntaxTranslateTo": "tr",
"commandSyntaxTravelingVendor": "vendor",
Expand Down Expand Up @@ -511,6 +513,7 @@
"noRegisteredEvents": "No registered events yet.",
"noRegisteredMarkers": "No registered markers.",
"noSavedNotes": "There are no saved notes.",
"noTrackersForServer": "No trackers linked to server",
"noToolCupboardWereFound": "No Tool Cupboard monitors were found.",
"none": "None",
"northEast": "North East",
Expand Down Expand Up @@ -553,6 +556,8 @@
"patrolHelicopterTakenDown": "Patrol Helicopter was taken down {location}.",
"percentSign": "Percent Sign",
"pipe": "Pipe",
"playerAddedToTracker": "Player {name} ({id}) has been added to tracker {trackerId}.",
"playerAlreadyExistsInTracker": "Player ({id}) is already registered in tracker {trackerId}.",
"playerHasBeenAliveFor": "{name} has been alive for {time}.",
"playerId": "Player ID",
"playerJoinedTheTeam": "{name} joined the team.",
Expand All @@ -566,7 +571,9 @@
"playerJustReturned": "{name} just returned ({time}).",
"playerJustWentAfk": "{name} just went AFK.",
"playerLeftTheTeam": "{name} left the team.",
"playerNotFoundInTracker": "Player ({id}) does not exist in tracker {trackerId}.",
"playerNotPairedWithServer": "Leader command does not work because {name} is not paired with the server.",
"playerRemovedFromTracker": "Player ({id}) has been removed from tracker {trackerId}.",
"players": "Players",
"playersSearch": "Players Search",
"plusSign": "Plus Sign",
Expand Down Expand Up @@ -725,6 +732,10 @@
"toolCupboard": "Tool Cupboard",
"total": "Total",
"tracker": "Tracker",
"trackerCreated": "Tracker created successfully. (ID: {trackerId})",
"trackerId": "Tracker ID",
"trackerIdAlreadyExists": "Tracker ID {trackerId} already exists!",
"trackerIdNotFound": "Tracker ID {trackerId} could not be found.",
"trackerAddPlayerDesc": "Add Player to {tracker}",
"trackerRemovePlayerDesc": "Remove Player from {tracker}",
"trademarkShownBeforeMessage": "{trademark} will be shown before messages.",
Expand Down
31 changes: 31 additions & 0 deletions src/structures/DiscordBot.js
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,37 @@ class DiscordBot extends Discord.Client {
}
}

createTrackerInstance(guildId, serverId, customId = null) {
const instance = this.getInstance(guildId);
const server = instance?.serverList?.[serverId];
if (!server) return null;

const trackerId = customId || this.findAvailableTrackerId(guildId);

if (instance.trackers.hasOwnProperty(trackerId)) {
return null;
}

instance.trackers[trackerId] = {
name: 'Tracker',
serverId,
battlemetricsId: server.battlemetricsId,
title: server.title ?? 'Untitled',
img: server.img ?? null,
clanTag: '',
trackerId,
everyone: false,
inGame: true,
players: [],
messageId: null,
createdAt: Date.now()
};

this.setInstance(guildId, instance);
return trackerId;
}


findAvailableGroupId(guildId, serverId) {
const instance = this.getInstance(guildId);

Expand Down
Loading
Loading