GithubHelp home page GithubHelp logo

special-k-s-flightsim-bots / dcsserverbot Goto Github PK

View Code? Open in Web Editor NEW
74.0 13.0 21.0 7.47 MB

Manage your DCS World servers with lots of extensions and possibilities (with Discord integration)

Home Page: https://special-k-s-flightsim-bots.github.io/DCSServerBot/

License: MIT License

Python 94.69% Lua 4.42% Batchfile 0.27% PLpgSQL 0.63% Procfile 0.01%
dcs-world discord-bot

dcsserverbot's Introduction

Welcome to DCSServerBot!

You've found a comprehensive solution that helps you administrate your DCS World servers. It has a Discord integration (now optional!) with slash-commands, built in per-server and per-user statistics, optional cloud-based statistics, Coalitions-support and much more! With its plugin system and reporting framework, DCSServerBot can be enhanced very easily to support whatever might come into your mind. DCSServerBot is a solution for DCS server admins built by a DCS server admin.

This documentation shows you the main features, how to install and configure the bot and some more sophisticated stuff at the bottom, if you for instance run multiple servers maybe even over multiple locations.

Now let's see, what DCSServerBot can do for you (installation instructions below)!


Architecture

DCSServerBot has a modular architecture with services, plugins and extensions that provide specific functionalities like monitoring the availability of your servers, a lot of Discord slash-commands and supports common add-ons like SRS, LotAtc, DCS Olympus and others.

The solution itself is made for anything from single-server environments up to large scale, worldwide installations with high availability requirements. There are nearly no limits. If you are interested into some deeper insights to the bots architecture, read here

Node

A node is an installation of DCSServerBot on one PC. The usual user will have one installation, meaning one node. You can run multiple instances of DCS ("DCS servers") with each node (see below). If you run multiple PCs or (virtual) servers, you need to install multiple DCSServerBot nodes. This results in a DCSServerBot cluster.
One node is always a master node, which handles all the Discord commands and controls the rest of the cluster.

Instance

Each node can control multiple instances of DCS, meaning DCS.exe or DCS_Server.exe processes. You can use the normal client installation of DCS World to run a server, but the Dedicated Server installation would be preferable.

Services

A service is a component that runs on each node. Services can be combined with plugins, if they provide additional Discord commands, like the Music service. Some services only run on the master node, like the Bot service for instance.

Service Scope Plugin Documentation
Backup Backup your bot- and DCS-configuration, your missions, database, etc. Backup README
Bot The Discord bot handling all discord commands. There is a Discord-free variant available also (see blow)! README
Cleanup Cleanup logfiles, trackfiles, etc. from your disk. README
Dashboard Nice console graphics display to show the status of your bot / servers. README
Monitoring Availability- and performance-monitoring of your DCS servers. ServerStats README
Music Play music over different SRS-radios on your servers. Music README
OvGME Manage mods that needs to be installed / updated in your DCS servers. OvGME README
Scheduler Schedule tasks based on a cron-like configuration. Scheduler README
ServiceBus Communication hub between every node of the bot cluster and all DCS-servers. README

Plugins

A plugin is an expansion of the bot that can be controlled via Discord commands and sometimes in-game chat commands. DCSServerBot comes with a rich set of default plugins, but it can be enhanced with optional plugins. I enhance the bot from time to time, but you as a community member can also create your own plugins (and maybe share them with others).

Plugin Scope Optional Depending on Documentation
GameMaster Interaction with the running mission (inform users, set flags, etc) no README
Mission Handling of missions, comparable to the WebGUI. no GameMaster README
Admin Admin commands to manage your DCS server. yes* README
Help Interactive help commands for Discord and in-game chat yes* README
UserStats Users statistics system. yes* Mission README
CreditSystem User credits, based on achievements. yes* Mission README
Scheduler Autostart / -stop of servers or missions, modify missions, etc. yes* Mission README
Cloud Cloud-based statistics and connection to the DGSA global ban system. yes* Userstats README
MissionStats Detailed users statistics / mission statistics. yes* Userstats README
Backup Create a backup of your database, server or bot configurations. yes README
Battleground Support for DCS Battleground yes README
Commands Create custom discord commands. yes README
Competitive Support for PvP communities, especially with TrueSkill™️ ranking system. yes Mission README
DBExporter Export the DCSServerBot database or singular tables as json. yes README
FunkMan Support for FunkMan yes README
GreenieBoard Greenieboard and LSO quality mark analysis (SC and Moose.AIRBOSS / FunkMan) yes Missionstats README
LotAtc Upload LotAtc Transponder files to your servers. yes README
MOTD Message for players on join or when they jump in a module. yes Mission, MissionStats README
Music Upload and play music over SRS. yes README
OvGME Install or update mods into your DCS server. yes README
Pretense Commands for Pretense missions. yes README
Punishment Punish users for team-hits or team-kills. yes Mission README
RealWeather Apply real weather to your missions (also available as an extension). yes README
RestAPI Simple REST-API to query users and statistics (WIP). yes Userstats, MissionStats README
ServerStats Server statistics for your DCS servers. yes Userstats README
SlotBlocking Slot blocking either based on discord roles or credits. yes Mission, CreditSystem README
SRS Display players activity on SRS, show active channels and enable slot blocking. yes MissionStats README
Tacview Install or uninstall Tacview from your server(s) and do a basic configuration. yes README
Voting Simple voting system for players to be able to change missions, weather, etc. yes README

*) These plugins are loaded by the bot by default, but they are not mandatory to operate the bot.
    If you do not want to load any of them, define a list of plugins in your main.yaml and only
    list the plugins you want to load.

How to install 3rd-Party Plugins

If a community member provides a plugin for DCSServerBot, chances are that it is packed into a zip file. You can download this zipfile and place it directly into the /plugins directory. DCSServerBot will automatically unpack the plugin for you, when DCSServerBot restarts. Keep in mind that some of these plugins might need configurations. Please refer to the respective plugin-documentation for more.

In case you want to write your own Plugin ...

You can find a sample in the plugins/sample subdirectory and a guide here. These will guide you through the steps needed to build your own plugin. Do you want your plugin to be added as an optional plugin to the DCSServerBot? Contact me via the contact details listed below.

