From 2a12f84dd9ad0691fb39a2509e6c41c548cd177c Mon Sep 17 00:00:00 2001 From: SoulGateKey Date: Sat, 26 Jul 2025 18:42:48 +0800 Subject: [PATCH 1/3] add implement of GetUserFriendCheckApi and UserFriendRegistApi --- titles/mai2/buddiesplus.py | 67 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/titles/mai2/buddiesplus.py b/titles/mai2/buddiesplus.py index e87fae6..fc0bcfb 100644 --- a/titles/mai2/buddiesplus.py +++ b/titles/mai2/buddiesplus.py @@ -58,3 +58,70 @@ class Mai2BuddiesPlus(Mai2Buddies): "friendBonusFlag": False } } + + async def handle_get_user_friend_check_api_request(self, data: Dict) -> Dict: + user1rivalList = await self.data.profile.get_rivals(data["userId1"]) + user2rivalList = await self.data.profile.get_rivals(data["userId2"]) + + is_user2_in_user1_rivals = any(rival["rival"] == data["userId2"] for rival in user1rivalList) + is_user1_in_user2_rivals = any(rival["rival"] == data["userId1"] for rival in user2rivalList) + + if is_user2_in_user1_rivals and is_user1_in_user2_rivals: + return {"returnCode": 0} + else: + return {"returnCode": 1} + + async def handle_user_friend_regist_api_request(self, data: Dict) -> Dict: + user1rivalList = await self.data.profile.get_rivals(data["userId1"]) or [] + user2rivalList = await self.data.profile.get_rivals(data["userId2"]) or [] + + is_user2_in_user1_rivals = any(rival["rival"] == data["userId2"] for rival in user1rivalList) + is_user1_in_user2_rivals = any(rival["rival"] == data["userId1"] for rival in user2rivalList) + user1_show_count = sum(1 for rival in user1rivalList if rival.get("show") == 1) + user2_show_count = sum(1 for rival in user2rivalList if rival.get("show") == 1) + + # initialize returnCode + returnCode1 = 2 + returnCode2 = 2 + + # Case1 no rival + if not is_user2_in_user1_rivals and not is_user1_in_user2_rivals: + if user1_show_count >= 3 and user2_show_count >= 3: + returnCode1, returnCode2 = 1, 1 + elif user1_show_count >= 3: + returnCode1, returnCode2 = 1, 2 + elif user2_show_count >= 3: + returnCode1, returnCode2 = 2, 1 + + # Case2 has single rival + elif is_user2_in_user1_rivals != is_user1_in_user2_rivals: + if is_user2_in_user1_rivals and not is_user1_in_user2_rivals: + if user1_show_count >= 3 and user2_show_count >= 3: + returnCode1, returnCode2 = 1, 1 + elif user1_show_count >= 3: + returnCode1, returnCode2 = 1, 2 + elif user2_show_count >= 3: + returnCode1, returnCode2 = 2, 1 + else: + if user1_show_count >= 3 and user2_show_count >= 3: + returnCode1, returnCode2 = 1, 1 + elif user1_show_count >= 3: + returnCode1, returnCode2 = 1, 2 + elif user2_show_count >= 3: + returnCode1, returnCode2 = 2, 1 + + # execute add_rival and show_rival + if not is_user2_in_user1_rivals: + await self.data.profile.add_rival(data["userId1"], data["userId2"]) + if returnCode1 == 2 and user1_show_count < 3: + await self.data.profile.set_rival_shown(data["userId1"], data["userId2"], True) + + if not is_user1_in_user2_rivals: + await self.data.profile.add_rival(data["userId2"], data["userId1"]) + if returnCode2 == 2 and user2_show_count < 3: + await self.data.profile.set_rival_shown(data["userId2"], data["userId1"], True) + + return { + "returnCode1": returnCode1, + "returnCode2": returnCode2 + } \ No newline at end of file From 1833e8abdeba8feaad9eaf9483ab622c316c9e2d Mon Sep 17 00:00:00 2001 From: SoulGateKey Date: Sun, 27 Jul 2025 03:06:30 +0800 Subject: [PATCH 2/3] add mai2 rival management features to frontend and templates --- titles/mai2/frontend.py | 42 ++++++++- titles/mai2/templates/mai2_index.jinja | 119 +++++++++++++++++++++++++ 2 files changed, 160 insertions(+), 1 deletion(-) diff --git a/titles/mai2/frontend.py b/titles/mai2/frontend.py index c760e13..aa030b8 100644 --- a/titles/mai2/frontend.py +++ b/titles/mai2/frontend.py @@ -46,6 +46,9 @@ class Mai2Frontend(FE_Base): Route("/update.name", self.update_name, methods=['POST']), Route("/version.change", self.version_change, methods=['POST']), Route("/photo/{photo_id}", self.get_photo, methods=['GET']), + Route("/rival.add", self.rival_POST, methods=['POST']), + Route("/rival.delete", self.rival_POST, methods=['POST']), + Route("/rival.show", self.rival_POST, methods=['POST']), ] async def render_GET(self, request: Request) -> bytes: @@ -61,11 +64,22 @@ class Mai2Frontend(FE_Base): if usr_sesh.user_id > 0: versions = await self.data.profile.get_all_profile_versions(usr_sesh.user_id) profile = [] + new_rival_list = [] if versions: # maimai_version is -1 means it is not initialized yet, select a default version from existing. if incoming_ver < 0: usr_sesh.maimai_version = versions[0]['version'] profile = await self.data.profile.get_profile_detail(usr_sesh.user_id, usr_sesh.maimai_version) + rival_list = await self.data.profile.get_rivals(usr_sesh.user_id) + + for rival in rival_list: + rivalid = rival["rival"] + rivalShow = rival["show"] + rivalprofile = await self.data.profile.get_profile_detail(rivalid, usr_sesh.maimai_version) + rivalName = rivalprofile["userName"] if rivalprofile else "UnknownName" + rivalRating = rivalprofile["playerRating"] if rivalprofile else 0 + new_rival = (rivalName, rivalRating, rivalid, rivalShow) + new_rival_list.append(new_rival) versions = [x['version'] for x in versions] resp = Response(template.render( @@ -76,7 +90,8 @@ class Mai2Frontend(FE_Base): profile=profile, version_list=Mai2Constants.VERSION_STRING, versions=versions, - cur_version=usr_sesh.maimai_version + cur_version=usr_sesh.maimai_version, + rival_list=new_rival_list ), media_type="text/html; charset=utf-8") if incoming_ver < 0: @@ -420,3 +435,28 @@ class Mai2Frontend(FE_Base): return FileResponse(f"{out_folder}.jpeg") return Response(status_code=404) + async def rival_POST(self, request: Request): + uri = request.url.path + frm = await request.form() + usr_sesh = self.validate_session(request) + if not usr_sesh: + usr_sesh = UserSession() + + if usr_sesh.user_id > 0: + if uri == "/game/mai2/rival.add": + rival_id = frm.get("rivalUserId") + await self.data.profile.add_rival(usr_sesh.user_id, rival_id) + # self.logger.info(f"{usr_sesh.user_id} added a rival") + return RedirectResponse("/game/mai2/", 303) + + elif uri == "/game/mai2/rival.delete": + rival_id = frm.get("rivalUserId") + await self.data.profile.remove_rival(usr_sesh.user_id, rival_id) + # self.logger.info(f"{response}") + return RedirectResponse("/game/mai2/", 303) + + elif uri == "/game/mai2/rival.show": + rival_id = frm.get("rivalUserId") + show = frm.get("showRival", "false") == "true" + await self.data.profile.set_rival_shown(usr_sesh.user_id, rival_id, show) + return RedirectResponse("/game/mai2/", 303) \ No newline at end of file diff --git a/titles/mai2/templates/mai2_index.jinja b/titles/mai2/templates/mai2_index.jinja index 6490fdc..50ebb72 100644 --- a/titles/mai2/templates/mai2_index.jinja +++ b/titles/mai2/templates/mai2_index.jinja @@ -17,6 +17,10 @@ + + ID: + {{ profile.user }} + version: @@ -86,6 +90,40 @@ +
+
+ + + + + + + + + + {% for rival in rival_list %} + + + + + + + + {% endfor %} +
+ RIVALS + +
IdNameRatingShow
{{ rival.2 }}{{ rival.0 }}{{ rival.1 }} +
+ +
+
+ +
+
{% if error is defined %} @@ -120,6 +158,75 @@ + +{% for rival in rival_list %} + +{% endfor %} +{% for rival in rival_list %} + +{% endfor %} +{% for rival in rival_list %} + +{% endfor %} {% endblock content %} \ No newline at end of file From de8294820a973466dc362545fd030eccc5f330a2 Mon Sep 17 00:00:00 2001 From: SoulGateKey Date: Fri, 1 Aug 2025 00:54:48 +0800 Subject: [PATCH 3/3] UserFriendRegist Bugfix --- titles/mai2/buddiesplus.py | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/titles/mai2/buddiesplus.py b/titles/mai2/buddiesplus.py index fc0bcfb..6ed0025 100644 --- a/titles/mai2/buddiesplus.py +++ b/titles/mai2/buddiesplus.py @@ -75,10 +75,10 @@ class Mai2BuddiesPlus(Mai2Buddies): user1rivalList = await self.data.profile.get_rivals(data["userId1"]) or [] user2rivalList = await self.data.profile.get_rivals(data["userId2"]) or [] - is_user2_in_user1_rivals = any(rival["rival"] == data["userId2"] for rival in user1rivalList) - is_user1_in_user2_rivals = any(rival["rival"] == data["userId1"] for rival in user2rivalList) - user1_show_count = sum(1 for rival in user1rivalList if rival.get("show") == 1) - user2_show_count = sum(1 for rival in user2rivalList if rival.get("show") == 1) + is_user2_in_user1_rivals = any(row.rival == data["userId2"] for row in user1rivalList) + is_user1_in_user2_rivals = any(row.rival == data["userId1"] for row in user2rivalList) + user1_show_count = sum(1 for row in user1rivalList if row.show is True) + user2_show_count = sum(1 for row in user2rivalList if row.show is True) # initialize returnCode returnCode1 = 2 @@ -95,20 +95,12 @@ class Mai2BuddiesPlus(Mai2Buddies): # Case2 has single rival elif is_user2_in_user1_rivals != is_user1_in_user2_rivals: - if is_user2_in_user1_rivals and not is_user1_in_user2_rivals: - if user1_show_count >= 3 and user2_show_count >= 3: - returnCode1, returnCode2 = 1, 1 - elif user1_show_count >= 3: - returnCode1, returnCode2 = 1, 2 - elif user2_show_count >= 3: - returnCode1, returnCode2 = 2, 1 - else: - if user1_show_count >= 3 and user2_show_count >= 3: - returnCode1, returnCode2 = 1, 1 - elif user1_show_count >= 3: - returnCode1, returnCode2 = 1, 2 - elif user2_show_count >= 3: - returnCode1, returnCode2 = 2, 1 + if user1_show_count >= 3 and user2_show_count >= 3: + returnCode1, returnCode2 = 1, 1 + elif user1_show_count >= 3: + returnCode1, returnCode2 = 1, 2 + elif user2_show_count >= 3: + returnCode1, returnCode2 = 2, 1 # execute add_rival and show_rival if not is_user2_in_user1_rivals: