add compatibility server setting
This commit is contained in:
parent
fe2c743480
commit
1d036c0d3c
|
@ -26,7 +26,7 @@ from fuzzywuzzy import process as fuzzy_process
|
||||||
import Items
|
import Items
|
||||||
import Regions
|
import Regions
|
||||||
import Utils
|
import Utils
|
||||||
from Utils import get_item_name_from_id, get_location_name_from_address, ReceivedItem
|
from Utils import get_item_name_from_id, get_location_name_from_address, ReceivedItem, _version_tuple
|
||||||
from NetUtils import Node, Endpoint
|
from NetUtils import Node, Endpoint
|
||||||
|
|
||||||
console_names = frozenset(set(Items.item_table) | set(Regions.location_table) | set(Items.item_name_groups))
|
console_names = frozenset(set(Items.item_table) | set(Regions.location_table) | set(Items.item_name_groups))
|
||||||
|
@ -60,8 +60,9 @@ class Client(Endpoint):
|
||||||
class Context(Node):
|
class Context(Node):
|
||||||
def __init__(self, host: str, port: int, password: str, location_check_points: int, hint_cost: int,
|
def __init__(self, host: str, port: int, password: str, location_check_points: int, hint_cost: int,
|
||||||
item_cheat: bool, forfeit_mode: str = "disabled", remaining_mode: str = "disabled",
|
item_cheat: bool, forfeit_mode: str = "disabled", remaining_mode: str = "disabled",
|
||||||
auto_shutdown: typing.SupportsFloat = 0):
|
auto_shutdown: typing.SupportsFloat = 0, compatibility: int = 2):
|
||||||
super(Context, self).__init__()
|
super(Context, self).__init__()
|
||||||
|
self.compatibility: int = compatibility
|
||||||
self.shutdown_task = None
|
self.shutdown_task = None
|
||||||
self.data_filename = None
|
self.data_filename = None
|
||||||
self.save_filename = None
|
self.save_filename = None
|
||||||
|
@ -190,8 +191,8 @@ class Context(Node):
|
||||||
self.auto_saver_thread = threading.Thread(target=save_regularly, daemon=True)
|
self.auto_saver_thread = threading.Thread(target=save_regularly, daemon=True)
|
||||||
self.auto_saver_thread.start()
|
self.auto_saver_thread.start()
|
||||||
|
|
||||||
import atexit
|
import atexit
|
||||||
atexit.register(self._save) # make sure we save on exit too
|
atexit.register(self._save) # make sure we save on exit too
|
||||||
|
|
||||||
def get_save(self) -> dict:
|
def get_save(self) -> dict:
|
||||||
d = {
|
d = {
|
||||||
|
@ -640,7 +641,8 @@ class CommonCommandProcessor(CommandProcessor):
|
||||||
"password": str,
|
"password": str,
|
||||||
"forfeit_mode": str,
|
"forfeit_mode": str,
|
||||||
"item_cheat": bool,
|
"item_cheat": bool,
|
||||||
"auto_save_interval": int}
|
"auto_save_interval": int,
|
||||||
|
"compatibility": int}
|
||||||
|
|
||||||
def _cmd_countdown(self, seconds: str = "10") -> bool:
|
def _cmd_countdown(self, seconds: str = "10") -> bool:
|
||||||
"""Start a countdown in seconds"""
|
"""Start a countdown in seconds"""
|
||||||
|
@ -889,7 +891,6 @@ async def process_client_cmd(ctx: Context, client: Client, cmd, args):
|
||||||
errors.add('InvalidPassword')
|
errors.add('InvalidPassword')
|
||||||
if type(args["rom"]) == list:
|
if type(args["rom"]) == list:
|
||||||
args["rom"] = bytes(letter for letter in args["rom"]).decode()
|
args["rom"] = bytes(letter for letter in args["rom"]).decode()
|
||||||
|
|
||||||
if args['rom'] not in ctx.rom_names:
|
if args['rom'] not in ctx.rom_names:
|
||||||
errors.add('InvalidRom')
|
errors.add('InvalidRom')
|
||||||
else:
|
else:
|
||||||
|
@ -909,8 +910,12 @@ async def process_client_cmd(ctx: Context, client: Client, cmd, args):
|
||||||
client.name = ctx.player_names[(team, slot)]
|
client.name = ctx.player_names[(team, slot)]
|
||||||
client.team = team
|
client.team = team
|
||||||
client.slot = slot
|
client.slot = slot
|
||||||
|
if ctx.compatibility == 1 and "Berserker" not in args.get('tags', Client.tags):
|
||||||
|
errors.add('IncompatibleVersion')
|
||||||
|
elif ctx.compatibility == 0 and args.get('version', Client.version) != list(_version_tuple):
|
||||||
|
errors.add('IncompatibleVersion')
|
||||||
if errors:
|
if errors:
|
||||||
|
logging.info(f"A client connection was refused due to: {errors}")
|
||||||
await ctx.send_msgs(client, [['ConnectionRefused', list(errors)]])
|
await ctx.send_msgs(client, [['ConnectionRefused', list(errors)]])
|
||||||
else:
|
else:
|
||||||
ctx.client_ids[client.team, client.slot] = args.get("uuid", None)
|
ctx.client_ids[client.team, client.slot] = args.get("uuid", None)
|
||||||
|
@ -1181,6 +1186,12 @@ def parse_args() -> argparse.Namespace:
|
||||||
parser.add_argument('--use_embedded_options', action="store_true",
|
parser.add_argument('--use_embedded_options', action="store_true",
|
||||||
help='retrieve forfeit, remaining and hint options from the multidata file,'
|
help='retrieve forfeit, remaining and hint options from the multidata file,'
|
||||||
' instead of host.yaml')
|
' instead of host.yaml')
|
||||||
|
parser.add_argument('--compatibility', default=defaults["compatibility"], type=int,
|
||||||
|
help="""
|
||||||
|
#2 -> recommended for casual/cooperative play, attempt to be compatible with everything across all versions
|
||||||
|
#1 -> recommended for friendly racing, only allow Berserker's Multiworld, to disallow old /getitem for example
|
||||||
|
#0 -> recommended for tournaments to force a level playing field, only allow an exact version match
|
||||||
|
""")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
@ -1214,7 +1225,8 @@ async def main(args: argparse.Namespace):
|
||||||
logging.basicConfig(format='[%(asctime)s] %(message)s', level=getattr(logging, args.loglevel.upper(), logging.INFO))
|
logging.basicConfig(format='[%(asctime)s] %(message)s', level=getattr(logging, args.loglevel.upper(), logging.INFO))
|
||||||
|
|
||||||
ctx = Context(args.host, args.port, args.password, args.location_check_points, args.hint_cost,
|
ctx = Context(args.host, args.port, args.password, args.location_check_points, args.hint_cost,
|
||||||
not args.disable_item_cheat, args.forfeit_mode, args.remaining_mode, args.auto_shutdown)
|
not args.disable_item_cheat, args.forfeit_mode, args.remaining_mode, args.auto_shutdown,
|
||||||
|
args.compatibility)
|
||||||
|
|
||||||
data_filename = args.multidata
|
data_filename = args.multidata
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ class DBCommandProcessor(ServerCommandProcessor):
|
||||||
|
|
||||||
class WebHostContext(Context):
|
class WebHostContext(Context):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(WebHostContext, self).__init__("", 0, "", 1, 40, True, "enabled", "enabled", 0)
|
super(WebHostContext, self).__init__("", 0, "", 1, 40, True, "enabled", "enabled", 0, 2)
|
||||||
self.main_loop = asyncio.get_running_loop()
|
self.main_loop = asyncio.get_running_loop()
|
||||||
self.video = {}
|
self.video = {}
|
||||||
self.tags = ["Berserker", "WebHost"]
|
self.tags = ["Berserker", "WebHost"]
|
||||||
|
|
|
@ -40,6 +40,11 @@ server_options:
|
||||||
remaining_mode: "goal"
|
remaining_mode: "goal"
|
||||||
# automatically shut down the server after this many seconds without new location checks, 0 to keep running
|
# automatically shut down the server after this many seconds without new location checks, 0 to keep running
|
||||||
auto_shutdown: 0
|
auto_shutdown: 0
|
||||||
|
#compatibility handling
|
||||||
|
#2 -> recommended for casual/cooperative play, attempt to be compatible with everything across all versions
|
||||||
|
#1 -> recommended for friendly racing, only allow Berserker's Multiworld, to disallow old /getitem for example
|
||||||
|
#0 -> recommended for tournaments to force a level playing field, only allow an exact version match
|
||||||
|
compatibility: 2
|
||||||
#options for MultiMystery.py
|
#options for MultiMystery.py
|
||||||
multi_mystery_options:
|
multi_mystery_options:
|
||||||
#teams, however, note that there is currently no way to supply names for teams 2+ through MultiMystery
|
#teams, however, note that there is currently no way to supply names for teams 2+ through MultiMystery
|
||||||
|
|
Loading…
Reference in New Issue