Extensions

Many DCS admins use extensions or add-ons like DCS-SRS, Tacview, LotAtc, etc.
DCSServerBot supports some of them already and can add a bit of quality of life.

Extension Scope
MizEdit My own invention, can be used to modify your missions. Very powerful, read it up here!
DCS Voice Chat DCS VOIP system to communicate with other pilots.
DCS-SRS Market leader in DCS VOIP integration.
Tacview Well known flight data capture and analysis tool.
LotAtc GCI- and ATC-extension for DCS World. Simple display only extension.
DSMC DSMC mission handling, should be activated when dealing with DSMC missions.
DCS Olympus Real-time control of your DCS missions through a map interface.
Lardoon Webgui for Tacview with search options.
Sneaker Moving map interface (see Battleground for another option!
DCS Real Weather Real weather for your missions.
OvGME Use mods within your DCS World servers.
gRPC Support gRPC, a communication framework with DCS World.
Pretense Dynamic campaign framework by Dzsek.

Check out Extensions for more info on how to use them.


Installation

Prerequisites

You need to have Python 3.9 or higher and PostgreSQL installed. Please make sure that you tick "Add python.exe to PATH" during your Python installation.

If you want to use instant autoupdate from the master branch, you have to install GIT and make sure the git-command is in your PATH.

Discord Setup

The bot needs a unique Token per installation. This one can be obtained at http://discord.com/developers

  • Create a "New Application".
  • Select Bot from the left menu and give it a nice name, icon and maybe a banner.
  • Press "Reset Token" and then "Copy" to obtain your token.
  • Now your Token is in your clipboard. Paste it in some editor for later use.
  • All "Privileged Gateway Intents" have to be enabled on that page.
  • To add the bot to your Discord guild, select "OAuth2" from the left menu
  • Select the "bot" checkbox in "OAuth2 URL Generator"
  • Select the following "Bot Permissions":
    • Left side:
      • Manage Channels
    • Center:
      • Send Messages
      • Manage Messages
      • Embed Links
      • Attach Files
      • Read Message History
      • Add Reactions
      • Use Slash Commands
  • Press "Copy" on the generated URL and paste it into the browser of your choice
  • Select the guild the bot has to be added to - and you're done!

⚠️ Attention!
For easier access to user and channel IDs, enable "Developer Mode" in "Advanced Settings" in your Discord client.

🆕 Setup without using Discord

If you do not want to use Discord, or if you maybe are not allowed to do so due to limitations of your Country, etc. you can now install DCSServerBot without the need to use Discord. Just select the respective option during the installation, and you will install a variant that works without.

⚠️ Attention!
Please keep in mind that DCSServerBot was originally made for Discord and that there are some functionalities that can only work, if you use it, like static graphs, greenieboards, and others.
But you can still use a lot and there are in-game chat-commands also that you can use, without any need of Discord.

Download

Best is to use git clone https://github.com/Special-K-s-Flightsim-Bots/DCSServerBot.git as you then always have the newest fixes, independent of and release version. Otherwise, download the latest release version as ZIP and extract it somewhere on your PC that is running the DCS server(s) and give it write permissions, if needed.

⚠️ Attention!
Make sure that the bots installation directory can only be seen by yourself and is not exposed to anybody outside via www etc. as it contains sensitive data.

Database

DCSServerBot uses PostgreSQL to store all information that needs to be persistent. This consists of, but is not limited to: players, mission information, statistics. DCSServerBot needs a fast database to do this. Install the latest available PostgreSQL version from the above-mentioned website.

⚠️ Attention!
If using PostgreSQL remotely over unsecured networks, it is recommended to have SSL enabled.

DCSServerBot Installation (Discord)

Run the provided install.cmd script or just run.cmd.
It will ask you for your Guild ID (right-click on your Discord server icon and select "Copy Server ID") and the bots user ID (right-click on the bot user and select "Copy User ID"). Then it will search for existing DCS installations, create the database user, password and database and asks whether you want to add existing DCS servers to the configuration.
When finished, the bot should launch successfully and maybe even start your servers already, if configured.

DCSServerBot Installation (non-Discord)

Run the provided install.cmd script or just run.cmd.
It will ask you for your DCS group name and a role mapping, where you can give specific DCS users roles that are needed to make the in-game commands work. You need the UCIDs of the users here. Then it will search for existing DCS installations, create the database user, password and database and asks whether you want to add existing DCS servers to the configuration.
When finished, the bot should launch successfully and maybe even start your servers already, if configured.

⚠️ Attention!
You should shut down your DCS servers during the bots installation, as it places its own LUA hooks inside the servers Scripts directory.
Please keep also in mind, that a lot of configuration parameters which you find below are not needed for a non-Discord setup. If you have no idea what to put in a specific parameter, that is usually a good sign to just skip it.

You can start the installer with these parameters:

Usage: install.cmd [-h] [-n NODE] [-c CONFIG] [-u USER] [-d DATABASE]

Welcome to DCSServerBot!

options:
  -h, --help                        Show this help message and exit
  -n NODE, --node NODE              Node name (default = hostname)
  -c CONFIG, --config CONFIG        Path to configuration
  -u USER, --user USER              Database username (default = dcsserverbot)
  -d DATABASE, --database DATABASE  Database name (default = dcsserverbot)

You might want to provide different node names, if you install multiple nodes on one PC and different database user and database names, if you want to install multiple bots for multiple Discord groups.

Desanitization

DCSServerBot desanitizes your MissionScripting environment. That means, it changes entries in Scripts\MissionScripting.lua of your DCS installation. If you use any other method of desanitization, DCSServerBot checks, if additional desanitizations are required and conducts them.

⚠️ Attention!
DCSServerBot needs write-permissions on the DCS-installation directory.
You can usually achieve that by giving the "User group" write permissions on it. Right-click on your DCS installation folder,
select Properties -> Security -> Edit, select "Users (...)" and tick Modify below. Then press the OK button. There might be a question about changing the permission on all subdirectories - say yes in that case.

Your MissionScripting.lua should look like this after a successful bot start:

do
	sanitizeModule('os')
	--sanitizeModule('io')
	--sanitizeModule('lfs')
	--_G['require'] = nil
	_G['loadlib'] = nil
	--_G['package'] = nil
end

Custom MissionScripting.lua

If you want to use a custom MissionScripting.lua that has more sanitization (for instance for LotAtc, Moose, OverlordBot or the like) or additional lines to be loaded (for instance for LotAtc, or DCS-gRPC), just place the MissionScripting.lua of your choice in the config directory of the bot. It will then be replaced on every bot startup.


Configuration

The bot configuration is held in several files in the config subdirectory. If you run the install.cmd script for the first time, it will generate basic files for you that you can amend to your needs afterwards. Your bot should be ready to run already, and you can skip this section for now, if you don't want to bother with the bots configuration in first place.

⚠️ Attention!
If you run more than one bot node, best is to share the configuration between all nodes. This can be done via a cloud drive for instance or with some file sync tool.

The following samples will show you what you can configure in DCSServerBot. For most of the configuration, default values will apply, so you don't need to define all these values explicitly. I printed them here for completeness and for the sake of documentation.

config/main.yaml

This file holds the main information about DCSServerBot. You can configure which plugins are loaded here for instance.

guild_id: 112233445566    # Your Discord server ID. Right-click on your server and select "Copy Server ID". On non-discord installations this number is filled for you.
guild_name: My Group      # Non-Discord only: your DCS group name
autoupdate: true          # use the bots autoupdate functionality, default is false
use_dashboard: true       # Use the dashboard display for your node. Default is true.
chat_command_prefix: '-'  # The command prefix to be used for in-game chat commands. Default is "-"
mission_rewrite: false    # Disable the re-write of missions by MizEdit or RealWeather. The server will be stopped for any mission change then. (default: true)
language: de              # Change the bots language to German. This is WIP, several languages are in the making, including DE, ES, RU and more
database:
  url: postgres://USER:PASSWORD@DB-IP:DB-PORT/DB-NAME   # The bot will auto-move the database password from here to a secret place and replace it with SECRET.
  pool_min: 5           # min size of the DB pool, default is 5
  pool_max: 10          # max size of the DB pool, default is 10
  max_reties: 10        # maximum number of retries to initially connect to the database on startups
logging:
  loglevel: DEBUG           # loglevel, default is DEBUG
  logrotate_count: 5        # Number of logfiles to keep after rotation. Default is 5.    
  logrotate_size: 10485760  # max size of a logfile, default is 10 MB
  utc: true                 # log in UTC (default: true), use local time otherwise
messages:
  player_username: Your player name contains invalid characters. Please change your # Default message for players with invalid usernames
    name to join our server.
  player_default_username: Please change your default player name at the top right  # Default message for players with default usernames
    of the multiplayer selection list to an individual one!
  player_banned: 'You are banned from this server. Reason: {}'                      # Default message for banned players.
filter:
  server_name: ^Special K -           # Filter to shorten your server names on many bot displays. Default is none. 
  mission_name: ^Operation|_|\(.*\)   # Filter to shorten your mission names on many bot displays. Default is none.
  tag: "'^[JDS]'"                     # If your community uses specific tags, this helps with the bots automatch functionality.
opt_plugins:                          # Optional: list of optional plugins to be loaded and used by the bot
- serverstats                         # see above
- dbexporter
- motd
- greenieboard
- punishment
- slotblocking
- music
- funkman
- ovgme
- commands
- restapi

config/nodes.yaml

This file holds the main configuration for all your nodes.
For a cluster installation, you want to describe all your nodes and instances on all your nodes, as the bot can (auto-)migrate stuff in-between the cluster!

NODENAME:                       # this will usually be your hostname
  listen_port: 10042            # On which port should the bot listen? Default is 10042
  listen_address: 0.0.0.0       # Optional: On which interface should the bot listen? Default is 127.0.0.1.
  slow_system: false            # Optional: if you are using a slower PC to run your servers, you should set this to true (default: false)
  preferred_master: true        # cluster only: this node should be the preferred master node (default: false)
  heartbeat: 30                 # cluster only: time for the heartbeat between the master and agent nodes to run (default: 30)
  cloud_drive: false            # cluster only: set this to false, if you do not have the bot installed on a cloud drive (default and recommended: true) 
  nodestats: true               # Enable/disable node statistics (database pool and event queue sizes), default: true
  DCS:
    installation: '%ProgramFiles%\\Eagle Dynamics\\DCS World Server'  # This is your DCS installation. Usually autodetected by the bot.
    autoupdate: true            # enable auto-update for your DCS servers. Default is false.
    cloud: true                 # If you have installed DCS on a NAS or cloud drive, autoupdate and desanitization will only take place once on all your nodes.
    desanitize: true            # Desanitize your MissionScripting.lua after each update. Default is true.
    minimized: true             # Start DCS minimized (default: true)
    user: xxxx                  # Your DCS username (only needed for specific use-cases)
    password: xxxx              # Your DCS password (will be auto-moved by the bot to a secret place)
  instances:
    DCS.release_server:        # The name of your instance. You can have multiple instances that have to have unique names.
      home: '%USERPROFILE%\\Saved Games\\DCS.release_server' # The path to your saved games directory.
      missions_dir: '%USERPROFILE%\Documents\Missions'        # You can overwrite the default missions dir like so. Default is the Missions dir below the instance home folder.
      bot_port: 6666            # The port DCSServerBot uses to communicate with your DCS server. Each instance has to have a unique port. This is NOT your DCS port (10308)!!!
      max_hung_minutes: 3       # Let DCSServerBot kill your server if it is unresponsive for more than x minutes. Default is 3. Disable it with 0.
      affinity: 2,3             # Optional: set the CPU-affinity for the DCS_Server.exe.
      priority: normal          # Optional: set the process priority (low, normal, high, realtime) for the DCS_Server.exe
      extensions:               # See the extension documentation for more detailed information on what to set here.
        SRS:
          config: '%USERPROFILE%\Saved Games\DCS.release_server\Config\SRS.cfg'  # it is recommended to copy your SRS "server.cfg" below your instances home directory.
          host: 127.0.0.1       # SRS servers local IP (default is 127.0.0.1)
          port: 5002            # SRS servers local port (default is 5002). The bot will change this in your SRS configuration, if set here!
          autostart: true       # this will autostart your DCS server with the DCS server start (default: true)
          autoupdate: true      # This will auto-update your SRS servers. Default is false, you need to run the bot as Administrator to make it work!
        Tacview:
          show_passwords: false # If you don't want to show the Tacview passwords (default: true)
    instance2:                  # you can have an unlimited amount of instance configurations, but each instance has to have a physical representation on your disk.
      ...

config/servers.yaml

This is your server configuration.
You might wonder why the configuration is split between nodes.yaml and servers.yaml? Even if you have a basic setup! This is to decouple the server configuration from the physical node (aka the "DCS.exe" / "DCS_Server.exe" process). You will learn to love it, especially when you decide to move a server from one instance to another or even from one node to another. This is much easier with a non-coupled approach like that.

DEFAULT:
  message_ban: 'You are banned from this server. Reason: {}' # default message, if a player is banned on the DCS server
  message_afk: '{player.name}, you have been kicked for being AFK for more than {time}.'  # default message for AFK users
  message_server_full: The server is full, please try again later!  # default message, if the server is considered full (see SlotBlocking plugin)
  message_reserved: 'This server is locked for specific users.\nPlease contact a server admin.' # Message if server requires discord role (optional)
  message_no_voice: You need to be in voice channel "{}" to use this server!  # default message, if you are not in Discord voice, but force_voice is on.
  message_slot_spamming: You have been kicked for slot spamming! # default message for slot spamming (changing more than 5 slots in-between 5 seconds)
  message_timeout: 10           # default timeout for DCS popup messages in seconds 
  display_ai_chat: false        # do not display AI chat messages in the chat channel (default: false)
  rules: |                      # Optional: Rules to be displayed for new users (needs MissionStats enabled!)
    These are the rules to play on this server:
    1) Do not team-kill
    2) Do not harass people
    3) Be a decent human being
    4) ...
  accept_rules_on_join: true    # True, if rules have to be acknowledged (players will be moved to spectators otherwise, default: false)
