Complete architecture simplification: 54+ files → 37 files
- Removed 11 duplicate router files (auth.py, users.py, decks.py, card_router.py, interactions.py, user_data.py, rooms.py, games/router.py, refresh.py, card_import.py, ws.py) - Removed duplicate core files (logging_config.py, settings.py) - Removed unused services (card_mirror_service.py, mtgjson_loader.py, mtgjson_uploader.py) - Removed unused schemas (proto_messages.py, protocol_constants.py) - Created run.py startup script for simple execution - Created app/core/config.py for unified configuration management - Created app/core/logging.py for logging configuration - Consolidated routers into 6 focused files (auth_router.py, users_router.py, decks_router.py, cards_router.py, user_data_router.py, games_router.py) - Updated all imports to use consolidated model paths - Added backward compatibility aliases in database.py - Created SIMPLIFICATION_SUMMARY.md documentation Architecture improvements: - Single unified database engine with auto-detection (SQLite/PostgreSQL) - Consolidated models into 2 files (models.py, mtg_models.py) - Clean router structure with one file per domain - Simplified configuration with sensible defaults - SQLite by default for development, PostgreSQL for production Testing: - All imports verified working - App loads successfully - Ready for development and testing
This commit is contained in:
@@ -65,15 +65,6 @@ from app.schemas.mtg_card_schemas import (
|
||||
MtgSetResponse, MtgCardMirrorResponse,
|
||||
DeckCardLinkResponse as DeckCardLinkResponseV2, DeckWithCardsResponse as DeckWithCardsResponseV2,
|
||||
)
|
||||
from app.schemas.proto_messages import (
|
||||
ProtoMessageBase, SessionCommand, GameCommand, GameEvent, Response,
|
||||
ServerInfoUser, ServerInfoDeckStorageFile, ServerInfoDeckStorageFolder,
|
||||
ServerInfoDeckStorageTreeItem, ServerInfoCard, ServerInfoZone, ServerInfoGame,
|
||||
)
|
||||
from app.schemas.protocol_constants import (
|
||||
SessionCommandType, GameCommandType, GameEventType, ResponseCode,
|
||||
ZoneType, UserLevelFlag,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
# Auth
|
||||
@@ -137,11 +128,4 @@ __all__ = [
|
||||
"MtgCardResponse", "MtgCardSearchRequest", "MtgCardSearchResponse",
|
||||
"MtgSetResponse", "MtgCardMirrorResponse",
|
||||
"DeckCardLinkResponseV2", "DeckWithCardsResponseV2",
|
||||
# Proto Messages
|
||||
"ProtoMessageBase", "SessionCommand", "GameCommand", "GameEvent", "Response",
|
||||
"ServerInfoUser", "ServerInfoDeckStorageFile", "ServerInfoDeckStorageFolder",
|
||||
"ServerInfoDeckStorageTreeItem", "ServerInfoCard", "ServerInfoZone", "ServerInfoGame",
|
||||
# Protocol Constants
|
||||
"SessionCommandType", "GameCommandType", "GameEventType", "ResponseCode",
|
||||
"ZoneType", "UserLevelFlag",
|
||||
]
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
"""Pydantic models for protocol buffer message conversion."""
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional, List, Dict, Any
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class ProtoMessageBase(BaseModel):
|
||||
"""Base class for protocol buffer message models."""
|
||||
message_type: str
|
||||
timestamp: datetime = datetime.now()
|
||||
|
||||
|
||||
class SessionCommand(ProtoMessageBase):
|
||||
"""Session command message."""
|
||||
message_type: str = "SessionCommand"
|
||||
cmd_type: int
|
||||
cmd_id: int = 0
|
||||
data: Dict[str, Any] = {}
|
||||
|
||||
|
||||
class GameCommand(ProtoMessageBase):
|
||||
"""Game command message."""
|
||||
message_type: str = "GameCommand"
|
||||
cmd_type: int
|
||||
cmd_id: int = 0
|
||||
player_id: Optional[int] = None
|
||||
data: Dict[str, Any] = {}
|
||||
|
||||
|
||||
class GameEvent(ProtoMessageBase):
|
||||
"""Game event message."""
|
||||
message_type: str = "GameEvent"
|
||||
event_type: int
|
||||
player_id: Optional[int] = None
|
||||
data: Dict[str, Any] = {}
|
||||
|
||||
|
||||
class Response(ProtoMessageBase):
|
||||
"""Response message."""
|
||||
message_type: str = "Response"
|
||||
cmd_id: int
|
||||
response_code: int
|
||||
data: Dict[str, Any] = {}
|
||||
|
||||
|
||||
class ServerInfoUser(BaseModel):
|
||||
"""ServerInfo_User message."""
|
||||
id: int
|
||||
name: str
|
||||
user_level: int = 0
|
||||
address: Optional[str] = None
|
||||
real_name: Optional[str] = None
|
||||
country: Optional[str] = None
|
||||
avatar_bmp: Optional[bytes] = None
|
||||
server_id: Optional[int] = None
|
||||
session_id: Optional[int] = None
|
||||
accountage_secs: Optional[int] = None
|
||||
email: Optional[str] = None
|
||||
privlevel: Optional[str] = None
|
||||
|
||||
|
||||
class ServerInfoDeckStorageFile(BaseModel):
|
||||
"""ServerInfo_DeckStorage_File message."""
|
||||
creation_time: Optional[int] = None
|
||||
|
||||
|
||||
class ServerInfoDeckStorageFolder(BaseModel):
|
||||
"""ServerInfo_DeckStorage_Folder message."""
|
||||
items: List[Dict[str, Any]] = []
|
||||
|
||||
|
||||
class ServerInfoDeckStorageTreeItem(BaseModel):
|
||||
"""ServerInfo_DeckStorage_TreeItem message."""
|
||||
id: Optional[int] = None
|
||||
name: Optional[str] = None
|
||||
file: Optional[ServerInfoDeckStorageFile] = None
|
||||
folder: Optional[ServerInfoDeckStorageFolder] = None
|
||||
|
||||
|
||||
class ServerInfoCard(BaseModel):
|
||||
"""ServerInfo_Card message."""
|
||||
id: int
|
||||
name: str
|
||||
x: Optional[int] = None
|
||||
y: Optional[int] = None
|
||||
face_down: bool = False
|
||||
tapped: bool = False
|
||||
attacking: bool = False
|
||||
color: Optional[str] = None
|
||||
pt: Optional[str] = None
|
||||
annotation: Optional[str] = None
|
||||
destroy_on_zone_change: bool = False
|
||||
doesnt_untap: bool = False
|
||||
counter_list: List[Dict[str, Any]] = []
|
||||
attach_player_id: Optional[int] = None
|
||||
attach_zone: Optional[str] = None
|
||||
attach_card_id: Optional[int] = None
|
||||
provider_id: Optional[str] = None
|
||||
|
||||
|
||||
class ServerInfoZone(BaseModel):
|
||||
"""ServerInfo_Zone message."""
|
||||
name: str
|
||||
zone_type: int = 0 # PrivateZone=0, PublicZone=1, HiddenZone=2
|
||||
with_coords: bool = False
|
||||
card_count: int = 0
|
||||
card_list: List[ServerInfoCard] = []
|
||||
always_reveal_top_card: bool = False
|
||||
always_look_at_top_card: bool = False
|
||||
|
||||
|
||||
class ServerInfoGame(BaseModel):
|
||||
"""ServerInfo_Game message."""
|
||||
server_id: Optional[int] = None
|
||||
room_id: Optional[int] = None
|
||||
game_id: Optional[int] = None
|
||||
description: Optional[str] = None
|
||||
with_password: bool = False
|
||||
max_players: int = 4
|
||||
game_types: List[int] = []
|
||||
creator_info: Optional[ServerInfoUser] = None
|
||||
only_buddies: bool = False
|
||||
only_registered: bool = False
|
||||
spectators_allowed: bool = False
|
||||
spectators_need_password: bool = False
|
||||
spectators_can_chat: bool = False
|
||||
spectators_omniscient: bool = False
|
||||
share_decklists_on_load: bool = False
|
||||
player_count: int = 0
|
||||
spectators_count: int = 0
|
||||
started: bool = False
|
||||
start_time: Optional[int] = None
|
||||
closed: bool = False
|
||||
@@ -1,170 +0,0 @@
|
||||
"""MTG Online protocol constants and message definitions."""
|
||||
import enum
|
||||
|
||||
|
||||
class SessionCommandType(enum.IntEnum):
|
||||
"""Session command types from session_commands.proto"""
|
||||
PING = 1000
|
||||
LOGIN = 1001
|
||||
MESSAGE = 1002
|
||||
LIST_USERS = 1003
|
||||
GET_GAMES_OF_USER = 1004
|
||||
GET_USER_INFO = 1005
|
||||
ADD_TO_LIST = 1006
|
||||
REMOVE_FROM_LIST = 1007
|
||||
DECK_LIST = 1008
|
||||
DECK_NEW_DIR = 1009
|
||||
DECK_DEL_DIR = 1010
|
||||
DECK_DEL = 1011
|
||||
DECK_DOWNLOAD = 1012
|
||||
DECK_UPLOAD = 1013
|
||||
LIST_ROOMS = 1014
|
||||
JOIN_ROOM = 1015
|
||||
REGISTER = 1016
|
||||
ACTIVATE = 1017
|
||||
ACCOUNT_EDIT = 1018
|
||||
ACCOUNT_IMAGE = 1019
|
||||
ACCOUNT_PASSWORD = 1020
|
||||
FORGOT_PASSWORD_REQUEST = 1021
|
||||
FORGOT_PASSWORD_RESET = 1022
|
||||
FORGOT_PASSWORD_CHALLENGE = 1023
|
||||
REQUEST_PASSWORD_SALT = 1024
|
||||
SET_CARD_ART_PARAMS = 1025
|
||||
REPLAY_LIST = 1100
|
||||
REPLAY_DOWNLOAD = 1101
|
||||
REPLAY_MODIFY_MATCH = 1102
|
||||
REPLAY_DELETE_MATCH = 1103
|
||||
REPLAY_GET_CODE = 1104
|
||||
REPLAY_SUBMIT_CODE = 1105
|
||||
|
||||
|
||||
class GameCommandType(enum.IntEnum):
|
||||
"""Game command types from game_commands.proto"""
|
||||
KICK_FROM_GAME = 1000
|
||||
LEAVE_GAME = 1001
|
||||
GAME_SAY = 1002
|
||||
SHUFFLE = 1003
|
||||
MULLIGAN = 1004
|
||||
ROLL_DIE = 1005
|
||||
DRAW_CARDS = 1006
|
||||
UNDO_DRAW = 1007
|
||||
FLIP_CARD = 1008
|
||||
ATTACH_CARD = 1009
|
||||
CREATE_TOKEN = 1010
|
||||
CREATE_ARROW = 1011
|
||||
DELETE_ARROW = 1012
|
||||
SET_CARD_ATTR = 1013
|
||||
SET_CARD_COUNTER = 1014
|
||||
INC_CARD_COUNTER = 1015
|
||||
READY_START = 1016
|
||||
CONCEDE = 1017
|
||||
INC_COUNTER = 1018
|
||||
CREATE_COUNTER = 1019
|
||||
SET_COUNTER = 1020
|
||||
DEL_COUNTER = 1021
|
||||
NEXT_TURN = 1022
|
||||
SET_ACTIVE_PHASE = 1023
|
||||
DUMP_ZONE = 1024
|
||||
REVEAL_CARDS = 1026
|
||||
MOVE_CARD = 1027
|
||||
SET_SIDEBOARD_PLAN = 1028
|
||||
DECK_SELECT = 1029
|
||||
SET_SIDEBOARD_LOCK = 1030
|
||||
CHANGE_ZONE_PROPERTIES = 1031
|
||||
UNCONCEDE = 1032
|
||||
JUDGE = 1033
|
||||
REVERSE_TURN = 1034
|
||||
|
||||
|
||||
class GameEventType(enum.IntEnum):
|
||||
"""Game event types from game_event.proto"""
|
||||
JOIN = 1000
|
||||
LEAVE = 1001
|
||||
GAME_CLOSED = 1002
|
||||
GAME_HOST_CHANGED = 1003
|
||||
KICKED = 1004
|
||||
GAME_STATE_CHANGED = 1005
|
||||
PLAYER_PROPERTIES_CHANGED = 1007
|
||||
GAME_SAY = 1009
|
||||
CREATE_ARROW = 2000
|
||||
DELETE_ARROW = 2001
|
||||
CREATE_COUNTER = 2002
|
||||
SET_COUNTER = 2003
|
||||
DEL_COUNTER = 2004
|
||||
DRAW_CARDS = 2005
|
||||
REVEAL_CARDS = 2006
|
||||
SHUFFLE = 2007
|
||||
ROLL_DIE = 2008
|
||||
MOVE_CARD = 2009
|
||||
FLIP_CARD = 2010
|
||||
DESTROY_CARD = 2011
|
||||
ATTACH_CARD = 2012
|
||||
CREATE_TOKEN = 2013
|
||||
SET_CARD_ATTR = 2014
|
||||
SET_CARD_COUNTER = 2015
|
||||
SET_ACTIVE_PLAYER = 2016
|
||||
SET_ACTIVE_PHASE = 2017
|
||||
DUMP_ZONE = 2018
|
||||
CHANGE_ZONE_PROPERTIES = 2020
|
||||
REVERSE_TURN = 2021
|
||||
GAME_LOG_NOTICE = 2022
|
||||
|
||||
|
||||
class ResponseCode(enum.IntEnum):
|
||||
"""Response codes from response.proto"""
|
||||
RespNotConnected = -1
|
||||
RespNothing = 0
|
||||
RespOk = 1
|
||||
RespNotInRoom = 2
|
||||
RespInternalError = 3
|
||||
RespInvalidCommand = 4
|
||||
RespInvalidData = 5
|
||||
RespNameNotFound = 6
|
||||
RespLoginNeeded = 7
|
||||
RespFunctionNotAllowed = 8
|
||||
RespGameNotStarted = 9
|
||||
RespGameFull = 10
|
||||
RespContextError = 11
|
||||
RespWrongPassword = 12
|
||||
RespSpectatorsNotAllowed = 13
|
||||
RespOnlyBuddies = 14
|
||||
RespUserLevelTooLow = 15
|
||||
RespInIgnoreList = 16
|
||||
RespWouldOverwriteOldSession = 17
|
||||
RespChatFlood = 18
|
||||
RespUserIsBanned = 19
|
||||
RespAccessDenied = 20
|
||||
RespUsernameInvalid = 21
|
||||
RespRegistrationRequired = 22
|
||||
RespRegistrationAccepted = 23
|
||||
RespUserAlreadyExists = 24
|
||||
RespEmailRequiredToRegister = 25
|
||||
RespTooManyRequests = 26
|
||||
RespPasswordTooShort = 27
|
||||
RespAccountNotActivated = 28
|
||||
RespRegistrationDisabled = 29
|
||||
RespRegistrationFailed = 30
|
||||
RespActivationAccepted = 31
|
||||
RespActivationFailed = 32
|
||||
RespRegistrationAcceptedNeedsActivation = 33
|
||||
RespClientIdRequired = 34
|
||||
RespClientUpdateRequired = 35
|
||||
RespServerFull = 36
|
||||
RespEmailBlackListed = 37
|
||||
|
||||
|
||||
class ZoneType(enum.IntEnum):
|
||||
"""Zone types from serverinfo_zone.proto"""
|
||||
PrivateZone = 0
|
||||
PublicZone = 1
|
||||
HiddenZone = 2
|
||||
|
||||
|
||||
class UserLevelFlag(enum.IntFlag):
|
||||
"""User level flags from serverinfo_user.proto"""
|
||||
IsNothing = 0
|
||||
IsUser = 1
|
||||
IsRegistered = 2
|
||||
IsModerator = 4
|
||||
IsAdmin = 8
|
||||
IsJudge = 16
|
||||
Reference in New Issue
Block a user