# 杂项助手函数 # 主要用于当作模块使用的时候的一些生活质量提升 import rapidjson as json from loguru import logger from HelperGetUserThing import implGetUser_ import unicodedata from HelperLogInOut import apiLogin, apiLogout, generateTimestamp from MyConfig import testUid def numberToLetter(number): """ 将数字转换为字母(1-26 to A-Z) """ if 1 <= number <= 26: return chr(number + 64) else: return None def maimaiVersionToHumanReadable(romVersion: str, dataVersion: str) -> str: try: romVersionList = romVersion.split(".") dataVersionList = dataVersion.split(".") except Exception as e: logger.warning(f"无法解析版本号: {romVersion} {dataVersion},错误:{e}") return "无效版本号:无法解析" try: romVersionList = [int(i) for i in romVersionList] dataVersionList = [int(i) for i in dataVersionList] except Exception as e: logger.warning(f"无法解析版本号: {romVersion} {dataVersion},错误:{e}") return "无效版本号:无法解读数字" finalVersionList = [] finalVersionList.append(romVersionList[0]) # quirk minorVer = max(romVersionList[1], dataVersionList[1]) if minorVer == 0: finalVersionList.append("00") else: finalVersionList.append(minorVer) finalVersionLetter = numberToLetter(max(romVersionList[2], dataVersionList[2])) if finalVersionLetter: finalVersionLetter = f"-{finalVersionLetter}" else: finalVersionLetter = "" finalVersionList.append(finalVersionLetter) if int(finalVersionList[1]) < 30: versionStringPrefix = "CH" else: versionStringPrefix = "CN" finalVersionString = f"{versionStringPrefix}{finalVersionList[0]}.{finalVersionList[1]}{finalVersionList[2]}" return finalVersionString levelIdDict = {"绿": 0, "黄": 1, "红": 2, "紫": 3, "白": 4, "宴": 5} def getHalfWidthString(s): """全角转半角,舞萌ID用""" return unicodedata.normalize("NFKC", s) def getHumanReadableLoginErrorCode(loginResult) -> str: """解析登录结果并且给出中文的报错解释""" match loginResult["returnCode"]: case 1: return False case 100: return "❌ 用户正在上机游玩,请下机后再试,或等待 15 分钟。" case 102: return "⚠️ 请在微信公众号内点击一次获取新的二维码,然后再试。" case 103: return "❌ 试图登录的账号 UID 无效,请检查账号是否正确。" case _: return "❌ 登录失败!这不应该发生,请反馈此问题。错误详情:" + loginResult def checkTechnologyUseCount(userId: int) -> int: """猜测账号是否用了科技,0没用过,其他为用过""" userData1 = implGetUser_("Data", userId) userData = userData1.get("userData", {}) userRegion = implGetUser_("Region", userId) userRegionList = userRegion.get("userRegionList", []) playCount = userData.get("playCount", 0) allRegionPlayCount = 0 for region in userRegionList: allRegionPlayCount += region.get("playCount", 0) logger.info( f"用户 {userId} 的总游玩次数: {playCount}, 各地区游玩次数: {allRegionPlayCount}" ) # 计算全部的 Region 加起来的游玩次数是否和 playCount 对不上,对不上就是用了科技 # 返回差值 return playCount - allRegionPlayCount def getFriendlyUserData(userId: int) -> str: """生成一个(相对)友好的UserData的人话""" userData1 = implGetUser_("Data", userId) userData = userData1.get("userData", {}) userRegion = implGetUser_("Region", userId) banState = userData1.get("banState") result = f"用户: {getHalfWidthString(userData.get('userName', '未知'))}\n" result += f"DX RATING: {userData.get('playerRating', '未知')} " result += f"B35: {userData.get('playerOldRating', '未知')} " result += f"B15: {userData.get('playerNewRating', '未知')}\n" result += f"总游戏次数: {userData.get('playCount', '未知')} " result += f"当前版本游戏次数: {userData.get('currentPlayCount', '未知')}\n" result += f"最近登录时间: {userData.get('lastLoginDate')} " result += f"最近登录版本: {maimaiVersionToHumanReadable(userData.get('lastRomVersion'), userData.get('lastDataVersion'))} " result += f"最近登录地区: {userData.get('lastRegionName', '未知')}\n" result += f"注册日期: {userData.get('firstPlayDate')} " result += f"注册版本: {maimaiVersionToHumanReadable(userData.get('firstRomVersion'), userData.get('firstDataVersion'))}\n" result += f"封号状态(banState): {banState}\n" try: logger.info(userRegion) result += getHumanReadableRegionData(userRegion) except Exception as e: result += f"地区数据获取失败:{e}\n" return result def getHumanReadableRegionData(userRegion: str) -> str: """生成一个人类可读的地区数据""" userRegionList = userRegion.get("userRegionList") logger.info(userRegionList) result = "" for region in userRegionList: regionName = WAHLAP_REGIONS.get(region["regionId"], "未知") playCount = region["playCount"] created = region["created"] result += f"\n{regionName} 游玩次数: {playCount} 首次游玩: {created}" return result def getHumanReadablePreview(preview_json_content: str) -> str: """简单,粗略地解释 Preview 的 Json String 为人话。""" previewData = json.loads(preview_json_content) userName = getHalfWidthString(previewData["userName"]) playerRating = previewData["playerRating"] finalString = f"用户名:{userName}\nDX RATING:{playerRating}\n" return finalString def getHumanReadableLoginBonusList(jsonString: str): """生成一个人类可读的 Login Bonus 的列表""" data = json.loads(jsonString) result = [] for bonus in data["userLoginBonusList"]: if not bonus["isComplete"]: # 过滤已经集满的 line = f"BonusID {bonus['bonusId']} 已集 {bonus['point']} 点" if bonus["isCurrent"]: # 如果是当前选中,追加标记 line += "(当前选中)" result.append(line) resultString = "" for line in result: # 转成字符串 resultString += line + "\n" return resultString def getHumanReadableTicketList(jsonString: str): """生成一个人类可读的 UserCharge 的列表""" data = json.loads(jsonString) userId = data["userId"] length = data["length"] userChargeList = data["userChargeList"] result = f"UID: {userId} 票槽大小: {length} 所有记录:" for currentItem in userChargeList: chargeId = currentItem["chargeId"] stock = currentItem["stock"] purchaseDate = currentItem["purchaseDate"] validDate = currentItem["validDate"] result += f"\nID: {chargeId} 持有: {stock}, 购买日期: {purchaseDate}, 有效期限: {validDate}" return result def getHumanReadableUserData(userData) -> str: """生成一个人类可读的 UserData 的数据(比较详细)""" userId = userData.get("userId") userData = userData.get("userData", {}) banState = userData.get("banState") logger.debug(userData) result = f"用户名: {userData.get('userName', '未知')} " result += f"UID: {userId}\n" result += f"当前 RATING: {userData.get('playerRating', '未知')} " result += f"B35: {userData.get('playerOldRating', '未知')} " result += f"B15: {userData.get('playerNewRating', '未知')} " result += f"最高 RATING: {userData.get('highestRating', '未知')}\n" result += f"级别段位: {userData.get('gradeRank', '未知')} " result += f"段位认定: {userData.get('courseRank', '未知')} " result += f"友人对战段位: {userData.get('classRank', '未知')}\n" result += f"总游戏次数: {userData.get('playCount', '未知')} " result += f"当前版本游戏次数: {userData.get('currentPlayCount', '未知')}\n" result += f"总DX分: {userData.get('totalDeluxscore', '未知')} " result += f"绿谱总DX分: {userData.get('totalBasicDeluxscore', '未知')} " result += f"黄谱总DX分: {userData.get('totalAdvancedDeluxscore', '未知')} " result += f"红谱总DX分: {userData.get('totalExpertDeluxscore', '未知')} " result += f"紫谱总DX分: {userData.get('totalMasterDeluxscore', '未知')} " result += f"白谱总DX分: {userData.get('totalReMasterDeluxscore', '未知')}\n" result += f"总SYNC: {userData.get('totalSync', '未知')} " result += f"绿谱总SYNC: {userData.get('totalBasicSync', '未知')} " result += f"黄谱总SYNC: {userData.get('totalAdvancedSync', '未知')} " result += f"红谱总SYNC: {userData.get('totalExpertSync', '未知')} " result += f"紫谱总SYNC: {userData.get('totalMasterSync', '未知')} " result += f"白谱总SYNC: {userData.get('totalReMasterSync', '未知')}\n" result += f"总分: {userData.get('totalAchievement', '未知')} " result += f"绿谱总分: {userData.get('totalBasicAchievement', '未知')} " result += f"黄谱总分: {userData.get('totalAdvancedAchievement', '未知')} " result += f"红谱总分: {userData.get('totalExpertAchievement', '未知')} " result += f"紫谱总分: {userData.get('totalMasterAchievement', '未知')} " result += f"白谱总分: {userData.get('totalReMasterAchievement', '未知')}\n" result += f"活动事件日期: {userData.get('eventWatchedDate')}\n" result += f"最后 ROM 版本: {userData.get('lastRomVersion', '未知')}\n" result += f"最后数据版本: {userData.get('lastDataVersion', '未知')}\n" result += f"最后登录时间: {userData.get('lastLoginDate')}\n" result += f"最后游戏时间: {userData.get('lastPlayDate')}\n" result += f"最后双人登录时间: {userData.get('lastPairLoginDate')}\n" result += f"最后免费游戏时间: {userData.get('lastTrialPlayDate')}\n" result += f"最后游戏花费: {userData.get('lastPlayCredit', '未知')}\n" result += f"最后地区 ID: {userData.get('lastRegionId', '未知')}\n" result += f"最后地区名称: {userData.get('lastRegionName', '未知')}\n" result += f"最后选择功能票: {userData.get('lastSelectTicket', '未知')}\n" result += f"最后一次段位认定: {userData.get('lastSelectCourse', '未知')}\n" result += f"最后一次 Course 计数: {userData.get('lastCountCourse', '未知')}\n" result += f"注册 ROM 版本: {userData.get('firstRomVersion', '未知')}\n" result += f"注册数据版本: {userData.get('firstDataVersion', '未知')}\n" result += f"注册日期: {userData.get('firstPlayDate')}\n" result += f"总觉醒: {userData.get('totalAwake', '未知')}\n" result += f"签到日期: {userData.get('dailyCourseBonusDate')}\n" result += f"跑图存储距离: {userData.get('mapStock', '未知')}m\n" result += f"封号状态: {banState}\n" return result WAHLAP_REGIONS = { 1: "北京", 2: "重庆", 3: "上海", 4: "天津", 5: "安徽", 6: "福建", 7: "甘肃", 8: "广东", 9: "贵州", 10: "海南", 11: "河北", 12: "黑龙江", 13: "河南", 14: "湖北", 15: "湖南", 16: "江苏", 17: "江西", 18: "吉林", 19: "辽宁", 20: "青海", 21: "陕西", 22: "山东", 23: "山西", 24: "四川", 25: "(未知25)", 26: "云南", 27: "浙江", 28: "广西", 29: "内蒙古", 30: "宁夏", 31: "新疆", 32: "西藏", } if __name__ == "__main__": # test version string convert print(maimaiVersionToHumanReadable("1.20.0", "1.0.0")) print(maimaiVersionToHumanReadable("1.41.00", "1.40.11")) print(maimaiVersionToHumanReadable("1.00.00", "1.00.00")) userId = testUid currentLoginTimestamp = generateTimestamp() loginResult = apiLogin(currentLoginTimestamp, userId) if loginResult["returnCode"] != 1: logger.info("登录失败") exit() try: logger.info(checkTechnologyUseCount(userId)) # logger.info(apiQueryTicket(userId)) finally: logger.info(apiLogout(currentLoginTimestamp, userId)) # logger.warning("Error")