Skip to content
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
12 changes: 12 additions & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Slash Command | Description
[**/map**](commands.md#map) | Get the currently connected server map image.
[**/market**](commands.md#market) | Operations for In-Game Vending Machines.
[**/players**](commands.md#players) | Get player/players information based on battlemetrics.
[**/raid**](commands.md#raid) | Display the raid costs for an item.
[**/recycle**](commands.md#recycle) | Display the output of recycling an item.
[**/research**](commands.md#research) | Display the cost to research an item.
[**/reset**](commands.md#reset) | Reset Discord channels.
Expand Down Expand Up @@ -224,6 +225,17 @@ Subcommand | Options | Description | Required
![Discord Slash Command players specific user Image](images/slash_commands/players_specific_user.png)


## **/raid**

> **Display the raid costs for an item.**

Subcommand | Options | Description | Required
---------- | ------- | ----------- | --------
  | `name` | The name of the item to raid. | `False`
  | `id` | The id of the item to raid. | `False`

![Discord Slash Command raid Image](images/slash_commands/raid.png)

## **/recycle**

> **Display the output of recycling an item.**
Expand Down
Binary file added docs/images/slash_commands/raid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
155 changes: 155 additions & 0 deletions src/commands/durability.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/*
Copyright (C) 2023 Alexander Emanuelsson (alexemanuelol)

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.

https://github.com/alexemanuelol/rustplusplus

*/

const Builder = require('@discordjs/builders');

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

module.exports = {
name: 'raid',

getData(client, guildId) {
return new Builder.SlashCommandBuilder()
.setName('raid')
.setDescription(client.intlGet(guildId, 'commandsRaidDesc'))
.addStringOption(option => option
.setName('name')
.setDescription(client.intlGet(guildId, 'theNameOfTheItem'))
.setRequired(false))
.addStringOption(option => option
.setName('id')
.setDescription(client.intlGet(guildId, 'theIdOfTheItem'))
.setRequired(false));
},



/**
* Group durability data by group and toolId.
* @param {array} data The array of durability data objects.
* @return {object} The grouped durability data.
*/
groupDurabilityData(client, data) {
const groupedData = {};

for (const item of data) {
if (item.which === 'soft') continue;

if (!groupedData[item.group]) {
groupedData[item.group] = {};
}

if (!groupedData[item.group][item.toolId]) {
groupedData[item.group][item.toolId] = [];
}

groupedData[item.group][item.toolId].push({
...item,
'itemName': client.items.getName(item.toolId)
});
}

return groupedData;
},

getDurabilityData(raidItemName, raidItemId, client, guildId) {
let itemId = null;
if (raidItemName !== null) {
let item = null
if (!item) {
item = client.rustlabs.getClosestOtherNameByName(raidItemName);
}

if (!item) {
item = client.items.getClosestItemIdByName(raidItemName);
if(item !== null) {
item = client.items.getName(item);
}
}

if (!item) {
item = client.rustlabs.getClosestBuildingBlockNameByName(raidItemName);
}

if (item === null) {
return null;
}
else {
itemId = item;
}
}
else if (raidItemId !== null) {
if (client.items.itemExist(raidItemId)) {
itemId = raidItemId;
}
else {
return null;
}
}
const itemName = client.items.getName(itemId);

const raidDetails = client.rustlabs.getDurabilityDetailsByName(raidItemName);
if (raidDetails === null) {
return null;
}

raidDetails[3] = this.groupDurabilityData(client, raidDetails[3]);
return raidDetails;
},

async execute(client, interaction) {
const guildId = interaction.guildId;

const verifyId = Math.floor(100000 + Math.random() * 900000);
client.logInteraction(interaction, verifyId, 'slashCommand');

if (!await client.validatePermissions(interaction)) return;
await interaction.deferReply({ ephemeral: true });

const raidItemName = interaction.options.getString('name');
const raidItemId = interaction.options.getString('id');
if (raidItemName === null && raidItemId === null) {
const str = client.intlGet(guildId, 'noNameIdGiven');
await client.interactionEditReply(interaction, DiscordEmbeds.getActionInfoEmbed(1, str));
client.log(client.intlGet(guildId, 'warningCap'), str);
return null;
}

client.log(client.intlGet(null, 'infoCap'), client.intlGet(null, 'slashCommandValueChange', {
id: `${verifyId}`,
value: `${raidItemName} ${raidItemId}`
}));

const raidDetails = this.getDurabilityData(raidItemName, raidItemId, client, interaction);

if (raidDetails === null) {
const str = client.intlGet(guildId, 'noItemWithNameFound', {
name: raidItemName
});
await client.interactionEditReply(interaction, DiscordEmbeds.getActionInfoEmbed(1, str));
client.log(client.intlGet(guildId, 'warningCap'), str);
return;
}

await DiscordMessages.sendRaidMessage(interaction, raidDetails);
client.log(client.intlGet(null, 'infoCap'), client.intlGet(guildId, 'commandsRaidDesc'));
},
};
30 changes: 30 additions & 0 deletions src/discordTools/discordEmbeds.js
Original file line number Diff line number Diff line change
Expand Up @@ -1126,6 +1126,36 @@ module.exports = {
});
},

getRaidEmbed: function (guildId, raidDetails) {
const raidCosts = {
name: '',
time: '',
sulfur: ''
};

const sortedItems = Object.values(raidDetails[3].explosive).sort((a, b) => {
const sulfurA = a[0].sulfur === null ? Infinity : Number(a[0].sulfur);
const sulfurB = b[0].sulfur === null ? Infinity : Number(b[0].sulfur);
return sulfurA - sulfurB;
});
for (const item of sortedItems) {
raidCosts.name += `${item[0].itemName}\n`;
raidCosts.time += `${item[0].timeString} (${item[0].quantity})\n`;
raidCosts.sulfur += `${item[0].sulfur}\n`;
}

return module.exports.getEmbed({
title: `${raidDetails[1]}`,
color: Constants.COLOR_DEFAULT,
timestamp: true,
fields: [
{ name: Client.client.intlGet(guildId, 'name'), value: raidCosts.name.trim(), inline: true },
{ name: Client.client.intlGet(guildId, 'time'), value: raidCosts.time.trim(), inline: true },
{ name: Client.client.intlGet(guildId, 'sulfur'), value: raidCosts.sulfur.trim(), inline: true }
]
});
},

getResearchEmbed: function (guildId, researchDetails) {
let typeString = '', scrapString = '';
if (researchDetails[2].researchTable !== null) {
Expand Down
9 changes: 9 additions & 0 deletions src/discordTools/discordMessages.js
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,15 @@ module.exports = {
await Client.client.interactionEditReply(interaction, content);
},

sendRaidMessage: async function (interaction, raidDetails) {
const content = {
embeds: [DiscordEmbeds.getRaidEmbed(interaction.guildId, raidDetails)],
ephemeral: true
}

await Client.client.interactionEditReply(interaction, content);
},

sendResearchMessage: async function (interaction, researchDetails) {
const content = {
embeds: [DiscordEmbeds.getResearchEmbed(interaction.guildId, researchDetails)],
Expand Down
5 changes: 4 additions & 1 deletion src/external/process_rustlabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,10 @@ function processItemDurability(rustlabsName, shortname, name, data, type = 'item
}
if (toolShortname === null || toolName === null) exit();
toolId = Object.keys(ITEMS).find(e => ITEMS[e].shortname === toolShortname && ITEMS[e].name === toolName);
if (!toolId) exit();
if (!toolId) {
console.error(`Tool ID not found for ${toolShortname} - ${toolName}`);
continue; // Skip this iteration and continue with the next match
}

/* Caption in tool name */
let captionInTool = null;
Expand Down
4 changes: 4 additions & 0 deletions src/handlers/discordCommandHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,10 @@ module.exports = {
commandLowerCase === `${prefix}${client.intlGet(guildId, 'commandSyntaxTravelingVendor')}`) {
response = rustplus.getCommandTravelingVendor();
}
else if (commandLowerCase === `${prefix}${client.intlGet('en', 'commandSyntaxRaid')}` ||
commandLowerCase === `${prefix}${client.intlGet(guildId, 'commandSyntaxRaid')}`) {
response = rustplus.getCommandRaidCost(command);
}
else {
/* Smart Switches/ Group Switches are not currently supported through discord. */
return false;
Expand Down
4 changes: 4 additions & 0 deletions src/handlers/inGameCommandHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,10 @@ module.exports = {
commandLowerCase === `${prefix}${client.intlGet(guildId, 'commandSyntaxTravelingVendor')}`) {
rustplus.sendInGameMessage(rustplus.getCommandTravelingVendor());
}
else if (commandLowerCase.startsWith(`${prefix}${client.intlGet('en', 'commandSyntaxRaid')}`) ||
commandLowerCase.startsWith(`${prefix}${client.intlGet(guildId, 'commandSyntaxRaid')}`)) {
rustplus.sendInGameMessage(rustplus.getCommandRaidCost(command));
}
else {
/* Maybe a custom command? */

Expand Down
4 changes: 4 additions & 0 deletions src/languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@
"commandSyntaxPlayers": "players",
"commandSyntaxPop": "pop",
"commandSyntaxProx": "prox",
"commandSyntaxRaid": "raid",
"commandSyntaxRecycle": "recycle",
"commandSyntaxRemove": "remove",
"commandSyntaxResearch": "research",
Expand Down Expand Up @@ -225,6 +226,7 @@
"commandsRecycleQuantityDesc": "The quantity of items to recycle.",
"commandsRecycleRecyclerTypeDesc": "The recycler type (recycler, shredder, safe-zone-recycler).",
"commandsResearchDesc": "Display the cost to research an item.",
"commandsRaidDesc": "Display the cost to destroy an item.",
"commandsResetAlarmsDesc": "Reset alarms channel.",
"commandsResetDesc": "Reset Discord channels.",
"commandsResetInformationDesc": "Reset information channel.",
Expand Down Expand Up @@ -297,6 +299,7 @@
"couldNotFindPlayerId": "Could not find player with id {id}.",
"couldNotFindRecycleDetails": "Could not find recycle details for {name}.",
"couldNotFindResearchDetails": "Could not find research details for {name}.",
"couldNotFindRaidDetails": "Could not find raid details for {name}.",
"couldNotFindRole": "Could not find role: {roleId}",
"couldNotFindStackDetails": "Could not find stack details for {name}.",
"couldNotFindTeammate": "Could not find teammate: {name}.",
Expand Down Expand Up @@ -682,6 +685,7 @@
"subscribeToChangesBattlemetrics": "Subscribe to different changes on Battlemetrics.",
"subscriptionList": "Subscription list",
"subscriptionListEmpty": "Item subscription list is empty.",
"sulfur": "Sulfur",
"sulfurQuarry": "Sulfur Quarry",
"switches": "Switches",
"teamMember": "Team Member",
Expand Down
14 changes: 7 additions & 7 deletions src/structures/RustLabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -469,10 +469,10 @@ class RustLabs {
}

if (!foundName) {
foundName = this.getClosestBuildingBlockNameByName(name);
foundName = this.items.getClosestItemIdByName(name);
if (foundName) {
if (this.durabilityData['buildingBlocks'].hasOwnProperty(foundName)) {
type = 'buildingBlocks';
if (this.durabilityData['items'].hasOwnProperty(foundName)) {
return this.getDurabilityDetailsById(foundName, group, which, orderedBy);
}
else {
foundName = null;
Expand All @@ -481,10 +481,10 @@ class RustLabs {
}

if (!foundName) {
foundName = this.items.getClosestItemIdByName(name);
foundName = this.getClosestBuildingBlockNameByName(name);
if (foundName) {
if (this.durabilityData['items'].hasOwnProperty(foundName)) {
return this.getDurabilityDetailsById(foundName, group, which, orderedBy);
if (this.durabilityData['buildingBlocks'].hasOwnProperty(foundName)) {
type = 'buildingBlocks';
}
else {
foundName = null;
Expand Down Expand Up @@ -529,7 +529,7 @@ class RustLabs {

content = this.getArrayOrderedByChoice(content, orderedBy);

return ['items', id, this.items.items[id], content];
return ['items', this.items.items[id].name, this.items.items[id], content];
}


Expand Down
33 changes: 33 additions & 0 deletions src/structures/RustPlus.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const Map = require('../util/map.js');
const RustPlusLite = require('../structures/RustPlusLite');
const TeamHandler = require('../handlers/teamHandler.js');
const Timer = require('../util/timer.js');
const Durability = require('../commands/durability.js');

const TOKENS_LIMIT = 24; /* Per player */
const TOKENS_REPLENISH = 3; /* Per second */
Expand Down Expand Up @@ -2746,6 +2747,38 @@ class RustPlus extends RustPlusLib {

return strings;
}

getCommandRaidCost(command) {
const prefix = this.generalSettings.prefix;
const commandRaid = `${prefix}${Client.client.intlGet(this.guildId, 'commandSyntaxRaid')}`;
const commandRaidEn = `${prefix}${Client.client.intlGet('en', 'commandSyntaxRaid')}`;
if (command.toLowerCase().startsWith(`${commandRaid} `)) {
command = command.slice(`${commandRaid} `.length).trim();
}
else {
command = command.slice(`${commandRaidEn} `.length).trim();
}

const durability = Durability.getDurabilityData(command, null, Client.client, this.guildId);
let raidCosts = `${durability[1]}: `;

if(!durability) {
return Client.client.intlGet(this.guildId, 'noItemWithNameFound', {
name: command
});
}

const sortedItems = Object.values(durability[3].explosive).sort((a, b) => {
const sulfurA = a[0].sulfur === null ? Infinity : Number(a[0].sulfur);
const sulfurB = b[0].sulfur === null ? Infinity : Number(b[0].sulfur);
return sulfurA - sulfurB;
}).slice(0,3);
for (const item of sortedItems) {
raidCosts += `${item[0].itemName} ${item[0].timeString} (${item[0].quantity}) ${item[0].sulfur}, `;
}

return raidCosts.trim().trim(",");
}
}

module.exports = RustPlus;