Reorganize directory structures

Signed-off-by: Sean Du <do4suki@gmail.com>
This commit is contained in:
2025-08-05 20:06:35 +08:00
parent d666470272
commit adf2a72630
2087 changed files with 637 additions and 603 deletions
+83
View File
@@ -0,0 +1,83 @@
package handler
import (
"encoding/json"
"honoka-chan/internal/model"
"honoka-chan/internal/utils"
"net/http"
"github.com/gin-gonic/gin"
)
type AlbumRes struct {
UnitId int `xorm:"unit_id"`
Rarity int `xorm:"rarity"`
}
func AlbumSeriesAll(ctx *gin.Context) {
var albumIds []int
err := MainEng.Table("album_series_m").Select("album_series_id").Find(&albumIds)
utils.CheckErr(err)
// fmt.Println(albumIds)
albumSeriesAllRes := []model.AlbumSeriesRes{}
for _, albumId := range albumIds {
unitList := []AlbumRes{}
err = MainEng.Table("unit_m").Where("album_series_id = ?", albumId).Cols("unit_id,rarity").Find(&unitList)
utils.CheckErr(err)
albumSeriesAll := []model.AlbumResult{}
for _, unit := range unitList {
albumSeries := model.AlbumResult{
UnitID: unit.UnitId,
RankMaxFlag: true,
LoveMaxFlag: true,
RankLevelMaxFlag: true,
AllMaxFlag: true,
TotalLove: 10000,
FavoritePoint: 1000,
}
if unit.Rarity != 4 {
switch unit.Rarity {
case 1:
// N
albumSeries.HighestLovePerUnit = 50
case 2:
// R
albumSeries.HighestLovePerUnit = 200
case 3:
// SR
albumSeries.HighestLovePerUnit = 500
case 5:
// SSR
albumSeries.HighestLovePerUnit = 750
}
} else {
// UR
albumSeries.HighestLovePerUnit = 1000
// IsSigned
albumSeries.SignFlag = utils.IsSigned(unit.UnitId)
}
albumSeriesAll = append(albumSeriesAll, albumSeries)
}
albumSeriesAllRes = append(albumSeriesAllRes, model.AlbumSeriesRes{
SeriesID: albumId,
UnitList: albumSeriesAll,
})
}
albumResp := model.AlbumSeriesResp{
ResponseData: albumSeriesAllRes,
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(albumResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
+37
View File
@@ -0,0 +1,37 @@
package handler
import (
"encoding/json"
"honoka-chan/internal/model"
"honoka-chan/internal/utils"
"html/template"
"net/http"
"time"
"github.com/gin-gonic/gin"
)
func AnnounceIndex(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "common/announce.html", gin.H{
"title": "Love Live! 学园偶像祭 本地服务器",
"content": template.HTML(`目前开发完毕的功能包括:<br><ul><li>登录</li><li>相册</li><li>编队</li><li>饰品</li><li>宝石</li><li>Live</li><li>个人信息设置</li><li>官方漫画</li><ul><br>
其他功能仍在开发中,有报错属于正常现象。<br><br>
侵权联系:<a href="https://space.bilibili.com/671443">梦路_YumeMichi @bilibili</a> 进行删除。`),
})
}
func AnnounceCheckState(ctx *gin.Context) {
announceResp := model.AnnounceResp{
ResponseData: model.AnnounceRes{
HasUnreadAnnounce: false,
ServerTimestamp: time.Now().Unix(),
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(announceResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
File diff suppressed because it is too large Load Diff
+31
View File
@@ -0,0 +1,31 @@
package handler
import (
"encoding/json"
"honoka-chan/internal/model"
"honoka-chan/internal/tools"
"honoka-chan/internal/utils"
"net/http"
"github.com/gin-gonic/gin"
"github.com/tidwall/gjson"
)
func AwardSet(ctx *gin.Context) {
req := gjson.Parse(ctx.PostForm("request_data"))
pref := tools.UserPref{
AwardID: int(req.Get("award_id").Int()),
}
_, err := UserEng.Table("user_preference_m").Where("user_id = ?", ctx.GetString("userid")).Update(&pref)
utils.CheckErr(err)
awardResp := model.AwardSetResp{
ResponseData: []any{},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(awardResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
+31
View File
@@ -0,0 +1,31 @@
package handler
import (
"encoding/json"
"honoka-chan/internal/model"
"honoka-chan/internal/tools"
"honoka-chan/internal/utils"
"net/http"
"github.com/gin-gonic/gin"
"github.com/tidwall/gjson"
)
func BackgroundSet(ctx *gin.Context) {
req := gjson.Parse(ctx.PostForm("request_data"))
pref := tools.UserPref{
BackgroundID: int(req.Get("background_id").Int()),
}
_, err := UserEng.Table("user_preference_m").Where("user_id = ?", ctx.GetString("userid")).Update(&pref)
utils.CheckErr(err)
backgroundResp := model.BackgroundSetResp{
ResponseData: []any{},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(backgroundResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
+176
View File
@@ -0,0 +1,176 @@
package handler
import (
"encoding/json"
"fmt"
"honoka-chan/config"
"honoka-chan/internal/model"
"honoka-chan/internal/utils"
"io"
"net/http"
"strings"
"github.com/gin-gonic/gin"
"xorm.io/builder"
)
type PkgInfo struct {
Id int `xorm:"pkg_id"`
Order int `xorm:"pkg_order"`
Size int `xorm:"pkg_size"`
}
func DownloadAdditional(ctx *gin.Context) {
downloadReq := model.AdditionalReq{}
if err := json.Unmarshal([]byte(ctx.GetString("request_data")), &downloadReq); err != nil {
panic(err)
}
pkgList := []model.AdditionalRes{}
if SifCdnServer != "" {
pkgType, pkgId := downloadReq.PackageType, downloadReq.PackageID
var pkgInfo []PkgInfo
err := MainEng.Table("download_m").Where("pkg_type = ? AND pkg_id = ? AND pkg_os = ?", pkgType, pkgId, downloadReq.TargetOs).
Cols("pkg_id,pkg_order,pkg_size").
OrderBy("pkg_id ASC, pkg_order ASC").Find(&pkgInfo)
utils.CheckErr(err)
for _, pkg := range pkgInfo {
pkgList = append(pkgList, model.AdditionalRes{
Size: pkg.Size,
URL: fmt.Sprintf("%s/%s/archives/%d_%d_%d.zip", SifCdnServer, downloadReq.TargetOs, pkgType, pkg.Id, pkg.Order),
})
}
}
addResp := model.AdditionalResp{
ResponseData: pkgList,
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(addResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
func DownloadBatch(ctx *gin.Context) {
downloadReq := model.BatchReq{}
if err := json.Unmarshal([]byte(ctx.GetString("request_data")), &downloadReq); err != nil {
panic(err)
}
pkgList := []model.BatchRes{}
if downloadReq.ClientVersion == config.PackageVersion && SifCdnServer != "" {
pkgType := downloadReq.PackageType
var pkgInfo []PkgInfo
err := MainEng.Table("download_m").Where(builder.NotIn("pkg_id", downloadReq.ExcludedPackageIds)).Where("pkg_type = ? AND pkg_os = ?", pkgType, downloadReq.Os).
Cols("pkg_id,pkg_order,pkg_size").
OrderBy("pkg_id ASC, pkg_order ASC").Find(&pkgInfo)
utils.CheckErr(err)
for _, pkg := range pkgInfo {
pkgList = append(pkgList, model.BatchRes{
Size: pkg.Size,
URL: fmt.Sprintf("%s/%s/archives/%d_%d_%d.zip", SifCdnServer, downloadReq.Os, pkgType, pkg.Id, pkg.Order),
})
}
}
batchResp := model.BatchResp{
ResponseData: pkgList,
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(batchResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
func DownloadUpdate(ctx *gin.Context) {
downloadReq := model.UpdateReq{}
if err := json.Unmarshal([]byte(ctx.GetString("request_data")), &downloadReq); err != nil {
panic(err)
}
pkgList := []model.UpdateRes{}
if downloadReq.ExternalVersion != config.PackageVersion && SifCdnServer != "" {
pkgType := 99
var pkgInfo []PkgInfo
err := MainEng.Table("download_m").Where("pkg_type = ? AND pkg_os = ?", pkgType, downloadReq.TargetOs).
Cols("pkg_id,pkg_order,pkg_size").
OrderBy("pkg_id ASC, pkg_order ASC").Find(&pkgInfo)
utils.CheckErr(err)
for _, pkg := range pkgInfo {
pkgList = append(pkgList, model.UpdateRes{
Size: pkg.Size,
URL: fmt.Sprintf("%s/%s/archives/%d_%d_%d.zip", SifCdnServer, downloadReq.TargetOs, pkgType, pkg.Id, pkg.Order),
Version: config.PackageVersion,
})
}
patchFileUrl := fmt.Sprintf("%s/%s/archives/99_0_115.zip", SifCdnServer, downloadReq.TargetOs)
resp, err := http.Get(patchFileUrl)
if err == nil {
res, err := io.ReadAll(resp.Body)
if err == nil {
pkgList = append(pkgList, model.UpdateRes{
Size: len(res),
URL: patchFileUrl,
Version: config.PackageVersion,
})
}
defer resp.Body.Close()
}
}
updateResp := model.UpdateResp{
ResponseData: pkgList,
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(updateResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
func DownloadUrl(ctx *gin.Context) {
// Extract SQL: SELECT CAST(pkg_type AS TEXT) || '_' || CAST(pkg_id AS TEXT) || '_' || CAST(pkg_order AS TEXT) || '.zip' AS zip_name FROM download_m ORDER BY pkg_type ASC,pkg_id ASC, pkg_order ASC;
// Extract Cmd: cat list.txt | while read line; do; unzip -o $line; done
downloadReq := model.UrlReq{}
if err := json.Unmarshal([]byte(ctx.GetString("request_data")), &downloadReq); err != nil {
panic(err)
}
urlList := []string{}
for _, v := range downloadReq.PathList {
urlList = append(urlList, fmt.Sprintf("%s/%s/extracted/%s", SifCdnServer, downloadReq.Os, strings.ReplaceAll(v, "\\", "")))
}
urlResp := model.UrlResp{
ResponseData: model.UrlRes{
UrlList: urlList,
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(urlResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
func DownloadEvent(ctx *gin.Context) {
eventResp := model.EventResp{
ResponseData: []any{},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(eventResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
+34
View File
@@ -0,0 +1,34 @@
package handler
import (
"encoding/json"
"honoka-chan/internal/model"
"honoka-chan/internal/utils"
"net/http"
"time"
"github.com/gin-gonic/gin"
)
func EventList(ctx *gin.Context) {
targets := []model.TargetList{}
for i := 0; i < 6; i++ {
targets = append(targets, model.TargetList{
Position: i + 1,
IsDisplayable: false,
})
}
eventsResp := model.EventsResp{
ResponseData: model.EventsRes{
TargetList: targets,
ServerTimestamp: time.Now().Unix(),
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(eventsResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
+28
View File
@@ -0,0 +1,28 @@
package handler
import (
"encoding/json"
"honoka-chan/internal/model"
"honoka-chan/internal/utils"
"net/http"
"time"
"github.com/gin-gonic/gin"
)
func Gdpr(ctx *gin.Context) {
gdprResp := model.GdprResp{
ResponseData: model.GdprRes{
EnableGdpr: true,
IsEea: false,
ServerTimestamp: time.Now().Unix(),
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(gdprResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
+23
View File
@@ -0,0 +1,23 @@
package handler
import (
"honoka-chan/config"
"honoka-chan/pkg/db"
"xorm.io/xorm"
)
var (
SifCdnServer string
AsCdnServer string
ErrorMsg = `{"code":20001,"message":""}`
MainEng *xorm.Engine
UserEng *xorm.Engine
)
func init() {
SifCdnServer = config.Conf.Settings.SifCdnServer
MainEng = db.MainEng
UserEng = db.UserEng
}
+156
View File
@@ -0,0 +1,156 @@
package handler
import (
"encoding/json"
"honoka-chan/internal/model"
"honoka-chan/internal/utils"
"net/http"
"time"
"github.com/gin-gonic/gin"
)
func LBonusExecute(ctx *gin.Context) {
weeks := map[string]int{
"Monday": 1,
"Tuesday": 2,
"Wednesday": 3,
"Thursday": 4,
"Friday": 5,
"Saturday": 6,
"Sunday": 7,
}
// 本月日历
y, m, d := time.Now().Local().Date()
cm := m
d1 := time.Date(y, m, 1, 0, 0, 0, 0, time.Local)
// fmt.Println(d1)
// fmt.Println(weeks[d1.Weekday().String()])
d2 := d1.AddDate(0, 1, -1)
// fmt.Println(d2)
weeksList := []model.LbDays{}
for c := d1; ; c = c.AddDate(0, 0, 1) {
_, _, rd := c.Date()
received := false
if rd <= d {
received = true
}
rw := weeks[c.Weekday().String()]
weeksList = append(weeksList, model.LbDays{
Day: rd,
DayOfTheWeek: rw,
SpecialDay: false,
SpecialImageAsset: "",
Received: received,
AdReceived: false,
Item: model.LbDayItem{
ItemID: 4,
AddType: 3001,
Amount: 1,
},
})
if c == d2 {
break
}
}
// 下月日历
y, m, _ = time.Now().AddDate(0, 1, 0).Date()
// fmt.Println(y, m, d)
d1 = time.Date(y, m, 1, 0, 0, 0, 0, time.Local)
// fmt.Println(d1)
// fmt.Println(weeks[d1.Weekday().String()])
d2 = d1.AddDate(0, 1, -1)
// fmt.Println(d2)
nextWeeksList := []model.LbDays{}
for c := d1; ; c = c.AddDate(0, 0, 1) {
_, _, rd := c.Date()
rw := weeks[c.Weekday().String()]
nextWeeksList = append(nextWeeksList, model.LbDays{
Day: rd,
DayOfTheWeek: rw,
SpecialDay: false,
SpecialImageAsset: "",
Received: false,
AdReceived: false,
Item: model.LbDayItem{
ItemID: 4,
AddType: 3001,
Amount: 1,
},
})
if c == d2 {
break
}
}
LbRes := model.LbResp{
ResponseData: model.LbRes{
Sheets: []any{},
CalendarInfo: model.CalendarInfo{
CurrentDate: time.Now().Format("2006-01-02 03:04:05"),
CurrentMonth: model.LbMonth{
Year: y,
Month: int(cm),
Days: weeksList,
},
NextMonth: model.LbMonth{
Year: y,
Month: int(m),
Days: nextWeeksList,
},
},
TotalLoginInfo: model.TotalLoginInfo{
LoginCount: 2626,
RemainingCount: 74,
Reward: []model.Reward{
{
ItemID: 5,
AddType: 1000,
Amount: 5,
},
},
},
LicenseLbonusList: []any{},
ClassSystem: model.LbClassSystem{
RankInfo: model.LbRankInfo{
BeforeClassRankID: 10,
AfterClassRankID: 10,
RankUpDate: "2020-02-12 11:57:15",
},
CompleteFlag: false,
IsOpened: true,
IsVisible: true,
},
StartDashSheets: []any{},
EffortPoint: []model.EffortPoint{
{
LiveEffortPointBoxSpecID: 5,
Capacity: 4000000,
Before: 1400116,
After: 1400116,
Rewards: []model.Rewards{},
},
},
LimitedEffortBox: []any{},
MuseumInfo: model.Museum{},
ServerTimestamp: time.Now().Unix(),
PresentCnt: 0,
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(LbRes)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
+693
View File
@@ -0,0 +1,693 @@
package handler
import (
"encoding/json"
"honoka-chan/config"
"honoka-chan/internal/model"
"honoka-chan/internal/utils"
"honoka-chan/pkg/db"
honokautils "honoka-chan/pkg/utils"
"math"
"net/http"
"strconv"
"time"
"github.com/gin-gonic/gin"
"github.com/tidwall/gjson"
)
func PartyList(ctx *gin.Context) {
resp := honokautils.ReadAllText("assets/serverdata/partylist.json")
ctx.Header("X-Message-Sign", utils.GenXMS([]byte(resp)))
ctx.String(http.StatusOK, resp)
}
func PlayLive(ctx *gin.Context) {
playReq := model.PlayReq{}
err := json.Unmarshal([]byte(ctx.GetString("request_data")), &playReq)
utils.CheckErr(err)
tDifficultyId := playReq.LiveDifficultyID
difficultyId, err := strconv.Atoi(tDifficultyId)
utils.CheckErr(err)
deckId := playReq.UnitDeckID
// Save Deck Id for /live/reward
key := "live_deck_" + ctx.GetString("userid")
err = db.DB.Set([]byte(key), []byte(strconv.Itoa(deckId)))
utils.CheckErr(err)
// Song type: normal / special
// sqlite3 doesn't support FULL OUTER JOIN so use UNION ALL here.
sql := `SELECT notes_setting_asset,c_rank_score,b_rank_score,a_rank_score,s_rank_score,ac_flag,swing_flag FROM live_setting_m WHERE live_setting_id IN (SELECT live_setting_id FROM normal_live_m WHERE live_difficulty_id = ? UNION ALL SELECT live_setting_id FROM special_live_m WHERE live_difficulty_id = ?)`
var notes_setting_asset string
var c_rank_score, b_rank_score, a_rank_score, s_rank_score, ac_flag, swing_flag int
err = MainEng.DB().QueryRow(sql, difficultyId, difficultyId).Scan(&notes_setting_asset, &c_rank_score, &b_rank_score, &a_rank_score, &s_rank_score, &ac_flag, &swing_flag)
utils.CheckErr(err)
// fmt.Println(notes_setting_asset)
// fmt.Println(c_rank_score, b_rank_score, a_rank_score, s_rank_score)
notes := []model.NotesList{}
// fmt.Println("./assets/notes/" + notes_setting_asset)
notes_list := honokautils.ReadAllText("./assets/serverdata/notes/" + notes_setting_asset)
err = json.Unmarshal([]byte(notes_list), &notes)
utils.CheckErr(err)
ranks := []model.RankInfo{}
ranks = append(ranks, model.RankInfo{
Rank: 5,
RankMin: 0,
RankMax: c_rank_score,
}, model.RankInfo{
Rank: 4,
RankMin: c_rank_score + 1,
RankMax: b_rank_score,
}, model.RankInfo{
Rank: 3,
RankMin: b_rank_score + 1,
RankMax: a_rank_score,
}, model.RankInfo{
Rank: 2,
RankMin: a_rank_score + 1,
RankMax: s_rank_score,
}, model.RankInfo{
Rank: 1,
RankMin: s_rank_score + 1,
RankMax: 0,
})
// UserEng.ShowSQL(true)
// MainEng.ShowSQL(true)
owningIdList := []int{}
err = UserEng.Table("deck_unit_m").Join("LEFT", "user_deck_m", "deck_unit_m.user_deck_id = user_deck_m.id").
Where("user_id = ? AND deck_id = ?", ctx.GetString("userid"), deckId).Cols("unit_owning_user_id").
OrderBy("deck_unit_m.position ASC").Find(&owningIdList)
utils.CheckErr(err)
unitList := []model.UnitList{}
var totalSmile, totalPure, totalCool, maxLove float64
var totalHp int
for _, owningId := range owningIdList {
var uId int
exists, err := MainEng.Table("common_unit_m").Where("unit_owning_user_id = ?", owningId).Cols("unit_id").Get(&uId)
utils.CheckErr(err)
var maxHp, attrId, unitTypeId int
var baseSmile, basePure, baseCool, smileMax, pureMax, coolMax float64
if exists {
// 公共卡片仅为100级属性
_, err = MainEng.Table("unit_m").Where("unit_id = ?", uId).
Join("LEFT", "unit_rarity_m", "unit_m.rarity = unit_rarity_m.rarity").
Cols("attribute_id,hp_max,smile_max,pure_max,cool_max,after_love_max,unit_type_id").
Get(&attrId, &maxHp, &baseSmile, &basePure, &baseCool, &maxLove, &unitTypeId)
utils.CheckErr(err)
} else {
// 用户卡片暂时固定为满级350级
exists, err := UserEng.Table("user_unit_m").Where("unit_owning_user_id = ?", owningId).Cols("unit_id").Get(&uId)
utils.CheckErr(err)
if exists {
// 卡片100级基础属性
_, err = MainEng.Table("unit_m").Where("unit_id = ?", uId).
Join("LEFT", "unit_rarity_m", "unit_m.rarity = unit_rarity_m.rarity").
Cols("attribute_id,hp_max,smile_max,pure_max,cool_max,after_love_max,unit_type_id").
Get(&attrId, &maxHp, &baseSmile, &basePure, &baseCool, &maxLove, &unitTypeId)
utils.CheckErr(err)
// 增量属性
var diffSmile, diffPure, diffCool float64
_, err = MainEng.Table("unit_level_limit_pattern_m").Where("unit_level_limit_id = 1 AND unit_level = 350").
Cols("smile_diff,pure_diff,cool_diff").Get(&diffSmile, &diffPure, &diffCool)
utils.CheckErr(err)
// 更新卡片属性(注意这里是负数,要用减号)
baseSmile -= diffSmile
basePure -= diffPure
baseCool -= diffCool
} else {
panic("no such unit")
}
}
// 饰品属性加成(满级)
var accessoryOwningId int
_, err = UserEng.Table("accessory_wear_m").Where("unit_owning_user_id = ?", owningId).
Cols("accessory_owning_user_id").Get(&accessoryOwningId)
utils.CheckErr(err)
var smileAccessory, pureAccessory, coolAccessory float64
_, err = MainEng.Table("common_accessory_m").Join("LEFT", "accessory_m", "common_accessory_m.accessory_id = accessory_m.accessory_id").
Where("accessory_owning_user_id = ?", accessoryOwningId).Cols("smile_max,pure_max,cool_max").
Get(&smileAccessory, &pureAccessory, &coolAccessory)
utils.CheckErr(err)
// fmt.Println("基础属性:", baseSmile, basePure, baseCool)
// 饰品属性加成(该加成会影响个宝等百分比宝石属性加成的计算,故先计算。)
baseSmile += smileAccessory
basePure += pureAccessory
baseCool += coolAccessory
// fmt.Println("饰品属性加成:", smileAccessory, pureAccessory, coolAccessory)
// fmt.Println("饰品属性加成后的基础属性:", baseSmile, basePure, baseCool)
// 回忆画廊属性加成(该加成会影响个宝等百分比宝石属性加成的计算,故先计算。)
var smileBuff, pureBuff, coolBuff float64
_, err = MainEng.Table("museum_contents_m").Select("SUM(smile_buff),SUM(pure_buff),SUM(cool_buff)").Get(&smileBuff, &pureBuff, &coolBuff)
utils.CheckErr(err)
baseSmile += smileBuff
basePure += pureBuff
baseCool += coolBuff
// fmt.Println("回忆画廊属性加成:", smileBuff, pureBuff, coolBuff)
// fmt.Println("回忆画廊属性加成后的基础属性:", baseSmile, basePure, baseCool)
// 绊属性加成(该加成会影响个宝等百分比宝石属性加成的计算,故先计算。)
if attrId == 1 {
baseSmile += maxLove
} else if attrId == 2 {
basePure += maxLove
} else if attrId == 3 {
baseCool += maxLove
}
// fmt.Println("绊属性加成:", maxLove)
// fmt.Println("绊属性加成后的基础属性:", baseSmile, basePure, baseCool)
// 宝石属性加成
var kissSmile, kissPure, kissCool float64
var skillSmile, skillPure, skillCool float64
// var mainCenterSmile, mainCenterPure, mainCenterCool float64
// var secCenterSmile, secCenterPure, secCenterCool float64
// 宝石加成(满级)
removableSkillIds := []int{}
err = UserEng.Table("skill_equip_m").Where("unit_owning_user_id = ? AND user_id = ?", owningId, ctx.GetString("userid")).
Cols("unit_removable_skill_id").Find(&removableSkillIds)
utils.CheckErr(err)
for _, sk := range removableSkillIds {
// 判断宝石效果类型(效果范围、效果类型、效果值、是否固定数值)
var effectRange, effectType, fixedValueFlag, refType int
var effectValue float64
_, err = MainEng.Table("unit_removable_skill_m").Where("unit_removable_skill_id = ?", sk).
Cols("effect_range,effect_type,effect_value,fixed_value_flag,target_reference_type").
Get(&effectRange, &effectType, &effectValue, &fixedValueFlag, &refType)
utils.CheckErr(err)
if fixedValueFlag == 1 {
// 吻、眼神属性加成(固定数值)
if effectType == 1 {
kissSmile += effectValue
} else if effectType == 2 {
kissPure += effectValue
} else if effectType == 3 {
kissCool += effectValue
}
// fmt.Println("吻、眼神属性加成:", kissSmile, kissPure, kissCool)
} else {
// 仅效果类型为1、2、3的有属性加成
if effectType == 1 || effectType == 2 || effectType == 3 {
// 加成范围:2:全员 1:非全员
if effectRange == 2 {
if effectType == 1 {
skillSmile += math.Ceil(baseSmile * (effectValue / 100))
} else if effectType == 2 {
skillPure += math.Ceil(basePure * (effectValue / 100))
} else if effectType == 3 {
skillCool += math.Ceil(baseCool * (effectValue / 100))
}
// fmt.Println("全员类宝石属性加成:", skillSmile, skillPure, skillCool)
} else {
// refType: 1 -> 年级类加成, target_type -> 指定年级(这里不需要使用,因为能装上宝石肯定是符合的)
// refType: 2 -> 个宝
// refType: 3 -> 爆分、奶、判宝石, 0 -> 竞技场宝石
if refType == 1 || refType == 2 { // 年级类和个宝都是百分比加成
if effectType == 1 {
skillSmile += math.Ceil(baseSmile * (effectValue / 100))
} else if effectType == 2 {
skillPure += math.Ceil(basePure * (effectValue / 100))
} else if effectValue == 3 {
skillCool += math.Ceil(baseCool * (effectValue / 100))
}
// fmt.Println("年级类宝石、个宝属性加成:", skillSmile, skillPure, skillCool)
}
}
}
}
}
// 单卡属性
smileMax = baseSmile + kissSmile + skillSmile
pureMax = basePure + kissPure + skillPure
coolMax = baseCool + kissCool + skillCool
// 主唱技能加成
var myCenterUnitId int
_, err = UserEng.Table("deck_unit_m").Join("LEFT", "user_deck_m", "deck_unit_m.user_deck_id = user_deck_m.id").
Where("user_deck_m.deck_id = ? AND user_deck_m.user_id = ? AND deck_unit_m.position = 5", playReq.UnitDeckID, ctx.GetString("userid")).
Cols("deck_unit_m.unit_id").Get(&myCenterUnitId)
utils.CheckErr(err)
// 主唱技能加成:主C技能(这里不使用新C技能,即以某属性的百分比提升另一属性)
var myAttrId int
var myEffectValue float64
_, err = MainEng.Table("unit_m").
Join("LEFT", "unit_leader_skill_m", "unit_m.default_leader_skill_id = unit_leader_skill_m.unit_leader_skill_id").
Where("unit_m.unit_id = ?", myCenterUnitId).
Cols("unit_m.attribute_id,unit_leader_skill_m.effect_value").Get(&myAttrId, &myEffectValue)
utils.CheckErr(err)
var myCenterSmile, myCenterPure, myCenterCool float64
if myAttrId == 1 {
myCenterSmile = math.Ceil(smileMax * (myEffectValue / 100))
} else if myAttrId == 2 {
myCenterPure = math.Ceil(pureMax * (myEffectValue / 100))
} else if myAttrId == 3 {
myCenterCool = math.Ceil(coolMax * (myEffectValue / 100))
}
// fmt.Println("主C技能属性加成:", myCenterSmile, myCenterPure, myCenterCool)
// 主唱技能加成:副C技能
var mySubEffectValue float64
var myMemberTagId int
_, err = MainEng.Table("unit_m").
Join("LEFT", "unit_leader_skill_extra_m", "unit_m.default_leader_skill_id = unit_leader_skill_extra_m.unit_leader_skill_id").
Where("unit_m.unit_id = ?", myCenterUnitId).
Cols("unit_leader_skill_extra_m.effect_value,unit_leader_skill_extra_m.member_tag_id").Get(&mySubEffectValue, &myMemberTagId)
utils.CheckErr(err)
exists, err = MainEng.Table("unit_type_member_tag_m").
Where("unit_type_id = ? AND member_tag_id = ?", unitTypeId, myMemberTagId).Exist()
utils.CheckErr(err)
var mySubSmile, mySubPure, mySubCool float64
if exists {
if myAttrId == 1 {
mySubSmile = math.Ceil(smileMax * (mySubEffectValue / 100))
} else if myAttrId == 2 {
mySubPure = math.Ceil(pureMax * (mySubEffectValue / 100))
} else if myAttrId == 3 {
mySubCool = math.Ceil(coolMax * (mySubEffectValue / 100))
}
// fmt.Println("副C技能属性加成:", mySubSmile, mySubPure, mySubCool)
}
// 好友主唱技能加成
// TODO 好友支援存入数据库
var tomoUnitId int64
partyList := gjson.Parse(honokautils.ReadAllText("assets/serverdata/partylist.json")).Get("response_data.party_list")
partyList.ForEach(func(key, value gjson.Result) bool {
if value.Get("user_info.user_id").Int() == playReq.PartyUserID {
tomoUnitId = value.Get("center_unit_info.unit_id").Int()
return false
}
return true
})
// fmt.Println("好友UnitID:", tomoUnitId)
// 好友主唱技能加成:主C技能(这里不使用新C技能,即以某属性的百分比提升另一属性)
var tomoAttrId int
var tomoEffectValue float64
_, err = MainEng.Table("unit_m").
Join("LEFT", "unit_leader_skill_m", "unit_m.default_leader_skill_id = unit_leader_skill_m.unit_leader_skill_id").
Where("unit_m.unit_id = ?", tomoUnitId).
Cols("unit_m.attribute_id,unit_leader_skill_m.effect_value").Get(&tomoAttrId, &tomoEffectValue)
utils.CheckErr(err)
var tomoCenterSmile, tomoCenterPure, tomoCenterCool float64
if myAttrId == 1 {
tomoCenterSmile = math.Ceil(smileMax * (tomoEffectValue / 100))
} else if myAttrId == 2 {
tomoCenterPure = math.Ceil(pureMax * (tomoEffectValue / 100))
} else if myAttrId == 3 {
tomoCenterCool = math.Ceil(coolMax * (tomoEffectValue / 100))
}
// fmt.Println("好友主C技能属性加成:", tomoCenterSmile, tomoCenterPure, tomoCenterCool)
// 好友主唱技能加成:副C技能
var tomoSubEffectValue float64
var tomoMemberTagId int
_, err = MainEng.Table("unit_m").
Join("LEFT", "unit_leader_skill_extra_m", "unit_m.default_leader_skill_id = unit_leader_skill_extra_m.unit_leader_skill_id").
Where("unit_m.unit_id = ?", tomoUnitId).
Cols("unit_leader_skill_extra_m.effect_value,unit_leader_skill_extra_m.member_tag_id").Get(&tomoSubEffectValue, &tomoMemberTagId)
utils.CheckErr(err)
exists, err = MainEng.Table("unit_type_member_tag_m").
Where("unit_type_id = ? AND member_tag_id = ?", unitTypeId, tomoMemberTagId).Exist()
utils.CheckErr(err)
var tomoSubSmile, tomoSubPure, tomoSubCool float64
if exists {
if myAttrId == 1 {
tomoSubSmile = math.Ceil(smileMax * (tomoSubEffectValue / 100))
} else if myAttrId == 2 {
tomoSubPure = math.Ceil(pureMax * (tomoSubEffectValue / 100))
} else if myAttrId == 3 {
tomoSubCool = math.Ceil(coolMax * (tomoSubEffectValue / 100))
}
// fmt.Println("好友副C技能属性加成:", tomoSubSmile, tomoSubPure, tomoSubCool)
}
// 全部卡属性
totalSmile += smileMax + myCenterSmile + mySubSmile + tomoCenterSmile + tomoSubSmile
totalPure += pureMax + myCenterPure + mySubPure + tomoCenterPure + tomoSubPure
totalCool += coolMax + myCenterCool + mySubCool + tomoCenterCool + tomoSubCool
totalHp += maxHp
// 单卡属性计算结果取上取整
fixedSmileMax := int(smileMax)
fixedPureMax := int(pureMax)
fixedCoolMax := int(coolMax)
// fmt.Println("单卡属性:", fixedSmileMax, fixedPureMax, fixedCoolMax)
unitList = append(unitList, model.UnitList{
Smile: fixedSmileMax,
Cute: fixedPureMax,
Cool: fixedCoolMax,
})
}
// 全部卡属性计算结果取上取整
fixedTotalSmile := int(math.Ceil(totalSmile))
fixedTotalPure := int(math.Ceil(totalPure))
fixedTotalCool := int(math.Ceil(totalCool))
// fmt.Println("全卡组属性:", fixedTotalSmile, fixedTotalPure, fixedTotalCool)
lives := []model.PlayLiveList{}
lives = append(lives, model.PlayLiveList{
LiveInfo: model.LiveInfo{
LiveDifficultyID: difficultyId,
IsRandom: false,
AcFlag: ac_flag,
SwingFlag: swing_flag,
NotesList: notes,
},
DeckInfo: model.DeckInfo{
UnitDeckID: deckId,
TotalSmile: fixedTotalSmile,
TotalCute: fixedTotalPure,
TotalCool: fixedTotalCool,
TotalHp: totalHp,
PreparedHpDamage: 0,
UnitList: unitList,
},
})
playResp := model.PlayResp{
ResponseData: model.PlayRes{
RankInfo: ranks,
EnergyFullTime: "2023-03-20 01:28:55",
OverMaxEnergy: 0,
AvailableLiveResume: false,
LiveList: lives,
IsMarathonEvent: false,
MarathonEventID: nil,
NoSkill: false,
CanActivateEffect: true,
ServerTimestamp: time.Now().Unix(),
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(playResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
func GameOver(ctx *gin.Context) {
overResp := model.GameOverResp{
ResponseData: []any{},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(overResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
func PlayScore(ctx *gin.Context) {
playScoreReq := model.PlayScoreReq{}
err := json.Unmarshal([]byte(ctx.GetString("request_data")), &playScoreReq)
utils.CheckErr(err)
tDifficultyId := playScoreReq.LiveDifficultyID
difficultyId, err := strconv.Atoi(tDifficultyId)
utils.CheckErr(err)
// Song type: normal / special
// sqlite3 doesn't support FULL OUTER JOIN so use UNION ALL here.
sql := `SELECT notes_setting_asset,c_rank_score,b_rank_score,a_rank_score,s_rank_score,ac_flag,swing_flag FROM live_setting_m WHERE live_setting_id IN (SELECT live_setting_id FROM normal_live_m WHERE live_difficulty_id = ? UNION ALL SELECT live_setting_id FROM special_live_m WHERE live_difficulty_id = ?)`
var notes_setting_asset string
var c_rank_score, b_rank_score, a_rank_score, s_rank_score, ac_flag, swing_flag int
err = MainEng.DB().QueryRow(sql, difficultyId, difficultyId).Scan(&notes_setting_asset, &c_rank_score, &b_rank_score, &a_rank_score, &s_rank_score, &ac_flag, &swing_flag)
utils.CheckErr(err)
// fmt.Println(notes_setting_asset)
// fmt.Println(c_rank_score, b_rank_score, a_rank_score, s_rank_score)
notes := []model.NotesList{}
// fmt.Println("./assets/notes/" + notes_setting_asset)
notes_list := honokautils.ReadAllText("./assets/serverdata/notes/" + notes_setting_asset)
err = json.Unmarshal([]byte(notes_list), &notes)
utils.CheckErr(err)
ranks := []model.RankInfo{}
ranks = append(ranks, model.RankInfo{
Rank: 5,
RankMin: 0,
RankMax: c_rank_score,
}, model.RankInfo{
Rank: 4,
RankMin: c_rank_score + 1,
RankMax: b_rank_score,
}, model.RankInfo{
Rank: 3,
RankMin: b_rank_score + 1,
RankMax: a_rank_score,
}, model.RankInfo{
Rank: 2,
RankMin: a_rank_score + 1,
RankMax: s_rank_score,
}, model.RankInfo{
Rank: 1,
RankMin: s_rank_score + 1,
RankMax: 0,
})
playResp := model.PlayScoreResp{
ResponseData: model.PlayScoreRes{
On: model.On{
HasRecord: false,
LiveInfo: model.LiveInfo{
LiveDifficultyID: difficultyId,
IsRandom: false,
AcFlag: ac_flag,
SwingFlag: swing_flag,
NotesList: notes,
},
},
Off: model.Off{
HasRecord: false,
LiveInfo: model.LiveInfo{
LiveDifficultyID: difficultyId,
IsRandom: false,
AcFlag: ac_flag,
SwingFlag: swing_flag,
NotesList: notes,
},
},
RankInfo: ranks,
CanActivateEffect: true,
ServerTimestamp: time.Now().Unix(),
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(playResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
func PlayReward(ctx *gin.Context) {
playRewardReq := model.PlayRewardReq{}
err := json.Unmarshal([]byte(ctx.GetString("request_data")), &playRewardReq)
utils.CheckErr(err)
difficultyId := playRewardReq.LiveDifficultyID
// Song type: normal / special
// sqlite3 doesn't support FULL OUTER JOIN so use UNION ALL here.
sql := `SELECT c_rank_score,b_rank_score,a_rank_score,s_rank_score,c_rank_combo,b_rank_combo,a_rank_combo,s_rank_combo,ac_flag,swing_flag FROM live_setting_m WHERE live_setting_id IN (SELECT live_setting_id FROM normal_live_m WHERE live_difficulty_id = ? UNION ALL SELECT live_setting_id FROM special_live_m WHERE live_difficulty_id = ?)`
var c_rank_score, b_rank_score, a_rank_score, s_rank_score, c_rank_combo, b_rank_combo, a_rank_combo, s_rank_combo, ac_flag, swing_flag int
err = MainEng.DB().QueryRow(sql, difficultyId, difficultyId).Scan(&c_rank_score, &b_rank_score, &a_rank_score, &s_rank_score, &c_rank_combo, &b_rank_combo, &a_rank_combo, &s_rank_combo, &ac_flag, &swing_flag)
utils.CheckErr(err)
key := "live_deck_" + ctx.GetString("userid")
deckId, err := db.DB.Get([]byte(key))
utils.CheckErr(err)
unitsList := []model.PlayRewardUnitList{}
err = UserEng.Table("deck_unit_m").Join("LEFT", "user_deck_m", "deck_unit_m.user_deck_id = user_deck_m.id").
Where("user_id = ? AND deck_id = ?", ctx.GetString("userid"), string(deckId)).Find(&unitsList)
utils.CheckErr(err)
totalScore := playRewardReq.ScoreSmile + playRewardReq.ScoreCool + playRewardReq.ScoreCute
playResp := model.RewardResp{
ResponseData: model.RewardRes{
LiveInfo: []model.RewardLiveInfo{
{
LiveDifficultyID: difficultyId,
IsRandom: false,
AcFlag: ac_flag,
SwingFlag: swing_flag,
},
},
TotalLove: 0,
IsHighScore: true,
HiScore: totalScore,
BaseRewardInfo: model.BaseRewardInfo{
PlayerExp: 0,
PlayerExpUnitMax: model.PlayerExpUnitMax{
Before: 0,
After: 0,
},
PlayerExpFriendMax: model.PlayerExpFriendMax{
Before: 99,
After: 99,
},
PlayerExpLpMax: model.PlayerExpLpMax{
Before: config.Conf.UserPrefs.EnergyMax,
After: config.Conf.UserPrefs.EnergyMax,
},
GameCoin: 0,
GameCoinRewardBoxFlag: false,
SocialPoint: 0,
},
RewardUnitList: model.RewardUnitList{
LiveClear: []model.LiveClear{},
LiveRank: []model.LiveRank{},
LiveCombo: []any{},
},
UnlockedSubscenarioIds: []any{},
UnlockedMultiUnitScenarioIds: []any{},
EffortPoint: []model.EffortPoint{},
IsEffortPointVisible: false,
LimitedEffortBox: []any{},
UnitList: unitsList,
BeforeUserInfo: model.BeforeUserInfo{
Level: config.Conf.UserPrefs.Level,
Exp: config.Conf.UserPrefs.ExpNumerator,
PreviousExp: 0,
NextExp: config.Conf.UserPrefs.ExpDenominator,
GameCoin: config.Conf.UserPrefs.GameCoin,
SnsCoin: config.Conf.UserPrefs.SnsCoin,
FreeSnsCoin: config.Conf.UserPrefs.SnsCoin,
PaidSnsCoin: 0,
SocialPoint: 1438165,
UnitMax: 5000,
WaitingUnitMax: 1000,
CurrentEnergy: config.Conf.UserPrefs.EnergyMax,
EnergyMax: config.Conf.UserPrefs.EnergyMax,
TrainingEnergy: 9,
TrainingEnergyMax: 10,
EnergyFullTime: "2023-03-20 01:28:55",
LicenseLiveEnergyRecoverlyTime: 60,
FriendMax: 99,
TutorialState: -1,
OverMaxEnergy: config.Conf.UserPrefs.OverMaxEnergy,
UnlockRandomLiveMuse: 1,
UnlockRandomLiveAqours: 1,
},
AfterUserInfo: model.AfterUserInfo{
Level: config.Conf.UserPrefs.Level,
Exp: config.Conf.UserPrefs.ExpNumerator,
PreviousExp: 0,
NextExp: config.Conf.UserPrefs.ExpDenominator,
GameCoin: config.Conf.UserPrefs.GameCoin,
SnsCoin: config.Conf.UserPrefs.SnsCoin,
FreeSnsCoin: config.Conf.UserPrefs.SnsCoin,
PaidSnsCoin: 0,
SocialPoint: 1438375,
UnitMax: 5000,
WaitingUnitMax: 1000,
CurrentEnergy: config.Conf.UserPrefs.EnergyMax,
EnergyMax: config.Conf.UserPrefs.EnergyMax,
TrainingEnergy: 9,
TrainingEnergyMax: 10,
EnergyFullTime: "2023-03-20 01:28:55",
LicenseLiveEnergyRecoverlyTime: 60,
FriendMax: 99,
TutorialState: -1,
OverMaxEnergy: config.Conf.UserPrefs.OverMaxEnergy,
UnlockRandomLiveMuse: 1,
UnlockRandomLiveAqours: 1,
},
NextLevelInfo: []model.NextLevelInfo{
{
Level: config.Conf.UserPrefs.Level,
FromExp: config.Conf.UserPrefs.ExpNumerator,
},
},
GoalAccompInfo: model.GoalAccompInfo{
AchievedIds: []any{},
Rewards: []any{},
},
SpecialRewardInfo: []any{},
EventInfo: []any{},
DailyRewardInfo: []any{},
CanSendFriendRequest: false,
UsingBuffInfo: []any{},
ClassSystem: model.ClassSystem{
RankInfo: model.RewardRankInfo{
BeforeClassRankID: 10,
AfterClassRankID: 10,
RankUpDate: "2020-02-12 11:57:15",
},
CompleteFlag: false,
IsOpened: true,
IsVisible: true,
},
AccomplishedAchievementList: []model.AccomplishedAchievementList{},
UnaccomplishedAchievementCnt: 0,
AddedAchievementList: []any{},
MuseumInfo: model.Museum{},
UnitSupportList: []model.RewardUnitSupportList{},
ServerTimestamp: time.Now().Unix(),
PresentCnt: 0,
},
ReleaseInfo: []any{},
StatusCode: 200,
}
if playRewardReq.MaxCombo > s_rank_combo {
playResp.ResponseData.ComboRank = 1
} else if playRewardReq.MaxCombo > a_rank_combo {
playResp.ResponseData.ComboRank = 2
} else if playRewardReq.MaxCombo > b_rank_combo {
playResp.ResponseData.ComboRank = 3
} else if playRewardReq.MaxCombo > c_rank_combo {
playResp.ResponseData.ComboRank = 4
} else {
playResp.ResponseData.ComboRank = 5
}
if totalScore > s_rank_score {
playResp.ResponseData.Rank = 1
} else if totalScore > a_rank_score {
playResp.ResponseData.Rank = 2
} else if totalScore > b_rank_score {
playResp.ResponseData.Rank = 3
} else if totalScore > c_rank_score {
playResp.ResponseData.Rank = 4
} else {
playResp.ResponseData.Rank = 5
}
resp, err := json.Marshal(playResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
+60
View File
@@ -0,0 +1,60 @@
package handler
import (
"encoding/json"
"honoka-chan/internal/model"
"honoka-chan/internal/utils"
"honoka-chan/pkg/db"
"net/http"
"strconv"
"time"
"github.com/gin-gonic/gin"
)
func AuthKey(ctx *gin.Context) {
authResp := model.AuthKeyResp{
ResponseData: model.AuthKeyRes{
AuthorizeToken: ctx.GetString("authorize_token"),
DummyToken: ctx.GetString("dummy_token"),
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(authResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.JSON(http.StatusOK, authResp)
}
func Login(ctx *gin.Context) {
loginKey := ctx.GetString("login_key")
var userId int
exists, err := UserEng.Table("user_key").Where("key = ?", loginKey).Cols("userid").Get(&userId)
utils.CheckErr(err)
if !exists || userId == 0 {
userId = 9999999
}
ctx.Set("userid", userId)
err = db.DB.Set([]byte(strconv.Itoa(userId)), []byte(ctx.GetString("authorize_token")))
utils.CheckErr(err)
loginResp := model.LoginResp{
ResponseData: model.LoginRes{
AuthorizeToken: ctx.GetString("authorize_token"),
UserId: userId,
ServerTimestamp: time.Now().Unix(),
AdultFlag: 2,
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(loginResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.JSON(http.StatusOK, loginResp)
}
+32
View File
@@ -0,0 +1,32 @@
package handler
import (
"encoding/json"
"honoka-chan/internal/model"
"honoka-chan/internal/utils"
"net/http"
"time"
"github.com/gin-gonic/gin"
)
func MultiUnitStartUp(ctx *gin.Context) {
startReq := model.MultiUnitStartUpReq{}
err := json.Unmarshal([]byte(ctx.PostForm("request_data")), &startReq)
utils.CheckErr(err)
startResp := model.MultiUnitStartUpResp{
ResponseData: model.MultiUnitStartUpRes{
MultiUnitScenarioID: startReq.MultiUnitScenarioID,
ScenarioAdjustment: 50,
ServerTimestamp: time.Now().Unix(),
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(startResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
+52
View File
@@ -0,0 +1,52 @@
package handler
import (
"encoding/json"
"honoka-chan/internal/model"
"honoka-chan/internal/utils"
"net/http"
"time"
"github.com/gin-gonic/gin"
)
type MuseumContent struct {
MuseumContentsId int `xorm:"museum_contents_id"`
SmileBuff int `xorm:"smile_buff"`
PureBuff int `xorm:"pure_buff"`
CoolBuff int `xorm:"cool_buff"`
}
func MuseumInfo(ctx *gin.Context) {
var contents []MuseumContent
err := MainEng.Table("museum_contents_m").Cols("museum_contents_id,smile_buff,pure_buff,cool_buff").Find(&contents)
utils.CheckErr(err)
var smileBuff, pureBuff, coolBuff int
var contentsList []int
for _, content := range contents {
smileBuff += content.SmileBuff
pureBuff += content.PureBuff
coolBuff += content.CoolBuff
contentsList = append(contentsList, content.MuseumContentsId)
}
museumResp := model.MuseumResp{
ResponseData: model.MuseumRes{
MuseumInfo: model.Museum{
Parameter: model.MuseumParameter{
Smile: smileBuff,
Pure: pureBuff,
Cool: coolBuff,
},
ContentsIDList: contentsList,
},
ServerTimestamp: time.Now().Unix(),
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(museumResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
+63
View File
@@ -0,0 +1,63 @@
package handler
import (
"encoding/json"
"honoka-chan/internal/model"
"honoka-chan/internal/utils"
"net/http"
"time"
"github.com/gin-gonic/gin"
)
func NoticeFriendVariety(ctx *gin.Context) {
noticeResp := model.NoticeFriendVarietyResp{
ResponseData: model.NoticeFriendVarietyRes{
ItemCount: 1,
NoticeList: []any{},
ServerTimestamp: time.Now().Unix(),
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(noticeResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
func NoticeFriendGreeting(ctx *gin.Context) {
noticeResp := model.NoticeFriendGreetingResp{
ResponseData: model.NoticeFriendGreetingRes{
NextId: 0,
NoticeList: []any{},
ServerTimestamp: time.Now().Unix(),
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(noticeResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
func NoticeUserGreeting(ctx *gin.Context) {
noticeResp := model.NoticeUserGreetingResp{
ResponseData: model.NoticeUserGreetingRes{
ItemCount: 0,
HasNext: false,
NoticeList: []any{},
ServerTimestamp: time.Now().Unix(),
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(noticeResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
+39
View File
@@ -0,0 +1,39 @@
package handler
import (
"encoding/json"
"honoka-chan/internal/model"
"honoka-chan/internal/utils"
"net/http"
"time"
"github.com/gin-gonic/gin"
)
func ProductList(ctx *gin.Context) {
prodReesp := model.ProductResp{
ResponseData: model.ProductRes{
RestrictionInfo: model.RestrictionInfo{
Restricted: false,
},
UnderAgeInfo: model.UnderAgeInfo{
BirthSet: true,
HasLimit: false,
LimitAmount: nil,
MonthUsed: 0,
},
SnsProductList: []any{},
ProductList: []any{},
SubscriptionList: []any{},
ShowPointShop: true,
ServerTimestamp: time.Now().Unix(),
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(prodReesp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
+31
View File
@@ -0,0 +1,31 @@
package handler
import (
"encoding/json"
"honoka-chan/internal/model"
"honoka-chan/internal/utils"
"net/http"
"time"
"github.com/gin-gonic/gin"
)
func PersonalNotice(ctx *gin.Context) {
noticeResp := model.PersonalNoticeResp{
ResponseData: model.PersonalNoticeRes{
HasNotice: false,
NoticeID: 0,
Type: 0,
Title: "",
Contents: "",
ServerTimestamp: time.Now().Unix(),
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(noticeResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
+495
View File
@@ -0,0 +1,495 @@
package handler
import (
"encoding/base64"
"encoding/json"
"fmt"
"honoka-chan/config"
"honoka-chan/internal/tools"
"honoka-chan/internal/utils"
"honoka-chan/pkg/db"
"honoka-chan/pkg/encrypt"
honokautils "honoka-chan/pkg/utils"
"io"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"github.com/forgoer/openssl"
"github.com/gin-gonic/gin"
)
type LoginResp struct {
Activation int `json:"activation"`
Autokey string `json:"autokey"`
CaptchaParams string `json:"captchaParams"`
CheckCodeGUID string `json:"checkCodeGuid"`
CheckCodeURL string `json:"checkCodeUrl"`
HasExtendAccs int `json:"hasExtendAccs"`
HasRealInfo int `json:"has_realInfo"`
ImagecodeType int `json:"imagecodeType"`
IsNewUser int `json:"isNewUser"`
Message string `json:"message"`
NextAction int `json:"nextAction"`
PromptMsg string `json:"prompt_msg"`
RealInfoNotification string `json:"realInfoNotification"`
RealInfoForce int `json:"realInfo_force"`
RealInfoForcePay int `json:"realInfo_force_pay"`
RealInfoStatus int `json:"realInfo_status"`
RealInfoStatusPay int `json:"realInfo_status_pay"`
Result int `json:"result"`
SdgHeight int `json:"sdg_height"`
SdgWidth int `json:"sdg_width"`
Ticket string `json:"ticket"`
UserAttribute string `json:"userAttribute"`
Userid string `json:"userid"`
}
type LoginAutoResp struct {
Result int `json:"result"`
Message string `json:"message"`
Autokey string `json:"autokey"`
UserId string `json:"userid"`
Ticket string `json:"ticket"`
}
type InitializeResp struct {
BrandLogo string `json:"brand_logo"`
BrandName string `json:"brand_name"`
DaoyuClientid string `json:"daoyu_clientid"`
DaoyuDownloadURL string `json:"daoyu_download_url"`
DeviceFeature string `json:"device_feature"`
DisplayThirdaccout int `json:"display_thirdaccout"`
ForceShowAgreement int `json:"force_show_agreement"`
GreportLogLevel string `json:"greport_log_level"`
GuestEnable int `json:"guest_enable"`
IsMatch int `json:"is_match"`
LogLevel string `json:"log_level"`
LoginButton []string `json:"login_button"`
LoginIcon []any `json:"login_icon"`
LoginLimitEnable int `json:"login_limit_enable"`
NeedFloatWindowPermission int `json:"need_float_window_permission"`
NewDeviceIDServer string `json:"new_device_id_server"`
QqAppID string `json:"qq_appId"`
QqKey string `json:"qq_key"`
ShowGuestConfirm int `json:"show_guest_confirm"`
VoicetipButton int `json:"voicetip_button"`
VoicetipOne string `json:"voicetip_one"`
VoicetipTwo string `json:"voicetip_two"`
WegameAppid string `json:"wegame_appid"`
WegameAppkey string `json:"wegame_appkey"`
WegameClientid string `json:"wegame_clientid"`
WegameCompanyID string `json:"wegame_companyId"`
WegameLoginURL string `json:"wegame_loginUrl"`
WeiboAppKey string `json:"weibo_appKey"`
WeiboRedirectURL string `json:"weibo_redirectUrl"`
WeixinAppID string `json:"weixin_appId"`
WeixinKey string `json:"weixin_key"`
}
func Active(ctx *gin.Context) {
// body, err := io.ReadAll(ctx.Request.Body)
// utils.CheckErr(err)
// defer ctx.Request.Body.Close()
// fmt.Println(string(body))
ctx.Header("Content-Type", "text/html;charset=utf-8")
ctx.String(http.StatusOK, `{ "code": 0, "msg": "ok", "data": { "message": "ok", "result": 0 } }`)
}
func PublicKey(ctx *gin.Context) {
publicKey := honokautils.ReadAllText(config.PublicKeyPath)
publicKey = strings.ReplaceAll(publicKey, "\n", "")
publicKey = strings.ReplaceAll(publicKey, "-----BEGIN PUBLIC KEY-----", "")
publicKey = strings.ReplaceAll(publicKey, "-----END PUBLIC KEY-----", "")
publicKey = strings.ReplaceAll(publicKey, "/", "\\/")
// fmt.Println(publicKey)
resp := fmt.Sprintf(`{ "code": 0, "msg": "", "data": { "result": 0, "message": "ok", "key": "%s", "method": "rsa" } }`, publicKey)
ctx.Header("Content-Type", "text/html;charset=utf-8")
ctx.String(http.StatusOK, resp)
}
func Handshake(ctx *gin.Context) {
body, err := io.ReadAll(ctx.Request.Body)
utils.CheckErr(err)
defer ctx.Request.Body.Close()
// fmt.Println(string(body))
body64, err := base64.StdEncoding.DecodeString(string(body))
utils.CheckErr(err)
decryptedBody := encrypt.RSADecrypt(body64)
// fmt.Println(decryptedBody)
// fmt.Println(string(decryptedBody))
params, err := url.ParseQuery(string(decryptedBody))
utils.CheckErr(err)
randKey := params.Get("randkey")
deviceId := ctx.Request.Header.Get("X-DEVICEID")
// fmt.Println(randKey)
// fmt.Println(deviceId)
err = db.DB.Set([]byte(deviceId), []byte(randKey))
utils.CheckErr(err)
token := strings.ToUpper(honokautils.RandomStr(33))
token = fmt.Sprintf(`{"message":"ok","result":0,"token":"%s"}`, token)
encryptedToken, err := openssl.Des3ECBEncrypt([]byte(token), []byte(randKey)[0:24], openssl.PKCS7_PADDING)
utils.CheckErr(err)
encryptedToken64 := base64.StdEncoding.EncodeToString(encryptedToken)
// fmt.Println(encryptedToken64)
resp := fmt.Sprintf(`{ "code": 0, "msg": "ok", "data": "%s" }`, encryptedToken64)
ctx.Header("Content-Type", "text/html;charset=utf-8")
ctx.String(http.StatusOK, resp)
}
func Initialize(ctx *gin.Context) {
// body, err := io.ReadAll(ctx.Request.Body)
// utils.CheckErr(err)
// defer ctx.Request.Body.Close()
// fmt.Println(string(body))
// body64, err := base64.StdEncoding.DecodeString(string(body))
// utils.CheckErr(err)
// fmt.Println(string(body64))
deviceId := ctx.Request.Header.Get("X-DEVICEID")
randKey, err := db.DB.Get([]byte(deviceId))
utils.CheckErr(err)
// decryptedBody, err := openssl.Des3ECBDecrypt(body64, randKey[0:24], openssl.PKCS7_PADDING)
// utils.CheckErr(err)
// fmt.Println(string(decryptedBody))
initResp := InitializeResp{
BrandLogo: "http://gskd.sdo.com/ghome/ztc/logo/og/logo_xhdpi.png",
BrandName: "盛趣游戏",
ForceShowAgreement: 1,
GreportLogLevel: "off",
LogLevel: "off",
LoginButton: []string{"official"},
LoginIcon: []any{},
NeedFloatWindowPermission: 1,
NewDeviceIDServer: strings.ToUpper(openssl.Md5ToString(deviceId)),
ShowGuestConfirm: 1,
VoicetipButton: 1,
}
data, err := json.Marshal(initResp)
utils.CheckErr(err)
encryptedData, err := openssl.Des3ECBEncrypt([]byte(data), randKey[0:24], openssl.PKCS7_PADDING)
utils.CheckErr(err)
encryptedData64 := base64.StdEncoding.EncodeToString(encryptedData)
// fmt.Println(encryptedToken64)
resp := fmt.Sprintf(`{ "code": 0, "msg": "ok", "data": "%s" }`, encryptedData64)
ctx.Header("Content-Type", "text/html;charset=utf-8")
ctx.String(http.StatusOK, resp)
}
func GetCode(ctx *gin.Context) {
resp := `{ "code": 0, "msg": "ok", "data": { "codeArray": [ { "btntext": "好的", "code": "-10264022", "msg_from": 2, "text": "", "title": "短信验证码被阻止", "type": 1 }, { "btntext": " ", "code": "-10869623", "msg_from": 2, "text": "", "title": "网络连接失败,无法一键登录", "type": 2 }, { "btntext": " ", "code": "10298300", "msg_from": 2, "text": "", "title": " ", "type": 3 }, { "btntext": "", "code": "10298311", "msg_from": 2, "text": "", "title": "", "type": 3 }, { "btntext": " ", "code": "10298312", "msg_from": 2, "text": "", "title": " ", "type": 3 }, { "btntext": " ", "code": "10298313", "msg_from": 2, "text": "", "title": " ", "type": 1 }, { "btntext": " ", "code": "10298321", "msg_from": 2, "text": "", "title": " ", "type": 3 }, { "btntext": " ", "code": "10298322", "msg_from": 2, "text": "", "title": " ", "type": 3 } ], "codeVersion": "1.0.5" } }`
ctx.Header("Content-Type", "text/html;charset=utf-8")
ctx.String(http.StatusOK, resp)
}
func LoginAuto(ctx *gin.Context) {
body, err := io.ReadAll(ctx.Request.Body)
utils.CheckErr(err)
defer ctx.Request.Body.Close()
// fmt.Println(string(body))
body64, err := base64.StdEncoding.DecodeString(string(body))
utils.CheckErr(err)
// fmt.Println(string(body64))
deviceId := ctx.Request.Header.Get("X-DEVICEID")
randKey, err := db.DB.Get([]byte(deviceId))
utils.CheckErr(err)
decryptedBody, err := openssl.Des3ECBDecrypt(body64, randKey[0:24], openssl.PKCS7_PADDING)
utils.CheckErr(err)
queryStr := string(decryptedBody)
// fmt.Println(queryStr)
params, err := url.ParseQuery(queryStr)
utils.CheckErr(err)
autoKey := params.Get("autokey")
// fmt.Println(autoKey)
if autoKey == "" {
ctx.String(http.StatusForbidden, ErrorMsg)
return
}
var userId, ticket string
_, err = UserEng.Table("users").Cols("userid,ticket").Where("autokey = ?", autoKey).Get(&userId, &ticket)
utils.CheckErr(err)
var resp string
if userId != "" {
autoResp := LoginAutoResp{
Result: 0,
Message: "ok",
Autokey: autoKey,
UserId: userId,
Ticket: ticket,
}
data, err := json.Marshal(autoResp)
// fmt.Println(string(data))
utils.CheckErr(err)
encryptedData, err := openssl.Des3ECBEncrypt(data, randKey[0:24], openssl.PKCS7_PADDING)
utils.CheckErr(err)
encryptedData64 := base64.StdEncoding.EncodeToString(encryptedData)
// fmt.Println(encryptedData64)
resp = fmt.Sprintf(`{ "code": 0, "msg": "ok", "data": "%s" }`, encryptedData64)
} else {
data := `{"message":"账号不存在或者登陆状态已过期!","result":31}`
encryptedData, err := openssl.Des3ECBEncrypt([]byte(data), randKey[0:24], openssl.PKCS7_PADDING)
utils.CheckErr(err)
encryptedData64 := base64.StdEncoding.EncodeToString(encryptedData)
// fmt.Println(encryptedData64)
resp = fmt.Sprintf(`{ "code": 31, "msg": "账号不存在或者登陆状态已过期!", "data": "%s" }`, encryptedData64)
}
ctx.Header("Content-Type", "text/html;charset=utf-8")
ctx.String(http.StatusOK, resp)
}
func LoginArea(ctx *gin.Context) {
userId := ctx.PostForm("userid")
if userId != "" {
// fmt.Println(userId)
resp := fmt.Sprintf(`{ "code": 0, "msg": "ok", "data": { "userid": "%s" } }`, userId)
ctx.Header("Content-Type", "text/html;charset=utf-8")
ctx.String(http.StatusOK, resp)
}
}
func AccountLogin(ctx *gin.Context) {
body, err := io.ReadAll(ctx.Request.Body)
utils.CheckErr(err)
defer ctx.Request.Body.Close()
// fmt.Println(string(body))
body64, err := base64.StdEncoding.DecodeString(string(body))
utils.CheckErr(err)
// fmt.Println(string(body64))
deviceId := ctx.Request.Header.Get("X-DEVICEID")
randKey, err := db.DB.Get([]byte(deviceId))
utils.CheckErr(err)
decryptedBody, err := openssl.Des3ECBDecrypt(body64, randKey[0:24], openssl.PKCS7_PADDING)
utils.CheckErr(err)
queryStr, err := url.QueryUnescape(string(decryptedBody))
utils.CheckErr(err)
params, err := url.ParseQuery(queryStr)
utils.CheckErr(err)
phone, password := params.Get("phone"), params.Get("password")
if phone == "" || password == "" {
ctx.String(http.StatusForbidden, ErrorMsg)
return
}
// sql := `CREATE TABLE "users" (
// "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
// "phone" TEXT,
// "password" TEXT,
// "autokey" TEXT,
// "ticket" TEXT,
// "userid" INTEGER,
// "last_login_time" INTEGER
// );
// CREATE TABLE "user_key" (
// "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
// "userid" INTEGER,
// "key" INTEGER
// );`
var pass, autoKey, ticket, userId string
_, err = UserEng.Table("users").Cols("password,autokey,ticket,userid").Where("phone = ?", phone).
Get(&pass, &autoKey, &ticket, &userId)
utils.CheckErr(err)
loginResp := LoginResp{}
loginCode := 0
loginMsg := "ok"
loginTime := time.Now().Unix()
if pass == "" {
// 未注册 - 自动注册
session := UserEng.NewSession()
defer session.Close()
// 开始会话
if err = session.Begin(); err != nil {
session.Rollback()
panic(err)
}
pass = openssl.Md5ToString(password)
autoKey = "AUTO" + strings.ToUpper(honokautils.RandomStr(32))
userId = strconv.Itoa(int(loginTime))
ticket = "9999999" + userId + userId
userStmt, err := session.DB().Prepare("INSERT INTO users(phone,password,autokey,ticket,userid,last_login_time) VALUES (?,?,?,?,?,?)")
if err != nil {
session.Rollback()
panic(err)
}
defer userStmt.Close()
_, err = userStmt.Exec(phone, pass, autoKey, ticket, userId, loginTime)
if err != nil {
session.Rollback()
panic(err)
}
// id, _ := res.LastInsertId()
// fmt.Println("LastInsertId:", id)
keyStmt, err := session.DB().Prepare("INSERT INTO user_key(userid,key) VALUES(?,?)")
if err != nil {
session.Rollback()
panic(err)
}
// 方便起见初始化 userid 和 key 一样
// 注意:user_key 表中的 key 是上文生成的用于登录的 userid,而 userid 则是用于 Authorize Token 生成用的
_, err = keyStmt.Exec(userId, userId)
if err != nil {
session.Rollback()
panic(err)
}
// 结束会话
if err = session.Commit(); err != nil {
session.Rollback()
panic(err)
}
tools.InitUserData(int(loginTime))
// Login Response
loginResp.Autokey = autoKey
loginResp.HasRealInfo = 1
loginResp.Message = "ok"
loginResp.RealInfoForce = 1
loginResp.Ticket = ticket
loginResp.UserAttribute = "0"
loginResp.Userid = userId
} else {
// 已注册
if openssl.Md5ToString(password) == pass {
// 密码正确
// Login Response
loginResp.Autokey = autoKey // 注意:更换设备(deviceId 发生变化)应重新生成 autokey
loginResp.HasRealInfo = 1
loginResp.Message = "ok"
loginResp.RealInfoForce = 1
loginResp.Ticket = "9999999" + userId + strconv.Itoa(int(loginTime)) // 实际登录用的密码(每次登录都会重新生成新的)
loginResp.UserAttribute = "0"
loginResp.Userid = userId // 实际登录用的账号
// 更新信息
userStmt, err := UserEng.DB().Prepare("UPDATE users SET autokey=?,ticket=?,last_login_time=? WHERE userid=?")
utils.CheckErr(err)
defer userStmt.Close()
_, err = userStmt.Exec(autoKey, ticket, loginTime, userId)
utils.CheckErr(err)
// aff, _ := res.RowsAffected()
// fmt.Println("RowsAffected:", aff)
} else {
// 密码错误
loginCode = 31
loginMsg = "账号不存在或者密码有误!"
}
}
data, err := json.Marshal(loginResp)
utils.CheckErr(err)
// fmt.Println(string(data))
encryptedData, err := openssl.Des3ECBEncrypt(data, randKey[0:24], openssl.PKCS7_PADDING)
utils.CheckErr(err)
encryptedData64 := base64.StdEncoding.EncodeToString(encryptedData)
// fmt.Println(encryptedToken64)
resp := fmt.Sprintf(`{ "code": %d, "msg": "%s", "data": "%s" }`, loginCode, loginMsg, encryptedData64)
ctx.Header("Content-Type", "text/html;charset=utf-8")
ctx.String(http.StatusOK, resp)
}
func ReportRole(ctx *gin.Context) {
// body, err := io.ReadAll(ctx.Request.Body)
// utils.CheckErr(err)
// defer ctx.Request.Body.Close()
// fmt.Println(string(body))
// body64, err := base64.StdEncoding.DecodeString(string(body))
// utils.CheckErr(err)
// fmt.Println(string(body64))
deviceId := ctx.Request.Header.Get("X-DEVICEID")
randKey, err := db.DB.Get([]byte(deviceId))
utils.CheckErr(err)
// decryptedBody, err := openssl.Des3ECBDecrypt(body64, randKey[0:24], openssl.PKCS7_PADDING)
// utils.CheckErr(err)
// fmt.Println(string(decryptedBody))
// decrypted, err := url.QueryUnescape(string(decryptedBody))
// utils.CheckErr(err)
// fmt.Println(decrypted)
// Unable to decrypt server data
token := `{"message":"Hello, world!"}`
encryptedToken, err := openssl.Des3ECBEncrypt([]byte(token), randKey[0:24], openssl.PKCS7_PADDING)
utils.CheckErr(err)
encryptedToken64 := base64.StdEncoding.EncodeToString(encryptedToken)
// fmt.Println(encryptedToken64)
resp := fmt.Sprintf(`{ "code": 0, "msg": "ok", "data": "%s" }`, encryptedToken64)
ctx.Header("Content-Type", "text/html;charset=utf-8")
ctx.String(http.StatusOK, resp)
}
func GetProductList(ctx *gin.Context) {
resp := `{ "code": 0, "msg": "ok", "data": { "message": [ ], "result": 0 } }`
ctx.Header("Content-Type", "text/html;charset=utf-8")
ctx.String(http.StatusOK, resp)
}
func GuestStatus(ctx *gin.Context) {
resp := `{"code":0,"msg":"ok","data":{"disablead":1,"loginswitch":1,"message":"ok","result":0}}`
ctx.Header("Content-Type", "text/html;charset=utf-8")
ctx.String(http.StatusOK, resp)
}
func ReportLog(ctx *gin.Context) {
// body, err := io.ReadAll(ctx.Request.Body)
// utils.CheckErr(err)
// defer ctx.Request.Body.Close()
// fmt.Println(string(body))
ctx.Header("Content-Type", "text/html;charset=utf-8")
ctx.String(http.StatusOK, "")
}
func ReportApp(ctx *gin.Context) {
// body, err := io.ReadAll(ctx.Request.Body)
// utils.CheckErr(err)
// defer ctx.Request.Body.Close()
// fmt.Println(string(body))
resp := `{ "code": 0, "msg": "", "data": { "needReport": 0 } }`
ctx.Header("Content-Type", "text/html;charset=utf-8")
ctx.String(http.StatusOK, resp)
}
func Agreement(ctx *gin.Context) {
resp := `{ "return_code": 0, "error_type": 0, "return_message": "", "data": { } }`
ctx.Header("Content-Type", "text/html;charset=utf-8")
ctx.String(http.StatusOK, resp)
}
+31
View File
@@ -0,0 +1,31 @@
package handler
import (
"encoding/json"
"honoka-chan/internal/model"
"honoka-chan/internal/tools"
"honoka-chan/internal/utils"
"net/http"
"github.com/gin-gonic/gin"
"github.com/tidwall/gjson"
)
func ProfileRegister(ctx *gin.Context) {
req := gjson.Parse(ctx.PostForm("request_data"))
pref := tools.UserPref{
UserDesc: req.Get("introduction").String(),
}
_, err := UserEng.Table("user_preference_m").Where("user_id = ?", ctx.GetString("userid")).Update(&pref)
utils.CheckErr(err)
profileResp := model.ProfileRegisterResp{
ResponseData: []any{},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(profileResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
+49
View File
@@ -0,0 +1,49 @@
package handler
import (
"encoding/base64"
"encoding/json"
"fmt"
"honoka-chan/internal/model"
"honoka-chan/internal/utils"
"honoka-chan/pkg/encrypt"
honokautils "honoka-chan/pkg/utils"
"net/http"
"time"
"github.com/gin-gonic/gin"
)
func ScenarioStartup(ctx *gin.Context) {
startReq := model.ScenarioReq{}
err := json.Unmarshal([]byte(ctx.PostForm("request_data")), &startReq)
utils.CheckErr(err)
startResp := model.ScenarioResp{
ResponseData: model.ScenarioRes{
ScenarioID: startReq.ScenarioID,
ScenarioAdjustment: 50,
ServerTimestamp: time.Now().Unix(),
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(startResp)
utils.CheckErr(err)
nonce := ctx.GetInt("nonce")
nonce++
ctx.Header("user_id", ctx.GetString("userid"))
ctx.Header("authorize", fmt.Sprintf("consumerKey=lovelive_test&timeStamp=%d&version=1.1&token=%s&nonce=%d&user_id=%s&requestTimeStamp=%d", time.Now().Unix(), ctx.GetString("token"), nonce, ctx.GetString("userid"), ctx.GetInt64("req_time")))
ctx.Header("X-Message-Sign", base64.StdEncoding.EncodeToString(encrypt.RSASignSHA1(resp)))
ctx.String(http.StatusOK, string(resp))
}
func ScenarioReward(ctx *gin.Context) {
resp := honokautils.ReadAllText("assets/serverdata/reward.json")
ctx.Header("X-Message-Sign", utils.GenXMS([]byte(resp)))
ctx.String(http.StatusOK, resp)
}
+49
View File
@@ -0,0 +1,49 @@
package handler
import (
"encoding/base64"
"encoding/json"
"fmt"
"honoka-chan/internal/model"
"honoka-chan/internal/utils"
"honoka-chan/pkg/encrypt"
honokautils "honoka-chan/pkg/utils"
"net/http"
"time"
"github.com/gin-gonic/gin"
)
func SubScenarioStartup(ctx *gin.Context) {
startReq := model.SubScenarioReq{}
err := json.Unmarshal([]byte(ctx.PostForm("request_data")), &startReq)
utils.CheckErr(err)
startResp := model.SubScenarioResp{
ResponseData: model.SubScenarioRes{
SubscenarioID: startReq.SubscenarioID,
ScenarioAdjustment: 50,
ServerTimestamp: time.Now().Unix(),
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(startResp)
utils.CheckErr(err)
nonce := ctx.GetInt("nonce")
nonce++
ctx.Header("user_id", ctx.GetString("userid"))
ctx.Header("authorize", fmt.Sprintf("consumerKey=lovelive_test&timeStamp=%d&version=1.1&token=%s&nonce=%d&user_id=%s&requestTimeStamp=%d", time.Now().Unix(), ctx.GetString("token"), nonce, ctx.GetString("userid"), ctx.GetInt64("req_time")))
ctx.Header("X-Message-Sign", base64.StdEncoding.EncodeToString(encrypt.RSASignSHA1(resp)))
ctx.String(http.StatusOK, string(resp))
}
func SubScenarioReward(ctx *gin.Context) {
resp := honokautils.ReadAllText("assets/serverdata/subreward.json")
ctx.Header("X-Message-Sign", utils.GenXMS([]byte(resp)))
ctx.String(http.StatusOK, resp)
}
+29
View File
@@ -0,0 +1,29 @@
package handler
import (
"encoding/json"
"honoka-chan/internal/model"
"honoka-chan/internal/utils"
"net/http"
"time"
"github.com/gin-gonic/gin"
)
func TosCheck(ctx *gin.Context) {
tosResp := model.TosResp{
ResponseData: model.TosRes{
TosID: 1,
TosType: 1,
IsAgreed: true,
ServerTimestamp: time.Now().Unix(),
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(tosResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
+316
View File
@@ -0,0 +1,316 @@
package handler
import (
"encoding/json"
"fmt"
"honoka-chan/internal/model"
"honoka-chan/internal/utils"
"net/http"
"strconv"
"time"
"github.com/gin-gonic/gin"
)
func SetDisplayRank(ctx *gin.Context) {
dispResp := model.SetDisplayRankResp{
ResponseData: []any{},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(dispResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
func SetDeck(ctx *gin.Context) {
userId, err := strconv.Atoi(ctx.GetString("userid"))
utils.CheckErr(err)
deckReq := model.UnitDeckReq{}
if err := json.Unmarshal([]byte(ctx.PostForm("request_data")), &deckReq); err != nil {
panic(err)
}
// 开始事务
// UserEng.ShowSQL(true)
session := UserEng.NewSession()
defer session.Close()
if err := session.Begin(); err != nil {
session.Rollback()
panic(err)
}
// 原有队伍信息
var userDeckId []int
err = session.Table("user_deck_m").Cols("id").Where("user_id = ?", userId).Find(&userDeckId)
if err != nil {
session.Rollback()
panic(err)
}
// 删除全部原有队伍成员
_, err = session.Table("deck_unit_m").In("user_deck_id", userDeckId).Delete()
if err != nil {
session.Rollback()
panic(err)
}
// 删除全部原有队伍
_, err = session.Table("user_deck_m").In("id", userDeckId).Delete()
if err != nil {
session.Rollback()
panic(err)
}
// 遍历新队伍
for _, deck := range deckReq.UnitDeckList {
// 新队伍信息
userDeck := model.UserDeckData{
DeckID: deck.UnitDeckID,
MainFlag: deck.MainFlag,
DeckName: deck.DeckName,
UserID: userId,
InsertDate: time.Now().Unix(),
}
_, err = session.Table("user_deck_m").Insert(&userDeck)
if err != nil {
session.Rollback()
panic(err)
}
userDeckId := userDeck.ID
// fmt.Println("新队伍 ID:", userDeckId)
// 队伍成员信息
for _, unit := range deck.UnitDeckDetail {
// 成员信息
newUnitData := model.UnitData{}
exists, err := session.Table("user_unit_m").Where("unit_owning_user_id = ?", unit.UnitOwningUserID).Exist()
if err != nil {
session.Rollback()
panic(err)
}
if exists {
// fmt.Println("新成员为用户增加成员")
_, err = session.Table("user_unit_m").Where("unit_owning_user_id = ?", unit.UnitOwningUserID).Get(&newUnitData)
if err != nil {
session.Rollback()
panic(err)
}
} else {
exists, err := MainEng.Table("common_unit_m").Where("unit_owning_user_id = ?", unit.UnitOwningUserID).Exist()
if err != nil {
session.Rollback()
panic(err)
}
if exists {
// fmt.Println("新成员为公共成员")
_, err = MainEng.Table("common_unit_m").Where("unit_owning_user_id = ?", unit.UnitOwningUserID).Get(&newUnitData)
if err != nil {
session.Rollback()
panic(err)
}
} else {
// fmt.Println("新成员不存在")
session.Rollback()
panic("unexpected operation")
}
}
// fmt.Println("新的成员信息:", newUnitData)
// 插入新成员信息
newUnitDeckData := model.UnitDeckData{}
b, err := json.Marshal(newUnitData)
if err != nil {
session.Rollback()
panic(err)
}
if err = json.Unmarshal(b, &newUnitDeckData); err != nil {
session.Rollback()
panic(err)
}
newUnitDeckData.BeforeLove = newUnitDeckData.MaxLove
newUnitDeckData.Position = unit.Position
newUnitDeckData.UserDeckID = userDeckId
newUnitDeckData.InsertData = time.Now().Unix()
_, err = session.Table("deck_unit_m").Insert(&newUnitDeckData)
if err != nil {
session.Rollback()
panic(err)
}
}
}
// 结束事务
if err = session.Commit(); err != nil {
session.Rollback()
panic(err)
}
dispResp := model.SetDeckResp{
ResponseData: []any{},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(dispResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
func SetDeckName(ctx *gin.Context) {
userId, err := strconv.Atoi(ctx.GetString("userid"))
utils.CheckErr(err)
deckReq := model.DeckNameReq{}
if err := json.Unmarshal([]byte(ctx.PostForm("request_data")), &deckReq); err != nil {
panic(err)
}
exists, err := UserEng.Table("user_deck_m").Where("user_id = ? AND deck_id = ?", userId, deckReq.UnitDeckID).Exist()
utils.CheckErr(err)
if !exists {
ctx.String(http.StatusForbidden, ErrorMsg)
return
}
userDeck := model.UserDeckData{
DeckName: deckReq.DeckName,
}
_, err = UserEng.Table("user_deck_m").Update(&userDeck, &model.UserDeckData{
UserID: userId,
DeckID: deckReq.UnitDeckID,
})
utils.CheckErr(err)
dispResp := model.SetDeckResp{
ResponseData: []any{},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(dispResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
func WearAccessory(ctx *gin.Context) {
fmt.Println(ctx.PostForm("request_data"))
req := model.WearAccessoryReq{}
if err := json.Unmarshal([]byte(ctx.PostForm("request_data")), &req); err != nil {
panic(err)
}
// UserEng.ShowSQL(true)
// 开始事务
session := UserEng.NewSession()
defer session.Close()
if err := session.Begin(); err != nil {
session.Rollback()
panic(err)
}
// 取下饰品
for _, v := range req.Remove {
fmt.Println("Remove:", v.AccessoryOwningUserID, v.UnitOwningUserID)
_, err := session.Table("accessory_wear_m").
Where("accessory_owning_user_id = ? AND unit_owning_user_id = ? AND user_id = ?", v.AccessoryOwningUserID, v.UnitOwningUserID, ctx.GetString("userid")).
Delete()
if err != nil {
session.Rollback()
panic(err)
}
}
// 佩戴饰品
for _, v := range req.Wear {
fmt.Println("Wear:", v.AccessoryOwningUserID, v.UnitOwningUserID)
data := model.AccessoryWearData{
AccessoryOwningUserID: v.AccessoryOwningUserID,
UnitOwningUserID: v.UnitOwningUserID,
UserId: ctx.GetString("userid"),
}
_, err := session.Table("accessory_wear_m").Insert(&data)
utils.CheckErr(err)
}
// 结束事务
if err := session.Commit(); err != nil {
session.Rollback()
panic(err)
}
wearResp := model.AwardSetResp{
ResponseData: []any{},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(wearResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
func RemoveSkillEquip(ctx *gin.Context) {
fmt.Println(ctx.PostForm("request_data"))
req := model.SkillEquipReq{}
if err := json.Unmarshal([]byte(ctx.PostForm("request_data")), &req); err != nil {
panic(err)
}
// UserEng.ShowSQL(true)
// 开始事务
session := UserEng.NewSession()
defer session.Close()
if err := session.Begin(); err != nil {
session.Rollback()
panic(err)
}
// 取下宝石
for _, v := range req.Remove {
fmt.Println("Remove:", v.UnitOwningUserID, v.UnitRemovableSkillID)
_, err := session.Table("skill_equip_m").
Where("unit_removable_skill_id = ? AND unit_owning_user_id = ? AND user_id = ?", v.UnitRemovableSkillID, v.UnitOwningUserID, ctx.GetString("userid")).
Delete()
if err != nil {
session.Rollback()
panic(err)
}
}
// 佩戴宝石
for _, v := range req.Equip {
fmt.Println("Equip:", v.UnitOwningUserID, v.UnitRemovableSkillID)
data := model.SkillEquipData{
UnitRemovableSkillId: v.UnitRemovableSkillID,
UnitOwningUserID: v.UnitOwningUserID,
UserId: ctx.GetString("userid"),
}
_, err := session.Table("skill_equip_m").Insert(&data)
utils.CheckErr(err)
}
// 结束事务
if err := session.Commit(); err != nil {
session.Rollback()
panic(err)
}
wearResp := model.AwardSetResp{
ResponseData: []any{},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(wearResp)
utils.CheckErr(err)
fmt.Println(string(resp))
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
+75
View File
@@ -0,0 +1,75 @@
package handler
import (
"encoding/json"
"honoka-chan/internal/model"
"honoka-chan/internal/tools"
"honoka-chan/internal/utils"
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/tidwall/gjson"
)
func SetNotificationToken(ctx *gin.Context) {
notifResp := model.NotificationResp{
ResponseData: []any{},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(notifResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
func ChangeNavi(ctx *gin.Context) {
req := gjson.Parse(ctx.PostForm("request_data"))
pref := tools.UserPref{
UnitOwningUserID: int(req.Get("unit_owning_user_id").Int()),
}
_, err := UserEng.Table("user_preference_m").Where("user_id = ?", ctx.GetString("userid")).Update(&pref)
utils.CheckErr(err)
naviResp := model.UserNaviChangeResp{
ResponseData: []any{},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(naviResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
func ChangeName(ctx *gin.Context) {
req := gjson.Parse(ctx.PostForm("request_data"))
var oldName string
exists, err := UserEng.Table("user_preference_m").Where("user_id = ?", ctx.GetString("userid")).Cols("user_name").Get(&oldName)
utils.CheckErr(err)
if !exists {
ctx.String(http.StatusForbidden, ErrorMsg)
return
}
pref := tools.UserPref{
UserName: req.Get("name").String(),
}
_, err = UserEng.Table("user_preference_m").Where("user_id = ?", ctx.GetString("userid")).Update(&pref)
utils.CheckErr(err)
nameResp := model.UserNameChangeResp{
ResponseData: model.UserNameChangeRes{
BeforeName: oldName,
AfterName: req.Get("name").String(),
ServerTimestamp: time.Now().Unix(),
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(nameResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
+74
View File
@@ -0,0 +1,74 @@
package handler
import (
"encoding/json"
"honoka-chan/config"
"honoka-chan/internal/model"
"honoka-chan/internal/tools"
"honoka-chan/internal/utils"
"net/http"
"strconv"
"time"
"github.com/gin-gonic/gin"
)
func UserInfo(ctx *gin.Context) {
userId, err := strconv.Atoi(ctx.GetString("userid"))
utils.CheckErr(err)
pref := tools.UserPref{}
exists, err := UserEng.Table("user_preference_m").Where("user_id = ?", userId).Get(&pref)
utils.CheckErr(err)
if !exists {
ctx.String(http.StatusForbidden, ErrorMsg)
return
}
userResp := model.UserInfoResp{
ResponseData: model.UserInfoRes{
User: model.UserInfo{
UserID: userId,
Name: pref.UserName,
Level: config.Conf.UserPrefs.Level,
Exp: config.Conf.UserPrefs.ExpNumerator,
PreviousExp: 0,
NextExp: config.Conf.UserPrefs.ExpDenominator,
GameCoin: config.Conf.UserPrefs.GameCoin,
SnsCoin: config.Conf.UserPrefs.SnsCoin,
FreeSnsCoin: config.Conf.UserPrefs.SnsCoin,
PaidSnsCoin: 0,
SocialPoint: 1438395,
UnitMax: 5000,
WaitingUnitMax: 1000,
EnergyMax: config.Conf.UserPrefs.EnergyMax,
EnergyFullTime: "2023-03-20 03:58:55",
LicenseLiveEnergyRecoverlyTime: 60,
EnergyFullNeedTime: 0,
OverMaxEnergy: config.Conf.UserPrefs.OverMaxEnergy,
TrainingEnergy: 100,
TrainingEnergyMax: 100,
FriendMax: 99,
InviteCode: config.Conf.UserPrefs.InviteCode,
InsertDate: "2015-08-10 18:58:30",
UpdateDate: "2018-08-09 18:13:12",
TutorialState: -1,
DiamondCoin: 0,
CrystalCoin: 0,
LpRecoveryItem: []model.LpRecoveryItem{},
},
Birth: model.Birth{
BirthMonth: 10,
BirthDay: 18,
},
ServerTimestamp: time.Now().Unix(),
},
ReleaseInfo: []any{},
StatusCode: 200,
}
resp, err := json.Marshal(userResp)
utils.CheckErr(err)
ctx.Header("X-Message-Sign", utils.GenXMS(resp))
ctx.String(http.StatusOK, string(resp))
}
+197
View File
@@ -0,0 +1,197 @@
package handler
import (
"encoding/csv"
"honoka-chan/internal/model"
"honoka-chan/internal/utils"
"net/http"
"os"
"path"
"strconv"
"time"
"github.com/forgoer/openssl"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
)
type ErrMsg struct {
Error int `json:"error"`
Msg string `json:"msg"`
}
func WebLogin(ctx *gin.Context) {
area := ctx.PostForm("area")
user := ctx.PostForm("user")
pass := ctx.PostForm("pass")
if area == "" || user == "" || pass == "" {
ctx.JSON(http.StatusOK, model.Msg{
Code: 1,
Message: "参数不完整!",
Redirect: "",
})
return
}
userName := " " + area + "-" + user
var userId int
exists, err := UserEng.Table("users").Where("phone = ? AND password = ?", userName, openssl.Md5ToString(pass)).Cols("userid").Get(&userId)
utils.CheckErr(err)
if !exists {
ctx.JSON(http.StatusOK, model.Msg{
Code: 1,
Message: "账号不存在或者密码有误!",
Redirect: "",
})
return
}
session := sessions.Default(ctx)
session.Options(sessions.Options{
MaxAge: 3600 * 24,
})
session.Set("userid", userId)
session.Save()
ctx.JSON(http.StatusOK, model.Msg{
Code: 0,
Message: "登录成功!",
Redirect: "/admin/index",
})
}
func WebLogout(ctx *gin.Context) {
session := sessions.Default(ctx)
session.Clear()
session.Options(sessions.Options{
Path: "/admin",
MaxAge: -1,
})
session.Save()
ctx.Redirect(http.StatusFound, "/admin/login")
}
func Upload(ctx *gin.Context) {
file, err := ctx.FormFile("file")
utils.CheckErr(err)
tmpPath := path.Join("./temp", file.Filename)
err = ctx.SaveUploadedFile(file, tmpPath)
utils.CheckErr(err)
session := UserEng.NewSession()
defer session.Close()
if err = session.Begin(); err != nil {
session.Rollback()
panic(err)
}
f, err := os.Open(tmpPath)
utils.CheckErr(err)
defer f.Close()
r := csv.NewReader(f)
rs, err := r.ReadAll()
if err != nil {
session.Rollback()
ctx.JSON(http.StatusOK, ErrMsg{Error: 1, Msg: "文件解析失败!"})
return
}
for _, rr := range rs {
if len(rr) != 2 || rr[0] == "" || rr[1] == "" {
session.Rollback()
ctx.JSON(http.StatusOK, ErrMsg{Error: 1, Msg: "文件解析失败!"})
return
}
skillLv, err := strconv.Atoi(rr[1])
if err != nil {
session.Rollback()
ctx.JSON(http.StatusOK, ErrMsg{Error: 1, Msg: "文件解析失败!"})
return
}
var unitId, unitExp, unitRarity, unitHp, unitSigned int
exists, err := MainEng.Table("common_unit_m").Join("LEFT", "unit_m", "common_unit_m.unit_id = unit_m.unit_id").
Where("unit_m.unit_number = ?", rr[0]).
Cols("common_unit_m.unit_id,common_unit_m.exp,unit_m.rarity,common_unit_m.max_hp,common_unit_m.is_signed").
Get(&unitId, &unitExp, &unitRarity, &unitHp, &unitSigned)
utils.CheckErr(err)
if !exists {
session.Rollback()
ctx.JSON(http.StatusOK, ErrMsg{Error: 1, Msg: "卡片不存在!"})
return
}
if unitRarity != 4 {
session.Rollback()
ctx.JSON(http.StatusOK, ErrMsg{Error: 1, Msg: "仅支持导入UR卡片!"})
return
}
if skillLv < 0 || skillLv > 8 {
session.Rollback()
ctx.JSON(http.StatusOK, ErrMsg{Error: 1, Msg: "技能等级设置有误!"})
return
}
var diffExp, diffSmile, diffPure, diffCool int
_, err = MainEng.Table("unit_level_limit_pattern_m").Where("unit_level_limit_id = 1 AND unit_level = 350").
Cols("next_exp,smile_diff,pure_diff,cool_diff").Get(&diffExp, &diffSmile, &diffPure, &diffCool)
utils.CheckErr(err)
isSigned := false
if unitSigned == 1 {
isSigned = true
}
var skillExp int
if skillLv != 8 {
skillExp = 0
} else {
skillExp = 29900
}
unitData := model.UnitData{
UserID: ctx.GetInt("userid"),
UnitID: unitId,
Exp: unitExp + diffExp,
NextExp: 0,
Level: 350,
MaxLevel: 350,
LevelLimitID: 1,
Rank: 2,
MaxRank: 2,
Love: 1000,
MaxLove: 1000,
UnitSkillExp: skillExp,
UnitSkillLevel: skillLv,
MaxHp: unitHp,
UnitRemovableSkillCapacity: 8,
FavoriteFlag: false,
DisplayRank: 2,
IsRankMax: true,
IsLoveMax: true,
IsLevelMax: true,
IsSigned: isSigned,
IsSkillLevelMax: true,
IsRemovableSkillCapacityMax: true,
InsertDate: time.Now().Format("2006-01-02 03:04:05"),
}
_, err = session.Table("user_unit_m").Insert(&unitData)
if err != nil {
session.Rollback()
panic(err)
}
if err = session.Commit(); err != nil {
session.Rollback()
panic(err)
}
}
ctx.JSON(http.StatusOK, ErrMsg{Error: 0, Msg: "上传成功!"})
}
+54
View File
@@ -0,0 +1,54 @@
package middleware
import (
"encoding/base64"
"encoding/json"
"fmt"
"honoka-chan/internal/utils"
"honoka-chan/pkg/db"
"honoka-chan/pkg/encrypt"
honokautils "honoka-chan/pkg/utils"
"time"
"github.com/gin-gonic/gin"
"github.com/tidwall/gjson"
)
func AuthKey(ctx *gin.Context) {
req := gjson.Parse(ctx.PostForm("request_data"))
tDummyToken, err := base64.StdEncoding.DecodeString(req.Get("dummy_token").String())
utils.CheckErr(err)
dummyToken := encrypt.RSADecrypt(tDummyToken)
// aesKey := dummyToken[0:16]
// tAuthData, err := base64.StdEncoding.DecodeString(req.Get("auth_data").String())
// utils.CheckErr(err)
// authData := utils.Sub16(encrypt.AES_CBC_Decrypt(tAuthData, aesKey))
// fmt.Println(string(authData))
clientToken := base64.StdEncoding.EncodeToString(dummyToken)
serverToken := base64.StdEncoding.EncodeToString([]byte(honokautils.RandomStr(32)))
authorizeToken := base64.StdEncoding.EncodeToString([]byte(honokautils.RandomStr(32)))
ctx.Set("dummy_token", serverToken)
ctx.Set("authorize_token", authorizeToken)
authJson, err := json.Marshal(map[string]any{
"client_token": clientToken,
"server_token": serverToken,
})
utils.CheckErr(err)
err = db.DB.Set([]byte(authorizeToken), authJson)
utils.CheckErr(err)
nonce := ctx.GetInt("nonce")
nonce++
ctx.Set("nonce", nonce)
authorize := fmt.Sprintf("consumerKey=lovelive_test&timeStamp=%d&version=1.1&nonce=%d&requestTimeStamp=%d", time.Now().Unix(), nonce, ctx.GetInt64("req_time"))
ctx.Header("user_id", "")
ctx.Header("authorize", authorize)
ctx.Next()
}
+82
View File
@@ -0,0 +1,82 @@
package middleware
import (
"fmt"
"honoka-chan/internal/utils"
"honoka-chan/pkg/db"
"net/http"
"net/url"
"strconv"
"time"
"github.com/gin-gonic/gin"
)
var (
ErrorMsg = `{"code":20001,"message":""}`
)
func CheckErr(err error) {
if err != nil {
panic(err)
}
}
func Common(ctx *gin.Context) {
ctx.Set("req_time", time.Now().Unix())
authorize := ctx.Request.Header.Get("Authorize")
if authorize == "" {
ctx.String(http.StatusForbidden, ErrorMsg)
ctx.Abort()
}
ctx.Set("authorize", authorize)
params, err := url.ParseQuery(authorize)
utils.CheckErr(err)
nonce, err := strconv.Atoi(params.Get("nonce"))
utils.CheckErr(err)
nonce++
ctx.Set("nonce", nonce)
token := params.Get("token")
ctx.Set("token", token)
if ctx.Request.URL.String() == "/main.php/login/authkey" ||
ctx.Request.URL.String() == "/main.php/login/login" {
// 特殊请求
fmt.Println("========")
} else {
userId := ctx.Request.Header.Get("User-ID")
if userId == "" {
ctx.String(http.StatusForbidden, ErrorMsg)
ctx.Abort()
}
ctx.Set("userid", userId)
rToken, err := db.DB.Get([]byte(userId))
utils.CheckErr(err)
if token != string(rToken) {
ctx.String(http.StatusForbidden, ErrorMsg)
ctx.Abort()
}
if !db.MatchTokenUid(token, userId) {
ctx.String(http.StatusForbidden, ErrorMsg)
ctx.Abort()
}
ctx.Header("user_id", userId)
ctx.Header("authorize", fmt.Sprintf("consumerKey=lovelive_test&timeStamp=%d&version=1.1&token=%s&nonce=%d&user_id=%s&requestTimeStamp=%d", time.Now().Unix(), token, nonce, userId, time.Now().Unix()))
}
ctx.Header("Content-Type", "application/json; charset=utf-8")
ctx.Header("X-Powered-By", "KLab Native APP Platform")
ctx.Header("server_version", "20120129")
ctx.Header("Server-Version", "97.4.6")
ctx.Header("version_up", "0")
ctx.Header("status_code", "200")
ctx.Next()
}
+45
View File
@@ -0,0 +1,45 @@
package middleware
import (
"encoding/base64"
"honoka-chan/internal/utils"
"honoka-chan/pkg/db"
"honoka-chan/pkg/encrypt"
honokautils "honoka-chan/pkg/utils"
"github.com/gin-gonic/gin"
"github.com/tidwall/gjson"
)
func Login(ctx *gin.Context) {
authData, err := db.DB.Get([]byte(ctx.GetString("token")))
utils.CheckErr(err)
clientToken, err := base64.StdEncoding.DecodeString(gjson.Get(string(authData), "client_token").String())
utils.CheckErr(err)
serverToken, err := base64.StdEncoding.DecodeString(gjson.Get(string(authData), "server_token").String())
utils.CheckErr(err)
xmcKey := honokautils.SliceXor(clientToken, serverToken)
aesKey := xmcKey[0:16]
req := gjson.Parse(ctx.GetString("request_data"))
tKey, err := base64.StdEncoding.DecodeString(req.Get("login_key").String())
utils.CheckErr(err)
loginKey := honokautils.Sub16(encrypt.AESCBCDecrypt(tKey, aesKey))
ctx.Set("login_key", string(loginKey))
tPasswd, err := base64.StdEncoding.DecodeString(req.Get("login_passwd").String())
utils.CheckErr(err)
loginPasswd := honokautils.Sub16(encrypt.AESCBCDecrypt(tPasswd, aesKey))
ctx.Set("login_passwd", string(loginPasswd))
nonce := ctx.GetInt("nonce")
nonce++
ctx.Set("nonce", nonce)
authorizeToken := base64.StdEncoding.EncodeToString([]byte(honokautils.RandomStr(32)))
ctx.Set("authorize_token", authorizeToken)
ctx.Next()
}
+34
View File
@@ -0,0 +1,34 @@
package middleware
import (
"honoka-chan/internal/utils"
"io"
"mime/multipart"
"strings"
"github.com/gin-gonic/gin"
)
func ParseMultipartForm(ctx *gin.Context) {
// I don't know why mime.ParseMediaType() is failed
// mime.ParseMediaType(ctx.Request.Header.Get("Content-Type"))
boundary := strings.ReplaceAll(ctx.Request.Header.Get("Content-Type"), "multipart/form-data; boundary=", "")
var reqData []byte
mReader := multipart.NewReader(ctx.Request.Body, boundary)
for {
part, err := mReader.NextPart()
if err == io.EOF {
break
}
utils.CheckErr(err)
data, err := io.ReadAll(part)
utils.CheckErr(err)
reqData = data
}
ctx.Set("request_data", string(reqData))
ctx.Next()
}
+29
View File
@@ -0,0 +1,29 @@
package middleware
import (
"net/http"
"strings"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
)
func WebAuth(ctx *gin.Context) {
session := sessions.Default(ctx)
requestUrl := strings.Split(ctx.Request.URL.String(), "?")[0] // 过滤 GET 参数
userId, ok := session.Get("userid").(int)
if ok {
if requestUrl == "/admin/login" {
ctx.Redirect(http.StatusFound, "/admin/index")
ctx.Abort()
}
} else {
if requestUrl != "/admin/login" {
ctx.Redirect(http.StatusFound, "/admin/login")
ctx.Abort()
}
}
ctx.Set("userid", userId)
ctx.Next()
}
+35
View File
@@ -0,0 +1,35 @@
package model
// AlbumResult ...
type AlbumResult struct {
UnitID int `json:"unit_id"`
RankMaxFlag bool `json:"rank_max_flag"`
LoveMaxFlag bool `json:"love_max_flag"`
RankLevelMaxFlag bool `json:"rank_level_max_flag"`
AllMaxFlag bool `json:"all_max_flag"`
HighestLovePerUnit int `json:"highest_love_per_unit"`
TotalLove int `json:"total_love"`
FavoritePoint int `json:"favorite_point"`
SignFlag bool `json:"sign_flag"`
}
// AlbumResp ...
type AlbumResp struct {
Result []AlbumResult `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
// AlbumSeriesRes ...
type AlbumSeriesRes struct {
SeriesID int `json:"series_id"`
UnitList []AlbumResult `json:"unit_list"`
}
// AlbumSeriesResp ...
type AlbumSeriesResp struct {
ResponseData []AlbumSeriesRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
+14
View File
@@ -0,0 +1,14 @@
package model
// AnnounceResp ...
type AnnounceResp struct {
ResponseData AnnounceRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// AnnounceRes ...
type AnnounceRes struct {
HasUnreadAnnounce bool `json:"has_unread_announce"`
ServerTimestamp int64 `json:"server_timestamp"`
}
+25
View File
@@ -0,0 +1,25 @@
package model
import "encoding/json"
// ApiReq ...
type ApiReq struct {
Module string `json:"module"`
Action string `json:"action"`
Timestamp int64 `json:"timeStamp"`
}
// ApiResp ...
type ApiResp struct {
ResponseData json.RawMessage `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// ApiUserInfoResp ...
type ApiUserInfoResp struct {
Result UserInfo `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
+14
View File
@@ -0,0 +1,14 @@
package model
// AuthKeyRes ...
type AuthKeyRes struct {
AuthorizeToken string `json:"authorize_token"`
DummyToken string `json:"dummy_token"`
}
// AuthKeyResp ...
type AuthKeyResp struct {
ResponseData AuthKeyRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
+28
View File
@@ -0,0 +1,28 @@
package model
// AwardSetResp ...
type AwardSetResp struct {
ResponseData []any `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// AwardInfo ...
type AwardInfo struct {
AwardID int `json:"award_id"`
IsSet bool `json:"is_set"`
InsertDate string `json:"insert_date"`
}
// AwardInfoRes ...
type AwardInfoRes struct {
AwardInfo []AwardInfo `json:"award_info"`
}
// AwardInfoResp ...
type AwardInfoResp struct {
Result AwardInfoRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
+28
View File
@@ -0,0 +1,28 @@
package model
// BackgroundSetResp ...
type BackgroundSetResp struct {
ResponseData []any `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// BackgroundInfo ...
type BackgroundInfo struct {
BackgroundID int `json:"background_id"`
IsSet bool `json:"is_set"`
InsertDate string `json:"insert_date"`
}
// BackgroundInfoRes ...
type BackgroundInfoRes struct {
BackgroundInfo []BackgroundInfo `json:"background_info"`
}
// BackgroundInfoResp ...
type BackgroundInfoResp struct {
Result BackgroundInfoRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
+29
View File
@@ -0,0 +1,29 @@
package model
// BannerList ...
type BannerList struct {
BannerType int `json:"banner_type"`
TargetID int `json:"target_id"`
AssetPath string `json:"asset_path"`
FixedFlag bool `json:"fixed_flag"`
BackSide bool `json:"back_side"`
BannerID int `json:"banner_id"`
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
AddUnitStartDate string `json:"add_unit_start_date,omitempty"`
WebviewURL string `json:"webview_url,omitempty"`
}
// BannerListRes ...
type BannerListRes struct {
TimeLimit string `json:"time_limit"`
BannerList []BannerList `json:"banner_list"`
}
// BannerListResp ...
type BannerListResp struct {
Result BannerListRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
+9
View File
@@ -0,0 +1,9 @@
package model
// ChallengeInfoResp ...
type ChallengeInfoResp struct {
Result []any `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
+21
View File
@@ -0,0 +1,21 @@
package model
// CostumeList ...
type CostumeList struct {
UnitID int `json:"unit_id"`
IsRankMax bool `json:"is_rank_max"`
IsSigned bool `json:"is_signed"`
}
// CostumeListRes ...
type CostumeListRes struct {
CostumeList []CostumeList `json:"costume_list"`
}
// CostumeListResp ...
type CostumeListResp struct {
Result CostumeListRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
+102
View File
@@ -0,0 +1,102 @@
package model
// AdditionalReq ...
type AdditionalReq struct {
Module string `json:"module"`
Mgd int `json:"mgd"`
Action string `json:"action"`
TimeStamp int `json:"timeStamp"`
PackageID int `json:"package_id"`
TargetOs string `json:"target_os"`
PackageType int `json:"package_type"`
CommandNum string `json:"commandNum"`
}
// AdditionalRes ...
type AdditionalRes struct {
Size int `json:"size"`
URL string `json:"url"`
}
// AdditionalResp ...
type AdditionalResp struct {
ResponseData []AdditionalRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// BatchReq ...
type BatchReq struct {
ClientVersion string `json:"client_version"`
Os string `json:"os"`
PackageType int `json:"package_type"`
ExcludedPackageIds []int `json:"excluded_package_ids"`
CommandNum string `json:"commandNum"`
}
// BatchRes ...
type BatchRes struct {
Size int `json:"size"`
URL string `json:"url"`
}
// BatchResp ...
type BatchResp struct {
ResponseData []BatchRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// UpdateReq ...
type UpdateReq struct {
Module string `json:"module"`
TargetOs string `json:"target_os"`
InstallVersion string `json:"install_version"`
TimeStamp int `json:"timeStamp"`
Action string `json:"action"`
PackageList []any `json:"package_list"`
CommandNum string `json:"commandNum"`
ExternalVersion string `json:"external_version"`
}
// UpdateRes ...
type UpdateRes struct {
Size int `json:"size"`
URL string `json:"url"`
Version string `json:"version"`
}
// UpdateResp ...
type UpdateResp struct {
ResponseData []UpdateRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// UrlReq ...
type UrlReq struct {
Module string `json:"module"`
Os string `json:"os"`
Mgd int `json:"mgd"`
PathList []string `json:"path_list"`
Action string `json:"action"`
}
// UrlRes ...
type UrlRes struct {
UrlList []string `json:"url_list"`
}
// UrlResp ...
type UrlResp struct {
ResponseData UrlRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// EventResp ...
type EventResp struct {
ResponseData []any `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
+20
View File
@@ -0,0 +1,20 @@
package model
// EventsResp ...
type EventsResp struct {
ResponseData EventsRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// EventsRes ...
type EventsRes struct {
TargetList []TargetList `json:"target_list"`
ServerTimestamp int64 `json:"server_timestamp"`
}
// TargetList ...
type TargetList struct {
Position int `json:"position"`
IsDisplayable bool `json:"is_displayable"`
}
+20
View File
@@ -0,0 +1,20 @@
package model
// ExchangePointList ...
type ExchangePointList struct {
Rarity int `json:"rarity"`
ExchangePoint int `json:"exchange_point"`
}
// ExchangePointRes ...
type ExchangePointRes struct {
ExchangePointList []ExchangePointList `json:"exchange_point_list"`
}
// ExchangePointResp ...
type ExchangePointResp struct {
Result ExchangePointRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
+15
View File
@@ -0,0 +1,15 @@
package model
// GdprResp ...
type GdprResp struct {
ResponseData GdprRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// GdprRes ...
type GdprRes struct {
EnableGdpr bool `json:"enable_gdpr"`
IsEea bool `json:"is_eea"`
ServerTimestamp int64 `json:"server_timestamp"`
}
+84
View File
@@ -0,0 +1,84 @@
package model
// LbDayItem ...
type LbDayItem struct {
ItemID int `json:"item_id"`
AddType int `json:"add_type"`
Amount int `json:"amount"`
}
// LbDays ...
type LbDays struct {
Day int `json:"day"`
DayOfTheWeek int `json:"day_of_the_week"`
SpecialDay bool `json:"special_day"`
SpecialImageAsset string `json:"special_image_asset"`
Received bool `json:"received"`
AdReceived bool `json:"ad_received"`
Item LbDayItem `json:"item"`
}
// LbMonth ...
type LbMonth struct {
Year int `json:"year"`
Month int `json:"month"`
Days []LbDays `json:"days"`
}
// CalendarInfo ...
type CalendarInfo struct {
CurrentDate string `json:"current_date"`
CurrentMonth LbMonth `json:"current_month"`
NextMonth LbMonth `json:"next_month"`
}
// Reward ...
type Reward struct {
ItemID int `json:"item_id"`
AddType int `json:"add_type"`
Amount int `json:"amount"`
}
// TotalLoginInfo ...
type TotalLoginInfo struct {
LoginCount int `json:"login_count"`
RemainingCount int `json:"remaining_count"`
Reward []Reward `json:"reward"`
}
// LbRankInfo ...
type LbRankInfo struct {
BeforeClassRankID int `json:"before_class_rank_id"`
AfterClassRankID int `json:"after_class_rank_id"`
RankUpDate string `json:"rank_up_date"`
}
// LbClassSystem ...
type LbClassSystem struct {
RankInfo LbRankInfo `json:"rank_info"`
CompleteFlag bool `json:"complete_flag"`
IsOpened bool `json:"is_opened"`
IsVisible bool `json:"is_visible"`
}
// LbRes ...
type LbRes struct {
Sheets []any `json:"sheets"`
CalendarInfo CalendarInfo `json:"calendar_info"`
TotalLoginInfo TotalLoginInfo `json:"total_login_info"`
LicenseLbonusList []any `json:"license_lbonus_list"`
ClassSystem LbClassSystem `json:"class_system"`
StartDashSheets []any `json:"start_dash_sheets"`
EffortPoint []EffortPoint `json:"effort_point"`
LimitedEffortBox []any `json:"limited_effort_box"`
MuseumInfo Museum `json:"museum_info"`
ServerTimestamp int64 `json:"server_timestamp"`
PresentCnt int `json:"present_cnt"`
}
// LbResp ...
type LbResp struct {
ResponseData LbRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
+655
View File
@@ -0,0 +1,655 @@
package model
// GameOverResp ...
type GameOverResp struct {
ResponseData []any `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// NormalLiveStatusList ...
type NormalLiveStatusList struct {
LiveDifficultyID int `json:"live_difficulty_id"`
Status int `json:"status"`
HiScore int `json:"hi_score"`
HiComboCount int `json:"hi_combo_count"`
ClearCnt int `json:"clear_cnt"`
AchievedGoalIDList []int `json:"achieved_goal_id_list"`
}
// SpecialLiveStatusList ...
type SpecialLiveStatusList struct {
LiveDifficultyID int `json:"live_difficulty_id"`
Status int `json:"status"`
HiScore int `json:"hi_score"`
HiComboCount int `json:"hi_combo_count"`
ClearCnt int `json:"clear_cnt"`
AchievedGoalIDList []int `json:"achieved_goal_id_list"`
}
// TrainingLiveStatusList ...
type TrainingLiveStatusList struct {
LiveDifficultyID int `json:"live_difficulty_id"`
Status int `json:"status"`
HiScore int `json:"hi_score"`
HiComboCount int `json:"hi_combo_count"`
ClearCnt int `json:"clear_cnt"`
AchievedGoalIDList []int `json:"achieved_goal_id_list"`
}
// LiveStatusRes ...
type LiveStatusRes struct {
NormalLiveStatusList []NormalLiveStatusList `json:"normal_live_status_list"`
SpecialLiveStatusList []SpecialLiveStatusList `json:"special_live_status_list"`
TrainingLiveStatusList []TrainingLiveStatusList `json:"training_live_status_list"`
MarathonLiveStatusList []any `json:"marathon_live_status_list"`
FreeLiveStatusList []any `json:"free_live_status_list"`
CanResumeLive bool `json:"can_resume_live"`
}
// LiveStatusResp ...
type LiveStatusResp struct {
Result LiveStatusRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
// LiveList ...
type LiveList struct {
LiveDifficultyID int `json:"live_difficulty_id"`
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
IsRandom bool `json:"is_random"`
}
// LimitedBonusCommonList ...
type LimitedBonusCommonList struct {
LiveType int `json:"live_type"`
LimitedBonusType int `json:"limited_bonus_type"`
LimitedBonusValue int `json:"limited_bonus_value"`
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
}
// RandomLiveList ...
type RandomLiveList struct {
AttributeID int `json:"attribute_id"`
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
}
// TrainingLiveList ...
type TrainingLiveList struct {
LiveDifficultyID int `json:"live_difficulty_id"`
StartDate string `json:"start_date"`
IsRandom bool `json:"is_random"`
}
// LiveScheduleRes ...
type LiveScheduleRes struct {
EventList []any `json:"event_list"`
LiveList []LiveList `json:"live_list"`
LimitedBonusList []any `json:"limited_bonus_list"`
LimitedBonusCommonList []LimitedBonusCommonList `json:"limited_bonus_common_list"`
RandomLiveList []RandomLiveList `json:"random_live_list"`
FreeLiveList []any `json:"free_live_list"`
TrainingLiveList []TrainingLiveList `json:"training_live_list"`
}
// LiveScheduleResp ...
type LiveScheduleResp struct {
Result LiveScheduleRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
// PlayReq ...
type PlayReq struct {
Module string `json:"module"`
PartyUserID int64 `json:"party_user_id"`
Action string `json:"action"`
Mgd int `json:"mgd"`
IsTraining bool `json:"is_training"`
UnitDeckID int `json:"unit_deck_id"`
LiveDifficultyID string `json:"live_difficulty_id"`
TimeStamp int `json:"timeStamp"`
LpFactor int `json:"lp_factor"`
CommandNum string `json:"commandNum"`
}
// RankInfo ...
type RankInfo struct {
Rank int `json:"rank"`
RankMin int `json:"rank_min"`
RankMax int `json:"rank_max"`
}
// NotesList ...
type NotesList struct {
TimingSec float64 `json:"timing_sec"`
NotesAttribute int `json:"notes_attribute"`
NotesLevel int `json:"notes_level"`
Effect int `json:"effect"`
EffectValue float64 `json:"effect_value"`
Position int `json:"position"`
}
// LiveInfo ...
type LiveInfo struct {
LiveDifficultyID int `json:"live_difficulty_id"`
IsRandom bool `json:"is_random"`
AcFlag int `json:"ac_flag"`
SwingFlag int `json:"swing_flag"`
NotesList []NotesList `json:"notes_list"`
}
// PlayCostume ...
type PlayCostume struct {
UnitID int `json:"unit_id"`
IsRankMax bool `json:"is_rank_max"`
IsSigned bool `json:"is_signed"`
}
// UnitList ...
type UnitList struct {
Smile int `json:"smile"`
Cute int `json:"cute"`
Cool int `json:"cool"`
Costume PlayCostume `json:"costume,omitempty"`
}
// DeckInfo ...
type DeckInfo struct {
UnitDeckID int `json:"unit_deck_id"`
TotalSmile int `json:"total_smile"`
TotalCute int `json:"total_cute"`
TotalCool int `json:"total_cool"`
TotalHp int `json:"total_hp"`
PreparedHpDamage int `json:"prepared_hp_damage"`
UnitList []UnitList `json:"unit_list"`
}
// PlayLiveList ...
type PlayLiveList struct {
LiveInfo LiveInfo `json:"live_info"`
DeckInfo DeckInfo `json:"deck_info"`
}
// PlayRes ...
type PlayRes struct {
RankInfo []RankInfo `json:"rank_info"`
EnergyFullTime string `json:"energy_full_time"`
OverMaxEnergy int `json:"over_max_energy"`
AvailableLiveResume bool `json:"available_live_resume"`
LiveList []PlayLiveList `json:"live_list"`
IsMarathonEvent bool `json:"is_marathon_event"`
MarathonEventID any `json:"marathon_event_id"`
NoSkill bool `json:"no_skill"`
CanActivateEffect bool `json:"can_activate_effect"`
ServerTimestamp int64 `json:"server_timestamp"`
}
// PlayResp ...
type PlayResp struct {
ResponseData PlayRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// PlayScoreReq ...
type PlayScoreReq struct {
Module string `json:"module"`
Action string `json:"action"`
TimeStamp int64 `json:"timeStamp"`
Mgd int `json:"mgd"`
LiveDifficultyID string `json:"live_difficulty_id"`
CommandNum string `json:"commandNum"`
}
// On ...
type On struct {
HasRecord bool `json:"has_record"`
LiveInfo LiveInfo `json:"live_info"`
RandomSeed any `json:"random_seed"`
MaxCombo any `json:"max_combo"`
UpdateDate any `json:"update_date"`
PreciseList any `json:"precise_list"`
DeckInfo any `json:"deck_info"`
TapAdjust any `json:"tap_adjust"`
CanReplay bool `json:"can_replay"`
}
// Off ...
type Off struct {
HasRecord bool `json:"has_record"`
LiveInfo LiveInfo `json:"live_info"`
RandomSeed any `json:"random_seed"`
MaxCombo any `json:"max_combo"`
UpdateDate any `json:"update_date"`
PreciseList any `json:"precise_list"`
DeckInfo any `json:"deck_info"`
TapAdjust any `json:"tap_adjust"`
CanReplay bool `json:"can_replay"`
}
// PlayScoreRes ...
type PlayScoreRes struct {
On On `json:"on"`
Off Off `json:"off"`
RankInfo []RankInfo `json:"rank_info"`
CanActivateEffect bool `json:"can_activate_effect"`
ServerTimestamp int64 `json:"server_timestamp"`
}
// PlayScoreResp ...
type PlayScoreResp struct {
ResponseData PlayScoreRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// PlayRewardReq ...
type PlayRewardReq struct {
Module string `json:"module"`
Action string `json:"action"`
GoodCnt int `json:"good_cnt"`
MissCnt int `json:"miss_cnt"`
IsTraining bool `json:"is_training"`
GreatCnt int `json:"great_cnt"`
CommandNum string `json:"commandNum"`
LoveCnt int `json:"love_cnt"`
RemainHp int `json:"remain_hp"`
MaxCombo int `json:"max_combo"`
ScoreSmile int `json:"score_smile"`
PerfectCnt int `json:"perfect_cnt"`
BadCnt int `json:"bad_cnt"`
Mgd int `json:"mgd"`
EventPoint int `json:"event_point"`
LiveDifficultyID int `json:"live_difficulty_id"`
TimeStamp int `json:"timeStamp"`
PreciseScoreLog PreciseScoreLog `json:"precise_score_log"`
ScoreCute int `json:"score_cute"`
EventID any `json:"event_id"`
ScoreCool int `json:"score_cool"`
}
// Icon ...
type Icon struct {
SlideID int `json:"slide_id"`
JustID int `json:"just_id"`
NormalID int `json:"normal_id"`
}
// LiveSetting ...
type LiveSetting struct {
StringSize int `json:"string_size"`
PreciseScoreAutoUpdateFlag bool `json:"precise_score_auto_update_flag"`
SeID int `json:"se_id"`
CutinBrightness int `json:"cutin_brightness"`
RandomValue int `json:"random_value"`
PreciseScoreUpdateType int `json:"precise_score_update_type"`
EffectFlag bool `json:"effect_flag"`
NotesSpeed float64 `json:"notes_speed"`
Icon Icon `json:"icon"`
CutinType int `json:"cutin_type"`
}
// PreciseList ...
type PreciseList struct {
Effect int `json:"effect"`
Count int `json:"count"`
Tap float64 `json:"tap"`
NoteNumber int `json:"note_number"`
Position int `json:"position"`
Accuracy int `json:"accuracy"`
IsSame bool `json:"is_same"`
}
// BackgroundScore ...
type BackgroundScore struct {
Smile int `json:"smile"`
Cute int `json:"cute"`
Cool int `json:"cool"`
}
// TriggerLog ...
type TriggerLog struct {
ActivationRate int `json:"activation_rate"`
Position int `json:"position"`
}
// PreciseScoreLog ...
type PreciseScoreLog struct {
LiveSetting LiveSetting `json:"live_setting"`
TapAdjust int `json:"tap_adjust"`
PreciseList []PreciseList `json:"precise_list"`
BackgroundScore BackgroundScore `json:"background_score"`
IsLogOn bool `json:"is_log_on"`
ScoreLog []int `json:"score_log"`
IsSkillOn bool `json:"is_skill_on"`
TriggerLog []TriggerLog `json:"trigger_log"`
RandomSeed int `json:"random_seed"`
}
// RewardLiveInfo ...
type RewardLiveInfo struct {
LiveDifficultyID int `json:"live_difficulty_id"`
IsRandom bool `json:"is_random"`
AcFlag int `json:"ac_flag"`
SwingFlag int `json:"swing_flag"`
}
// PlayerExpUnitMax ...
type PlayerExpUnitMax struct {
Before int `json:"before"`
After int `json:"after"`
}
// PlayerExpFriendMax ...
type PlayerExpFriendMax struct {
Before int `json:"before"`
After int `json:"after"`
}
// PlayerExpLpMax ...
type PlayerExpLpMax struct {
Before int `json:"before"`
After int `json:"after"`
}
// BaseRewardInfo ...
type BaseRewardInfo struct {
PlayerExp int `json:"player_exp"`
PlayerExpUnitMax PlayerExpUnitMax `json:"player_exp_unit_max"`
PlayerExpFriendMax PlayerExpFriendMax `json:"player_exp_friend_max"`
PlayerExpLpMax PlayerExpLpMax `json:"player_exp_lp_max"`
GameCoin int `json:"game_coin"`
GameCoinRewardBoxFlag bool `json:"game_coin_reward_box_flag"`
SocialPoint int `json:"social_point"`
}
// LiveClear ...
type LiveClear struct {
AddType int `json:"add_type"`
Amount int `json:"amount"`
ItemCategoryID int `json:"item_category_id"`
UnitID int `json:"unit_id"`
UnitOwningUserID int64 `json:"unit_owning_user_id"`
IsSupportMember bool `json:"is_support_member"`
Exp int `json:"exp"`
NextExp int `json:"next_exp"`
MaxHp int `json:"max_hp"`
Level int `json:"level"`
MaxLevel int `json:"max_level"`
LevelLimitID int `json:"level_limit_id"`
SkillLevel int `json:"skill_level"`
Rank int `json:"rank"`
Love int `json:"love"`
IsRankMax bool `json:"is_rank_max"`
IsLevelMax bool `json:"is_level_max"`
IsLoveMax bool `json:"is_love_max"`
IsSigned bool `json:"is_signed"`
NewUnitFlag bool `json:"new_unit_flag"`
RewardBoxFlag bool `json:"reward_box_flag"`
UnitSkillExp int `json:"unit_skill_exp"`
DisplayRank int `json:"display_rank"`
UnitRemovableSkillCapacity int `json:"unit_removable_skill_capacity"`
RemovableSkillIds []any `json:"removable_skill_ids"`
}
// LiveRank ...
type LiveRank struct {
AddType int `json:"add_type"`
Amount int `json:"amount"`
ItemCategoryID int `json:"item_category_id"`
UnitID int `json:"unit_id"`
UnitOwningUserID int64 `json:"unit_owning_user_id"`
IsSupportMember bool `json:"is_support_member"`
Exp int `json:"exp"`
NextExp int `json:"next_exp"`
MaxHp int `json:"max_hp"`
Level int `json:"level"`
MaxLevel int `json:"max_level"`
LevelLimitID int `json:"level_limit_id"`
SkillLevel int `json:"skill_level"`
Rank int `json:"rank"`
Love int `json:"love"`
IsRankMax bool `json:"is_rank_max"`
IsLevelMax bool `json:"is_level_max"`
IsLoveMax bool `json:"is_love_max"`
IsSigned bool `json:"is_signed"`
NewUnitFlag bool `json:"new_unit_flag"`
RewardBoxFlag bool `json:"reward_box_flag"`
UnitSkillExp int `json:"unit_skill_exp"`
DisplayRank int `json:"display_rank"`
UnitRemovableSkillCapacity int `json:"unit_removable_skill_capacity"`
RemovableSkillIds []any `json:"removable_skill_ids"`
}
// RewardUnitList ...
type RewardUnitList struct {
LiveClear []LiveClear `json:"live_clear"`
LiveRank []LiveRank `json:"live_rank"`
LiveCombo []any `json:"live_combo"`
}
// Rewards ...
type Rewards struct {
Rarity int `json:"rarity"`
ItemID int `json:"item_id"`
AddType int `json:"add_type"`
Amount int `json:"amount"`
ItemCategoryID int `json:"item_category_id"`
RewardBoxFlag bool `json:"reward_box_flag"`
InsertDate string `json:"insert_date"`
}
// EffortPoint ...
type EffortPoint struct {
LiveEffortPointBoxSpecID int `json:"live_effort_point_box_spec_id"`
Capacity int `json:"capacity"`
Before int `json:"before"`
After int `json:"after"`
Rewards []Rewards `json:"rewards"`
}
// PlayRewardUnitList ...
type PlayRewardUnitList struct {
ID int `xorm:"id pk autoincr" json:"-"`
UserDeckID int `xorm:"user_deck_id" json:"-"`
UnitOwningUserID int `xorm:"unit_owning_user_id" json:"unit_owning_user_id"`
UnitID int `xorm:"unit_id" json:"unit_id"`
Position int `xorm:"position" json:"position"`
Level int `xorm:"level" json:"level"`
LevelLimitID int `xorm:"level_limit_id" json:"level_limit_id"`
DisplayRank int `xorm:"display_rank" json:"display_rank"`
Love int `xorm:"love" json:"love"`
UnitSkillLevel int `xorm:"unit_skill_level" json:"unit_skill_level"`
IsRankMax bool `xorm:"is_rank_max" json:"is_rank_max"`
IsLoveMax bool `xorm:"is_love_max" json:"is_love_max"`
IsLevelMax bool `xorm:"is_level_max" json:"is_level_max"`
IsSigned bool `xorm:"is_signed" json:"is_signed"`
BeforeLove int `xorm:"before_love" json:"before_love"`
MaxLove int `xorm:"max_love" json:"max_love"`
InsertData int64 `xorm:"insert_date" json:"-"`
}
// BeforeUserInfo ...
type BeforeUserInfo struct {
Level int `json:"level"`
Exp int `json:"exp"`
PreviousExp int `json:"previous_exp"`
NextExp int `json:"next_exp"`
GameCoin int `json:"game_coin"`
SnsCoin int `json:"sns_coin"`
FreeSnsCoin int `json:"free_sns_coin"`
PaidSnsCoin int `json:"paid_sns_coin"`
SocialPoint int `json:"social_point"`
UnitMax int `json:"unit_max"`
WaitingUnitMax int `json:"waiting_unit_max"`
CurrentEnergy int `json:"current_energy"`
EnergyMax int `json:"energy_max"`
TrainingEnergy int `json:"training_energy"`
TrainingEnergyMax int `json:"training_energy_max"`
EnergyFullTime string `json:"energy_full_time"`
LicenseLiveEnergyRecoverlyTime int `json:"license_live_energy_recoverly_time"`
FriendMax int `json:"friend_max"`
TutorialState int `json:"tutorial_state"`
OverMaxEnergy int `json:"over_max_energy"`
UnlockRandomLiveMuse int `json:"unlock_random_live_muse"`
UnlockRandomLiveAqours int `json:"unlock_random_live_aqours"`
}
// AfterUserInfo ...
type AfterUserInfo struct {
Level int `json:"level"`
Exp int `json:"exp"`
PreviousExp int `json:"previous_exp"`
NextExp int `json:"next_exp"`
GameCoin int `json:"game_coin"`
SnsCoin int `json:"sns_coin"`
FreeSnsCoin int `json:"free_sns_coin"`
PaidSnsCoin int `json:"paid_sns_coin"`
SocialPoint int `json:"social_point"`
UnitMax int `json:"unit_max"`
WaitingUnitMax int `json:"waiting_unit_max"`
CurrentEnergy int `json:"current_energy"`
EnergyMax int `json:"energy_max"`
TrainingEnergy int `json:"training_energy"`
TrainingEnergyMax int `json:"training_energy_max"`
EnergyFullTime string `json:"energy_full_time"`
LicenseLiveEnergyRecoverlyTime int `json:"license_live_energy_recoverly_time"`
FriendMax int `json:"friend_max"`
TutorialState int `json:"tutorial_state"`
OverMaxEnergy int `json:"over_max_energy"`
UnlockRandomLiveMuse int `json:"unlock_random_live_muse"`
UnlockRandomLiveAqours int `json:"unlock_random_live_aqours"`
}
// NextLevelInfo ...
type NextLevelInfo struct {
Level int `json:"level"`
FromExp int `json:"from_exp"`
}
// GoalAccompInfo ...
type GoalAccompInfo struct {
AchievedIds []any `json:"achieved_ids"`
Rewards []any `json:"rewards"`
}
// RewardRankInfo ...
type RewardRankInfo struct {
BeforeClassRankID int `json:"before_class_rank_id"`
AfterClassRankID int `json:"after_class_rank_id"`
RankUpDate string `json:"rank_up_date"`
}
// ClassSystem ...
type ClassSystem struct {
RankInfo RewardRankInfo `json:"rank_info"`
CompleteFlag bool `json:"complete_flag"`
IsOpened bool `json:"is_opened"`
IsVisible bool `json:"is_visible"`
}
// PlayRewardList ...
type PlayRewardList struct {
ItemID int `json:"item_id"`
AddType int `json:"add_type"`
Amount int `json:"amount"`
ItemCategoryID int `json:"item_category_id"`
RewardBoxFlag bool `json:"reward_box_flag"`
}
// AccomplishedAchievementList ...
type AccomplishedAchievementList struct {
AchievementID int `json:"achievement_id"`
Count int `json:"count"`
IsAccomplished bool `json:"is_accomplished"`
InsertDate string `json:"insert_date"`
EndDate string `json:"end_date"`
RemainingTime string `json:"remaining_time"`
IsNew bool `json:"is_new"`
ForDisplay bool `json:"for_display"`
IsLocked bool `json:"is_locked"`
OpenConditionString string `json:"open_condition_string"`
AccomplishID string `json:"accomplish_id"`
RewardList []PlayRewardList `json:"reward_list"`
}
// RewardUnitSupportList ...
type RewardUnitSupportList struct {
UnitID int `json:"unit_id"`
Amount int `json:"amount"`
}
// RewardRes ...
type RewardRes struct {
LiveInfo []RewardLiveInfo `json:"live_info"`
Rank int `json:"rank"`
ComboRank int `json:"combo_rank"`
TotalLove int `json:"total_love"`
IsHighScore bool `json:"is_high_score"`
HiScore int `json:"hi_score"`
BaseRewardInfo BaseRewardInfo `json:"base_reward_info"`
RewardUnitList RewardUnitList `json:"reward_unit_list"`
UnlockedSubscenarioIds []any `json:"unlocked_subscenario_ids"`
UnlockedMultiUnitScenarioIds []any `json:"unlocked_multi_unit_scenario_ids"`
EffortPoint []EffortPoint `json:"effort_point"`
IsEffortPointVisible bool `json:"is_effort_point_visible"`
LimitedEffortBox []any `json:"limited_effort_box"`
UnitList []PlayRewardUnitList `json:"unit_list"`
BeforeUserInfo BeforeUserInfo `json:"before_user_info"`
AfterUserInfo AfterUserInfo `json:"after_user_info"`
NextLevelInfo []NextLevelInfo `json:"next_level_info"`
GoalAccompInfo GoalAccompInfo `json:"goal_accomp_info"`
SpecialRewardInfo []any `json:"special_reward_info"`
EventInfo []any `json:"event_info"`
DailyRewardInfo []any `json:"daily_reward_info"`
CanSendFriendRequest bool `json:"can_send_friend_request"`
UsingBuffInfo []any `json:"using_buff_info"`
ClassSystem ClassSystem `json:"class_system"`
AccomplishedAchievementList []AccomplishedAchievementList `json:"accomplished_achievement_list"`
UnaccomplishedAchievementCnt int `json:"unaccomplished_achievement_cnt"`
AddedAchievementList []any `json:"added_achievement_list"`
MuseumInfo Museum `json:"museum_info"`
UnitSupportList []RewardUnitSupportList `json:"unit_support_list"`
ServerTimestamp int64 `json:"server_timestamp"`
PresentCnt int `json:"present_cnt"`
}
// RewardResp ...
type RewardResp struct {
ResponseData RewardRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// LiveSeInfoRes ...
type LiveSeInfoRes struct {
LiveSeList []int `json:"live_se_list"`
}
// LiveSeInfoResp ...
type LiveSeInfoResp struct {
Result LiveSeInfoRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
// LiveIconInfoRes ...
type LiveIconInfoRes struct {
LiveNotesIconList []int `json:"live_notes_icon_list"`
}
// LiveIconInfoResp ...
type LiveIconInfoResp struct {
Result LiveIconInfoRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
+19
View File
@@ -0,0 +1,19 @@
package model
// LoginRes ...
type LoginRes struct {
AuthorizeToken string `json:"authorize_token"`
UserId int `json:"user_id"`
ReviewVersion string `json:"review_version"`
ServerTimestamp int64 `json:"server_timestamp"`
IdfaEnabled bool `json:"idfa_enabled"`
SkipLoginNews bool `json:"skip_login_news"`
AdultFlag int `json:"adult_flag"`
}
// LoginResp ...
type LoginResp struct {
ResponseData LoginRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
+9
View File
@@ -0,0 +1,9 @@
package model
// MarathonInfoResp ...
type MarathonInfoResp struct {
Result []any `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
+55
View File
@@ -0,0 +1,55 @@
package model
// MultiUnitScenarioChapterList ...
type MultiUnitScenarioChapterList struct {
MultiUnitScenarioID int `json:"multi_unit_scenario_id"`
Chapter int `json:"chapter"`
Status int `json:"status"`
}
// MultiUnitScenarioStatusList ...
type MultiUnitScenarioStatusList struct {
MultiUnitID int `json:"multi_unit_id"`
Status int `json:"status"`
MultiUnitScenarioBtnAsset string `json:"multi_unit_scenario_btn_asset"`
OpenDate string `json:"open_date"`
ChapterList []MultiUnitScenarioChapterList `json:"chapter_list"`
}
// MultiUnitScenarioStatusRes ...
type MultiUnitScenarioStatusRes struct {
MultiUnitScenarioStatusList []MultiUnitScenarioStatusList `json:"multi_unit_scenario_status_list"`
UnlockedMultiUnitScenarioIds []any `json:"unlocked_multi_unit_scenario_ids"`
}
// MultiUnitScenarioStatusResp ...
type MultiUnitScenarioStatusResp struct {
Result MultiUnitScenarioStatusRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
// MultiUnitStartUpResp ...
type MultiUnitStartUpResp struct {
ResponseData MultiUnitStartUpRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// MultiUnitStartUpRes ...
type MultiUnitStartUpRes struct {
MultiUnitScenarioID int `json:"multi_unit_scenario_id"`
ScenarioAdjustment int `json:"scenario_adjustment"`
ServerTimestamp int64 `json:"server_timestamp"`
}
// MultiUnitStartUpReq ...
type MultiUnitStartUpReq struct {
Module string `json:"module"`
Action string `json:"action"`
TimeStamp int `json:"timeStamp"`
Mgd int `json:"mgd"`
MultiUnitScenarioID int `json:"multi_unit_scenario_id"`
CommandNum string `json:"commandNum"`
}
+40
View File
@@ -0,0 +1,40 @@
package model
// MuseumResp ...
type MuseumResp struct {
ResponseData MuseumRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// MuseumParameter ...
type MuseumParameter struct {
Smile int `json:"smile"`
Pure int `json:"pure"`
Cool int `json:"cool"`
}
// Museum ...
type Museum struct {
Parameter MuseumParameter `json:"parameter"`
ContentsIDList []int `json:"contents_id_list"`
}
// MuseumRes ...
type MuseumRes struct {
MuseumInfo Museum `json:"museum_info"`
ServerTimestamp int64 `json:"server_timestamp"`
}
// MuseumInfoRes ...
type MuseumInfoRes struct {
MuseumInfo Museum `json:"museum_info"`
}
// MuseumInfoResp ...
type MuseumInfoResp struct {
Result MuseumInfoRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
+14
View File
@@ -0,0 +1,14 @@
package model
// SpecialCutinRes ...
type SpecialCutinRes struct {
SpecialCutinList []any `json:"special_cutin_list"`
}
// SpecialCutinResp ...
type SpecialCutinResp struct {
Result SpecialCutinRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
+58
View File
@@ -0,0 +1,58 @@
package model
// NoticeFriendVarietyResp ...
type NoticeFriendVarietyResp struct {
ResponseData NoticeFriendVarietyRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// NoticeFriendVarietyRes ...
type NoticeFriendVarietyRes struct {
ItemCount int `json:"item_count"`
NoticeList []any `json:"notice_list"`
ServerTimestamp int64 `json:"server_timestamp"`
}
// NoticeFriendGreetingResp ...
type NoticeFriendGreetingResp struct {
ResponseData NoticeFriendGreetingRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// NoticeFriendGreetingRes ...
type NoticeFriendGreetingRes struct {
NextId int `json:"next_id"`
NoticeList []any `json:"notice_list"`
ServerTimestamp int64 `json:"server_timestamp"`
}
// NoticeUserGreetingResp ...
type NoticeUserGreetingResp struct {
ResponseData NoticeUserGreetingRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// NoticeUserGreetingRes ...
type NoticeUserGreetingRes struct {
ItemCount int `json:"item_count"`
HasNext bool `json:"has_next"`
NoticeList []any `json:"notice_list"`
ServerTimestamp int64 `json:"server_timestamp"`
}
// NoticeMarqueeRes ...
type NoticeMarqueeRes struct {
ItemCount int `json:"item_count"`
MarqueeList []any `json:"marquee_list"`
}
// NoticeMarqueeResp ...
type NoticeMarqueeResp struct {
Result NoticeMarqueeRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
+154
View File
@@ -0,0 +1,154 @@
package model
// RestrictionInfo ...
type RestrictionInfo struct {
Restricted bool `json:"restricted"`
}
// UnderAgeInfo ...
type UnderAgeInfo struct {
BirthSet bool `json:"birth_set"`
HasLimit bool `json:"has_limit"`
LimitAmount any `json:"limit_amount"`
MonthUsed int `json:"month_used"`
}
// SnsProductItemList ...
type SnsProductItemList struct {
ItemID int `json:"item_id"`
AddType int `json:"add_type"`
Amount int `json:"amount"`
IsFreebie bool `json:"is_freebie"`
}
// SnsProductList ...
type SnsProductList struct {
ProductID string `json:"product_id"`
Name string `json:"name"`
Price int `json:"price"`
CanBuy bool `json:"can_buy"`
ProductType int `json:"product_type"`
ItemList []SnsProductItemList `json:"item_list"`
}
// ProductItemList ...
type ProductItemList struct {
ItemID int `json:"item_id"`
AddType int `json:"add_type"`
Amount int `json:"amount"`
IsFreebie bool `json:"is_freebie"`
IsRankMax bool `json:"is_rank_max,omitempty"`
}
// LimitStatus ...
type LimitStatus struct {
TermStartDate string `json:"term_start_date"`
RemainingTime string `json:"remaining_time"`
RemainingCount int `json:"remaining_count"`
}
// ProductList ...
type ProductList struct {
ProductID string `json:"product_id"`
Name string `json:"name"`
BannerImgAsset string `json:"banner_img_asset"`
Price int `json:"price"`
CanBuy bool `json:"can_buy"`
ProductType int `json:"product_type"`
AnnounceURL string `json:"announce_url"`
ConfirmURL string `json:"confirm_url"`
ItemList []ProductItemList `json:"item_list"`
LimitStatus LimitStatus `json:"limit_status"`
}
// SubscriptionItemList ...
type SubscriptionItemList struct {
ItemID int `json:"item_id"`
AddType int `json:"add_type"`
Amount int `json:"amount"`
IsFreebie bool `json:"is_freebie"`
}
// RewardList ...
type RewardList struct {
ItemID int `json:"item_id"`
AddType int `json:"add_type"`
Amount int `json:"amount"`
}
// Items ...
type Items struct {
Seq int `json:"seq"`
RewardList []RewardList `json:"reward_list"`
}
// LicenseInfo ...
type LicenseInfo struct {
Name string `json:"name"`
Items []Items `json:"items"`
}
// UserStatus ...
type UserStatus struct {
IsLicensed bool `json:"is_licensed"`
}
// SubscriptionStatus ...
type SubscriptionStatus struct {
LicenseID int `json:"license_id"`
LicenseType int `json:"license_type"`
LicenseInfo LicenseInfo `json:"license_info,omitempty"`
UserStatus UserStatus `json:"user_status"`
PurchaseCount int `json:"purchase_count"`
BadgeFlag bool `json:"badge_flag"`
}
// SubscriptionList ...
type SubscriptionList struct {
ProductID string `json:"product_id"`
Name string `json:"name"`
BannerImgAsset string `json:"banner_img_asset"`
Price int `json:"price"`
CanBuy bool `json:"can_buy"`
ProductType int `json:"product_type"`
ProductURL string `json:"product_url"`
ItemList []SubscriptionItemList `json:"item_list"`
LimitStatus LimitStatus `json:"limit_status"`
SubscriptionStatus SubscriptionStatus `json:"subscription_status"`
}
// ProductListRes ...
type ProductListRes struct {
RestrictionInfo RestrictionInfo `json:"restriction_info"`
UnderAgeInfo UnderAgeInfo `json:"under_age_info"`
SnsProductList []SnsProductList `json:"sns_product_list"`
ProductList []ProductList `json:"product_list"`
SubscriptionList []SubscriptionList `json:"subscription_list"`
ShowPointShop bool `json:"show_point_shop"`
}
// ProductListResp ...
type ProductListResp struct {
Result ProductListRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
// ProductResp ...
type ProductResp struct {
ResponseData ProductRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// ProductRes ...
type ProductRes struct {
RestrictionInfo RestrictionInfo `json:"restriction_info"`
UnderAgeInfo UnderAgeInfo `json:"under_age_info"`
SnsProductList []any `json:"sns_product_list"`
ProductList []any `json:"product_list"`
SubscriptionList []any `json:"subscription_list"`
ShowPointShop bool `json:"show_point_shop"`
ServerTimestamp int64 `json:"server_timestamp"`
}
+18
View File
@@ -0,0 +1,18 @@
package model
// PersonalNoticeResp ...
type PersonalNoticeResp struct {
ResponseData PersonalNoticeRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// PersonalNoticeRes ...
type PersonalNoticeRes struct {
HasNotice bool `json:"has_notice"`
NoticeID int `json:"notice_id"`
Type int `json:"type"`
Title string `json:"title"`
Contents string `json:"contents"`
ServerTimestamp int64 `json:"server_timestamp"`
}
+8
View File
@@ -0,0 +1,8 @@
package model
// AwardSetResp ...
type ProfileRegisterResp struct {
ResponseData []any `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
+98
View File
@@ -0,0 +1,98 @@
package model
// ScenarioStatusList ...
type ScenarioStatusList struct {
ScenarioID int `json:"scenario_id"`
Status int `json:"status"`
}
// ScenarioStatusRes ...
type ScenarioStatusRes struct {
ScenarioStatusList []ScenarioStatusList `json:"scenario_status_list"`
}
// ScenarioStatusResp ...
type ScenarioStatusResp struct {
Result ScenarioStatusRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
// SubscenarioStatusList ...
type SubscenarioStatusList struct {
SubscenarioID int `json:"subscenario_id"`
Status int `json:"status"`
}
// SubscenarioStatusRes ...
type SubscenarioStatusRes struct {
SubscenarioStatusList []SubscenarioStatusList `json:"subscenario_status_list"`
UnlockedSubscenarioIds []any `json:"unlocked_subscenario_ids"`
}
// SubscenarioStatusResp ...
type SubscenarioStatusResp struct {
Result SubscenarioStatusRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
// EventScenarioChapterList ...
type EventScenarioChapterList struct {
EventScenarioID int `json:"event_scenario_id"`
Chapter int `json:"chapter"`
ChapterAsset string `json:"chapter_asset,omitempty"`
Status int `json:"status"`
OpenFlashFlag int `json:"open_flash_flag"`
IsReward bool `json:"is_reward"`
CostType int `json:"cost_type"`
ItemID int `json:"item_id"`
Amount int `json:"amount"`
}
// EventScenarioList ...
type EventScenarioList struct {
EventID int `json:"event_id"`
EventScenarioBtnAsset string `json:"event_scenario_btn_asset"`
OpenDate string `json:"open_date"`
ChapterList []EventScenarioChapterList `json:"chapter_list"`
}
// EventScenarioStatusRes ...
type EventScenarioStatusRes struct {
EventScenarioList []EventScenarioList `json:"event_scenario_list"`
}
// EventScenarioStatusResp ...
type EventScenarioStatusResp struct {
Result EventScenarioStatusRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
// ScenarioResp ...
type ScenarioResp struct {
ResponseData ScenarioRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// ScenarioRes ...
type ScenarioRes struct {
ScenarioID int `json:"scenario_id"`
ScenarioAdjustment int `json:"scenario_adjustment"`
ServerTimestamp int64 `json:"server_timestamp"`
}
// ScenarioReq ...
type ScenarioReq struct {
Module string `json:"module"`
Action string `json:"action"`
TimeStamp int `json:"timeStamp"`
Mgd int `json:"mgd"`
CommandNum string `json:"commandNum"`
ScenarioID int `json:"scenario_id"`
}
+25
View File
@@ -0,0 +1,25 @@
package model
// SubScenarioResp ...
type SubScenarioResp struct {
ResponseData SubScenarioRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// SubScenarioRes ...
type SubScenarioRes struct {
SubscenarioID int `json:"subscenario_id"`
ScenarioAdjustment int `json:"scenario_adjustment"`
ServerTimestamp int64 `json:"server_timestamp"`
}
// SubScenarioReq ...
type SubScenarioReq struct {
Module string `json:"module"`
Action string `json:"action"`
TimeStamp int `json:"timeStamp"`
SubscenarioID int `json:"subscenario_id"`
Mgd int `json:"mgd"`
CommandNum string `json:"commandNum"`
}
+200
View File
@@ -0,0 +1,200 @@
package model
// UnitData ...
type UnitData struct {
UnitOwningUserID int `xorm:"unit_owning_user_id pk autoincr" json:"unit_owning_user_id"`
UserID int `xorm:"user_id" json:"-"`
UnitID int `xorm:"unit_id" json:"unit_id"`
Exp int `xorm:"exp" json:"exp"`
NextExp int `xorm:"next_exp" json:"next_exp"`
Level int `xorm:"level" json:"level"`
MaxLevel int `xorm:"max_level" json:"max_level"`
LevelLimitID int `xorm:"level_limit_id" json:"level_limit_id"`
Rank int `xorm:"rank" json:"rank"`
MaxRank int `xorm:"max_rank" json:"max_rank"`
Love int `xorm:"love" json:"love"`
MaxLove int `xorm:"max_love" json:"max_love"`
UnitSkillExp int `xorm:"unit_skill_exp" json:"unit_skill_exp"`
UnitSkillLevel int `xorm:"unit_skill_level" json:"unit_skill_level"`
MaxHp int `xorm:"max_hp" json:"max_hp"`
UnitRemovableSkillCapacity int `xorm:"unit_removable_skill_capacity" json:"unit_removable_skill_capacity"`
FavoriteFlag bool `xorm:"favorite_flag" json:"favorite_flag"`
DisplayRank int `xorm:"display_rank" json:"display_rank"`
IsRankMax bool `xorm:"is_rank_max" json:"is_rank_max"`
IsLoveMax bool `xorm:"is_love_max" json:"is_love_max"`
IsLevelMax bool `xorm:"is_level_max" json:"is_level_max"`
IsSigned bool `xorm:"is_signed" json:"is_signed"`
IsSkillLevelMax bool `xorm:"is_skill_level_max" json:"is_skill_level_max"`
IsRemovableSkillCapacityMax bool `xorm:"is_removable_skill_capacity_max" json:"is_removable_skill_capacity_max"`
InsertDate string `xorm:"insert_date" json:"insert_date"`
}
// UserDeckData ...
type UserDeckData struct {
ID int `xorm:"id pk autoincr"`
DeckID int `xorm:"deck_id"`
MainFlag int `xorm:"main_flag"`
DeckName string `xorm:"deck_name"`
UserID int `xorm:"user_id"`
InsertDate int64 `xorm:"insert_date"`
}
// UnitDeckData ...
type UnitDeckData struct {
ID int `xorm:"id pk autoincr" json:"-"`
UserDeckID int `xorm:"user_deck_id" json:"-"`
UnitOwningUserID int `xorm:"unit_owning_user_id" json:"unit_owning_user_id"`
UnitID int `xorm:"unit_id" json:"unit_id"`
Position int `xorm:"position" json:"position"`
Level int `xorm:"level" json:"level"`
LevelLimitID int `xorm:"level_limit_id" json:"level_limit_id"`
DisplayRank int `xorm:"display_rank" json:"display_rank"`
Love int `xorm:"love" json:"love"`
UnitSkillLevel int `xorm:"unit_skill_level" json:"unit_skill_level"`
IsRankMax bool `xorm:"is_rank_max" json:"is_rank_max"`
IsLoveMax bool `xorm:"is_love_max" json:"is_love_max"`
IsLevelMax bool `xorm:"is_level_max" json:"is_level_max"`
IsSigned bool `xorm:"is_signed" json:"is_signed"`
BeforeLove int `xorm:"before_love" json:"before_love"`
MaxLove int `xorm:"max_love" json:"max_love"`
InsertData int64 `xorm:"insert_date" json:"-"`
}
// DifficultyRes ...
type DifficultyRes struct {
Difficulty int `json:"difficulty"`
ClearCnt int `json:"clear_cnt"`
}
// DifficultyResp ...
type DifficultyResp struct {
Result []DifficultyRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
// LoveResp ...
type LoveResp struct {
Result []any `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
// AccessoryInfo ...
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"`
}
// ProfileUserInfo ...
type ProfileUserInfo 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"`
InviteCode string `json:"invite_code"`
ElapsedTimeFromLogin string `json:"elapsed_time_from_login"`
Introduction string `json:"introduction"`
}
// CenterUnitInfo ...
type CenterUnitInfo struct {
UnitOwningUserID int `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 Costume `json:"costume"`
TotalSmile int `json:"total_smile"`
TotalCute int `json:"total_cute"`
TotalCool int `json:"total_cool"`
TotalHp int `json:"total_hp"`
}
// NaviUnitInfo ...
type NaviUnitInfo struct {
UnitOwningUserID int `json:"unit_owning_user_id"`
UnitID int `json:"unit_id"`
Exp int `json:"exp"`
NextExp int `json:"next_exp"`
Level int `json:"level"`
MaxLevel int `json:"max_level"`
LevelLimitID int `json:"level_limit_id"`
Rank int `json:"rank"`
MaxRank int `json:"max_rank"`
Love int `json:"love"`
MaxLove int `json:"max_love"`
UnitSkillExp int `json:"unit_skill_exp"`
UnitSkillLevel int `json:"unit_skill_level"`
MaxHp int `json:"max_hp"`
UnitRemovableSkillCapacity int `json:"unit_removable_skill_capacity"`
FavoriteFlag bool `json:"favorite_flag"`
DisplayRank int `json:"display_rank"`
IsRankMax bool `json:"is_rank_max"`
IsLoveMax bool `json:"is_love_max"`
IsLevelMax bool `json:"is_level_max"`
IsSigned bool `json:"is_signed"`
IsSkillLevelMax bool `json:"is_skill_level_max"`
IsRemovableSkillCapacityMax bool `json:"is_removable_skill_capacity_max"`
InsertDate string `json:"insert_date"`
TotalSmile int `json:"total_smile"`
TotalCute int `json:"total_cute"`
TotalCool int `json:"total_cool"`
TotalHp int `json:"total_hp"`
RemovableSkillIds []int `json:"removable_skill_ids"`
}
// ProfileRes ...
type ProfileRes struct {
UserInfo ProfileUserInfo `json:"user_info"`
CenterUnitInfo CenterUnitInfo `json:"center_unit_info"`
NaviUnitInfo NaviUnitInfo `json:"navi_unit_info"`
IsAlliance bool `json:"is_alliance"`
FriendStatus int `json:"friend_status"`
SettingAwardID int `json:"setting_award_id"`
SettingBackgroundID int `json:"setting_background_id"`
}
// ProfileResp ...
type ProfileResp struct {
Result ProfileRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
+78
View File
@@ -0,0 +1,78 @@
package model
// TopInfoLicenseInfo ...
type TopInfoLicenseInfo struct {
LicenseList []any `json:"license_list"`
LicensedInfo []any `json:"licensed_info"`
ExpiredInfo []any `json:"expired_info"`
BadgeFlag bool `json:"badge_flag"`
}
// TopInfoRes ...
type TopInfoRes struct {
FriendActionCnt int `json:"friend_action_cnt"`
FriendGreetCnt int `json:"friend_greet_cnt"`
FriendVarietyCnt int `json:"friend_variety_cnt"`
FriendNewCnt int `json:"friend_new_cnt"`
PresentCnt int `json:"present_cnt"`
SecretBoxBadgeFlag bool `json:"secret_box_badge_flag"`
ServerDatetime string `json:"server_datetime"`
ServerTimestamp int64 `json:"server_timestamp"`
NoticeFriendDatetime string `json:"notice_friend_datetime"`
NoticeMailDatetime string `json:"notice_mail_datetime"`
FriendsApprovalWaitCnt int `json:"friends_approval_wait_cnt"`
FriendsRequestCnt int `json:"friends_request_cnt"`
IsTodayBirthday bool `json:"is_today_birthday"`
LicenseInfo TopInfoLicenseInfo `json:"license_info"`
UsingBuffInfo []any `json:"using_buff_info"`
IsKlabIDTaskFlag bool `json:"is_klab_id_task_flag"`
KlabIDTaskCanSync bool `json:"klab_id_task_can_sync"`
HasUnreadAnnounce bool `json:"has_unread_announce"`
ExchangeBadgeCnt []int `json:"exchange_badge_cnt"`
AdFlag bool `json:"ad_flag"`
HasAdReward bool `json:"has_ad_reward"`
}
// TopInfoResp ...
type TopInfoResp struct {
Result TopInfoRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
// TopInfoOnceNotification ...
type TopInfoOnceNotification struct {
Push bool `json:"push"`
Lp bool `json:"lp"`
UpdateInfo bool `json:"update_info"`
Campaign bool `json:"campaign"`
Live bool `json:"live"`
Lbonus bool `json:"lbonus"`
Event bool `json:"event"`
Secretbox bool `json:"secretbox"`
Birthday bool `json:"birthday"`
}
// TopInfoOnceRes ...
type TopInfoOnceRes struct {
NewAchievementCnt int `json:"new_achievement_cnt"`
UnaccomplishedAchievementCnt int `json:"unaccomplished_achievement_cnt"`
LiveDailyRewardExist bool `json:"live_daily_reward_exist"`
TrainingEnergy int `json:"training_energy"`
TrainingEnergyMax int `json:"training_energy_max"`
Notification TopInfoOnceNotification `json:"notification"`
OpenArena bool `json:"open_arena"`
CostumeStatus bool `json:"costume_status"`
OpenAccessory bool `json:"open_accessory"`
ArenaSiSkillUniqueCheck bool `json:"arena_si_skill_unique_check"`
OpenV98 bool `json:"open_v98"`
}
// TopInfoOnceResp ...
type TopInfoOnceResp struct {
Result TopInfoOnceRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
+16
View File
@@ -0,0 +1,16 @@
package model
// TosResp ...
type TosResp struct {
ResponseData TosRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// TosResp ...
type TosRes struct {
TosID int `json:"tos_id"`
TosType int `json:"tos_type"`
IsAgreed bool `json:"is_agreed"`
ServerTimestamp int64 `json:"server_timestamp"`
}
+316
View File
@@ -0,0 +1,316 @@
package model
// AccessoryList ...
type AccessoryList struct {
AccessoryOwningUserID int `json:"accessory_owning_user_id" xorm:"accessory_owning_user_id"`
AccessoryID int `json:"accessory_id" xorm:"accessory_id"`
Exp int `json:"exp" xorm:"exp"`
NextExp int `json:"next_exp" xorm:"-"`
Level int `json:"level" xorm:"-"`
MaxLevel int `json:"max_level" xorm:"-"`
RankUpCount int `json:"rank_up_count" xorm:"-"`
FavoriteFlag bool `json:"favorite_flag" xorm:"-"`
}
// WearingInfo
type WearingInfo struct {
UnitOwningUserID int `json:"unit_owning_user_id" xorm:"unit_owning_user_id"`
AccessoryOwningUserID int `json:"accessory_owning_user_id" xorm:"accessory_owning_user_id"`
}
// UnitAccessoryAllResult ...
type UnitAccessoryAllResult struct {
AccessoryList []AccessoryList `json:"accessory_list"`
WearingInfo []WearingInfo `json:"wearing_info"`
EspecialCreateFlag bool `json:"especial_create_flag"`
}
// UnitAccessoryAllResp ...
type UnitAccessoryAllResp struct {
Result UnitAccessoryAllResult `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
// WearAccessoryReq ...
type WearAccessoryReq struct {
Module string `json:"module"`
Remove []Remove `json:"remove"`
Action string `json:"action"`
TimeStamp int `json:"timeStamp"`
Wear []Wear `json:"wear"`
Mgd int `json:"mgd"`
CommandNum string `json:"commandNum"`
}
// Remove ...
type Remove struct {
AccessoryOwningUserID int `json:"accessory_owning_user_id"`
UnitOwningUserID int `json:"unit_owning_user_id"`
}
// Wear ...
type Wear struct {
AccessoryOwningUserID int `json:"accessory_owning_user_id"`
UnitOwningUserID int `json:"unit_owning_user_id"`
}
// AccessoryWearData ...
type AccessoryWearData struct {
Id int `xorm:"id pk autoincr"`
AccessoryOwningUserID int `xorm:"accessory_owning_user_id"`
UnitOwningUserID int `xorm:"unit_owning_user_id"`
UserId string `xorm:"user_id"`
}
// AccessoryWearResp ...
type AccessoryWearResp struct {
ResponseData []any `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// SkillEquipReq ...
type SkillEquipReq struct {
Module string `json:"module"`
Remove []SkillRemove `json:"remove"`
Action string `json:"action"`
TimeStamp int `json:"timeStamp"`
Equip []SkillEquip `json:"equip"`
Mgd int `json:"mgd"`
CommandNum string `json:"commandNum"`
}
// SkillRemove ...
type SkillRemove struct {
UnitRemovableSkillID int `json:"unit_removable_skill_id"`
UnitOwningUserID int `json:"unit_owning_user_id"`
}
// SkillEquip ...
type SkillEquip struct {
UnitRemovableSkillID int `json:"unit_removable_skill_id"`
UnitOwningUserID int `json:"unit_owning_user_id"`
}
// SkillEquipCount ...
type SkillEquipCount struct {
UnitRemovableSkillId int `xorm:"unit_removable_skill_id"`
Count int `xorm:"ct"`
}
// SkillEquipData ...
type SkillEquipData struct {
Id int `xorm:"id pk autoincr"`
UnitRemovableSkillId int `xorm:"unit_removable_skill_id"`
UnitOwningUserID int `xorm:"unit_owning_user_id"`
UserId string `xorm:"user_id"`
}
// SkillEquipDetail ...
type SkillEquipDetail struct {
UnitRemovableSkillID int `json:"unit_removable_skill_id" xorm:"unit_removable_skill_id"`
}
// SkillEquipList ...
type SkillEquipList struct {
UnitOwningUserID int `json:"unit_owning_user_id"`
Detail []SkillEquipDetail `json:"detail"`
}
// SkillEquipResp ...
type SkillEquipResp struct {
ResponseData []any `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// SetDisplayRankResp ...
type SetDisplayRankResp struct {
ResponseData []any `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// SetDeckResp ...
type SetDeckResp struct {
ResponseData []any `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// Costume ...
type Costume struct {
UnitID int `json:"unit_id"`
IsRankMax bool `json:"is_rank_max"`
IsSigned bool `json:"is_signed"`
}
// Active ...
type Active struct {
UnitOwningUserID int `xorm:"unit_owning_user_id pk autoincr" json:"unit_owning_user_id"`
UserID int `xorm:"user_id" json:"-"`
UnitID int `xorm:"unit_id" json:"unit_id"`
Exp int `xorm:"exp" json:"exp"`
NextExp int `xorm:"next_exp" json:"next_exp"`
Level int `xorm:"level" json:"level"`
MaxLevel int `xorm:"max_level" json:"max_level"`
LevelLimitID int `xorm:"level_limit_id" json:"level_limit_id"`
Rank int `xorm:"rank" json:"rank"`
MaxRank int `xorm:"max_rank" json:"max_rank"`
Love int `xorm:"love" json:"love"`
MaxLove int `xorm:"max_love" json:"max_love"`
UnitSkillExp int `xorm:"unit_skill_exp" json:"unit_skill_exp"`
UnitSkillLevel int `xorm:"unit_skill_level" json:"unit_skill_level"`
MaxHp int `xorm:"max_hp" json:"max_hp"`
UnitRemovableSkillCapacity int `xorm:"unit_removable_skill_capacity" json:"unit_removable_skill_capacity"`
FavoriteFlag bool `xorm:"favorite_flag" json:"favorite_flag"`
DisplayRank int `xorm:"display_rank" json:"display_rank"`
IsRankMax bool `xorm:"is_rank_max" json:"is_rank_max"`
IsLoveMax bool `xorm:"is_love_max" json:"is_love_max"`
IsLevelMax bool `xorm:"is_level_max" json:"is_level_max"`
IsSigned bool `xorm:"is_signed" json:"is_signed"`
IsSkillLevelMax bool `xorm:"is_skill_level_max" json:"is_skill_level_max"`
IsRemovableSkillCapacityMax bool `xorm:"is_removable_skill_capacity_max" json:"is_removable_skill_capacity_max"`
InsertDate string `xorm:"insert_date" json:"insert_date"`
// Costume Costume `json:"costume,omitempty"`
}
// Waiting ...
type Waiting 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"`
MaxLevel int `json:"max_level"`
LevelLimitID int `json:"level_limit_id"`
Rank int `json:"rank"`
MaxRank int `json:"max_rank"`
Love int `json:"love"`
MaxLove int `json:"max_love"`
UnitSkillExp int `json:"unit_skill_exp"`
UnitSkillLevel int `json:"unit_skill_level"`
MaxHp int `json:"max_hp"`
UnitRemovableSkillCapacity int `json:"unit_removable_skill_capacity"`
FavoriteFlag bool `json:"favorite_flag"`
DisplayRank int `json:"display_rank"`
IsRankMax bool `json:"is_rank_max"`
IsLoveMax bool `json:"is_love_max"`
IsLevelMax bool `json:"is_level_max"`
IsSigned bool `json:"is_signed"`
IsSkillLevelMax bool `json:"is_skill_level_max"`
IsRemovableSkillCapacityMax bool `json:"is_removable_skill_capacity_max"`
InsertDate string `json:"insert_date"`
}
// UnitAllRes ...
type UnitAllRes struct {
Active []Active `json:"active"`
Waiting []Waiting `json:"waiting"`
}
// UnitAllResp ...
type UnitAllResp struct {
Result UnitAllRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
// UnitOwningUserIds ...
type UnitOwningUserIds struct {
Position int `json:"position"`
UnitOwningUserID int `json:"unit_owning_user_id"`
}
// UnitDeckInfoRes ...
type UnitDeckInfoRes struct {
UnitDeckID int `json:"unit_deck_id"`
MainFlag bool `json:"main_flag"`
DeckName string `json:"deck_name"`
UnitOwningUserIds []UnitOwningUserIds `json:"unit_owning_user_ids"`
}
// UnitDeckInfoResp ...
type UnitDeckInfoResp struct {
Result []UnitDeckInfoRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
// UnitSupportList ...
type UnitSupportList struct {
UnitID int `json:"unit_id"`
Amount int `json:"amount"`
}
// UnitSupportRes ...
type UnitSupportRes struct {
UnitSupportList []UnitSupportList `json:"unit_support_list"`
}
// UnitSupportResp ...
type UnitSupportResp struct {
Result UnitSupportRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
// OwningInfo ...
type OwningInfo struct {
UnitRemovableSkillID int `json:"unit_removable_skill_id"`
TotalAmount int `json:"total_amount"`
EquippedAmount int `json:"equipped_amount"`
InsertDate string `json:"insert_date"`
}
// RemovableSkillRes ...
type RemovableSkillRes struct {
OwningInfo []OwningInfo `json:"owning_info"`
EquipmentInfo map[int]any `json:"equipment_info"`
}
// RemovableSkillResp ...
type RemovableSkillResp struct {
Result RemovableSkillRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
// UnitDeckReq ...
type UnitDeckReq struct {
Module string `json:"module"`
UnitDeckList []UnitDeckList `json:"unit_deck_list"`
Action string `json:"action"`
Mgd int `json:"mgd"`
}
// UnitDeckDetail ...
type UnitDeckDetail struct {
Position int `json:"position"`
UnitOwningUserID int `json:"unit_owning_user_id"`
}
// UnitDeckList ...
type UnitDeckList struct {
UnitDeckDetail []UnitDeckDetail `json:"unit_deck_detail"`
UnitDeckID int `json:"unit_deck_id"`
MainFlag int `json:"main_flag"`
DeckName string `json:"deck_name"`
}
// DeckNameReq ...
type DeckNameReq struct {
Module string `json:"module"`
UnitDeckID int `json:"unit_deck_id"`
Action string `json:"action"`
TimeStamp int `json:"timeStamp"`
Mgd int `json:"mgd"`
CommandNum string `json:"commandNum"`
DeckName string `json:"deck_name"`
}
+48
View File
@@ -0,0 +1,48 @@
package model
// UserNaviResp ...
type UserNaviChangeResp struct {
ResponseData []any `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// UserNameChangeResp ...
type UserNameChangeResp struct {
ResponseData UserNameChangeRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// UserNameChangeRes ...
type UserNameChangeRes struct {
BeforeName string `json:"before_name"`
AfterName string `json:"after_name"`
ServerTimestamp int64 `json:"server_timestamp"`
}
// User ...
type User struct {
UserID int `json:"user_id"`
UnitOwningUserID int `json:"unit_owning_user_id"`
}
// UserNaviRes ...
type UserNaviRes struct {
User User `json:"user"`
}
// UserNaviResp ...
type UserNaviResp struct {
Result UserNaviRes `json:"result"`
Status int `json:"status"`
CommandNum bool `json:"commandNum"`
TimeStamp int64 `json:"timeStamp"`
}
// NotificationResp ...
type NotificationResp struct {
ResponseData []any `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
+59
View File
@@ -0,0 +1,59 @@
package model
// UserInfoResp ...
type UserInfoResp struct {
ResponseData UserInfoRes `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
// UserInfoRes ...
type UserInfoRes struct {
User UserInfo `json:"user"`
Birth Birth `json:"birth"`
ServerTimestamp int64 `json:"server_timestamp"`
}
// LpRecoveryItem ...
type LpRecoveryItem struct {
ItemID int `json:"item_id"`
Amount int `json:"amount"`
}
// UserInfo ...
type UserInfo struct {
UserID int `json:"user_id"`
Name string `json:"name"`
Level int `json:"level"`
Exp int `json:"exp"`
PreviousExp int `json:"previous_exp"`
NextExp int `json:"next_exp"`
GameCoin int `json:"game_coin"`
SnsCoin int `json:"sns_coin"`
FreeSnsCoin int `json:"free_sns_coin"`
PaidSnsCoin int `json:"paid_sns_coin"`
SocialPoint int `json:"social_point"`
UnitMax int `json:"unit_max"`
WaitingUnitMax int `json:"waiting_unit_max"`
EnergyMax int `json:"energy_max"`
EnergyFullTime string `json:"energy_full_time"`
LicenseLiveEnergyRecoverlyTime int `json:"license_live_energy_recoverly_time"`
EnergyFullNeedTime int `json:"energy_full_need_time"`
OverMaxEnergy int `json:"over_max_energy"`
TrainingEnergy int `json:"training_energy"`
TrainingEnergyMax int `json:"training_energy_max"`
FriendMax int `json:"friend_max"`
InviteCode string `json:"invite_code"`
InsertDate string `json:"insert_date"`
UpdateDate string `json:"update_date"`
TutorialState int `json:"tutorial_state"`
DiamondCoin int `json:"diamond_coin"`
CrystalCoin int `json:"crystal_coin"`
LpRecoveryItem []LpRecoveryItem `json:"lp_recovery_item"`
}
// Birth ...
type Birth struct {
BirthMonth int `json:"birth_month"`
BirthDay int `json:"birth_day"`
}
+8
View File
@@ -0,0 +1,8 @@
package model
// Msg ...
type Msg struct {
Code int `json:"code"`
Message string `json:"message"`
Redirect string `json:"redirect"`
}
+141
View File
@@ -0,0 +1,141 @@
package router
import (
"honoka-chan/internal/handler"
"honoka-chan/internal/middleware"
"net/http"
"os"
"path/filepath"
"strings"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
)
func SifRouter(r *gin.Engine) {
// Static
r.Static("/static", "assets/static")
var files []string
_ = filepath.Walk("assets/static/templates", func(path string, info os.FileInfo, err error) error {
if strings.HasSuffix(path, ".html") {
files = append(files, path)
}
return nil
})
r.LoadHTMLFiles(files...)
// session
store := cookie.NewStore([]byte("llsif"))
r.Use(sessions.Sessions("llsif", store))
// /
r.Any("/", func(ctx *gin.Context) {
ctx.String(http.StatusOK, "Hello, world!")
})
// Private APIs
v1 := r.Group("v1")
{
v1.GET("/basic/getcode", handler.GetCode)
v1.POST("/account/active", handler.Active)
v1.POST("/account/initialize", handler.Initialize)
v1.POST("/account/loginauto", handler.LoginAuto)
v1.POST("/account/login", handler.AccountLogin)
v1.POST("/account/reportRole", handler.ReportRole)
v1.POST("/basic/getcode", handler.GetCode)
v1.POST("/basic/getProductList", handler.GetProductList)
v1.POST("/basic/handshake", handler.Handshake)
v1.POST("/basic/loginarea", handler.LoginArea)
v1.POST("/basic/publickey", handler.PublicKey)
v1.POST("/guest/status", handler.GuestStatus)
}
r.GET("/agreement/all", handler.Agreement)
r.GET("/integration/appReport/initialize", handler.ReportApp)
r.POST("/report/ge/app", handler.ReportLog)
// Private APIs
// Server APIs
m := r.Group("main.php").Use(middleware.Common)
{
m.POST("/album/seriesAll", middleware.ParseMultipartForm, handler.AlbumSeriesAll)
m.POST("/announce/checkState", middleware.ParseMultipartForm, handler.AnnounceCheckState)
m.POST("/api", middleware.ParseMultipartForm, handler.Api)
m.POST("/award/set", handler.AwardSet)
m.POST("/background/set", handler.BackgroundSet)
m.POST("/download/additional", middleware.ParseMultipartForm, handler.DownloadAdditional)
m.POST("/download/batch", middleware.ParseMultipartForm, handler.DownloadBatch)
m.POST("/download/event", middleware.ParseMultipartForm, handler.DownloadEvent)
m.POST("/download/getUrl", middleware.ParseMultipartForm, handler.DownloadUrl)
m.POST("/download/update", middleware.ParseMultipartForm, handler.DownloadUpdate)
m.POST("/event/eventList", middleware.ParseMultipartForm, handler.EventList)
m.POST("/gdpr/get", middleware.ParseMultipartForm, handler.Gdpr)
m.POST("/lbonus/execute", handler.LBonusExecute)
m.POST("/live/gameover", handler.GameOver)
m.POST("/live/partyList", handler.PartyList)
m.POST("/live/play", middleware.ParseMultipartForm, handler.PlayLive)
m.POST("/live/preciseScore", middleware.ParseMultipartForm, handler.PlayScore)
m.POST("/live/reward", middleware.ParseMultipartForm, handler.PlayReward)
m.POST("/login/authkey", middleware.AuthKey, handler.AuthKey)
m.POST("/login/login", middleware.ParseMultipartForm, middleware.Login, handler.Login)
m.POST("/multiunit/scenarioStartup", handler.MultiUnitStartUp)
m.POST("/museum/info", middleware.ParseMultipartForm, handler.MuseumInfo)
m.POST("/notice/noticeFriendGreeting", middleware.ParseMultipartForm, handler.NoticeFriendGreeting)
m.POST("/notice/noticeFriendVariety", middleware.ParseMultipartForm, handler.NoticeFriendVariety)
m.POST("/notice/noticeUserGreetingHistory", handler.NoticeUserGreeting)
m.POST("/payment/productList", middleware.ParseMultipartForm, handler.ProductList)
m.POST("/personalnotice/get", middleware.ParseMultipartForm, handler.PersonalNotice)
m.POST("/profile/profileRegister", handler.ProfileRegister)
m.POST("/scenario/reward", handler.ScenarioReward)
m.POST("/scenario/startup", handler.ScenarioStartup)
m.POST("/subscenario/reward", handler.SubScenarioStartup)
m.POST("/subscenario/startup", handler.SubScenarioStartup)
m.POST("/tos/tosCheck", middleware.ParseMultipartForm, handler.TosCheck)
m.POST("/unit/deck", handler.SetDeck)
m.POST("/unit/deckName", handler.SetDeckName)
m.POST("/unit/favorite", handler.SetDisplayRank)
m.POST("/unit/removableSkillEquipment", handler.RemoveSkillEquip)
m.POST("/unit/setDisplayRank", handler.SetDisplayRank)
m.POST("/unit/wearAccessory", handler.WearAccessory)
m.POST("/user/changeName", handler.ChangeName)
m.POST("/user/changeNavi", handler.ChangeNavi)
m.POST("/user/setNotificationToken", handler.SetNotificationToken)
m.POST("/user/userInfo", middleware.ParseMultipartForm, handler.UserInfo)
}
r.GET("/webview.php/announce/index", handler.AnnounceIndex)
// Server APIs
// Manga
r.GET("/manga", func(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "common/manga.html", gin.H{})
})
// WebUI
w := r.Group("admin").Use(middleware.WebAuth)
{
w.GET("/index", func(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "admin/index.html", gin.H{
"url": strings.Split(ctx.Request.URL.String(), "?")[0],
})
})
w.GET("/login", func(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "admin/login.html", gin.H{})
})
w.POST("/login", handler.WebLogin)
w.GET("/logout", handler.WebLogout)
w.GET("/card", func(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "admin/card.html", gin.H{
"menu": 1,
"url": strings.Split(ctx.Request.URL.String(), "?")[0],
})
})
w.GET("/upload", func(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "admin/upload.html", gin.H{
"menu": 1,
"url": strings.Split(ctx.Request.URL.String(), "?")[0],
})
})
w.POST("/upload", handler.Upload)
}
}
+150
View File
@@ -0,0 +1,150 @@
package tools
import (
"fmt"
"honoka-chan/internal/model"
"honoka-chan/internal/utils"
"honoka-chan/pkg/db"
"time"
)
type UserData struct {
ID int `xorm:"id pk autoincr"`
Phone string `xorm:"phone"`
Password string `xorm:"password"`
Autokey string `xorm:"autokey"`
Ticket string `xorm:"ticket"`
UserID int `xorm:"userid"`
LastLoginTime int64 `xorm:"last_login_time"`
}
type UserPref struct {
ID int `xorm:"id pk autoincr"`
UserID int `xorm:"user_id"`
AwardID int `xorm:"award_id"`
BackgroundID int `xorm:"background_id"`
UnitOwningUserID int `xorm:"unit_owning_user_id"`
UserName string `xorm:"user_name"`
UserLevel int `xorm:"user_level"`
UserDesc string `xorm:"user_desc"`
UpdateTime int64 `xorm:"update_time"`
}
func InitUserData(userId int) {
userList := []UserData{}
if userId != 0 {
err := db.UserEng.Table("users").Where("userid = ?", userId).Find(&userList)
utils.CheckErr(err)
} else {
err := db.UserEng.Table("users").Asc("id").Find(&userList)
utils.CheckErr(err)
}
session := db.UserEng.NewSession()
defer session.Close()
if err := session.Begin(); err != nil {
panic(err)
}
for _, user := range userList {
// 检查用户配置
exists, err := db.UserEng.Table("user_preference_m").Where("user_id = ?", user.UserID).Exist()
utils.CheckErr(err)
if !exists {
// 默认中心成员()
var oId int
_, err = db.MainEng.Table("common_unit_m").Cols("unit_owning_user_id").Where("unit_id = ?", 31).Get(&oId)
utils.CheckErr(err)
fmt.Println("Center UnitOwningUserID:", oId)
userPref := UserPref{
UserID: user.UserID,
AwardID: 1, // 音乃木坂学生
BackgroundID: 1, // 初始背景
UnitOwningUserID: oId,
UserName: "音乃木坂学生",
UserLevel: 1,
UserDesc: "你好。",
UpdateTime: time.Now().Unix(),
}
_, err = session.Table("user_preference_m").Insert(&userPref)
utils.CheckErr(err)
fmt.Println("UserPref ID", userPref.ID)
}
// 检查用户卡组配置
exists, err = db.UserEng.Table("user_deck_m").Where("user_id = ?", user.UserID).Asc("deck_id").Exist()
utils.CheckErr(err)
// fmt.Println("UserDeck exists:", exists)
if !exists {
userDeck := model.UserDeckData{
DeckID: 1,
MainFlag: 1,
DeckName: "队伍A",
UserID: user.UserID,
InsertDate: time.Now().Unix(),
}
// 默认队伍
_, err = session.Table("user_deck_m").Insert(&userDeck)
if err != nil {
session.Rollback()
panic(err)
}
userDeckId := userDeck.ID
fmt.Println("New UserDeck:", userDeckId)
// 默认卡组
unitIds := []int{}
err = db.MainEng.Table("unit_m").Cols("unit_id").Where("album_series_id = ?", 615).Find(&unitIds)
if err != nil {
session.Rollback()
panic(err)
}
unitData := []model.UnitData{}
err = db.MainEng.Table("common_unit_m").In("unit_id", unitIds).Find(&unitData)
if err != nil {
session.Rollback()
panic(err)
}
// fmt.Println(unitData)
position := 1
for _, unit := range unitData {
unitDeckData := model.UnitDeckData{
UserDeckID: userDeckId,
UnitOwningUserID: unit.UnitOwningUserID,
UnitID: unit.UnitID,
Position: position,
Level: 100,
LevelLimitID: 1,
DisplayRank: 2,
Love: 1000,
UnitSkillLevel: 8,
IsRankMax: true,
IsLoveMax: true,
IsLevelMax: true,
IsSigned: unit.IsSigned,
BeforeLove: 1000,
MaxLove: 1000,
InsertData: time.Now().Unix(),
}
_, err = session.Table("deck_unit_m").Insert(&unitDeckData)
if err != nil {
session.Rollback()
panic(err)
}
fmt.Println("New DeckUnit:", unitDeckData.ID)
position++
}
if err = session.Commit(); err != nil {
panic(err)
}
}
}
}
+498
View File
@@ -0,0 +1,498 @@
package tools
func init() {
InitUserData(0)
// eng, err := xorm.NewEngine("sqlite", "assets/masterdata.db")
// utils.CheckErr(err)
// err = eng.Ping()
// utils.CheckErr(err)
// suitIds := []int{}
// err = eng.Table("m_suit").Cols("id").OrderBy("id ASC").Find(&suitIds)
// utils.CheckErr(err)
// jsonStr := "["
// for _, suit := range suitIds {
// suitInfo := model.AsSuitInfo{
// SuitMasterID: suit,
// IsNew: false,
// }
// m, err := json.Marshal(suitInfo)
// utils.CheckErr(err)
// jsonStr += fmt.Sprintf("%d,%s,", suit, string(m))
// }
// jsonStr = strings.TrimRight(jsonStr, ",")
// jsonStr += "]"
// fmt.Println(jsonStr)
// eng, err := xorm.NewEngine("sqlite", "assets/masterdata.db")
// utils.CheckErr(err)
// err = eng.Ping()
// utils.CheckErr(err)
// emblemIds := []int{}
// err = eng.Table("m_emblem").Cols("id").OrderBy("id ASC").Find(&emblemIds)
// utils.CheckErr(err)
// jsonStr := "["
// for _, emblem := range emblemIds {
// emblemInfo := model.AsEmblemInfo{
// EmblemMID: emblem,
// AcquiredAt: time.Now().Unix(),
// }
// m, err := json.Marshal(emblemInfo)
// utils.CheckErr(err)
// jsonStr += fmt.Sprintf("%d,%s,", emblem, string(m))
// }
// jsonStr = strings.TrimRight(jsonStr, ",")
// jsonStr += "]"
// fmt.Println(jsonStr)
// eng, err := xorm.NewEngine("sqlite", "assets/masterdata.db")
// utils.CheckErr(err)
// err = eng.Ping()
// utils.CheckErr(err)
// emblemIds := []int{}
// err = eng.Table("m_emblem").Cols("id").OrderBy("id ASC").Find(&emblemIds)
// utils.CheckErr(err)
// ids := []model.AsEmblemId{}
// for _, id := range emblemIds {
// ids = append(ids, model.AsEmblemId{
// EmblemMasterID: id,
// IsNew: false,
// })
// }
// m, err := json.Marshal(ids)
// utils.CheckErr(err)
// fmt.Println(string(m))
// eng, err := xorm.NewEngine("sqlite", "assets/masterdata.db")
// utils.CheckErr(err)
// err = eng.Ping()
// utils.CheckErr(err)
// difficultyIds := []int{}
// err = eng.Table("m_live_difficulty").Cols("live_difficulty_id").OrderBy("live_difficulty_id ASC").Find(&difficultyIds)
// utils.CheckErr(err)
// jsonStr := "["
// for _, id := range difficultyIds {
// difficultyInfo := model.AsLiveDifficultyInfo{
// LiveDifficultyID: id,
// MaxScore: 0,
// MaxCombo: 0,
// PlayCount: 0,
// ClearCount: 0,
// CancelCount: 0,
// NotClearedCount: 0,
// IsFullCombo: false,
// ClearedDifficultyAchievement1: nil,
// ClearedDifficultyAchievement2: nil,
// ClearedDifficultyAchievement3: nil,
// EnableAutoplay: false,
// IsAutoplay: false,
// IsNew: false,
// }
// m, err := json.Marshal(difficultyInfo)
// utils.CheckErr(err)
// jsonStr += fmt.Sprintf("%d,%s,", id, string(m))
// }
// jsonStr = strings.TrimRight(jsonStr, ",")
// jsonStr += "]"
// fmt.Println(jsonStr)
// eng, err := xorm.NewEngine("sqlite", "assets/masterdata.db")
// utils.CheckErr(err)
// err = eng.Ping()
// utils.CheckErr(err)
// storyIds := []int{}
// err = eng.Table("m_story_main_cell").Cols("id").OrderBy("id ASC").Find(&storyIds)
// utils.CheckErr(err)
// jsonStr := "["
// for _, id := range storyIds {
// storyInfo := model.AsMainStoryInfo{
// StoryMainMasterID: id,
// }
// m, err := json.Marshal(storyInfo)
// utils.CheckErr(err)
// jsonStr += fmt.Sprintf("%d,%s,", id, string(m))
// }
// jsonStr = strings.TrimRight(jsonStr, ",")
// jsonStr += "]"
// fmt.Println(jsonStr)
// eng, err := xorm.NewEngine("sqlite", "assets/masterdata.db")
// utils.CheckErr(err)
// err = eng.Ping()
// utils.CheckErr(err)
// voiceIds := []int{}
// err = eng.Table("m_navi_voice").Cols("id").OrderBy("id ASC").Find(&voiceIds)
// utils.CheckErr(err)
// jsonStr := "["
// for _, id := range voiceIds {
// storyInfo := model.AsNaviVoiceInfo{
// NaviVoiceMasterID: id,
// IsNew: false,
// }
// m, err := json.Marshal(storyInfo)
// utils.CheckErr(err)
// jsonStr += fmt.Sprintf("%d,%s,", id, string(m))
// }
// jsonStr = strings.TrimRight(jsonStr, ",")
// jsonStr += "]"
// fmt.Println(jsonStr)
// eng, err := xorm.NewEngine("sqlite", "assets/masterdata.db")
// utils.CheckErr(err)
// err = eng.Ping()
// utils.CheckErr(err)
// backgroundIds := []int{}
// err = eng.Table("m_custom_background").Cols("id").OrderBy("id ASC").Find(&backgroundIds)
// utils.CheckErr(err)
// jsonStr := "["
// for _, id := range backgroundIds {
// storyInfo := model.AsCustomBackgroundInfo{
// CustomBackgroundMasterID: id,
// IsNew: false,
// }
// m, err := json.Marshal(storyInfo)
// utils.CheckErr(err)
// jsonStr += fmt.Sprintf("%d,%s,", id, string(m))
// }
// jsonStr = strings.TrimRight(jsonStr, ",")
// jsonStr += "]"
// fmt.Println(jsonStr)
// eng, err := xorm.NewEngine("sqlite", "assets/masterdata.db")
// utils.CheckErr(err)
// err = eng.Ping()
// utils.CheckErr(err)
// storyIds := []int{}
// err = eng.Table("m_story_side").Cols("id").OrderBy("id ASC").Find(&storyIds)
// utils.CheckErr(err)
// jsonStr := "["
// for _, id := range storyIds {
// storyInfo := model.AsStorySideInfo{
// StorySideMasterID: id,
// IsNew: false,
// AcquiredAt: time.Now().Unix(),
// }
// m, err := json.Marshal(storyInfo)
// utils.CheckErr(err)
// jsonStr += fmt.Sprintf("%d,%s,", id, string(m))
// }
// jsonStr = strings.TrimRight(jsonStr, ",")
// jsonStr += "]"
// fmt.Println(jsonStr)
// eng, err := xorm.NewEngine("sqlite", "assets/masterdata.db")
// utils.CheckErr(err)
// err = eng.Ping()
// utils.CheckErr(err)
// storyIds := []int{}
// err = eng.Table("m_story_member").Cols("id").OrderBy("id ASC").Find(&storyIds)
// utils.CheckErr(err)
// jsonStr := "["
// for _, id := range storyIds {
// storyInfo := model.AsStoryMemberInfo{
// StoryMemberMasterID: id,
// IsNew: false,
// AcquiredAt: time.Now().Unix(),
// }
// m, err := json.Marshal(storyInfo)
// utils.CheckErr(err)
// jsonStr += fmt.Sprintf("%d,%s,", id, string(m))
// }
// jsonStr = strings.TrimRight(jsonStr, ",")
// jsonStr += "]"
// fmt.Println(jsonStr)
// eng, err := xorm.NewEngine("sqlite", "assets/masterdata.db")
// utils.CheckErr(err)
// err = eng.Ping()
// utils.CheckErr(err)
// eventIds := []int{}
// err = eng.Table("m_story_event_history_detail").Cols("story_event_id").OrderBy("story_event_id ASC").Find(&eventIds)
// utils.CheckErr(err)
// jsonStr := "["
// for _, id := range eventIds {
// storyInfo := model.AsStoryEventInfo{
// StoryEventID: id,
// }
// m, err := json.Marshal(storyInfo)
// utils.CheckErr(err)
// jsonStr += fmt.Sprintf("%d,%s,", id, string(m))
// }
// jsonStr = strings.TrimRight(jsonStr, ",")
// jsonStr += "]"
// fmt.Println(jsonStr)
// eng, err := xorm.NewEngine("sqlite", "assets/masterdata.db")
// utils.CheckErr(err)
// err = eng.Ping()
// utils.CheckErr(err)
// missionRes := []model.AsMissionRes{}
// err = eng.Table("m_mission").Cols("id,mission_clear_condition_count").
// Where("term = 3 AND (end_at > ? OR end_at IS NULL)", time.Now().Unix()).OrderBy("id ASC").Find(&missionRes)
// utils.CheckErr(err)
// jsonStr := "["
// for _, res := range missionRes {
// storyInfo := model.AsFreeMissionInfo{
// MissionMID: res.ID,
// IsNew: false,
// MissionCount: res.Count,
// IsCleared: true,
// IsReceivedReward: true,
// NewExpiredAt: time.Now().Unix(),
// }
// m, err := json.Marshal(storyInfo)
// utils.CheckErr(err)
// jsonStr += fmt.Sprintf("%d,%s,", res.ID, string(m))
// }
// jsonStr = strings.TrimRight(jsonStr, ",")
// jsonStr += "]"
// fmt.Println(jsonStr)
// eng, err := xorm.NewEngine("sqlite", "assets/masterdata.db")
// utils.CheckErr(err)
// err = eng.Ping()
// utils.CheckErr(err)
// missionRes := []model.AsMissionRes{}
// err = eng.Table("m_mission").Cols("id,mission_clear_condition_count").
// Where("term = 1 AND (end_at > ? OR end_at IS NULL)", time.Now().Unix()).OrderBy("id ASC").Find(&missionRes)
// utils.CheckErr(err)
// jsonStr := "["
// for _, res := range missionRes {
// storyInfo := model.AsDailyMissionInfo{
// MissionMID: res.ID,
// IsNew: false,
// MissionStartCount: res.Count,
// MissionCount: res.Count,
// IsCleared: true,
// IsReceivedReward: true,
// ClearedExpiredAt: time.Now().Unix(),
// }
// m, err := json.Marshal(storyInfo)
// utils.CheckErr(err)
// jsonStr += fmt.Sprintf("%d,%s,", res.ID, string(m))
// }
// jsonStr = strings.TrimRight(jsonStr, ",")
// jsonStr += "]"
// fmt.Println(jsonStr)
// eng, err := xorm.NewEngine("sqlite", "assets/masterdata.db")
// utils.CheckErr(err)
// err = eng.Ping()
// utils.CheckErr(err)
// missionRes := []model.AsMissionRes{}
// err = eng.Table("m_mission").Cols("id,mission_clear_condition_count").
// Where("term = 2 AND (end_at > ? OR end_at IS NULL)", time.Now().Unix()).OrderBy("id ASC").Find(&missionRes)
// utils.CheckErr(err)
// jsonStr := "["
// for _, res := range missionRes {
// storyInfo := model.AsWeeklyMissionInfo{
// MissionMID: res.ID,
// IsNew: false,
// MissionStartCount: res.Count,
// MissionCount: res.Count,
// IsCleared: true,
// IsReceivedReward: true,
// ClearedExpiredAt: time.Now().Unix(),
// NewExpiredAt: time.Now().Unix(),
// }
// m, err := json.Marshal(storyInfo)
// utils.CheckErr(err)
// jsonStr += fmt.Sprintf("%d,%s,", res.ID, string(m))
// }
// jsonStr = strings.TrimRight(jsonStr, ",")
// jsonStr += "]"
// fmt.Println(jsonStr)
// eng, err := xorm.NewEngine("sqlite", "assets/masterdata.db")
// utils.CheckErr(err)
// err = eng.Ping()
// utils.CheckErr(err)
// eng.ShowSQL(true)
// memberIds := []int{}
// err = eng.Table("m_member").Cols("id").OrderBy("id ASC").Find(&memberIds)
// utils.CheckErr(err)
// jsonStr := "["
// for _, memberId := range memberIds {
// cellIds := []int{}
// err = eng.Table("m_member_love_panel_cell").
// Join("LEFT", "m_member_love_panel", "m_member_love_panel_cell.member_love_panel_master_id = m_member_love_panel.id").
// Cols("m_member_love_panel_cell.id").Where("m_member_love_panel.member_master_id = ?", memberId).
// OrderBy("m_member_love_panel_cell.id ASC").Find(&cellIds)
// utils.CheckErr(err)
// panelInfo := model.AsMemberLovePanelInfo{
// MemberID: memberId,
// MemberLovePanelCellIds: cellIds,
// }
// m, err := json.Marshal(panelInfo)
// utils.CheckErr(err)
// jsonStr += fmt.Sprintf("%s,", string(m))
// }
// jsonStr = strings.TrimRight(jsonStr, ",")
// jsonStr += "]"
// fmt.Println(jsonStr)
// mEng, err := xorm.NewEngine("sqlite", "assets/masterdata.db")
// utils.CheckErr(err)
// err = mEng.Ping()
// utils.CheckErr(err)
// defer mEng.Close()
// dEng, err := xorm.NewEngine("sqlite", "assets/dictionary_zh_k.db")
// utils.CheckErr(err)
// err = dEng.Ping()
// utils.CheckErr(err)
// defer dEng.Close()
// cardRes := []model.AsCardRes{}
// err = mEng.Table("m_card").Cols("id,card_rarity_type,max_passive_skill_slot").OrderBy("id ASC").Find(&cardRes)
// utils.CheckErr(err)
// jsonStr := "["
// for _, card := range cardRes {
// // 绊板等级加成
// cardLevel := 0
// cardCellCount := 0
// if card.CardRarityType == 10 {
// cardLevel = 40 + 42
// cardCellCount = 61
// } else if card.CardRarityType == 20 {
// cardLevel = 60 + 24
// cardCellCount = 75
// } else if card.CardRarityType == 30 {
// cardLevel = 80 + 12
// cardCellCount = 87
// }
// var apBuff, stBuff, teBuff int
// _, err := mEng.Table("m_training_tree_card_param").Where("id = ? AND training_content_type = ?", card.ID, 2).Select("SUM(value)").Get(&stBuff)
// utils.CheckErr(err)
// // fmt.Println(stBuff)
// _, err = mEng.Table("m_training_tree_card_param").Where("id = ? AND training_content_type = ?", card.ID, 3).Select("SUM(value)").Get(&apBuff)
// utils.CheckErr(err)
// // fmt.Println(apBuff)
// _, err = mEng.Table("m_training_tree_card_param").Where("id = ? AND training_content_type = ?", card.ID, 4).Select("SUM(value)").Get(&teBuff)
// utils.CheckErr(err)
// // fmt.Println(teBuff)
// var skillName string
// var skillId int
// _, err = mEng.Table("m_card_passive_skill_original").Where("card_master_id = ? AND skill_level = 5", card.ID).Cols("name").Get(&skillName)
// utils.CheckErr(err)
// skillName = strings.ReplaceAll(skillName, "k.", "")
// // fmt.Println(skillName)
// // dEng.ShowSQL(true)
// condition := "id LIKE '%" + skillName + "%' AND (message LIKE '%表现%同策略%' OR message LIKE '%表现%同属性%') AND message NOT LIKE '%时%'"
// count, err := dEng.Table("m_dictionary").
// Where(condition).
// Count()
// utils.CheckErr(err)
// if count > 0 {
// skillId = 30000507
// } else {
// skillId = 30000482
// }
// var passiveSkillLevel int
// _, err = mEng.Table("m_card_passive_skill_original").Where("card_master_id = ?", card.ID).
// Cols("skill_level").OrderBy("skill_level DESC").Limit(1).Get(&passiveSkillLevel)
// utils.CheckErr(err)
// cardInfo := model.AsCardInfo{
// CardMasterID: card.ID,
// Level: cardLevel,
// Exp: 0,
// LovePoint: 0,
// IsFavorite: false,
// IsAwakening: true,
// IsAwakeningImage: true,
// IsAllTrainingActivated: true,
// TrainingActivatedCellCount: cardCellCount,
// MaxFreePassiveSkill: card.MaxPassiveSkillSlot,
// Grade: 5,
// TrainingLife: stBuff,
// TrainingAttack: apBuff,
// TrainingDexterity: teBuff,
// ActiveSkillLevel: 5,
// PassiveSkillALevel: passiveSkillLevel,
// PassiveSkillBLevel: 1,
// PassiveSkillCLevel: 1,
// AdditionalPassiveSkill1ID: skillId,
// AdditionalPassiveSkill2ID: skillId,
// AdditionalPassiveSkill3ID: skillId,
// AdditionalPassiveSkill4ID: skillId,
// AcquiredAt: time.Now().Unix(),
// IsNew: false,
// }
// m, err := json.Marshal(cardInfo)
// utils.CheckErr(err)
// jsonStr += fmt.Sprintf("%d,%s,", card.ID, string(m))
// }
// jsonStr = strings.TrimRight(jsonStr, ",")
// jsonStr += "]"
// fmt.Println(jsonStr)
// gjson.Parse(utils.ReadAllText("data/notesdata.json")).ForEach(func(k, v gjson.Result) bool {
// v.ForEach(func(kk, vv gjson.Result) bool {
// if vv.IsObject() {
// fileName := vv.Get("live.live_stage.live_difficulty_id").String()
// utils.WriteAllText("temp/"+fileName+".json", vv.Get("live.live_stage").String())
// }
// return true
// })
// return true
// })
}
func CheckErr(err error) {
if err != nil {
panic(err)
}
}
+24
View File
@@ -0,0 +1,24 @@
package utils
import (
"encoding/base64"
"honoka-chan/pkg/db"
"honoka-chan/pkg/encrypt"
)
func CheckErr(err error) {
if err != nil {
panic(err)
}
}
func IsSigned(unitId int) bool {
exists, err := db.MainEng.Table("unit_sign_asset_m").Where("unit_id = ?", unitId).Exist()
CheckErr(err)
return exists
}
func GenXMS(resp []byte) string {
return base64.StdEncoding.EncodeToString(encrypt.RSASignSHA1(resp))
}