|
|
package utils
|
|
|
|
|
|
import (
|
|
|
"crypto/md5"
|
|
|
"encoding/hex"
|
|
|
"fmt"
|
|
|
"math/rand"
|
|
|
"regexp"
|
|
|
"sort"
|
|
|
"strings"
|
|
|
"time"
|
|
|
)
|
|
|
|
|
|
func toHexDigest(str string) string {
|
|
|
h := md5.New()
|
|
|
h.Write([]byte(str))
|
|
|
|
|
|
return hex.EncodeToString(h.Sum(nil))
|
|
|
}
|
|
|
|
|
|
/* contributor: https://github.com/Azure99/GenshinPlayerQuery/issues/20 @lulu666lulu */
|
|
|
func GetDS(url, data string) (t, v, ds string) {
|
|
|
// 5: mobile web
|
|
|
const appType = "5"
|
|
|
const apiSalt = "xV8v4Qu54lUKrEYFZkJhB8cuOh9Asafs"
|
|
|
const appVersion = "2.11.1"
|
|
|
rand.Seed(time.Now().UnixNano())
|
|
|
|
|
|
// unix timestamp
|
|
|
i := time.Now().Unix()
|
|
|
// random number 100k - 200k
|
|
|
r := rand.Intn(100000) + 100000
|
|
|
// body
|
|
|
b := data
|
|
|
// query
|
|
|
q := func() string {
|
|
|
urlParts := strings.Split(url, "?")
|
|
|
if len(urlParts) == 2 {
|
|
|
querys := strings.Split(urlParts[1], "&")
|
|
|
sort.Strings(querys)
|
|
|
return strings.Join(querys, "&")
|
|
|
}
|
|
|
return ""
|
|
|
}()
|
|
|
c := toHexDigest(fmt.Sprintf("salt=%s&t=%d&r=%d&b=%s&q=%s", apiSalt, i, r, b, q))
|
|
|
ds = fmt.Sprintf("%d,%d,%s", i, r, c)
|
|
|
|
|
|
return appType, appVersion, ds
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
* t1, t2: string, HH:MM
|
|
|
* t1 > t2 return 1
|
|
|
* t1 = t2 return 0
|
|
|
* t1 < t2 return -1
|
|
|
*/
|
|
|
func timeCmp(t1, t2 string) int {
|
|
|
hh1, mm1, hh2, mm2 := 0, 0, 0, 0
|
|
|
fmt.Sscanf(t1, "%d:%d", &hh1, &mm1)
|
|
|
fmt.Sscanf(t2, "%d:%d", &hh2, &mm2)
|
|
|
|
|
|
switch {
|
|
|
case hh1 > hh2:
|
|
|
return 1
|
|
|
case hh2 > hh1:
|
|
|
return -1
|
|
|
case mm1 > mm2:
|
|
|
return 1
|
|
|
case mm1 < mm2:
|
|
|
return -1
|
|
|
default:
|
|
|
return 0
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
* 判断当前时刻是否在某个事件段内, 分钟级
|
|
|
* timeRangeStr: string, HH:MM-HH:MM
|
|
|
* 返回true or false, 若结果true,第二个返回值为距离结束时间段结束的时间,否则返回0
|
|
|
* 如果timeRangeStr格式错误,返回false, 0
|
|
|
*/
|
|
|
func NowInTimeRange(timeRangeStr string) (bool, time.Duration) {
|
|
|
rc := regexp.MustCompile("^((0?[0-9]|1[0-9]|2[0-3]):(0?[0-9]|[1-5][0-9])) *- *((0?[0-9]|1[0-9]|2[0-3]):(0?[0-9]|[1-5][0-9]))$")
|
|
|
if timeRangeStr == "" || !rc.Match([]byte(timeRangeStr)) {
|
|
|
/* 无效的时间段 */
|
|
|
return false, 0
|
|
|
}
|
|
|
waitTime := func(now, end time.Time) time.Duration {
|
|
|
return time.Duration((end.Unix() - now.Unix())) * time.Second
|
|
|
}
|
|
|
timeRange := regexp.MustCompile("((0?[0-9]|1[0-9]|2[0-3]):([1-5][0-9]|0?[0-9]))").FindAllString(timeRangeStr, 2)
|
|
|
now := time.Now()
|
|
|
end, _ := time.ParseInLocation("2006-01-02 15:04", fmt.Sprintf("%d-%02d-%02d %s", now.Year(), now.Month(), now.Day(), timeRange[1]), time.Local)
|
|
|
nowHHMM := fmt.Sprint(now.Hour(), ":", now.Minute())
|
|
|
if timeCmp(timeRange[0], timeRange[1]) > 0 {
|
|
|
/* 时间范围跨过0点 */
|
|
|
if timeCmp(nowHHMM, timeRange[0]) >= 0 && timeCmp(nowHHMM, "23:59") <= 0 {
|
|
|
/* 0点前 */
|
|
|
return true, waitTime(now, end.AddDate(0, 0, 1))
|
|
|
}
|
|
|
if timeCmp(nowHHMM, "00:00") >= 0 && timeCmp(nowHHMM, timeRange[1]) < 0 {
|
|
|
return true, waitTime(now, end)
|
|
|
}
|
|
|
} else {
|
|
|
if timeCmp(nowHHMM, timeRange[0]) >= 0 && timeCmp(nowHHMM, timeRange[1]) < 0 {
|
|
|
return true, waitTime(now, end)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return false, 0
|
|
|
}
|