Compare commits

..

No commits in common. "main" and "0.1.6" have entirely different histories.
main ... 0.1.6

16 changed files with 61 additions and 52 deletions

View file

@ -5,26 +5,27 @@ It posts the server name, password, time, and player count. Written in Node.js,
discord.js library to interact with Discord and fetches server stats via the XML feed
(accessible through the server's web interface). The update interval is configurable.
## Screenshots
<details>
<summary>Discord embed in english</summary>
![discord_en.png](misc%2Fimages%2Freadme%2Fdiscord_en.png)
![discord_en.png](misc%2Fimages%2Fdiscord_en.png)
</details>
<details>
<summary>Discord embed in german</summary>
![discord_de.png](misc%2Fimages%2Freadme%2Fdiscord_de.png)
![discord_de.png](misc%2Fimages%2Fdiscord_de.png)
</details>
<details>
<summary>Terminal output (NodeJS)</summary>
![bot_terminal.png](misc%2Fimages%2Freadme%2Fbot_terminal.png)
![bot_terminal.png](misc%2Fimages%2Fbot_terminal.png)
</details>
@ -72,27 +73,21 @@ discord.js library to interact with Discord and fetches server stats via the XML
1. Navigate to the root directory of the cloned repository.
2. Build and start the container:
```bash
docker compose up -d --build
docker-compose up -d --build
```
3. The bot should now be running and posting server stats to the specified Discord channel.
### Option 2: Run Without Docker (Using Node.js)
1. Navigate to the root directory of the cloned repository.
2. Install dependencies:
```bash
npm install
```
3. Start the bot:
```bash
npm start
```
4. The bot should now be running and posting server stats to the specified Discord channel.
- Note: Closing the terminal will stop the bot. Use a process manager like [PM2](https://pm2.io/) to keep it running.

View file

@ -1,8 +1,8 @@
{
"application": {
"serverPassword": "TypeMyServerPasswordHere",
"serverStatsUrl": "http://127.0.0.1:8080/feed/dedicated-server-stats.xml",
"serverMapUrl": "http://127.0.0.1:8080/feed/dedicated-server-stats-map.jpg",
"serverStatsUrl": "http://1.1.1.1:8080/feed/dedicated-server-stats.xml",
"serverMapUrl": "http://1.1.1.1:8080/feed/dedicated-server-stats-map.jpg",
"updateIntervalSeconds": 30
},
"discord": {

View file

@ -1,8 +1,8 @@
{
"application": {
"serverPassword": "TypeMyServerPasswordHere",
"serverStatsUrl": "http://127.0.0.1:8080/feed/dedicated-server-stats.xml",
"serverMapUrl": "http://127.0.0.1:8080/feed/dedicated-server-stats-map.jpg",
"serverStatsUrl": "http://1.1.1.1:8080/feed/dedicated-server-stats.xml",
"serverMapUrl": "http://1.1.1.1:8080/feed/dedicated-server-stats-map.jpg",
"updateIntervalSeconds": 30
},
"discord": {

View file

@ -1,3 +1,5 @@
version: "2"
services:
ls25bot:
build:
@ -23,13 +25,3 @@ services:
echo "Restarting ls25bot container at $(date)"
docker restart ls25bot
done
# This is used for development purposes only
webserver:
image: nginx:alpine
container_name: ls25bot-webserver
restart: always
volumes:
- ./misc/files:/usr/share/nginx/html
ports:
- "8080:80"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

View file

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View file

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View file

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

View file

@ -1,6 +1,6 @@
{
"name": "ls25-discord-bot",
"version": "0.1.8",
"version": "0.1.6",
"description": "A simple discord bot for farming simulator 25",
"main": "source/Main.ts",
"scripts": {

View file

@ -92,16 +92,6 @@ export default class DiscordEmbed {
return true;
}
/**
* Truncates a string at a given length
* @param text The input text to truncate
* @param maxLength The allowed characters until truncation
* @returns The truncated string
*/
private async truncateText(text: string, maxLength = 1024): Promise<string> {
return text.length > maxLength ? text.slice(0, maxLength - 3) + '...' : text;
}
/**
* Send server stats embed in a channel
* @param serverStats
@ -110,6 +100,8 @@ export default class DiscordEmbed {
let embed = new EmbedBuilder();
let config = this.appConfiguration;
serverStats.getServerMonth();
embed.setTitle(config.translation.discordEmbed.title);
if (!serverStats.isOnline()) {
embed.setColor(0xCA0000);
@ -123,8 +115,6 @@ export default class DiscordEmbed {
embed.setThumbnail(config.application.serverMapUrl);
let playerListString: string;
let playerListTitleString = `${config.translation.discordEmbed.titlePlayerCount} (${serverStats.getPlayerCount()??0}/${serverStats.getMaxPlayerCount()??0}):`;
if(serverStats.getPlayerList().length === 0) {
playerListString = config.translation.discordEmbed.noPlayersOnline;
} else {
@ -139,7 +129,7 @@ export default class DiscordEmbed {
let serverMods = serverStats.getServerMods();
let serverModsText = "-/-";
if(serverMods.length > 0) {
serverModsText = await this.truncateText(serverMods.map(mod => `${mod.name}`).join(', '));
serverModsText = serverMods.map(mod => `${mod.name}`).join(', ');
}
// @ts-ignore
@ -150,11 +140,12 @@ export default class DiscordEmbed {
{name: config.translation.discordEmbed.titleServerMap, value: serverStats.getServerMap()},
{name: config.translation.discordEmbed.titleServerMods, value: serverModsText},
{
name: playerListTitleString,
name: `${config.translation.discordEmbed.titlePlayerCount} (${serverStats.getPlayerCount()}/${serverStats.getMaxPlayerCount()}):`,
value: playerListString
},
);
}
this.appLogger.debug(embed);
return embed;
}
}

View file

@ -137,6 +137,37 @@ export default class ServerStatusFeed {
});
}
/**
* Returns the server month as a string
* @returns {string} The server month as a string
*/
public getServerMonth(): string {
let config: IConfiguration = Configuration.getConfiguration();
let dayTime = this.getServerStats()?.Server.dayTime;
if (dayTime === undefined) {
return "Error";
}
let month = dayTime / (60 * 60 * 1000 * 24);
month = month % 1;
month = month * 12;
month = Math.floor(month);
let months = [
config.translation.common.monthJanuary,
config.translation.common.monthFebruary,
config.translation.common.monthMarch,
config.translation.common.monthApril,
config.translation.common.monthMay,
config.translation.common.monthJune,
config.translation.common.monthJuly,
config.translation.common.monthAugust,
config.translation.common.monthSeptember,
config.translation.common.monthOctober,
config.translation.common.monthNovember,
config.translation.common.monthDecember
]
return months[month-1];
}
/**
* Returns the server time in the format HH:MM
* @returns {string} The server time in the format HH:MM
@ -156,23 +187,23 @@ export default class ServerStatusFeed {
if(minutesString.length === 1) {
minutesString = `0${minutesString}`;
}
return `${hoursString}:${minutesString}`;
return `${hoursString}:${minutesString} (${this.getServerMonth()})`;
}
/**
* Returns the server player count
* @returns {number | null | undefined} The server player count
* @returns {number} The server player count
*/
public getPlayerCount(): number | null | undefined {
return <number>this.getServerStats()?.Server?.Slots?.numUsed;
public getPlayerCount(): number {
return <number>this.getServerStats()?.Server.Slots.numUsed;
}
/**
* Returns the server player count
* @returns {number | null | undefined} The server player count
* @returns {number} The server player count
*/
public getMaxPlayerCount(): number | null | undefined {
return <number>this.getServerStats()?.Server?.Slots?.capacity;
public getMaxPlayerCount(): number {
return <number>this.getServerStats()?.Server.Slots.capacity;
}
/**