Merge branch 'develop'

This commit is contained in:
Hay1tsme 2023-03-03 17:07:58 -05:00
commit a0e24c6742
9 changed files with 116 additions and 1646 deletions

View File

@ -14,6 +14,7 @@ from time import strptime
from core.config import CoreConfig
from core.data import Data
from core.utils import Utils
from core.const import *
class AllnetServlet:
def __init__(self, core_cfg: CoreConfig, cfg_folder: str):
@ -115,6 +116,7 @@ class AllnetServlet:
else:
resp = AllnetPowerOnResponse2()
self.logger.debug(f"Allnet request: {vars(req)}")
if req.game_id not in self.uri_registry:
msg = f"Unrecognised game {req.game_id} attempted allnet auth from {request_ip}."
self.data.base.log_event("allnet", "ALLNET_AUTH_UNKNOWN_GAME", logging.WARN, msg)
@ -136,15 +138,19 @@ class AllnetServlet:
if machine is not None:
arcade = self.data.arcade.get_arcade(machine["arcade"])
resp.country = arcade["country"] if machine["country"] is None else machine["country"]
country = arcade["country"] if machine["country"] is None else machine["country"]
if country is None:
country = AllnetCountryCode.JAPAN.value
resp.country = country
resp.place_id = arcade["id"]
resp.allnet_id = machine["id"]
resp.name = arcade["name"]
resp.nickname = arcade["nickname"]
resp.region0 = arcade["region_id"]
resp.region_name0 = arcade["country"]
resp.region_name1 = arcade["state"]
resp.region_name2 = arcade["city"]
resp.name = arcade["name"] if arcade["name"] is not None else ""
resp.nickname = arcade["nickname"] if arcade["nickname"] is not None else ""
resp.region0 = arcade["region_id"] if arcade["region_id"] is not None else AllnetJapanRegionId.AICHI.value
resp.region_name0 = arcade["country"] if arcade["country"] is not None else AllnetCountryCode.JAPAN.value
resp.region_name1 = arcade["state"] if arcade["state"] is not None else AllnetJapanRegionId.AICHI.name
resp.region_name2 = arcade["city"] if arcade["city"] is not None else ""
resp.client_timezone = arcade["timezone"] if arcade["timezone"] is not None else "+0900"
int_ver = req.ver.replace(".", "")
@ -154,6 +160,7 @@ class AllnetServlet:
msg = f"{req.serial} authenticated from {request_ip}: {req.game_id} v{req.ver}"
self.data.base.log_event("allnet", "ALLNET_AUTH_SUCCESS", logging.INFO, msg)
self.logger.info(msg)
self.logger.debug(f"Allnet response: {vars(resp)}")
return self.dict_to_http_form_string([vars(resp)]).encode("utf-8")

File diff suppressed because it is too large Load Diff

View File