My Fancy Server:                # Your server name, as displayed in the server list and listed in serverSettings.lua
  server_user: Admin            # Name of the server user #1 (technical user), default is "Admin".
  afk_time: 300                 # Time in seconds after which a player that is on spectators is considered being AFK. Default: -1, which is disabled
  ping_admin_on_crash: true     # Ping DCS Admin role in discord, when the server crashed. Default: true
  autoscan: false               # Enable autoscan for new missions (and auto-add them to the mission list). Default: false
  autorole: Fancy Players       # Optional: give people this role, if they are online on this server (overwrites autorole[online] in bot.yaml!).
  force_voice: false            # Optional: enforce the usage of a voice channel (users needs to be linked!) - default: false
  discord:                      # Optional: specify discord roles that are allowed to use this server
    - '@everyone'               # Attention: people can not self-link on these servers and have to be liked properly already!
  channels:
    status: 1122334455667788    # The Discord channel to display the server status embed and players embed into. Right-click on your channel and select "Copy Channel ID". You can disable it with -1
    chat: 8877665544332211      # The Discord channel for the in-game chat replication. You can disable it with setting it to -1.
    admin: 1188227733664455     # The channel where you can fire admin commands to this server. You can decide if you want to have a central admin channel or server specific ones. See bot.yaml for more.
    voice: 1827364518273645     # The voice channel, where people need to connect to (if force_voice is true). 
  chat_log:
    count: 10                   # A log file that holds the in-game chat to check for abuse. Tells how many files will be kept, default is 10.
    size: 1048576               # Max logfile size, default is 1 MB. 
  no_coalition_chat: true       # Do not replicate red and blue chats to the Discord chat replication (default: false)
  serverSettings:               # Overwrite the serverSettings.lua with these values
    port: 10308
    advanced:
      resume_mode: 0
My 2nd Fancy Server:            # You can have an unlimited amount of server configurations.
  ...

config/presets.yaml

This file holds your different presets that you can apply to missions as modifications.
See MizEdit for further details.

services/bot.yaml

This is your Discord-bot configuration.

token: SECRET_DISCORD_TOKEN                     # Your TOKEN, as received from the discord developer portal. This will be auto-moved to a secret place by the bot.
owner: 1122334455667788                         # The ID of your bot user. Right click, select "Copy User ID".
automatch: true                                 # Use the bots auto-matching functionality (see below), default is true.
autoban: false                                  # Use the bots auto-ban functionality (see below), default is false.
autorole:                                       # Automatically give roles to people, depending on conditions (see below). The roles need to be set up in your Discord server.
  on_join: Member                               # Give anyone the "Member" role, if they join your Discord.
  linked: DCS                                   # Give people that get linked the DCS role.
  online: Online                                # Give people that are online on any of your servers the "Online" role.
no_dcs_autoban: false                           # If true, people banned on your Discord will not be banned on your servers (default: false)
message_ban: User has been banned on Discord.   # Default reason to show people that try to join your DCS servers when they are banned on Discord.
message_autodelete: 300                         # Most of the Discord messages are private messages. If not, this is the timeout after that they vanish. Default is 300 (5 mins). 
admin_channel: 1122334455667788                 # Optional: Central admin channel (see below).
reports:
  num_workers: 4                                # Number of worker threads to be used for any reports generated by the bot. Default is 4.
discord_status: Managing DCS servers ...        # Message to be displayed as the bots Discord status. Default is none.
audit_channel: 88776655443322                   # Central audit channel to send audit events to (default: none)
roles:                                          # Roles mapping. The bot uses internal roles to decouple from Discord own role system.
  Admin:                                        # Map your Discord role "Admin" to the bots role "Admin" (default: Admin)
  - Admin                                       
  Alert:                                        # Optional Alert role. Default is DCS Admin. Would be pinged on server crashes and low performance
  - DCS Admin
  DCS Admin:                                    # Map your Discord role "Moderator" and "Staff" to the bots "DCS Admin" role (default: DCS Admin)
  - Moderator
  - Staff
  GameMaster:                                   # Map the GameMaster role to anybody with the Staff role in your Discord.
  - Staff
  DCS:                                          # Map the bots DCS role to everyone in your discord. Only everyone needs the leading @!
  - @everyone

