mirror of
https://github.com/Lost-MSth/Arcaea-server.git
synced 2025-12-14 08:06:23 +08:00
[Enhance] World map sub folder
- Make the world maps' folder can have sub folders.
This commit is contained in:
@@ -82,11 +82,15 @@ class BundleParser:
|
||||
version_tuple_bundles: 'dict[tuple[str, str], ContentBundle]' = {}
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.parse()
|
||||
if not self.bundles:
|
||||
self.parse()
|
||||
|
||||
def re_init(self) -> None:
|
||||
self.bundles.clear()
|
||||
self.max_bundle_version.clear()
|
||||
self.next_versions.clear()
|
||||
self.version_tuple_bundles.clear()
|
||||
self.get_bundles.cache_clear()
|
||||
self.parse()
|
||||
|
||||
def parse(self) -> None:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from .config_manager import Config
|
||||
|
||||
ARCAEA_SERVER_VERSION = 'v2.11.3.13'
|
||||
ARCAEA_SERVER_VERSION = 'v2.11.3.14'
|
||||
ARCAEA_DATABASE_VERSION = 'v2.11.3.13'
|
||||
ARCAEA_LOG_DATBASE_VERSION = 'v1.1'
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ from core.sql import (Connect, DatabaseMigrator, LogDatabaseMigrator,
|
||||
MemoryDatabase)
|
||||
from core.user import UserRegister
|
||||
from core.util import try_rename
|
||||
from core.world import MapParser
|
||||
|
||||
|
||||
class DatabaseInit:
|
||||
@@ -326,12 +327,11 @@ class FileChecker:
|
||||
def check_song_file(self) -> bool:
|
||||
'''检查song有关文件并初始化缓存'''
|
||||
f = self.check_folder(Config.SONG_FILE_FOLDER_PATH)
|
||||
self.logger.info("Start to initialize song data...")
|
||||
self.logger.info("Initialize song data...")
|
||||
try:
|
||||
DownloadList.initialize_cache()
|
||||
if not Config.SONG_FILE_HASH_PRE_CALCULATE:
|
||||
self.logger.info('Song file hash pre-calculate is disabled.')
|
||||
self.logger.info('Song data initialization is complete!')
|
||||
except Exception as e:
|
||||
self.logger.error(format_exc())
|
||||
self.logger.warning('Song data initialization error!')
|
||||
@@ -341,17 +341,28 @@ class FileChecker:
|
||||
def check_content_bundle(self) -> bool:
|
||||
'''检查 content bundle 有关文件并初始化缓存'''
|
||||
f = self.check_folder(Config.CONTENT_BUNDLE_FOLDER_PATH)
|
||||
self.logger.info("Start to initialize content bundle data...")
|
||||
self.logger.info("Initialize content bundle data...")
|
||||
try:
|
||||
BundleParser()
|
||||
self.logger.info('Content bundle data initialization is complete!')
|
||||
except Exception as e:
|
||||
self.logger.error(format_exc())
|
||||
self.logger.warning('Content bundle data initialization error!')
|
||||
f = False
|
||||
return f
|
||||
|
||||
def check_world_map(self) -> bool:
|
||||
'''检查 world map 有关文件并初始化缓存'''
|
||||
f = self.check_folder(Config.WORLD_MAP_FOLDER_PATH)
|
||||
self.logger.info("Initialize world map data...")
|
||||
try:
|
||||
MapParser()
|
||||
except Exception as e:
|
||||
self.logger.error(format_exc())
|
||||
self.logger.warning('World map data initialization error!')
|
||||
f = False
|
||||
return f
|
||||
|
||||
def check_before_run(self) -> bool:
|
||||
'''运行前检查,返回布尔值'''
|
||||
MemoryDatabase() # 初始化内存数据库
|
||||
return self.check_song_file() and self.check_content_bundle() and self.check_update_database()
|
||||
return self.check_song_file() and self.check_content_bundle() and self.check_update_database() and self.check_world_map()
|
||||
|
||||
@@ -6,6 +6,7 @@ from .save import SaveData
|
||||
from .score import Score
|
||||
from .sql import Connect, Sql
|
||||
from .user import User
|
||||
from .world import MapParser
|
||||
|
||||
|
||||
class BaseOperation:
|
||||
@@ -88,6 +89,16 @@ class RefreshBundleCache(BaseOperation):
|
||||
BundleParser().re_init()
|
||||
|
||||
|
||||
class RefreshWorldMapCache(BaseOperation):
|
||||
'''
|
||||
刷新 map 缓存
|
||||
'''
|
||||
_name = 'refresh_world_map_cache'
|
||||
|
||||
def run(self):
|
||||
MapParser().re_init()
|
||||
|
||||
|
||||
class SaveUpdateScore(BaseOperation):
|
||||
'''
|
||||
云存档更新成绩,是覆盖式更新
|
||||
|
||||
@@ -437,7 +437,7 @@ class DatabaseMigrator:
|
||||
def _version_2_11_3_11(self):
|
||||
'''
|
||||
2.11.3.11 版本特殊更新,调整 recent30 表结构
|
||||
recent30 表从 (user_id: int PK, song_id<index>: text, rating<index>: real, ...) \
|
||||
recent30 表从 (user_id: int PK, rating<index>: real, song_id<index>: text, ...) \
|
||||
更改为 (user_id: int PK, r_index: int PK, time_played: int, song_id: text, difficulty: int, score: int, sp, p, n, m, hp, mod, clear_type, rating: real)
|
||||
'''
|
||||
|
||||
|
||||
@@ -10,34 +10,46 @@ from .error import InputError, MapLocked, NoData
|
||||
from .item import ItemFactory
|
||||
|
||||
|
||||
@lru_cache(maxsize=128)
|
||||
def get_world_name(file_dir: str = Constant.WORLD_MAP_FOLDER_PATH) -> list:
|
||||
'''获取所有地图名称,返回列表'''
|
||||
file_list = []
|
||||
for root, dirs, files in os.walk(file_dir):
|
||||
for file in files:
|
||||
if os.path.splitext(file)[1] == '.json':
|
||||
file_list.append(os.path.splitext(file)[0])
|
||||
return file_list
|
||||
class MapParser:
|
||||
|
||||
map_id_path: 'dict[str, str]' = {}
|
||||
|
||||
@lru_cache(maxsize=128)
|
||||
def get_world_info(map_id: str) -> dict:
|
||||
'''读取json文件内容,返回字典'''
|
||||
world_info = {}
|
||||
with open(os.path.join(Constant.WORLD_MAP_FOLDER_PATH, f'{map_id}.json'), 'rb') as f:
|
||||
world_info = load(f)
|
||||
def __init__(self) -> None:
|
||||
if not self.map_id_path:
|
||||
self.parse()
|
||||
|
||||
return world_info
|
||||
def parse(self) -> None:
|
||||
for root, dirs, files in os.walk(Constant.WORLD_MAP_FOLDER_PATH):
|
||||
for file in files:
|
||||
if not file.endswith('.json'):
|
||||
continue
|
||||
|
||||
path = os.path.join(root, file)
|
||||
self.map_id_path[file[:-5]] = path
|
||||
|
||||
def get_world_all(c, user) -> list:
|
||||
'''
|
||||
读取所有地图信息,返回列表
|
||||
parameter: `user` - `User`类或子类的实例
|
||||
'''
|
||||
worlds = get_world_name()
|
||||
return [UserMap(c, map_id, user) for map_id in worlds]
|
||||
def re_init(self) -> None:
|
||||
self.map_id_path.clear()
|
||||
self.get_world_info.cache_clear()
|
||||
self.parse()
|
||||
|
||||
@staticmethod
|
||||
@lru_cache(maxsize=128)
|
||||
def get_world_info(map_id: str) -> dict:
|
||||
'''读取json文件内容,返回字典'''
|
||||
world_info = {}
|
||||
with open(MapParser.map_id_path[map_id], 'rb') as f:
|
||||
world_info = load(f)
|
||||
|
||||
return world_info
|
||||
|
||||
@staticmethod
|
||||
def get_world_all(c, user) -> list:
|
||||
'''
|
||||
读取所有地图信息,返回列表
|
||||
parameter: `user` - `User` 类或子类的实例
|
||||
`c` - 数据库连接
|
||||
'''
|
||||
return [UserMap(c, map_id, user) for map_id in MapParser.map_id_path.keys()]
|
||||
|
||||
|
||||
class Step:
|
||||
@@ -208,7 +220,7 @@ class Map:
|
||||
|
||||
def select_map_info(self):
|
||||
'''获取地图信息'''
|
||||
self.from_dict(get_world_info(self.map_id))
|
||||
self.from_dict(MapParser.get_world_info(self.map_id))
|
||||
|
||||
|
||||
class UserMap(Map):
|
||||
|
||||
@@ -2,7 +2,7 @@ from flask import Blueprint, request
|
||||
|
||||
from core.sql import Connect
|
||||
from core.user import UserOnline
|
||||
from core.world import UserMap, get_world_all
|
||||
from core.world import MapParser, UserMap
|
||||
|
||||
from .auth import auth_required
|
||||
from .func import arc_try, success_return
|
||||
@@ -20,7 +20,7 @@ def world_all(user_id):
|
||||
return success_return({
|
||||
"current_map": user.current_map.map_id,
|
||||
"user_id": user_id,
|
||||
"maps": [x.to_dict(has_map_info=True, has_rewards=True) for x in get_world_all(c, user)]
|
||||
"maps": [x.to_dict(has_map_info=True, has_rewards=True) for x in MapParser.get_world_all(c, user)]
|
||||
})
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user