mirror of
https://github.com/Walter-Sparrow/lunar-tear.git
synced 2026-07-02 05:43:41 +03:00
Add authentication server, dev CLI, Docker multi-service setup, and cross-platform improvements
This commit is contained in:
@@ -0,0 +1,450 @@
|
||||
package userdata
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"maps"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
pb "lunar-tear/server/gen/proto"
|
||||
"lunar-tear/server/internal/store"
|
||||
)
|
||||
|
||||
func mapsEqualSimple[K comparable, V comparable](a, b map[K]V) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for k, va := range a {
|
||||
if vb, ok := b[k]; !ok || va != vb {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func mapsEqualStruct[K comparable, V comparable](a, b map[K]V) bool {
|
||||
return mapsEqualSimple(a, b)
|
||||
}
|
||||
|
||||
func mapsEqualSliceValues[K comparable, V comparable](a, b map[K][]V) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for k, va := range a {
|
||||
vb, ok := b[k]
|
||||
if !ok || !slices.Equal(va, vb) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func gimmickStateEqual(a, b store.GimmickState) bool {
|
||||
return mapsEqualStruct(a.Progress, b.Progress) &&
|
||||
mapsEqualStruct(a.OrnamentProgress, b.OrnamentProgress) &&
|
||||
mapsEqualStruct(a.Sequences, b.Sequences) &&
|
||||
mapsEqualStruct(a.Unlocks, b.Unlocks)
|
||||
}
|
||||
|
||||
func ChangedTables(before, after *store.UserState) []string {
|
||||
var changed []string
|
||||
add := func(name string) { changed = append(changed, name) }
|
||||
|
||||
if before.UserId != after.UserId || before.PlayerId != after.PlayerId ||
|
||||
before.OsType != after.OsType || before.PlatformType != after.PlatformType ||
|
||||
before.UserRestrictionType != after.UserRestrictionType ||
|
||||
before.RegisterDatetime != after.RegisterDatetime ||
|
||||
before.GameStartDatetime != after.GameStartDatetime ||
|
||||
before.LatestVersion != after.LatestVersion {
|
||||
add("IUser")
|
||||
}
|
||||
if before.Setting != after.Setting {
|
||||
add("IUserSetting")
|
||||
}
|
||||
if before.Status != after.Status {
|
||||
add("IUserStatus")
|
||||
}
|
||||
if before.Gem != after.Gem {
|
||||
add("IUserGem")
|
||||
}
|
||||
if before.Profile != after.Profile {
|
||||
add("IUserProfile")
|
||||
}
|
||||
if before.Login != after.Login {
|
||||
add("IUserLogin")
|
||||
}
|
||||
if before.LoginBonus != after.LoginBonus {
|
||||
add("IUserLoginBonus")
|
||||
}
|
||||
if before.PortalCageStatus != after.PortalCageStatus {
|
||||
add("IUserPortalCageStatus")
|
||||
}
|
||||
if before.GuerrillaFreeOpen != after.GuerrillaFreeOpen {
|
||||
add("IUserEventQuestGuerrillaFreeOpen")
|
||||
}
|
||||
if before.ShopReplaceable != after.ShopReplaceable {
|
||||
add("IUserShopReplaceable")
|
||||
}
|
||||
if before.Explore != after.Explore {
|
||||
add("IUserExplore")
|
||||
}
|
||||
if before.BigHuntProgress != after.BigHuntProgress {
|
||||
add("IUserBigHuntProgressStatus")
|
||||
}
|
||||
if before.FacebookId != after.FacebookId {
|
||||
add("IUserFacebook")
|
||||
}
|
||||
|
||||
if before.MainQuest != after.MainQuest {
|
||||
add("IUserMainQuestFlowStatus")
|
||||
add("IUserMainQuestMainFlowStatus")
|
||||
add("IUserMainQuestProgressStatus")
|
||||
add("IUserMainQuestSeasonRoute")
|
||||
add("IUserMainQuestReplayFlowStatus")
|
||||
}
|
||||
if before.EventQuest != after.EventQuest {
|
||||
add("IUserEventQuestProgressStatus")
|
||||
}
|
||||
if before.ExtraQuest != after.ExtraQuest {
|
||||
add("IUserExtraQuestProgressStatus")
|
||||
}
|
||||
if before.SideStoryActiveProgress != after.SideStoryActiveProgress {
|
||||
add("IUserSideStoryQuestSceneProgressStatus")
|
||||
}
|
||||
|
||||
if !mapsEqualStruct(before.Tutorials, after.Tutorials) {
|
||||
add("IUserTutorialProgress")
|
||||
}
|
||||
if !mapsEqualStruct(before.Missions, after.Missions) {
|
||||
add("IUserMission")
|
||||
}
|
||||
if !mapsEqualStruct(before.Characters, after.Characters) {
|
||||
add("IUserCharacter")
|
||||
}
|
||||
if !mapsEqualStruct(before.Costumes, after.Costumes) {
|
||||
add("IUserCostume")
|
||||
}
|
||||
if !mapsEqualStruct(before.Weapons, after.Weapons) {
|
||||
add("IUserWeapon")
|
||||
}
|
||||
if !mapsEqualStruct(before.WeaponStories, after.WeaponStories) {
|
||||
add("IUserWeaponStory")
|
||||
}
|
||||
if !mapsEqualStruct(before.WeaponNotes, after.WeaponNotes) {
|
||||
add("IUserWeaponNote")
|
||||
}
|
||||
if !mapsEqualStruct(before.Companions, after.Companions) {
|
||||
add("IUserCompanion")
|
||||
}
|
||||
if !mapsEqualStruct(before.Thoughts, after.Thoughts) {
|
||||
add("IUserThought")
|
||||
}
|
||||
if !mapsEqualSimple(before.ConsumableItems, after.ConsumableItems) {
|
||||
add("IUserConsumableItem")
|
||||
}
|
||||
if !mapsEqualSimple(before.Materials, after.Materials) {
|
||||
add("IUserMaterial")
|
||||
}
|
||||
if !mapsEqualSimple(before.ImportantItems, after.ImportantItems) {
|
||||
add("IUserImportantItem")
|
||||
}
|
||||
if !mapsEqualSimple(before.PremiumItems, after.PremiumItems) {
|
||||
add("IUserPremiumItem")
|
||||
}
|
||||
if !mapsEqualStruct(before.Parts, after.Parts) {
|
||||
add("IUserParts")
|
||||
}
|
||||
if !mapsEqualStruct(before.PartsGroupNotes, after.PartsGroupNotes) {
|
||||
add("IUserPartsGroupNote")
|
||||
}
|
||||
if !mapsEqualStruct(before.PartsPresets, after.PartsPresets) {
|
||||
add("IUserPartsPreset")
|
||||
}
|
||||
if !mapsEqualStruct(before.CostumeActiveSkills, after.CostumeActiveSkills) {
|
||||
add("IUserCostumeActiveSkill")
|
||||
}
|
||||
if !mapsEqualSliceValues(before.WeaponSkills, after.WeaponSkills) {
|
||||
add("IUserWeaponSkill")
|
||||
}
|
||||
if !mapsEqualSliceValues(before.WeaponAbilities, after.WeaponAbilities) {
|
||||
add("IUserWeaponAbility")
|
||||
}
|
||||
if !mapsEqualStruct(before.WeaponAwakens, after.WeaponAwakens) {
|
||||
add("IUserWeaponAwaken")
|
||||
}
|
||||
if !mapsEqualStruct(before.DeckTypeNotes, after.DeckTypeNotes) {
|
||||
add("IUserDeckTypeNote")
|
||||
}
|
||||
if !mapsEqualStruct(before.DeckCharacters, after.DeckCharacters) {
|
||||
add("IUserDeckCharacter")
|
||||
add("IUserDeckCharacterDressupCostume")
|
||||
}
|
||||
if !mapsEqualStruct(before.Decks, after.Decks) {
|
||||
add("IUserDeck")
|
||||
}
|
||||
if !mapsEqualSliceValues(before.DeckSubWeapons, after.DeckSubWeapons) {
|
||||
add("IUserDeckSubWeaponGroup")
|
||||
}
|
||||
if !mapsEqualSliceValues(before.DeckParts, after.DeckParts) {
|
||||
add("IUserDeckPartsGroup")
|
||||
}
|
||||
if !mapsEqualStruct(before.Quests, after.Quests) {
|
||||
add("IUserQuest")
|
||||
}
|
||||
if !mapsEqualStruct(before.QuestMissions, after.QuestMissions) {
|
||||
add("IUserQuestMission")
|
||||
}
|
||||
if !mapsEqualStruct(before.SideStoryQuests, after.SideStoryQuests) {
|
||||
add("IUserSideStoryQuest")
|
||||
}
|
||||
if !mapsEqualStruct(before.QuestLimitContentStatus, after.QuestLimitContentStatus) {
|
||||
add("IUserQuestLimitContentStatus")
|
||||
}
|
||||
if !mapsEqualSimple(before.NaviCutInPlayed, after.NaviCutInPlayed) {
|
||||
add("IUserNaviCutIn")
|
||||
}
|
||||
if !mapsEqualSimple(before.ViewedMovies, after.ViewedMovies) {
|
||||
add("IUserMovie")
|
||||
}
|
||||
if !mapsEqualSimple(before.ContentsStories, after.ContentsStories) {
|
||||
add("IUserContentsStory")
|
||||
}
|
||||
if !mapsEqualSimple(before.DrawnOmikuji, after.DrawnOmikuji) {
|
||||
add("IUserOmikuji")
|
||||
}
|
||||
if !mapsEqualSimple(before.DokanConfirmed, after.DokanConfirmed) {
|
||||
add("IUserDokan")
|
||||
}
|
||||
if !mapsEqualStruct(before.ShopItems, after.ShopItems) {
|
||||
add("IUserShopItem")
|
||||
}
|
||||
if !mapsEqualStruct(before.ShopReplaceableLineup, after.ShopReplaceableLineup) {
|
||||
add("IUserShopReplaceableLineup")
|
||||
}
|
||||
if !mapsEqualStruct(before.ExploreScores, after.ExploreScores) {
|
||||
add("IUserExploreScore")
|
||||
}
|
||||
if !mapsEqualStruct(before.CharacterBoards, after.CharacterBoards) {
|
||||
add("IUserCharacterBoard")
|
||||
}
|
||||
if !mapsEqualStruct(before.CharacterBoardAbilities, after.CharacterBoardAbilities) {
|
||||
add("IUserCharacterBoardAbility")
|
||||
}
|
||||
if !mapsEqualStruct(before.CharacterBoardStatusUps, after.CharacterBoardStatusUps) {
|
||||
add("IUserCharacterBoardStatusUp")
|
||||
}
|
||||
if !mapsEqualStruct(before.CostumeAwakenStatusUps, after.CostumeAwakenStatusUps) {
|
||||
add("IUserCostumeAwakenStatusUp")
|
||||
}
|
||||
if !mapsEqualStruct(before.CostumeLotteryEffects, after.CostumeLotteryEffects) {
|
||||
add("IUserCostumeLotteryEffect")
|
||||
}
|
||||
if !mapsEqualStruct(before.CostumeLotteryEffectPending, after.CostumeLotteryEffectPending) {
|
||||
add("IUserCostumeLotteryEffectPending")
|
||||
}
|
||||
if !mapsEqualStruct(before.AutoSaleSettings, after.AutoSaleSettings) {
|
||||
add("IUserAutoSaleSettingDetail")
|
||||
}
|
||||
if !mapsEqualStruct(before.CharacterRebirths, after.CharacterRebirths) {
|
||||
add("IUserCharacterRebirth")
|
||||
}
|
||||
if !mapsEqualStruct(before.CageOrnamentRewards, after.CageOrnamentRewards) {
|
||||
add("IUserCageOrnamentReward")
|
||||
}
|
||||
|
||||
if !mapsEqualStruct(before.BigHuntMaxScores, after.BigHuntMaxScores) {
|
||||
add("IUserBigHuntMaxScore")
|
||||
}
|
||||
if !mapsEqualStruct(before.BigHuntStatuses, after.BigHuntStatuses) {
|
||||
add("IUserBigHuntStatus")
|
||||
}
|
||||
if !mapsEqualStruct(before.BigHuntScheduleMaxScores, after.BigHuntScheduleMaxScores) {
|
||||
add("IUserBigHuntScheduleMaxScore")
|
||||
}
|
||||
if !mapsEqualStruct(before.BigHuntWeeklyMaxScores, after.BigHuntWeeklyMaxScores) {
|
||||
add("IUserBigHuntWeeklyMaxScore")
|
||||
}
|
||||
if !mapsEqualStruct(before.BigHuntWeeklyStatuses, after.BigHuntWeeklyStatuses) {
|
||||
add("IUserBigHuntWeeklyStatus")
|
||||
}
|
||||
|
||||
if !gimmickStateEqual(before.Gimmick, after.Gimmick) {
|
||||
if !mapsEqualStruct(before.Gimmick.Progress, after.Gimmick.Progress) {
|
||||
add("IUserGimmick")
|
||||
}
|
||||
if !mapsEqualStruct(before.Gimmick.OrnamentProgress, after.Gimmick.OrnamentProgress) {
|
||||
add("IUserGimmickOrnamentProgress")
|
||||
}
|
||||
if !mapsEqualStruct(before.Gimmick.Sequences, after.Gimmick.Sequences) {
|
||||
add("IUserGimmickSequence")
|
||||
}
|
||||
if !mapsEqualStruct(before.Gimmick.Unlocks, after.Gimmick.Unlocks) {
|
||||
add("IUserGimmickUnlock")
|
||||
}
|
||||
}
|
||||
|
||||
return changed
|
||||
}
|
||||
|
||||
func ComputeDelta(before, after *store.UserState, changedTables []string) map[string]*pb.DiffData {
|
||||
diff := make(map[string]*pb.DiffData, len(changedTables))
|
||||
for _, table := range changedTables {
|
||||
afterJSON := projectTable(table, *after)
|
||||
deleteKeys := "[]"
|
||||
if kf := keyFieldsForTable(table); len(kf) > 0 {
|
||||
beforeJSON := projectTable(table, *before)
|
||||
deleteKeys = ComputeDeleteKeys(
|
||||
parseJSONRecords(beforeJSON),
|
||||
parseJSONRecords(afterJSON),
|
||||
kf,
|
||||
)
|
||||
}
|
||||
diff[table] = &pb.DiffData{
|
||||
UpdateRecordsJson: afterJSON,
|
||||
DeleteKeysJson: deleteKeys,
|
||||
}
|
||||
}
|
||||
return diff
|
||||
}
|
||||
|
||||
func AllTableNames() []string {
|
||||
return slices.Sorted(maps.Keys(projectors))
|
||||
}
|
||||
|
||||
func SortedChangedNames(tables []string) string {
|
||||
sorted := make([]string, len(tables))
|
||||
copy(sorted, tables)
|
||||
sort.Strings(sorted)
|
||||
return strings.Join(sorted, ",")
|
||||
}
|
||||
|
||||
func parseJSONRecords(jsonStr string) []map[string]any {
|
||||
if jsonStr == "" || jsonStr == "[]" {
|
||||
return nil
|
||||
}
|
||||
var records []map[string]any
|
||||
if err := json.Unmarshal([]byte(jsonStr), &records); err != nil {
|
||||
return nil
|
||||
}
|
||||
return records
|
||||
}
|
||||
|
||||
func keyFieldsForTable(table string) []string {
|
||||
switch table {
|
||||
case "IUserWeapon":
|
||||
return []string{"userId", "userWeaponUuid"}
|
||||
case "IUserWeaponSkill":
|
||||
return []string{"userId", "userWeaponUuid", "slotNumber"}
|
||||
case "IUserWeaponAbility":
|
||||
return []string{"userId", "userWeaponUuid", "slotNumber"}
|
||||
case "IUserWeaponAwaken":
|
||||
return []string{"userId", "userWeaponUuid"}
|
||||
case "IUserCostume":
|
||||
return []string{"userId", "userCostumeUuid"}
|
||||
case "IUserCompanion":
|
||||
return []string{"userId", "userCompanionUuid"}
|
||||
case "IUserThought":
|
||||
return []string{"userId", "userThoughtUuid"}
|
||||
case "IUserParts":
|
||||
return []string{"userId", "userPartsUuid"}
|
||||
case "IUserDeckCharacter":
|
||||
return []string{"userId", "userDeckCharacterUuid"}
|
||||
case "IUserDeck":
|
||||
return []string{"userId", "deckType", "userDeckNumber"}
|
||||
case "IUserDeckSubWeaponGroup":
|
||||
return []string{"userId", "userDeckCharacterUuid", "sortOrder"}
|
||||
case "IUserDeckPartsGroup":
|
||||
return []string{"userId", "userDeckCharacterUuid", "sortOrder"}
|
||||
case "IUserDeckCharacterDressupCostume":
|
||||
return []string{"userId", "userDeckCharacterUuid"}
|
||||
case "IUserCharacter":
|
||||
return []string{"userId", "characterId"}
|
||||
case "IUserConsumableItem":
|
||||
return []string{"userId", "consumableItemId"}
|
||||
case "IUserMaterial":
|
||||
return []string{"userId", "materialId"}
|
||||
case "IUserImportantItem":
|
||||
return []string{"userId", "importantItemId"}
|
||||
case "IUserPremiumItem":
|
||||
return []string{"userId", "premiumItemId"}
|
||||
case "IUserQuest":
|
||||
return []string{"userId", "questId"}
|
||||
case "IUserQuestMission":
|
||||
return []string{"userId", "questId", "questMissionId"}
|
||||
case "IUserMission":
|
||||
return []string{"userId", "missionId"}
|
||||
case "IUserWeaponStory":
|
||||
return []string{"userId", "weaponId"}
|
||||
case "IUserWeaponNote":
|
||||
return []string{"userId", "weaponId"}
|
||||
case "IUserTutorialProgress":
|
||||
return []string{"userId", "tutorialType"}
|
||||
case "IUserGimmick":
|
||||
return []string{"userId", "gimmickSequenceScheduleId", "gimmickSequenceId", "gimmickId"}
|
||||
case "IUserGimmickOrnamentProgress":
|
||||
return []string{"userId", "gimmickSequenceScheduleId", "gimmickSequenceId", "gimmickId", "gimmickOrnamentIndex"}
|
||||
case "IUserGimmickSequence":
|
||||
return []string{"userId", "gimmickSequenceScheduleId", "gimmickSequenceId"}
|
||||
case "IUserGimmickUnlock":
|
||||
return []string{"userId", "gimmickSequenceScheduleId", "gimmickSequenceId", "gimmickId"}
|
||||
case "IUserCostumeActiveSkill":
|
||||
return []string{"userId", "userCostumeUuid"}
|
||||
case "IUserCostumeAwakenStatusUp":
|
||||
return []string{"userId", "userCostumeUuid", "statusCalculationType"}
|
||||
case "IUserCostumeLotteryEffect":
|
||||
return []string{"userId", "userCostumeUuid", "slotNumber"}
|
||||
case "IUserCostumeLotteryEffectPending":
|
||||
return []string{"userId", "userCostumeUuid"}
|
||||
case "IUserCharacterBoard":
|
||||
return []string{"userId", "characterBoardId"}
|
||||
case "IUserCharacterBoardAbility":
|
||||
return []string{"userId", "characterId", "abilityId"}
|
||||
case "IUserCharacterBoardStatusUp":
|
||||
return []string{"userId", "characterId", "statusCalculationType"}
|
||||
case "IUserExploreScore":
|
||||
return []string{"userId", "exploreId"}
|
||||
case "IUserPartsGroupNote":
|
||||
return []string{"userId", "partsGroupId"}
|
||||
case "IUserPartsPreset":
|
||||
return []string{"userId", "userPartsPresetNumber"}
|
||||
case "IUserCageOrnamentReward":
|
||||
return []string{"userId", "cageOrnamentId"}
|
||||
case "IUserAutoSaleSettingDetail":
|
||||
return []string{"userId", "possessionAutoSaleItemType"}
|
||||
case "IUserCharacterRebirth":
|
||||
return []string{"userId", "characterId"}
|
||||
case "IUserShopItem":
|
||||
return []string{"userId", "shopItemId"}
|
||||
case "IUserShopReplaceableLineup":
|
||||
return []string{"userId", "slotNumber"}
|
||||
case "IUserNaviCutIn":
|
||||
return []string{"userId", "naviCutInId"}
|
||||
case "IUserMovie":
|
||||
return []string{"userId", "movieId"}
|
||||
case "IUserContentsStory":
|
||||
return []string{"userId", "contentsStoryId"}
|
||||
case "IUserOmikuji":
|
||||
return []string{"userId", "omikujiId"}
|
||||
case "IUserDokan":
|
||||
return []string{"userId", "dokanId"}
|
||||
case "IUserSideStoryQuest":
|
||||
return []string{"userId", "sideStoryQuestId"}
|
||||
case "IUserQuestLimitContentStatus":
|
||||
return []string{"userId", "questId"}
|
||||
case "IUserBigHuntMaxScore":
|
||||
return []string{"userId", "bigHuntBossId"}
|
||||
case "IUserBigHuntStatus":
|
||||
return []string{"userId", "bigHuntBossQuestId"}
|
||||
case "IUserBigHuntScheduleMaxScore":
|
||||
return []string{"userId", "bigHuntScheduleId", "bigHuntBossId"}
|
||||
case "IUserBigHuntWeeklyMaxScore":
|
||||
return []string{"userId", "bigHuntWeeklyVersion", "attributeType"}
|
||||
case "IUserBigHuntWeeklyStatus":
|
||||
return []string{"userId", "bigHuntWeeklyVersion"}
|
||||
case "IUserDeckTypeNote":
|
||||
return []string{"userId", "deckType"}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -4,11 +4,12 @@ import (
|
||||
"sort"
|
||||
|
||||
"lunar-tear/server/internal/store"
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
register("IUserBigHuntProgressStatus", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(map[string]any{
|
||||
s, _ := utils.EncodeJSONMaps(map[string]any{
|
||||
"userId": user.UserId,
|
||||
"currentBigHuntBossQuestId": user.BigHuntProgress.CurrentBigHuntBossQuestId,
|
||||
"currentBigHuntQuestId": user.BigHuntProgress.CurrentBigHuntQuestId,
|
||||
@@ -39,7 +40,7 @@ func init() {
|
||||
"latestVersion": ms.LatestVersion,
|
||||
})
|
||||
}
|
||||
s, _ := encodeJSONMaps(records...)
|
||||
s, _ := utils.EncodeJSONMaps(records...)
|
||||
return s
|
||||
})
|
||||
|
||||
@@ -63,7 +64,7 @@ func init() {
|
||||
"latestVersion": st.LatestVersion,
|
||||
})
|
||||
}
|
||||
s, _ := encodeJSONMaps(records...)
|
||||
s, _ := utils.EncodeJSONMaps(records...)
|
||||
return s
|
||||
})
|
||||
|
||||
@@ -97,7 +98,7 @@ func init() {
|
||||
"latestVersion": ms.LatestVersion,
|
||||
})
|
||||
}
|
||||
s, _ := encodeJSONMaps(records...)
|
||||
s, _ := utils.EncodeJSONMaps(records...)
|
||||
return s
|
||||
})
|
||||
|
||||
@@ -130,7 +131,7 @@ func init() {
|
||||
"latestVersion": ms.LatestVersion,
|
||||
})
|
||||
}
|
||||
s, _ := encodeJSONMaps(records...)
|
||||
s, _ := utils.EncodeJSONMaps(records...)
|
||||
return s
|
||||
})
|
||||
|
||||
@@ -153,7 +154,7 @@ func init() {
|
||||
"latestVersion": ws.LatestVersion,
|
||||
})
|
||||
}
|
||||
s, _ := encodeJSONMaps(records...)
|
||||
s, _ := utils.EncodeJSONMaps(records...)
|
||||
return s
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,19 +4,20 @@ import (
|
||||
"sort"
|
||||
|
||||
"lunar-tear/server/internal/store"
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
register("IUserCharacterBoard", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedCharacterBoardRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedCharacterBoardRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserCharacterBoardAbility", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedCharacterBoardAbilityRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedCharacterBoardAbilityRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserCharacterBoardStatusUp", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedCharacterBoardStatusUpRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedCharacterBoardStatusUpRecords(user)...)
|
||||
return s
|
||||
})
|
||||
registerStatic("IUserCharacterBoardCompleteReward")
|
||||
|
||||
@@ -5,31 +5,32 @@ import (
|
||||
|
||||
"lunar-tear/server/internal/model"
|
||||
"lunar-tear/server/internal/store"
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
register("IUserDeck", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedDeckRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedDeckRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserDeckCharacter", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedDeckCharacterRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedDeckCharacterRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserDeckSubWeaponGroup", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedDeckSubWeaponGroupRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedDeckSubWeaponGroupRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserDeckTypeNote", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedDeckTypeNoteRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedDeckTypeNoteRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserDeckPartsGroup", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedDeckPartsGroupRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedDeckPartsGroupRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserDeckCharacterDressupCostume", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedDeckDressupCostumeRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedDeckDressupCostumeRecords(user)...)
|
||||
return s
|
||||
})
|
||||
registerStatic(
|
||||
|
||||
@@ -4,23 +4,24 @@ import (
|
||||
"sort"
|
||||
|
||||
"lunar-tear/server/internal/store"
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
register("IUserGimmick", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedGimmickRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedGimmickRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserGimmickOrnamentProgress", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedGimmickOrnamentProgressRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedGimmickOrnamentProgressRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserGimmickSequence", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedGimmickSequenceRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedGimmickSequenceRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserGimmickUnlock", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedGimmickUnlockRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedGimmickUnlockRecords(user)...)
|
||||
return s
|
||||
})
|
||||
}
|
||||
|
||||
@@ -6,111 +6,112 @@ import (
|
||||
|
||||
"lunar-tear/server/internal/gametime"
|
||||
"lunar-tear/server/internal/store"
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
register("IUserCharacter", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedCharacterRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedCharacterRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserCostume", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedCostumeRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedCostumeRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserWeapon", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(SortedWeaponRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(SortedWeaponRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserWeaponStory", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedWeaponStoryRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedWeaponStoryRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserWeaponNote", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedWeaponNoteRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedWeaponNoteRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserCompanion", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedCompanionRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedCompanionRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserThought", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedThoughtRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedThoughtRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserConsumableItem", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(SortedConsumableItemRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(SortedConsumableItemRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserMaterial", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(SortedMaterialRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(SortedMaterialRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserImportantItem", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedImportantItemRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedImportantItemRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserPremiumItem", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedPremiumItemRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedPremiumItemRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserParts", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(SortedPartsRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(SortedPartsRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserCostumeActiveSkill", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedCostumeActiveSkillRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedCostumeActiveSkillRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserWeaponSkill", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(SortedWeaponSkillRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(SortedWeaponSkillRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserWeaponAbility", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(SortedWeaponAbilityRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(SortedWeaponAbilityRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserExplore", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(exploreRecord(user))
|
||||
s, _ := utils.EncodeJSONMaps(exploreRecord(user))
|
||||
return s
|
||||
})
|
||||
register("IUserExploreScore", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedExploreScoreRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedExploreScoreRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserPartsGroupNote", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedPartsGroupNoteRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedPartsGroupNoteRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserPartsPreset", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedPartsPresetRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedPartsPresetRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserCostumeAwakenStatusUp", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedCostumeAwakenStatusUpRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedCostumeAwakenStatusUpRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserAutoSaleSettingDetail", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedAutoSaleSettingRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedAutoSaleSettingRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserCharacterRebirth", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedCharacterRebirthRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedCharacterRebirthRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserCageOrnamentReward", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedCageOrnamentRewardRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedCageOrnamentRewardRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserWeaponAwaken", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(SortedWeaponAwakenRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(SortedWeaponAwakenRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserCostumeLotteryEffect", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedCostumeLotteryEffectRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedCostumeLotteryEffectRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserCostumeLotteryEffectPending", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(SortedCostumeLotteryEffectPendingRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(SortedCostumeLotteryEffectPendingRecords(user)...)
|
||||
return s
|
||||
})
|
||||
registerStatic(
|
||||
@@ -285,7 +286,7 @@ func WeaponStoryRecordsForIds(user store.UserState, weaponIds []int32) string {
|
||||
"latestVersion": row.LatestVersion,
|
||||
})
|
||||
}
|
||||
s, _ := encodeJSONMaps(records...)
|
||||
s, _ := utils.EncodeJSONMaps(records...)
|
||||
return s
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"sort"
|
||||
|
||||
"lunar-tear/server/internal/store"
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
func sortedQuestRecords(user store.UserState) []map[string]any {
|
||||
@@ -60,15 +61,15 @@ func sortedQuestMissionRecords(user store.UserState) []map[string]any {
|
||||
|
||||
func init() {
|
||||
register("IUserQuest", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedQuestRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedQuestRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserQuestMission", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedQuestMissionRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedQuestMissionRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserMainQuestFlowStatus", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(map[string]any{
|
||||
s, _ := utils.EncodeJSONMaps(map[string]any{
|
||||
"userId": user.UserId,
|
||||
"currentQuestFlowType": user.MainQuest.CurrentQuestFlowType,
|
||||
"latestVersion": user.MainQuest.LatestVersion,
|
||||
@@ -76,7 +77,7 @@ func init() {
|
||||
return s
|
||||
})
|
||||
register("IUserMainQuestMainFlowStatus", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(map[string]any{
|
||||
s, _ := utils.EncodeJSONMaps(map[string]any{
|
||||
"userId": user.UserId,
|
||||
"currentMainQuestRouteId": user.MainQuest.CurrentMainQuestRouteId,
|
||||
"currentQuestSceneId": user.MainQuest.CurrentQuestSceneId,
|
||||
@@ -87,7 +88,7 @@ func init() {
|
||||
return s
|
||||
})
|
||||
register("IUserMainQuestProgressStatus", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(map[string]any{
|
||||
s, _ := utils.EncodeJSONMaps(map[string]any{
|
||||
"userId": user.UserId,
|
||||
"currentQuestSceneId": user.MainQuest.ProgressQuestSceneId,
|
||||
"headQuestSceneId": user.MainQuest.ProgressHeadQuestSceneId,
|
||||
@@ -97,7 +98,7 @@ func init() {
|
||||
return s
|
||||
})
|
||||
register("IUserMainQuestSeasonRoute", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(map[string]any{
|
||||
s, _ := utils.EncodeJSONMaps(map[string]any{
|
||||
"userId": user.UserId,
|
||||
"mainQuestSeasonId": user.MainQuest.MainQuestSeasonId,
|
||||
"mainQuestRouteId": user.MainQuest.CurrentMainQuestRouteId,
|
||||
@@ -106,7 +107,7 @@ func init() {
|
||||
return s
|
||||
})
|
||||
register("IUserEventQuestProgressStatus", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(map[string]any{
|
||||
s, _ := utils.EncodeJSONMaps(map[string]any{
|
||||
"userId": user.UserId,
|
||||
"currentEventQuestChapterId": user.EventQuest.CurrentEventQuestChapterId,
|
||||
"currentQuestId": user.EventQuest.CurrentQuestId,
|
||||
@@ -117,7 +118,7 @@ func init() {
|
||||
return s
|
||||
})
|
||||
register("IUserExtraQuestProgressStatus", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(map[string]any{
|
||||
s, _ := utils.EncodeJSONMaps(map[string]any{
|
||||
"userId": user.UserId,
|
||||
"currentQuestId": user.ExtraQuest.CurrentQuestId,
|
||||
"currentQuestSceneId": user.ExtraQuest.CurrentQuestSceneId,
|
||||
@@ -127,7 +128,7 @@ func init() {
|
||||
return s
|
||||
})
|
||||
register("IUserMainQuestReplayFlowStatus", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(map[string]any{
|
||||
s, _ := utils.EncodeJSONMaps(map[string]any{
|
||||
"userId": user.UserId,
|
||||
"currentHeadQuestSceneId": user.MainQuest.ReplayFlowHeadQuestSceneId,
|
||||
"currentQuestSceneId": user.MainQuest.ReplayFlowCurrentQuestSceneId,
|
||||
@@ -136,7 +137,7 @@ func init() {
|
||||
return s
|
||||
})
|
||||
register("IUserSideStoryQuestSceneProgressStatus", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(map[string]any{
|
||||
s, _ := utils.EncodeJSONMaps(map[string]any{
|
||||
"userId": user.UserId,
|
||||
"currentSideStoryQuestId": user.SideStoryActiveProgress.CurrentSideStoryQuestId,
|
||||
"currentSideStoryQuestSceneId": user.SideStoryActiveProgress.CurrentSideStoryQuestSceneId,
|
||||
@@ -164,7 +165,7 @@ func init() {
|
||||
"latestVersion": progress.LatestVersion,
|
||||
})
|
||||
}
|
||||
s, _ := encodeJSONMaps(records...)
|
||||
s, _ := utils.EncodeJSONMaps(records...)
|
||||
return s
|
||||
})
|
||||
register("IUserQuestLimitContentStatus", func(user store.UserState) string {
|
||||
@@ -187,7 +188,7 @@ func init() {
|
||||
"latestVersion": st.LatestVersion,
|
||||
})
|
||||
}
|
||||
s, _ := encodeJSONMaps(records...)
|
||||
s, _ := utils.EncodeJSONMaps(records...)
|
||||
return s
|
||||
})
|
||||
registerStatic(
|
||||
|
||||
@@ -5,11 +5,12 @@ import (
|
||||
|
||||
"lunar-tear/server/internal/gametime"
|
||||
"lunar-tear/server/internal/store"
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
register("IUser", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(map[string]any{
|
||||
s, _ := utils.EncodeJSONMaps(map[string]any{
|
||||
"userId": user.UserId,
|
||||
"playerId": user.PlayerId,
|
||||
"osType": user.OsType,
|
||||
@@ -22,15 +23,15 @@ func init() {
|
||||
return s
|
||||
})
|
||||
register("IUserSetting", func(user store.UserState) string {
|
||||
s, _ := encodeJSONRecords(&EntityIUserSetting{
|
||||
UserId: user.UserId,
|
||||
IsNotifyPurchaseAlert: user.Setting.IsNotifyPurchaseAlert,
|
||||
LatestVersion: user.Setting.LatestVersion,
|
||||
s, _ := utils.EncodeJSONMaps(map[string]any{
|
||||
"userId": user.UserId,
|
||||
"isNotifyPurchaseAlert": user.Setting.IsNotifyPurchaseAlert,
|
||||
"latestVersion": user.Setting.LatestVersion,
|
||||
})
|
||||
return s
|
||||
})
|
||||
register("IUserStatus", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(map[string]any{
|
||||
s, _ := utils.EncodeJSONMaps(map[string]any{
|
||||
"userId": user.UserId,
|
||||
"level": user.Status.Level,
|
||||
"exp": user.Status.Exp,
|
||||
@@ -41,16 +42,16 @@ func init() {
|
||||
return s
|
||||
})
|
||||
register("IUserGem", func(user store.UserState) string {
|
||||
s, _ := encodeJSONRecords(&EntityIUserGem{
|
||||
UserId: user.UserId,
|
||||
PaidGem: user.Gem.PaidGem,
|
||||
FreeGem: user.Gem.FreeGem,
|
||||
LatestVersion: gametime.NowMillis(),
|
||||
s, _ := utils.EncodeJSONMaps(map[string]any{
|
||||
"userId": user.UserId,
|
||||
"paidGem": user.Gem.PaidGem,
|
||||
"freeGem": user.Gem.FreeGem,
|
||||
"latestVersion": gametime.NowMillis(),
|
||||
})
|
||||
return s
|
||||
})
|
||||
register("IUserProfile", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(map[string]any{
|
||||
s, _ := utils.EncodeJSONMaps(map[string]any{
|
||||
"userId": user.UserId,
|
||||
"name": user.Profile.Name,
|
||||
"nameUpdateDatetime": user.Profile.NameUpdateDatetime,
|
||||
@@ -63,58 +64,58 @@ func init() {
|
||||
return s
|
||||
})
|
||||
register("IUserLogin", func(user store.UserState) string {
|
||||
s, _ := encodeJSONRecords(&EntityIUserLogin{
|
||||
UserId: user.UserId,
|
||||
TotalLoginCount: user.Login.TotalLoginCount,
|
||||
ContinualLoginCount: user.Login.ContinualLoginCount,
|
||||
MaxContinualLoginCount: user.Login.MaxContinualLoginCount,
|
||||
LastLoginDatetime: user.Login.LastLoginDatetime,
|
||||
LastComebackLoginDatetime: user.Login.LastComebackLoginDatetime,
|
||||
LatestVersion: user.Login.LatestVersion,
|
||||
s, _ := utils.EncodeJSONMaps(map[string]any{
|
||||
"userId": user.UserId,
|
||||
"totalLoginCount": user.Login.TotalLoginCount,
|
||||
"continualLoginCount": user.Login.ContinualLoginCount,
|
||||
"maxContinualLoginCount": user.Login.MaxContinualLoginCount,
|
||||
"lastLoginDatetime": user.Login.LastLoginDatetime,
|
||||
"lastComebackLoginDatetime": user.Login.LastComebackLoginDatetime,
|
||||
"latestVersion": user.Login.LatestVersion,
|
||||
})
|
||||
return s
|
||||
})
|
||||
register("IUserLoginBonus", func(user store.UserState) string {
|
||||
s, _ := encodeJSONRecords(&EntityIUserLoginBonus{
|
||||
UserId: user.UserId,
|
||||
LoginBonusId: user.LoginBonus.LoginBonusId,
|
||||
CurrentPageNumber: user.LoginBonus.CurrentPageNumber,
|
||||
CurrentStampNumber: user.LoginBonus.CurrentStampNumber,
|
||||
LatestRewardReceiveDatetime: user.LoginBonus.LatestRewardReceiveDatetime,
|
||||
LatestVersion: user.LoginBonus.LatestVersion,
|
||||
s, _ := utils.EncodeJSONMaps(map[string]any{
|
||||
"userId": user.UserId,
|
||||
"loginBonusId": user.LoginBonus.LoginBonusId,
|
||||
"currentPageNumber": user.LoginBonus.CurrentPageNumber,
|
||||
"currentStampNumber": user.LoginBonus.CurrentStampNumber,
|
||||
"latestRewardReceiveDatetime": user.LoginBonus.LatestRewardReceiveDatetime,
|
||||
"latestVersion": user.LoginBonus.LatestVersion,
|
||||
})
|
||||
return s
|
||||
})
|
||||
register("IUserTutorialProgress", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedTutorialRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedTutorialRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserMission", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedMissionRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedMissionRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserNaviCutIn", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedNaviCutInRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedNaviCutInRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserMovie", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedMovieRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedMovieRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserContentsStory", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedContentsStoryRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedContentsStoryRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserOmikuji", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedOmikujiRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedOmikujiRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserDokan", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedDokanRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedDokanRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserPortalCageStatus", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(map[string]any{
|
||||
s, _ := utils.EncodeJSONMaps(map[string]any{
|
||||
"userId": user.UserId,
|
||||
"isCurrentProgress": user.PortalCageStatus.IsCurrentProgress,
|
||||
"dropItemStartDatetime": user.PortalCageStatus.DropItemStartDatetime,
|
||||
@@ -124,7 +125,7 @@ func init() {
|
||||
return s
|
||||
})
|
||||
register("IUserEventQuestGuerrillaFreeOpen", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(map[string]any{
|
||||
s, _ := utils.EncodeJSONMaps(map[string]any{
|
||||
"userId": user.UserId,
|
||||
"startDatetime": user.GuerrillaFreeOpen.StartDatetime,
|
||||
"openMinutes": user.GuerrillaFreeOpen.OpenMinutes,
|
||||
@@ -135,11 +136,11 @@ func init() {
|
||||
})
|
||||
|
||||
register("IUserShopItem", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedShopItemRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedShopItemRecords(user)...)
|
||||
return s
|
||||
})
|
||||
register("IUserShopReplaceable", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(map[string]any{
|
||||
s, _ := utils.EncodeJSONMaps(map[string]any{
|
||||
"userId": user.UserId,
|
||||
"lineupUpdateCount": user.ShopReplaceable.LineupUpdateCount,
|
||||
"latestLineupUpdateDatetime": user.ShopReplaceable.LatestLineupUpdateDatetime,
|
||||
@@ -148,11 +149,26 @@ func init() {
|
||||
return s
|
||||
})
|
||||
register("IUserShopReplaceableLineup", func(user store.UserState) string {
|
||||
s, _ := encodeJSONMaps(sortedShopReplaceableLineupRecords(user)...)
|
||||
s, _ := utils.EncodeJSONMaps(sortedShopReplaceableLineupRecords(user)...)
|
||||
return s
|
||||
})
|
||||
|
||||
registerStatic()
|
||||
register("IUserFacebook", func(user store.UserState) string {
|
||||
return ProjectFacebook(user.UserId, user.FacebookId)
|
||||
})
|
||||
registerStatic("IUserApple")
|
||||
}
|
||||
|
||||
func ProjectFacebook(userId int64, facebookId int64) string {
|
||||
if facebookId == 0 {
|
||||
return "[]"
|
||||
}
|
||||
s, _ := utils.EncodeJSONMaps(map[string]any{
|
||||
"userId": userId,
|
||||
"facebookId": facebookId,
|
||||
"latestVersion": gametime.NowMillis(),
|
||||
})
|
||||
return s
|
||||
}
|
||||
|
||||
func sortedTutorialRecords(user store.UserState) []map[string]any {
|
||||
|
||||
@@ -99,6 +99,8 @@ func FullClientTableMap(user store.UserState) map[string]string {
|
||||
"IUserBigHuntScheduleMaxScore": projectTable("IUserBigHuntScheduleMaxScore", user),
|
||||
"IUserBigHuntWeeklyMaxScore": projectTable("IUserBigHuntWeeklyMaxScore", user),
|
||||
"IUserBigHuntWeeklyStatus": projectTable("IUserBigHuntWeeklyStatus", user),
|
||||
"IUserFacebook": projectTable("IUserFacebook", user),
|
||||
"IUserApple": projectTable("IUserApple", user),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,302 +0,0 @@
|
||||
package userdata
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"lunar-tear/server/internal/gametime"
|
||||
|
||||
"github.com/vmihailenco/msgpack/v5"
|
||||
)
|
||||
|
||||
// EntityIUser mirrors the game's EntityIUser [MessagePackObject] with [Key(0..7)].
|
||||
// Serialized as a MessagePack array of 8 elements.
|
||||
type EntityIUser struct {
|
||||
_msgpack struct{} `msgpack:",asArray"`
|
||||
UserId int64 // Key(0)
|
||||
PlayerId int64 // Key(1)
|
||||
OsType int32 // Key(2) — 2 = Android
|
||||
PlatformType int32 // Key(3) — 2 = GooglePlay
|
||||
UserRestrictionType int32 // Key(4) — 0 = None
|
||||
RegisterDatetime int64 // Key(5) — unix millis
|
||||
GameStartDatetime int64 // Key(6) — unix millis
|
||||
LatestVersion int64 // Key(7)
|
||||
}
|
||||
|
||||
// EntityIUserSetting mirrors EntityIUserSetting [Key(0..2)].
|
||||
type EntityIUserSetting struct {
|
||||
_msgpack struct{} `msgpack:",asArray"`
|
||||
UserId int64 `json:"userId"` // Key(0)
|
||||
IsNotifyPurchaseAlert bool `json:"isNotifyPurchaseAlert"` // Key(1)
|
||||
LatestVersion int64 `json:"latestVersion"` // Key(2)
|
||||
}
|
||||
|
||||
// EntityIUserTutorialProgress mirrors EntityIUserTutorialProgress [Key(0..4)].
|
||||
type EntityIUserTutorialProgress struct {
|
||||
_msgpack struct{} `msgpack:",asArray"`
|
||||
UserId int64 // Key(0)
|
||||
TutorialType int32 // Key(1)
|
||||
ProgressPhase int32 // Key(2)
|
||||
ChoiceId int32 // Key(3)
|
||||
LatestVersion int64 // Key(4)
|
||||
}
|
||||
|
||||
// EntityIUserQuest mirrors EntityIUserQuest [Key(0..9)].
|
||||
type EntityIUserQuest struct {
|
||||
_msgpack struct{} `msgpack:",asArray"`
|
||||
UserId int64 // Key(0)
|
||||
QuestId int32 // Key(1)
|
||||
QuestStateType int32 // Key(2) — 2 = Cleared
|
||||
IsBattleOnly bool // Key(3)
|
||||
LatestStartDatetime int64 // Key(4) — unix millis
|
||||
ClearCount int32 // Key(5)
|
||||
DailyClearCount int32 // Key(6)
|
||||
LastClearDatetime int64 // Key(7) — unix millis
|
||||
ShortestClearFrames int32 // Key(8)
|
||||
LatestVersion int64 // Key(9)
|
||||
}
|
||||
|
||||
// EntityIUserMainQuestFlowStatus mirrors EntityIUserMainQuestFlowStatus [Key(0..2)].
|
||||
type EntityIUserMainQuestFlowStatus struct {
|
||||
_msgpack struct{} `msgpack:",asArray"`
|
||||
UserId int64 // Key(0)
|
||||
CurrentQuestFlowType int32 // Key(1) // QuestFlowType: 0=UNKNOWN, 1=MAIN_FLOW, 2=SUB_FLOW, 3=REPLAY_FLOW, 4=ANOTHER_ROUTE_REPLAY_FLOW
|
||||
LatestVersion int64 // Key(2)
|
||||
}
|
||||
|
||||
// EntityIUserMainQuestMainFlowStatus mirrors EntityIUserMainQuestMainFlowStatus [Key(0..5)].
|
||||
type EntityIUserMainQuestMainFlowStatus struct {
|
||||
_msgpack struct{} `msgpack:",asArray"`
|
||||
UserId int64 // Key(0)
|
||||
CurrentMainQuestRouteId int32 // Key(1)
|
||||
CurrentQuestSceneId int32 // Key(2)
|
||||
HeadQuestSceneId int32 // Key(3)
|
||||
IsReachedLastQuestScene bool // Key(4)
|
||||
LatestVersion int64 // Key(5)
|
||||
}
|
||||
|
||||
// EntityIUserMainQuestProgressStatus mirrors EntityIUserMainQuestProgressStatus [Key(0..4)].
|
||||
// This table is used by ActivePlayerToEntityPlayingMainQuestStatus (0x2AB4A48).
|
||||
type EntityIUserMainQuestProgressStatus struct {
|
||||
_msgpack struct{} `msgpack:",asArray"`
|
||||
UserId int64 // Key(0)
|
||||
CurrentQuestSceneId int32 // Key(1)
|
||||
HeadQuestSceneId int32 // Key(2)
|
||||
CurrentQuestFlowType int32 // Key(3) // QuestFlowType: 0=UNKNOWN, 1=MAIN_FLOW, 2=SUB_FLOW, 3=REPLAY_FLOW, 4=ANOTHER_ROUTE_REPLAY_FLOW
|
||||
LatestVersion int64 // Key(4)
|
||||
}
|
||||
|
||||
// EntityIUserMainQuestSeasonRoute mirrors EntityIUserMainQuestSeasonRoute [Key(0..3)].
|
||||
type EntityIUserMainQuestSeasonRoute struct {
|
||||
_msgpack struct{} `msgpack:",asArray"`
|
||||
UserId int64 // Key(0)
|
||||
MainQuestSeasonId int32 // Key(1)
|
||||
MainQuestRouteId int32 // Key(2)
|
||||
LatestVersion int64 // Key(3)
|
||||
}
|
||||
|
||||
// EntityIUserStatus mirrors EntityIUserStatus [Key(0..5)].
|
||||
type EntityIUserStatus struct {
|
||||
_msgpack struct{} `msgpack:",asArray"`
|
||||
UserId int64 // Key(0)
|
||||
Level int32 // Key(1)
|
||||
Exp int32 // Key(2)
|
||||
StaminaMilliValue int32 // Key(3)
|
||||
StaminaUpdateDatetime int64 // Key(4)
|
||||
LatestVersion int64 // Key(5)
|
||||
}
|
||||
|
||||
// EntityIUserGem mirrors EntityIUserGem [Key(0..3)].
|
||||
type EntityIUserGem struct {
|
||||
_msgpack struct{} `msgpack:",asArray"`
|
||||
UserId int64 `json:"userId"` // Key(0)
|
||||
PaidGem int32 `json:"paidGem"` // Key(1)
|
||||
FreeGem int32 `json:"freeGem"` // Key(2)
|
||||
LatestVersion int64 `json:"latestVersion"` // Key(3)
|
||||
}
|
||||
|
||||
// EntityIUserProfile mirrors EntityIUserProfile [Key(0..7)].
|
||||
type EntityIUserProfile struct {
|
||||
_msgpack struct{} `msgpack:",asArray"`
|
||||
UserId int64 // Key(0)
|
||||
Name string // Key(1)
|
||||
NameUpdateDatetime int64 // Key(2)
|
||||
Message string // Key(3)
|
||||
MessageUpdateDatetime int64 // Key(4)
|
||||
FavoriteCostumeId int32 // Key(5)
|
||||
FavoriteCostumeIdUpdateDatetime int64 // Key(6)
|
||||
LatestVersion int64 // Key(7)
|
||||
}
|
||||
|
||||
// EntityIUserCharacter mirrors EntityIUserCharacter [Key(0..4)].
|
||||
type EntityIUserCharacter struct {
|
||||
_msgpack struct{} `msgpack:",asArray"`
|
||||
UserId int64 // Key(0)
|
||||
CharacterId int32 // Key(1)
|
||||
Level int32 // Key(2)
|
||||
Exp int32 // Key(3)
|
||||
LatestVersion int64 // Key(4)
|
||||
}
|
||||
|
||||
// EntityIUserCostume mirrors EntityIUserCostume [Key(0..9)].
|
||||
type EntityIUserCostume struct {
|
||||
_msgpack struct{} `msgpack:",asArray"`
|
||||
UserId int64 // Key(0)
|
||||
UserCostumeUuid string // Key(1)
|
||||
CostumeId int32 // Key(2)
|
||||
LimitBreakCount int32 // Key(3)
|
||||
Level int32 // Key(4)
|
||||
Exp int32 // Key(5)
|
||||
HeadupDisplayViewId int32 // Key(6)
|
||||
AcquisitionDatetime int64 // Key(7)
|
||||
AwakenCount int32 // Key(8)
|
||||
LatestVersion int64 // Key(9)
|
||||
}
|
||||
|
||||
// EntityIUserWeapon mirrors EntityIUserWeapon [Key(0..8)].
|
||||
type EntityIUserWeapon struct {
|
||||
_msgpack struct{} `msgpack:",asArray"`
|
||||
UserId int64 // Key(0)
|
||||
UserWeaponUuid string // Key(1)
|
||||
WeaponId int32 // Key(2)
|
||||
Level int32 // Key(3)
|
||||
Exp int32 // Key(4)
|
||||
LimitBreakCount int32 // Key(5)
|
||||
IsProtected bool // Key(6)
|
||||
AcquisitionDatetime int64 // Key(7)
|
||||
LatestVersion int64 // Key(8)
|
||||
}
|
||||
|
||||
// EntityIUserCompanion mirrors EntityIUserCompanion [Key(0..6)].
|
||||
type EntityIUserCompanion struct {
|
||||
_msgpack struct{} `msgpack:",asArray"`
|
||||
UserId int64 // Key(0)
|
||||
UserCompanionUuid string // Key(1)
|
||||
CompanionId int32 // Key(2)
|
||||
HeadupDisplayViewId int32 // Key(3)
|
||||
Level int32 // Key(4)
|
||||
AcquisitionDatetime int64 // Key(5)
|
||||
LatestVersion int64 // Key(6)
|
||||
}
|
||||
|
||||
// EntityIUserDeckCharacter mirrors EntityIUserDeckCharacter [Key(0..7)].
|
||||
type EntityIUserDeckCharacter struct {
|
||||
_msgpack struct{} `msgpack:",asArray"`
|
||||
UserId int64 // Key(0)
|
||||
UserDeckCharacterUuid string // Key(1)
|
||||
UserCostumeUuid string // Key(2)
|
||||
MainUserWeaponUuid string // Key(3)
|
||||
UserCompanionUuid string // Key(4)
|
||||
Power int32 // Key(5)
|
||||
UserThoughtUuid string // Key(6)
|
||||
LatestVersion int64 // Key(7)
|
||||
}
|
||||
|
||||
// EntityIUserDeck mirrors EntityIUserDeck [Key(0..8)].
|
||||
type EntityIUserDeck struct {
|
||||
_msgpack struct{} `msgpack:",asArray"`
|
||||
UserId int64 // Key(0)
|
||||
DeckType int32 // Key(1)
|
||||
UserDeckNumber int32 // Key(2)
|
||||
UserDeckCharacterUuid01 string // Key(3)
|
||||
UserDeckCharacterUuid02 string // Key(4)
|
||||
UserDeckCharacterUuid03 string // Key(5)
|
||||
Name string // Key(6)
|
||||
Power int32 // Key(7)
|
||||
LatestVersion int64 // Key(8)
|
||||
}
|
||||
|
||||
// EntityIUserLogin mirrors EntityIUserLogin [Key(0..6)].
|
||||
type EntityIUserLogin struct {
|
||||
_msgpack struct{} `msgpack:",asArray"`
|
||||
UserId int64 `json:"userId"` // Key(0)
|
||||
TotalLoginCount int32 `json:"totalLoginCount"` // Key(1)
|
||||
ContinualLoginCount int32 `json:"continualLoginCount"` // Key(2)
|
||||
MaxContinualLoginCount int32 `json:"maxContinualLoginCount"` // Key(3)
|
||||
LastLoginDatetime int64 `json:"lastLoginDatetime"` // Key(4)
|
||||
LastComebackLoginDatetime int64 `json:"lastComebackLoginDatetime"` // Key(5)
|
||||
LatestVersion int64 `json:"latestVersion"` // Key(6)
|
||||
}
|
||||
|
||||
// EntityIUserLoginBonus mirrors EntityIUserLoginBonus [Key(0..5)].
|
||||
type EntityIUserLoginBonus struct {
|
||||
_msgpack struct{} `msgpack:",asArray"`
|
||||
UserId int64 `json:"userId"` // Key(0)
|
||||
LoginBonusId int32 `json:"loginBonusId"` // Key(1)
|
||||
CurrentPageNumber int32 `json:"currentPageNumber"` // Key(2)
|
||||
CurrentStampNumber int32 `json:"currentStampNumber"` // Key(3)
|
||||
LatestRewardReceiveDatetime int64 `json:"latestRewardReceiveDatetime"` // Key(4)
|
||||
LatestVersion int64 `json:"latestVersion"` // Key(5)
|
||||
}
|
||||
|
||||
// EntityIUserMission mirrors EntityIUserMission [Key(0..6)].
|
||||
type EntityIUserMission struct {
|
||||
_msgpack struct{} `msgpack:",asArray"`
|
||||
UserId int64 // Key(0)
|
||||
MissionId int32 // Key(1)
|
||||
StartDatetime int64 // Key(2)
|
||||
ProgressValue int32 // Key(3)
|
||||
MissionProgressStatusType int32 // Key(4)
|
||||
ClearDatetime int64 // Key(5)
|
||||
LatestVersion int64 // Key(6)
|
||||
}
|
||||
|
||||
// EncodeRecords serializes a slice of entities to the client-expected format:
|
||||
// a JSON array of base64-encoded MessagePack byte strings.
|
||||
func EncodeRecords(entities ...any) (string, error) {
|
||||
b64List := make([]string, 0, len(entities))
|
||||
for _, e := range entities {
|
||||
data, err := msgpack.Marshal(e)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("msgpack marshal: %w", err)
|
||||
}
|
||||
b64List = append(b64List, base64.StdEncoding.EncodeToString(data))
|
||||
}
|
||||
jsonBytes, err := json.Marshal(b64List)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("json marshal: %w", err)
|
||||
}
|
||||
return string(jsonBytes), nil
|
||||
}
|
||||
|
||||
func encodeJSONRecords(entities ...any) (string, error) {
|
||||
jsonBytes, err := json.Marshal(entities)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("json marshal records: %w", err)
|
||||
}
|
||||
return string(jsonBytes), nil
|
||||
}
|
||||
|
||||
func encodeJSONMaps(records ...map[string]any) (string, error) {
|
||||
jsonBytes, err := json.Marshal(records)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("json marshal maps: %w", err)
|
||||
}
|
||||
return string(jsonBytes), nil
|
||||
}
|
||||
|
||||
// DefaultUserData returns pre-built user data tables for a fresh user.
|
||||
// We provide BOTH msgpack-encoded (base64) and plain JSON variants.
|
||||
// The server tries msgpack first; if the client doesn't accept it, switch to JSON.
|
||||
func DefaultUserData(userId int64) map[string]string {
|
||||
now := gametime.Now().Unix()
|
||||
|
||||
userRecord, _ := EncodeRecords(&EntityIUser{
|
||||
UserId: userId,
|
||||
PlayerId: userId,
|
||||
OsType: 2,
|
||||
PlatformType: 2,
|
||||
RegisterDatetime: now,
|
||||
})
|
||||
|
||||
settingRecord, _ := EncodeRecords(&EntityIUserSetting{
|
||||
UserId: userId,
|
||||
})
|
||||
|
||||
data := map[string]string{
|
||||
"user": userRecord,
|
||||
"user_setting": settingRecord,
|
||||
}
|
||||
return data
|
||||
}
|
||||
Reference in New Issue
Block a user