Nimdy / Dedicated_Valheim_Server_Script

Valheim Server Manager . Supports: ValheimPlus, Bepinex, Multi-world, Multi-Lang, Update, Backup, Restore and more: Built for Linux
GNU Affero General Public License v3.0
697 stars 120 forks source link

I made a Discord Bot #68

Closed bppr closed 3 years ago

bppr commented 3 years ago

Hello, not sure if you're interested in pursuing this, but I created a Discord bot that allows you to run a daemonized NodeJS process on the server, which can connect as a bot to a discord server and be issued commands such as !valheim up to start the server, !valheim down to stop it, and !valheim info to see if it's running.

It's pretty basic right now and runs more as a proof of concept, but it might be interesting to you? Might also be prudent to just create a repository of my own and go from there. Let me know what your thoughts are!

anujbiyani commented 3 years ago

This would be neat! More user-friendly way for less technical players on my server to self-administrate a little.

futurejohn commented 3 years ago

That sounds really cool! From the sound of it, this would depend on the virtual machine being accessible, right? Is it possible for those commands to start/stop the VM itself (an AWS EC2 instance in my case)?

bppr commented 3 years ago

@futurejohn I'm running it on the same server as my Valheim installation (also on EC2) - it just requires to install Node/NPM via apt, and then the discord.js NPM package. It manages the Valheim server by shelling out to systemctl, so it's best if installed and run on the same server as the Valheim process. I also created a systemd service to manage the Discord bot's process, so it stays alive outside of SSH connections.

bppr commented 3 years ago

I think at this point the majority of the remaining development effort in integrating this would be in creating an installation shell script to install the Node/NPM dependencies and then to install the systemd service for managing the Discord bot's process. I think an equal amount of time would be needed for documentation and integrating it with the new menu script. The whole bot, outside of configuring it with Discord, is one NodeJS file that's about 50 lines long.

I'd be happy to do so either in pursuit of a PR or in pursuit of a second repo.

bppr commented 3 years ago

currently, the setup looks like this:

1) configure an "app" on the Discord developer portal 2) create a bot within that app 3) create an OAuth URL with the correct permissions (read messages, post messages) 4) use the OAuth URL to invite the bot to a server 5) plug the bot token into the NodeJS bot script 6) start the bot by running the script

note this doesn't manage your EC2/DigitalOcean/whatever servers themselves, just the Valheim service installed by this script

Nimdy commented 3 years ago

Sounds like a good idea.

-Set Variable to enable/disable bot -Build function to install bot and required files/services..etc -Build function to remove bot

(In Discord)

Future--> Send public message from Discord(Admins only) to public server chat window for awareness.

Just thinking outside the box here.

I am down to do some collaboration efforts.

To be fair (LetterKenny Singing): I want to continue adding more features and capabilities to the Menu System but I am only one nerd with a Wife/Kids/full time job. I only work on this stuff when I have down time and my coding over all is very basic. I shine in Cyber Security and Networking, so I am completely open to any help and group efforts.

ShikyoKira commented 3 years ago

Apart from doing a passive report as suggested by Nimdy, any plans for active reporting/notification? Examples such as player login and logout, server down, server up and so on..

bppr commented 3 years ago

@ShikyoKira that would require us to have some sort of event from the Valheim server itself. Right now we have the infrastructure built to get an event from Discord (in the form of a message), but not from Valheim. I'm not even sure if it's possible without modding the Valheim server installation.

Nimdy commented 3 years ago

once I get done with the menu 100%

I will start doing serious stuff.

The key here will be injections to the services before the game starts.... more to come... I havent gotten to play Valheim in like days.... ><

Nimdy commented 3 years ago

found DIS....

https://github.com/EnriqueMoran/remoteDiscordShell

Security.... is my only worry....

bppr commented 3 years ago

Yeah, I certainly like my friends but I wouldn't allow them to run arbitrary shell commands on my server.

We finally built a longboat last night and one friend brought a cheat weapon over from another server and one-shot our boat in the middle of the ocean on her maiden voyage, killing us all. For that reason, it's best to not trust your friends and only run shell scripts that are approved behind a named Discord command with no parameters.

Here's the code for anyone interested. I am busy the next day or so but I can hop in your Discord this weekend and we can chat about where to go next @Nimdy!

const discord = require('discord.js');
const client = new discord.Client();
const { exec } = require('child_process');

const PUBLIC_IP = '<your-ip-here>';
const DISCORD_TOKEN = '<your-token-here>';

function serverCtl(direction, msg) {
  console.log(`taking server ${direction}`);
  msg.react('⏳');
  const cmd = direction === 'up' ? 'start' : 'stop';
  exec(`sudo systemctl ${cmd} valheimserver.service`, (err) => {
    if(err) {
      msg.reply(`There was an error: ${err}`);
      console.log(err)
      return
    }

    msg.reply(`Server is now ${direction}`);
  });
}

function isServerActive(callback) {
  exec('sudo systemctl show valheimserver.service --no-page', (err, stdout, stderr) => {
    const lines = stdout.split('\n')
    const isActive = lines.find(line => line.startsWith('ActiveState'))
      .split('=')
      .includes('active')

    callback(isActive)
  });
}

client.on('ready', () => console.log(`Logged in as ${client.user.tag}!`));

client.on('message', msg => {
  if(!msg.content.startsWith('!')) return

  switch(msg.content) {

  case '!ping': 
    msg.reply('Pong!');
  case '!valheim up': 
    serverCtl('up', msg);
  case '!valheim down': 
    serverCtl('down', msg);
  case '!valheim info':
    isServerActive(isActive => {
      msg.reply(
        isActive 
          ? `Server is running at ${PUBLIC_IP}:2456`
          : 'Server is not currently running. `!valheim up` to start the server!');
    });
  default:
    return
  }
});

client.login(DISCORD_TOKEN);
bppr commented 3 years ago

I was thinking another nice command to have would be a "stop/wait/backup/start" lifecycle that would allow the update commands documented here to be run by anyone as well?

Nimdy commented 3 years ago

hit me up in Discord later, so we can chit chity chat chat about your plans :).... if you like

Nimdy commented 3 years ago

@bppr Let me know when you are back and if you still want to do something together. Been waiting but I know life gets in the way.

:)

ShikyoKira commented 3 years ago

@bppr i have managed to make an active reporting bot by capturing the data packet through the specific port. I'm sure you will be interested in it

https://github.com/ShikyoKira/pcap_bot https://github.com/ShikyoKira/jobe_bot https://github.com/ShikyoKira/notify_bot