[Enhance] World map sub folder

- Make the world maps' folder can have sub folders.
This commit is contained in:
Lost-MSth
2024-06-20 00:13:58 +08:00
parent 64526e3c4b
commit c38208832b
7 changed files with 72 additions and 34 deletions

View File

@@ -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:

View File

@@ -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'

View File

@@ -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()

View File

@@ -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):
'''
云存档更新成绩,是覆盖式更新

View File

@@ -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)
'''

View File

@@ -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):

View File

@@ -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)]
})