Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[question] webserver #22

Open
gmodmurderserver opened this issue Nov 14, 2022 · 11 comments
Open

[question] webserver #22

gmodmurderserver opened this issue Nov 14, 2022 · 11 comments
Assignees
Labels
question Further information is requested

Comments

@gmodmurderserver
Copy link

how does one run a webserver when the server runs, so that this could work properly?

@brandonsturgeon
Copy link
Member

brandonsturgeon commented Nov 14, 2022

Great question!

I'm afraid it's a bit complicated. Our webserver setup is a proprietary system that lets us interact with our game servers from a web address.

If you wanted to mimic the web server portion for a specific server, ultimately you'll need a public endpoint that returns a json payload in the format of: { "server-is-up": true/false }.

One way of accomplishing this is using a language that has an rcon library available. You can use the rcon library to send a simple status command to your server, and if it replies, you can respond to the API caller with { "server-is-up": true }, if it times out or errors, you can respond with { "server-is-up": false }

Here's a simple (probably functional?) proof-of-concept:

# rcon_interface.py
# be sure to set the RCON_IP, RCON_PORT, and RCON_PASSWORD environment variables
import os
import valve.rcon

class RCONInterface:
    def __init__(self):
        self.set_rcon_credentials()

    def set_rcon_credentials(self):
        self.address = os.getenv("RCON_IP")
        self.port = os.getenv("RCON_PORT")
        self.password = os.getenv("RCON_PASSWORD")

    def issue_command(self, command):
        connection_address = (self.address, int(self.port))

        try:
            with valve.rcon.RCON(connection_address, self.password, timeout=5) as rcon:
                response = rcon(command)
                print("Rcon response:")
                print(response)

                if response:
                    return True, response

        except valve.rcon.RCONCommunicationError as socket_err:
            print(f"Hit a communication error when trying to issue: '{command}' to '{self.address}:{self.port}'")
            print(socket_err)

            return False, socket_err

        except valve.rcon.RCONTimeoutError as timeout_err:
            print(f"Hit a timeout error when trying to issue: '{command}' to '{self.address}:{self.port}'")
            print(timeout_err)

            return False, timeout_err

        except Exception as generic_err:
            print(f"Hit an unknown error when trying to issue: '{command}' to '{self.address}:{self.port}'")

            return False, generic_err

        print("No conditions met, assuming failure?")
        return False
# web.py
from rcon_interface.py import RCONInterface 
from flask import Flask
import time

app = Flask(__name__)
rcon = RCONInterface()

last_status = True
last_check = 0

@app.route("/ping")
def ping():
    # Cache the response for a few seconds so you're not sending tons of rcon requests
    if last_check > time.time() - 3:
        return { "server-is-up": last_status }

    is_up, err_message = rcon.issue_command("status")
    last_status = is_up
    last_check = time.time()

    return { "server-is-up": is_up }

You could deploy this script on the same host as the game server, or you could retrofit it to work in something like Amazon's AWS Lambda. If you know Javascript (or can be bothered to transpile to JS), you could use Cloudflare Workers, too.

Sorry this is a hassle. We had to make a generic solution for all of our game servers, and it's very specific to how we have things set up, so it wasn't made to be nicely shareable.

@brandonsturgeon brandonsturgeon added the question Further information is requested label Nov 14, 2022
@brandonsturgeon brandonsturgeon self-assigned this Nov 14, 2022
@gmodmurderserver
Copy link
Author

hmmm, thanks, pretty much all i need it to do is run when the server itself does, and when its detected its up, it could run the restart command, etc

@brandonsturgeon
Copy link
Member

Yeah I suppose you could do that with this web server too.

When you return a server-is-up: false response, you could also kick off the restart command (you'd have to be 100% sure it doesn't run multiple times though, that'd be a mess)

@gmodmurderserver
Copy link
Author

i tried the python stuff, and it seems to do pretty much nothing when the server restarts or crashes

@wrefgtzweve
Copy link
Member

wrefgtzweve commented Nov 16, 2022

i can recommend using https://github.com/Yepoleb/python-a2s instead of rcon

@gmodmurderserver
Copy link
Author

im guessing i just replace "valve.rcon" with a2s?

@wrefgtzweve
Copy link
Member

roughly, yeah. you'd only need the web.py part and just run a a2s.info to the server to see if its up, if it times out it isnt

@gmodmurderserver
Copy link
Author

ah right i see, i am pretty new to python and all lol

@wrefgtzweve
Copy link
Member

it can be done with any language has a a2s / rcon library, this is just a rough example

@gmodmurderserver
Copy link
Author

https://files.catbox.moe/or4t5m.png
does this look right? lol

@wrefgtzweve
Copy link
Member

no, you'd have to call the a2s function whenever you want to do a info request, check their examples

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants