SRCDS integration with the webserver
Posted: Thu Jan 28, 2016 8:46 pm
Hey there.
Currently I'm implementing some of the features requested by cr4nkz and thought of his class-based buymenu idea.
We can't alter game's buymenu, but we can do radio popups or ESC menus. But what I decided to do is put buymenu in MOTD.
I once had MOTD used for filling ban reasons: http://i.imgur.com/lRJwwhi.png
Sequence of events is
Security of this approach can be improved by storing the secret salt in the database and changing it after every request.
MySQL database acts as a coordinator between website (MOTD) and gameserver. For filling out ban reasons post-factum this is more than enough.
But if we're talking about buymenu, any action (e.g. players clicks 'buy weapon' in MOTD) needs a response from the game server.
Approach #1. (dirty)
Still use MySQL as a coordinator. Website puts the data like 'player X bought weapon Y' to the database.
Game server either:
1. Checks the database every 5 seconds to see if there're any purchases made.
2. Checks the database as soon as the player closes their MOTD - we can detect that if player starts moving. If they start moving, check the database action queue and equip player with the weapons.
Disadvantages:
Database is not meant to be used this way, this approach is too hacky. Also requires database to be hosted somewhere.
Approach #2.
With the power of mighty Python open another TCP port on SRCDS and serve it for web. Then we can send MOTD with the following URL
Or, alternatively, open TCP port on SRCDS but hide it from web. Instead, serve the web with a web-server. The web-server then connects to SRCDS on every HTTP request to pass data to it.
Disadvantages:
SRCDS is not meant to be used this way. Then, any self-respectful game hosting will tell you what they think about you and your buymenu. So it still requires the server to be hosted somewhere serious, say, VPS.
Approach #3.
Create your own coordinator and connect SRCDS to it on a constant basis.
I see 3 ways of doing that:
1. Standalone buymenu server. SRCDS is connected to it (as a client) constantly through sockets. Webserver serves MOTD. Webserver connects to buymenu server on every HTTP request and exchanges data with buymenu server, then buymenu server exchanges data with SRCDS.
2. Standalone buymenu server. SRCDS is connected to it constantly through sockets. Buymenu server is open to the web and serves MOTD by itself. On every HTTP request it exchanges data with SRCDS.
3. Web-sockets web-server. SRCDS is connected to it constantly through web-sockets as one of the HTTP clients.
In all three cases the game server acts as a client, no need to open extra ports.
First one is more protected. Buymenu server is hidden from the web, all three servers (buymenu, web, game) can be located on the same machine. Webserver serves MOTD and basically does the job it's written for. Then you've got CloudFlare, all this stuff to protect you.
Second one is more flexible. For example, since we're basically writing our own hybrid web-server, we can do support for web-sockets thus allowing data to pass from the game server into the MOTD, too. Very important thing to understand that this buymenu server is meant to serve 64 players at best. Which are not a trouble. Until somebody decides to DDoS you.
Third one may sound as a good idea, but basically this is still about writing your own web-application from scratch. Both Apache and nginx are designed to work on per-request basis. CloudFlare is designed to work on per-request basis. And here instead of a script which runs on every HTTP request, you have script that's running indefinitely in a loop. I thought of nginx + uWSGI, but still, I see no benefits to using this way over the second one, because any web-designed DDoS-protection is not suitable in the case.
Disadvantages:
Requires either to host buymenu server (VPS) or finding a good web-hosting that would support web-sockets.
Thank you so much for reading. What do you guys think of these ways? I'm choosing between 3.1 and 3.2.
Currently I'm implementing some of the features requested by cr4nkz and thought of his class-based buymenu idea.
We can't alter game's buymenu, but we can do radio popups or ESC menus. But what I decided to do is put buymenu in MOTD.
I once had MOTD used for filling ban reasons: http://i.imgur.com/lRJwwhi.png
Sequence of events is
- Admin bans a player, game server puts the ban (with empty reason) in MySQL database. This database is shared between web- and game-server.
- Admin types !reason, server sends them MOTD with the following url:
Code: Select all
http://example.org/banlist/<admin steamid>/<admin auth string>/
<admin steamid> - admin Steam Community id
<admin auth string> - sha512(<constant secret salt> + <admin steamid>) - Website takes admin steamid that is received, calculates sha512(<same secret salt> + <admin steamid) on its own and compares result to the received auth string. If they're equal, this is a valid admin coming from our server. If not, somebody's being too smart.
- Website returns the page (you can see the screen above) with all registered bans for this admin, each ban has a field to edit the ban reason
- Admin fill the reason and clicks "Save". Form sends request to the same exact URL + additional POST data which contains the ban reason
- Website processes the URL once again, but this time saves received ban reason to the MySQL database.
- Website returns the page (something like "Success"), admin closes MOTD.
Security of this approach can be improved by storing the secret salt in the database and changing it after every request.
MySQL database acts as a coordinator between website (MOTD) and gameserver. For filling out ban reasons post-factum this is more than enough.
But if we're talking about buymenu, any action (e.g. players clicks 'buy weapon' in MOTD) needs a response from the game server.
Approach #1. (dirty)
Still use MySQL as a coordinator. Website puts the data like 'player X bought weapon Y' to the database.
Game server either:
1. Checks the database every 5 seconds to see if there're any purchases made.
2. Checks the database as soon as the player closes their MOTD - we can detect that if player starts moving. If they start moving, check the database action queue and equip player with the weapons.
Disadvantages:
Database is not meant to be used this way, this approach is too hacky. Also requires database to be hosted somewhere.
Approach #2.
With the power of mighty Python open another TCP port on SRCDS and serve it for web. Then we can send MOTD with the following URL
Code: Select all
http://<your server ip>:27080/buymenu/<player steamid>/<auth string>/
Or, alternatively, open TCP port on SRCDS but hide it from web. Instead, serve the web with a web-server. The web-server then connects to SRCDS on every HTTP request to pass data to it.
Disadvantages:
SRCDS is not meant to be used this way. Then, any self-respectful game hosting will tell you what they think about you and your buymenu. So it still requires the server to be hosted somewhere serious, say, VPS.
Approach #3.
Create your own coordinator and connect SRCDS to it on a constant basis.
I see 3 ways of doing that:
1. Standalone buymenu server. SRCDS is connected to it (as a client) constantly through sockets. Webserver serves MOTD. Webserver connects to buymenu server on every HTTP request and exchanges data with buymenu server, then buymenu server exchanges data with SRCDS.
2. Standalone buymenu server. SRCDS is connected to it constantly through sockets. Buymenu server is open to the web and serves MOTD by itself. On every HTTP request it exchanges data with SRCDS.
3. Web-sockets web-server. SRCDS is connected to it constantly through web-sockets as one of the HTTP clients.
In all three cases the game server acts as a client, no need to open extra ports.
First one is more protected. Buymenu server is hidden from the web, all three servers (buymenu, web, game) can be located on the same machine. Webserver serves MOTD and basically does the job it's written for. Then you've got CloudFlare, all this stuff to protect you.
Second one is more flexible. For example, since we're basically writing our own hybrid web-server, we can do support for web-sockets thus allowing data to pass from the game server into the MOTD, too. Very important thing to understand that this buymenu server is meant to serve 64 players at best. Which are not a trouble. Until somebody decides to DDoS you.
Third one may sound as a good idea, but basically this is still about writing your own web-application from scratch. Both Apache and nginx are designed to work on per-request basis. CloudFlare is designed to work on per-request basis. And here instead of a script which runs on every HTTP request, you have script that's running indefinitely in a loop. I thought of nginx + uWSGI, but still, I see no benefits to using this way over the second one, because any web-designed DDoS-protection is not suitable in the case.
Disadvantages:
Requires either to host buymenu server (VPS) or finding a good web-hosting that would support web-sockets.
Thank you so much for reading. What do you guys think of these ways? I'm choosing between 3.1 and 3.2.