+1
-1
@@ -2,8 +2,8 @@ honoka-chan
|
|||||||
honoka-chan.exe
|
honoka-chan.exe
|
||||||
|
|
||||||
data
|
data
|
||||||
|
temp
|
||||||
|
|
||||||
assets/data.db
|
assets/data.db
|
||||||
assets/unit.sd
|
|
||||||
|
|
||||||
.vscode
|
.vscode
|
||||||
|
|||||||
+114
-2
@@ -1,14 +1,24 @@
|
|||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"honoka-chan/model"
|
"honoka-chan/model"
|
||||||
|
"honoka-chan/tools"
|
||||||
|
"honoka-chan/utils"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"path"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/forgoer/openssl"
|
"github.com/forgoer/openssl"
|
||||||
"github.com/gin-contrib/sessions"
|
"github.com/gin-contrib/sessions"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ErrMsg struct {
|
||||||
|
Error int `json:"error"`
|
||||||
|
Msg string `json:"msg"`
|
||||||
|
}
|
||||||
|
|
||||||
func WebLogin(ctx *gin.Context) {
|
func WebLogin(ctx *gin.Context) {
|
||||||
area := ctx.PostForm("area")
|
area := ctx.PostForm("area")
|
||||||
user := ctx.PostForm("user")
|
user := ctx.PostForm("user")
|
||||||
@@ -23,7 +33,8 @@ func WebLogin(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
userName := " " + area + "-" + user
|
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)
|
CheckErr(err)
|
||||||
if !exists {
|
if !exists {
|
||||||
ctx.JSON(http.StatusOK, model.Msg{
|
ctx.JSON(http.StatusOK, model.Msg{
|
||||||
@@ -38,7 +49,7 @@ func WebLogin(ctx *gin.Context) {
|
|||||||
session.Options(sessions.Options{
|
session.Options(sessions.Options{
|
||||||
MaxAge: 3600 * 24,
|
MaxAge: 3600 * 24,
|
||||||
})
|
})
|
||||||
session.Set("username", userName)
|
session.Set("userid", userId)
|
||||||
session.Save()
|
session.Save()
|
||||||
|
|
||||||
ctx.JSON(http.StatusOK, model.Msg{
|
ctx.JSON(http.StatusOK, model.Msg{
|
||||||
@@ -59,3 +70,104 @@ func WebLogout(ctx *gin.Context) {
|
|||||||
|
|
||||||
ctx.Redirect(http.StatusFound, "/admin/login")
|
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: "上传成功!"})
|
||||||
|
}
|
||||||
|
|||||||
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"honoka-chan/handler"
|
"honoka-chan/handler"
|
||||||
_ "honoka-chan/llhelper"
|
|
||||||
"honoka-chan/middleware"
|
"honoka-chan/middleware"
|
||||||
_ "honoka-chan/tools"
|
_ "honoka-chan/tools"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -137,12 +136,13 @@ func main() {
|
|||||||
"url": strings.Split(ctx.Request.URL.String(), "?")[0],
|
"url": strings.Split(ctx.Request.URL.String(), "?")[0],
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
w.GET("/deck", func(ctx *gin.Context) {
|
w.GET("/upload", func(ctx *gin.Context) {
|
||||||
ctx.HTML(http.StatusOK, "admin/card.html", gin.H{
|
ctx.HTML(http.StatusOK, "admin/upload.html", gin.H{
|
||||||
"menu": 1,
|
"menu": 1,
|
||||||
"url": strings.Split(ctx.Request.URL.String(), "?")[0],
|
"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")
|
r.Run(":80") // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
|
||||||
|
|||||||
+2
-1
@@ -11,7 +11,7 @@ import (
|
|||||||
func WebAuth(ctx *gin.Context) {
|
func WebAuth(ctx *gin.Context) {
|
||||||
session := sessions.Default(ctx)
|
session := sessions.Default(ctx)
|
||||||
requestUrl := strings.Split(ctx.Request.URL.String(), "?")[0] // 过滤 GET 参数
|
requestUrl := strings.Split(ctx.Request.URL.String(), "?")[0] // 过滤 GET 参数
|
||||||
_, ok := session.Get("username").(string)
|
userId, ok := session.Get("userid").(int)
|
||||||
if ok {
|
if ok {
|
||||||
if requestUrl == "/admin/login" {
|
if requestUrl == "/admin/login" {
|
||||||
ctx.Redirect(http.StatusFound, "/admin/index")
|
ctx.Redirect(http.StatusFound, "/admin/index")
|
||||||
@@ -23,6 +23,7 @@ func WebAuth(ctx *gin.Context) {
|
|||||||
ctx.Abort()
|
ctx.Abort()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ctx.Set("userid", userId)
|
||||||
|
|
||||||
ctx.Next()
|
ctx.Next()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package llhelper
|
package model
|
||||||
|
|
||||||
type Data struct {
|
type Data struct {
|
||||||
Version int `json:"version"`
|
Version int `json:"version"`
|
||||||
@@ -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 }}
|
|
||||||
@@ -7,6 +7,10 @@
|
|||||||
color: aliceblue;
|
color: aliceblue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layui-body {
|
||||||
|
padding-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
.layui-header {
|
.layui-header {
|
||||||
background-color: #e4007f !important;
|
background-color: #e4007f !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
<a class="" href="javascript:;">卡片管理</a>
|
<a class="" href="javascript:;">卡片管理</a>
|
||||||
<dl class="layui-nav-child">
|
<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/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>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -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 }}
|
||||||
Reference in New Issue
Block a user