mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-24 07:53:30 +08:00
161 lines
6.3 KiB
Python
161 lines
6.3 KiB
Python
# Copyright (c) 2011-2020 Eric Froemling
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
# of this software and associated documentation files (the "Software"), to deal
|
|
# in the Software without restriction, including without limitation the rights
|
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
# copies of the Software, and to permit persons to whom the Software is
|
|
# furnished to do so, subject to the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be included in
|
|
# all copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
# SOFTWARE.
|
|
# -----------------------------------------------------------------------------
|
|
"""Functionality related to the server manager script."""
|
|
from __future__ import annotations
|
|
|
|
from enum import Enum
|
|
from dataclasses import dataclass
|
|
from typing import TYPE_CHECKING, overload
|
|
|
|
if TYPE_CHECKING:
|
|
from typing import Optional, Any, Tuple
|
|
from typing_extensions import Literal
|
|
|
|
|
|
@dataclass
|
|
class ServerConfig:
|
|
"""Configuration for the server manager script."""
|
|
|
|
# Name of our server in the public parties list.
|
|
party_name: str = 'FFA'
|
|
|
|
# If True, your party will show up in the global public party list
|
|
# Otherwise it will still be joinable via LAN or connecting by IP address.
|
|
party_is_public: bool = True
|
|
|
|
# UDP port to host on. Change this to work around firewalls or run multiple
|
|
# servers on one machine.
|
|
# 43210 is the default and the only port that will show up in the LAN
|
|
# browser tab.
|
|
port: int = 43210
|
|
|
|
# Max devices in the party. Note that this does *NOT* mean max players.
|
|
# Any device in the party can have more than one player on it if they have
|
|
# multiple controllers. Also, this number currently includes the server so
|
|
# generally make it 1 bigger than you need. Max-players is not currently
|
|
# exposed but I'll try to add that soon.
|
|
max_party_size: int = 6
|
|
|
|
# Options here are 'ffa' (free-for-all) and 'teams'
|
|
# This value is only used if you do not supply a playlist_code (see below).
|
|
# In that case the default teams or free-for-all playlist gets used.
|
|
session_type: str = 'ffa'
|
|
|
|
# To host your own custom playlists, use the 'share' functionality in the
|
|
# playlist editor in the regular version of the game.
|
|
# This will give you a numeric code you can enter here to host that
|
|
# playlist.
|
|
playlist_code: Optional[int] = None
|
|
|
|
# Whether to shuffle the playlist or play its games in designated order.
|
|
playlist_shuffle: bool = True
|
|
|
|
# If True, keeps team sizes equal by disallowing joining the largest team
|
|
# (teams mode only).
|
|
auto_balance_teams: bool = True
|
|
|
|
# Whether to enable telnet access.
|
|
# This allows you to run python commands on the server as it is running.
|
|
# Note: you can now also run live commands via stdin so telnet is generally
|
|
# unnecessary. BallisticaCore's telnet server is very simple so you may
|
|
# have to turn off any fancy features in your telnet client to get it to
|
|
# work. There is no password protection so make sure to only enable this
|
|
# if access to this port is fully trusted (behind a firewall, etc).
|
|
# IMPORTANT: Telnet is not encrypted at all, so you really should not
|
|
# expose it's port to the world. If you need remote access, consider
|
|
# connecting to your machine via ssh and running telnet to localhost
|
|
# from there.
|
|
enable_telnet: bool = False
|
|
|
|
# Port used for telnet.
|
|
telnet_port: int = 43250
|
|
|
|
# This can be None for no password but PLEASE do not expose that to the
|
|
# world or your machine will likely get owned.
|
|
telnet_password: Optional[str] = 'changeme'
|
|
|
|
# Series length in teams mode (7 == 'best-of-7' series; a team must
|
|
# get 4 wins)
|
|
teams_series_length: int = 7
|
|
|
|
# Points to win in free-for-all mode (Points are awarded per game based on
|
|
# performance)
|
|
ffa_series_length: int = 24
|
|
|
|
# If you provide a custom stats webpage for your server, you can use
|
|
# this to provide a convenient in-game link to it in the server-browser
|
|
# beside the server name.
|
|
# if ${ACCOUNT} is present in the string, it will be replaced by the
|
|
# currently-signed-in account's id. To fetch info about an account,
|
|
# your backend server can use the following url:
|
|
# http://bombsquadgame.com/accountquery?id=ACCOUNT_ID_HERE
|
|
stats_url: Optional[str] = None
|
|
|
|
# FIXME REMOVE
|
|
quit: bool = False
|
|
|
|
# FIXME REMOVE
|
|
quit_reason: Optional[str] = None
|
|
|
|
|
|
# NOTE: as much as possible, communication from the server-manager to the
|
|
# child binary should go through this and not ad-hoc python string commands
|
|
# since this way is type safe.
|
|
class ServerCommand(Enum):
|
|
"""Command types that can be sent to the app in server-mode."""
|
|
CONFIG = 'config'
|
|
QUIT = 'quit'
|
|
|
|
|
|
@overload
|
|
def make_server_command(command: Literal[ServerCommand.CONFIG],
|
|
payload: ServerConfig) -> bytes:
|
|
"""Overload for CONFIG commands."""
|
|
...
|
|
|
|
|
|
@overload
|
|
def make_server_command(command: Literal[ServerCommand.QUIT],
|
|
payload: int) -> bytes:
|
|
"""Overload for QUIT commands."""
|
|
...
|
|
|
|
|
|
def make_server_command(command: ServerCommand, payload: Any) -> bytes:
|
|
"""Create a command that can be exec'ed on the server binary."""
|
|
import pickle
|
|
|
|
# Pickle this stuff down to bytes and wrap it in a command to
|
|
# extract/run it on the other end.
|
|
val = repr(pickle.dumps((command, payload)))
|
|
assert '\n' not in val
|
|
return f'import ba._server; ba._server._cmd({val})\n'.encode()
|
|
|
|
|
|
def extract_server_command(cmd: str) -> Tuple[ServerCommand, Any]:
|
|
"""Given a server-command string, returns command objects."""
|
|
|
|
# Yes, eval is unsafe and all that, but this is only intended
|
|
# for communication between a parent and child process so we
|
|
# can live with it here.
|
|
print('would extract', cmd)
|
|
return ServerCommand.CONFIG, None
|