as: Support playing lives

Only support "Sweet Eyes" currently.

Signed-off-by: Yuan Si <do4suki@gmail.com>
This commit is contained in:
2023-06-07 07:01:37 +08:00
parent 2d207cfd68
commit affc960a95
8 changed files with 4025 additions and 6 deletions
+3
View File
@@ -0,0 +1,3 @@
{
"last_play_live_difficulty_deck": null
}
+239
View File
@@ -0,0 +1,239 @@
{
"partner_select_state": {
"live_partners": [
{
"user_id": 666666666,
"name": {
"dot_under_text": "B站主播:梦路_YumeMichi"
},
"rank": 1,
"last_login_at": 1685971269,
"card_by_category": [
1,
{
"card_master_id": 302073002,
"level": 80,
"grade": 5,
"love_level": 1,
"is_awakening": true,
"is_awakening_image": true,
"is_all_training_activated": true,
"active_skill_level": 5,
"passive_skill_levels": [
7,
1
],
"additional_passive_skill_ids": [
30000507,
30000507,
30000507,
30000452,
0,
0,
0,
0,
0
],
"max_free_passive_skill": 4,
"training_stamina": 4488,
"training_appeal": 9213,
"training_technique": 9922,
"member_love_panels": []
},
2,
{
"card_master_id": 200083002,
"level": 80,
"grade": 5,
"love_level": 1,
"is_awakening": true,
"is_awakening_image": true,
"is_all_training_activated": true,
"active_skill_level": 5,
"passive_skill_levels": [
5,
1
],
"additional_passive_skill_ids": [
30000507,
30000507,
30000507,
30000452,
0,
0,
0,
0,
0
],
"max_free_passive_skill": 4,
"training_stamina": 10800,
"training_appeal": 6000,
"training_technique": 7200,
"member_love_panels": []
},
3,
{
"card_master_id": 200013002,
"level": 80,
"grade": 5,
"love_level": 1,
"is_awakening": true,
"is_awakening_image": true,
"is_all_training_activated": true,
"active_skill_level": 5,
"passive_skill_levels": [
5,
1
],
"additional_passive_skill_ids": [
30000507,
30000507,
30000507,
30000452,
0,
0,
0,
0,
0
],
"max_free_passive_skill": 4,
"training_stamina": 4950,
"training_appeal": 9900,
"training_technique": 9900,
"member_love_panels": []
},
4,
{
"card_master_id": 200063002,
"level": 80,
"grade": 5,
"love_level": 1,
"is_awakening": true,
"is_awakening_image": true,
"is_all_training_activated": true,
"active_skill_level": 5,
"passive_skill_levels": [
5,
1
],
"additional_passive_skill_ids": [
30000507,
30000507,
30000507,
30000452,
0,
0,
0,
0,
0
],
"max_free_passive_skill": 4,
"training_stamina": 3655,
"training_appeal": 10237,
"training_technique": 10480,
"member_love_panels": []
},
5,
{
"card_master_id": 201043002,
"level": 80,
"grade": 5,
"love_level": 1,
"is_awakening": true,
"is_awakening_image": true,
"is_all_training_activated": true,
"active_skill_level": 5,
"passive_skill_levels": [
5,
1
],
"additional_passive_skill_ids": [
30000507,
30000507,
30000507,
30000452,
0,
0,
0,
0,
0
],
"max_free_passive_skill": 4,
"training_stamina": 3655,
"training_appeal": 9505,
"training_technique": 11212,
"member_love_panels": []
},
6,
{
"card_master_id": 101032001,
"level": 60,
"grade": 5,
"love_level": 1,
"is_awakening": true,
"is_awakening_image": true,
"is_all_training_activated": true,
"active_skill_level": 5,
"passive_skill_levels": [
5,
1
],
"additional_passive_skill_ids": [
30000512,
30000512,
30000462,
0,
0,
0,
0,
0,
0
],
"max_free_passive_skill": 3,
"training_stamina": 3920,
"training_appeal": 3360,
"training_technique": 3920,
"member_love_panels": []
},
7,
{
"card_master_id": 201033001,
"level": 80,
"grade": 5,
"love_level": 1,
"is_awakening": true,
"is_awakening_image": true,
"is_all_training_activated": true,
"active_skill_level": 5,
"passive_skill_levels": [
5,
1
],
"additional_passive_skill_ids": [
30000507,
30000507,
30000507,
30000507,
0,
0,
0,
0,
0
],
"max_free_passive_skill": 4,
"training_stamina": 4575,
"training_appeal": 10522,
"training_technique": 7777,
"member_love_panels": []
}
],
"emblem_id": 1106001,
"is_friend": true,
"introduction_message": {
"dot_under_text": "B站主播:梦路_YumeMichi"
}
}
],
"friend_count": 1
}
}
+161
View File
@@ -0,0 +1,161 @@
{
"live_result": {
"live_difficulty_master_id": "LIVE_DIFFICULTY_ID",
"live_deck_id": "DECK_ID",
"standard_drops": [],
"additional_drops": [],
"gimmick_drops": [],
"member_love_statuses": [],
"mvp": "MVP_INFO",
"partner": "PARTNER_INFO",
"live_result_achievements": [
1,
{
"position": 1,
"is_already_achieved": true,
"is_currently_achieved": false
},
2,
{
"position": 2,
"is_already_achieved": true,
"is_currently_achieved": false
},
3,
{
"position": 3,
"is_already_achieved": true,
"is_currently_achieved": false
}
],
"live_result_achievement_status": "LIVE_RESULT",
"voltage": "LIVE_VOLTAGE",
"last_best_voltage": "LIVE_VOLTAGE",
"before_user_exp": 416799,
"gain_user_exp": 34,
"is_reward_accessory_in_present_box": false,
"active_event_result": null,
"live_result_tower": null,
"live_result_member_guild": null
},
"user_model_diff": {
"user_status": {
"name": {
"dot_under_text": "梦路2号机@果果厨"
},
"nickname": {
"dot_under_text": "梦路"
},
"last_login_at": 1685956564,
"rank": 122,
"exp": 416833,
"message": {
"dot_under_text": "B站主播:梦路_YumeMichi"
},
"recommend_card_master_id": 200013001,
"max_friend_num": 0,
"live_point_full_at": 1685961172,
"live_point_broken": 150,
"live_point_subscription_recovery_daily_count": 1,
"live_point_subscription_recovery_daily_reset_at": 1656259200,
"activity_point_count": 0,
"activity_point_reset_at": 1684123200,
"activity_point_payment_recovery_daily_count": 10,
"activity_point_payment_recovery_daily_reset_at": 1683734400,
"game_money": 115773389,
"card_exp": 32445167,
"free_sns_coin": 360,
"apple_sns_coin": 0,
"google_sns_coin": 0,
"cash": 0,
"subscription_coin": 30,
"birth_date": null,
"birth_month": 10,
"birth_day": 18,
"latest_live_deck_id": "DECK_ID",
"main_lesson_deck_id": 1,
"favorite_member_id": 1,
"last_live_difficulty_id": "LIVE_DIFFICULTY_ID",
"lp_magnification": 1,
"emblem_id": 10400253,
"device_token": "",
"tutorial_phase": 99,
"tutorial_end_at": 1622217482,
"login_days": 450,
"navi_tap_count": 1,
"navi_tap_recover_at": 1685030400,
"is_auto_mode": false,
"max_score_live_difficulty_master_id": 12037401,
"live_max_score": 40553270,
"max_combo_live_difficulty_master_id": 12037401,
"live_max_combo": 301,
"lesson_resume_status": 1,
"accessory_box_additional": 90,
"terms_of_use_version": 0,
"bootstrap_sifid_check_at": 1683178908,
"gdpr_version": 0,
"member_guild_member_master_id": 1,
"member_guild_last_updated_at": 1659485328
},
"user_member_by_member_id": [],
"user_card_by_card_id": [],
"user_suit_by_suit_id": [],
"user_live_deck_by_id": [],
"user_live_party_by_id": [],
"user_lesson_deck_by_id": [],
"user_live_mv_deck_by_id": [],
"user_live_mv_deck_custom_by_id": [],
"user_live_difficulty_by_difficulty_id": [],
"user_story_main_by_story_main_id": [],
"user_story_main_selected_by_story_main_cell_id": [],
"user_voice_by_voice_id": [],
"user_emblem_by_emblem_id": [],
"user_gacha_ticket_by_ticket_id": [],
"user_gacha_point_by_point_id": [],
"user_lesson_enhancing_item_by_item_id": [],
"user_training_material_by_item_id": [],
"user_grade_up_item_by_item_id": [],
"user_custom_background_by_id": [],
"user_story_side_by_id": [],
"user_story_member_by_id": [],
"user_communication_member_detail_badge_by_id": [],
"user_story_event_history_by_id": [],
"user_recovery_lp_by_id": [],
"user_recovery_ap_by_id": [],
"user_mission_by_mission_id": [],
"user_daily_mission_by_mission_id": [],
"user_weekly_mission_by_mission_id": [],
"user_info_trigger_basic_by_trigger_id": [],
"user_info_trigger_card_grade_up_by_trigger_id": [],
"user_info_trigger_member_guild_support_item_expired_by_trigger_id": [],
"user_info_trigger_member_love_level_up_by_trigger_id": [],
"user_accessory_by_user_accessory_id": [],
"user_accessory_level_up_item_by_id": [],
"user_accessory_rarity_up_item_by_id": [],
"user_unlock_scenes_by_enum": [],
"user_scene_tips_by_enum": [],
"user_rule_description_by_id": [],
"user_exchange_event_point_by_id": [],
"user_school_idol_festival_id_reward_mission_by_id": [],
"user_gps_present_received_by_id": [],
"user_event_marathon_by_event_master_id": [],
"user_event_mining_by_event_master_id": [],
"user_event_coop_by_event_master_id": [],
"user_live_skip_ticket_by_id": [],
"user_story_event_unlock_item_by_id": [],
"user_event_marathon_booster_by_id": [],
"user_reference_book_by_id": [],
"user_review_request_process_flow_by_id": [],
"user_rank_exp_by_id": [],
"user_share_by_id": [],
"user_tower_by_tower_id": [],
"user_recovery_tower_card_used_count_item_by_recovery_tower_card_used_count_item_master_id": [],
"user_story_linkage_by_id": [],
"user_subscription_status_by_id": [],
"user_story_main_part_digest_movie_by_id": [],
"user_member_guild_by_id": [],
"user_member_guild_support_item_by_id": [],
"user_daily_theater_by_daily_theater_id": [],
"user_play_list_by_id": []
}
}
+132
View File
@@ -0,0 +1,132 @@
{
"live": {
"live_id": "LIVE_ID",
"live_type": 1,
"deck_id": "DECK_ID",
"live_stage": "LIVE_NOTES",
"live_partner_card": "LIVE_PARTNER",
"is_partner_friend": true,
"cell_id": null,
"tower_live": null
},
"user_model_diff": {
"user_status": {
"name": {
"dot_under_text": "梦路2号机@果果厨"
},
"nickname": {
"dot_under_text": "梦路"
},
"last_login_at": 1684754024,
"rank": 122,
"exp": 416263,
"message": {
"dot_under_text": "B站主播:梦路_YumeMichi"
},
"recommend_card_master_id": 200013001,
"max_friend_num": 0,
"live_point_full_at": 1684158189,
"live_point_broken": 150,
"live_point_subscription_recovery_daily_count": 1,
"live_point_subscription_recovery_daily_reset_at": 1656259200,
"activity_point_count": 0,
"activity_point_reset_at": 1684123200,
"activity_point_payment_recovery_daily_count": 10,
"activity_point_payment_recovery_daily_reset_at": 1683734400,
"game_money": 115665089,
"card_exp": 32316167,
"free_sns_coin": 280,
"apple_sns_coin": 0,
"google_sns_coin": 0,
"cash": 0,
"subscription_coin": 30,
"birth_date": null,
"birth_month": 10,
"birth_day": 18,
"latest_live_deck_id": "DECK_ID",
"main_lesson_deck_id": 1,
"favorite_member_id": 1,
"last_live_difficulty_id": "LIVE_DIFFICULTY_ID",
"lp_magnification": 1,
"emblem_id": 13100608,
"device_token": "",
"tutorial_phase": 99,
"tutorial_end_at": 1622217482,
"login_days": 446,
"navi_tap_count": 1,
"navi_tap_recover_at": 1683043200,
"is_auto_mode": false,
"max_score_live_difficulty_master_id": 12037401,
"live_max_score": 40553270,
"max_combo_live_difficulty_master_id": 12037401,
"live_max_combo": 301,
"lesson_resume_status": 1,
"accessory_box_additional": 90,
"terms_of_use_version": 0,
"bootstrap_sifid_check_at": 1683178908,
"gdpr_version": 0,
"member_guild_member_master_id": 1,
"member_guild_last_updated_at": 1659485328
},
"user_member_by_member_id": [],
"user_card_by_card_id": [],
"user_suit_by_suit_id": [],
"user_live_deck_by_id": [],
"user_live_party_by_id": [],
"user_lesson_deck_by_id": [],
"user_live_mv_deck_by_id": [],
"user_live_mv_deck_custom_by_id": [],
"user_live_difficulty_by_difficulty_id": [],
"user_story_main_by_story_main_id": [],
"user_story_main_selected_by_story_main_cell_id": [],
"user_voice_by_voice_id": [],
"user_emblem_by_emblem_id": [],
"user_gacha_ticket_by_ticket_id": [],
"user_gacha_point_by_point_id": [],
"user_lesson_enhancing_item_by_item_id": [],
"user_training_material_by_item_id": [],
"user_grade_up_item_by_item_id": [],
"user_custom_background_by_id": [],
"user_story_side_by_id": [],
"user_story_member_by_id": [],
"user_communication_member_detail_badge_by_id": [],
"user_story_event_history_by_id": [],
"user_recovery_lp_by_id": [],
"user_recovery_ap_by_id": [],
"user_mission_by_mission_id": [],
"user_daily_mission_by_mission_id": [],
"user_weekly_mission_by_mission_id": [],
"user_info_trigger_basic_by_trigger_id": [],
"user_info_trigger_card_grade_up_by_trigger_id": [],
"user_info_trigger_member_guild_support_item_expired_by_trigger_id": [],
"user_info_trigger_member_love_level_up_by_trigger_id": [],
"user_accessory_by_user_accessory_id": [],
"user_accessory_level_up_item_by_id": [],
"user_accessory_rarity_up_item_by_id": [],
"user_unlock_scenes_by_enum": [],
"user_scene_tips_by_enum": [],
"user_rule_description_by_id": [],
"user_exchange_event_point_by_id": [],
"user_school_idol_festival_id_reward_mission_by_id": [],
"user_gps_present_received_by_id": [],
"user_event_marathon_by_event_master_id": [],
"user_event_mining_by_event_master_id": [],
"user_event_coop_by_event_master_id": [],
"user_live_skip_ticket_by_id": [],
"user_story_event_unlock_item_by_id": [],
"user_event_marathon_booster_by_id": [],
"user_reference_book_by_id": [],
"user_review_request_process_flow_by_id": [],
"user_rank_exp_by_id": [],
"user_share_by_id": [],
"user_tower_by_tower_id": [],
"user_recovery_tower_card_used_count_item_by_recovery_tower_card_used_count_item_master_id": [],
"user_story_linkage_by_id": [],
"user_subscription_status_by_id": [],
"user_story_main_part_digest_movie_by_id": [],
"user_member_guild_by_id": [],
"user_member_guild_support_item_by_id": [],
"user_daily_theater_by_daily_theater_id": [],
"user_play_list_by_id": []
}
}
File diff suppressed because it is too large Load Diff
-6
View File
@@ -7,12 +7,6 @@ import (
"github.com/gin-gonic/gin"
)
func CheckErr(err error) {
if err != nil {
panic(err)
}
}
func main() {
// Gin
gin.SetMode(gin.ReleaseMode)
+54
View File
@@ -408,6 +408,60 @@ type AsPartyName struct {
DotUnderText string `json:"dot_under_text"`
}
// AsLiveStartReq ...
type AsLiveStartReq struct {
LiveDifficultyID int `json:"live_difficulty_id"`
DeckID int `json:"deck_id"`
PartnerUserID int `json:"partner_user_id"`
PartnerCardMasterID int `json:"partner_card_master_id"`
LpMagnification int `json:"lp_magnification"`
IsAutoPlay bool `json:"is_auto_play"`
IsReferenceBook bool `json:"is_reference_book"`
}
// AsLivePartnerInfo ...
type AsLivePartnerInfo struct {
UserID int `json:"user_id"`
Name PartnerName `json:"name"`
Rank int `json:"rank"`
LastPlayedAt int64 `json:"last_played_at"`
RecommendCardMasterID int `json:"recommend_card_master_id"`
RecommendCardLevel int `json:"recommend_card_level"`
IsRecommendCardImageAwaken bool `json:"is_recommend_card_image_awaken"`
IsRecommendCardAllTrainingActivated bool `json:"is_recommend_card_all_training_activated"`
EmblemID int `json:"emblem_id"`
IsNew bool `json:"is_new"`
IntroductionMessage IntroductionMessage `json:"introduction_message"`
FriendApprovedAt interface{} `json:"friend_approved_at"`
RequestStatus int `json:"request_status"`
IsRequestPending bool `json:"is_request_pending"`
}
// PartnerName ...
type PartnerName struct {
DotUnderText string `json:"dot_under_text"`
}
// IntroductionMessage ...
type IntroductionMessage struct {
DotUnderText string `json:"dot_under_text"`
}
// AsLiveResultAchievementStatus ...
type AsLiveResultAchievementStatus struct {
ClearCount int64 `json:"clear_count"`
GotVoltage int64 `json:"got_voltage"`
RemainingStamina int64 `json:"remaining_stamina"`
}
// AsMvpInfo ...
type AsMvpInfo struct {
CardMasterID int64 `json:"card_master_id"`
GetVoltage int64 `json:"get_voltage"`
SkillTriggeredCount int64 `json:"skill_triggered_count"`
AppealCount int64 `json:"appeal_count"`
}
// AsReq ...
type AsReq interface{}
+158
View File
@@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"honoka-chan/config"
"honoka-chan/database"
"honoka-chan/encrypt"
"honoka-chan/handler"
"honoka-chan/middleware"
@@ -13,6 +14,7 @@ import (
"net/http"
"os"
"path/filepath"
"strconv"
"strings"
"time"
@@ -830,6 +832,162 @@ func AsRouter(r *gin.Engine) {
resp := SignResp(ctx.GetString("ep"), respBody, sessionKey)
ctx.Header("Content-Type", "application/json")
ctx.String(http.StatusOK, resp)
})
s.POST("/livePartners/fetch", func(ctx *gin.Context) {
resp := SignResp(ctx.GetString("ep"), utils.ReadAllText("assets/as/fetchLivePartners.json"), sessionKey)
ctx.Header("Content-Type", "application/json")
ctx.String(http.StatusOK, resp)
})
s.POST("/liveDeck/fetchLiveDeckSelect", func(ctx *gin.Context) {
resp := SignResp(ctx.GetString("ep"), utils.ReadAllText("assets/as/fetchLiveDeckSelect.json"), sessionKey)
ctx.Header("Content-Type", "application/json")
ctx.String(http.StatusOK, resp)
})
s.POST("/live/start", func(ctx *gin.Context) {
reqBody := gjson.Parse(ctx.GetString("reqBody")).Array()[0]
// fmt.Println(reqBody.String())
liveStartReq := model.AsLiveStartReq{}
if err := json.Unmarshal([]byte(reqBody.String()), &liveStartReq); err != nil {
panic(err)
}
// fmt.Println(liveStartReq)
var cardInfo string
partnerResp := gjson.Parse(utils.ReadAllText("assets/as/fetchLivePartners.json")).Get("partner_select_state.live_partners")
partnerResp.ForEach(func(k, v gjson.Result) bool {
userId := v.Get("user_id").Int()
if userId == int64(liveStartReq.PartnerUserID) {
v.Get("card_by_category").ForEach(func(kk, vv gjson.Result) bool {
if vv.IsObject() {
cardId := vv.Get("card_master_id").Int()
if cardId == int64(liveStartReq.PartnerCardMasterID) {
cardInfo = vv.String()
// fmt.Println(cardInfo)
return false
}
}
return true
})
return false
}
return true
})
// 保存请求包因为 /live/finish 接口的响应包里有部分字段不在该接口的请求包里
liveId := strconv.Itoa(int(time.Now().UnixNano()))
err := database.LevelDb.Put([]byte("live_"+liveId), []byte(reqBody.String()))
CheckErr(err)
liveDifficultyId := strconv.Itoa(liveStartReq.LiveDifficultyID)
liveNotes := utils.ReadAllText("assets/as/notes/" + liveDifficultyId + ".json")
if liveNotes == "" {
panic("歌曲情报信息不存在!")
}
liveStartResp := utils.ReadAllText("assets/as/liveStart.json")
liveStartResp = strings.ReplaceAll(liveStartResp, `"LIVE_ID"`, liveId)
liveStartResp = strings.ReplaceAll(liveStartResp, `"DECK_ID"`, strconv.Itoa(liveStartReq.DeckID))
liveStartResp = strings.ReplaceAll(liveStartResp, `"LIVE_NOTES"`, liveNotes)
liveStartResp = strings.ReplaceAll(liveStartResp, `"LIVE_PARTNER"`, cardInfo)
liveStartResp = strings.ReplaceAll(liveStartResp, `"LIVE_DIFFICULTY_ID"`, liveDifficultyId)
resp := SignResp(ctx.GetString("ep"), liveStartResp, sessionKey)
ctx.Header("Content-Type", "application/json")
ctx.String(http.StatusOK, resp)
})
s.POST("/live/finish", func(ctx *gin.Context) {
reqBody := gjson.Parse(ctx.GetString("reqBody")).Array()[0]
// fmt.Println(reqBody.String())
var cardMasterId, maxVolt, skillCount, appealCount int64
liveFinishReq := gjson.Parse(reqBody.String())
liveFinishReq.Get("live_score.card_stat_dict").ForEach(func(key, value gjson.Result) bool {
if value.IsObject() {
volt := value.Get("got_voltage").Int()
if volt > maxVolt {
maxVolt = volt
cardMasterId = value.Get("card_master_id").Int()
skillCount = value.Get("skill_triggered_count").Int()
appealCount = value.Get("appeal_count").Int()
}
}
return true
})
mvpInfo := model.AsMvpInfo{
CardMasterID: cardMasterId,
GetVoltage: maxVolt,
SkillTriggeredCount: skillCount,
AppealCount: appealCount,
}
mvp, err := json.Marshal(mvpInfo)
CheckErr(err)
// fmt.Println("mvpInfo:", mvpInfo)
liveId := liveFinishReq.Get("live_id").String()
res, err := database.LevelDb.Get([]byte("live_" + liveId))
CheckErr(err)
liveStartReq := model.AsLiveStartReq{}
if err := json.Unmarshal(res, &liveStartReq); err != nil {
panic(err)
}
// fmt.Println("liveStartReq:", liveStartReq)
partnerInfo := model.AsLivePartnerInfo{
LastPlayedAt: time.Now().Unix(),
RecommendCardMasterID: liveStartReq.PartnerCardMasterID,
RecommendCardLevel: 1,
IsRecommendCardImageAwaken: true,
IsRecommendCardAllTrainingActivated: true,
IsNew: false,
FriendApprovedAt: nil,
RequestStatus: 3,
IsRequestPending: false,
}
partnerResp := gjson.Parse(utils.ReadAllText("assets/as/fetchLivePartners.json")).Get("partner_select_state.live_partners")
partnerResp.ForEach(func(k, v gjson.Result) bool {
userId := v.Get("user_id").Int()
if userId == int64(liveStartReq.PartnerUserID) {
partnerInfo.UserID = int(userId)
partnerInfo.Name.DotUnderText = v.Get("name.dot_under_text").String()
partnerInfo.Rank = int(v.Get("rank").Int())
partnerInfo.EmblemID = int(v.Get("emblem_id").Int())
partnerInfo.IntroductionMessage.DotUnderText = v.Get("introduction_message.dot_under_text").String()
}
return true
})
partner, err := json.Marshal(partnerInfo)
CheckErr(err)
// fmt.Println(partnerInfo)
liveResultResp := model.AsLiveResultAchievementStatus{
ClearCount: 1,
GotVoltage: liveFinishReq.Get("live_score.current_score").Int(),
RemainingStamina: liveFinishReq.Get("live_score.remaining_stamina").Int(),
}
liveResult, err := json.Marshal(liveResultResp)
CheckErr(err)
// fmt.Println(liveResultResp)
liveFinishResp := utils.ReadAllText("assets/as/liveFinish.json")
liveFinishResp = strings.ReplaceAll(liveFinishResp, `"LIVE_DIFFICULTY_ID"`, strconv.Itoa(liveStartReq.LiveDifficultyID))
liveFinishResp = strings.ReplaceAll(liveFinishResp, `"DECK_ID"`, strconv.Itoa(liveStartReq.DeckID))
liveFinishResp = strings.ReplaceAll(liveFinishResp, `"MVP_INFO"`, string(mvp))
liveFinishResp = strings.ReplaceAll(liveFinishResp, `"PARTNER_INFO"`, string(partner))
liveFinishResp = strings.ReplaceAll(liveFinishResp, `"LIVE_RESULT"`, string(liveResult))
liveFinishResp = strings.ReplaceAll(liveFinishResp, `"LIVE_VOLTAGE"`, liveFinishReq.Get("live_score.current_score").String())
// fmt.Println(liveFinishResp)
resp := SignResp(ctx.GetString("ep"), liveFinishResp, sessionKey)
ctx.Header("Content-Type", "application/json")
ctx.String(http.StatusOK, resp)
})