forked from osuAkatsuki/bancho.py
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
executable file
·135 lines (109 loc) · 4.17 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env python3.9
"""main.py - a user-friendly, safe wrapper around bancho.py's runtime
bancho.py is an in-progress osu! server implementation for developers of all levels
of experience interested in hosting their own osu private server instance(s).
the project is developed primarily by the osu!Akatsuki (https://akatsuki.pw/) team,
and our aim is to create the most easily maintainable, reliable, and feature-rich
osu! server implementation available.
we're also fully open source!
https://github.com/osuAkatsuki/bancho.py
"""
from __future__ import annotations
__author__ = "Joshua Smith (cmyui)"
__email__ = "[email protected]"
__discord__ = "cmyui#0425"
import os
# set working directory to the bancho/ directory.
os.chdir(os.path.dirname(os.path.realpath(__file__)))
import argparse
import logging
import sys
from typing import Sequence
import uvicorn
import app.utils
import app.settings
from app.logging import Ansi
from app.logging import log
def main(argv: Sequence[str]) -> int:
"""Ensure runtime environment is ready, and start the server."""
app.utils.setup_runtime_environment()
for safety_check in (
app.utils.ensure_supported_platform, # linux only at the moment
app.utils.ensure_local_services_are_running, # mysql (if local)
app.utils.ensure_directory_structure, # .data/ & achievements/ dir structure
app.utils.ensure_dependencies_and_requirements, # submodules & oppai-ng built
):
if (exit_code := safety_check()) != 0:
return exit_code
""" Parse and handle command-line arguments. """
parser = argparse.ArgumentParser(
description=("An open-source osu! server implementation by osu!Akatsuki."),
)
parser.add_argument(
"-V",
"--version",
action="version",
version=f"%(prog)s v{app.settings.VERSION}",
)
parser.parse_args(argv)
""" Server should be safe to start """
# install any debugging hooks from
# _testing/runtime.py, if present
app.utils._install_debugging_hooks()
# check our internet connection status
if not app.utils.check_connection(timeout=1.5):
log("No internet connection available.", Ansi.LYELLOW)
# show info & any contextual warnings.
app.utils.display_startup_dialog()
# the server supports both inet and unix sockets.
if (
app.utils.is_valid_inet_address(app.settings.SERVER_ADDR)
and app.settings.SERVER_PORT is not None
):
server_arguments = {
"host": app.settings.SERVER_ADDR,
"port": app.settings.SERVER_PORT,
}
elif (
app.utils.is_valid_unix_address(app.settings.SERVER_ADDR)
and app.settings.SERVER_PORT is None
):
server_arguments = {
"uds": app.settings.SERVER_ADDR,
}
# make sure the socket file does not exist on disk and can be bound
# (uvicorn currently does not do this for us, and will raise an exc)
if os.path.exists(app.settings.SERVER_ADDR):
if (
app.utils.processes_listening_on_unix_socket(app.settings.SERVER_ADDR)
!= 0
):
log(
f"There are other processes listening on {app.settings.SERVER_ADDR}.\n"
f"If you've lost it, bancho.py can be killed gracefully with SIGINT.",
Ansi.LRED,
)
return 1
else:
os.remove(app.settings.SERVER_ADDR)
else:
raise ValueError(
"%r does not appear to be an IPv4, IPv6 or Unix address"
% app.settings.SERVER_ADDR,
) from None
# run the server indefinitely
uvicorn.run(
"app.api.init_api:asgi_app",
reload=app.settings.DEBUG,
log_level=logging.WARNING,
server_header=False,
date_header=False,
# TODO: uvicorn calls .lower() on the key & value,
# but i would prefer Bancho-Version to keep
# with standards. perhaps look into this.
headers=(("bancho-version", app.settings.VERSION),),
**server_arguments,
)
return 0
if __name__ == "__main__":
raise SystemExit(main(sys.argv[1:]))