Support uploading units

Signed-off-by: Yuan Si <do4suki@gmail.com>
This commit is contained in:
2023-04-30 08:48:12 +08:00
parent e55b2ce7cd
commit f8477490a0
10 changed files with 204 additions and 155 deletions
+1 -1
View File
@@ -2,8 +2,8 @@ honoka-chan
honoka-chan.exe
data
temp
assets/data.db
assets/unit.sd
.vscode
+114 -2
View File
@@ -1,14 +1,24 @@
package handler
import (
"encoding/json"
"honoka-chan/model"
"honoka-chan/tools"
"honoka-chan/utils"
"net/http"
"path"
"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")
@@ -23,7 +33,8 @@ func WebLogin(ctx *gin.Context) {
}
userName := " " + area + "-" + user
exists, err := UserEng.Table("users").Where("phone = ? AND password = ?", userName, openssl.Md5ToString(pass)).Exist()
var userId int
exists, err := UserEng.Table("users").Where("phone = ? AND password = ?", userName, openssl.Md5ToString(pass)).Cols("userid").Get(&userId)
CheckErr(err)
if !exists {
ctx.JSON(http.StatusOK, model.Msg{
@@ -38,7 +49,7 @@ func WebLogin(ctx *gin.Context) {
session.Options(sessions.Options{
MaxAge: 3600 * 24,
})
session.Set("username", userName)
session.Set("userid", userId)
session.Save()
ctx.JSON(http.StatusOK, model.Msg{
@@ -59,3 +70,104 @@ func WebLogout(ctx *gin.Context) {
ctx.Redirect(http.StatusFound, "/admin/login")
}
func Upload(ctx *gin.Context) {
file, err := ctx.FormFile("file")
CheckErr(err)
tmpPath := path.Join("./temp", file.Filename)
err = ctx.SaveUploadedFile(file, tmpPath)
CheckErr(err)
data := model.Data{}
err = json.Unmarshal([]byte(utils.ReadAllText(tmpPath)), &data)
CheckErr(err)
session := UserEng.NewSession()
defer session.Close()
if err = session.Begin(); err != nil {
session.Rollback()
panic(err)
}
for _, team := range data.Team {
if team.Cardid == 0 {
continue
}
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 = ?", team.Cardid).
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)
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
}
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)
CheckErr(err)
isSigned := false
if unitSigned == 1 {
isSigned = true
}
var skillExp int
if team.Skilllevel != 8 {
skillExp = 0
} else {
skillExp = 29900
}
unitData := tools.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: team.Skilllevel,
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: "上传成功!"})
}
-119
View File
@@ -1,119 +0,0 @@
package llhelper
import (
"encoding/json"
"fmt"
"honoka-chan/config"
"honoka-chan/tools"
"honoka-chan/utils"
"os"
)
var (
unitFile = "assets/unit.sd"
)
func CheckErr(err error) {
if err != nil {
panic(err)
}
}
func init() {
LoadData()
}
func LoadData() {
_, err := os.Stat(unitFile)
if err != nil {
fmt.Println(err)
return
}
data := Data{}
err = json.Unmarshal([]byte(utils.ReadAllText(unitFile)), &data)
CheckErr(err)
session := config.UserEng.NewSession()
defer session.Close()
if err = session.Begin(); err != nil {
session.Rollback()
panic(err)
}
for _, team := range data.Team {
fmt.Println(team.Cardid)
if team.Cardid == 0 {
continue
}
var unitId, unitExp, unitRarity, unitHp, unitSigned int
exists, err := config.MainEng.Table("common_unit_m").Join("LEFT", "unit_m", "common_unit_m.unit_id = unit_m.unit_id").
Where("unit_m.unit_number = ?", team.Cardid).
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)
CheckErr(err)
if !exists {
panic("no such unit")
}
if unitRarity != 4 {
panic("only support UR")
}
var diffExp, diffSmile, diffPure, diffCool int
_, err = config.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)
CheckErr(err)
isSigned := false
if unitSigned == 1 {
isSigned = true
}
var skillExp int
if team.Skilllevel != 8 {
skillExp = 0
} else {
skillExp = 29900
}
unitData := tools.UnitData{
UserID: 1681205441, // Replace with your own
UnitID: unitId,
Exp: unitExp + diffExp,
NextExp: 0,
Level: 350,
MaxLevel: 350,
LevelLimitID: 1,
Rank: 2,
MaxRank: 2,
Love: 1000,
MaxLove: 1000,
UnitSkillExp: skillExp,
UnitSkillLevel: team.Skilllevel,
MaxHp: unitHp,
UnitRemovableSkillCapacity: 8,
FavoriteFlag: false,
DisplayRank: 2,
IsRankMax: true,
IsLoveMax: true,
IsLevelMax: true,
IsSigned: isSigned,
IsSkillLevelMax: true,
IsRemovableSkillCapacityMax: true,
InsertDate: "2023-04-20 10:00:00",
}
_, err = session.Table("user_unit_m").Insert(&unitData)
if err != nil {
session.Rollback()
panic(err)
}
fmt.Println("Insert ID:", unitData.UnitOwningUserID)
if err = session.Commit(); err != nil {
session.Rollback()
panic(err)
}
}
}
+3 -3
View File
@@ -2,7 +2,6 @@ package main
import (
"honoka-chan/handler"
_ "honoka-chan/llhelper"
"honoka-chan/middleware"
_ "honoka-chan/tools"
"net/http"
@@ -137,12 +136,13 @@ func main() {
"url": strings.Split(ctx.Request.URL.String(), "?")[0],
})
})
w.GET("/deck", func(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "admin/card.html", gin.H{
w.GET("/upload", func(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "admin/upload.html", gin.H{
"menu": 1,
"url": strings.Split(ctx.Request.URL.String(), "?")[0],
})
})
w.POST("/upload", handler.Upload)
}
r.Run(":80") // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
+2 -1
View File
@@ -11,7 +11,7 @@ import (
func WebAuth(ctx *gin.Context) {
session := sessions.Default(ctx)
requestUrl := strings.Split(ctx.Request.URL.String(), "?")[0] // 过滤 GET 参数
_, ok := session.Get("username").(string)
userId, ok := session.Get("userid").(int)
if ok {
if requestUrl == "/admin/login" {
ctx.Redirect(http.StatusFound, "/admin/index")
@@ -23,6 +23,7 @@ func WebAuth(ctx *gin.Context) {
ctx.Abort()
}
}
ctx.Set("userid", userId)
ctx.Next()
}
+1 -1
View File
@@ -1,4 +1,4 @@
package llhelper
package model
type Data struct {
Version int `json:"version"`
-27
View File
@@ -1,27 +0,0 @@
{{ define "admin/deck.html" }}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>SIF 小助手</title>
{{ template "admin/nav/css.html" . }}
</head>
<body>
<div class="layui-layout layui-layout-admin">
{{ template "admin/nav/header.html" . }}
{{ template "admin/nav/side.html" . }}
<div class="layui-body">
<div style="padding: 15px;">{{ .url }}</div>
</div>
{{ template "admin/nav/footer.html" . }}
</div>
<script src="/static/js/layui.js"></script>
</body>
</html>
{{ end }}
+4
View File
@@ -7,6 +7,10 @@
color: aliceblue;
}
.layui-body {
padding-top: 30px;
}
.layui-header {
background-color: #e4007f !important;
}
+2 -1
View File
@@ -6,7 +6,8 @@
<a class="" href="javascript:;">卡片管理</a>
<dl class="layui-nav-child">
<dd {{ if eq .url "/admin/card" }} class="layui-this" {{ end }}><a href="/admin/card">卡片一览</a></dd>
<dd {{ if eq .url "/admin/deck" }} class="layui-this" {{ end }}><a href="/admin/deck">编队管理</a></dd>
<dd {{ if eq .url "/admin/upload" }} class="layui-this" {{ end }}><a href="/admin/upload">卡片导入</a>
</dd>
</dd>
</dl>
</li>
+77
View File
@@ -0,0 +1,77 @@
{{ define "admin/upload.html" }}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>SIF 小助手</title>
{{ template "admin/nav/css.html" . }}
</head>
<body>
<div class="layui-layout layui-layout-admin">
{{ template "admin/nav/header.html" . }}
{{ template "admin/nav/side.html" . }}
<div class="layui-body">
<form class="layui-form layui-col-md4" action="">
<div class="layui-form-item">
<label class="layui-form-label">文件</label>
<div class="layui-input-block">
<button type="button" name="file" class="layui-btn layui-btn-normal" id="test8">选择文件</button>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<div class="layui-collapse">
<div class="layui-colla-item">
<h2 class="layui-colla-title">帮助</h2>
<div class="layui-colla-content">
<ol>
<li>仅支持导入LLHelper队伍信息</li>
<li>仅需要设置技能等级,卡片默认等级MAX,宝石请在游戏内设置</li>
<li>仅支持导入UR卡片</li>
<li>仅支持导入国服拥有的卡片</li>
</ol>
</div>
</div>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button type="button" class="layui-btn" id="test9">开始导入</button>
</div>
</div>
</form>
</div>
{{ template "admin/nav/footer.html" . }}
</div>
<script src="/static/js/layui.js"></script>
<script>
layui.use(['upload', 'layer'], function () {
var $ = layui.jquery
, upload = layui.upload
, layer = layui.layer;
upload.render({
elem: '#test8'
, url: '/admin/upload' // 此处配置你自己的上传接口即可
, auto: false
, accept: 'file' // 普通文件
, exts: 'sd' // 只允许上传 .sd 文件
, size: 50 // 限制文件大小,单位 KB
, bindAction: '#test9'
, done: function (res) {
layer.msg(res.msg);
}
});
});
</script>
</body>
</html>
{{ end }}