mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-03-24 11:03:21 -07:00
Merge branch 'main' into HEAD
# Conflicts: # WebHostLib/autolauncher.py # WebHostLib/customserver.py
This commit is contained in:
@@ -31,6 +31,7 @@ app.config["SELFLAUNCHKEY"] = None # can point to a SSL Certificate Key to encr
|
||||
app.config["SELFGEN"] = True # application process is in charge of scheduling Generations.
|
||||
app.config["DEBUG"] = False
|
||||
app.config["PORT"] = 80
|
||||
app.config["GAME_PORTS"] = "49152-65535"
|
||||
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
|
||||
app.config['MAX_CONTENT_LENGTH'] = 64 * 1024 * 1024 # 64 megabyte limit
|
||||
# if you want to deploy, make sure you have a non-guessable secret key
|
||||
|
||||
@@ -147,6 +147,7 @@ class MultiworldInstance():
|
||||
self.cert = config["SELFLAUNCHCERT"]
|
||||
self.key = config["SELFLAUNCHKEY"]
|
||||
self.host = config["HOST_ADDRESS"]
|
||||
self.game_ports = config["GAME_PORTS"]
|
||||
self.rooms_to_start = multiprocessing.Queue()
|
||||
self.rooms_shutting_down = multiprocessing.Queue()
|
||||
self.name = f"MultiHoster{id}"
|
||||
@@ -157,7 +158,7 @@ class MultiworldInstance():
|
||||
|
||||
process = multiprocessing.Process(group=None, target=run_server_process,
|
||||
args=(self.name, self.ponyconfig, get_static_server_data(),
|
||||
self.cert, self.key, self.host,
|
||||
self.cert, self.key, self.host, self.game_ports,
|
||||
self.rooms_to_start, self.rooms_shutting_down),
|
||||
name=self.name)
|
||||
process.start()
|
||||
|
||||
@@ -21,6 +21,8 @@ import Utils
|
||||
|
||||
from MultiServer import Context, server, auto_shutdown, ServerCommandProcessor, ClientMessageProcessor, load_server_cert
|
||||
from Utils import restricted_loads, cache_argsless
|
||||
|
||||
from . import app
|
||||
from .locker import Locker
|
||||
from .models import Command, GameDataPackage, Room, db
|
||||
|
||||
@@ -100,13 +102,13 @@ class WebHostContext(Context):
|
||||
time.sleep(5)
|
||||
|
||||
@db_session
|
||||
def load(self, room_id: int):
|
||||
def load(self, room_id: int, game_ports: str):
|
||||
self.room_id = room_id
|
||||
room = Room.get(id=room_id)
|
||||
if room.last_port:
|
||||
self.port = room.last_port
|
||||
else:
|
||||
self.port = get_random_port()
|
||||
self.port = get_random_port(game_ports)
|
||||
|
||||
multidata = self.decompress(room.seed.multidata)
|
||||
game_data_packages = {}
|
||||
@@ -168,8 +170,45 @@ class WebHostContext(Context):
|
||||
return d
|
||||
|
||||
|
||||
def get_random_port():
|
||||
return random.randint(49152, 65535)
|
||||
def get_random_port(game_ports):
|
||||
config_range_list = game_ports.split(",")
|
||||
available_ports = []
|
||||
for item in config_range_list:
|
||||
if '-' in item:
|
||||
start, end = map(int, item.split('-'))
|
||||
available_ports.extend(range(start, end+1))
|
||||
else:
|
||||
available_ports.append(int(item))
|
||||
|
||||
port = get_port_from_list(available_ports)
|
||||
if port == 0:
|
||||
checked_ports = []
|
||||
while len(set(checked_ports)) < (65535-49152)+1:
|
||||
port = random.randint(49152, 65535)
|
||||
if not is_port_in_use(port):
|
||||
break
|
||||
else:
|
||||
checked_ports.append(port)
|
||||
logging.info(f"Unable to find an available port in custom range. Expanded search to the default ports. Hosting on port {port}.")
|
||||
|
||||
return port
|
||||
|
||||
|
||||
def get_port_from_list(available_ports: list) -> int:
|
||||
while available_ports:
|
||||
port = random.choice(available_ports)
|
||||
available_ports.remove(port)
|
||||
|
||||
if not is_port_in_use(port):
|
||||
break
|
||||
else:
|
||||
port = 0
|
||||
return port
|
||||
|
||||
|
||||
def is_port_in_use(port: int) -> bool:
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||
return s.connect_ex(('localhost', port)) == 0
|
||||
|
||||
|
||||
@cache_argsless
|
||||
@@ -223,7 +262,7 @@ def set_up_logging(room_id) -> logging.Logger:
|
||||
|
||||
def run_server_process(name: str, ponyconfig: dict, static_server_data: dict,
|
||||
cert_file: typing.Optional[str], cert_key_file: typing.Optional[str],
|
||||
host: str, rooms_to_run: multiprocessing.Queue, rooms_shutting_down: multiprocessing.Queue):
|
||||
host: str, game_ports: str, rooms_to_run: multiprocessing.Queue, rooms_shutting_down: multiprocessing.Queue):
|
||||
Utils.init_logging(name)
|
||||
try:
|
||||
import resource
|
||||
@@ -255,7 +294,7 @@ def run_server_process(name: str, ponyconfig: dict, static_server_data: dict,
|
||||
try:
|
||||
logger = set_up_logging(room_id)
|
||||
ctx = WebHostContext(static_server_data, logger)
|
||||
ctx.load(room_id)
|
||||
ctx.load(room_id, game_ports)
|
||||
ctx.init_save()
|
||||
assert ctx.server is None
|
||||
try:
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
# Web hosting port
|
||||
#PORT: 80
|
||||
|
||||
# Ports used for game hosting. Values can be specific ports, port ranges or both. Default is: "49152-65535"
|
||||
# Examples of valid values: "40000-41000,49152-65535"
|
||||
# If ports within the range(s) are already in use, the WebHost will fallback to the default "49152-65535" range.
|
||||
#GAME_PORTS: "49152-65535"
|
||||
|
||||
# Place where uploads go.
|
||||
#UPLOAD_FOLDER: uploads
|
||||
|
||||
|
||||
Reference in New Issue
Block a user