├── .env-example
├── .github
└── workflows
│ ├── deploy-dev.yml
│ └── deploy-master.yml
├── .gitignore
├── Dockerfile
├── LICENSE
├── README.md
├── config.json
├── docker-entrypoint.sh
├── fMzdScKiYi.gif
├── index.js
├── package-lock.json
├── package.json
├── src
├── Commands
│ ├── BotInfoCommand.js
│ ├── GuidCommand.js
│ ├── HelpCommand.js
│ ├── SteamCommand.js
│ └── UidCommand.js
├── Configs
│ └── EnvironmentSelector.js
├── Constants
│ ├── EnvironmentConstants.js
│ ├── GameListConstants.js
│ ├── GeneralConstants.js
│ ├── HttpConstants.js
│ └── TextConstants.js
├── Controllers
│ ├── ApiController.js
│ ├── HealthCheckController.js
│ └── ServersController.js
├── Daos
│ ├── ArmaDao.js
│ ├── CommandsDao.js
│ ├── DayzDao.js
│ ├── GuidDao.js
│ └── UidDao.js
├── Database
│ ├── DbConnection.js
│ └── Models
│ │ ├── GeneralStore.js
│ │ ├── GuidStore.js
│ │ ├── UidStore.js
│ │ ├── discordinfo.js
│ │ ├── setArmaServer.js
│ │ └── setdayzserver.js
├── Helpers
│ └── GenericFunctions.js
├── Middlewares
│ └── LoggerMiddleware.js
├── Models
│ └── Response
│ │ ├── ErrorResponse.js
│ │ ├── FormaterResponse.js
│ │ ├── ObtainGuidResponse.js
│ │ └── ObtainUidResponse.js
├── Routes
│ └── ApiRouter.js
├── WebServer.js
└── services
│ ├── ApiService.js
│ ├── MessageEventService.js
│ └── ServersService.js
└── swagger.json
/.env-example:
--------------------------------------------------------------------------------
1 | TOKEN=YOUR-DISCORD-BOT-TOKEN-HERE
2 | STEAM_API=YOUR-STEAM-API-KEY-HERE
3 | DB_URI=YOUR-MONGO-DB-URI-HERE
4 | DBL_TOKEN=YOUR_DBL_TOKEN_HERE
5 | CLIENT_ID=YOUR_BOT_CLIENT_ID
6 | API_PORT=API_PORT_HERE
--------------------------------------------------------------------------------
/.github/workflows/deploy-dev.yml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | branches:
4 | - develop
5 |
6 | name: deploy bot to master infraestructure
7 |
8 | jobs:
9 | deploy:
10 | name: Build and push image to registry
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v2
14 |
15 | - name: Set up QEMU
16 | uses: docker/setup-qemu-action@v1
17 |
18 | - name: Set up Docker Buildx
19 | uses: docker/setup-buildx-action@v1
20 |
21 | - name: Login to Private Registry
22 | uses: docker/login-action@v1
23 | with:
24 | registry: ${{ secrets.REGISTRY_URL }}
25 | username: ${{ secrets.REGISTRY_USERNAME }}
26 | password: ${{ secrets.REGISTRY_TOKEN }}
27 |
28 | - name: build and push to registry
29 | uses: docker/build-push-action@v3
30 | with:
31 | push: true
32 | context: .
33 | file: ./Dockerfile
34 | build-args: APP=dev
35 | platforms: linux/arm/v7
36 | tags: ${{ secrets.REGISTRY_URL }}/steamid64toguid-bot-dev:v2.1.3
37 |
--------------------------------------------------------------------------------
/.github/workflows/deploy-master.yml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | branches:
4 | - master
5 |
6 | name: deploy bot to master infraestructure
7 |
8 | jobs:
9 | deploy:
10 | name: Build and push image to registry
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v2
14 |
15 | - name: Set up QEMU
16 | uses: docker/setup-qemu-action@v1
17 |
18 | - name: Set up Docker Buildx
19 | uses: docker/setup-buildx-action@v1
20 |
21 | - name: Login to Private Registry
22 | uses: docker/login-action@v1
23 | with:
24 | registry: ${{ secrets.REGISTRY_URL }}
25 | username: ${{ secrets.REGISTRY_USERNAME }}
26 | password: ${{ secrets.REGISTRY_TOKEN }}
27 |
28 | - name: build and push to registry
29 | uses: docker/build-push-action@v3
30 | with:
31 | push: true
32 | context: .
33 | file: ./Dockerfile
34 | build-args: APP=prod
35 | platforms: linux/arm/v7
36 | tags: ${{ secrets.REGISTRY_URL }}/steamid64toguid-bot-prod:v2.1.3
37 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | Commands-bk
3 | dev.json
4 | .env
5 | .env.dev
6 | .env.local
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:16-buster-slim
2 |
3 | ENV APP $APP
4 | ENV API_PORT $API_PORT
5 | ENV TOKEN $TOKEN
6 | ENV DBL_TOKEN $DBL_TOKEN
7 | ENV STEAM_API $STEAM_API
8 | ENV DB_URI $DB_URI
9 | ENV CLIENT_ID $CLIENT_ID
10 |
11 | WORKDIR /app
12 | COPY . /app/
13 | RUN chmod +x /app/docker-entrypoint.sh
14 | ENTRYPOINT ["/app/docker-entrypoint.sh"]
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 siegmund0
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DayZ - Arma 3 Discord Bot Calculator SteamID64 to Battleye GUID or UID
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | ## Readme
13 | [Support Discord](https://discord.gg/M3FvUq8)
14 |
15 | [Bot invitation link](https://discord.com/api/oauth2/authorize?client_id=706139732073250860&permissions=537394240&scope=bot)
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Features
24 | - ⚡ You can convert steamid64 to Guid or UID very easily and quickly (Battleye GUID or Bohemia Interactive UID).
25 | - 🌱 It has a command that displays a complete list of all bot commands 🤣
26 |
27 | - 🔭 Commands:
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | ## Prerequisites
38 | - Have Node.js installed
39 | - It is necessary to have a MongoDb database.
40 |
41 | > **Note:** If **You Want** can join the support discord.
42 |
43 | ---
44 |
45 | ### Satisfactory GUID Convertion
46 |
47 |
48 |
49 |
50 | ### Satisfactory UID Convertion
51 |
52 |
53 |
54 |
55 | #### Steam id Finder
56 |
57 |
58 |
59 |
60 | ---
61 |
62 | ### YOU NEED MONGODB AND NODE.JS
63 |
--------------------------------------------------------------------------------
/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "database": {
3 | "active": true
4 | },
5 | "api": {
6 | "active": true
7 | }
8 | }
--------------------------------------------------------------------------------
/docker-entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | cd /app
3 | npm install;
4 | npm run start:${APP};
--------------------------------------------------------------------------------
/fMzdScKiYi.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ignaciochemes/SteamID64ToGUID-Discord-Bot/82313e8ddfa48338db6dbdeb697c35634bc2d85a/fMzdScKiYi.gif
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const fs = require('node:fs');
2 | const path = require('node:path');
3 | const { Client, GatewayIntentBits, REST, Collection, Routes, ActivityType } = require("discord.js");
4 | const { getEnvironment } = require("./src/Configs/EnvironmentSelector");
5 | const { DatabaseConnection } = require("./src/Database/DbConnection");
6 | const { WebServer } = require('./src/WebServer');
7 | const { default: AutoPoster } = require('topgg-autoposter');
8 | const config = require('./config.json');
9 |
10 | getEnvironment();
11 | if (config.database.active === true) {
12 | DatabaseConnection.getInstance();
13 | }
14 | if (config.api.active === true) {
15 | new WebServer().listen();
16 | }
17 |
18 | const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages] });
19 | client.commands = new Collection();
20 | const commandsPath = path.join(__dirname, './src/Commands');
21 | const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
22 | const commands = [];
23 |
24 | for (const file of commandFiles) {
25 | const filePath = path.join(commandsPath, file);
26 | const command = require(filePath);
27 | client.commands.set(command.data.name, command);
28 | commands.push(command.data.toJSON());
29 | }
30 |
31 | const rest = new REST({ version: '10' }).setToken(process.env.TOKEN);
32 |
33 | setInterval(async () => {
34 | if (process.env.STEAMID_ENV === 'production') {
35 | const ap = AutoPoster(process.env.DBL_TOKEN, client);
36 | ap.on('posted', () => {
37 | console.log('Server count posted!');
38 | })
39 | }
40 | }, 3600000);
41 |
42 | (async () => {
43 | try {
44 | console.log('Started refreshing application (/) commands.');
45 | await rest.put(
46 | Routes.applicationCommands(process.env.CLIENT_ID),
47 | { body: commands },
48 | );
49 | console.log('Successfully reloaded application (/) commands.');
50 | } catch (error) {
51 | console.error(error);
52 | }
53 | })();
54 |
55 | client.on('ready', () => {
56 | console.log(`Logeado como ${client.user.tag}`);
57 | let actividades = ['Arma', 'Dayz'], i = 0;
58 | setInterval(() => { client.user.setActivity(`/help | ${actividades[i++ % actividades.length]}`, { type: ActivityType.Watching }) }, 30000);
59 | });
60 |
61 | client.on('interactionCreate', async interaction => {
62 | if (!interaction.isChatInputCommand()) return;
63 | const command = client.commands.get(interaction.commandName);
64 | if (!command) return;
65 |
66 | try {
67 | await command.execute(interaction);
68 | } catch (error) {
69 | console.error(error);
70 | await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
71 | }
72 | });
73 |
74 | client.login(process.env.TOKEN);
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "oaki",
3 | "version": "2.1.3",
4 | "description": "oakiBot",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "node index.js",
8 | "start:dev:win": "SET STEAMID_ENV=development&&node index.js",
9 | "start:local:win": "SET STEAMID_ENV=local&&nodemon index.js",
10 | "start:prod": "STEAMID_ENV=production node index.js",
11 | "start:dev": "STEAMID_ENV=development nodemon index.js",
12 | "start:local": "STEAMID_ENV=local nodemon index.js"
13 | },
14 | "keywords": [
15 | "-"
16 | ],
17 | "author": "oaki",
18 | "license": "ISC",
19 | "dependencies": {
20 | "@top-gg/sdk": "^3.1.6",
21 | "axios": "^1.6.5",
22 | "body-parser": "^1.20.2",
23 | "discord.js": "^14.14.1",
24 | "dotenv": "^16.3.1",
25 | "express": "^4.18.2",
26 | "express-winston": "^4.2.0",
27 | "gamedig": "^4.3.1",
28 | "mongoose": "^8.0.4",
29 | "morgan": "^1.10.0",
30 | "nodemon": "^3.0.2",
31 | "os": "^0.1.2",
32 | "os-utils": "0.0.14",
33 | "ping": "^0.4.4",
34 | "steamapi": "^2.5.0",
35 | "swagger-ui-express": "^5.0.0",
36 | "topgg-autoposter": "^2.0.1",
37 | "winston": "^3.11.0"
38 | }
39 | }
--------------------------------------------------------------------------------
/src/Commands/BotInfoCommand.js:
--------------------------------------------------------------------------------
1 | const OS = require('os');
2 | const os = require('os');
3 | const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
4 | const { GeneralConstants } = require("../Constants/GeneralConstants");
5 | const { GeneralDao } = require("../Daos/CommandsDao");
6 | const { formatUptime } = require('../Helpers/GenericFunctions');
7 |
8 | module.exports = {
9 | data: new SlashCommandBuilder()
10 | .setName("bot-info")
11 | .setDescription("Shows server info"),
12 | async execute(interaction) {
13 | let aggregate = await GeneralDao.generalStoreDao(interaction.commandName, interaction.user.id, GeneralConstants.COMANDOS);
14 | aggregate[0] ? aggregate = aggregate[0].Total : aggregate = 1;
15 | let embed = new EmbedBuilder();
16 | embed.setTitle(`Bot Information`);
17 | embed.setColor(GeneralConstants.DEFAULT_COLOR);
18 | embed.addFields(
19 | {
20 | name: "General:",
21 | value: `Name: \`${interaction.client.user.username}\` \nID: \`${interaction.client.user.id}\` \nGuilds: \`${interaction.client.guilds.cache.size}\` \nUsers: \`${interaction.client.users.cache.size}\``,
22 | inline: true
23 | },
24 | {
25 | name: "Developer:",
26 | value: `Name: \`${interaction.client.users.cache.get(GeneralConstants.DEVELOPER_ID).username}\` \nID: \`${GeneralConstants.DEVELOPER_ID}\``,
27 | inline: true
28 | },
29 | {
30 | name: "System:",
31 | value: `Platform: \`${OS.platform()}\` \nCPU: \`${OS.cpus()[0].model}\` \nRAM: \`${Math.round(OS.totalmem() / 1024 / 1024)} MB\``
32 | },
33 | {
34 | name: "Process Usage:",
35 | value: `CPU: \`${Math.round(process.cpuUsage().system / 1024 / 1024)} %\` \nRAM: \`${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)} MB\``,
36 | inline: true
37 | },
38 | {
39 | name: "System Free Resources:",
40 | value: `CPU: \`${Math.round(os.loadavg()[0] * 100)} %\` \nRAM: \`${Math.round(os.freemem() / 1024 / 1024)} MB\``,
41 | inline: true
42 | },
43 | {
44 | name: "Node.js:",
45 | value: `Version: \`${process.version}\` \nArchitecture: \`${process.arch}\``,
46 | },
47 | {
48 | name: "Statistics:",
49 | value: `Commands used: \`${aggregate}\``,
50 | inline: true
51 | },
52 | {
53 | name: "Uptime:",
54 | value: `\`${formatUptime(os.uptime())}\``,
55 | inline: true
56 | }
57 | );
58 | embed.setThumbnail(`${interaction.client.user.displayAvatarURL()}`);
59 | embed.setFooter({ text: GeneralConstants.DEFAULT_FOOTER });
60 | await interaction.reply({ embeds: [embed] });
61 | }
62 | }
--------------------------------------------------------------------------------
/src/Commands/GuidCommand.js:
--------------------------------------------------------------------------------
1 | const { createHash } = require("crypto");
2 | const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
3 | const { GeneralConstants } = require("../Constants/GeneralConstants");
4 | const { TextConstants } = require("../Constants/TextConstants");
5 | const { GeneralDao } = require("../Daos/CommandsDao");
6 | const { GuidDao } = require("../Daos/GuidDao");
7 |
8 | module.exports = {
9 | data: new SlashCommandBuilder()
10 | .setName('guid')
11 | .setDescription('Convert SteamId64 to GUID')
12 | .addStringOption(option =>
13 | option.setName('steamid64')
14 | .setDescription('Enter your SteamId64')
15 | .setRequired(true)
16 | ),
17 | async execute(interaction) {
18 | let aggregate = await GuidDao.agregate();
19 | aggregate[0] ? aggregate = aggregate[0].Total : aggregate = 1;
20 | await GeneralDao.generalStoreDao(interaction.commandName, interaction.user.id, GeneralConstants.COMANDOS);
21 | const steamId64 = interaction.options.getString('steamid64');
22 | if (!/^\d{17}$/.test(steamId64)) {
23 | return interaction.reply({ content: TextConstants.GUID_MENOR_ARGS, ephemeral: true });
24 | };
25 | let embed = new EmbedBuilder();
26 | let guid;
27 | try {
28 | const buffer = Buffer.alloc(10);
29 | buffer.writeBigUInt64LE(BigInt(steamId64));
30 | guid = createHash('md5').update(Buffer.concat([Buffer.from([0x42, 0x45]), buffer.subarray(0, 8)])).digest('hex');
31 | await GeneralDao.guidStoreDao(guid, interaction.user.id, aggregate)
32 | embed.setDescription("<@" + interaction.user.id + ">" + " " + `Global GUID converted: \`${aggregate}\``);
33 | embed.addFields(
34 | { name: 'SteamId64', value: `\`${steamId64}\``, inline: true },
35 | { name: 'GUID', value: `\`${guid}\``, inline: true }
36 | );
37 | embed.setColor(GeneralConstants.DEFAULT_COLOR);
38 | embed.setFooter({ text: GeneralConstants.DEFAULT_FOOTER });
39 | } catch (error) {
40 | embed.setTitle('Error converting');
41 | embed.setDescription(`Are you sure you entered a correct number? \nExecute /steam and enter your Steam Link. Like this: \`/steam 765611....\` \nYou have to find your SteamId64 765611 .... and then, use it with the command \`/guid 765611.....\` to return the hash.`)
42 | embed.setColor("#A62019");
43 | } finally {
44 | return interaction.reply({ embeds: [embed] });
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/src/Commands/HelpCommand.js:
--------------------------------------------------------------------------------
1 | const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
2 | const { GeneralConstants } = require("../Constants/GeneralConstants");
3 | const { GeneralDao } = require("../Daos/CommandsDao");
4 |
5 | module.exports = {
6 | data: new SlashCommandBuilder()
7 | .setName("help")
8 | .setDescription("Shows all commands"),
9 | async execute(interaction) {
10 | let aggregate = await GeneralDao.generalStoreDao(interaction.commandName, interaction.user.id, GeneralConstants.COMANDOS);
11 | aggregate[0] ? aggregate = aggregate[0].Total : aggregate = 1;
12 | let embed = new EmbedBuilder();
13 | const allCommands = interaction.client.commands.map(command => command.data.toJSON());
14 | const commands = allCommands.map(command => {
15 | return {
16 | name: `\`/${command.name}\``,
17 | value: `Description: ${command.description} \nUsage: /${command.name}`,
18 | }
19 | });
20 | embed.setTitle(`Commands`);
21 | embed.setDescription('For use a command, type / before the command name');
22 | embed.setColor(GeneralConstants.DEFAULT_COLOR);
23 | embed.addFields(commands);
24 | embed.setFooter({ text: GeneralConstants.DEFAULT_FOOTER });
25 | await interaction.reply({ embeds: [embed] });
26 | }
27 | }
--------------------------------------------------------------------------------
/src/Commands/SteamCommand.js:
--------------------------------------------------------------------------------
1 | const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
2 | const SteamAPI = require("steamapi");
3 | const { GeneralConstants } = require("../Constants/GeneralConstants");
4 | const { GeneralDao } = require("../Daos/CommandsDao");
5 |
6 | const steam = new SteamAPI(process.env.STEAM_API);
7 | let id64Resolve = [];
8 |
9 | module.exports = {
10 | data: new SlashCommandBuilder()
11 | .setName("steam")
12 | .setDescription("Convert Steam profile url to SteamId64")
13 | .addStringOption(option =>
14 | option.setName("steamurl")
15 | .setDescription("Enter your Steam profile url")
16 | .setRequired(true)
17 | ),
18 | async execute(interaction) {
19 | await GeneralDao.generalStoreDao(interaction.commandName, interaction.user.id, GeneralConstants.COMANDOS);
20 | const pwd = interaction.options._hoistedOptions[0].value;
21 | let embed = new EmbedBuilder();
22 | try {
23 | let resolve = await steam.resolve(pwd).then(id => {
24 | id64Resolve = id;
25 | if (id64Resolve.toString().length != 17) return interaction.reply('Something is wrong. Please try again.');
26 | return id64Resolve;
27 | });
28 | steam.getUserSummary(resolve).then(summary => {
29 | const { nickName, realName, countryCode } = _steamInfoCorrector(summary.nickname, summary.realName, summary.countryCode);
30 | if (summary.gameServerIP, summary.gameServerSteamID, summary.gameExtraInfo, summary.gameID === undefined) {
31 | embed.setTitle(`Steam Information`);
32 | embed.setColor(GeneralConstants.DEFAULT_COLOR);
33 | embed.addFields(
34 | {
35 | name: "General:",
36 | value: `Nickname: \`${nickName}\` \nReal Name: \`${realName}\` \nCountry Code: \`${countryCode}\``,
37 | inline: true
38 | },
39 | {
40 | name: "Steam ID 64:",
41 | value: `Steam ID: \`${summary.steamID}\``,
42 | inline: true
43 | }
44 | );
45 | embed.setThumbnail(`${summary.avatar.large}`);
46 | embed.setFooter({ text: GeneralConstants.DEFAULT_FOOTER });
47 | return interaction.reply({ embeds: [embed] });
48 | } else {
49 | embed.setTitle(`Steam Information`);
50 | embed.setColor(GeneralConstants.DEFAULT_COLOR);
51 | embed.addFields(
52 | {
53 | name: "General:",
54 | value: `Nickname: \`${nickName}\` \nReal Name: \`${realName}\` \nCountry Code: \`${countryCode}\``,
55 | inline: true
56 | },
57 | {
58 | name: "Steam ID 64:",
59 | value: `Steam ID: \`${summary.steamID}\``,
60 | inline: true
61 | },
62 | {
63 | name: "Game:",
64 | value: `\nGame Server IP: \`${summary.gameServerIP}\` \nGame Server Steam ID: \`${summary.gameServerSteamID}\` \nGame Extra Info: \`${summary.gameExtraInfo}\` \nGame ID: \`${summary.gameID}\``,
65 | inline: true
66 | }
67 | );
68 | embed.setThumbnail(`${summary.avatar.large}`);
69 | embed.setFooter({ text: GeneralConstants.DEFAULT_FOOTER });
70 | return interaction.reply({ embeds: [embed] });
71 | }
72 | });
73 | } catch (error) {
74 | embed.setTitle(`Steam Information`);
75 | embed.setColor(GeneralConstants.DEFAULT_COLOR);
76 | embed.setDescription(`Something is wrong. Please try again.`);
77 | embed.setFooter({ text: GeneralConstants.DEFAULT_FOOTER });
78 | }
79 | }
80 | }
81 |
82 | const _steamInfoCorrector = (nickName, realName, countryCode) => {
83 | !nickName || nickName === null ? nickName = 'Not found' : nickName = nickName;
84 | !realName || realName === null ? realName = 'Not found' : realName = realName;
85 | !countryCode || countryCode === null ? countryCode = 'Not found' : countryCode = countryCode;
86 | return { nickName, realName, countryCode };
87 | }
--------------------------------------------------------------------------------
/src/Commands/UidCommand.js:
--------------------------------------------------------------------------------
1 | const { createHash } = require("crypto");
2 | const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
3 | const { GeneralConstants } = require("../Constants/GeneralConstants");
4 | const { TextConstants } = require("../Constants/TextConstants");
5 | const { GeneralDao } = require("../Daos/CommandsDao");
6 | const { UidDao } = require("../Daos/UidDao");
7 |
8 | module.exports = {
9 | data: new SlashCommandBuilder()
10 | .setName('uid')
11 | .setDescription('Convert SteamId64 to UID')
12 | .addStringOption(option =>
13 | option.setName('steamid64')
14 | .setDescription('Enter your SteamId64')
15 | .setRequired(true)
16 | ),
17 | async execute(interaction) {
18 | let aggregate = await UidDao.agregate();
19 | aggregate[0] ? aggregate = aggregate[0].Total : aggregate = 1;
20 | await GeneralDao.generalStoreDao(interaction.commandName, interaction.user.id, GeneralConstants.COMANDOS);
21 | const steamId64 = interaction.options.getString('steamid64');
22 | if (!/^\d{17}$/.test(steamId64)) {
23 | return interaction.reply({ content: TextConstants.UID_MENOR_ARGS, ephemeral: true });
24 | };
25 | let embed = new EmbedBuilder();
26 | try {
27 | let pwdToBase64 = createHash('sha256').update(steamId64).digest('base64');
28 | let pwdReplace = pwdToBase64.replace(GeneralConstants.MAS_REGEX, GeneralConstants.GUION);
29 | let pwdFinally = pwdReplace.replace(GeneralConstants.BARRA_REGEX, GeneralConstants.GUION_BAJO);
30 | await GeneralDao.uidStoreDao(pwdFinally, interaction.user.id, aggregate);
31 | embed.setDescription("<@" + interaction.user.id + ">" + " " + `Global UIDS converted: \`${aggregate}\``);
32 | embed.addFields(
33 | { name: 'SteamId64', value: `\`${steamId64}\``, inline: true },
34 | { name: '✅ Works UID', value: `\`${pwdFinally}\`` },
35 | { name: '❌ Test UID', value: `\`${pwdToBase64}\`` }
36 | );
37 | embed.setColor(GeneralConstants.DEFAULT_COLOR);
38 | embed.setFooter({ text: GeneralConstants.DEFAULT_FOOTER });
39 | } catch (error) {
40 | console.log(error);
41 | embed.setTitle('Error converting');
42 | embed.setDescription(`Are you sure you entered a correct number? \nExecute /steam and enter your Steam Link. Like this: \`/steam 765611....\` \nYou have to find your SteamId64 765611 .... and then, use it with the command \`/uid 765611.....\` to return the hash.`)
43 | embed.setColor("#A62019");
44 | } finally {
45 | return interaction.reply({ embeds: [embed] });
46 | }
47 | }
48 |
49 | }
--------------------------------------------------------------------------------
/src/Configs/EnvironmentSelector.js:
--------------------------------------------------------------------------------
1 | const dotenv = require('dotenv');
2 | const path = require('path');
3 | const { EnvironmentConstants } = require('../Constants/EnvironmentConstants');
4 |
5 | const PROD = EnvironmentConstants.PROD;
6 | const DEV = EnvironmentConstants.DEV;
7 | const LOCAL = EnvironmentConstants.LOCAL;
8 |
9 | let envData = {};
10 |
11 | const getEnvironment = () => {
12 | switch (process.env.STEAMID_ENV) {
13 | case PROD:
14 | envData = dotenv.config({ path: path.resolve(__dirname, '../../.env') }).parsed;
15 | console.log('Environment: Production');
16 | break;
17 | case DEV:
18 | envData = dotenv.config({ path: path.resolve(__dirname, '../../.env.dev') }).parsed;
19 | console.log('Environment: Development');
20 | break
21 | case LOCAL:
22 | envData = dotenv.config({ path: path.resolve(__dirname, '../../.env.local') }).parsed;
23 | console.log('Environment: Local');
24 | break
25 | default:
26 | envData = dotenv.config({ path: path.resolve(__dirname, '../../.env') }).parsed;
27 | }
28 | }
29 |
30 | module.exports = { getEnvironment, envData }
--------------------------------------------------------------------------------
/src/Constants/EnvironmentConstants.js:
--------------------------------------------------------------------------------
1 | class EnvironmentConstants {
2 | static PROD = 'production';
3 | static LOCAL = 'local';
4 | static DEV = 'development'
5 | }
6 |
7 | module.exports = { EnvironmentConstants };
--------------------------------------------------------------------------------
/src/Constants/GameListConstants.js:
--------------------------------------------------------------------------------
1 | const GameList = {
2 | games: {
3 | 'arma3': 'Arma 3',
4 | 'arma2': 'Arma 2',
5 | 'dayz': 'Dayz Standalone',
6 | 'dayzmod': 'Dayz Mod 2013',
7 | 'csgo': 'Counter-Strike: Global Offensive',
8 | 'cs16': 'Counter-Strike 1.6',
9 | 'fivem': 'FiveM',
10 | 'samp': 'San Andreas Multiplayer',
11 | 'mtasa': 'MTA San Andreas',
12 | 'mtavc': 'MTA Vice City',
13 | 'minecraft': 'Minecraft',
14 | 'minecraftpe': 'Minecraft: Pocket Edition',
15 | 'ps': 'Post Scriptum',
16 | 'przomboid': 'Project Zomboid',
17 | 'rust': 'Rust',
18 | 'rfactor': 'rFactor',
19 | 'squad': 'Squad',
20 | 'valheim': 'Valheim',
21 | '7d2d': '7 Days to Die',
22 | 'aoe2': 'Age of Empires 2',
23 | 'arkse': 'Ark Survival Evolved',
24 | 'assettocorsa': 'Assetto Corsa',
25 | 'conanexiles': 'Conan Exiles',
26 | 'garrysmod': 'Garry\'s Mod',
27 | 'hll': 'Hell Let Loose',
28 | 'insurgency': 'Insurgency',
29 | 'insurgencysandstorm': 'Insurgency: Sandstorm',
30 | 'killingfloor': 'Killing Floor',
31 | 'killingfloor2': 'Killing Floor 2',
32 | 'left4dead': 'Left 4 Dead',
33 | 'left4dead2': 'Left 4 Dead 2',
34 | 'openttd': 'OpenTTD',
35 | },
36 | services: {
37 | 'teamspeak3': 'TeamSpeak 3',
38 | 'teamspeak2': 'TeamSpeak 2',
39 | 'ventrilo': 'Ventrilo',
40 | 'discord': 'Discord',
41 | }
42 | };
43 |
44 | module.exports = { GameList };
--------------------------------------------------------------------------------
/src/Constants/GeneralConstants.js:
--------------------------------------------------------------------------------
1 | class GeneralConstants {
2 | static COMANDOS = 'comandos';
3 | static MAS_REGEX = /\+/g;
4 | static GUION = '-';
5 | static GUION_BAJO = '_';
6 | static BARRA_REGEX = /\//g;
7 | static THUMBNAIL = 'https://i.imgur.com/mnSJzVk.jpg';
8 | static DISPLAY_COLOR_1 = '#000000';
9 | static DISPLAY_COLOR_2 = '#ffffff';
10 | static DEFAULT_COLOR = '#F8C300';
11 | static DEFAULT_FOOTER = '2024 © Id64ToGuid | Bohemia Interactive - Battleye | Develop by oaki';
12 | static GENERAL_TIMEOUT = 60000;
13 | static BOT_INVITE_LINK = '\n https://discordapp.com/api/oauth2/authorize?client_id=706139732073250860&permissions=523328&scope=bot';
14 | static GITHUB_LINK = '\n https://github.com/ignaciochemes/SteamID64ToGUID-Discord-Bot';
15 | static SUPORT_DISCORD = '\n https://discord.gg/6YtgFUg';
16 | static LOGS2_CHANNEL = '841775829066317844';
17 | static LOGS_CHANNEL = '792023635203457025';
18 | static DEVELOPER_ID = '257668549051547649';
19 | }
20 |
21 | module.exports = { GeneralConstants }
--------------------------------------------------------------------------------
/src/Constants/HttpConstants.js:
--------------------------------------------------------------------------------
1 | class HttpConstants {
2 | static OK = 200;
3 | static BAD_REQUEST = 400;
4 | static UNAUTHORIZED = 401;
5 | static NOT_FOUND = 404;
6 | static INTERNAL_SERVER_ERROR = 500;
7 | }
8 |
9 | module.exports = { HttpConstants };
--------------------------------------------------------------------------------
/src/Constants/TextConstants.js:
--------------------------------------------------------------------------------
1 | class TextConstants {
2 | static UID_NO_ARGS = `Insert account id64 | -uid | -uid 765611981... \nIf you dont have your steam id 64 number, please execute the following command\n\`-steam \`\nExample -steam https://steamcommunity.com/id/siegmundsensi/`;
3 | static UID_MENOR_ARGS = `The entered arguments are wrong or not complete. Please check the data. \nIf you have any questions, just enter the uid comman. | /uid | /uid 765611981... \nIf you dont have your steam id 64 number, please execute the following command\n\`/steam \`\nExample /steam https://steamcommunity.com/id/siegmundsensi/`;
4 | static GUID_NO_ARGS = 'Insert account id64 | /guid | /guid 765611981... \nIf you dont have your steam id 64 number, please execute the following command\n\`/steam \`\nExample /steam https://steamcommunity.com/id/siegmundsensi/';
5 | static GUID_MENOR_ARGS = 'The entered arguments are wrong or not complete. Please check the data. \nIf you have any questions, just enter the /guid comman. | /guid | /guid 765611981... \nIf you dont have your steam id 64 number, please execute the following command\n\`/steam \`\nExample /steam https://steamcommunity.com/id/siegmundsensi/';
6 | static SETPREFIX_NO_ARGS = 'You must provide a **new prefix**!';
7 | static SETPREFIX_MAYOR_ARGS = 'Your new prefix must be under \`5\` characters!';
8 | static SETDAYZ_NO_ARGS = 'You must provide your **Dayz Server IP**. Eg: \`-setdayzserver 0.0.0.0\` and press enter.';
9 | static SETDAYZ_MAYOR_ARGS = 'Your new ip must be under \`15\` characters!';
10 | static SETARMA_NO_ARGS = 'You must provide your **Arma 3 Server IP**. Eg: \`-setarma3server 0.0.0.0\` and press enter.';
11 | static SETARMA_MAYOR_ARGS = 'Your new ip must be under \`15\` characters!';
12 | static ID64_NO_ARGS = 'Insert account url | -steam ';
13 | static ARMA_NO_USER_IP = 'No ip related to your discord profile.id was found. Please enter the following command to configure one. \`-setarma3server\`.';
14 | static DAYZ_NO_USER_IP = 'No ip related to your discord profile.id was found. Please enter the following command to configure one. \`-setdayzserver\`.';
15 |
16 | static QUERY_PORT = 'Now I need you to put the QUERY port of the server to trace. Write the number and press ENTER \nThis message will be deleted in a minute.';
17 | static NO_QUERY_PORT = 'You didnt enter the QUERY port. You have to start the operation again!';
18 | static CANCEL = 'Operation canceled!';
19 | static DB_SORT_ERROR = 'No se pudo sortear la base';
20 | }
21 |
22 | module.exports = { TextConstants };
--------------------------------------------------------------------------------
/src/Controllers/ApiController.js:
--------------------------------------------------------------------------------
1 | const { FormaterResponse } = require("../Models/Response/FormaterResponse");
2 | const { ApiService } = require("../services/ApiService");
3 |
4 | class ApiController {
5 |
6 | static async guidController(req, res) {
7 | const response = await ApiService.obtainGuid(req);
8 | return res.json(new FormaterResponse(response));
9 | }
10 |
11 | static uidController(req, res) {
12 | const response = ApiService.uidService(req);
13 | return res.json(new FormaterResponse(response));
14 | }
15 |
16 | }
17 |
18 | module.exports = { ApiController };
--------------------------------------------------------------------------------
/src/Controllers/HealthCheckController.js:
--------------------------------------------------------------------------------
1 | const { FormaterResponse } = require("../Models/Response/FormaterResponse");
2 |
3 | class HealthCheckController {
4 |
5 | static async healthCheck(req, res) {
6 | const response = { status: "OK", message: "Server is running" };
7 | return res.json(new FormaterResponse(response));
8 | }
9 |
10 | }
11 |
12 | module.exports = { HealthCheckController };
--------------------------------------------------------------------------------
/src/Controllers/ServersController.js:
--------------------------------------------------------------------------------
1 | const { FormaterResponse } = require("../Models/Response/FormaterResponse");
2 | const { ServersService } = require("../services/ServersService");
3 |
4 | class ServersController {
5 |
6 | static async getServerInfo(req, res) {
7 | const response = await ServersService.getServerInfo(req);
8 | return res.json(new FormaterResponse(response));
9 | }
10 |
11 | static async getGamesList(req, res) {
12 | const response = await ServersService.getGamesList();
13 | return res.json(new FormaterResponse(response));
14 | }
15 | }
16 |
17 | module.exports = { ServersController };
--------------------------------------------------------------------------------
/src/Daos/ArmaDao.js:
--------------------------------------------------------------------------------
1 | const armaSchema = require('../database/models/setArmaServer');
2 |
3 | class ArmaDao {
4 |
5 | static async save(message, ip, puerto) {
6 | const newData = new armaSchema({
7 | Arma3Ip: ip,
8 | ArmaPort: puerto,
9 | GuildID: message.author.id,
10 | })
11 | await newData.save();
12 | };
13 |
14 | static async setServer(message) {
15 | return await armaSchema.findOneAndRemove({ GuildID: message.author.id });
16 | };
17 |
18 | static async getServer(message) {
19 | const query = await armaSchema.findOne({ GuildID: message.author.id });
20 | return query;
21 | };
22 | }
23 |
24 | module.exports = { ArmaDao };
--------------------------------------------------------------------------------
/src/Daos/CommandsDao.js:
--------------------------------------------------------------------------------
1 | const uidStoreSchema = require('../Database/Models/UidStore');
2 | const guidStoreSchema = require('../Database/Models/GuidStore');
3 | const generalStoreSchema = require('../Database/Models/GeneralStore');
4 |
5 | class GeneralDao {
6 |
7 | static async generalStoreDao(commandName, userId, commandType) {
8 | const newDataGeneral = new generalStoreSchema({
9 | comando: commandName,
10 | user: userId,
11 | name: commandType
12 | });
13 | await newDataGeneral.save();
14 | const count = await generalStoreSchema.aggregate([{ $group: { _id: "$name", Total: { $sum: 1 } } }]);
15 | return count;
16 | };
17 |
18 | static async uidStoreDao(uid, userId, aggregate) {
19 | const newData = new uidStoreSchema({
20 | uid: uid,
21 | user: userId,
22 | name: "uid",
23 | numero: aggregate,
24 | });
25 | await newData.save();
26 | }
27 |
28 | static async guidStoreDao(guid, userId, aggregate) {
29 | const newData = new guidStoreSchema({
30 | guid: guid,
31 | user: userId,
32 | name: "guid",
33 | numero: aggregate,
34 | });
35 | await newData.save();
36 | }
37 | }
38 |
39 | module.exports = { GeneralDao };
--------------------------------------------------------------------------------
/src/Daos/DayzDao.js:
--------------------------------------------------------------------------------
1 | const dayzSchema = require('../Database/Models/setDayzServer');
2 |
3 | class DayzDao {
4 |
5 | static async save(message, ip, puerto) {
6 | const newData = new dayzSchema({
7 | DayzIp: ip,
8 | DayzPort: puerto,
9 | GuildID: message.author.id,
10 | })
11 | await newData.save();
12 | };
13 |
14 | static async setServer(message) {
15 | await dayzSchema.findOneAndRemove({ GuildID: message.author.id });
16 | };
17 |
18 | static async getServer(message) {
19 | const query = await dayzSchema.findOne({ GuildID: message.author.id });
20 | return query;
21 | }
22 | }
23 |
24 | module.exports = { DayzDao };
--------------------------------------------------------------------------------
/src/Daos/GuidDao.js:
--------------------------------------------------------------------------------
1 | const guidStoreSchema = require("../Database/Models/GuidStore");
2 |
3 | class GuidDao {
4 | static async agregate() {
5 | return await guidStoreSchema.aggregate([
6 | {
7 | $group: {
8 | _id: "$name",
9 | Total: { $sum: 1 }
10 | }
11 | }
12 | ])
13 | }
14 | }
15 |
16 | module.exports = { GuidDao };
--------------------------------------------------------------------------------
/src/Daos/UidDao.js:
--------------------------------------------------------------------------------
1 | const uidStoreSchema = require("../Database/Models/UidStore");
2 |
3 | class UidDao {
4 |
5 | static async agregate() {
6 | return await uidStoreSchema.aggregate([
7 | {
8 | $group: {
9 | _id: "$name",
10 | Total: { $sum: 1 }
11 | }
12 | }
13 | ])
14 | }
15 | }
16 |
17 | module.exports = { UidDao };
--------------------------------------------------------------------------------
/src/Database/DbConnection.js:
--------------------------------------------------------------------------------
1 | const { connect } = require('mongoose');
2 |
3 | class DatabaseConnection {
4 | static _instancia;
5 | constructor() {
6 | this.dbConnection();
7 | }
8 |
9 | static getInstance() {
10 | if (DatabaseConnection._instancia) throw new Error('Ya existe una instancia de DatabaseConnection');
11 | DatabaseConnection._instancia = new DatabaseConnection();
12 | return DatabaseConnection._instancia;
13 | }
14 |
15 | async dbConnection() {
16 | await connect(`${process.env.DB_URI}`)
17 | .then(() => { console.log('Base de datos conectada!') })
18 | .catch((e) => { console.log('Error al conectar con la base de datos!', e) })
19 | };
20 | }
21 |
22 | module.exports = { DatabaseConnection };
--------------------------------------------------------------------------------
/src/Database/Models/GeneralStore.js:
--------------------------------------------------------------------------------
1 | const { model, Schema } = require('mongoose');
2 |
3 | const generalStoreSchema = new Schema({
4 | comando: { type: String },
5 | user: { type: String },
6 | name: { type: String },
7 | });
8 |
9 | module.exports = model('generalAlmacenamiento', generalStoreSchema);
--------------------------------------------------------------------------------
/src/Database/Models/GuidStore.js:
--------------------------------------------------------------------------------
1 | const { model, Schema } = require('mongoose');
2 |
3 | const guidStoreSchema = new Schema({
4 | guid: { type: String },
5 | user: { type: String },
6 | name: { type: String },
7 | numero: { type: Number }
8 | });
9 |
10 | module.exports = model('guidAlmacenamiento', guidStoreSchema);
--------------------------------------------------------------------------------
/src/Database/Models/UidStore.js:
--------------------------------------------------------------------------------
1 | const { model, Schema } = require('mongoose');
2 |
3 | const uidStoreSchema = new Schema({
4 | uid: { type: String },
5 | user: { type: String },
6 | name: { type: String },
7 | numero: { type: Number },
8 | });
9 |
10 | module.exports = model('uidAlmacenamiento', uidStoreSchema);
--------------------------------------------------------------------------------
/src/Database/Models/discordinfo.js:
--------------------------------------------------------------------------------
1 | const { model, Schema } = require('mongoose');
2 |
3 | const discordInfoSchema = new Schema({
4 | Servers: { type: String },
5 | Users: { type: String },
6 | Channels: { type: String }
7 | });
8 |
9 | module.exports = model('discordinfo', discordInfoSchema);
--------------------------------------------------------------------------------
/src/Database/Models/setArmaServer.js:
--------------------------------------------------------------------------------
1 | const { model, Schema } = require('mongoose');
2 |
3 | const armaSchema = new Schema({
4 | Arma3Ip: { type: String },
5 | ArmaPort: { type: String },
6 | GuildID: { type: String }
7 | });
8 |
9 | module.exports = model('arma3ip', armaSchema);
--------------------------------------------------------------------------------
/src/Database/Models/setdayzserver.js:
--------------------------------------------------------------------------------
1 | const { model, Schema } = require('mongoose');
2 |
3 | const dayzSchema = new Schema({
4 | DayzIp: { type: String },
5 | DayzPort: { type: String },
6 | GuildID: {type: String}
7 | });
8 |
9 | module.exports = model('dayzip', dayzSchema);
--------------------------------------------------------------------------------
/src/Helpers/GenericFunctions.js:
--------------------------------------------------------------------------------
1 | const formatUptime = (uptimeInSeconds) => {
2 | const days = Math.floor(uptimeInSeconds / 86400);
3 | const hours = Math.floor((uptimeInSeconds % 86400) / 3600);
4 | const minutes = Math.floor((uptimeInSeconds % 3600) / 60);
5 | const seconds = Math.floor(uptimeInSeconds % 60);
6 |
7 | return `${days}d ${hours}h ${minutes}m ${seconds}s`;
8 | };
9 |
10 | module.exports = {
11 | formatUptime,
12 | };
--------------------------------------------------------------------------------
/src/Middlewares/LoggerMiddleware.js:
--------------------------------------------------------------------------------
1 | const winston = require('winston');
2 | const expressWinston = require('express-winston');
3 |
4 | const logger = expressWinston.logger({
5 | transports: [
6 | new winston.transports.Console()
7 | ],
8 | format: winston.format.combine(
9 | winston.format.colorize(),
10 | winston.format.json()
11 | ),
12 | meta: true,
13 | msg: "HTTP {{req.method}} {{req.url}}",
14 | expressFormat: true,
15 | colorize: false,
16 | ignoreRoute: function (req, res) { return false; }
17 | });
18 |
19 | module.exports = logger;
--------------------------------------------------------------------------------
/src/Models/Response/ErrorResponse.js:
--------------------------------------------------------------------------------
1 | class ErrorResponse {
2 | statusCode = null;
3 | error = null;
4 | message = null;
5 |
6 | constructor(statusCode, error, message) {
7 | this.statusCode = statusCode;
8 | this.error = error ? error : 'Error';
9 | this.message = message ? message : 'Internal Server Error';
10 | }
11 | }
12 |
13 | module.exports = { ErrorResponse };
--------------------------------------------------------------------------------
/src/Models/Response/FormaterResponse.js:
--------------------------------------------------------------------------------
1 | class FormaterResponse {
2 | result = null;
3 |
4 | constructor(result) {
5 | this.result = result;
6 | }
7 | }
8 |
9 | module.exports = { FormaterResponse };
--------------------------------------------------------------------------------
/src/Models/Response/ObtainGuidResponse.js:
--------------------------------------------------------------------------------
1 | class ObtainGuidResponse {
2 | guid = null;
3 | steamId = null;
4 |
5 | constructor(guid, steamId) {
6 | this.guid = guid ? guid : null;
7 | this.steamId = steamId ? steamId : null;
8 | }
9 | }
10 |
11 | module.exports = { ObtainGuidResponse };
--------------------------------------------------------------------------------
/src/Models/Response/ObtainUidResponse.js:
--------------------------------------------------------------------------------
1 | class ObtainUidResponse {
2 | cfToolsUid = null;
3 | bohemiaUid = null;
4 | steamId = null;
5 |
6 | constructor(cfToolsUid, bohemiaUid, steamId) {
7 | this.cfToolsUid = cfToolsUid ? cfToolsUid : null;
8 | this.bohemiaUid = bohemiaUid ? bohemiaUid : null;
9 | this.steamId = steamId ? steamId : null;
10 | }
11 | }
12 |
13 | module.exports = { ObtainUidResponse };
--------------------------------------------------------------------------------
/src/Routes/ApiRouter.js:
--------------------------------------------------------------------------------
1 | const { Router } = require('express');
2 | const { ApiController } = require('../Controllers/ApiController');
3 | const { HealthCheckController } = require('../Controllers/HealthCheckController');
4 | const { ServersController } = require('../Controllers/ServersController');
5 | const router = Router();
6 |
7 | router.get('/guid', ApiController.guidController);
8 | router.get('/uid', ApiController.uidController);
9 | router.get('/health-check', HealthCheckController.healthCheck);
10 |
11 | router.get('/servers', ServersController.getServerInfo);
12 | router.get('/servers/games/list', ServersController.getGamesList);
13 |
14 | module.exports = router;
--------------------------------------------------------------------------------
/src/WebServer.js:
--------------------------------------------------------------------------------
1 | const bodyParser = require('body-parser');
2 | const express = require('express');
3 | const logger = require('./Middlewares/LoggerMiddleware');
4 | const swaggerUi = require('swagger-ui-express');
5 | const swaggerDocument = require('../swagger.json');
6 |
7 | class WebServer {
8 | constructor() {
9 | this.app = express();
10 | this.port = process.env.API_PORT || 3000;
11 | this.prefix = '/api/v1';
12 | this.middlewares();
13 | this.routes();
14 | }
15 |
16 | middlewares() {
17 | this.app.use(bodyParser.json());
18 | this.app.use(bodyParser.urlencoded({ extended: true }));
19 | this.app.use(logger);
20 | }
21 |
22 | routes() {
23 | this.app.use(this.prefix, require('./Routes/ApiRouter'));
24 | this.app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
25 | }
26 |
27 | listen() {
28 | this.app.listen(this.port, () => {
29 | console.log(`API Server on port: ${parseInt(this.port)}`);
30 | })
31 | }
32 | }
33 |
34 | module.exports = { WebServer };
--------------------------------------------------------------------------------
/src/services/ApiService.js:
--------------------------------------------------------------------------------
1 | const { createHash } = require('crypto');
2 | const { HttpConstants } = require('../Constants/HttpConstants');
3 | const { GeneralConstants } = require('../Constants/GeneralConstants');
4 | const { ErrorResponse } = require('../Models/Response/ErrorResponse');
5 | const { ObtainGuidResponse } = require('../Models/Response/ObtainGuidResponse');
6 | const { ObtainUidResponse } = require('../Models/Response/ObtainUidResponse');
7 |
8 | class ApiService {
9 |
10 | static async obtainGuid(req) {
11 | if (!req.query.steam) return new ErrorResponse(HttpConstants.BAD_REQUEST, "Enter the query parameters", "/api/guid?steam=your-steam-id-64-here");
12 | if (req.query.steam.length != 17) return new ErrorResponse(HttpConstants.BAD_REQUEST, "Argument must be 17 characters");
13 | let bytes = [];
14 | try {
15 | for (let i = 0; i < 8; i++) {
16 | bytes.push(Number((BigInt(req.query.steam) >> (8n * BigInt(i))) & 0xFFn))
17 | }
18 | let guid = createHash('md5').update(Buffer.from([0x42, 0x45, ...bytes])).digest('hex');
19 | bytes = [];
20 | const response = new ObtainGuidResponse(guid, req.query.steam);
21 | return response;
22 | } catch (e) {
23 | return new ErrorResponse(HttpConstants.INTERNAL_SERVER_ERROR, "Fatal Error");
24 | }
25 | }
26 |
27 | static uidService(req) {
28 | if (!req.query.steam) return new ErrorResponse(HttpConstants.BAD_REQUEST, "Enter the query parameters", "/api/uid?steam=your-steam-id-64-here");
29 | if (req.query.steam.length != 17) return new ErrorResponse(HttpConstants.BAD_REQUEST, "Argument must be 17 characters");
30 | try {
31 | let pwdToBase64 = createHash('sha256').update(req.query.steam).digest('base64');
32 | let pwdReplace = pwdToBase64.replace(GeneralConstants.MAS_REGEX, GeneralConstants.GUION);
33 | let pwdFinally = pwdReplace.replace(GeneralConstants.BARRA_REGEX, GeneralConstants.GUION_BAJO);
34 | const response = new ObtainUidResponse(pwdFinally, pwdToBase64, req.query.steam);
35 | return response;
36 | } catch (e) {
37 | return new ErrorResponse(HttpConstants.INTERNAL_SERVER_ERROR, "Fatal Error");
38 | }
39 | }
40 | }
41 |
42 | module.exports = { ApiService }
--------------------------------------------------------------------------------
/src/services/MessageEventService.js:
--------------------------------------------------------------------------------
1 | class MessageEventService {
2 |
3 | static async sendLogsToChannel() {
4 | //TODO
5 | }
6 | }
7 |
8 | module.exports = { MessageEventService };
--------------------------------------------------------------------------------
/src/services/ServersService.js:
--------------------------------------------------------------------------------
1 | const GD = require('gamedig');
2 | const { GameList } = require('../Constants/GameListConstants');
3 | const { HttpConstants } = require('../Constants/HttpConstants');
4 | const { ErrorResponse } = require('../Models/Response/ErrorResponse');
5 |
6 | class ServersService {
7 |
8 | static async getServerInfo(req) {
9 | const query = req.query;
10 | if (!query?.game) return new ErrorResponse(HttpConstants.BAD_REQUEST, "Enter game query parameter", "/api/servers?game=arma3");
11 | if (!query?.host) return new ErrorResponse(HttpConstants.BAD_REQUEST, "Enter host query parameter", "/api/servers/game=arma3?host=your-ip-here");
12 | let game = Object.values(GameList);
13 | let findGame;
14 | for (const g of game) {
15 | const find = Object.keys(g).find(key => key === query.game);
16 | if (find !== undefined) {
17 | findGame = g[find];
18 | break;
19 | }
20 | }
21 | if (!game || !findGame) return new ErrorResponse(HttpConstants.BAD_REQUEST, "Game or Service not found", "/api/servers?game=dayz");
22 | try {
23 | const ping = await GD.query({
24 | type: query.game.toLowerCase(),
25 | host: query.host,
26 | port: query?.port ? query.port : 2302
27 | });
28 | return ping;
29 | } catch (e) {
30 | return new ErrorResponse(HttpConstants.BAD_REQUEST, "Error to fetch the server");
31 | }
32 | }
33 |
34 | static async getGamesList() {
35 | const games = GameList;
36 | return games;
37 | }
38 | }
39 |
40 | module.exports = { ServersService };
--------------------------------------------------------------------------------
/swagger.json:
--------------------------------------------------------------------------------
1 | {
2 | "openapi": "3.0.3",
3 | "info": {
4 | "title": "SteamId64ToGuid - Public API",
5 | "version": "20220928"
6 | },
7 | "servers": [
8 | {
9 | "url": "https://apidev.steamid64toguid.cf/api/v1"
10 | }
11 | ],
12 | "tags": [
13 | {
14 | "name": "Convert"
15 | },
16 | {
17 | "name": "Servers"
18 | }
19 | ],
20 | "paths": {
21 | "/guid": {
22 | "get": {
23 | "tags": [
24 | "Convert"
25 | ],
26 | "summary": "Convert Steam ID 64 to GUID",
27 | "parameters": [
28 | {
29 | "name": "steam",
30 | "in": "query",
31 | "description": "User Steam ID",
32 | "required": true,
33 | "schema": {
34 | "type": "string",
35 | "default": 76561199088563020
36 | }
37 | }
38 | ],
39 | "responses": {
40 | "200": {
41 | "description": "Successful response -",
42 | "content": {
43 | "application/json": {
44 | "schema": {
45 | "type": "object",
46 | "properties": {
47 | "result": {
48 | "$ref": "#/components/schemas/GuidSchemaResponse"
49 | }
50 | }
51 | }
52 | }
53 | }
54 | },
55 | "400": {
56 | "description": "Bad Request -",
57 | "content": {
58 | "application/json": {
59 | "schema": {
60 | "type": "object",
61 | "properties": {
62 | "statusCode": {
63 | "type": "number",
64 | "format": "number",
65 | "example": 400
66 | },
67 | "error": {
68 | "type": "string",
69 | "format": "string",
70 | "example": "Enter the query parameters"
71 | },
72 | "message": {
73 | "type": "string",
74 | "format": "string",
75 | "example": "/api/guid?steam=your-steam-id-64-here"
76 | }
77 | }
78 | }
79 | }
80 | }
81 | }
82 | }
83 | }
84 | },
85 | "/uid": {
86 | "get": {
87 | "tags": [
88 | "Convert"
89 | ],
90 | "summary": "Convert Steam ID 64 to GUID",
91 | "parameters": [
92 | {
93 | "name": "steam",
94 | "in": "query",
95 | "description": "User Steam ID",
96 | "required": true,
97 | "schema": {
98 | "type": "string",
99 | "default": 76561199088563020
100 | }
101 | }
102 | ],
103 | "responses": {
104 | "200": {
105 | "description": "Successful response -",
106 | "content": {
107 | "application/json": {
108 | "schema": {
109 | "type": "object",
110 | "properties": {
111 | "result": {
112 | "$ref": "#/components/schemas/UidSchemaResponse"
113 | }
114 | }
115 | }
116 | }
117 | }
118 | },
119 | "400": {
120 | "description": "Bad Request -",
121 | "content": {
122 | "application/json": {
123 | "schema": {
124 | "type": "object",
125 | "properties": {
126 | "statusCode": {
127 | "type": "number",
128 | "format": "number",
129 | "example": 400
130 | },
131 | "error": {
132 | "type": "string",
133 | "format": "string",
134 | "example": "Enter the query parameters"
135 | },
136 | "message": {
137 | "type": "string",
138 | "format": "string",
139 | "example": "/api/uid?steam=your-steam-id-64-here"
140 | }
141 | }
142 | }
143 | }
144 | }
145 | }
146 | }
147 | }
148 | },
149 | "/servers": {
150 | "get": {
151 | "tags": [
152 | "Servers"
153 | ],
154 | "summary": "Get remote game server information",
155 | "parameters": [
156 | {
157 | "name": "game",
158 | "in": "query",
159 | "description": "Game name",
160 | "required": true,
161 | "schema": {
162 | "type": "string",
163 | "example": "arma3"
164 | }
165 | },
166 | {
167 | "name": "host",
168 | "in": "query",
169 | "description": "Game server host (ip)",
170 | "required": true,
171 | "schema": {
172 | "type": "string",
173 | "example": "127.0.0.1"
174 | }
175 | },
176 | {
177 | "name": "port",
178 | "in": "query",
179 | "description": "Game port",
180 | "required": false,
181 | "schema": {
182 | "type": "string",
183 | "default": 2302
184 | }
185 | }
186 | ],
187 | "responses": {
188 | "200": {
189 | "description": "Successful response -",
190 | "content": {
191 | "application/json": {
192 | "schema": {
193 | "type": "object",
194 | "properties": {
195 | "result": {
196 | "$ref": "#/components/schemas/GameServerResponse"
197 | }
198 | }
199 | }
200 | }
201 | }
202 | },
203 | "400": {
204 | "description": "Bad Request -",
205 | "content": {
206 | "application/json": {
207 | "schema": {
208 | "type": "object",
209 | "properties": {
210 | "statusCode": {
211 | "type": "number",
212 | "format": "number",
213 | "example": 400
214 | },
215 | "error": {
216 | "type": "string",
217 | "format": "string",
218 | "example": "Enter game query parameter"
219 | },
220 | "message": {
221 | "type": "string",
222 | "format": "string",
223 | "example": "/api/servers?game=arma3"
224 | }
225 | }
226 | }
227 | }
228 | }
229 | }
230 | }
231 | }
232 | },
233 | "/servers/games/list": {
234 | "get": {
235 | "tags": [
236 | "Servers"
237 | ],
238 | "summary": "Get game list",
239 | "responses": {
240 | "200": {
241 | "description": "Successful response -",
242 | "content": {
243 | "application/json": {
244 | "schema": {
245 | "type": "object",
246 | "properties": {
247 | "result": {
248 | "$ref": "#/components/schemas/GameListResponse"
249 | }
250 | }
251 | }
252 | }
253 | }
254 | }
255 | }
256 | }
257 | }
258 | },
259 | "components": {
260 | "schemas": {
261 | "GuidSchemaResponse": {
262 | "type": "object",
263 | "properties": {
264 | "guid": {
265 | "type": "string",
266 | "format": "string",
267 | "example": "bcf8c798fe19eb44a9dbbcd8b831fd85"
268 | },
269 | "steamId": {
270 | "type": "string",
271 | "format": "string",
272 | "example": "76561199088563030"
273 | }
274 | }
275 | },
276 | "UidSchemaResponse": {
277 | "type": "object",
278 | "properties": {
279 | "cfToolsUid": {
280 | "type": "string",
281 | "format": "string",
282 | "example": "8r8LJKISEFtFODaYtkrBupF6kf_ebhPnI2U6R0IeftQ="
283 | },
284 | "bohemiaUid": {
285 | "type": "string",
286 | "format": "string",
287 | "example": "8r8LJKISEFtFODaYtkrBupF6kf/ebhPnI2U6R0IeftQ="
288 | },
289 | "steamId": {
290 | "type": "string",
291 | "format": "string",
292 | "example": "76561199088563030"
293 | }
294 | }
295 | },
296 | "GameServerResponse": {
297 | "type": "object",
298 | "properties": {
299 | "hugeGameServerInformation": {
300 | "type": "object",
301 | "format": "object"
302 | }
303 | }
304 | },
305 | "GameListResponse": {
306 | "type": "object",
307 | "properties": {
308 | "games": {
309 | "type": "object",
310 | "format": "object",
311 | "example": {
312 | "arma3": "Arma 3",
313 | "arma2": "Arma 2",
314 | "dayz": "Dayz Standalone",
315 | "dayzmod": "Dayz Mod 2013",
316 | "csgo": "Counter-Strike: Global Offensive",
317 | "cs16": "Counter-Strike 1.6",
318 | "fivem": "FiveM",
319 | "samp": "San Andreas Multiplayer",
320 | "mtasa": "MTA San Andreas",
321 | "mtavc": "MTA Vice City",
322 | "minecraft": "Minecraft",
323 | "minecraftpe": "Minecraft: Pocket Edition",
324 | "ps": "Post Scriptum",
325 | "przomboid": "Project Zomboid",
326 | "rust": "Rust",
327 | "rfactor": "rFactor",
328 | "squad": "Squad",
329 | "valheim": "Valheim",
330 | "7d2d": "7 Days to Die",
331 | "aoe2": "Age of Empires 2",
332 | "arkse": "Ark Survival Evolved",
333 | "assettocorsa": "Assetto Corsa",
334 | "conanexiles": "Conan Exiles",
335 | "garrysmod": "Garrys Mod",
336 | "hll": "Hell Let Loose",
337 | "insurgency": "Insurgency",
338 | "insurgencysandstorm": "Insurgency: Sandstorm",
339 | "killingfloor": "Killing Floor",
340 | "killingfloor2": "Killing Floor 2",
341 | "left4dead": "Left 4 Dead",
342 | "left4dead2": "Left 4 Dead 2",
343 | "openttd": "OpenTTD"
344 | }
345 | },
346 | "services": {
347 | "type": "object",
348 | "format": "object",
349 | "example": {
350 | "teamspeak3": "TeamSpeak 3",
351 | "teamspeak2": "TeamSpeak 2",
352 | "ventrilo": "Ventrilo",
353 | "discord": "Discord"
354 | }
355 | }
356 | }
357 | }
358 | }
359 | }
360 | }
--------------------------------------------------------------------------------