Thank you for contributing to this project. All contributions are welcome. But for the sake of sanity, please follow the guidelines to contribute to Elite BGS.
Elite BGS requires a few things to get going:
- Git and Github account
- A recent Node.js LTS version, v12.18.2 (Erbium) and above
- MongoDB 4.0 and above
- Redis 6.2 (stable) and above
- Configure secrets for
frontend,backend,eddn_listener,guild_botandtick_listener - A Discord account for OAuth authentication (required) and a Discord "guild" (server) if
guild_botis required
On the server or development workstation, Node.js, MongoDB, and Redis must be installed and correctly working. Otherwise, these instructions may fail. If you develop on Windows, you will need to install Redis in Windows Subsystem For Linux (WSL2), a Docker container, or a virtual machine, as there are no current native Windows ports.
Documentation to serve the frontend application scalably in production is not yet available. Documentation updates on how to do this on a single host or within a Dockerized environment such as Google Cloud Platform or Kubernetes are most welcome.
See below on how to contribute using branches and pull requests.
- An IDE or code editor is highly recommended, preferably with Node.js integration and debugger
- GitHub Desktop can make working with GitHub a lot easier on Windows or Mac platforms
guild_botto send Elite BGS admin notifications to Discord- A Bugsnag account and API token if you want crash reporting and analysis
Download the latest stable version of Node.js for your platform, and let it install. After installation, restart your terminal or PowerShell window to ensure that Node.js is now on the default path and check that both these commands work:
foo@bar:~$ node -v
v12.18.2
foo@bar:~$ npm -v
6.14.4Update npm:
foo@bar:~$ npm update- Install MongoDB, and use the default port 27017
- Enabling access control is essential for production environments and optional for development environments.
- Create a database in the MongoDB instance,
elite_bgscontaining a single collection calledconfigs - Add a single document in the
configscollection with the following data:
{
"time_offset" : 60000,
"guild_id" : "",
"admin_channel_id" : "",
"user_role_id" : "",
"blacklisted_software" : [],
"version_software" : [],
"whitelisted_software" : []
}-
time_offsetis an integer, whereeddn_listenerwill reject records older than that many milliseconds -
guild_idIf using Discord admin notifications, your guild (server) ID, otherwise blank -
admin_channel_idIf using Discord admin notifications, the channel ID you'd like Elite BGS admin notifications, otherwise blank -
user_role_idIf using Discord admin notifications, the Discord role ID that Elite BGS admin notifications should use, otherwise blank -
blacklisted_softwareis an array of software that cannot submit data to Elite BGS. Example format (the apps may or may not be harmful, just an example):{ ... "blacklisted_software" : [ "^ed-ibe (api)$", "^ed central production server$", "^eliteocr$", "^regulatednoise__dj$", "^ocellus - elite: dangerous assistant$", "^eva" ], ... } -
version_softwareis an array of software that is too old to submit data to Elite BGS. Example format:
{
...
"version_software" : [
{
"name" : "E:D Market Connector [Windows]",
"version" : "2.4.2.0"
},
{
"name" : "E:D Market Connector [Linux]",
"version" : "2.4.2.0"
}
]
}-
whitelisted_softwareis an array of the only softwares that can submit data to Elite BGS. Example format (the apps are trusted, just an example):{ ... "whitelisted_software" : [ "^E:D Market Connector.*$", "^edd$" ], ... }
If you're not going to use blacklisted software in your testing, you can leave blacklisted_software, version_software and whitelisted_software as empty arrays as in the first definition.
For Linux systems, follow the instructions at https://redis.io/download and install the most recent stable Redis on your system. Make sure it is enabled and started:
On most system.d based Linux flavors:
foo@bar:~$ sudo systemctl enable redis.service
foo@bar:~$ sudo systemctl start redis.serviceThat's it. Redis has no configuration. As Redis, by default, has no authentication or access control, please do not allow it to listen on a port open to the Internet.
Installing on Windows requires installing the Windows Subsystem for Linux or using a Docker Redis container. We recommend the Debian WSL2 version, as it's probably the easiest to get going, but if you already have Docker running, that works. WSL2 installs Debian by default, so follow those instructions to get Redis running.
Building Elite BGS is relatively straightforward if taken step by step. Being a more extensive app split into five parts, there's a bit more work than a typical demo or a smaller application.
foo@bar:~$ git clone git@github.com:[your-username]/elitebgs.gitThere are five major components to Elite BGS:
backendis the Elite BGS RESTful API Server and is written in Node.js, Express, Redis, and MongoDB. Backend is read-only; it relies upon other servers to update MongoDB collections.eddn_listenerlistens to the EDDN firehose via a socket. It parses messages it is interested in and stores them in various MongoDB collections. It will throw errors if it sees records it doesn't necessarily care about, but these are warnings and not fatalfrontendis an Angular application written in TypeScript that is the user interface that most users are familiar with.guild_botis a Node.js application that provides admin notifications to a Discord server run by you, an Elite BGS administrator. This is not BGS Bot - that's an entirely different project.tick_listeneris a small node.js application that watches for ticks from Cmdr Phelbore's tick service. In the future, this code will likely adopt Cmdr Phelbore's code, but for now, it relies upon monitoring a socket to determine when the tick occurs.
Let's first get all the dependencies needed to build and run the underlying servers that run Elite BGS installed.
foo@bar:~$ cd elitebgs
foo@bar:~$ cd backend
foo@bar:~$ npm i
foo@bar:~$ cd ../eddn_listener
foo@bar:~$ npm i
foo@bar:~$ cd ../frontend
foo@bar:~$ npm i
foo@bar:~$ cd ../guild_bot
foo@bar:~$ npm i
foo@bar:~$ cd ../tick_listener
foo@bar:~$ npm iPlease address any errors you see, such as installing missing node modules, such as say lodash or similar. This may happen when the code demands a module that is not yet in package.json, but is needed:
foo@bar:~$ npm install --save <module> This will include the package in package.json as well as install it locally. This should then allow a clean `npm i' with no errors. Please report missing packages as an issue.
The secrets file is used by all Elite BGS components, including the front end, but we need it mainly for the back end services.
Create a new secrets.js file for each service in their respective folders with the following lines:
"use strict";
// Authenticated MongoDB (not default, strongly recommended in prod). Comment out if not using authentication
module.exports.elite_bgs_db_user = "[username for elite_bgs db]";
module.exports.elite_bgs_db_pwd = "[password for elite_bgs db]";
module.exports.elite_bgs_db_url = "mongodb://localhost:27017/elite_bgs";
module.exports.bugsnag_use = [true/false];
module.exports.bugsnag_token = "[Bugsnag token for backend Express app]"; "use strict";
// Authenticated MongoDB (not default, strongly recommended in prod). Comment out if not using authentication
module.exports.elite_bgs_db_user = "[username for elite_bgs db]";
module.exports.elite_bgs_db_pwd = "[password for elite_bgs db]";
module.exports.elite_bgs_db_url = "mongodb://localhost:27017/elite_bgs";
module.exports.bugsnag_use = [true/false];
module.exports.bugsnag_token = "[Bugsnag token for eddn_listener Express app]"; "use strict";
// Authenticated MongoDB (not default, strongly recommended in prod). Comment out if not using authentication
module.exports.elite_bgs_db_user = "[username for elite_bgs db]";
module.exports.elite_bgs_db_pwd = "[password for elite_bgs db]";
module.exports.elite_bgs_db_url = "mongodb://localhost:27017/elite_bgs";
module.exports.bugsnag_token_angular = "[Bugsnag token for frontend Angular app]";
module.exports.bugsnag_token = "[Bugsnag token for frontend Express app]";
module.exports.bugsnag_sourcemap_send = [true/false];
module.exports.bugsnag_use = [true/false];
module.exports.session_secret = "[a secret for express-session]";
module.exports.client_id = "[Discord API client id]";
module.exports.client_secret = "[Discord API client secret]";
// Change the port to 4013 (or any other configured port) when running production
module.exports.discord_use = [true/false];
module.exports.companion_bot_endpoint = "http://localhost:3013" "use strict";
// Authenticated MongoDB (not default, strongly recommended in prod). Comment out if not using authentication
module.exports.elite_bgs_db_user = "[username for elite_bgs db]";
module.exports.elite_bgs_db_pwd = "[password for elite_bgs db]";
module.exports.elite_bgs_db_url = "mongodb://localhost:27017/elite_bgs";
module.exports.discord_token = "[Discord bot token]";
module.exports.bugsnag_use = [true/false];
module.exports.bugsnag_token = "[Bugsnag token for backend express app]"; "use strict";
// Authenticated MongoDB (not default, strongly recommended in prod). Comment out if not using authentication
module.exports.elite_bgs_db_user = "[username for elite_bgs db]";
module.exports.elite_bgs_db_pwd = "[password for elite_bgs db]";
module.exports.elite_bgs_db_url = "mongodb://localhost:27017/elite_bgs";
module.exports.bugsnag_use = [true/false];
module.exports.bugsnag_token = "[Bugsnag token for backend express app]";elite_bgs_db_userif you have set up MongoDB access control (mandatory in production environments), the username for the elite_bgs collection, or blank in developmentelite_bgs_db_pwdif you have set up MongoDB access control (mandatory in production environments), the password for the elite_bgs collection, or blank in developmentelite_bgs_db_urlElite BGS assumes a local MongoDB installation on port 27017. Change this if you have a cloud or different MongoDB configurationsession_secretis a random value. Create a random password using a password generator. Please don't change it, or your users will need to log in againdiscord_useenables Discordguild_botintegration if set to true, set to false otherwiseclient_idis your application's Discord Client ID - this CANNOT be blank. See next sectionclient_secretis your application's Discord Client Secret - this CANNOT be blank. See next sectiondiscord_tokenis the bot public key.companion_bot_endpointis the endpoint where theguild_botis running. Default dev port is3013and prod port is4013bugsnag_useenables BugSnag if set to true, set to false otherwisebugsnag_tokenis your BugSnag API key for each Express app. Please don't set it ifbugsnag_useisfalsebugsnag_token_angularis your BugSnag API key for the Angular app. Please don't set it ifbugsnag_useisfalsebugsnag_sourcemap_sendwill send sourcemaps of the built files to BugSnag if set to true. Set it false if you don't want this
NB: Although MongoDB access control is strongly recommended, MongoDB has significant password composition limitations. We suggest a long random alphanumeric password rather than a highly complex password because many punctuation characters, including ; are not valid MongoDB passwords.
Elite BGS frontend requires a valid oAuth2 redirect URL for your Discord server to be set up, allowing the frontend application to authenticate clients with Discord. Without OAuth URL redirection, Elite BGS frontend will not run.
- Enable Discord developer mode
- Login to the Discord Developer Portal Application
- Click Applications > New Application
Call it something like "elitebgs-dev" or similar for development, and whatever you like in Production
- Navigate Developer Dashboard > Applications >
elitebgs-dev> OAuth2 - Click "Add Redirect" and use
http://localhost:3014/auth/discord/callbackfor development, orhttps://<yourElite BGSUrl>/auth/discord/callbackfor production - Grab the client ID next on the oAuth page, and add it to
module.exports.client_idinsecrets.js
Reference for creating Discord applications
Security notice: Do not add or commit secrets.js or your client ID to Git.
The front end is a bit more complicated than the other Elite BGS components, which can quickly be started after installing the necessary node modules. The frontend code must be built at least once by hand to get past an interactive question, and it relies upon Angular and TypeScript to be installed, so we must get those installed the first time we build the app.
Ensure the same secrets.js file installed above is at frontend/secrets.js. This is used to run a small node.js server used by the front end code for Discord oAuth integration and other frontend-y stuff.
Create a file called frontend/src/secrets.ts (should be at the same level as main.ts), which will contain all the secret tokens used by the Angular frontend. These include a random secret for the router (not currently used) and your private BugSnag API key.
The new secrets.ts file needs to have the following content:
class Bugsnag {
public static readonly token: string = '[Bugsnag token for frontend angular app]';
public static readonly use: boolean = [true/false]
}
export { Bugsnag };usewhen true enables BugSnag. Set it tofalseif not neededtokenis an optional BugSnag token. Please don't set it ifuseisfalse
Security notice: Do not add or commit your secrets to Git.
frontend is an Angular application written in TypeScript, and it needs to be transpiled into browser-friendly code. To do this, we first install Angular CLI and TypeScript command line tools, which the build process uses, and then build the code:
foo@bar:~$ cd elitebgs/frontend
foo@bar:~$ npm install -g @angular/cli typescript
foo@bar:~$ ng -v
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI: 10.2.2
Node: 12.16.3
OS: win32 x64
Angular: 10.2.4
...
foo@bar:~$ tsc -v
Version 4.2.3If both ng and tsc work, we can go ahead and build frontend:
foo@bar:~$ npm run buildYou will see a prompt on your first compile:
? Would you like to share anonymous usage data about this project with the Angular Team at
Google under Google's Privacy Policy at https://policies.google.com/privacy? For more details and how to change this setting, see http://angular.io/analytics. [y/N]Opt-in or out as you wish, and it won't ask again, allowing nodemon to automatically work without further input during compilation, which can be a problem if you jump in and run startdev.
Please take care of any errors you see. Sometimes, two attempts are required to get a successful build. You may need to add more node modules locally to get it to build. In development, you will likely see warnings about the production environment not being used, and that's correct. Developers can generally ignore other alerts as long as the build succeeds. Feel free to submit a pull request to fix or address these warnings.
Elite BGS has two optional integrations, guild_bot to send admin notifications via Discord and a commercial monitoring platform called BugSnag to capture and analyze errors.
Elite BGS guild_bot can send admin notifications to a Discord server, also known as a guild. Elite BGS frontend uses Discord for OAuth authentication but doesn't need guild_bot 's optional integration to function, and guild_bot doesn't rely upon the oAuth redirection URL to work - they are separate and different. Elite BGS guild_bot is not BGS Bot, which provides Discord channel commands to provide information to factions.
If you want to get admin notification via guild_bot:
- In
frontend/secrets.js, setdiscord_usetotrueandcompanion_bot_endpointto the endpoint where theguild_botserver is running (defaulthttp://localhost:3013) - Navigate to Discord's Application Dashboard >
elitebgs-devorwhatever> General Information - Copy Client ID to
client_id, Client Secret toclient_secret, and Public Key todiscord_tokenin secrets.js - In MongoDB, change the following values in the configs collection:
guild_idThe guild (server) IDadmin_channel_idThe channel ID you'd like Elite BGS admin notificationsuser_role_idThe Discord role ID that Elite BGS admin notifications should use. @everyone is fine, but you may wish to use something custom, such as write only permissions.
If you don't want to use Discord:
- In
frontend/secrets.js, setdiscord_usetofalse.companion_bot_endpointcan be left blank andguild_botservice need not be started - In MongoDB set
guild_id,admin_channel_id,user_role_idto blank in the configs collection.
Security notice: Do not add or commit your secrets to Git.
BugSnag is an error capture and analysis platform. This is great for production, but as you have access to errors in the console, it's unnecessary for development unless you're testing BugSnag integration or fixing issues with BugSnag. If you are using the free Lite tier, it has limited events per day. If you are in development mode, consider only using BugSnag integration if you intend to work on or test BugSnag related functionality.
If you want to use BugSnag, create a BugSnag account, then an application, and obtain the application's API key.
You should create a separate application for each service. Also, the Express app in frontend should be a separate application from the Angular app.
In each secrets.js file in backend, eddn_listener, frontend, guild_bot, and tick_detector
- set
bugsnag_usetotrue - set
bugsnag_tokento your BugSnag application API key
Additionally in frontend/secrets.js
- set
bugsnag_sourcemap_sendtotrue - set
bugsnag_token_angularto your BugSnag application API key generated for the Angular application
Additionally in frontend/src/secrets.ts
- set
Bugsnag.usetotrue, andBugsnag.tokento your BugSnag application API key
If you don't want to use BugSnag, and rely on the console or your debugger instead:
In each secrets.js file in backend, eddn_listener, frontend, guild_bot, and tick_detector
- set
bugsnag_usetotrueand omit all otherbugsnag_properties - In
frontend/src/secrets.ts, setBugsnag.usetofalse, and omitBugsnag.token
Security notice: Do not add or commit your secrets to Git.
As Elite BGS is split into five parts, the following default HTTP ports are used:
| Service | Prod | Dev | Debug |
|---|---|---|---|
| backend API | 4010 | 3010 | 9029 |
| eddn_listener | 4011 | 3011 | 9129 |
| tick_listener | 4012 | 3012 | 9229 |
| guild_bot | 4013 | 3013 | 9329 |
| frontend app + accompanying backend | 4014 | 3014 | 9429 |
If you've read this far, you're likely to be developing Elite BGS or want to run your custom version. Developers can start development mode in their IDE, via the command line, or within a debugger like this:
foo@bar:~$ cd elitebgs
foo@bar:~$ npm run startdev # starts all five servers at onceYou can also run an individual service:
foo@bar:~$ cd elitebgs/backend
foo@bar:~$ npm run startdev # starts just backendYou can also use your IDE to navigate to package.json and configure, run, or debug a script target, which gives you great control over the development process.
To execute the project in production mode:
Ensure you have the correct URL in frontend/processVars.js, as otherwise the internal links within the application will not work, or will redirect the user to the main production site:
} else if (process.env.NODE_ENV === 'production') {
host = 'elitebgs.app'; // CHANGE ME
protocol = 'https';
} foo@bar:~$ cd elitebgs
foo@bar:~$ npm run start # starts all production instancesReview the HTTP ports above to connect to the Elite BGS front end or set up a port forwarding or caching configuration to scale and serve many clients.
You will need to establish a TLS listener and, if very busy, a load balancer, such as via a cloud router or Nginx or Apache Reverse Proxy, and ensure that your URL's DNS servers point to your server and the URL you have chosen.
Elite BGS is an open-source project and relies upon contributors such as yourself fixing issues or creating new features for the benefit of all. Elite BGS follows standard GitHub industry practices, including that new fixes or features should be in their branch and committed via a pull request. GitHub has many excellent articles on how to install and get going with pull requests and branches.
Find an issue you want to fix or enhance, and let folks know that you want to work on it. Create a new branch for your issue or enhancement:
git checkout -b [name-of-your-new-branch]
After you have made the necessary changes and committed them, push them to your forked repository. Then create a pull request to the master base branch.
I will review the PR and might ask to make changes before accepting them.