@ -4,8 +4,10 @@ from sqlalchemy.sql.schema import ForeignKey, PrimaryKeyConstraint
from sqlalchemy.types import Integer, String, Boolean
from sqlalchemy.sql import func, select
from sqlalchemy.dialects.mysql import insert
import re
from core.data.schema.base import BaseData, metadata
from core.const import *
arcade = Table(
"arcade",
@ -50,9 +52,20 @@ arcade_owner = Table(
class ArcadeData(BaseData):
def get_machine(self, serial: str = None, id: int = None) -> Optional[Dict]:
if serial is not None:
sql = machine.select(machine.c.serial == serial)
serial = serial.replace("-", "")
if len(serial) == 11:
sql = machine.select(machine.c.serial.like(f"{serial}%"))
elif len(serial) == 15:
sql = machine.select(machine.c.serial == serial)
else:
self.logger.error(f"{__name__ }: Malformed serial {serial}")
return None
elif id is not None:
sql = machine.select(machine.c.id == id)
else:
self.logger.error(f"{__name__ }: Need either serial or ID to look up!")
return None
@ -61,20 +74,28 @@ class ArcadeData(BaseData):
if result is None: return None
return result.fetchone()
def put_machine(self, arcade_id: int, serial: str = None, board: str = None, game: str = None, is_cab: bool = False) -> Optional[int]:
def put_machine(self, arcade_id: int, serial: str = "", board: str = None, game: str = None, is_cab: bool = False) -> Optional[int]:
if arcade_id:
self.logger.error(f"{__name__ }: Need arcade id!")
return None
if serial is None:
pass
sql = machine.insert().values(arcade = arcade_id, keychip = serial, board = board, game = game, is_cab = is_cab)
result = self.execute(sql)
if result is None: return None
return result.lastrowid
def set_machine_serial(self, machine_id: int, serial: str) -> None:
result = self.execute(machine.update(machine.c.id == machine_id).values(keychip = serial))
if result is None:
self.logger.error(f"Failed to update serial for machine {machine_id} -> {serial}")
return result.lastrowid
def set_machine_boardid(self, machine_id: int, boardid: str) -> None:
result = self.execute(machine.update(machine.c.id == machine_id).values(board = boardid))
if result is None:
self.logger.error(f"Failed to update board id for machine {machine_id} -> {boardid}")
def get_arcade(self, id: int) -> Optional[Dict]:
sql = arcade.select(arcade.c.id == id)
result = self.execute(sql)
@ -109,5 +130,31 @@ class ArcadeData(BaseData):
if result is None: return None
return result.lastrowid
def generate_keychip_serial(self, platform_id: int) -> str:
pass
def format_serial(self, platform_code: str, platform_rev: int, serial_num: int, append: int = 4152) -> str:
return f"{platform_code}{platform_rev:02d}A{serial_num:04d}{append:04d}" # 0x41 = A, 0x52 = R
def validate_keychip_format(self, serial: str) -> bool:
serial = serial.replace("-", "")
if len(serial) != 11 or len(serial) != 15:
self.logger.error(f"Serial validate failed: Incorrect length for {serial} (len {len(serial)})")
return False
platform_code = serial[:4]
platform_rev = serial[4:6]
const_a = serial[6]
num = serial[7:11]
append = serial[11:15]
if re.match("A[7|6]\d[E|X][0|1][0|1|2]A\d{4,8}", serial) is None:
self.logger.error(f"Serial validate failed: {serial} failed regex")
return False
if len(append) != 0 or len(append) != 4:
self.logger.error(f"Serial validate failed: {serial} had malformed append {append}")
return False
if len(num) != 4:
self.logger.error(f"Serial validate failed: {serial} had malformed number {num}")
return False
return True

View File

@ -33,15 +33,4 @@ if __name__=='__main__':
else:
data.migrate_database(args.game, int(args.version), args.action)
elif args.action == "migrate":
data.logger.info("Migrating from old schema to new schema")
data.restore_from_old_schema()
elif args.action == "dump":
data.logger.info("Dumping old schema to migrate to new schema")
data.dump_db()
elif args.action == "generate":
pass
data.logger.info("Done")

View File

@ -96,7 +96,7 @@ sudo ufw allow 8443
sudo ufw allow 22345
sudo ufw allow 8090
sudo ufw allow 8444
sudo ufw allow 9000
sudo ufw allow 8080
```
## Running the ARTEMiS instance

View File

@ -57,7 +57,7 @@ title:
## Firewall Adjustements
Make sure the following ports are open both on your router and local Windows firewall in case you want to use this for public use (NOT recommended):
> Port 80 (TCP), 443 (TCP), 8443 (TCP), 22345 (TCP), 8090 (TCP) **webui, 8444 (TCP) **mucha, 9000 (TCP)
> Port 80 (TCP), 443 (TCP), 8443 (TCP), 22345 (TCP), 8080 (TCP), 8090 (TCP) **webui, 8444 (TCP) **mucha
## Running the ARTEMiS instance
> python index.py

View File

@ -9,6 +9,7 @@ from titles.wacca.const import WaccaConstants
from titles.wacca.database import WaccaData
from titles.wacca.handlers import *
from core.const import AllnetCountryCode
class WaccaBase():
def __init__(self, cfg: CoreConfig, game_cfg: WaccaConfig) -> None:
@ -74,6 +75,7 @@ class WaccaBase():
if prefecture_name not in [region.name for region in WaccaConstants.Region]:
self.logger.warning(f"Invalid prefecture name {game_cfg.server.prefecture_name} in config file")
self.region_id = WaccaConstants.Region.HOKKAIDO
else:
self.region_id = WaccaConstants.Region[prefecture_name]
@ -91,10 +93,28 @@ class WaccaBase():
def handle_housing_start_request(self, data: Dict) -> Dict:
req = HousingStartRequestV1(data)
if req.appVersion.country != "JPN" and req.appVersion.country in [region.name for region in WaccaConstants.Region]:
machine = self.data.arcade.get_machine(req.chipId)
if machine is not None:
arcade = self.data.arcade.get_arcade(machine["arcade"])
allnet_region_id = arcade["region_id"]
if req.appVersion.country == AllnetCountryCode.JAPAN.value:
if allnet_region_id is not None:
region = WaccaConstants.allnet_region_id_to_wacca_region(allnet_region_id)
if region is None:
region_id = self.region_id
else:
region_id = region
else:
region_id = self.region_id
elif req.appVersion.country in WaccaConstants.VALID_COUNTRIES:
region_id = WaccaConstants.Region[req.appVersion.country]
else:
region_id = self.region_id
region_id = WaccaConstants.Region.NONE
resp = HousingStartResponseV1(region_id)
return resp.make()

View File

@ -1,4 +1,7 @@
from enum import Enum
from typing import Optional
from core.const import AllnetJapanRegionId
class WaccaConstants():
CONFIG_NAME = "wacca.yaml"
@ -166,3 +169,21 @@ class WaccaConstants():
@classmethod
def game_ver_to_string(cls, ver: int):
return cls.VERSION_NAMES[ver]
@classmethod
def allnet_region_id_to_wacca_region(cls, region: int) -> Optional[Region]:
try:
return [
cls.Region.NONE, cls.Region.AICHI, cls.Region.AOMORI, cls.Region.AKITA, cls.Region.ISHIKAWA,
cls.Region.IBARAKI, cls.Region.IWATE, cls.Region.EHIME, cls.Region.OITA, cls.Region.OSAKA,
cls.Region.OKAYAMA, cls.Region.OKINAWA, cls.Region.KAGAWA, cls.Region.KAGOSHIMA, cls.Region.KANAGAWA,
cls.Region.GIFU, cls.Region.KYOTO, cls.Region.KUMAMOTO, cls.Region.GUNMA, cls.Region.KOCHI,
cls.Region.SAITAMA, cls.Region.SAGA, cls.Region.SHIGA, cls.Region.SHIZUOKA, cls.Region.SHIMANE,
cls.Region.CHIBA, cls.Region.TOKYO, cls.Region.TOKUSHIMA, cls.Region.TOCHIGI, cls.Region.TOTTORI,
cls.Region.TOYAMA, cls.Region.NAGASAKI, cls.Region.NAGANO, cls.Region.NARA, cls.Region.NIIGATA,
cls.Region.HYOGO, cls.Region.HIROSHIMA, cls.Region.FUKUI, cls.Region.FUKUOKA, cls.Region.FUKUSHIMA,
cls.Region.HOKKAIDO, cls.Region.MIE, cls.Region.MIYAGI, cls.Region.MIYAZAKI, cls.Region.YAMAGATA,
cls.Region.YAMAGUCHI, cls.Region.YAMANASHI, cls.Region.WAKAYAMA,
][region]
except: return None

View File

@ -78,9 +78,9 @@ class Version(ShortVersion):
super().__init__(version, major, minor, patch)
split = version.split(".")
if len(split) >= 6:
self.country = split[3]
self.country: str = split[3]
self.build = int(split[4])
self.role = split[5]
self.role: str = split[5]
else:
self.country = country