Splamy / TS3AudioBot

Advanced Musicbot for Teamspeak 3
https://splamy.de/TSAudioBot/Home
Open Software License 3.0
691 stars 140 forks source link

Optimal Production Hoster Setup #293

Closed bennetgallein closed 5 years ago

bennetgallein commented 6 years ago

Hey Guys, I currently have the Job to develop a Webinterface for a Teamspeak Hoster. They want to sell TS3AudioBot as Musicbots. Now the challenge is up to me to figure out how to have an optimal Server Setup to manage more than one Instance. I thought about using Docker to create Bots dynamically but the challenge is to connect the Bot to a provided IP. Also I thought about using different configs with entered IP and different Ports for WebAPI and launching the Bot in a screen or so.

Let me know if someone has experience with this topic and what your approach would be!

Christian1998 commented 6 years ago

📌Interested

Splamy commented 6 years ago

Since noone actively hosting the bot wants to give a statement. I'll just give my 2 cents on how I imagined it could work. The bot already has multi instance integrated, but with some limitations:

As well as even though the TS3AB is pretty stable, if there are any core problems multiple instances would be affected by this. (For for example a restart.)

Single core management on the other hand should be rather straight forward. You can declare with the rights.toml file a master api key which is managed by the backend. The backend could call !bot connect new <ip/domain/nicknam> (<password>) to connect to a new server. When the connect was successful the template can be saved with !bot save <name> (or as api for example /bot/use/<botid>/(/bot/save/<name>) because bot save is a bot instance method). To enable or disable autostart when the entire core starts you can add a global config entry in [Bots] for example with !settings global set Bots.<name>.run true (hmm, just tested, this does not work yet, I will add it soon. Right now you can only edit this entry if it already exists)

If you want more stability and customizability for each user you could also try the Multi core approch, aka one TS3AudioBot.exe process for each user. You'd have to place the binary and all dependencies in a folder, lets say ./Core, and each new user gets a folder with all the configs ./User1/ts3audiobot.toml,ts3audiobot.db,etc... You can easily use one generated config file as template and just paste the relevant text or get a toml library read the template and let it write the with the modifications.

bennetgallein commented 6 years ago

Thanks for the answer first off. I'm probably gonna take the first approach, because it's easier for me to just create new instances. The only problems are the shared history and the shared permissions, which, as you could image, won't work that well in a production hosting environment. I'm willing to implement that solution as a public project, so everyone who is in the need of something in that direction has at least a starting point. Sadly, I'm not a C# developer otherwise I'd love to support further Development. Let me know if there are any updates that belong to this topic!

bennetgallein commented 6 years ago

Okay, I'll give a quick update. I've implemented all of the necessary commands for multi instancing into a PHP Wrapper, so it can be easily managed. The Wrapper is located here: TS3AB-API. See the README on how to get started using it. In the Database, I save the current ID of the Bot and on entering the Webpanel the ID gets check if there is an instance running. If not, it starts a new one and saves it to the Database. This is an excerpt of my code for that:

$api->getCommandExecutor()->use($id);
if (isset(json_decode($api->getCommandExecutor()->help())->ErrorCode)) {
            // bot not running.
            $api->getCommandExecutor()->use(0);
            $new = $api->getCommandExecutor()->connectTo($bot->id);
            $id = json_decode($new)->Id;
            $sql = "UPDATE if_mb SET last_id=" . $id . " WHERE id=" . $bot->id;
            $res = $query->query($sql);
}

$bot->id is the auto incrementing id of the database and the id under the bot is saved. $id is the last ID the Bot had.

$connectNew = json_decode($bot->getCommandExecutor()->connectNew($ip));
if (isset($connectNew->Id)) {
                $newID = $connectNew->Id;
                $last =  $query->getConnection()->lastInsertId();
                $bot->getCommandExecutor()->use($newID);
                $bot->getCommandExecutor()->save($last);
                $bot->getCommandExecutor()->name($nickname);
                $query->raw("UPDATE if_mb SET last_id=" . $newID . " WHERE id=" . $last);
                $res2 = $query->execute();
} 

This is to code to create an new Bot. It should be self-explaining.

So if an instance crashes for some reason, the last id from the Database would result in the Code creating a new instance. With that, at least in my mind, a user will always have his own bot and not someone elses. flowchart I also made this "flowchart" to visualize the process a little bit.

The things that bother me at the moment, are the shared permissions and the shared history, which I would love to see getting instance only.