diff --git a/android/app/build.gradle b/android/app/build.gradle index 9b88cd9..b32b594 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -12,8 +12,8 @@ android { minSdk 24 targetSdk 34 // 和网页里的 APP_VERSION 对齐,升级时一起改 - versionCode 102 - versionName "1.0.2" + versionCode 103 + versionName "1.0.3" ndk { abiFilters "arm64-v8a" diff --git a/astral/api/UpsertUserAll.py b/astral/api/UpsertUserAll.py index bcde612..ce843cc 100644 --- a/astral/api/UpsertUserAll.py +++ b/astral/api/UpsertUserAll.py @@ -736,6 +736,12 @@ class PlayData: default_factory=lambda: config.PLAY_MUSIC_PLAY_COUNT_GAIN) map_distance_gain: int = field(default_factory=lambda: config.PLAY_MAP_DISTANCE_GAIN) character_exp_gain: int = field(default_factory=lambda: config.PLAY_CHARACTER_EXP_GAIN) + #: ★ 目标地图:0 = 不切换(沿用服务器下发的 selectMapId,只推进当前选中的那张)。 + #: 非 0 = 先把 userData.selectMapId 切到该 mapId,再把 distance 加在它身上。 + #: 注意:服务端是否接受客户端改 selectMapId 尚未在真机验证 —— 真机样本里 + #: selectMapId 只出现在 Get 侧,Upsert 侧从没被改过。若服务端忽略该字段, + #: 推进仍会落在「服务器当前选中的地图」上,而不是这里指定的那张。 + select_map_id: int = 0 # ---- 里程 / 登录奖励 ---- # ★ 这两个是**登录奖励发放**才产生的,普通游玩结算不回传(留空)。 @@ -1757,6 +1763,11 @@ def apply_play_effects( ud["dateTime"] = int(auth_date_time) if ud.get("banState") is None: ud["banState"] = 0 + # ★ 切区域:只有显式给了目标 mapId 才写入;否则保持服务器下发的 selectMapId。 + # 放在这里(而不是差分段)是为了让下面 userMapList 能读到"切换后"的值。 + _want_map = int(getattr(play, "select_map_id", 0) or 0) + if _want_map: + ud["selectMapId"] = _want_map # ---------------- userExtend ---------------- ext_list = user_all.get("userExtend") or [] @@ -1824,17 +1835,31 @@ def apply_play_effects( if "userMapList" in user_all: if play.map_distance_gain: baseline = user_all.get("_baseline_map") or [] - map_id = None ud = (user_all.get("userData") or [{}])[0] - if isinstance(ud, dict): - map_id = ud.get("selectMapId") + want = int(getattr(play, "select_map_id", 0) or 0) + map_id = want or (ud.get("selectMapId") if isinstance(ud, dict) else None) target = None for item in baseline: if isinstance(item, dict) and item.get("mapId") == map_id: target = copy.deepcopy(item) break - if target is None and baseline and isinstance(baseline[0], dict): - target = copy.deepcopy(baseline[0]) + if target is None: + if map_id: + # ★ 目标地图不在玩家基线里(没进过这个区域): + # 按 GetUserMap 返回的字段形状造一条全新记录,distance 从 0 起算。 + # 这条会因「新状态有、基线没有」在差分环节被保留, + # isNewMapList 自动打 "1"(新增)。 + target = { + "mapId": int(map_id), + "distance": 0, + "isLock": False, + "isClear": False, + "isComplete": False, + "unlockFlag": 0, + } + log_info("userMapList:目标地图 " + str(map_id) + " 不在基线中,按新记录构造") + elif baseline and isinstance(baseline[0], dict): + target = copy.deepcopy(baseline[0]) if target is not None: target["distance"] = int(target.get("distance", 0) or 0) + play.map_distance_gain user_all["userMapList"] = [target] diff --git a/maipulse/app.py b/maipulse/app.py index e4eb201..ce3407c 100644 --- a/maipulse/app.py +++ b/maipulse/app.py @@ -37,6 +37,7 @@ from flask import Flask, jsonify, request, send_file # noqa: E402 import api # noqa: E402 from core import accounts, charge, items, repair, session, shop, unlock, b50, profile # noqa: E402 from core import characters, mileage, history, recommend as recommend_mod # noqa: E402 +from core import runmap # noqa: E402 app = Flask(__name__, static_folder=None) LOCK = threading.Lock() @@ -370,9 +371,13 @@ def api_ds(): @app.post("/api/logout") @guarded def api_logout(): - if not S["logged_in"]: + # ★ 只要还有 token 就去登出:热重启/异常后 logged_in 可能已经是 False, + # 但服务端会话还活着,这时候不踢掉就会卡 isLogin=True,再扫码 returnCode=100。 + if not S.get("logged_in") and not S.get("token"): return fail("未登录") resp = session.logout(S) + S.update({"logged_in": False, "is_login": False, "token": "", + "login_id": "", "login_at": 0}) return ok(returnCode=getattr(resp, "returnCode", None)) @@ -387,11 +392,11 @@ def api_shutdown(): """ info = {} try: - if S.get("logged_in"): + if S.get("logged_in") or S.get("token"): resp = session.logout(S) info["logout"] = getattr(resp, "returnCode", None) else: - info["logout"] = "未登录,跳过" + info["logout"] = "没有会话,跳过" except Exception as exc: # noqa: BLE001 info["logoutError"] = str(exc) threading.Timer(0.8, lambda: os._exit(0)).start() @@ -408,20 +413,24 @@ def api_reload(): 登录态和会话都保住。只重载 core 包内的纯逻辑模块,不碰 api / Flask。 """ import importlib - names = ["core.settle", "core.play", "core.items", "core.unlock", - "core.charge", "core.repair", "core.session", "core.shop", - "core.b50", "core.profile", "core.characters", "core.mileage"] + import pkgutil + import core as _core_pkg + # ★ 自动发现 core 包下所有已加载的模块,别再手写列表: + # 漏一个(比如后加的 runmap)就会出现「改了代码、reload 报成功、实际没生效」。 + names = sorted("core." + m.name for m in pkgutil.iter_modules(_core_pkg.__path__)) done = [] + skipped = [] for name in names: mod = sys.modules.get(name) if mod is None: + skipped.append(name) # 没被 import 过的不用管 continue try: importlib.reload(mod) done.append(name) except Exception as exc: # noqa: BLE001 return fail("重载 %s 失败:%s" % (name, exc)) - return ok(reloaded=done, logged=bool(S.get("logged_in"))) + return ok(reloaded=done, skipped=skipped, logged=bool(S.get("logged_in"))) @app.get("/api/state") @@ -655,6 +664,47 @@ def api_unlock(): return ok(**result) +# ---------------------------------------------------------------- 一键跑图 + +@app.get("/api/runmap") +@guarded +def api_runmap_list(): + """区域列表 + 玩家当前进度(只读)。""" + need_login() + try: + return ok(**runmap.overview(S)) + except Exception as exc: # noqa: BLE001 + return fail(str(exc)) + + +@app.post("/api/runmap") +@guarded +def api_runmap_write(): + """一键跑图:把选中区域推到终点,或推指定距离。默认 dry-run。""" + need_login() + body = request.get_json(silent=True) or {} + try: + map_id = int(body.get("mapId") or 0) + distance = int(body.get("distance") or 0) + step = int(body.get("step") or 0) + except (TypeError, ValueError): + return fail("mapId / distance / step 必须都是数字") + if not map_id: + return fail("没有选区区域") + mode = str(body.get("mode") or "fill") + if mode not in ("fill", "delta"): + return fail("mode 只能是 fill 或 delta") + if mode == "delta" and distance <= 0: + return fail("delta 模式下 distance 必须大于 0") + try: + result = runmap.run(S, map_id, mode=mode, distance=distance, step=step, + dry_run=bool(body.get("dryRun", True)), + cooldown=float(body.get("cooldown", 0))) + return ok(**result) + except Exception as exc: # noqa: BLE001 + return fail(str(exc)) + + # ---------------------------------------------------------------- 小黑屋 @app.post("/api/unstick") @@ -874,8 +924,8 @@ def api_master(): # ---------------------------------------------------------------- 更新 -APP_VERSION = "1.0.2" -APP_BUILD = "2026-10-30" +APP_VERSION = "1.0.3" +APP_BUILD = "2026-11-04" @app.get("/api/version") diff --git a/maipulse/core/runmap.py b/maipulse/core/runmap.py new file mode 100644 index 0000000..9e128bb --- /dev/null +++ b/maipulse/core/runmap.py @@ -0,0 +1,254 @@ +# -*- coding: utf-8 -*- +"""一键跑图:把指定区域的地图进度推到终点。 + +机制(不是独立接口,走 UpsertUserAll 的差分): + userData.selectMapId 指向本次推进的地图 + userMapList 只回传「distance 变了」的那一条 + PlayData.map_distance_gain 每局推进的距离 + +地图表来自游戏包 StreamingAssets/<版本>/map/MapXXXXXX/Map.xml: + TreasureExDatas 里每条奖励带一个 Distance, + Flag=End 那条就是跑完这张图的终点距离。 + +★ 两个现场才看得出来的不确定点(代码已按最乐观实现,需要真实账号验证): + 1. 服务端是否接受客户端改写 selectMapId。真机样本里 selectMapId 只出现在 + Get 侧,Upsert 侧从没被改过。若不接受,推进仍会落在服务器当前选中的图上。 + 2. 一局能走多远。真机一局 11000,跑完 Phigros 要 68 局;一次性 +750000 + 可能被拒绝或截断。所以默认分段(step)推进,而不是一把梭。 +""" +from __future__ import annotations + +import json +import os + +import api + +from . import settle, session + +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +MAP_JSON = os.path.join(BASE_DIR, "data", "master", "map.json") + +#: 真机一局走过的距离(机台实测值) +STEP_DISTANCE = 11000 + +_CATALOG = None + + +def catalog() -> list: + """全部区域(含终点距离)。按 mapId 升序。""" + global _CATALOG + if _CATALOG is None: + if not os.path.isfile(MAP_JSON): + _CATALOG = [] + else: + with open(MAP_JSON, encoding="utf-8") as fp: + _CATALOG = json.load(fp) + return _CATALOG + + +def find_area(map_id: int) -> dict: + mid = int(map_id) + for row in catalog(): + try: + if int(row.get("mapId") or 0) == mid: + return row + except (TypeError, ValueError): + continue + return {} + + +def progress(snapshot: dict) -> dict: + """从快照取玩家各地图进度:mapId -> {distance, isClear, isComplete, isLock}。 + + ★ 节点可能是「Get 响应包装」{"userMapList": [...]},要先拆一层。 + """ + node = (snapshot or {}).get("userMapList") + if isinstance(node, dict): + node = node.get("userMapList") or [] + out = {} + for row in node or []: + if not isinstance(row, dict): + continue + try: + mid = int(row.get("mapId") or 0) + except (TypeError, ValueError): + continue + if not mid: + continue + out[mid] = { + "distance": int(row.get("distance") or 0), + "isClear": bool(row.get("isClear")), + "isComplete": bool(row.get("isComplete")), + "isLock": bool(row.get("isLock")), + } + return out + + +def overview(state: dict) -> dict: + """区域列表 + 玩家进度,给前端渲染。""" + user_id = int(state["user_id"]) + snapshot = api.GetNeedUserData(user_id, token=state["token"], save=False) + have = progress(snapshot) + select = None + node = snapshot.get("userData") + # ★ Get 侧 userData 是两层嵌套:{"userData": {"userId":…, "userData": {...}, "banState":0}} + # 内层是**单个 dict**,不是 list;Upsert 侧才可能是 list。两种都要兼容。 + if isinstance(node, dict): + inner = node.get("userData") + if isinstance(inner, dict): + node = [inner] + elif isinstance(inner, list): + node = inner + elif isinstance(node, list): + node = node + if isinstance(node, dict): + node = [node] + if isinstance(node, list) and node and isinstance(node[0], dict): + try: + select = int(node[0].get("selectMapId") or 0) or None + except (TypeError, ValueError): + select = None + + areas = [] + for row in catalog(): + mid = int(row.get("mapId") or 0) + cur = have.get(mid) or {} + end = int(row.get("endDistance") or 0) + dist = int(cur.get("distance") or 0) + area = dict(row) + area.update({ + "current": dist, + "cleared": bool(cur.get("isClear") or cur.get("isComplete")), + "entered": mid in have, + "selected": mid == select, + "remain": max(0, end - dist) if end else None, + "percent": (round(dist * 100.0 / end, 1) if end else None), + }) + areas.append(area) + return {"areas": areas, "selectMapId": select, "entered": len(have)} + + +def plan(map_id: int, mode: str = "fill", distance: int = 0, + current: int = 0, step: int = 0) -> list: + """算出要分几段推,每段推多少。返回 [gain, gain, ...]。""" + area = find_area(map_id) + end = int(area.get("endDistance") or 0) + + if mode == "fill": + total = max(0, end - int(current or 0)) + else: + total = max(0, int(distance or 0)) + if total <= 0: + return [] + + step = int(step or 0) + if step <= 0: + # 没指定就按「不超过终点的 1/8、也不超过 10 万」切,避免单包过猛 + cap = max(STEP_DISTANCE, min(100000, (end or total) // 8 or STEP_DISTANCE)) + step = max(STEP_DISTANCE, cap) + + gains, left = [], total + while left > 0: + take = min(step, left) + gains.append(take) + left -= take + return gains + + +def run(state: dict, map_id: int, *, mode: str = "fill", distance: int = 0, + step: int = 0, dry_run: bool = False, cooldown: float = 0.0, + verify: bool = False) -> dict: + """把指定区域推进到终点(mode=fill)或推指定距离(mode=delta)。""" + mid = int(map_id) + area = find_area(mid) + if not area: + raise RuntimeError("没有这个区域:%s" % mid) + + user_id = int(state["user_id"]) + probe = api.GetNeedUserData(user_id, token=state["token"], save=False) + cur = (progress(probe).get(mid) or {}).get("distance") or 0 + gains = plan(mid, mode=mode, distance=distance, current=cur, step=step) + + result = { + "mode": mode, + "mapId": mid, + "name": area.get("name"), + "endDistance": int(area.get("endDistance") or 0), + "before": cur, + "total": sum(gains), + "batches": len(gains), + "done": 0, + "failed": 0, + "dryRun": bool(dry_run), + "returnCode": None, + "errors": [], + "steps": [], + } + if not gains: + result["note"] = "已经是终点,不用推" + return result + + for index, gain in enumerate(gains, 1): + one = _run_once(state, mid, gain, dry_run, cooldown, verify) + result["returnCode"] = one.get("returnCode") + if one.get("error"): + result["failed"] += gain + result["errors"].append("第 %d 段:%s" % (index, one["error"])) + break + result["done"] += gain + result["steps"].append({"seq": index, "gain": gain, + "after": one.get("after"), + "returnCode": one.get("returnCode")}) + if dry_run: + break + result["after"] = result["before"] + result["done"] + return result + + +def _run_once(state: dict, map_id: int, gain: int, + dry_run: bool, cooldown: float, verify: bool = False) -> dict: + """发一局,推进一小段。 + + ★ verify=False(默认):发完不回头读。回读要再拉一次全量快照, + 一段就多几秒,跑几十段时几乎全是等回读。进度靠本地累加, + 真要看落地效果,跑完点一次「读进度」就行。 + """ + user_id = int(state["user_id"]) + session.fresh(state) + who = session.ids() + snapshot = api.GetNeedUserData(user_id, token=state["token"], save=False) + + play_data, playlog = settle.prepare(state, snapshot) + play_data.map_distance_gain = int(gain) + play_data.select_map_id = int(map_id) + + settle.ensure_play_window(state) + settle.upload(state, playlog) + + patch = settle.patch(state, snapshot, play_data) + resp = api.UpsertUserAll( + user_id, state["login_id"], + login_date_time=state["login_date_time"], + auth_date_time=state["date_time"], + token=state["token"], + snapshot=snapshot, + play=play_data, + user_playlog_list=[playlog], + patch=patch, + verify_landing=bool(verify), + auto_characters=False, + place_id=who["place_id"], place_name=who["place_name"], + region_id=who["region_id"], region_name=who["region_name"], + client_id=who["client_id"], + cooldown_sec=float(cooldown), + dry_run=bool(dry_run), + confirm=not dry_run, + ) + one = { + "returnCode": getattr(resp, "returnCode", None), + "apiName": getattr(resp, "apiName", ""), + } + if verify and not dry_run: + after = api.GetNeedUserData(user_id, token=state["token"], save=False) + one["after"] = (progress(after).get(int(map_id)) or {}).get("distance") + return one \ No newline at end of file diff --git a/maipulse/data/icons/508031.png b/maipulse/data/icons/508031.png new file mode 100644 index 0000000..ca966eb Binary files /dev/null and b/maipulse/data/icons/508031.png differ diff --git a/maipulse/data/master/map.json b/maipulse/data/master/map.json new file mode 100644 index 0000000..d15d09b --- /dev/null +++ b/maipulse/data/master/map.json @@ -0,0 +1,1927 @@ +[ + { + "mapId": 1, + "name": "启程区域", + "island": "maimaiDX", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 6800, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 2, + "name": "青春区域", + "island": "maimaiDX", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 15000, + "slots": 7, + "bonusMagnification": 2000 + }, + { + "mapId": 3, + "name": "DX区域", + "island": "maimaiDX", + "collabo": false, + "infinity": true, + "version": "A000", + "endDistance": 0, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 4, + "name": "大都会区域", + "island": "maimaiDX", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 14000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 5, + "name": "龙之区域", + "island": "maimaiDX", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 9400, + "slots": 9, + "bonusMagnification": 2000 + }, + { + "mapId": 6, + "name": "天界区域", + "island": "maimaiDX", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 20000, + "slots": 7, + "bonusMagnification": 2000 + }, + { + "mapId": 7, + "name": "BLACK ROSE区域", + "island": "maimaiDX", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 369000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 33, + "name": "GYARI区域", + "island": "maimaiDX", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 8610, + "slots": 7, + "bonusMagnification": 2000 + }, + { + "mapId": 34, + "name": "東方Project区域", + "island": "maimaiDX", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 17000, + "slots": 14, + "bonusMagnification": 2000 + }, + { + "mapId": 35, + "name": "Project DIVA区域", + "island": "maimaiDX", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 35000, + "slots": 13, + "bonusMagnification": 2000 + }, + { + "mapId": 39, + "name": "からめる区域", + "island": "maimaiDX", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 200000, + "slots": 7, + "bonusMagnification": 2000 + }, + { + "mapId": 40, + "name": "イロドリミドリ区域", + "island": "maimaiDX", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 14000, + "slots": 12, + "bonusMagnification": 2000 + }, + { + "mapId": 42, + "name": "結月ゆかり区域", + "island": "maimaiDX", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 7800, + "slots": 7, + "bonusMagnification": 2000 + }, + { + "mapId": 50001, + "name": "启程区域2", + "island": "maimaiDX", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 252000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 50002, + "name": "大都会区域2 イーシュ襲来", + "island": "maimaiDX", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 168000, + "slots": 6, + "bonusMagnification": 2000 + }, + { + "mapId": 50003, + "name": "大都会区域2 黒姫の逆襲", + "island": "maimaiDX", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 252000, + "slots": 5, + "bonusMagnification": 2000 + }, + { + "mapId": 50004, + "name": "みかんヶ岡区域 朝焼け通り", + "island": "maimaiDX", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 126000, + "slots": 6, + "bonusMagnification": 2000 + }, + { + "mapId": 50005, + "name": "みかんヶ岡区域 月夜通り", + "island": "maimaiDX", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 168000, + "slots": 5, + "bonusMagnification": 2000 + }, + { + "mapId": 50006, + "name": "天界区域2", + "island": "maimaiDX", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 1072000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 50007, + "name": "DX区域2", + "island": "maimaiDX", + "collabo": false, + "infinity": true, + "version": "A000", + "endDistance": 0, + "slots": 8, + "bonusMagnification": 2000 + }, + { + "mapId": 50008, + "name": "BLACK ROSE区域2 黒薔薇病篇", + "island": "maimaiDX", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 378000, + "slots": 3, + "bonusMagnification": 2000 + }, + { + "mapId": 50009, + "name": "BLACK ROSE区域2 二つの仮面篇", + "island": "maimaiDX", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 294000, + "slots": 3, + "bonusMagnification": 2000 + }, + { + "mapId": 50033, + "name": "オンゲキ区域", + "island": "maimaiDX", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 19000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 50034, + "name": "#コンパス区域", + "island": "maimaiDX", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 16000, + "slots": 12, + "bonusMagnification": 2000 + }, + { + "mapId": 50036, + "name": "ポンコツクエスト区域", + "island": "maimaiDX", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 9000, + "slots": 7, + "bonusMagnification": 2000 + }, + { + "mapId": 50037, + "name": "Project DIVA区域2", + "island": "maimaiDX", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 11000, + "slots": 7, + "bonusMagnification": 2000 + }, + { + "mapId": 50039, + "name": "東方Project×アトレ秋葉原区域", + "island": "maimaiDX", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 16500, + "slots": 7, + "bonusMagnification": 2000 + }, + { + "mapId": 100001, + "name": "咻哇咻哇区域", + "island": "maimaiDX Splash", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 630000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 100003, + "name": "大都会区域3", + "island": "maimaiDX Splash", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 882000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 100004, + "name": "天空街区域", + "island": "maimaiDX Splash", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 336000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 100005, + "name": "天界区域3", + "island": "maimaiDX Splash", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 1386000, + "slots": 9, + "bonusMagnification": 2000 + }, + { + "mapId": 100006, + "name": "BLACK ROSE区域3", + "island": "maimaiDX Splash", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 504000, + "slots": 7, + "bonusMagnification": 2000 + }, + { + "mapId": 100007, + "name": "咻哇乐园区域", + "island": "maimaiDX Splash", + "collabo": false, + "infinity": true, + "version": "A000", + "endDistance": 0, + "slots": 3, + "bonusMagnification": 2000 + }, + { + "mapId": 100053, + "name": "ナユタン星人区域", + "island": "maimaiDX Splash", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 364000, + "slots": 7, + "bonusMagnification": 2000 + }, + { + "mapId": 100054, + "name": "GYARI区域2", + "island": "maimaiDX Splash", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 420000, + "slots": 6, + "bonusMagnification": 2000 + }, + { + "mapId": 100055, + "name": "東方Projectリバイバル区域", + "island": "maimaiDX Splash", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 588000, + "slots": 6, + "bonusMagnification": 2000 + }, + { + "mapId": 100056, + "name": "Arcaea区域", + "island": "maimaiDX Splash", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 774000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 100057, + "name": "かいりきベア区域", + "island": "maimaiDX Splash", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 364000, + "slots": 6, + "bonusMagnification": 2000 + }, + { + "mapId": 100058, + "name": "プロジェクトセカイ区域", + "island": "maimaiDX Splash", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 840000, + "slots": 12, + "bonusMagnification": 2000 + }, + { + "mapId": 100059, + "name": "にじさんじ区域", + "island": "maimaiDX Splash", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 805000, + "slots": 14, + "bonusMagnification": 2000 + }, + { + "mapId": 100060, + "name": "いらすとや区域", + "island": "maimaiDX Splash", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 797000, + "slots": 12, + "bonusMagnification": 2000 + }, + { + "mapId": 100061, + "name": "オンゲキ区域2", + "island": "maimaiDX Splash", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 840000, + "slots": 8, + "bonusMagnification": 2000 + }, + { + "mapId": 150001, + "name": "咻哇咻哇区域2", + "island": "maimaiDX Splash", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 800000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 150002, + "name": "BLACK ROSE区域4", + "island": "maimaiDX Splash", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 500000, + "slots": 4, + "bonusMagnification": 2000 + }, + { + "mapId": 150003, + "name": "天空街区域2", + "island": "maimaiDX Splash", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 612000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 150004, + "name": "kawaii区域", + "island": "maimaiDX Splash", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 1300000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 150005, + "name": "高天原区域", + "island": "maimaiDX Splash", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 1111000, + "slots": 9, + "bonusMagnification": 2000 + }, + { + "mapId": 150006, + "name": "咻哇乐园区域2", + "island": "maimaiDX Splash", + "collabo": false, + "infinity": true, + "version": "A000", + "endDistance": 0, + "slots": 3, + "bonusMagnification": 2000 + }, + { + "mapId": 150052, + "name": "すみっコぐらし区域", + "island": "maimaiDX Splash", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 300000, + "slots": 9, + "bonusMagnification": 2000 + }, + { + "mapId": 150053, + "name": "HaNaMiNa区域", + "island": "maimaiDX Splash", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 600000, + "slots": 6, + "bonusMagnification": 2000 + }, + { + "mapId": 150054, + "name": "HARDCORE TANO*C区域", + "island": "maimaiDX Splash", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 999000, + "slots": 14, + "bonusMagnification": 2000 + }, + { + "mapId": 150055, + "name": "東方Projectリバイバル区域2", + "island": "maimaiDX Splash", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 500000, + "slots": 8, + "bonusMagnification": 2000 + }, + { + "mapId": 150059, + "name": "はるまきごはん区域", + "island": "maimaiDX Splash", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 400000, + "slots": 6, + "bonusMagnification": 2000 + }, + { + "mapId": 150060, + "name": "オンゲキ区域3", + "island": "maimaiDX Splash", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 600000, + "slots": 7, + "bonusMagnification": 2000 + }, + { + "mapId": 200001, + "name": "宇宙空间站区域", + "island": "maimaiDX UNiVERSE", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 800000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 200002, + "name": "天界区域4", + "island": "maimaiDX UNiVERSE", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 800000, + "slots": 9, + "bonusMagnification": 2000 + }, + { + "mapId": 200003, + "name": "大都会区域4", + "island": "maimaiDX UNiVERSE", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 1000000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 200004, + "name": "7sRef区域", + "island": "maimaiDX UNiVERSE", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 1300000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 200005, + "name": "银河区域", + "island": "maimaiDX UNiVERSE", + "collabo": false, + "infinity": true, + "version": "A000", + "endDistance": 0, + "slots": 3, + "bonusMagnification": 2000 + }, + { + "mapId": 200006, + "name": "BLACK ROSE区域5", + "island": "maimaiDX UNiVERSE", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 500000, + "slots": 6, + "bonusMagnification": 2000 + }, + { + "mapId": 200051, + "name": "アイドルマスター ミリオンライブ!区域", + "island": "maimaiDX UNiVERSE", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 250000, + "slots": 6, + "bonusMagnification": 2000 + }, + { + "mapId": 200052, + "name": "アイドルマスター SideM区域", + "island": "maimaiDX UNiVERSE", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 150000, + "slots": 4, + "bonusMagnification": 2000 + }, + { + "mapId": 200053, + "name": "cosMo@暴走P区域", + "island": "maimaiDX UNiVERSE", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 411000, + "slots": 9, + "bonusMagnification": 2000 + }, + { + "mapId": 200054, + "name": "オーイシ×加藤のピザラジオ区域", + "island": "maimaiDX UNiVERSE", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 132000, + "slots": 3, + "bonusMagnification": 2000 + }, + { + "mapId": 200055, + "name": "東方ダンマクカグラ区域", + "island": "maimaiDX UNiVERSE", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 450000, + "slots": 6, + "bonusMagnification": 2000 + }, + { + "mapId": 200056, + "name": "キノシタ区域", + "island": "maimaiDX UNiVERSE", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 400000, + "slots": 8, + "bonusMagnification": 2000 + }, + { + "mapId": 200059, + "name": "Rain Drops区域", + "island": "maimaiDX UNiVERSE", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 250000, + "slots": 5, + "bonusMagnification": 2000 + }, + { + "mapId": 200060, + "name": "プロジェクトセカイ区域2", + "island": "maimaiDX UNiVERSE", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 576000, + "slots": 21, + "bonusMagnification": 2000 + }, + { + "mapId": 200061, + "name": "Project DIVA区域3", + "island": "maimaiDX UNiVERSE", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 288000, + "slots": 7, + "bonusMagnification": 2000 + }, + { + "mapId": 200062, + "name": "オンゲキ区域4", + "island": "maimaiDX UNiVERSE", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 600000, + "slots": 8, + "bonusMagnification": 2000 + }, + { + "mapId": 200063, + "name": "舞ヶ原シンセ研究会区域", + "island": "maimaiDX UNiVERSE", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 432000, + "slots": 5, + "bonusMagnification": 2000 + }, + { + "mapId": 250001, + "name": "宇宙空间站区域2", + "island": "maimaiDX UNiVERSE", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 800000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 250002, + "name": "大都会区域5", + "island": "maimaiDX UNiVERSE", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 900000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 250003, + "name": "天界区域5", + "island": "maimaiDX UNiVERSE", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 1000000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 250004, + "name": "7sRef区域2", + "island": "maimaiDX UNiVERSE", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 1300000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 250005, + "name": "银河区域2", + "island": "maimaiDX UNiVERSE", + "collabo": false, + "infinity": true, + "version": "A000", + "endDistance": 0, + "slots": 12, + "bonusMagnification": 2000 + }, + { + "mapId": 250006, + "name": "BLACK ROSE区域6", + "island": "maimaiDX UNiVERSE", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 400000, + "slots": 7, + "bonusMagnification": 2000 + }, + { + "mapId": 250007, + "name": "10周年纪念区域", + "island": "maimaiDX UNiVERSE", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 777000, + "slots": 78, + "bonusMagnification": 2000 + }, + { + "mapId": 250052, + "name": "ツユ区域", + "island": "maimaiDX UNiVERSE", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 350000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 250053, + "name": "D4DJ Groovy Mix区域", + "island": "maimaiDX UNiVERSE", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 400000, + "slots": 15, + "bonusMagnification": 2000 + }, + { + "mapId": 250054, + "name": "Diverse System区域", + "island": "maimaiDX UNiVERSE", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 800000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 250055, + "name": "Rain Drops区域2", + "island": "maimaiDX UNiVERSE", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 250000, + "slots": 7, + "bonusMagnification": 2000 + }, + { + "mapId": 250056, + "name": "ゲームセンターCX区域", + "island": "maimaiDX UNiVERSE", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 200000, + "slots": 9, + "bonusMagnification": 2000 + }, + { + "mapId": 250058, + "name": "CHUNITHM区域", + "island": "maimaiDX UNiVERSE", + "collabo": true, + "infinity": false, + "version": "A015", + "endDistance": 500000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 250059, + "name": "すりぃ区域", + "island": "maimaiDX UNiVERSE", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 450000, + "slots": 20, + "bonusMagnification": 2000 + }, + { + "mapId": 250060, + "name": "オンゲキ区域5", + "island": "maimaiDX UNiVERSE", + "collabo": true, + "infinity": false, + "version": "A015", + "endDistance": 600000, + "slots": 14, + "bonusMagnification": 2000 + }, + { + "mapId": 300001, + "name": "欢乐节日区域", + "island": "maimaiDX FESTiVAL", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 800000, + "slots": 12, + "bonusMagnification": 2000 + }, + { + "mapId": 300002, + "name": "大都会区域6", + "island": "maimaiDX FESTiVAL", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 1100000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 300003, + "name": "天空街区域3", + "island": "maimaiDX FESTiVAL", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 900000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 300004, + "name": "天界区域6", + "island": "maimaiDX FESTiVAL", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 1400000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 300005, + "name": "节日区域", + "island": "maimaiDX FESTiVAL", + "collabo": false, + "infinity": true, + "version": "A000", + "endDistance": 0, + "slots": 12, + "bonusMagnification": 2000 + }, + { + "mapId": 300006, + "name": "BLACK ROSE区域7", + "island": "maimaiDX FESTiVAL", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 500000, + "slots": 8, + "bonusMagnification": 2000 + }, + { + "mapId": 300052, + "name": "DECO*27区域", + "island": "maimaiDX FESTiVAL", + "collabo": true, + "infinity": false, + "version": "A011", + "endDistance": 400000, + "slots": 18, + "bonusMagnification": 2000 + }, + { + "mapId": 300053, + "name": "プロジェクトセカイ区域3", + "island": "maimaiDX FESTiVAL", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 500000, + "slots": 12, + "bonusMagnification": 2000 + }, + { + "mapId": 300054, + "name": "東方Project×オンゲキ区域", + "island": "maimaiDX FESTiVAL", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 600000, + "slots": 12, + "bonusMagnification": 2000 + }, + { + "mapId": 300055, + "name": "さなちゃんねる区域", + "island": "maimaiDX FESTiVAL", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 260000, + "slots": 15, + "bonusMagnification": 2000 + }, + { + "mapId": 300057, + "name": "樋口楓区域", + "island": "maimaiDX FESTiVAL", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 250000, + "slots": 12, + "bonusMagnification": 2000 + }, + { + "mapId": 300058, + "name": "電音部区域", + "island": "maimaiDX FESTiVAL", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 400000, + "slots": 14, + "bonusMagnification": 2000 + }, + { + "mapId": 300059, + "name": "CHUNITHM区域2", + "island": "maimaiDX FESTiVAL", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 600000, + "slots": 15, + "bonusMagnification": 2000 + }, + { + "mapId": 300060, + "name": "syudou区域", + "island": "maimaiDX FESTiVAL", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 350000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 300061, + "name": "Arcaea区域2", + "island": "maimaiDX FESTiVAL", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 900000, + "slots": 13, + "bonusMagnification": 2000 + }, + { + "mapId": 350001, + "name": "欢乐节日区域2", + "island": "maimaiDX FESTiVAL", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 800000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 350003, + "name": "天空街区域4", + "island": "maimaiDX FESTiVAL", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 900000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 350004, + "name": "龙之区域2", + "island": "maimaiDX FESTiVAL", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 1111000, + "slots": 9, + "bonusMagnification": 2000 + }, + { + "mapId": 350005, + "name": "节日区域2", + "island": "maimaiDX FESTiVAL", + "collabo": false, + "infinity": true, + "version": "A000", + "endDistance": 0, + "slots": 12, + "bonusMagnification": 2000 + }, + { + "mapId": 350006, + "name": "BLACK ROSE区域8", + "island": "maimaiDX FESTiVAL", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 500000, + "slots": 9, + "bonusMagnification": 2000 + }, + { + "mapId": 350007, + "name": "10周年纪念区域2", + "island": "maimaiDX FESTiVAL", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 1111000, + "slots": 32, + "bonusMagnification": 2000 + }, + { + "mapId": 350051, + "name": "ヒメヒナ区域", + "island": "maimaiDX FESTiVAL", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 230000, + "slots": 12, + "bonusMagnification": 2000 + }, + { + "mapId": 350052, + "name": "ピノキオピー区域", + "island": "maimaiDX FESTiVAL", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 400000, + "slots": 15, + "bonusMagnification": 2000 + }, + { + "mapId": 350053, + "name": "Muse Dash区域", + "island": "maimaiDX FESTiVAL", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 660000, + "slots": 21, + "bonusMagnification": 2000 + }, + { + "mapId": 350054, + "name": "東方Project×イロドリミドリ区域", + "island": "maimaiDX FESTiVAL", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 670000, + "slots": 21, + "bonusMagnification": 2000 + }, + { + "mapId": 350055, + "name": "MEGAREX区域", + "island": "maimaiDX FESTiVAL", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 910000, + "slots": 19, + "bonusMagnification": 2000 + }, + { + "mapId": 350056, + "name": "からめる区域2", + "island": "maimaiDX FESTiVAL", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 710000, + "slots": 24, + "bonusMagnification": 2000 + }, + { + "mapId": 350057, + "name": "音楽的同位体 可不区域", + "island": "maimaiDX FESTiVAL", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 310000, + "slots": 7, + "bonusMagnification": 2000 + }, + { + "mapId": 350058, + "name": "オンゲキ区域6", + "island": "maimaiDX FESTiVAL", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 610000, + "slots": 14, + "bonusMagnification": 2000 + }, + { + "mapId": 400001, + "name": "派对区域", + "island": "maimaiDX BUDDiES", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 800000, + "slots": 14, + "bonusMagnification": 2000 + }, + { + "mapId": 400002, + "name": "大都会区域7", + "island": "maimaiDX BUDDiES", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 1000000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 400003, + "name": "天空街区域5", + "island": "maimaiDX BUDDiES", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 900000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 400004, + "name": "7sRef区域3", + "island": "maimaiDX BUDDiES", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 1400000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 400005, + "name": "BUDDiES区域", + "island": "maimaiDX BUDDiES", + "collabo": false, + "infinity": true, + "version": "A000", + "endDistance": 0, + "slots": 12, + "bonusMagnification": 2000 + }, + { + "mapId": 400006, + "name": "BLACK ROSE区域9", + "island": "maimaiDX BUDDiES", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 500000, + "slots": 9, + "bonusMagnification": 2000 + }, + { + "mapId": 400051, + "name": "いよわ区域", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 220000, + "slots": 13, + "bonusMagnification": 2000 + }, + { + "mapId": 400052, + "name": "グルーヴコースター区域", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 360000, + "slots": 13, + "bonusMagnification": 2000 + }, + { + "mapId": 400053, + "name": "ヘブンバーンズレッド区域", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 300000, + "slots": 17, + "bonusMagnification": 2000 + }, + { + "mapId": 400054, + "name": "WACCA区域", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 700000, + "slots": 16, + "bonusMagnification": 2000 + }, + { + "mapId": 400056, + "name": "sasakure.UK区域", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 240000, + "slots": 13, + "bonusMagnification": 2000 + }, + { + "mapId": 400057, + "name": "TJ.hangneil区域", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 444000, + "slots": 8, + "bonusMagnification": 2000 + }, + { + "mapId": 400058, + "name": "月面区域", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 240000, + "slots": 8, + "bonusMagnification": 2000 + }, + { + "mapId": 400059, + "name": "裏 月面区域", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 666000, + "slots": 6, + "bonusMagnification": 2000 + }, + { + "mapId": 400061, + "name": "東北ずん子区域", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 280000, + "slots": 15, + "bonusMagnification": 2000 + }, + { + "mapId": 400062, + "name": "CHUNITHM区域3", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 600000, + "slots": 13, + "bonusMagnification": 2000 + }, + { + "mapId": 400063, + "name": "プロジェクトセカイ区域4", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 600000, + "slots": 38, + "bonusMagnification": 2000 + }, + { + "mapId": 450001, + "name": "派对区域2", + "island": "maimaiDX BUDDiES", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 900000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 450002, + "name": "大都会区域8", + "island": "maimaiDX BUDDiES", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 1100000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 450003, + "name": "龙之区域3", + "island": "maimaiDX BUDDiES", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 900000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 450004, + "name": "天界区域7", + "island": "maimaiDX BUDDiES", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 1400000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 450005, + "name": "BUDDiES区域2", + "island": "maimaiDX BUDDiES", + "collabo": false, + "infinity": true, + "version": "A000", + "endDistance": 0, + "slots": 13, + "bonusMagnification": 2000 + }, + { + "mapId": 450051, + "name": "NEEDY GIRL OVERDOSE区域", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 250000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 450052, + "name": "花譜区域", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 200000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 450053, + "name": "ゆこぴ区域", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 250000, + "slots": 19, + "bonusMagnification": 2000 + }, + { + "mapId": 450054, + "name": "グルーヴコースター区域2", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 550000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 450056, + "name": "にじさんじのB級バラエティ(仮)区域", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 250000, + "slots": 12, + "bonusMagnification": 2000 + }, + { + "mapId": 450057, + "name": "東方ダンマクカグラ ファンタジア・ロスト区域", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 650000, + "slots": 14, + "bonusMagnification": 2000 + }, + { + "mapId": 450058, + "name": "HARDCORE TANO*C区域2", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 800000, + "slots": 13, + "bonusMagnification": 2000 + }, + { + "mapId": 450059, + "name": "#コンパス区域2", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 300000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 450060, + "name": "周防パトラ区域", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 250000, + "slots": 15, + "bonusMagnification": 2000 + }, + { + "mapId": 450061, + "name": "オンゲキ区域7", + "island": "maimaiDX BUDDiES", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 650000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 500001, + "name": "天空街区域6", + "island": "maimaiDX PRiSM", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 800000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 500002, + "name": "天界区域8", + "island": "maimaiDX PRiSM", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 1100000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 500003, + "name": "BLACK ROSE区域10", + "island": "maimaiDX PRiSM", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 800000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 500004, + "name": "大都会区域9", + "island": "maimaiDX PRiSM", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 1400000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 500005, + "name": "棱镜区域", + "island": "maimaiDX PRiSM", + "collabo": false, + "infinity": true, + "version": "A000", + "endDistance": 0, + "slots": 13, + "bonusMagnification": 2000 + }, + { + "mapId": 500052, + "name": "かいりきベア区域2", + "island": "maimaiDX PRiSM", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 300000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 500053, + "name": "MonsterZ MATE区域", + "island": "maimaiDX PRiSM", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 250000, + "slots": 12, + "bonusMagnification": 2000 + }, + { + "mapId": 500054, + "name": "おめがシスターズ区域", + "island": "maimaiDX PRiSM", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 200000, + "slots": 7, + "bonusMagnification": 2000 + }, + { + "mapId": 500055, + "name": "ワールドダイスター 夢のステラリウム区域", + "island": "maimaiDX PRiSM", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 550000, + "slots": 17, + "bonusMagnification": 2000 + }, + { + "mapId": 500056, + "name": "夢限大みゅーたいぷ区域", + "island": "maimaiDX PRiSM", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 300000, + "slots": 12, + "bonusMagnification": 2000 + }, + { + "mapId": 500057, + "name": "Arcaea区域3", + "island": "maimaiDX PRiSM", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 750000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 500058, + "name": "重音テト区域", + "island": "maimaiDX PRiSM", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 500000, + "slots": 16, + "bonusMagnification": 2000 + }, + { + "mapId": 500059, + "name": "ななひら区域", + "island": "maimaiDX PRiSM", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 350000, + "slots": 11, + "bonusMagnification": 2000 + }, + { + "mapId": 500060, + "name": "オンゲキ区域8", + "island": "maimaiDX PRiSM", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 750000, + "slots": 23, + "bonusMagnification": 2000 + }, + { + "mapId": 550001, + "name": "七彩区域", + "island": "maimaiDX PRiSM", + "collabo": false, + "infinity": false, + "version": "A000", + "endDistance": 900000, + "slots": 12, + "bonusMagnification": 2000 + }, + { + "mapId": 550002, + "name": "龙之区域4", + "island": "maimaiDX PRiSM", + "collabo": false, + "infinity": false, + "version": "A015", + "endDistance": 1200000, + "slots": 10, + "bonusMagnification": 2000 + }, + { + "mapId": 550003, + "name": "7sRef区域4", + "island": "maimaiDX PRiSM", + "collabo": false, + "infinity": false, + "version": "A031", + "endDistance": 2000000, + "slots": 27, + "bonusMagnification": 2000 + }, + { + "mapId": 550004, + "name": "棱镜区域2", + "island": "maimaiDX PRiSM", + "collabo": false, + "infinity": true, + "version": "A000", + "endDistance": 0, + "slots": 13, + "bonusMagnification": 2000 + }, + { + "mapId": 550051, + "name": "NEEDY GIRL OVERDOSE区域2", + "island": "maimaiDX PRiSM", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 350000, + "slots": 15, + "bonusMagnification": 2000 + }, + { + "mapId": 550052, + "name": "神椿市協奏中。区域", + "island": "maimaiDX PRiSM", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 300000, + "slots": 12, + "bonusMagnification": 2000 + }, + { + "mapId": 550054, + "name": "那須どうぶつ王国区域", + "island": "maimaiDX PRiSM", + "collabo": true, + "infinity": false, + "version": "A015", + "endDistance": 200000, + "slots": 9, + "bonusMagnification": 2000 + }, + { + "mapId": 550055, + "name": "DECO*27区域2", + "island": "maimaiDX PRiSM", + "collabo": true, + "infinity": false, + "version": "A011", + "endDistance": 350000, + "slots": 13, + "bonusMagnification": 2000 + }, + { + "mapId": 550056, + "name": "ビートまりお区域", + "island": "maimaiDX PRiSM", + "collabo": true, + "infinity": false, + "version": "A011", + "endDistance": 600000, + "slots": 12, + "bonusMagnification": 2000 + }, + { + "mapId": 550057, + "name": "小春六花・夏色花梨・花隈千冬区域", + "island": "maimaiDX PRiSM", + "collabo": true, + "infinity": false, + "version": "A041", + "endDistance": 500000, + "slots": 20, + "bonusMagnification": 2000 + }, + { + "mapId": 550058, + "name": "CHUNITHM区域4", + "island": "maimaiDX PRiSM", + "collabo": true, + "infinity": false, + "version": "A021", + "endDistance": 800000, + "slots": 14, + "bonusMagnification": 2000 + }, + { + "mapId": 550059, + "name": "三枝明那区域", + "island": "maimaiDX PRiSM", + "collabo": true, + "infinity": false, + "version": "A021", + "endDistance": 300000, + "slots": 9, + "bonusMagnification": 2000 + }, + { + "mapId": 550060, + "name": "Phigros区域", + "island": "maimaiDX PRiSM", + "collabo": true, + "infinity": false, + "version": "A041", + "endDistance": 750000, + "slots": 12, + "bonusMagnification": 2000 + }, + { + "mapId": 600059, + "name": "Paradigm: Reboot区域", + "island": "maimaiDX PRiSM", + "collabo": true, + "infinity": false, + "version": "A000", + "endDistance": 700000, + "slots": 10, + "bonusMagnification": 2000 + } +] \ No newline at end of file diff --git a/maipulse/html/assets/icons/map.svg b/maipulse/html/assets/icons/map.svg new file mode 100644 index 0000000..02d5667 --- /dev/null +++ b/maipulse/html/assets/icons/map.svg @@ -0,0 +1,19 @@ + + + + + + + + \ No newline at end of file diff --git a/maipulse/html/index.html b/maipulse/html/index.html index a801772..6feacfd 100644 --- a/maipulse/html/index.html +++ b/maipulse/html/index.html @@ -316,6 +316,7 @@ .card[data-tab]{display:none;grid-column:1/-1} body[data-tab="home"] .card[data-tab="home"], body[data-tab="ticket"] .card[data-tab="ticket"], + body[data-tab="map"] .card[data-tab="map"], body[data-tab="b50"] .card[data-tab="b50"], body[data-tab="risk"] .card[data-tab="risk"], body[data-tab="settings"] .card[data-tab="settings"]{display:block} @@ -556,6 +557,50 @@
+
+

一键跑图

+

推进区域地图进度。走 UpsertUserAll 的 userMapList 差分 —— + 只回传 distance 变化的那一条。

+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ + +
+
+
+
⚠️ 高风险区 @@ -724,6 +769,8 @@
+
+
@@ -774,6 +821,7 @@