⚠️ Attention!
The bots role needs to be above any other role in your Discord server that it has to be able to manage.
If you want the bot to give the "Online" role for people for example, it has to be below the bot's role.

CJK-Fonts Support

DCSServerBot supports external fonts, especially CJK-fonts to render the graphs and show your player names using the real characters of your language. Unfortunately, I can not auto-download the respective fonts from Google Fonts anymore, where I have to ask you guys to do that on your own.
To download the supported fonts, go to https://fonts.google.com/ and search for

Then press "Get font" and "Download all". Copy the ZIP file into a folder "fonts" that you create below the DCSServerBot installation directory. The bot will take this ZIP on its next startup, unpack it and delete the ZIP file. From then on, the bot will use the respective font(s) without further configurations.

Auto Matching (default: enabled)

To use in-game commands, your DCS players need to be matched to Discord users. Matched players are able to see statistics and you can see a variety of statistics yourself as well. The bot offers a linking system between Discord and DCS accounts to enable this. Players can do this with the /linkme command. This creates a permanent and secured link that can then be used for in-game commands. The bot can also auto-match a DCS player to Discord user. This way, players can see their own stats via Discord commands. The bot will try to match the Discord username to DCS player name. This works best when DCS and Discord names match! It can generate false links though, which is why I prefer (or recommend) the /linkme command. People still seem to like the auto-matching, that is why it is in and you can use it (enabled per default).

Auto-Banning (default: disabled)

DCSServerBot supports automatically bans / unbans of players from the configured DCS servers, as soon as they leave / join your Discord guild. If you like that feature, set autoban: true in services/bot.yaml (default: false).

However, players that are being banned from your Discord or that are being detected as hackers are auto-banned from all your configured DCS servers independent of that setting. You can prevent this by setting no_dcs_autoban: true.

Roles (Discord and non-Discord)

The bot uses the following internal roles to apply specific permissions to commands.
You can map your Discord roles to these internal roles like described in the example above or for the non-Discord variant, you just add your UCIDs as a list below each group.
Non-Discord installations usually only need the Admin and DCS Admin roles.

Role Description
Admin People with this role are allowed to manage the server, start it up, shut it down, update it, change the password and gather the server statistics.
DCS Admin People with this role are allowed to restart missions, managing the mission list, ban and unban people.
DCS People with this role are allowed to chat, check their statistics and gather information about running missions and players.
GameMaster People with this role can see both Coalitions and run specific commands that are helpful in missions.

See Coalitions for coalition roles.

Handling of Passwords and other Secrets

DCSServerBot stores the secret Discord TOKEN and your database and (optional) DCS password in separate files. If ever you have added these to your config files like mentioned above, the bot will take them and move them away. This is a security feature. If you somehow forgot the values, you can always reveal them by starting the bot with the -s option like so: run.cmd -s.

DCS/Hook Configuration

The DCS World integration is done via Hooks. They are being installed automatically into your configured DCS servers by the bot.

Sample Configuration

To view some sample configurations for the bot or for each configurable plugin, look here.

Additional Security Features

Players that have no pilot ID (empty or whitespace) or that share an account with others, will not be able to join your DCS server. This is not configurable, it's a general rule (and a good one in my eyes).
Besides that, people that try to join from the very same IP that a banned user has used before will be rejected also (ban-avoidance). You get a message in the discord admin-channel about it.

Setup Multiple Servers on a Single Host

To run multiple DCS servers under control of DCSServerBot you just have to make sure that you configure different communication ports. This can be done with the parameter bot_port in nodes.yaml. The default is 6666, you can just increase that for every server (6667, 6668, ...).
Don't forget to configure different Discord channels (chat and status, optional admin) for every server, too. This will be done in the servers.yaml file.
To add subsequent servers, just follow the steps above, and you're good, unless they are on a different Windows server (see Multi-Node-Setup in that case).

DCSServerBot will autodetect all configured DCS servers on installation and generate simple configuration files for you already. To add a new instance, you can either do that manually or use /node add_instance in your Discord.

Starting the Bot

To start the bot, use the packaged run.cmd command. This creates the necessary Python virtual environment and launches the bot afterward.
If you want to run the bot from autostart, press Win+R, enter shell:startup and press ENTER, create a shortcut to your run.cmd in there.

Repairing the Bot

If you have issues starting DCSServerBot, especially after an update, it might be that some 3rd party library got corrupted. In rare cases, it can also happen, that an auto-update is not possible at all, because some file got changed that was not supposed to be changed, or some other corruption has occurred.
In these cases, you can run the repair.cmd script in the DCSServerBot installation folder.

How to do the more complex stuff?

DCSServerBot can be used to run a whole worldwide distributed set of DCS servers and therefore supports the largest communities. The installation and maintenance of such a use-case is just a bit more complex than a single server installation. Please refer to Multi-Node-Setup for further information.

How to talk to the Bot from inside Missions

If you plan to create Bot-events from inside a DCS mission, that is possible! Just make sure, you include this line in a trigger:

  dofile(lfs.writedir() .. 'Scripts/net/DCSServerBot/DCSServerBot.lua')

Don't use a Mission Start trigger, as this might clash with other plugins loading stuff into the mission._

After that, you can for instance send chat messages to the bot using

  dcsbot.sendBotMessage('Hello World', '12345678') -- 12345678 is the ID of the channel, the message should appear, default is the configured chat channel

inside a trigger or anywhere else where scripting is allowed.

⚠️ Attention!
Channel always has to be a string, encapsulated with '', not a number because of Integer limitations in LUA.

Embeds can be sent using code similar to this snippet:

  title = 'Special K successfully landed at Kutaisi!'
  description = 'The unbelievable and unimaginable event happend. Special K succeeded at his 110th try to successfully land at Kutaisi, belly down.'
  img = 'https://i.chzbgr.com/full/8459987200/hB315ED4E/damn-instruction-manual'
  fields = {
    ['Pilot'] = 'sexy as hell',
    ['Speed'] = '130 kn',
    ['Wind'] = 'calm'
  }
  footer = 'Just kidding, they forgot to put their gear down!'
  dcsbot.sendEmbed(title, description, img, fields, footer)

They will be posted in the chat channel by default, if not specified otherwise (adding the channel id as a last parameter of the sendEmbed() call, see sendBotMessage() above).

