429 lines
18 KiB
Go
429 lines
18 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"io"
|
|
"time"
|
|
|
|
"git.sunturtle.xyz/zephyr/horse"
|
|
)
|
|
|
|
type SupportCardID int32 // package horse doesn't have this yet
|
|
|
|
type OldWorkSingleIdleMode struct {
|
|
Chara SingleModeChara `json:"charaInfo"`
|
|
StartTime int64 `json:"startTime"`
|
|
EndTime int64 `json:"endTime"`
|
|
ProgressLog OldIdleSingleModeProgressLog `json:"progressLogInfo"`
|
|
}
|
|
|
|
type ProgressInfo struct {
|
|
Chara SingleModeChara `json:"chara_info"`
|
|
StartTime string `json:"start_time"`
|
|
EndTime string `json:"end_time"`
|
|
DressID int32 `json:"dress_id"`
|
|
}
|
|
|
|
type WorkIdleSingleMode struct {
|
|
ProgressInfo ProgressInfo `json:"progress_info"`
|
|
ProgressLog IdleSingleModeProgressLog `json:"progress_log_info"`
|
|
End End `json:"end_info"`
|
|
OldChara *SingleModeChara `json:"chara_info"`
|
|
}
|
|
|
|
type Skill struct {
|
|
SkillID horse.SkillID `json:"skill_id"`
|
|
Level int32 `json:"level"`
|
|
}
|
|
|
|
type SkillTip struct {
|
|
GroupID horse.SkillGroupID `json:"group_id"`
|
|
Rarity int32 `json:"rarity"`
|
|
Level int32 `json:"level"`
|
|
}
|
|
|
|
type SingleModeSupportCard struct {
|
|
Position int32 `json:"position"`
|
|
SupportCardID SupportCardID `json:"support_card_id"`
|
|
LimitBreakCount int32 `json:"limit_break_count"`
|
|
Exp int32 `json:"exp"`
|
|
TrainingPartnerState int32 `json:"training_partner_state"`
|
|
OwnerViewerID int64 `json:"owner_viewer_id"`
|
|
RentalType int32 `json:"rental_type"`
|
|
}
|
|
|
|
type GroupOuting struct {
|
|
CharaID horse.CharacterID `json:"chara_id"`
|
|
IsOuting int32 `json:"is_outing"`
|
|
StoryStep int32 `json:"story_step"`
|
|
}
|
|
|
|
type Evaluation struct {
|
|
TargetID int32 `json:"target_id"`
|
|
TrainingPartner int32 `json:"training_partner_id"`
|
|
Evaluation int32 `json:"evaluation"`
|
|
IsOuting int32 `json:"is_outing"`
|
|
StoryStep int32 `json:"story_step"`
|
|
IsAppear int32 `json:"is_appear"`
|
|
GroupOutingInfo []GroupOuting `json:"group_outing_info_array"`
|
|
}
|
|
|
|
type TrainingLevel struct {
|
|
CommandID int32 `json:"command_id"`
|
|
Level int32 `json:"level"`
|
|
}
|
|
|
|
type GuestOuting struct {
|
|
SupportCardID SupportCardID `json:"support_card_id"`
|
|
StoryStep int32 `json:"story_step"`
|
|
GroupOutingInfo []GroupOuting `json:"group_outing_info_array"`
|
|
}
|
|
|
|
type SingleModeSkillUpgrade struct {
|
|
ConditionID int32 `json:"condition_id"`
|
|
TotalCount int32 `json:"total_count"`
|
|
CurrentCount int32 `json:"current_count"`
|
|
}
|
|
|
|
type SingleModeChara struct {
|
|
SingleModeCharaID int32 `json:"single_mode_chara_id"`
|
|
CardID horse.UmaID `json:"card_id"`
|
|
CharaGrade int32 `json:"chara_grade"`
|
|
Speed int32 `json:"speed"`
|
|
Stamina int32 `json:"stamina"`
|
|
Power int32 `json:"power"`
|
|
Wiz int32 `json:"wiz"`
|
|
Guts int32 `json:"guts"`
|
|
Vital int32 `json:"vital"`
|
|
MaxSpeed int32 `json:"max_speed"`
|
|
MaxStamina int32 `json:"max_stamina"`
|
|
MaxPower int32 `json:"max_power"`
|
|
MaxWiz int32 `json:"max_wiz"`
|
|
MaxGuts int32 `json:"max_guts"`
|
|
DefaultMaxSpeed int32 `json:"default_max_speed"`
|
|
DefaultMaxStamina int32 `json:"default_max_stamina"`
|
|
DefaultMaxPower int32 `json:"default_max_power"`
|
|
DefaultMaxWiz int32 `json:"default_max_wiz"`
|
|
DefaultMaxGuts int32 `json:"default_max_guts"`
|
|
MaxVital int32 `json:"max_vital"`
|
|
Motivation int32 `json:"motivation"`
|
|
Fans int32 `json:"fans"`
|
|
Rarity int32 `json:"rarity"`
|
|
RaceProgramID int32 `json:"race_program_id"`
|
|
ReserveRaceProgramID int32 `json:"reserve_race_program_id"`
|
|
RaceRunningStyle int32 `json:"race_running_style"`
|
|
IsShortRace int32 `json:"is_short_race"`
|
|
TalentLevel int32 `json:"talent_level"`
|
|
Skills []Skill `json:"skill_array"`
|
|
DisableSkillIDs []horse.SkillID `json:"disable_skill_id_array"`
|
|
SkillTips []SkillTip `json:"skill_tips_array"`
|
|
SupportCards []SingleModeSupportCard `json:"support_card_array"`
|
|
SuccessionTrainedCharaID1 int32 `json:"succession_trained_chara_id_1"`
|
|
SuccessionTrainedCharaID2 int32 `json:"succession_trained_chara_id_2"`
|
|
ProperDistanceShort horse.AptitudeLevel `json:"proper_distance_short"`
|
|
ProperDistanceMile horse.AptitudeLevel `json:"proper_distance_mile"`
|
|
ProperDistanceMiddle horse.AptitudeLevel `json:"proper_distance_middle"`
|
|
ProperDistanceLong horse.AptitudeLevel `json:"proper_distance_long"`
|
|
ProperRunningStyleNige horse.AptitudeLevel `json:"proper_running_style_nige"`
|
|
ProperRunningStyleSenko horse.AptitudeLevel `json:"proper_running_style_senko"`
|
|
ProperRunningStyleSashi horse.AptitudeLevel `json:"proper_running_style_sashi"`
|
|
ProperRunningStyleOikomi horse.AptitudeLevel `json:"proper_running_style_oikomi"`
|
|
ProperGroundTurf horse.AptitudeLevel `json:"proper_ground_turf"`
|
|
ProperGroundDirt horse.AptitudeLevel `json:"proper_ground_dirt"`
|
|
Turn int32 `json:"turn"`
|
|
SkillPoint int32 `json:"skill_point"`
|
|
ShortCutState int32 `json:"short_cut_state"`
|
|
State int32 `json:"state"`
|
|
PlayingState int32 `json:"playing_state"`
|
|
ScenarioID horse.ScenarioID `json:"scenario_id"`
|
|
RouteID int32 `json:"route_id"`
|
|
StartTime string `json:"start_time"`
|
|
Evaluations []Evaluation `json:"evaluation_info_array"`
|
|
TrainingLevels []TrainingLevel `json:"training_level_info_array"`
|
|
NicknameIDs []int32 `json:"nickname_id_array"`
|
|
CharaEffectIDs []int32 `json:"chara_effect_id_array"`
|
|
RouteRaceIDs []int32 `json:"route_race_id_array"`
|
|
GuestOutings []GuestOuting `json:"guest_outing_info_array"`
|
|
SkillUpgrades []SingleModeSkillUpgrade `json:"skill_upgrade_info_array"`
|
|
}
|
|
|
|
type OldCharaEffectLog struct {
|
|
CharaEffectID int32 `json:"charaEffectId"`
|
|
IsActive bool `json:"isActive"`
|
|
}
|
|
|
|
type CharaEffectLog struct {
|
|
CharaEffectID int32 `json:"chara_effect_id"`
|
|
IsActive bool `json:"is_active"`
|
|
}
|
|
|
|
type IdleSingleModeSignedInt struct {
|
|
Sign int32 `json:"sign"`
|
|
Value int32 `json:"value"`
|
|
}
|
|
|
|
type OldIdleSingleModeGainInfo struct {
|
|
Speed IdleSingleModeSignedInt `json:"speed"`
|
|
Stamina IdleSingleModeSignedInt `json:"stamina"`
|
|
Power IdleSingleModeSignedInt `json:"power"`
|
|
Wiz IdleSingleModeSignedInt `json:"wiz"`
|
|
Guts IdleSingleModeSignedInt `json:"guts"`
|
|
MaxSpeed int32 `json:"maxSpeed"`
|
|
MaxStamina int32 `json:"maxStamina"`
|
|
MaxPower int32 `json:"maxPower"`
|
|
MaxWiz int32 `json:"maxWiz"`
|
|
MaxGuts int32 `json:"maxGuts"`
|
|
ProperDistanceShort horse.AptitudeLevel `json:"properDistanceShort"`
|
|
ProperDistanceMile horse.AptitudeLevel `json:"properDistanceMile"`
|
|
ProperDistanceMiddle horse.AptitudeLevel `json:"properDistanceMiddle"`
|
|
ProperDistanceLong horse.AptitudeLevel `json:"properDistanceLong"`
|
|
ProperRunningStyleNige horse.AptitudeLevel `json:"properRunningStyleNige"`
|
|
ProperRunningStyleSenko horse.AptitudeLevel `json:"properRunningStyleSenko"`
|
|
ProperRunningStyleSashi horse.AptitudeLevel `json:"properRunningStyleSashi"`
|
|
ProperRunningStyleOikomi horse.AptitudeLevel `json:"properRunningStyleOikomi"`
|
|
ProperGroundTurf horse.AptitudeLevel `json:"properGroundTurf"`
|
|
ProperGroundDirt horse.AptitudeLevel `json:"properGroundDirt"`
|
|
SkillPoint int32 `json:"skillPoint"`
|
|
SkillTips []SkillTip `json:"skillTips"`
|
|
}
|
|
|
|
type IdleSingleModeGainInfo struct {
|
|
Speed IdleSingleModeSignedInt `json:"speed"`
|
|
Stamina IdleSingleModeSignedInt `json:"stamina"`
|
|
Power IdleSingleModeSignedInt `json:"power"`
|
|
Wiz IdleSingleModeSignedInt `json:"wiz"`
|
|
Guts IdleSingleModeSignedInt `json:"guts"`
|
|
MaxSpeed int32 `json:"max_speed"`
|
|
MaxStamina int32 `json:"max_stamina"`
|
|
MaxPower int32 `json:"max_power"`
|
|
MaxWiz int32 `json:"max_wiz"`
|
|
MaxGuts int32 `json:"max_guts"`
|
|
ProperDistanceShort horse.AptitudeLevel `json:"proper_distance_short"`
|
|
ProperDistanceMile horse.AptitudeLevel `json:"proper_distance_mile"`
|
|
ProperDistanceMiddle horse.AptitudeLevel `json:"proper_distance_middle"`
|
|
ProperDistanceLong horse.AptitudeLevel `json:"proper_distance_long"`
|
|
ProperRunningStyleNige horse.AptitudeLevel `json:"proper_running_style_nige"`
|
|
ProperRunningStyleSenko horse.AptitudeLevel `json:"proper_running_style_senko"`
|
|
ProperRunningStyleSashi horse.AptitudeLevel `json:"proper_running_style_sashi"`
|
|
ProperRunningStyleOikomi horse.AptitudeLevel `json:"proper_running_style_oikomi"`
|
|
ProperGroundTurf horse.AptitudeLevel `json:"proper_ground_turf"`
|
|
ProperGroundDirt horse.AptitudeLevel `json:"proper_ground_dirt"`
|
|
SkillPoint int32 `json:"skill_point"`
|
|
SkillTips []SkillTip `json:"skill_tips_array"`
|
|
}
|
|
|
|
type OldIdleSingleModeSupportCardGain struct {
|
|
SupportCardID SupportCardID `json:"supportCardId"`
|
|
GainInfo OldIdleSingleModeGainInfo `json:"gainInfo"`
|
|
}
|
|
|
|
type IdleSingleModeSupportCardGain struct {
|
|
SupportCardID SupportCardID `json:"support_card_id"`
|
|
GainInfo IdleSingleModeGainInfo `json:"gain_info"`
|
|
}
|
|
|
|
type OldFactor struct {
|
|
FactorID horse.SparkID `json:"factorId"`
|
|
Level int32 `json:"level"`
|
|
}
|
|
|
|
type Factor struct {
|
|
FactorID horse.SparkID `json:"factor_id"`
|
|
Level int32 `json:"level"`
|
|
}
|
|
|
|
type OldIdleSingleModeSuccessionFactorGain struct {
|
|
Year int32 `json:"year"`
|
|
GainFactorInfo []OldFactor `json:"gainFactorInfoArray"`
|
|
}
|
|
|
|
type IdleSingleModeSuccessionFactorGain struct {
|
|
Year int32 `json:"year"`
|
|
GainFactorInfo []Factor `json:"gain_factor_info_array"`
|
|
}
|
|
|
|
type SingleRaceHistory struct {
|
|
Turn int32 `json:"turn"`
|
|
ProgramID int32 `json:"program_id"`
|
|
Weather int32 `json:"weather"`
|
|
GroundCondition int32 `json:"ground_condition"`
|
|
RunningStyle int32 `json:"running_style"`
|
|
ResultRank int32 `json:"result_rank"`
|
|
FrameOrder int32 `json:"frame_order"`
|
|
NPCCount int32 `json:"npc_count"`
|
|
}
|
|
|
|
type RaceReward struct {
|
|
ItemType int32 `json:"item_type"`
|
|
ItemID int32 `json:"item_id"`
|
|
ItemNum int32 `json:"item_num"`
|
|
}
|
|
|
|
type RaceRewardLimit struct {
|
|
RewardID int32 `json:"reward_id"`
|
|
ItemType int32 `json:"item_type"`
|
|
ItemID int32 `json:"item_id"`
|
|
ItemNum int32 `json:"item_num"`
|
|
RestCount int32 `json:"rest_count"`
|
|
}
|
|
|
|
type CharaRaceReward struct {
|
|
ResultRank int32 `json:"result_rank"`
|
|
ResultTime int32 `json:"result_time"`
|
|
RaceReward []RaceReward `json:"race_reward"`
|
|
RaceRewardBonus []RaceReward `json:"race_reward_bonus"`
|
|
RaceRewardPlusBonus []RaceReward `json:"race_reward_plus_bonus"`
|
|
RaceRewardBonusWin []RaceReward `json:"race_reward_bonus_win"`
|
|
RaceRewardLimit []RaceRewardLimit `json:"race_reward_limit"`
|
|
GainedFans int32 `json:"gained_fans"`
|
|
CampaignIDs []int32 `json:"campaign_id_array"`
|
|
}
|
|
|
|
type IdleSingleModeRaceHistory struct {
|
|
RaceHistory SingleRaceHistory `json:"race_history"`
|
|
RaceRewardInfo CharaRaceReward `json:"race_reward_info"`
|
|
LoseTipsID int32 `json:"lose_tips_id"`
|
|
}
|
|
|
|
type OldIdleSingleModeProgressLog struct {
|
|
CharaEffectLog []OldCharaEffectLog `json:"charaEffectLog"`
|
|
SupportCardGains []OldIdleSingleModeSupportCardGain `json:"supportCardGainInfo"`
|
|
EventGain OldIdleSingleModeGainInfo `json:"eventGainInfo"`
|
|
SuccessionGain OldIdleSingleModeGainInfo `json:"successionGainInfo"`
|
|
SuccessionFactorGains []OldIdleSingleModeSuccessionFactorGain `json:"successionFactorGainArray"`
|
|
RaceHistory []IdleSingleModeRaceHistory `json:"raceHistoryArray"`
|
|
GainSkillIDs []horse.SkillID `json:"gainSkillIdArray"`
|
|
TotalSkillPoint int32 `json:"totalSkillPoint"`
|
|
}
|
|
|
|
type IdleSingleModeProgressLog struct {
|
|
CharaEffectLog []CharaEffectLog `json:"chara_effect_log_array"`
|
|
SupportCardGains []IdleSingleModeSupportCardGain `json:"support_card_gain_info_array"`
|
|
EventGain IdleSingleModeGainInfo `json:"event_gain_info"`
|
|
SuccessionGain IdleSingleModeGainInfo `json:"succession_gain_info"`
|
|
SuccessionFactorGains []IdleSingleModeSuccessionFactorGain `json:"succession_factor_gain_array"`
|
|
RaceHistory []IdleSingleModeRaceHistory `json:"race_history_array"`
|
|
GainSkillIDs []horse.SkillID `json:"gain_skill_id_array"`
|
|
TotalSkillPoint int32 `json:"total_skill_point"`
|
|
}
|
|
|
|
type AddItem struct {
|
|
ItemID int32 `json:"item_id"`
|
|
Number int32 `json:"number"`
|
|
}
|
|
|
|
type RewardSummary struct {
|
|
AddItem []AddItem `json:"add_item_list"`
|
|
}
|
|
|
|
type End struct {
|
|
Chara SingleModeChara `json:"chara_info"`
|
|
CharaButWerseterIsOverworked *SingleModeChara `json:"chara_starting_info"`
|
|
RewardSummary RewardSummary `json:"reward_summary_info"`
|
|
}
|
|
|
|
func loadISM(r io.Reader) (WorkIdleSingleMode, error) {
|
|
// Since we have two potential types to read at the top level,
|
|
// decode one message and try it both ways.
|
|
var b json.RawMessage
|
|
var err error
|
|
if err = json.NewDecoder(r).Decode(&b); err != nil {
|
|
return WorkIdleSingleMode{}, err
|
|
}
|
|
{
|
|
var ism WorkIdleSingleMode
|
|
d := json.NewDecoder(bytes.NewReader(b))
|
|
d.DisallowUnknownFields()
|
|
err = d.Decode(&ism)
|
|
if err == nil {
|
|
// NOTE(zeph): this is for no error
|
|
// If old fields are populated, move them to the correct ones.
|
|
if ism.End.CharaButWerseterIsOverworked != nil {
|
|
ism.End.Chara = *ism.End.CharaButWerseterIsOverworked
|
|
ism.End.CharaButWerseterIsOverworked = nil
|
|
}
|
|
if ism.OldChara != nil {
|
|
ism.ProgressInfo.Chara = *ism.OldChara
|
|
ism.OldChara = nil
|
|
}
|
|
return ism, nil
|
|
}
|
|
}
|
|
{
|
|
var ism OldWorkSingleIdleMode
|
|
d := json.NewDecoder(bytes.NewReader(b))
|
|
d.DisallowUnknownFields()
|
|
// Use a new error variable here.
|
|
// If this fails, we want to return the reason we didn't use the API type instead.
|
|
if err := d.Decode(&ism); err == nil {
|
|
// NOTE(zeph): this is for no error
|
|
return unold(ism), nil
|
|
}
|
|
}
|
|
// NOTE(zeph): this is the error from decoding the API type, not the validation type.
|
|
return WorkIdleSingleMode{}, err
|
|
}
|
|
|
|
func unold(old OldWorkSingleIdleMode) WorkIdleSingleMode {
|
|
return WorkIdleSingleMode{
|
|
ProgressInfo: ProgressInfo{
|
|
Chara: old.Chara,
|
|
StartTime: time.Unix(old.StartTime, 0).Format(time.DateTime),
|
|
EndTime: time.Unix(old.EndTime, 0).Format(time.DateTime),
|
|
},
|
|
ProgressLog: IdleSingleModeProgressLog{
|
|
CharaEffectLog: unoldEffects(old.ProgressLog.CharaEffectLog),
|
|
SupportCardGains: unoldCardGains(old.ProgressLog.SupportCardGains),
|
|
EventGain: IdleSingleModeGainInfo(old.ProgressLog.EventGain),
|
|
SuccessionGain: IdleSingleModeGainInfo(old.ProgressLog.SuccessionGain),
|
|
SuccessionFactorGains: unoldFactorGains(old.ProgressLog.SuccessionFactorGains),
|
|
RaceHistory: old.ProgressLog.RaceHistory,
|
|
GainSkillIDs: old.ProgressLog.GainSkillIDs,
|
|
TotalSkillPoint: old.ProgressLog.TotalSkillPoint,
|
|
},
|
|
// We could try to roll up starting numbers plus gains,
|
|
// but only a few of these files exist anyway.
|
|
// Not worth the effort.
|
|
End: End{},
|
|
}
|
|
}
|
|
|
|
func unoldEffects(olds []OldCharaEffectLog) []CharaEffectLog {
|
|
new := make([]CharaEffectLog, len(olds))
|
|
for i, old := range olds {
|
|
new[i] = CharaEffectLog(old)
|
|
}
|
|
return new
|
|
}
|
|
|
|
func unoldCardGains(olds []OldIdleSingleModeSupportCardGain) []IdleSingleModeSupportCardGain {
|
|
new := make([]IdleSingleModeSupportCardGain, len(olds))
|
|
for i, old := range olds {
|
|
new[i] = IdleSingleModeSupportCardGain{
|
|
SupportCardID: old.SupportCardID,
|
|
GainInfo: IdleSingleModeGainInfo(old.GainInfo),
|
|
}
|
|
}
|
|
return new
|
|
}
|
|
|
|
func unoldFactorGains(olds []OldIdleSingleModeSuccessionFactorGain) []IdleSingleModeSuccessionFactorGain {
|
|
new := make([]IdleSingleModeSuccessionFactorGain, len(olds))
|
|
for i, old := range olds {
|
|
new[i] = IdleSingleModeSuccessionFactorGain{
|
|
Year: old.Year,
|
|
GainFactorInfo: unoldFactors(old.GainFactorInfo),
|
|
}
|
|
}
|
|
return new
|
|
}
|
|
|
|
func unoldFactors(olds []OldFactor) []Factor {
|
|
new := make([]Factor, len(olds))
|
|
for i, old := range olds {
|
|
new[i] = Factor(old)
|
|
}
|
|
return new
|
|
}
|