Manual
Intro
Carsa's Companion is a website used to supplement and improve Carsa's Commands (a management addon for Stormworks: Build and Rescue). It allows an easier to use and visual way to use the functions offered by the management addon (which normally only works via chat messages). The Companion relies on the logic, data and permission system of the management addon which runs in the game.
If you are short on time, use the Quickstart Guide.
Features
The companion allows access to all the management addon functionality in a visual and interactive way. On top of the already existing functionality, the companion offers additional functions:
- Allow access to all management addon functions without the need to run the game and be connected to the game server
- Change game settings
- Show a live map of players and vehicles on a 2D map that matches the ingame seed
- Start / Stop a dedicated Stormworks server via the companion and see the console output of the executable
Manual Sections
This manual is split into several sections:
For Users | for people that play on the server |
For Admins / Owners | for people that run and administrate the server |
For Developers | for people that want to change the code of this program |
Information on privacy and data visibility
Data that is available / visible on the website of this program is the same as the data available / visible when you connect to the game server via Stormworks: Build and Rescue
. This includes (amongst others) the player names, their steamid, chat messages.
Additionally, in order to detect the public IP of the companion server, an external service (run by CrazyFluffyPony, one of the authors of this program) will be contacted. No data is being shared with this service, the service only uses the anonymized request to count how many times the program has been started in order to know if the program is being used and deserves updates and new features.
Quickstart Guide
- Download the executable here
- Place it in a folder you like (e.g.
Desktop/C2-Companion ) - Run executable (double click)
- Open this URL in your browser: http://localhost:3366/
- Read through the section Customizable setings.
- Go to
settings and adjust the settings to your liking - Enable the companion in the game: Enter into the chat:
?setPref companion true
For Users
Permissions / Who can do what
Permissions depend on the roles you have in the game (special case: if you access the website from a browser on the same machine this webserver is running on: localhost). Those permissions will be the same in the companion. A user that has the permision to kick via
For the additional functions of the companion the permissions work as follows:
Not logged in user | ||||||||||||
Logged in user (without Owner role) | ||||||||||||
Owner | ||||||||||||
localhost |
Pages
Home
Shows version information and includes important links.
Players
Shows a list of players. Users that have the necessary permisions can kick/ban or change the roles of those players.
Vehicles
Shows a list of vehicles. Users that have the necessary permisions can despawn those vehicles.
Roles
Manage roles: Add, delete, change members, access to commands and permissions of each role.
Rules
Manage rules: Add, delete, change.
Preferences
Change Carsa's Commands preferences.
Game Settings
Change game settings (from custom menu in the game).
Chat
Shows the chat from the server and allows to send chat messages (both only when logged in).
Logs
Shows Carsa's Commands logs from the server (only the ones generated while the companion website is visited).
Settings
Change Webserver Settings (for the companion Webserver). Read more here.
Map
Show the map (Matches game seed). Shows current players and vehicles (live). Players can be kicked/banned and vehicles can be despawned by clicking on their markers.
GameServer Management
Start and stop the dedicated gameserver executable and view its console output.
Tests (must be enabled in settings)
Allows to remotely enable debugging of Carsa's Commands, allows to run some connectivity and performance tests, allows to test several UI components. Read more here.
For Admins / Owners
Customizable Settings
By default, the companion is only accessible on the local network (e.g. your LAN and WLAN network at home). With some simple clicks on the
- Who has access to the companion (only the same computer and computers in the same network, or everyone from the internet). For everyone read more here.
- If users can see the live map (the owner can always see it)
- The filepath to the dedicated server executable (required if you want to start / stop the Stormworks server via the companion)
If you want players to receive the companion welcome message (read more below) when the join the game, enable the preference companionInfoOnJoin
on the
Security
The code for the executable that runs the companion is open source, you can check it for errors and build the executables yourself (see readme). The code uses a minimal amount of third party libraries, all served as a static copy within the git repository. The code was written to have minimal functionality outside of the Stormworks game (only read and write some log files and a settings file, only able to start and terminate an executable specified by the owner of the machine). Two seperate Webservers are used for the website and the connection to the game to further sandbox functionality. The creator of the code has followed best practices (e.g. OWASP) to keep risks as low as possible. If you find any problems, we are happy to contact us, create an issue or even a pull request with a fix.
In terms of permissions in the game, the companion relies 100% on the management addon (the only exception is a browser on the same machine who is allowed to change settings of only the companion). In order to identify players and their permissions, a player can obtain a unique token while writing into the chat in the game (only needs to be done once). Tokens are random enough to prevent being guessed, additionally, logins are rate-limited to prevent a brute force attack.
How to report errors
If you find any errors, please contact us or create an issue. Do not forget to include the logs:
- for the companion website, either an error popup includes the log message, or you go to the
home go to the sectionHelp
and clickExport Logs - for the companion server itself, go to the folder where it is located and take the file
log.txt
How to debug or test
If you are interested in debugging or testing yourself, go to the enable-test-mode
setting. This will allow you to access the X
stands for a log level:
1 | show errors |
2 | + show warnings |
3 | + show infos |
4 | + show logs |
5 | + show debugs |
Allowing external access to companion
allow-external-accesson
If you run the companion on your PC (e.g. behind a router in your home network) you need to enable port forwarding in your routers settings if you want others on the internet to access the companion website.
You must forward the following ports (if you use a different incoming port then some links might not work):
3366 | TCP |
3367 | TCP |
For Developers
This is meant for people who want to change the source code of this program. We would like to document this even better, but time is limited, especially for a hobby project.
Favorable Skills
These skills / knowledges are not 100% required, but definitely helpful and might sometimes be mandatory to understand what is going on.
- HTTP
- HTML5
- JavaScript ES6
- CSS (SASS / Compass)
- git
Tech Stack
Backend | ||
Node.js | JavaScript runtime (server) | |
Express (Node.js) | Webserver framework (Basic Webserver) | |
Handlebars | Templating Framework (Assemble page HTML) | |
Compass | CSS Framework (Assemble CSS) | |
Frontend | ||
Vue.js | User Interface Framework (Single Page Application) | |
Vuex | State Management Library for Vue.js (Central Datastorage) | |
jQuery | JavaScript Library (Utility) | |
WebSocket | Real-Time Communication (Two-Way Server-Client Communication) |
Setup build tools
- if you are on windows you will need a command line tool, i suggest the official one from git: gitforwindows.org/
- install node (e.g. v16) nodejs.org
- install compass (use git bash for this):
$ gem install compass - install nodemon (use git bash for this):
$ npm install -g nodemon
Nodemon is optional, but it will automatically restart the server when any source file loaded and make your life easier.
git hooks for versioning
After you cloned this repository, run commit.txt
to be the current commit hash. You can also trigger it manually by doing a checkout on the current select branch (e.g.
Coding
- command line tool 1 (e.g. git bash):
$ cd compass & compass watch - command line tool 2 (e.g. git bash):
$ nodemon or for debugging$ nodemon -- loglevel=3 (3 = info, 4 = log, 5= debug)
Upgrading the version
Just edit the file public_static/version.txt
Upgrading vue.js and vuex library
Visit https://unpkg.com/browse/vue@3.2.29/dist/ and select the most recent version. Download the vue.global.js
(for testing) or vue.global.prod.js
(for production). Replace /public_static/scripts/lib/vue.js
with whatever you downloaded.
Procedure is similar for vuex (https://unpkg.com/browse/vuex@4.0.2/dist/).
Updating manual
Simply edit manual.html
directly. All scripts, styles, images are included in this single file.
If you make any changes to the styling (inside compass/sass/manual.scss
) you must recompile the stylesheets (via compass), take the output from public_static/stylesheets/manual.css
and replace the
Creating executable
Install pkg:
run
The executables can be found in /dist
Update playlist.xml (locations) for the management addon (Carsa's companion)
For every map tile, we define a zone, which is required to show the tiles in the webclient live map at the right position. The ingame script finds all those zones and their positions. In case new tiles are added (game update), you need to update the playlist.xml (automated with a script of course).
After you did build the playlist.xml (see Readme of Carsas-CommandsV2) then you can run
The above command will read %appdata%/Roaming/Stormworks/data/missions/Carsa's Commands/playlist.xml
inject the env_mods/locations and write the ouput to %appdata%/Roaming/Stormworks/data/missions/Carsa's Commands/playlist_with_zones.xml
Now you have to replace the original playlist.xml
file with the playlist_with_zones.xml
file.
Folder Structure
.githooks | contains code that creates the file "public_static/commit.txt" with the current git commit hash |
build-tools | contains build tools and scripts |
c2 | contains source code for the Node.js webserver |
compass | contains source code of sass/compass that will later be compiled into css files |
dist | contains generated standalone executables |
node-modules | contains all the npm dependencies (as source code) |
public-static | contains files served by the webserver (as "/static/...") which are required for the website (including javascript files, compiled css, images, tile images, etc. |
views | contains handlebar templates for all the html pages |
app.js | the main server application file |
setup_git_hooks.sh | Used to setup githooks that create the "public_static/commit.txt" file |
Other files not mentioned in this table are either explained later, in the readme or are self explanatory.
Concepts
Message types
For the messages that are being sent from the Frontend: message types starting with command-
are always messages that are sent from the Frontend to the Game. All other messages that are being sent from the Frontend are only meant for the Backend and not forwarded to the Game.
For the messages that are being sent from the Game: message types starting with sync-
are messages containing data of syncables. Those will be forwarded to all clients. For other message types, individual rules apply. Sometimes, the message is only forwared to clients with certain permissions, ...
Syncables
Syncables are special data, both defined on the management addon and in the frontend code. The management addon will send those data updates when the data changes (and whenever a client connects freshly to the server). In the frontend, components that trigger a command (of the management addon) will often wait until a certain sync (defined per component) arrives. In the meanwhile, they will lock themselves so the user cannot try to trigger that command again before he is being displayed the new current state.
Message Flow
These are several examples for different variants of message flows. They should help you to understand the message/event oriented flow. Both the connection Webclient <-> Backend and Backend <-> Game are full duplex. Both sides can send messages. Each message contains an id (counted individual for every side). Every message requires a response (a message with the same individual id). This response can either be sent immediately (e.g. when Game sends request to backend) or asynchronously after some time (e.g. when Webclient sends command to backend and backend sends to game and then back the whole chain once the game triggers another HTTP request containing the response).
The duplex HTTP connection between Game and Backend is different from the duplex WebSocket connection between Frontend and Backend: The game can only send requests to the backend, but the backend cannot send requests to the game. Instead the backend has to wait for the game to do another request and then include its own request inside the response of that HTTP request. This means a bit of delay. To minimize this delay, the heartbeat happens very often. Every hearbeat (and every other request) the GameHTTPHandler checks if there is a message (from Backend to Game) in the queue, if so, it will add this message to the response. If there is still more messages in the clue, a flag will be set, that indicates the management addon to immediately start another HTTP request to pickup the other messages in the queue.
Game -> Backend
Example: Tokens
The management addon sends the current companion tokens of all players to the backend (initially and when a token changes or a new player joins). The ModuleCore registers a message handler for
Game -> Backend -> Frontend
Example: Heartbeat
The management addon sends a heartbeat (small message) that tells the backend the management addont is still running. The Backend will then forward this message to all webclients (currently only used for status bar blinking). The ModuleCore reigsters a message handler for
Backend -> Frontend
Example: Initial game connection state
When a new WebSocket connection is being opened in WebInterface, it dispatches an event, C2 listens to that event and sends a message to all webclients with the current connection state of the management addon.
Frontend -> Backend -> Frontend
Example: Server Settings
If a user changes a server setting on the
Frontend -> Backend -> Game -> Backend -> Frontend
Example: Kick Player
In the Frontend, the user clicks a button inside a component which triggers the kickPlayer
command. This also locks the button. The Frontend sends a message of type kickPlayer
command will listen to it and unlock itself.
Backend Code Structure
app.js
The main application file initializes the express webserver, sets up the routes and pages and loads the C2
code.
C2.js
This class loads all the modules and provides some APIs for them. Each module can use those APIs to send messages to either game or webclients, can register callbacks/handlers for specific message types from either the game or the webclients.
C2_ConsoleLogger.js
This class intercepts logs and writes them to the logfile.
C2_Utility.js
This class provides utility functions for logging and an event system.
C2GameHttpHandler.js
This class handles HTTP requests coming from the Stormworks game and request that other C2 code wants to send to the game. It is a seperate webserver that runs on a different port then the main webserver. This class handles new requests and responses to existing requests (full duplex system) but the basis is only HTTP requests coming from the Stormworks game (more precise: from the management addon). It is able to split huge messages into several parts and also merge back together those parts. If a the reponse to a request runs into a timeout, this class fails that request automatically. The class communicates with the management addon via JSON, the payload/data inside the JSON is always (this is different to the WebSocketHandler) a JSON string, which means JSOn will be parsed automatically. The payload/data will be forwarded to other parts of C2 code (e.g. as the response to an answer) as some kind of an object (Object, Array, string, boolean, whatever the JSON.parse() output is)!
C2GameInterface.js
This class is the streamlined connection between any C2 code and the GameHTTPHandler. It also detects wether the management addon is connected (using a heartbeat system).
C2WebSocketHandler.js
This class handles WebSocket connections and request coming from webclients as well as request that other C2 code wants to send to webclients. This class handles new requests and responses to existing requests (full duplex system). This class communicates with the webclients code via JSON, the payload/data inside the JSON is often a JSON string but does not have to. The payload/data will be forwarded to other parts of C2 code (e.g. as the response to an answer) as a string! The C2 code has to handle/parse the payload/data itself (if the payload/data is forwarded to the game, no parsing happens, since the parsing will happen in the game code).
C2WebInterface.js
This class is the streamlined connection between any C2 code and the WebSocketHTTPHandler.
C2GameWebServer.js
This class is responsible for the second webserver which is only responsible for accepting HTTP request from the Stormworks game (more precise: the management addon).
C2Module_Core.js
This class is responsible for setting up the core functionality:
- Backend permission management (filter data coming from game and sent to webclient, control access to webserver settings management)
- Version Checks
- Notifications for the user (not 100% implemented and only used for version checks)
- Rate-limit logins (via token)
- Relay commands between WebInterface <-> GameInterface
- Webserver settings management
C2Module_Map.js
This class is responsible for functionality around the
C2Module_Test.js
This class is responsible for functionality around the
C2Module_Gameserver.js
This class is responsible for managing the dedicated game server executable (Stormworks). It relays information between the WebInterface and the GameServerManager.
C2GameServerManager.js
This class is responsible of starting and stoping the game server executable. It utilizes GameServerProcess which is spawned as a child process and relays console output from that child process back to the Module_Gameserver. It also handles state events of the child process (e.g. errors, exit, etc). It also constantly checks if a process that matches the game server executable is currently running and can kill that process.
C2GameServerProcess.js
This class is responsible of spawning a cmd process that executes the game server executable. This cmd process is then able to continue running on its own (even if the companion application stops). This class also relays console output from the executable back to the GameServerManager.
Frontend Code Structure
C2.js
This class initializes Vue.js and the Vuex store. It provides an API for modules to register message callbacks/handlers, storables, syncables, components and pages and an API for showing notifications. Displays error popup as a fallback for Vue.js internal error handling (of the components themselves).
C2_ConsoleLogger.js
This class is responsible to intercept logs, cache them and later provide them for error messages displayed to the user.
C2_Utility.js
This class provides utility functions for logging and an event system. It also provides mixins components can use for logging, sending messages or commands. It also provides some basic components (e.g. lockables, extendables, buttons, icons, ...)
C2WebClient.js
This class is just a small wrapper for the WebSock. It takes care of converting data into lua format (undefined and null are converted into nil, an array is converted into a space seperated text (to represent an argument string)).
C2WebSock.js
This class provides functions to easily send messages and receive responses. It enhances the default WebSocket class by automatically trying to reconnect. It can also trigger the page reload, if the Backend requested a force reload (e.g. after server restart).
C2Module_Core.js
This class is responsible for setting up the core functionality
- Notifications
- Status bar
- Login and user state
home players vehicles roles rules preferences gamesettings logs chat settings
C2Module_Map.js
This class is responsible for the
C2Module_Test.js
This class is responsible for the
C2Module_Gameserver.js
This class is responsible for the