If you like to use a single embed, maybe in the status channel, and update it instead of creating new messages, you can do that, by giving is a name like "myEmbed" in this example. The name has to be unique per server.

  title = 'RED Coalition captured Kutaisi!'
  description = 'After a successful last bombing run, RED succeeded in capturing the strategic base of Kutaisi.\nBLUE has to fight back **NOW** there is just one base left!'
  dcsbot.updateEmbed('myEmbed', title, description)
  --[....]
  title = 'Mission Over!'
  description = 'RED has won after capturing the last BLUE base Batumi, congratulations!'
  img = 'http://3.bp.blogspot.com/-2u16gMPPgMQ/T1wfXR-bn9I/AAAAAAAAFrQ/yBKrNa9Q88U/s1600/chuck-norris-in-war-middle-east-funny-pinoy-jokes-2012.jpg'
  dcsbot.updateEmbed('myEmbed', title, description, img)

If no embed named "myEmbed" is already there, the updateEmbed() call will generate it for you. Otherwise, it will be replaced with this one.


Contact / Support

If you need support, if you want to chat with me or other users or if you like to contribute, jump into my Support Discord.
If you like what I do, and you want to support me, you can do that via my Patreon Page.


Credits

Thanks to the developers of the awesome solutions HypeMan and perun, that gave me the main ideas to this solution. I gave my best to mark the few parts in the code to show where I copied some ideas or even code from you guys, which honestly is just a very small piece. Hope that is ok. Also thanks to Moose for aligning the API for FunkMan with me and make it compatible with DCSServerBot in first place.

dcsserverbot's People

Contributors

bdutton12 avatar bevansin avatar kaltokri avatar karel26 avatar killg0renl avatar rolln-dev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dcsserverbot's Issues

Not an "issue", more a question

In reference to the DCS Desanitization, does the OS module need to be desanitized? I work for Fox3 Managed Solutions and out of abundance for security, we prefer not to desanitize the OS module. Would love to know if it's necessary or a work around is possible!

New DCS Real Weather config may break compatibility with DCS Server Bot extension

It appears the changes to Real Weather's configuration in v1.9.0-rc2 break compatibility with the DCS Server Bot extension. The new configuration file uses nested keys to improve readability in addition to adding more possible configuration options.

I believe the offending lines are the following from extensions/realweather.py

cfg['input-mission-file'] = filename + '.orig'
cfg['output-mission-file'] = filename
for key in list(cfg.keys()):
    if key in self.config:
        cfg[key] = self.config[key]

Error Module

Hello, please can you help me with this error ?

I've installed all from requirements.txt (postgre is alredy installed)

======= RESTART: C:\Users\Administrator\Desktop\DCSServerBot-2.2.0\bot.py ======
Traceback (most recent call last):
  File "C:\Users\Administrator\Desktop\DCSServerBot-2.2.0\bot.py", line 79, in <module>
    current_hash = repo.head.commit.hexsha
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\git\refs\symbolic.py", line 217, in _get_commit
    obj = self._get_object()
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\git\refs\symbolic.py", line 210, in _get_object
    return Object.new_from_sha(self.repo, hex_to_bin(self.dereference_recursive(self.repo, self.path)))
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\git\refs\symbolic.py", line 151, in dereference_recursive
    hexsha, ref_path = cls._get_ref_info(repo, ref_path)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\git\refs\symbolic.py", line 201, in _get_ref_info
    return cls._get_ref_info_helper(repo, ref_path)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\git\refs\symbolic.py", line 184, in _get_ref_info_helper
    raise ValueError("Reference at %r does not exist" % ref_path)
ValueError: Reference at 'refs/heads/master' does not exist

Chat channel filtering?

Hi,

First I want to say; Excellent work on this tool! Amazing features.

I am wondering if it's possible to either suppress certain types of chats (maybe with rules to match based on chat content?) or if I could at least only allow chats from human players? Im not seeing any documentation on it.

If not, I think this would be an excellent option to have. I like the idea of being able to help people while not being in the game myself.

One other feature that might be cool is the ability to @ people in the discord from game chat. Not sure how that would work though.

Question

Hi, this is not a problem with the programm but I'm interested in how you did this. Could you describe to me how you get the player stats from the server or the general information.

Thanks and kind regards

Server not detected after startup

Hi, I have a weird problem, our dcs server is starting fine, and in scripts/net/dcsserverbot/dcsserverbotconfig.lua I see the following:

-- DCSServerBotConfig.lua
----------------------------------------------------------
-- This file has been generated by DCSServerBot based on
-- the dcsserverbot.ini file located in the config sub-
-- directory of the DCSServerBot installation.
----------------------------------------------------------
-- !!! PLEASE DON'T CHANGE THIS FILE DIRECTLY BUT      !!!
-- !!! CHANGE THE ACCORDING VALUES IN dcsserverbot.ini !!!
----------------------------------------------------------
module('DCSServerBotConfig')

VERSION = '2.6.7'
-- General Values
BOT_HOST = '127.0.0.1'
BOT_PORT = 10042
CHAT_COMMAND_PREFIX = '-'
SERVER_USER = 'Admin'
-- Instance Values
DCS_HOST = '127.0.0.1'
DCS_PORT = 6666
STATISTICS = true           -- true = enable user statistics
MISSION_STATISTICS = true -- true = enable mission statistics
COALITIONS = false           -- true = enable coalitions
CHAT_CHANNEL = '1065304278194999356'   -- In-game chat will be replicated here
STATUS_CHANNEL = '1065304318690983956'   -- a persistent server and players status will be presented here
ADMIN_CHANNEL = '1065304424873992222'   -- admin commands can be fired here
MESSAGE_PLAYER_USERNAME = 'Your player name contains invalid characters. Please change your name to join our server.'
MESSAGE_PLAYER_DEFAULT_USERNAME = 'Please change your default player name at the top right of the multiplayer selection list to an individual one!'
MESSAGE_BAN = 'You are banned from this server. Reason: {}'
MESSAGE_SLOT_SPAMMING = 'You have been kicked for slot spamming!'

However DCSServerBot never finds out that the server started successfully, even though it did. When I restart DCSServerBot while DCS is running, I get the following:

