Implement friend APIs and target profile support

- Add friend search/list/request/requestCancel/response/expel handlers and schemas
- Store friend relationships in user_friend and backfill default friend links at startup
- Auto-add the default user as a friend for newly created accounts
- Support target user_id in /api profile requests and return target profile data
- Make profile accessory_info optional to avoid zero-value accessory payloads
- Update login topInfo friend counters from friend relationship state

Signed-off-by: Sean Du <do4suki@gmail.com>
This commit is contained in:
2026-06-05 01:54:59 +08:00
parent ec2c5a6dac
commit d48293be44
28 changed files with 1653 additions and 159 deletions
+10
View File
@@ -0,0 +1,10 @@
package friendschema
type UserIDReq struct {
UserID int `json:"user_id"`
}
type ResponseReq struct {
UserID int `json:"user_id"`
Status int `json:"status"`
}
+7
View File
@@ -0,0 +1,7 @@
package friendschema
type ExpelResp struct {
ResponseData []any `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
+84
View File
@@ -0,0 +1,84 @@
package friendschema
type ListReq struct {
Module string `json:"module"`
Type int `json:"type"`
Action string `json:"action"`
TimeStamp int64 `json:"timeStamp"`
Mgd int `json:"mgd"`
Sort int `json:"sort"`
Page int `json:"page"`
CommandNum string `json:"commandNum"`
}
type UserData struct {
UserID int `json:"user_id"`
Name string `json:"name"`
Level int `json:"level"`
ElapsedTimeFromLogin string `json:"elapsed_time_from_login"`
ElapsedTimeFromApplied string `json:"elapsed_time_from_applied"`
Comment string `json:"comment"`
}
type AccessoryInfo struct {
AccessoryOwningUserID int `json:"accessory_owning_user_id"`
AccessoryID int `json:"accessory_id"`
Exp int `json:"exp"`
NextExp int `json:"next_exp"`
Level int `json:"level"`
MaxLevel int `json:"max_level"`
RankUpCount int `json:"rank_up_count"`
FavoriteFlag bool `json:"favorite_flag"`
}
type CenterUnitInfo struct {
UnitOwningUserID int64 `json:"unit_owning_user_id"`
UnitID int `json:"unit_id"`
Exp int `json:"exp"`
NextExp int `json:"next_exp"`
Level int `json:"level"`
LevelLimitID int `json:"level_limit_id"`
MaxLevel int `json:"max_level"`
Rank int `json:"rank"`
MaxRank int `json:"max_rank"`
Love int `json:"love"`
MaxLove int `json:"max_love"`
UnitSkillLevel int `json:"unit_skill_level"`
MaxHp int `json:"max_hp"`
FavoriteFlag bool `json:"favorite_flag"`
DisplayRank int `json:"display_rank"`
UnitSkillExp int `json:"unit_skill_exp"`
UnitRemovableSkillCapacity int `json:"unit_removable_skill_capacity"`
Attribute int `json:"attribute"`
Smile int `json:"smile"`
Cute int `json:"cute"`
Cool int `json:"cool"`
IsLoveMax bool `json:"is_love_max"`
IsLevelMax bool `json:"is_level_max"`
IsRankMax bool `json:"is_rank_max"`
IsSigned bool `json:"is_signed"`
IsSkillLevelMax bool `json:"is_skill_level_max"`
SettingAwardID int `json:"setting_award_id"`
RemovableSkillIds []int `json:"removable_skill_ids"`
AccessoryInfo AccessoryInfo `json:"accessory_info"`
}
type FriendList struct {
UserData UserData `json:"user_data"`
CenterUnitInfo CenterUnitInfo `json:"center_unit_info"`
SettingAwardID int `json:"setting_award_id"`
IsNew bool `json:"is_new"`
}
type ListData struct {
ItemCount int `json:"item_count"`
FriendList []FriendList `json:"friend_list"`
NewFriendList []any `json:"new_friend_list"`
ServerTimestamp int64 `json:"server_timestamp"`
}
type ListResp struct {
ResponseData ListData `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
+11
View File
@@ -0,0 +1,11 @@
package friendschema
type RequestData struct {
IsFriend bool `json:"is_friend"`
}
type RequestResp struct {
ResponseData RequestData `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
+11
View File
@@ -0,0 +1,11 @@
package friendschema
type RequestCancelData struct {
IsFriend bool `json:"is_friend"`
}
type RequestCancelResp struct {
ResponseData RequestCancelData `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
+7
View File
@@ -0,0 +1,7 @@
package friendschema
type ResponseResp struct {
ResponseData []any `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
+77
View File
@@ -0,0 +1,77 @@
package friendschema
type SearchReq struct {
Module string `json:"module"`
Action string `json:"action"`
TimeStamp int64 `json:"timeStamp"`
Mgd int `json:"mgd"`
InviteCode string `json:"invite_code"`
CommandNum string `json:"commandNum"`
}
type SearchUserInfo struct {
UserID int `json:"user_id"`
Name string `json:"name"`
Level int `json:"level"`
CostMax int `json:"cost_max"`
UnitMax int `json:"unit_max"`
EnergyMax int `json:"energy_max"`
FriendMax int `json:"friend_max"`
UnitCnt int `json:"unit_cnt"`
ElapsedTimeFromLogin string `json:"elapsed_time_from_login"`
Comment string `json:"comment"`
}
type SearchCostume struct {
UnitID int `json:"unit_id"`
IsRankMax bool `json:"is_rank_max"`
IsSigned bool `json:"is_signed"`
}
type SearchCenterUnitInfo struct {
UnitOwningUserID int64 `json:"unit_owning_user_id"`
UnitID int `json:"unit_id"`
Exp int `json:"exp"`
NextExp int `json:"next_exp"`
Level int `json:"level"`
LevelLimitID int `json:"level_limit_id"`
MaxLevel int `json:"max_level"`
Rank int `json:"rank"`
MaxRank int `json:"max_rank"`
Love int `json:"love"`
MaxLove int `json:"max_love"`
UnitSkillLevel int `json:"unit_skill_level"`
MaxHp int `json:"max_hp"`
FavoriteFlag bool `json:"favorite_flag"`
DisplayRank int `json:"display_rank"`
UnitSkillExp int `json:"unit_skill_exp"`
UnitRemovableSkillCapacity int `json:"unit_removable_skill_capacity"`
Attribute int `json:"attribute"`
Smile int `json:"smile"`
Cute int `json:"cute"`
Cool int `json:"cool"`
IsLoveMax bool `json:"is_love_max"`
IsLevelMax bool `json:"is_level_max"`
IsRankMax bool `json:"is_rank_max"`
IsSigned bool `json:"is_signed"`
IsSkillLevelMax bool `json:"is_skill_level_max"`
SettingAwardID int `json:"setting_award_id"`
RemovableSkillIds []int `json:"removable_skill_ids"`
AccessoryInfo AccessoryInfo `json:"accessory_info"`
Costume SearchCostume `json:"costume"`
}
type SearchData struct {
UserInfo SearchUserInfo `json:"user_info"`
CenterUnitInfo SearchCenterUnitInfo `json:"center_unit_info"`
SettingAwardID int `json:"setting_award_id"`
IsAlliance bool `json:"is_alliance"`
FriendStatus int `json:"friend_status"`
ServerTimestamp int64 `json:"server_timestamp"`
}
type SearchResp struct {
ResponseData SearchData `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}