refactor/some core files to .ts + update some imports in commands

This commit is contained in:
SowinskiBraeden committed 2025-09-28 22:10:14 -07:00
1 parent 76aee78f23
commit afcf24115e
32 files changed
+792 -666

No files matched your search

+4 -4
View File
@@ -48,7 +48,7 @@ If you're simply looking to add a new command and not make significant changes t
3. Use the following template to start your command file:
```javascript
const { EmbedBuilder } = require('discord.js'); // Not required, but encouraged to use embeds to reply to commands.
const CommandOptions = require('../util/CommandOptionTypes').CommandOptionTypes; // Not required but recommended for clear cmd options.
const ApplicationCommandOptionType = require('../util/CommandOptionTypes').CommandOptionTypes; // Not required but recommended for clear cmd options.
module.exports = {
name: "new-command", // Insert your command name here, I encourage that you use hyphens `-` to seperate words.
@@ -62,7 +62,7 @@ If you're simply looking to add a new command and not make significant changes t
name: "cmd_param_1",
description: "What this parameter is for",
value: "cmd_param_1_default", // Default value of this parameter
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: true,
}
],
@@ -111,7 +111,7 @@ Adding additional interactions to your command? Buttons, Select Menus, etc? You
1. Create an `Interactions` object within your command file. E.g. my new command `/commands/greet.js` will have the following:
```javascript
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, } = require('discord.js'); // Some additional imported definitions for our button.
const CommandOptions = require('../util/CommandOptionTypes').CommandOptionTypes;
const ApplicationCommandOptionType = require('../util/CommandOptionTypes').CommandOptionTypes;
module.exports = {
name: "greet",
@@ -123,7 +123,7 @@ Adding additional interactions to your command? Buttons, Select Menus, etc? You
name: "name",
description: "Name to greet",
value: "name", // Default value of this parameter
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: true,
}],
SlashCommand: {
+20
View File
@@ -21,6 +21,7 @@
"winston": "^3.8.1"
},
"devDependencies": {
"@types/concat-stream": "^2.0.3",
"@types/node": "^24.5.2",
"@typescript-eslint/eslint-plugin": "^8.44.1",
"@typescript-eslint/parser": "^8.44.1",
@@ -1635,6 +1636,16 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/concat-stream": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-2.0.3.tgz",
"integrity": "sha512-3qe4oQAPNwVNwK4C9c8u+VJqv9kez+2MR4qJpoPFfXtgxxif1QbFusvXzK0/Wra2VX07smostI2VMmJNSpZjuQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
@@ -5813,6 +5824,15 @@
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
"dev": true
},
"@types/concat-stream": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-2.0.3.tgz",
"integrity": "sha512-3qe4oQAPNwVNwK4C9c8u+VJqv9kez+2MR4qJpoPFfXtgxxif1QbFusvXzK0/Wra2VX07smostI2VMmJNSpZjuQ==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+1
View File
@@ -29,6 +29,7 @@
"winston": "^3.8.1"
},
"devDependencies": {
"@types/concat-stream": "^2.0.3",
"@types/node": "^24.5.2",
"@typescript-eslint/eslint-plugin": "^8.44.1",
"@typescript-eslint/parser": "^8.44.1",
+1 -1
View File
@@ -1,5 +1,5 @@
import DayZR from "./DayZRBot";
import config from "./config/config";
import { config } from "./config/config";
import { GatewayIntentBits } from "discord.js";
import path from "path";
+17 -17
View File
@@ -1,5 +1,5 @@
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, StringSelectMenuBuilder } = require("discord.js");
const CommandOptions = require("../util/CommandOptionTypes").CommandOptionTypes;
const { ApplicationCommandOptionType } = require("discord.js");
const bitfieldCalculator = require("discord-bitfield-calculator");
const { Armbands } = require("../database/armbands.js");
const { createUser, addUser } = require("../database/user");
@@ -19,55 +19,55 @@ module.exports = {
name: "gamertag-link",
description: "Link a gamertag for a user",
value: "gamertag-link",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "user",
description: "User to link gamertag to",
value: "user",
type: CommandOptions.User,
type: ApplicationCommandOptionType.User,
required: true,
},
{
name: "gamertag",
description: "Gamertag of player",
value: "gamertag",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: true,
}]
}, {
name: "gamertag-unlink",
description: "Unlink a gamertag for a user",
value: "gamertag-unlink",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "user",
description: "User to link gamertag to",
value: "user",
type: CommandOptions.User,
type: ApplicationCommandOptionType.User,
required: true,
}]
}, {
name: "claim-armband",
description: "Claim an armband for a faction",
value: "claim-armband",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "faction_role",
description: "Claim an armband for this faction role.",
value: "faction_role",
type: CommandOptions.Role,
type: ApplicationCommandOptionType.Role,
required: true,
}]
}, {
name: "bounty-clear",
description: "Clear a bounty off a player",
value: "bounty-clear",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "gamertag",
description: "Gamertag of player",
value: "gamertag",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: true,
}]
},
@@ -75,43 +75,43 @@ module.exports = {
name: "money",
description: "Add/Remove money to a user",
value: "money",
type: CommandOptions.SubCommandGroup,
type: ApplicationCommandOptionType.SubCommandGroup,
options: [{
name: "add",
description: "Add money to user",
value: "add",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "amount",
description: "The amount to add to balance",
value: "amount",
type: CommandOptions.Float,
type: ApplicationCommandOptionType.Float,
min_value: 0.01,
required: true,
}, {
name: "to",
description: "User to alter balance",
value: "to",
type: CommandOptions.User,
type: ApplicationCommandOptionType.User,
required: true,
}],
}, {
name: "remove",
description: "Remove money from a user",
value: "remove",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "amount",
description: "The amount to remove from balance",
value: "amount",
type: CommandOptions.Float,
type: ApplicationCommandOptionType.Float,
min_value: 0.01,
required: true,
}, {
name: "from",
description: "User to alter balance",
value: "from",
type: CommandOptions.User,
type: ApplicationCommandOptionType.User,
required: true,
}]
}]
+27 -27
View File
@@ -1,5 +1,5 @@
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, StringSelectMenuBuilder } = require("discord.js");
const CommandOptions = require("../util/CommandOptionTypes").CommandOptionTypes;
const { ApplicationCommandOptionType } = require("discord.js");
const bitfieldCalculator = require("discord-bitfield-calculator");
const generateAlarmMenus = (alarms, customId, placeholder, description) => {
@@ -40,13 +40,13 @@ module.exports = {
name: "create",
description: "Create a new Zone Ping Alarm",
value: "create",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [
{
name: "x-coord",
description: "X Coordinate of the origin",
value: "x-coord",
type: CommandOptions.Float,
type: ApplicationCommandOptionType.Float,
min_value: 0.01,
required: true,
},
@@ -54,7 +54,7 @@ module.exports = {
name: "y-coord",
description: "Y Coordinate of the origin",
value: "y-coord",
type: CommandOptions.Float,
type: ApplicationCommandOptionType.Float,
min_value: 0.01,
required: true,
},
@@ -62,7 +62,7 @@ module.exports = {
name: "radius",
description: "Radius of Alarm",
value: "radius",
type: CommandOptions.Float,
type: ApplicationCommandOptionType.Float,
min_value: 25.00,
required: true,
},
@@ -70,14 +70,14 @@ module.exports = {
name: "name",
description: "Alarm Name",
value: "name",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: true,
},
{
name: "channel",
description: "Alarm Channel",
value: "channel",
type: CommandOptions.Channel,
type: ApplicationCommandOptionType.Channel,
channel_types: [0], // Restrict to text channel
required: true,
},
@@ -85,21 +85,21 @@ module.exports = {
name: "role",
description: "Role to Ping on Alarm",
value: "role",
type: CommandOptions.Role,
type: ApplicationCommandOptionType.Role,
required: true,
},
{
name: "emp-exempt",
description: "Is this Alarm Exempt to EMP Attacks?",
value: false,
type: CommandOptions.Boolean,
type: ApplicationCommandOptionType.Boolean,
required: false,
},
{
name: "show-player-coords",
description: "Show a players coords when in the radius of the Alarm?",
value: true,
type: CommandOptions.Boolean,
type: ApplicationCommandOptionType.Boolean,
required: false,
}
]
@@ -108,18 +108,18 @@ module.exports = {
name: "delete",
description: "Delete an Alarm",
value: "delete",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
},
{
name: "add-player",
description: "Add player to be ignored list of an Alarm",
value: "add-player",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "gamertag",
description: "Gamertag of player to ignore",
value: "gamertag",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: true,
}]
},
@@ -127,12 +127,12 @@ module.exports = {
name: "remove-player",
description: "Remove a player from the ignored list of an Alarm",
value: "remove-player",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "gamertag",
description: "Gamertag of player to ignore",
value: "gamertag",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: true,
}]
},
@@ -140,24 +140,24 @@ module.exports = {
name: "disable",
description: "Disable an Alarm",
value: "disable",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
},
{
name: "enable",
description: "Enable an Alarm",
value: "enable",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
},
{
name: "mute",
description: "Mute the role ping of an Alarm",
value: "mute",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "toggle",
description: "Turn on/off role pings for this alarm",
value: false,
type: CommandOptions.Boolean,
type: ApplicationCommandOptionType.Boolean,
required: true,
}]
},
@@ -165,12 +165,12 @@ module.exports = {
name: "set-rule",
description: "Add a Rule to an Alarm",
value: "set-rule",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "rule",
description: "Select a rule to add to an Alarm",
value: "rule",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: true,
choices: [
{ name: "Ban on Entry", value: "ban_on_entry" },
@@ -183,18 +183,18 @@ module.exports = {
name: "remove-rule",
description: "Remove a rule from an Alarm",
value: "remove-rule",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
},
{
name: "rename",
description: "Rename an Alarm",
value: "rename",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "name",
description: "New Alarm Name",
value: "name",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: true,
}]
},
@@ -202,12 +202,12 @@ module.exports = {
name: "move-origin",
description: "Move the origin of an Alarm",
value: "move-origin",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "x-coord",
description: "X Coordinate of the new origin",
value: "x-coord",
type: CommandOptions.Float,
type: ApplicationCommandOptionType.Float,
min_value: 0.01,
required: true,
},
@@ -215,7 +215,7 @@ module.exports = {
name: "y-coord",
description: "Y Coordinate of the new origin",
value: "y-coord",
type: CommandOptions.Float,
type: ApplicationCommandOptionType.Float,
min_value: 0.01,
required: true,
}]
+6 -6
View File
@@ -1,5 +1,5 @@
const { EmbedBuilder } = require("discord.js");
const CommandOptions = require("../util/CommandOptionTypes").CommandOptionTypes;
const { ApplicationCommandOptionType } = require("discord.js");
const { createUser, addUser } = require("../database/user");
module.exports = {
@@ -17,12 +17,12 @@ module.exports = {
name: "balance",
description: "View your bank balance",
value: "balance",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "user",
description: "User to view ballance",
value: "user",
type: CommandOptions.User,
type: ApplicationCommandOptionType.User,
required: false,
}]
},
@@ -30,20 +30,20 @@ module.exports = {
name: "transfer",
description: "Transfer money to another user",
value: "transfer",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [
{
name: "user",
description: "User to transfer to",
value: "user",
type: CommandOptions.User,
type: ApplicationCommandOptionType.User,
required: true,
},
{
name: "amount",
description: "The amount to transfer",
value: "amount",
type: CommandOptions.Float,
type: ApplicationCommandOptionType.Float,
min_value: 0.01,
required: true,
},
+7 -7
View File
@@ -1,5 +1,5 @@
const { EmbedBuilder } = require("discord.js");
const CommandOptions = require("../util/CommandOptionTypes").CommandOptionTypes;
const { ApplicationCommandOptionType } = require("discord.js");
const { createUser, addUser } = require("../database/user");
const { UpdatePlayer } = require("../database/player");
@@ -17,37 +17,37 @@ module.exports = {
name: "set",
description: "Set a bounty on a player",
value: "set",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "gamertag",
description: "Gamertag of player for bounty",
value: "gamertag",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: true,
}, {
name: "value",
description: "Amount of the bounty",
value: "value",
type: CommandOptions.Float,
type: ApplicationCommandOptionType.Float,
min_value: 0.01,
required: true
}, {
name: "anonymous",
description: "Make this bounty anonymous (does not show your name)",
value: false,
type: CommandOptions.Boolean,
type: ApplicationCommandOptionType.Boolean,
required: false
}]
}, {
name: "pay",
description: "Pay off your bounty",
value: "pay",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
}, {
name: "view",
description: "View all active bounties",
value: "view",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
}],
SlashCommand: {
/**
+2 -2
View File
@@ -1,5 +1,5 @@
const { ActionRowBuilder, EmbedBuilder, ButtonBuilder, ButtonStyle, StringSelectMenuBuilder } = require("discord.js");
const CommandOptions = require("../util/CommandOptionTypes").CommandOptionTypes;
const { ApplicationCommandOptionType } = require("discord.js");
const { Armbands } = require("../database/armbands.js");
module.exports = {
@@ -16,7 +16,7 @@ module.exports = {
name: "faction_role",
description: "Claim an armband for this faction role",
value: "faction_role",
type: CommandOptions.Role,
type: ApplicationCommandOptionType.Role,
required: true,
}],
SlashCommand: {
+3 -3
View File
@@ -1,5 +1,5 @@
const { EmbedBuilder } = require("discord.js");
const CommandOptions = require("../util/CommandOptionTypes").CommandOptionTypes;
const { ApplicationCommandOptionType } = require("discord.js");
const { insertPVPstats } = require("../database/player");
module.exports = {
@@ -16,12 +16,12 @@ module.exports = {
name: "discord",
description: "Discord user to lookup stats",
value: "discord",
type: CommandOptions.User,
type: ApplicationCommandOptionType.User,
required: false,
}, {
name: "gamertag",
description: "Gamertag to lookup stats",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: false,
}],
SlashCommand: {
+60 -60
View File
@@ -1,5 +1,5 @@
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js");
const CommandOptions = require("../util/CommandOptionTypes").CommandOptionTypes;
const { ApplicationCommandOptionType } = require("discord.js");
const bitfieldCalculator = require("discord-bitfield-calculator");
const { getDefaultSettings } = require("../database/guild");
@@ -18,18 +18,18 @@ module.exports = {
name: "killfeed",
description: "Configure the killfeed",
value: "killfeed",
type: CommandOptions.SubCommandGroup,
type: ApplicationCommandOptionType.SubCommandGroup,
options: [
{
name: "channel",
description: "Configure the killfeed channel",
value: "channel",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "channel",
description: "The channel to configure",
value: "channel",
type: CommandOptions.Channel,
type: ApplicationCommandOptionType.Channel,
required: true
}]
},
@@ -37,12 +37,12 @@ module.exports = {
name: "show_coords",
description: "Show the coordinates of the victim in the killfeed channel.",
value: "show_coords",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "configuration",
description: "True or False",
value: false,
type: CommandOptions.Boolean,
type: ApplicationCommandOptionType.Boolean,
required: true,
}]
},
@@ -50,12 +50,12 @@ module.exports = {
name: "show_weapon",
description: "Show the image of the weapon in the killfeed",
value: "show_weapon",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "configuration",
description: "True or False",
value: false,
type: CommandOptions.Boolean,
type: ApplicationCommandOptionType.Boolean,
required: true,
}]
}
@@ -65,18 +65,18 @@ module.exports = {
name: "allowed_channels",
description: "Set channels you're allowed to use the bot in",
value: "allowed_channels",
type: CommandOptions.SubCommandGroup,
type: ApplicationCommandOptionType.SubCommandGroup,
options: [
{
name: "add",
description: "Add channel",
value: "add",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "channel",
description: "The channel to configure",
value: "channel",
type: CommandOptions.Channel,
type: ApplicationCommandOptionType.Channel,
channel_types: [0], // Restrict to text channel
required: true,
}]
@@ -85,12 +85,12 @@ module.exports = {
name: "remove",
description: "Remove channel",
value: "remove",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "channel",
description: "The channel to configure",
value: "channel",
type: CommandOptions.Channel,
type: ApplicationCommandOptionType.Channel,
channel_types: [0], // Restrict to text channel
required: true,
}]
@@ -99,13 +99,13 @@ module.exports = {
name: "clear",
description: "Clears all configured channels",
value: "clear",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
},
{
name: "view",
description: "View configured allowed channels",
value: "view",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
}
]
},
@@ -113,13 +113,13 @@ module.exports = {
name: "set_channel",
description: "Configure a channel",
value: "set_channel",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [
{
name: "channel_type",
description: "Select the channel type",
value: "channel_type",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
choices: [
{ name: "Killfeed", value: "killfeedChannel" }, { name: "Admin Logs", value: "connectionLogsChannel" },
{ name: "Welcome", value: "welcomeChannel" }, { name: "Online Players", value: "activePlayersChannel" },
@@ -130,7 +130,7 @@ module.exports = {
name: "channel",
description: "The channel to configure",
value: "channel",
type: CommandOptions.Channel,
type: ApplicationCommandOptionType.Channel,
channel_types: [0], // Restrict to text channel
required: true,
},
@@ -140,12 +140,12 @@ module.exports = {
name: "linked_gt_role",
description: "Role for users with linked gamertags",
value: "linked_gt_role",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "role",
description: "Role to configure",
value: "role",
type: CommandOptions.Role,
type: ApplicationCommandOptionType.Role,
required: true,
}]
},
@@ -153,12 +153,12 @@ module.exports = {
name: "member_role",
description: "Role for users who join the server",
value: "member_role",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "role",
description: "Role to configure",
value: "role",
type: CommandOptions.Role,
type: ApplicationCommandOptionType.Role,
required: true,
}]
},
@@ -166,18 +166,18 @@ module.exports = {
name: "bot_admin_role",
description: "Set/remove bot admin role",
value: "bot_admin_role",
type: CommandOptions.SubCommandGroup,
type: ApplicationCommandOptionType.SubCommandGroup,
options: [
{
name: "add",
description: "Configure role to be bot admin",
value: "add",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "role",
description: "Role to confiure",
value: "role",
type: CommandOptions.Role,
type: ApplicationCommandOptionType.Role,
required: true,
}]
},
@@ -185,12 +185,12 @@ module.exports = {
name: "remove",
description: "Remove configured role as bot admin",
value: "remove",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "role",
description: "Role to remove",
value: "role",
type: CommandOptions.Role,
type: ApplicationCommandOptionType.Role,
required: true,
}]
},
@@ -198,7 +198,7 @@ module.exports = {
name: "view",
description: "View the configured bot admin roles",
value: "view",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
}
]
},
@@ -206,12 +206,12 @@ module.exports = {
name: "admin_ping_role",
description: "Admin role to ping in admin logs channel",
value: "admin_ping_role",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "role",
description: "Role to configure",
value: "role",
type: CommandOptions.Role,
type: ApplicationCommandOptionType.Role,
required: true,
}]
},
@@ -219,18 +219,18 @@ module.exports = {
name: "exclude",
description: "Exclude roles that can be used to claim armbands",
value: "exclude",
type: CommandOptions.SubCommandGroup,
type: ApplicationCommandOptionType.SubCommandGroup,
options: [
{
name: "add",
description: "Configure role to be excluded",
value: "add",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "role",
description: "Role to confiure",
value: "role",
type: CommandOptions.Role,
type: ApplicationCommandOptionType.Role,
required: true,
}]
},
@@ -238,12 +238,12 @@ module.exports = {
name: "remove",
description: "Remove configured role thats excluded",
value: "remove",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "role",
description: "Role to remove",
value: "role",
type: CommandOptions.Role,
type: ApplicationCommandOptionType.Role,
required: true,
}]
},
@@ -251,7 +251,7 @@ module.exports = {
name: "view",
description: "View the configured excluded roles",
value: "view",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
},
]
},
@@ -259,24 +259,24 @@ module.exports = {
name: "reset",
description: "Restore all settings to default configurations",
value: "reset",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
},
{
name: "view",
description: "View current settings configuration",
value: "view",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
},
{
name: "starting_balance",
description: "Set the starting balance of a new user",
value: "starting_balance",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "amount",
description: "The amount to set the starting balance",
value: "amount",
type: CommandOptions.Float,
type: ApplicationCommandOptionType.Float,
min_value: 1.00,
required: true,
}]
@@ -285,12 +285,12 @@ module.exports = {
name: "uav-price",
description: "Configure the price of a UAV",
value: "uav-price",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "amount",
description: "The amount to set the UAV price",
value: "amount",
type: CommandOptions.Float,
type: ApplicationCommandOptionType.Float,
min_value: 0.01,
required: true,
}]
@@ -299,12 +299,12 @@ module.exports = {
name: "emp-price",
description: "Configure the price of an EMP",
value: "emp-price",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "amount",
description: "The amount to set the EMP price",
value: "amount",
type: CommandOptions.Float,
type: ApplicationCommandOptionType.Float,
min_value: 0.01,
required: true,
}]
@@ -313,26 +313,26 @@ module.exports = {
name: "income_role",
description: "Set/remove roles to recieve income",
value: "set_income_role",
type: CommandOptions.SubCommandGroup,
type: ApplicationCommandOptionType.SubCommandGroup,
options: [
{
name: "set",
description: "Set role",
value: "set",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [
{
name: "role",
description: "Role to set",
value: "role",
type: CommandOptions.Role,
type: ApplicationCommandOptionType.Role,
required: true,
},
{
name: "amount",
description: "The amount to collect",
value: 120.00,
type: CommandOptions.Float,
type: ApplicationCommandOptionType.Float,
min_value: 0.01,
required: true,
}
@@ -342,12 +342,12 @@ module.exports = {
name: "remove",
description: "Remove role",
value: "remove",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "role",
description: "Role to remove",
value: "role",
type: CommandOptions.Role,
type: ApplicationCommandOptionType.Role,
required: true,
}]
},
@@ -357,12 +357,12 @@ module.exports = {
name: "income_limiter",
description: "Change the number of hours to wait before collecting next income",
value: "income_limiter",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "hours",
description: "Number of hours till income can be collected",
value: 168.00, // 1 week
type: CommandOptions.Float,
type: ApplicationCommandOptionType.Float,
min_value: 1.00,
required: true,
}]
@@ -371,12 +371,12 @@ module.exports = {
name: "combat-log-timer",
description: "Adjust number of minutes to detect combat logs (0 disables combat log)",
value: "combat-log-timer",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "minutes",
description: "Minutes to qualify combat log",
value: 5,
type: CommandOptions.Integer,
type: ApplicationCommandOptionType.Integer,
min_value: 0,
}]
},
@@ -384,12 +384,12 @@ module.exports = {
name: "toggle-uav-purchase",
description: "Allow/Disallow UAV purchases",
value: "toggle-uav-purchase",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "configuration",
description: "True or False",
value: false,
type: CommandOptions.Boolean,
type: ApplicationCommandOptionType.Boolean,
required: true,
}]
},
@@ -397,12 +397,12 @@ module.exports = {
name: "toggle-emp-purchase",
description: "Allow/Disallow EMP purchases",
value: "toggle-uav-purchase",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "configuration",
description: "True or False",
value: false,
type: CommandOptions.Boolean,
type: ApplicationCommandOptionType.Boolean,
required: true,
}]
},
@@ -410,12 +410,12 @@ module.exports = {
name: "welcome_message_server_name",
description: "Configure the server name in the welcome message",
value: "welcome_message_server_name",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "name",
description: "Server name to include in welcome message",
value: "name",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: true,
}]
}
+8 -8
View File
@@ -1,5 +1,5 @@
const { EmbedBuilder, ActionRowBuilder, StringSelectMenuBuilder } = require("discord.js");
const CommandOptions = require("../util/CommandOptionTypes").CommandOptionTypes;
const { ApplicationCommandOptionType } = require("discord.js");
const bitfieldCalculator = require("discord-bitfield-calculator");
module.exports = {
@@ -16,19 +16,19 @@ module.exports = {
name: "player-track",
description: "Track a player and announce location",
value: "player-track",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "gamertag",
description: "Gamertag of player",
value: "gamertag",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: true,
},
{
name: "time",
description: "Duration of tracking",
value: "time",
type: CommandOptions.Integer,
type: ApplicationCommandOptionType.Integer,
required: true,
choices: [
{ name: "10-minutes", value: 10 }, { name: "15-minutes", value: 15 }, { name: "20-minutes", value: 20 }, { name: "25-minutes", value: 25 },
@@ -39,28 +39,28 @@ module.exports = {
name: "event-name",
description: "Name of the event",
value: "event-name",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: true,
},
{
name: "channel",
description: "Channel to post tracking data",
value: "channel",
type: CommandOptions.Channel,
type: ApplicationCommandOptionType.Channel,
channel_types: [0], // Restrict to text channel
required: true,
}, {
name: "role",
description: "Optional role to ping",
value: "role",
type: CommandOptions.Role,
type: ApplicationCommandOptionType.Role,
required: false,
}]
}, {
name: "delete",
description: "Delete an active event",
value: "delete",
type: CommandOptions.SubCommand
type: ApplicationCommandOptionType.SubCommand
}],
SlashCommand: {
/**
+2 -2
View File
@@ -1,5 +1,5 @@
const { EmbedBuilder } = require("discord.js");
const CommandOptions = require("../util/CommandOptionTypes").CommandOptionTypes;
const { ApplicationCommandOptionType } = require("discord.js");
const { Armbands } = require("../database/armbands.js");
module.exports = {
@@ -16,7 +16,7 @@ module.exports = {
name: "faction_role",
description: "View a specific faction's armband by role",
value: "faction_role",
type: CommandOptions.Role,
type: ApplicationCommandOptionType.Role,
required: false,
}],
SlashCommand: {
+2 -2
View File
@@ -1,5 +1,5 @@
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js");
const CommandOptions = require("../util/CommandOptionTypes").CommandOptionTypes;
const { ApplicationCommandOptionType } = require("discord.js");
const { UpdatePlayer } = require("../database/player");
module.exports = {
@@ -16,7 +16,7 @@ module.exports = {
name: "gamertag",
description: "Gamertag of player",
value: "gamertag",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: true,
}],
SlashCommand: {
+6 -6
View File
@@ -1,5 +1,5 @@
const { EmbedBuilder } = require("discord.js");
const CommandOptions = require("../util/CommandOptionTypes").CommandOptionTypes;
const { ApplicationCommandOptionType } = require("discord.js");
const pack = require("../../package"); // Project root package.json
module.exports = {
@@ -17,12 +17,12 @@ module.exports = {
name: "commands",
description: "List all commands",
value: "commands",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "command",
description: "Get information on a specific command",
value: "command",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: false,
}]
},
@@ -30,19 +30,19 @@ module.exports = {
name: "support",
description: "Get support for Application",
value: "support",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
},
{
name: "credits",
description: "DayZ.R Bot Credits",
value: "credits",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
},
{
name: "stats",
description: "Current Bot Statistics",
value: "stats",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
}
],
SlashCommand: {
+3 -3
View File
@@ -1,5 +1,5 @@
const { EmbedBuilder } = require("discord.js");
const CommandOptions = require("../util/CommandOptionTypes").CommandOptionTypes;
const { ApplicationCommandOptionType } = require("discord.js");
module.exports = {
name: "leaderboard",
@@ -15,7 +15,7 @@ module.exports = {
name: "category",
description: "Leaderboard Category",
value: "category",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: true,
choices: [
{ name: "Money", value: "money" },
@@ -38,7 +38,7 @@ module.exports = {
name: "limit",
description: "Leaderboard limit",
value: "limit",
type: CommandOptions.Integer,
type: ApplicationCommandOptionType.Integer,
min_value: 1,
max_value: 25,
required: true,
+5 -5
View File
@@ -1,5 +1,5 @@
const { EmbedBuilder } = require("discord.js");
const CommandOptions = require("../util/CommandOptionTypes").CommandOptionTypes;
const { ApplicationCommandOptionType } = require("discord.js");
module.exports = {
name: "lookup",
@@ -15,24 +15,24 @@ module.exports = {
name: "discord",
description: "Find a Discord user from a Gamertag",
value: "discord",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "gamertag",
description: "Gamertag of player",
value: "gamertag",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: true,
}]
}, {
name: "gamertag",
description: "Find a Gamertag from a Discord user",
value: "gamertag",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "user",
description: "Discord User",
value: "user",
type: CommandOptions.User,
type: ApplicationCommandOptionType.User,
required: true,
}]
}],
+4 -4
View File
@@ -1,5 +1,5 @@
const { EmbedBuilder } = require("discord.js");
const CommandOptions = require("../util/CommandOptionTypes").CommandOptionTypes;
const { ApplicationCommandOptionType } = require("discord.js");
const { insertPVPstats } = require("../database/player");
module.exports = {
@@ -16,7 +16,7 @@ module.exports = {
name: "category",
description: "Leaderboard Category",
value: "category",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: true,
choices: [
{ name: "Money", value: "money" },
@@ -39,12 +39,12 @@ module.exports = {
name: "discord",
description: "discord user to lookup stats",
value: "discord",
type: CommandOptions.User,
type: ApplicationCommandOptionType.User,
required: false,
}, {
name: "gamertag",
description: "gamertag to lookup stats",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: false,
}],
SlashCommand: {
+2 -2
View File
@@ -1,6 +1,6 @@
const { EmbedBuilder, ActionRowBuilder, StringSelectMenuBuilder } = require("discord.js");
const { createUser, addUser } = require("../database/user");
const CommandOptions = require("../util/CommandOptionTypes").CommandOptionTypes;
const { ApplicationCommandOptionType } = require("discord.js");
module.exports = {
name: "purchase-emp",
@@ -16,7 +16,7 @@ module.exports = {
name: "duration",
description: "Select the duration of the emp (30 or 60 minutes)",
value: "duration",
type: CommandOptions.Integer,
type: ApplicationCommandOptionType.Integer,
required: true,
choices: [
{ name: "30 Minutes", value: 30 },
+3 -3
View File
@@ -1,5 +1,5 @@
const { EmbedBuilder } = require("discord.js");
const CommandOptions = require("../util/CommandOptionTypes").CommandOptionTypes;
const { ApplicationCommandOptionType } = require("discord.js");
const { createUser, addUser } = require("../database/user")
module.exports = {
@@ -17,7 +17,7 @@ module.exports = {
name: "x-coord",
description: "X Coordinate of the origin",
value: "x-coord",
type: CommandOptions.Float,
type: ApplicationCommandOptionType.Float,
min_value: 0.01,
required: true,
},
@@ -25,7 +25,7 @@ module.exports = {
name: "y-coord",
description: "Y Coordinate of the origin",
value: "y-coord",
type: CommandOptions.Float,
type: ApplicationCommandOptionType.Float,
min_value: 0.01,
required: true,
},
+2 -2
View File
@@ -1,5 +1,5 @@
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js");
const CommandOptions = require("../util/CommandOptionTypes").CommandOptionTypes;
const { ApplicationCommandOptionType } = require("discord.js");
const { addUser } = require("../database/user");
const bitfieldCalculator = require("discord-bitfield-calculator");
@@ -17,7 +17,7 @@ module.exports = {
name: "user",
description: "User to reset",
value: "user",
type: CommandOptions.User,
type: ApplicationCommandOptionType.User,
required: true,
}],
SlashCommand: {
+15 -15
View File
@@ -1,5 +1,5 @@
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, ModalBuilder, TextInputBuilder, TextInputStyle } = require("discord.js");
const CommandOptions = require("../util/CommandOptionTypes").CommandOptionTypes;
const { ApplicationCommandOptionType } = require("discord.js");
const bitfieldCalculator = require("discord-bitfield-calculator");
const { BanPlayer, UnbanPlayer, RestartServer, CheckServerStatus, DisableBaseDamage, DisableContainerDamage, NitradoCredentialStatus } = require("../util/NitradoAPI");
const { encrypt, decrypt } = require("../util/Cryptic");
@@ -18,48 +18,48 @@ module.exports = {
name: "initialize",
description: "Connect your Nitrado server to the bot",
value: "initialize",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
},
{
name: "disconnect",
description: "Delete your Nitrado server from the bot database",
value: "disconnect",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
},
{
name: "credentials-status",
description: "Check the status of your Nitrado Credentials",
value: "credentials-status",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
},
{
name: "retry-credentials",
description: "If your credentials are marked as FAILED, try retreiving Nitrado logs again.",
value: "retry-credentials",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
},
{
name: "ban-player",
description: "Ban a player from the DayZ server",
value: "ban-player",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "gamertag",
description: "gamertag of the player to ban.",
value: "gamertag",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: true,
}]
}, {
name: "unban-player",
description: "Unban a player from the DayZ server",
value: "unban-player",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "gamertag",
description: "gamertag of the player to unban.",
value: "gamertag",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: true,
}]
},
@@ -67,34 +67,34 @@ module.exports = {
name: "restart",
description: "Restart the DayZ Server",
value: "restart",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
}, {
name: "auto-restart",
description: "Enable/Disable periodic server checks and restart if stopped",
value: "auto-restart",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
}, {
name: "disable-base-damage",
description: "Disable/Enable base damage",
value: "disable-base-damage",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "preference",
description: "DisableBaseDamage Preference",
value: true,
type: CommandOptions.Boolean,
type: ApplicationCommandOptionType.Boolean,
required: true,
}]
}, {
name: "disable-container-damage",
description: "Disable/Enable container damage",
value: "disable-container-damage",
type: CommandOptions.SubCommand,
type: ApplicationCommandOptionType.SubCommand,
options: [{
name: "preference",
description: "disableContainerDamage Preference",
value: true,
type: CommandOptions.Boolean,
type: ApplicationCommandOptionType.Boolean,
required: true,
}]
}],
+4 -4
View File
@@ -1,5 +1,5 @@
const { EmbedBuilder, ActionRowBuilder, StringSelectMenuBuilder } = require("discord.js");
const CommandOptions = require("../util/CommandOptionTypes").CommandOptionTypes;
const { ApplicationCommandOptionType } = require("discord.js");
const { weapons } = require("../database/weapons");
const { insertPVPstats, createWeaponStats } = require("../database/player");
@@ -17,7 +17,7 @@ module.exports = {
name: "category",
description: "Weapon category",
value: "category",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: true,
choices: [
{ name: "Handguns", value: "handguns" },
@@ -36,12 +36,12 @@ module.exports = {
name: "discord",
description: "Discord user to lookup stats",
value: "discord",
type: CommandOptions.User,
type: ApplicationCommandOptionType.User,
required: false,
}, {
name: "gamertag",
description: "Gamertag to lookup stats",
type: CommandOptions.String,
type: ApplicationCommandOptionType.String,
required: false,
}],
SlashCommand: {
File diff suppressed because one or more lines are too long.
File diff suppressed because one or more lines are too long.
@@ -1,17 +1,22 @@
const { calculateVector } = require("../util/Vector");
import { calculateVector } from "@util/Vector";
module.exports = {
Missions: {
export const Missions = {
"dayzOffline.chernarusplus": "Chernarus",
"dayzOffline.enoch": "Livonia",
"dayzOffline.sakhal": "Sakhal",
},
} as const;
export type MissionKey = keyof typeof Missions;
export type MissionName = typeof Missions[MissionKey];
export type Position = [number, number];
// Calculates the nearest location to a given coordinate
nearest: (pos, mission) => {
export function nearest(pos: Position, mission: MissionName): string {
let tempDest;
let lastDist = 1000000;
let destination_dir;
for (let i = 0; i < destinations[mission].length; i++) {
let { distance, theta, dir } = calculateVector(pos, destinations[mission][i].coord);
if (distance < lastDist) {
@@ -21,11 +26,15 @@ module.exports = {
}
}
return lastDist > 500 ? `${destination_dir} of ${tempDest}` : `Near ${tempDest}`;
}
};
interface Destination {
name: string;
coord: Position;
}
// A curated list of destinations across DayZ Chernarus and Livonia
const destinations = {
const destinations: Record<MissionName, Array<Destination>> = {
Chernarus: [
{
name: "Sinystok",
-102
View File
@@ -1,102 +0,0 @@
module.exports = {
GetGuild: async (client, GuildId) => {
let guild = undefined;
if (client.databaseConnected) guild = await client.dbo.collection("guilds").findOne({ "server.serverID": GuildId }).then(guild => guild);
// If guild not found, generate guild default
if (!guild) {
guild = {}
guild.server = module.exports.getDefaultSettings(GuildId);
guild.Nitrado = undefined;
if (client.databaseConnected) {
client.dbo.collection("guilds").insertOne(guild, (err, res) => {
if (err) client.error(`GetGuild Insert Error: ${err}`);
});
}
}
return {
serverID: GuildId,
Nitrado: guild.Nitrado,
lastLog: guild.server.lastLog,
serverName: guild.server.serverName,
autoRestart: guild.server.autoRestart,
showKillfeedCoords: guild.server.showKillfeedCoords,
showKillfeedWeapon: guild.server.showKillfeedWeapon,
purchaseUAV: guild.server.purchaseUAV,
purchaseEMP: guild.server.purchaseEMP,
allowedChannels: guild.server.allowedChannels,
customChannelStatus: guild.server.allowedChannels.length > 0 ? true : false,
hasBotAdmin: guild.server.botAdminRoles.length > 0 ? true : false,
killfeedChannel: guild.server.killfeedChannel,
connectionLogsChannel: guild.server.connectionLogsChannel,
activePlayersChannel: guild.server.activePlayersChannel,
welcomeChannel: guild.server.welcomeChannel,
factionArmbands: guild.server.factionArmbands,
usedArmbands: guild.server.usedArmbands,
excludedRoles: guild.server.excludedRoles,
hasExcludedRoles: guild.server.excludedRoles.length > 0 ? true : false,
botAdminRoles: guild.server.botAdminRoles,
alarms: guild.server.alarms,
events: guild.server.events,
uavs: guild.server.uavs,
incomeRoles: guild.server.incomeRoles,
incomeLimiter: guild.server.incomeLimiter,
startingBalance: guild.server.startingBalance,
uavPrice: guild.server.uavPrice,
empPrice: guild.server.empPrice,
linkedGamertagRole: guild.server.linkedGamertagRole,
memberRole: guild.server.memberRole,
adminRole: guild.server.adminRole,
combatLogTimer: guild.server.combatLogTimer,
};
},
getDefaultSettings(GuildId) {
return {
serverID: GuildId,
lastLog: null,
serverName: "our server!",
autoRestart: 0,
showKillfeedCoords: 0,
showKillfeedWeapon: 0,
purchaseUAV: 1, // Allow/Disallow purchase of UAVs
purchaseEMP: 1, // Allow/Disallow purchase of EMPs
allowedChannels: [],
killfeedChannel: "",
connectionLogsChannel: "",
activePlayersChannel: "",
welcomeChannel: "",
factionArmbands: {},
usedArmbands: [],
excludedRoles: [],
botAdminRoles: [],
alarms: [],
events: [],
uavs: [],
incomeRoles: [],
incomeLimiter: 168, // # of hours in 7 days
startingBalance: 500,
uavPrice: 50000,
empPrice: 500000,
linkedGamertagRole: "",
memberRole: "",
adminRole: "",
combatLogTimer: 5, // minutes
}
}
}
+193
View File
@@ -0,0 +1,193 @@
import { Snowflake } from "discord.js";
import DayZR from "../DayZRBot";
import { NitradoCredentialStatus } from "@util/NitradoAPI";
export const enum IntegerBoolean {
FALSE,
TRUE
};
export interface UAV {
// TODO: fill this out
};
export interface Alarm {
// TODO: fill this out
};
export interface NitradoConfig {
ServerID: string;
UserID: string;
Auth: string;
Status: NitradoCredentialStatus;
};
interface GuildConfigAttributes {
serverID: Snowflake;
lastLog: string | null;
serverName: string;
autoRestart: IntegerBoolean;
showKillfeedCoords: IntegerBoolean;
showKillfeedWeapon: IntegerBoolean;
purchaseUAV: IntegerBoolean;
purchaseEMP: IntegerBoolean;
allowedChannels: Array<Snowflake>;
customChannelStatus?: boolean; // optional - generated outside of DB
hasBotAdmin?: boolean; // optional - generated outside of DB
killfeedChannel: Snowflake;
connectionLogsChannel: Snowflake;
activePlayersChannel: Snowflake;
welcomeChannel: Snowflake;
factionArmbands: any;
usedArmbands: Array<string>;
excludedRoles: Array<string>;
hasExcludedRoles?: boolean; // optional - generated outside of DB
botAdminRoles: Array<Snowflake>;
alarms: Array<Alarm>;
events: Array<any>;
uavs: Array<UAV>;
incomeRoles: Array<Snowflake>;
incomeLimiter: number;
startingBalance: number;
uavPrice: number;
empPrice: number;
linkedGamertagRole: Snowflake;
memberRole: Snowflake;
adminRole: Snowflake;
combatLogTimer: number;
}
interface GuildConfigDB {
server: GuildConfigAttributes;
Nitrado: NitradoConfig | null;
};
// TODO: have better names, i.e. combatLogTimer in seconds or minutes? inclomeLimiter?
// TODO: figure out interface of
// Also this is so stupid, in the DB all server attributes are under server,
// while in the code we almost always have the attributes directly in top
// level of object, i.e. guild.startingBalance instead of guild.server.startingBalance
export interface GuildConfig extends GuildConfigAttributes {
Nitrado: NitradoConfig | null;
}
export async function GetGuild(client: DayZR, GuildId: Snowflake): Promise<GuildConfig>
{
let guild: GuildConfigDB | null = null;
if (client.databaseConnected)
{
guild = await client.dbo.collection("guilds").findOne(
{
"server.serverID": GuildId
}
).then((guild: GuildConfigDB) => guild);
}
// If guild not found, generate guild default
if (!guild)
{
guild = {
server: getDefaultSettings(GuildId),
Nitrado: null,
};
if (client.databaseConnected)
{
client.dbo.collection("guilds").insertOne(guild, (err: string) => {
if (err) client.error(`GetGuild Insert Error: ${err}`);
});
}
}
return {
serverID: GuildId,
Nitrado: guild.Nitrado,
lastLog: guild.server.lastLog,
serverName: guild.server.serverName,
autoRestart: guild.server.autoRestart,
showKillfeedCoords: guild.server.showKillfeedCoords,
showKillfeedWeapon: guild.server.showKillfeedWeapon,
purchaseUAV: guild.server.purchaseUAV,
purchaseEMP: guild.server.purchaseEMP,
allowedChannels: guild.server.allowedChannels,
customChannelStatus: guild.server.allowedChannels.length > 0,
hasBotAdmin: guild.server.botAdminRoles.length > 0,
killfeedChannel: guild.server.killfeedChannel,
connectionLogsChannel: guild.server.connectionLogsChannel,
activePlayersChannel: guild.server.activePlayersChannel,
welcomeChannel: guild.server.welcomeChannel,
factionArmbands: guild.server.factionArmbands,
usedArmbands: guild.server.usedArmbands,
excludedRoles: guild.server.excludedRoles,
hasExcludedRoles: guild.server.excludedRoles.length > 0,
botAdminRoles: guild.server.botAdminRoles,
alarms: guild.server.alarms,
events: guild.server.events,
uavs: guild.server.uavs,
incomeRoles: guild.server.incomeRoles,
incomeLimiter: guild.server.incomeLimiter,
startingBalance: guild.server.startingBalance,
uavPrice: guild.server.uavPrice,
empPrice: guild.server.empPrice,
linkedGamertagRole: guild.server.linkedGamertagRole,
memberRole: guild.server.memberRole,
adminRole: guild.server.adminRole,
combatLogTimer: guild.server.combatLogTimer,
};
}
export function getDefaultSettings(GuildId: Snowflake): GuildConfigAttributes {
return {
serverID: GuildId,
lastLog: null,
serverName: "our server!",
autoRestart: IntegerBoolean.FALSE,
showKillfeedCoords: IntegerBoolean.FALSE,
showKillfeedWeapon: IntegerBoolean.FALSE,
purchaseUAV: IntegerBoolean.TRUE, // Allow/Disallow purchase of UAVs
purchaseEMP: IntegerBoolean.TRUE, // Allow/Disallow purchase of EMPs
allowedChannels: [],
killfeedChannel: "",
connectionLogsChannel: "",
activePlayersChannel: "",
welcomeChannel: "",
factionArmbands: {},
usedArmbands: [],
excludedRoles: [],
botAdminRoles: [],
alarms: [],
events: [],
uavs: [],
incomeRoles: [],
incomeLimiter: 168, // # of hours in 7 days
startingBalance: 500,
uavPrice: 50000,
empPrice: 500000,
linkedGamertagRole: "",
memberRole: "",
adminRole: "",
combatLogTimer: 5, // minutes
};
};
-15
View File
@@ -1,15 +0,0 @@
module.exports = {
CommandOptionTypes: {
SubCommand: 1,
SubCommandGroup: 2,
String: 3,
Integer: 4,
Boolean: 5,
User: 6,
Channel: 7,
Role: 8,
Mentionable: 9,
Float: 10, // AKA Number in Discord"s Documentation
Attachment: 11,
}
};
-311
View File
@@ -1,311 +0,0 @@
const { finished } = require("stream/promises");
const concat = require("concat-stream");
const { Readable } = require("stream");
const FormData = require("form-data");
const fs = require("fs");
const maxRetries = 5;
const retryDelay = 5000; // 5 seconds
// Private functions (only called locally)
const UploadNitradoFile = async (nitrado_cred, client, remoteDir, remoteFilename, localFileDir) => {
for (let retries = 0; retries <= maxRetries; retries++) {
try {
const res = await fetch(`https://api.nitrado.net/services/${nitrado_cred.ServerID}/gameservers/file_server/upload?` + new URLSearchParams({
path: remoteDir,
file: remoteFilename
}), {
method: "POST",
headers: {
"Authorization": nitrado_cred.Auth
},
}).then(response => response.json());
let contents = fs.readFileSync(localFileDir, "utf8");
const uploadRes = await fetch(res.data.token.url, {
method: "POST",
headers: {
"Content-Type": "application/binary",
token: res.data.token.token
},
body: contents,
})
if (!uploadRes.ok) {
client.error(`Failed to upload file to Nitrado (${nitrado_cred.ServerID}): status: ${uploadRes.status}, message: ${res.statusText}: UploadNitradoFile`);
if (retries === 2) return 1; // Return error status on the second failed status code.
} else {
return uploadRes;
}
} catch (error) {
client.error(`UploadNitradoFile: Error connecting to server (${nitrado_cred.ServerID}): ${error.message}`);
if (retries === maxRetries) {
client.error(`UploadNitradoFile: Error connecting to server (${nitrado_cred.ServerID}) after ${maxRetries} retries`);
return 1;
}
}
await new Promise(resolve => setTimeout(resolve, retryDelay)); // Delay before retrying
}
}
const HandlePlayerBan = async (nitrado_cred, client, gamertag, ban) => {
const data = await module.exports.FetchServerSettings(nitrado_cred, client, "HandlePlayerBan"); // Fetch server status
if (data && data != 1) {
let bans = data.data.gameserver.settings.general.bans;
if (ban) bans += `\r\n${gamertag}`;
else if (!ban) bans = bans.replace(gamertag, "");
else client.error("Incorrect Ban Option: HandlePlayerBan");
let category = "general";
let key = "bans";
return await module.exports.PostServerSettings(nitrado_cred, client, category, key, bans); // returns 1 (failed) or 0 (not failed)
}
}
const GetRemoteDir = async (nitrado_cred, client, dir = "") => {
const dirParam = client.exists(dir) ? `?dir=${dir}` : "";
for (let retries = 0; retries <= maxRetries; retries++) {
try {
const res = await fetch(`https://api.nitrado.net/services/${nitrado_cred.ServerID}/gameservers/file_server/list${dirParam}`, {
headers: {
"Authorization": nitrado_cred.Auth
}
}).then(response =>
response.json().then(data => data)
).then(res => res);
if (res.status === "error") return 1;
return res.data.entries;
} catch (error) {
client.error(`GetRemoteDir: Error connecting to server (${nitrado_cred.ServerID}): ${error}`);
if (retries == maxRetries) {
client.error(`GetRemoteDir: Error connecting to server (${nitrado_cred.ServerID}) after ${maxRetries} retries`);
return 1;
}
}
await new Promise(resolve => setTimeout(resolve, retryDelay)); // Delay before retrying
}
}
// Public functions (called externally)
module.exports = {
DownloadNitradoFile: async (nitrado_cred, client, filename, outputDir) => {
for (let retries = 0; retries <= maxRetries; retries++) {
try {
const res = await fetch(`https://api.nitrado.net/services/${nitrado_cred.ServerID}/gameservers/file_server/download?file=${filename}`, {
headers: {
"Authorization": nitrado_cred.Auth
}
}).then(response =>
response.json().then(data => data)
).then(res => res);
const stream = fs.createWriteStream(outputDir);
if (!res.data || !res.data.token) {
client.error(`Error downloading File "${filename}": message: ${res.message}: DownloadNitradoFile`);
return 1;
}
const { body } = await fetch(res.data.token.url);
await finished(Readable.fromWeb(body).pipe(stream));
return 0;
} catch (error) {
client.error(`DownloadNitradoFile: Error connecting to server (${nitrado_cred.ServerID}): ${error.message}`);
if (retries === maxRetries) {
client.error(`DownloadNitradoFile: Error connecting to server (${nitrado_cred.ServerID}) after ${maxRetries} retries`);
return 1;
}
}
await new Promise(resolve => setTimeout(resolve, retryDelay)); // Delay before retrying
}
},
/*
Export explicit function names; i.e BanPlayer() & UnbanPlayer()
that call to the private parent function HandlePlayerBan()
rather than write two whole different functions for each.
*/
BanPlayer: async (nitrado_cred, client, gamertag) => await HandlePlayerBan(nitrado_cred, client, gamertag, true),
UnbanPlayer: async (nitrado_cred, client, gamertag) => await HandlePlayerBan(nitrado_cred, client, gamertag, false),
RestartServer: async (nitrado_cred, client, restart_message, message) => {
const params = {
restart_message: restart_message,
message: message
};
for (let retries = 0; retries < maxRetries; retries++) {
try {
const res = await fetch(`https://api.nitrado.net/services/${nitrado_cred.ServerID}/gameservers/restart`, {
method: "POST",
headers: {
"Authorization": nitrado_cred.Auth,
},
body: JSON.stringify(params)
});
if (!res.ok) {
client.error(`Failed to restart Nitrado server (${nitrado_cred.ServerID}): status: ${res.status}, message: ${res.statusText}: RestartServer`);
return 1; // Return error status on failed status code.
} else {
return 0;
}
} catch (error) {
client.error(`RestartServer: Error connecting to server (${nitrado_cred.ServerID}): ${error.message}`);
if (retries === maxRetries) {
client.error(`RestartServer: Error connecting to server (${nitrado_cred.ServerID}) after ${maxRetries} retries`);
return 1;
}
}
await new Promise(resolve => setTimeout(resolve, retryDelay)); // Delay before retrying
}
},
FetchServerSettings: async (nitrado_cred, client, fetcher) => {
for (let retries = 0; retries <= maxRetries; retries++) {
try {
// get current status
const res = await fetch(`https://api.nitrado.net/services/${nitrado_cred.ServerID}/gameservers`, {
headers: {
"Authorization": nitrado_cred.Auth
}
});
if (!res.ok) {
client.error(`Failed to get Nitrado server stats (${nitrado_cred.ServerID}): status: ${res.status}, message: ${res.statusText}: ${fetcher} via FetchServerSettings`);
if (res.status == 401) return 1; // return immediately if unauthorized
if (retries === 2) return 1; // Return error status on the second failed status code.
} else {
const data = await res.json();
return data;
}
} catch (error) {
client.error(`${fetcher} via FetchServerSettings: Error connecting to server (${nitrado_cred.ServerID}): ${error.message}`);
if (retries === maxRetries) {
client.error(`${fetcher} via FetchServerSettings: Error connecting to server (${nitrado_cred.ServerID}) after ${maxRetries} retries`);
return 1;
}
}
await new Promise(resolve => setTimeout(resolve, retryDelay)); // Delay before retrying
}
},
PostServerSettings: async (nitrado_cred, client, category, key, value) => {
for (let retries = 0; retries <= maxRetries; retries++) {
try {
const formData = new FormData();
formData.append("category", category);
formData.append("key", key);
formData.append("value", value);
formData.pipe(concat(data => {
async function postData() {
const res = await fetch(`https://api.nitrado.net/services/${nitrado_cred.ServerID}/gameservers/settings`, {
method: "POST",
credentials: "include",
headers: {
...formData.getHeaders(),
"Authorization": nitrado_cred.Auth
},
body: data,
});
if (!res.ok) {
client.error(`Failed to get post Nitrado server settings (${nitrado_cred.ServerID}): status: ${res.status}, message: ${res.statusText}: PostServerSettings`);
if (retries === 2) return 1; // Return error status on the second failed status code.
} else {
const data = await res.json();
return data;
}
}
postData();
}));
return 0;
} catch (error) {
client.error(`PostServerSettings: Error connecting to server (${nitrado_cred.ServerID}): ${error.message}`);
if (retries === maxRetries) {
client.error(`PostServerSettings: Error connecting to server (${nitrado_cred.ServerID}) after ${maxRetries} retries`);
return 1;
}
}
await new Promise(resolve => setTimeout(resolve, retryDelay)); // Delay before retrying
}
},
CheckServerStatus: async (nitrado_cred, client) => {
const data = await module.exports.FetchServerSettings(nitrado_cred, client, "CheckServerStatus"); // Fetch server status
if (data && data != 1) {
if (data && data.data.gameserver.status === "stopped") {
client.log(`Restart of Nitrado server ${nitrado_cred.ServerID} has been invoked by the bot, the periodic check showed status of "${data.data.gameserver.status}".`);
// Write optional "restart_message" to set in the Nitrado server logs and send a notice "message" to your server community.
restart_message = "Server being restarted by periodic bot check.";
message = "The server was restarted by periodic bot check!";
module.exports.RestartServer(nitrado_cred, client, restart_message, message);
}
}
},
DisableBaseDamage: async (nitrado_cred, client, preference) => {
const pref = preference ? "1" : "0";
const posted = await module.exports.PostServerSettings(nitrado_cred, client, "config", "disableBaseDamage", pref);
if (posted == 1) return 1;
const remoteDirs = await GetRemoteDir(nitrado_cred, client);
if (remoteDirs == 1) return 1;
const basePath = remoteDirs.filter(dir => dir.type == "dir")[0].path
const remoteDirsFromBase = await GetRemoteDir(nitrado_cred, client, basePath);
if (remoteDirsFromBase == 1) return 1;
const missionPath = remoteDirsFromBase[0].path;
const cfggameplayPath = `${missionPath}/cfggameplay.json`;
const jsonDir = `./logs/cfggameplay.json`;
await module.exports.DownloadNitradoFile(nitrado_cred, client, cfggameplayPath, jsonDir);
let gameplay = JSON.parse(fs.readFileSync(jsonDir));
gameplay.GeneralData.disableBaseDamage = preference;
// write JSON to file
fs.writeFileSync(jsonDir, JSON.stringify(gameplay, null, 2));
const uploaded = await UploadNitradoFile(nitrado_cred, client, missionPath, "cfggameplay.json", jsonDir);
if (uploaded == 1) return 1;
return 0;
},
DisableContainerDamage: async (nitrado_cred, client, preference) => {
const pref = preference ? "1" : "0";
const posted = await module.exports.PostServerSettings(nitrado_cred, client, "config", "disableContainerDamage", pref);
if (posted == 1) return 1;
const remoteDirs = await GetRemoteDir(nitrado_cred, client);
if (remoteDirs == 1) return 1;
const basePath = remoteDirs.filter(dir => dir.type == "dir")[0].path
const remoteDirsFromBase = await GetRemoteDir(nitrado_cred, client, basePath);
if (remoteDirsFromBase == 1) return 1;
const missionPath = remoteDirsFromBase[0].path;
const cfggameplayPath = `${missionPath}/cfggameplay.json`;
const jsonDir = `./logs/cfggameplay.json`;
await module.exports.DownloadNitradoFile(nitrado_cred, client, cfggameplayPath, jsonDir);
let gameplay = JSON.parse(fs.readFileSync(jsonDir));
gameplay.GeneralData.disableContainerDamage = preference;
// write JSON to file
fs.writeFileSync(jsonDir, JSON.stringify(gameplay, null, 2));
const uploaded = await UploadNitradoFile(nitrado_cred, client, missionPath, "cfggameplay.json", jsonDir);
if (uploaded == 1) return 1;
return 0;
},
NitradoCredentialStatus: {
FAILED: "FAILED",
OK: "OK",
},
}
+311
View File
@@ -0,0 +1,311 @@
import { finished } from "stream/promises";
const concat = require("concat-stream"); // convert to import ?
import { Readable } from "stream";
import FormData from "form-data";
import * as fs from "fs";
const MAX_RETRIES = 5;
const RETRY_DELAY_MS = 5000; // 5 seconds
export const enum NitradoCredentialStatus {
FAILED = "FAILED",
OK = "OK",
};
/**
* TODO: I have littered this file with "any" types just to temporarily have no errors after converting from .js to .ts
* come back and actually go through line by line and clean this whole file
*/
const UploadNitradoFile = async (nitrado_cred: any, client: any, remoteDir: any, remoteFilename: any, localFileDir: any) => {
for (let retries = 0; retries <= MAX_RETRIES; retries++) {
try {
const res = await fetch(`https://api.nitrado.net/services/${nitrado_cred.ServerID}/gameservers/file_server/upload?` + new URLSearchParams({
path: remoteDir,
file: remoteFilename
}), {
method: "POST",
headers: {
"Authorization": nitrado_cred.Auth
},
}).then(response => response.json());
let contents = fs.readFileSync(localFileDir, "utf8");
const uploadRes = await fetch(res.data.token.url, {
method: "POST",
headers: {
"Content-Type": "application/binary",
token: res.data.token.token
},
body: contents,
})
if (!uploadRes.ok) {
client.error(`Failed to upload file to Nitrado (${nitrado_cred.ServerID}): status: ${uploadRes.status}, message: ${res.statusText}: UploadNitradoFile`);
if (retries === 2) return 1; // Return error status on the second failed status code.
} else {
return uploadRes;
}
} catch (error: any) {
client.error(`UploadNitradoFile: Error connecting to server (${nitrado_cred.ServerID}): ${error.message}`);
if (retries === MAX_RETRIES) {
client.error(`UploadNitradoFile: Error connecting to server (${nitrado_cred.ServerID}) after ${MAX_RETRIES} retries`);
return 1;
}
}
await new Promise(resolve => setTimeout(resolve, RETRY_DELAY_MS)); // Delay before retrying
}
}
const HandlePlayerBan = async (nitrado_cred: any, client: any, gamertag: any, ban: any) => {
const data = await module.exports.FetchServerSettings(nitrado_cred, client, "HandlePlayerBan"); // Fetch server status
if (data && data != 1) {
let bans = data.data.gameserver.settings.general.bans;
if (ban) bans += `\r\n${gamertag}`;
else if (!ban) bans = bans.replace(gamertag, "");
else client.error("Incorrect Ban Option: HandlePlayerBan");
let category = "general";
let key = "bans";
return await module.exports.PostServerSettings(nitrado_cred, client, category, key, bans); // returns 1 (failed) or 0 (not failed)
}
}
const GetRemoteDir = async (nitrado_cred: any, client: any, dir = "") => {
const dirParam = client.exists(dir) ? `?dir=${dir}` : "";
for (let retries = 0; retries <= MAX_RETRIES; retries++) {
try {
const res = await fetch(`https://api.nitrado.net/services/${nitrado_cred.ServerID}/gameservers/file_server/list${dirParam}`, {
headers: {
"Authorization": nitrado_cred.Auth
}
}).then(response =>
response.json().then(data => data)
).then(res => res);
if (res.status === "error") return 1;
return res.data.entries;
} catch (error) {
client.error(`GetRemoteDir: Error connecting to server (${nitrado_cred.ServerID}): ${error}`);
if (retries == MAX_RETRIES) {
client.error(`GetRemoteDir: Error connecting to server (${nitrado_cred.ServerID}) after ${MAX_RETRIES} retries`);
return 1;
}
}
await new Promise(resolve => setTimeout(resolve, RETRY_DELAY_MS)); // Delay before retrying
}
}
/*** exported function ***/
export const DownloadNitradoFile = async (nitrado_cred: any, client: any, filename: any, outputDir: any) => {
for (let retries = 0; retries <= MAX_RETRIES; retries++) {
try {
const res = await fetch(`https://api.nitrado.net/services/${nitrado_cred.ServerID}/gameservers/file_server/download?file=${filename}`, {
headers: {
"Authorization": nitrado_cred.Auth
}
}).then(response =>
response.json().then(data => data)
).then(res => res);
const stream: any = fs.createWriteStream(outputDir);
if (!res.data || !res.data.token) {
client.error(`Error downloading File "${filename}": message: ${res.message}: DownloadNitradoFile`);
return 1;
}
const { body }: any = await fetch(res.data.token.url);
await finished(Readable.fromWeb(body).pipe(stream));
return 0;
} catch (error: any) {
client.error(`DownloadNitradoFile: Error connecting to server (${nitrado_cred.ServerID}): ${error.message}`);
if (retries === MAX_RETRIES) {
client.error(`DownloadNitradoFile: Error connecting to server (${nitrado_cred.ServerID}) after ${MAX_RETRIES} retries`);
return 1;
}
}
await new Promise(resolve => setTimeout(resolve, RETRY_DELAY_MS)); // Delay before retrying
}
};
/*
Export explicit function names; i.e BanPlayer() & UnbanPlayer()
that call to the private parent function HandlePlayerBan()
rather than write two whole different functions for each.
*/
export const BanPlayer = async (nitrado_cred: any, client: any, gamertag: any) => await HandlePlayerBan(nitrado_cred, client, gamertag, true);
export const UnbanPlayer = async (nitrado_cred: any, client: any, gamertag: any) => await HandlePlayerBan(nitrado_cred, client, gamertag, false);
export const RestartServer = async (nitrado_cred: any, client: any, restart_message: any, message: any) => {
const params = {
restart_message: restart_message,
message: message
};
for (let retries = 0; retries < MAX_RETRIES; retries++) {
try {
const res = await fetch(`https://api.nitrado.net/services/${nitrado_cred.ServerID}/gameservers/restart`, {
method: "POST",
headers: {
"Authorization": nitrado_cred.Auth,
},
body: JSON.stringify(params)
});
if (!res.ok) {
client.error(`Failed to restart Nitrado server (${nitrado_cred.ServerID}): status: ${res.status}, message: ${res.statusText}: RestartServer`);
return 1; // Return error status on failed status code.
} else {
return 0;
}
} catch (error: any) {
client.error(`RestartServer: Error connecting to server (${nitrado_cred.ServerID}): ${error.message}`);
if (retries === MAX_RETRIES) {
client.error(`RestartServer: Error connecting to server (${nitrado_cred.ServerID}) after ${MAX_RETRIES} retries`);
return 1;
}
}
await new Promise(resolve => setTimeout(resolve, RETRY_DELAY_MS)); // Delay before retrying
}
};
export const FetchServerSettings = async (nitrado_cred: any, client: any, fetcher: any) => {
for (let retries = 0; retries <= MAX_RETRIES; retries++) {
try {
// get current status
const res = await fetch(`https://api.nitrado.net/services/${nitrado_cred.ServerID}/gameservers`, {
headers: {
"Authorization": nitrado_cred.Auth
}
});
if (!res.ok) {
client.error(`Failed to get Nitrado server stats (${nitrado_cred.ServerID}): status: ${res.status}, message: ${res.statusText}: ${fetcher} via FetchServerSettings`);
if (res.status == 401) return 1; // return immediately if unauthorized
if (retries === 2) return 1; // Return error status on the second failed status code.
} else {
const data = await res.json();
return data;
}
} catch (error: any) {
client.error(`${fetcher} via FetchServerSettings: Error connecting to server (${nitrado_cred.ServerID}): ${error.message}`);
if (retries === MAX_RETRIES) {
client.error(`${fetcher} via FetchServerSettings: Error connecting to server (${nitrado_cred.ServerID}) after ${MAX_RETRIES} retries`);
return 1;
}
}
await new Promise(resolve => setTimeout(resolve, RETRY_DELAY_MS)); // Delay before retrying
}
};
export const PostServerSettings = async (nitrado_cred: any, client: any, category: any, key: any, value: any) => {
for (let retries = 0; retries <= MAX_RETRIES; retries++) {
try {
const formData = new FormData();
formData.append("category", category);
formData.append("key", key);
formData.append("value", value);
formData.pipe(concat((data: any) => {
async function postData() {
const res = await fetch(`https://api.nitrado.net/services/${nitrado_cred.ServerID}/gameservers/settings`, {
method: "POST",
credentials: "include",
headers: {
...formData.getHeaders(),
"Authorization": nitrado_cred.Auth
},
body: data,
});
if (!res.ok) {
client.error(`Failed to get post Nitrado server settings (${nitrado_cred.ServerID}): status: ${res.status}, message: ${res.statusText}: PostServerSettings`);
if (retries === 2) return 1; // Return error status on the second failed status code.
} else {
const data = await res.json();
return data;
}
}
postData();
}));
return 0;
} catch (error: any) {
client.error(`PostServerSettings: Error connecting to server (${nitrado_cred.ServerID}): ${error.message}`);
if (retries === MAX_RETRIES) {
client.error(`PostServerSettings: Error connecting to server (${nitrado_cred.ServerID}) after ${MAX_RETRIES} retries`);
return 1;
}
}
await new Promise(resolve => setTimeout(resolve, RETRY_DELAY_MS)); // Delay before retrying
}
};
export const CheckServerStatus = async (nitrado_cred: any, client: any) => {
const data = await module.exports.FetchServerSettings(nitrado_cred, client, "CheckServerStatus"); // Fetch server status
if (data && data != 1) {
if (data && data.data.gameserver.status === "stopped") {
client.log(`Restart of Nitrado server ${nitrado_cred.ServerID} has been invoked by the bot, the periodic check showed status of "${data.data.gameserver.status}".`);
// Write optional "restart_message" to set in the Nitrado server logs and send a notice "message" to your server community.
let restart_message = "Server being restarted by periodic bot check.";
let message = "The server was restarted by periodic bot check!";
module.exports.RestartServer(nitrado_cred, client, restart_message, message);
}
}
};
export const DisableBaseDamage = async (nitrado_cred: any, client: any, preference: any) => {
const pref = preference ? "1" : "0";
const posted = await module.exports.PostServerSettings(nitrado_cred, client, "config", "disableBaseDamage", pref);
if (posted == 1) return 1;
const remoteDirs = await GetRemoteDir(nitrado_cred, client);
if (remoteDirs == 1) return 1;
const basePath = remoteDirs.filter((dir: any) => dir.type == "dir")[0].path
const remoteDirsFromBase = await GetRemoteDir(nitrado_cred, client, basePath);
if (remoteDirsFromBase == 1) return 1;
const missionPath = remoteDirsFromBase[0].path;
const cfggameplayPath = `${missionPath}/cfggameplay.json`;
const jsonDir = `./logs/cfggameplay.json`;
await module.exports.DownloadNitradoFile(nitrado_cred, client, cfggameplayPath, jsonDir);
let gameplay = JSON.parse(fs.readFileSync(jsonDir, "utf-8"));
gameplay.GeneralData.disableBaseDamage = preference;
// write JSON to file
fs.writeFileSync(jsonDir, JSON.stringify(gameplay, null, 2));
const uploaded = await UploadNitradoFile(nitrado_cred, client, missionPath, "cfggameplay.json", jsonDir);
if (uploaded == 1) return 1;
return 0;
};
export const DisableContainerDamage = async (nitrado_cred: any, client: any, preference: any) => {
const pref = preference ? "1" : "0";
const posted = await module.exports.PostServerSettings(nitrado_cred, client, "config", "disableContainerDamage", pref);
if (posted == 1) return 1;
const remoteDirs = await GetRemoteDir(nitrado_cred, client);
if (remoteDirs == 1) return 1;
const basePath = remoteDirs.filter((dir: any) => dir.type == "dir")[0].path
const remoteDirsFromBase = await GetRemoteDir(nitrado_cred, client, basePath);
if (remoteDirsFromBase == 1) return 1;
const missionPath = remoteDirsFromBase[0].path;
const cfggameplayPath = `${missionPath}/cfggameplay.json`;
const jsonDir = `./logs/cfggameplay.json`;
await module.exports.DownloadNitradoFile(nitrado_cred, client, cfggameplayPath, jsonDir);
let gameplay = JSON.parse(fs.readFileSync(jsonDir, "utf-8"));
gameplay.GeneralData.disableContainerDamage = preference;
// write JSON to file
fs.writeFileSync(jsonDir, JSON.stringify(gameplay, null, 2));
const uploaded = await UploadNitradoFile(nitrado_cred, client, missionPath, "cfggameplay.json", jsonDir);
if (uploaded == 1) return 1;
return 0;
};
+6 -1
View File
@@ -9,7 +9,12 @@
"skipLibCheck": true,
"resolveJsonModule": true,
"forceConsistentCasingInFileNames": true,
"allowJs": true
"allowJs": true,
"baseUrl": "./src",
"paths": {
"@util/*": ["util/*"],
"@db/*": ["database/*"]
}
},
"include": ["src"],
"exclude": ["node_modules"]