2023-06-27 21:05:21.173 INFO    - Registering Discord Commands (this might take a bit) ...
2023-06-27 21:05:21.376 INFO    - Discord Commands registered.
2023-06-27 21:05:21.391 INFO    - Searching for running DCS servers (this might take a bit) ...
2023-06-27 21:05:24.407 INFO    - No running servers found.
2023-06-27 21:05:24.407 INFO    DCSServerBot started, accepting commands.

in dcsserverbot.ini I have this:

[DCS.openbeta_server]
DCS_HOST = 127.0.0.1
DCS_PORT = 6666
DCS_HOME = c:\\Users\\User\\Saved Games\\DCS.openbeta_server
STATISTICS = true
MISSION_STATISTICS = true

There's no error messages in dcs.log

Any ideas what I could try? I also tried a different port for DCS_PORT, like 16666, but no joy.

Cant get the url to work with sneaker

I would like to use the rl option but so far I have had no luck.. instead I just loose access to the web UI all together unless I remove the Url out of the Node.yaml
I admit I'm new to this and it more then likley user error.
so here is what i got.
the example from the install.
Sneaker:
cmd: '%USERPROFILE%\Documents\GitHub\sneaker\sneaker.exe'
bind: 0.0.0.0:8080 # local listen configuration for sneaker
url: https://myfancyhost.com # optional: show a different host instead of the servers external IP

This i what I put into the My Nodes.yaml.

Sneaker:
cmd: C:\Users\jeste\Documents\GitHub\sneaker\sneaker-windows-amd64-v0.0.7.exe
bind: 0.0.0.0:10350 # local listen configuration for sneaker
url: http://live.hunterbattleground.com # optional: show a different host instead of the servers external IP

I'm I missing something of missing a step? Because when i make the URL blank it works fine.. but shows my IP address..
any help would be great..
and to answer anything like so i have web hosting on the server.. no .. no other programs are involved just Sneaker DCSserverbot and of course DCS.
Till then awesome program.. I using most of the add-ons and plug ins.. and i lost how it works with discord!
FYI I also try DCSbattleground.. no not at the same time.. but it was the same problem.
so i want back to sneaker with no url to get it to work.
Thanks in advance! O yes the 10350 port is opened and the 8080 port too.. i been trying anything i can think of.

Single DCS Instance

Is it possible to use only one DCS World Server instance and have multiple servers running only one installation and different SavedGames folders ?
When I starting configure multiple servers dcsserverbot.ini file - bot responds

DCSServerBot
БОТ
 — Сегодня, в 11:56
@DCS Admin Can't reach server "ICS Vortex Test" for more than 3 minutes. Creating minidump and killing ...
Latest dcs-<timestamp>.log can be pulled with .download
If the scheduler is configured for this server, it will relaunch it automatically.

and kills running DCS instance.

image

Pretense

Pretense not supported with MIZedit ?for realweather

Suggestion: .restart command communication

When in Discord, sending a '.restart message here' - all that appears in DCS is "message here", while the Discord feedback says "Restarting mission in 2 mins ...". This can be misleading. Suggestion is to communicate to DCS that there's 2 minutes remaining, as that is what really matters - info to the pilots.. Also, suggestion to add a parameter for how many minutes until restart (can still have a default of 2 mins or whatnot).

Current default that is sent to DCS chat is "!!! Server is going DOWN for REBOOT in 2 mins !!!". This only happens if the Discord command is '.restart' without anything else.

V 2.5.2

Bot Version - Dev 2.5.2 | Py 3.8

Traceback (most recent call last):
  File "C:\Users\Administrator\Desktop\DCSServerBot-development\core\__init__.py", line 1, in <module>
    from .bot import *
  File "C:\Users\Administrator\Desktop\DCSServerBot-development\core\bot.py", line 12, in <module>
    from .listener import EventListener
  File "C:\Users\Administrator\Desktop\DCSServerBot-development\core\listener.py", line 6, in <module>
    class EventListener:
  File "C:\Users\Administrator\Desktop\DCSServerBot-development\core\listener.py", line 18, in EventListener
    async def processEvent(self, data: dict[str, Union[str, int]]) -> None:
TypeError: 'type' object is not subscriptable

Error

Traceback (most recent call last):
  File "C:\Users\Administrator\Desktop\DCSServerBot-2.2.0\cogs\agent.py", line 158, in init
    if (('AUTOSTART_DCS' in self.bot.config[installation]) and (self.bot.config.getboolean(installation, 'AUTOSTART_DCS') is True)):
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\configparser.py", line 960, in __getitem__
    raise KeyError(key)
KeyError: 'caucaso'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Administrator\Desktop\DCSServerBot-2.2.0\cogs\agent.py", line 164, in init
    if (('AUTOSTART_SRS' in self.bot.config[installation]) and (self.bot.config.getboolean(installation, 'AUTOSTART_SRS') is True)):
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\configparser.py", line 960, in __getitem__
    raise KeyError(key)
KeyError: 'caucaso'

Chat from DCS allies to Discord issue

When a player seated in an aircraft in DCS chats to "allies", it is not reflected in Discord.

Example:
image

