Reorganize directory structures
Signed-off-by: Sean Du <do4suki@gmail.com>
This commit is contained in:
@@ -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))
|
||||
}
|
||||
@@ -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
@@ -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))
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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(¬es_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), ¬es)
|
||||
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(¬es_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), ¬es)
|
||||
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))
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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: "上传成功!"})
|
||||
}
|
||||
Reference in New Issue
Block a user