All lines, except 3rd ("hi from allies) was sent to all. Those were all seen in discord, except "hi from allies":

image

Problem with install

Hey! Im stuck in install. I ave installed python 3.11 32bit, postgresql, git. When i try to run install.cmd from bot folder i get this:
Traceback (most recent call last):
File "C:\Users\serwer\DCSServerBot\install.py", line 5, in
import psycopg
ModuleNotFoundError: No module named 'psycopg'
Please press any key to continue...

iI have already installed psycopg with pip command
C:\Users\serwer>pip install psycopg
Collecting psycopg
Downloading psycopg-3.1.17-py3-none-any.whl (178 kB)
---------------------------------------- 178.0/178.0 kB 2.7 MB/s eta 0:00:00
Collecting typing-extensions>=4.1
Downloading typing_extensions-4.9.0-py3-none-any.whl (32 kB)
Collecting tzdata
Downloading tzdata-2023.4-py2.py3-none-any.whl (346 kB)
---------------------------------------- 346.6/346.6 kB 5.4 MB/s eta 0:00:00
Installing collected packages: tzdata, typing-extensions, psycopg
Successfully installed psycopg-3.1.17 typing-extensions-4.9.0 tzdata-2023.4

but problem persist.
Any ideas what im doing wrong?

Add Weather preset info to the preset.yaml?

This is what I have found and it would be useful to have either in the documentation or the .yaml file itself, to figure out what the weather presets are and what they are called, at a glance.

############################################################################
################### HERE BELOW FOR THE WEATHER PRESETS #####################
############################################################################

## Link to the forum post https://forum.dcs.world/topic/272828-cloud-presets-what-are-the-notations-below-the-pictures-of-the-clouds/?do=findComment&comment=4679524


# Preset1
# Description: Light Scattered 1
# Few Scattered Clouds \nMETAR:FEW/SCT 7/8
# 
# Preset2
# Description: Light Scattered 2
# Two Layers Few and Scattered \nMETAR:FEW/SCT 8/10 SCT 23/24
# 
# Preset3
# Description: High Scattered 1
# Two Layer Scattered \nMETAR:SCT 8/9 FEW 21
# 
# Preset4
# Description: High Scattered 2
# Two Layer Scattered \nMETAR:SCT 8/10 FEW/SCT 24/26
#
# Preset5
# Description: Scattered 1
# Three Layer High altitude Scattered \nMETAR:SCT 14/17 FEW 27/29 BKN 40
# 
# Preset6
# Description: Scattered 2
# One Layer Scattered/Broken \nMETAR:SCT/BKN 8/10 FEW 40
# 
# Preset7
# Description: Scattered 3
# Two Layer Scattered/Broken \nMETAR:BKN 7.5/12 SCT/BKN 21/23 SCT 40
#
# Preset8
# Description: High Scattered 3
# Two Layer Scattered/Broken High Altitude \nMETAR:SCT/BKN 18/20 FEW 36/38 FEW 40
# 
# Preset9
# Description: Scattered 4
# Two Layer Broken/Scattered \nMETAR:BKN 7.5/10 SCT 20/22 FEW41
# 
# Preset10
# Description: Scattered 5
# Two Layers Scattered Large Thick Clouds  \nMETAR:SCT/BKN 18/20 FEW36/38 FEW 40
# 
# Preset11
# Description: Scattered 6
# Two Layers Scattered Large Clouds High Ceiling \nMETAR:BKN 18/20 BKN 32/33 FEW 41
# 
# Preset12
# Description: Scattered 7
# Two Layers Scattered Large Clouds High Ceiling \nMETAR:BKN 12/14 SCT 22/23 FEW 41
# 
# Preset13
# Description: Broken 1
# Two Layers Broken Clouds \nMETAR:BKN 12/14 BKN 26/28 FEW 41
# 
# Preset14
# Description: Broken 2
# Broken Thick Low Layer with Few High Layer\nMETAR:BKN LYR 7/16 FEW 41
# 
# Preset15
# Description: Broken 3
# Two Layers Broken Large Clouds \nMETAR:SCT/BKN 14/18 BKN 24/27 FEW 40
# 
# Preset16
# Description: Broken 4
# Two Layers Broken Large Clouds \nMETAR:BKN 14/18 BKN 28/30 FEW 40
# 
# Preset17
# Description: Broken 5
# Three Layers Broken/Overcast \nMETAR:BKN/OVC LYR 7/13 20/22 32/34
# 
# Preset18
# Description: Broken 6
# Three Layers Broken/Overcast \nMETAR:BKN/OVC LYR 13/15 25/29 38/41
# 
# Preset19
# Description: Broken 7
# Three Layers Overcast At Low Level \nMETAR:OVC 9/16 BKN/OVC LYR 23/24 31/33
# 
# Preset20
# Description: Broken 8
# Three Layers Overcast Low Level \nMETAR:BKN/OVC 13/18 BKN 28/30 SCT FEW 38
# 
# Preset21
# Description: Overcast 1
# Overcast low level \nMETAR:BKN/OVC LYR 7/8 17/19
# 
# Preset22
# Description: Overcast 2
# Overcast low Level \nMETAR:BKN LYR 7/10 17/20
# 
# Preset23
# Description: Overcast 3
# Three Layer Broken Low Level Scattered High \nMETAR:BKN LYR 11/14 18/25 SCT 32/35
# 
# Preset24
# Description: Overcast 4
# Three Layer Overcast \nMETAR:BKN/OVC 3/7 17/22 BKN 34
# 
# Preset25
# Description: Overcast 5
# Three Layer Overcast \nMETAR:OVC LYR 12/14 22/25 40/42
# 
# Preset26
# Description: Overcast 6
# Three Layer Overcast \nMETAR:OVC 9/15 BKN 23/25 SCT 32
# 
# Preset27
# Description: Overcast 7
# Three Layer Overcast \nMETAR:OVC 8/15 SCT/BKN 25/26 34/36
# 
# RainyPreset1
# Description: Overcast And Rain 1
# Overcast with Rain \nMETAR:VIS 3-5KM RA OVC 3/15 28/30 FEW 40
# 
# RainyPreset2
# Description: Overcast And Rain 2
# Overcast with Rain \nMETAR:VIS 1-5KM RA BKN/OVC 3/11 SCT 18/29 FEW 40
# 
# RainyPreset3
# Description: Overcast And Rain 3
# Overcast with Rain \nMETAR:VIS 3-5KM RA OVC LYR 6/18 19/21 SCT 34

Music service/plugin not working

Hello
i got the following error
ERROR 'NoneType' object is not subscriptable
Traceback (most recent call last):
File "C:\DCSServerBot\core\listener.py", line 127, in processEvent
await self.events[name](self, server, data)
File "C:\DCSServerBot\core\listener.py", line 36, in call
await self.callback(listener, server, data)
File "C:\DCSServerBot\plugins\music\listener.py", line 15, in registerDCSServer
await self.service.init_radios(server=server)
File "C:\DCSServerBot\services\music\service.py", line 66, in init_radios
radio: Radio = getattr(sys.modules['services.music.radios'], config['type'])(name=name, server=server)
~~~~~~^^^^^^^^

i found small issue with music plugin plugins\music\listener.py
it seems that it needs to add some space for all lines containing server=server to server = server

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.