master
dustoair 3 years ago
commit fa06e419da

@ -0,0 +1,21 @@
kind: pipeline
type: ssh # 使用SSH
name: baidu
server:
host: 172.16.0.10
user: root
password: 123456
clone:
disable: true
steps:
- name: docker
commands:
- echo Drone start
- date
- /root/sre/build_genshin.sh
- date
- echo Drone end

9
.gitignore vendored

@ -0,0 +1,9 @@
.idea
go.sum
main.exe
eth.exe
log.txt
logs
*.log
uploads
gin.log

@ -0,0 +1,20 @@
################################################################################
## MAIN STAGE ##
################################################################################
# Copy the manager into the distroless image.
#FROM scratch
#FROM hub.sre.ink/base/distroless-static:nonroot-20210710
#FROM mirror.ccs.tencentyun.com/library/alpine:3.13
FROM alpine:3.15.0
#FROM hub.sre.ink/base/alpine:3.15.0
LABEL Description="原神工具箱"
MAINTAINER sre <sre@yangqiao.org>
RUN echo 'https://mirrors.cloud.tencent.com/alpine/v3.13/main' > /etc/apk/repositories \
&& echo 'https://mirrors.cloud.tencent.com/alpine/v3.13/community' >>/etc/apk/repositories \
&& apk update && apk add tzdata && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone
WORKDIR /app
COPY genshin.bin /app/genshin.bin
RUN chmod 755 /app/genshin.bin
#USER nonroot:nonroot
ENTRYPOINT ["/app/genshin.bin"]

@ -0,0 +1,22 @@
package global
var (
//标识 char
LastRare = 0
LastEpic = 0
//大保底标识 char
LastEpicCommon = false
//当期up角色
UpEpicChar = "夜兰"
//当前UP的4星角色
UpRareChar = []string{"闪耀偶像·芭芭拉(水)", "智明无邪·烟绯(火)", "未授勋之花·诺艾尔(岩)"}
//常驻5星角色
EpicCommonCharactorPool = []string{"迪卢克", "七七", "刻晴", "琴", "莫娜"}
//常驻4星角色
RareChar = []string{"班尼特", "行秋", "迪奥娜", "北斗", "芭芭拉", "烟绯", "诺艾尔"}
)

@ -0,0 +1,11 @@
package global
const (
UseOldApi = "no"
MiCookie = "UM_distincb5801; _MHYUUID=502d6e78-e5ec-480c-98d6-0cfdd5cf60da; mi18nLang=zh-cn; account_id=285923115; ltuid=285923115; _ga_R8CG4VZ69C=GS1.1.1650932768.1.1.1650933672.0; _ga_KPXDK6J368=GS1.1.1653121921.1.1.1653122857.0; _ga_BL22GL4FMD=GS1.1.1655136657.3.1.1655136670.0; _ga_9TTX3TE5YL=GS1.1.1657123701.4.0.1657123701.0; _ga_5DECE6NN1T=GS1.1.1657422258.3.1.1657422260.0; _ga=GA1.2.822707536.1650932589; _ga_N90YRBX6FW=GS1.1.1657422283.15.1.1657423868.0; CNZZDATA1275023096=1119969765-1650922518-%7C1657883174; _gid=GA1.2.1840959498.1657885859; ltoken=31BhDecafgXeaoakn2R9uwwwXckMEkplK7dlbBTq; cookie_token=vugqhRqh5vTcTxIc15gPMH9NYeOsy8Lnwba0mUrJ; _gat=1"
MiUid = "10000"
MiServer = "cn_gf01"
NoticeResinLimit = 120
NoticeHomeCoinLimit = 2000
RequestRate = 8 * 60 //8分钟恢复1点树脂
)

@ -0,0 +1,28 @@
package global
var (
//标识 weapon
LastRareWeapon = 0
LastEpicWeapon = 0
//大保底标识 weapon
LastEpicCommonWeapon = false
//武器定轨开关
WeaponTargetSwitch = true
//武器定轨武器
WeaponTarget = "弓·若水"
//武器定轨数量
WeaponTargetCount = 0
//当期up武器
UpEpicWeapon = []string{"弓·若水", "长柄武器·和璞鸢"}
//当前UP的4星武器
UpRareWeapon = []string{"长柄武器·千岩长枪", "单手剑·祭礼剑", "双手剑·西风大剑", "法器·昭心", "弓·祭礼弓"}
//常驻5星武器
EpicCommonWeaponPool = []string{"狼的末路", "风鹰剑", "天空之卷", "阿莫斯之弓", "天空之翼"}
//常驻4星武器
RareWeapon = []string{"单手剑·祭礼剑", "弓·祭礼弓", "长柄武器·西风长枪", "双手剑·西风大剑", "双手剑·雨裁", "双手剑·钟剑", "法器·昭心"}
//常驻3星武器
CommonItem = []string{"双手剑·以理服人", "双手剑·浴血龙剑", "法器·讨龙", "法器·翡翠法环", "长柄武器·白樱枪", "长柄武器·黑樱枪", "旅行剑"}
)

@ -0,0 +1,5 @@
module GenshinImpact
go 1.18
require github.com/robfig/cron v1.2.0 // indirect

@ -0,0 +1,69 @@
package lottery
import (
"GenshinImpact/global"
"math/rand"
)
// 角色up池
func PickCharUp() string {
if global.LastRare >= 10 {
global.LastRare -= 10
}
if global.LastEpic >= 90 {
global.LastEpic -= 90
}
if global.LastEpic == 89 {
//必出橙色
//fmt.Println("必出橙色-----------------------------------------------------------------------------------------------------------------------")
return RandomEpic()
}
if global.LastRare == 9 {
//必出紫色
//fmt.Println("必出紫色")
return RandomRare()
}
//单抽
//5星概率为0.6% 最多90次必出5星 0-59
//4星概率为5.1% 其中角色2.55% 武器2.55% 最多10次必出4星 255 255
//https://www.bilibili.com/read/cv12616453
//原神抽卡概率工具表 超过73抽后概率增加
//模型五星综合概率为1.6052%期望62.297抽概率在第74抽开始上升。
//作者:一棵平衡树 https://www.bilibili.com/read/cv12616453 出处bilibili
dice := rand.Intn(10000)
adjustRate := 59
if global.LastEpic > 72 {
adjustRate = 660 + 600*(global.LastEpic-72)
}
adjustRateRare := 255 + 255
if global.LastRare == 8 {
//模型四星综合概率为13.057%期望7.6589抽概率在第9抽开始上升。
//作者:一棵平衡树 https://www.bilibili.com/read/cv12616453 出处bilibili
adjustRateRare += 5000
}
switch {
case dice <= adjustRate:
//epic
return RandomEpic()
case dice <= adjustRate+adjustRateRare:
//rare
return RandomRare()
default:
//common item
return RandomCommonItem()
}
}
// 随机取字符串
func RandomStr(sls []string) string {
return sls[rand.Intn(len(sls))]
}
// 常驻3星武器 角色池
func RandomCommonItem() string {
global.LastEpic += 1
global.LastRare += 1
commonItem := global.CommonItem
return commonItem[rand.Intn(len(commonItem))]
}

@ -0,0 +1,33 @@
package lottery
import (
"GenshinImpact/global"
"math/rand"
)
// 5星
func RandomEpic() string {
global.LastEpic = 0
global.LastRare = 0
if global.LastEpicCommon == true {
global.LastEpicCommon = false
return RandomEpicUPCharator()
}
diceUp := rand.Intn(10)
if diceUp <= 4 {
return RandomEpicUPCharator()
}
return RandomEpicCommonCharactor()
}
// 常驻5星角色
func RandomEpicCommonCharactor() string {
global.LastEpicCommon = true
epicCommonCharactorPool := global.EpicCommonCharactorPool
return epicCommonCharactorPool[rand.Intn(len(epicCommonCharactorPool))]
}
// 当期up角色
func RandomEpicUPCharator() string {
return global.UpEpicChar
}

@ -0,0 +1,46 @@
package lottery
import (
"GenshinImpact/global"
"math/rand"
)
// 5星
func RandomEpicWeapon() string {
global.LastEpicWeapon = 0
global.LastRareWeapon = 0
if global.LastEpicCommonWeapon == true {
//当期upWeapon
return RandomEpicUpWeapon()
}
diceUp := rand.Intn(100)
//up5占5星出货75%
if diceUp <= 74 {
//当期upWeapon
return RandomEpicUpWeapon()
}
return RandomEpicCommonWeapon()
}
// UP5星Weapon
func RandomEpicUpWeapon() string {
global.LastEpicCommonWeapon = false
if global.WeaponTargetSwitch {
if global.WeaponTargetCount == 2 {
global.WeaponTargetCount = 0
return global.WeaponTarget
}
global.WeaponTargetCount += 1
}
return RandomStr(global.UpEpicWeapon)
}
// 常驻5星Weapon
func RandomEpicCommonWeapon() string {
global.LastEpicCommonWeapon = true
if global.WeaponTargetSwitch && global.WeaponTargetCount < 2 {
global.WeaponTargetCount += 1
}
return RandomStr(global.EpicCommonWeaponPool)
}

@ -0,0 +1,10 @@
package lottery
import (
"math/rand"
"time"
)
func init() {
rand.Seed(time.Now().UnixNano()) // 纳秒时间戳
}

@ -0,0 +1,69 @@
package lottery
import (
"GenshinImpact/global"
"fmt"
"math/rand"
"strconv"
"testing"
)
func TestPickWeapon(t *testing.T) {
totalRare := 0
totalEpic := 0
epicList := []string{}
preEpicNo := 0 //保存上一个epic号
for i := 1; i <= 240; i++ {
preEpicNo = global.LastEpicWeapon
res := PickWeaponUp()
if global.LastRareWeapon == 0 || global.LastEpicWeapon == 0 {
fmt.Println(i, global.LastRareWeapon, global.LastEpicWeapon, res)
if global.LastRareWeapon == 0 {
totalRare += 1
}
if global.LastEpicWeapon == 0 {
epicList = append(epicList, strconv.Itoa(preEpicNo+1)+res)
totalEpic += 1
}
}
}
fmt.Println("totalRare", totalRare)
fmt.Println("totalEpic", totalEpic)
fmt.Println("epicList", epicList)
}
func TestPickChar(t *testing.T) {
totalRare := 0
totalEpic := 0
epicList := []string{}
preEpicNo := 0 //保存上一个epic号
for i := 1; i <= 10000000; i++ {
preEpicNo = global.LastEpic
res := PickCharUp()
if global.LastRare == 0 || global.LastEpic == 0 {
//fmt.Println(i, global.LastRare, global.LastEpic, res)
if global.LastRare == 0 {
totalRare += 1
}
if global.LastEpic == 0 {
epicList = append(epicList, strconv.Itoa(preEpicNo+1)+res)
totalEpic += 1
}
}
}
fmt.Println("totalRare", totalRare)
fmt.Println("totalEpic", totalEpic)
fmt.Println("totalEpic/total", 10000000.00/totalEpic)
fmt.Println("epicList", epicList)
}
func TestRandom(t *testing.T) {
for {
fmt.Println(rand.Intn(10))
}
}

@ -0,0 +1,24 @@
package lottery
import (
"GenshinImpact/global"
"math/rand"
)
// 4星物品
func RandomRare() string {
global.LastRare = 0
global.LastEpic += 1
diceUp := rand.Intn(10)
if diceUp <= 4 {
//当前UP的4星角色
return RandomStr(global.UpRareChar)
}
diceChar := rand.Intn(10)
if diceChar <= 4 {
//常驻4星角色
return RandomStr(global.RareChar)
}
//常驻4星武器
return RandomStr(global.RareWeapon)
}

@ -0,0 +1,26 @@
package lottery
import (
"GenshinImpact/global"
"math/rand"
)
// 4星Weapon
func RandomRareWeapon() string {
global.LastRareWeapon = 0
global.LastEpicWeapon += 1
diceUp := rand.Intn(100)
//up4占4星出货75%
if diceUp <= 74 {
//当前UP的4星Weapon
return RandomStr(global.UpRareWeapon)
}
diceChar := rand.Intn(10)
//4星概率为6% 其中角色3% 武器3%
if diceChar <= 4 {
//常驻4星角色
return RandomStr(global.RareChar)
}
//常驻4星武器
return RandomStr(global.RareWeapon)
}

@ -0,0 +1,68 @@
package lottery
import (
"GenshinImpact/global"
"math/rand"
)
// 武器up池
func PickWeaponUp() string {
if global.LastRareWeapon >= 9 {
global.LastRareWeapon -= 9
}
if global.LastEpicWeapon >= 80 {
global.LastEpicWeapon -= 80
}
//保底
if global.LastEpicWeapon == 79 {
//必出橙色
//fmt.Println("必出橙色-----------------------------------------------------------------------------------------------------------------------")
return RandomEpicWeapon()
}
if global.LastRareWeapon == 9 {
//必出紫色
//fmt.Println("必出紫色")
return RandomRareWeapon()
}
//单抽
//up5占5星出货75%
//up4占4星出货75%
//5星概率为0.7% 最多80次必出5星
//4星概率为6% 其中角色3% 武器3% 最多10次必出4星
//当起源到4星时 75%为up武器
//如果本次不是当期up 下一个一定是up
//https://www.bilibili.com/read/cv12616453
//模型五星综合概率为1.8779%期望53.250抽概率在第63抽开始上升保底位置实为第77抽而非公示的第80抽。
//作者:一棵平衡树 https://www.bilibili.com/read/cv12616453 出处bilibili
//模型四星综合概率为14.857%期望6.7309抽概率在第8抽开始上升保底位置实为第9抽而非公示的第10抽。
//作者:一棵平衡树 https://www.bilibili.com/read/cv12616453 出处bilibili
dice := rand.Intn(10000)
adjustRateWeapon := 69
if global.LastEpicWeapon > 61 {
adjustRateWeapon = 770 + 700*(global.LastEpicWeapon-61)
}
adjustRateRareWeapon := 300 + 300
if global.LastRareWeapon == 7 {
adjustRateRareWeapon += 6000
}
switch {
case dice <= adjustRateWeapon:
//epic
return RandomEpicWeapon()
case dice <= adjustRateWeapon+adjustRateRareWeapon:
//rare
return RandomRareWeapon()
default:
//常驻3星武器
return RandomCommonItemWeapon()
}
}
// 常驻3星武器 武器池
func RandomCommonItemWeapon() string {
global.LastEpicWeapon += 1
global.LastRareWeapon += 1
commonItem := global.CommonItem
return commonItem[rand.Intn(len(commonItem))]
}

@ -0,0 +1,19 @@
package main
import (
"GenshinImpact/mihoyo"
"fmt"
"github.com/robfig/cron"
)
func main() {
c := cron.New()
//树脂每8分钟恢复1点
//晚七点到晚上24点前提醒 工作日
c.AddFunc("0 */8 19-23 * * 1-5", func() { go mihoyo.BeginWorkDay() })
//早七点到晚上24点前提醒 周末
c.AddFunc("0 */8 7-23 * * 0,6", func() { go mihoyo.BeginWorkEnd() })
fmt.Println("任务注册成功")
c.Start()
select {}
}

@ -0,0 +1,58 @@
package mihoyo
import (
"encoding/json"
"fmt"
"net/http"
"time"
)
type MiyoRequest struct {
url string
headers map[string]string
}
type MiyoResponse struct {
RetCode int `json:"retcode"`
Message string `json:"message"`
Data json.RawMessage `json:"data"`
}
func NewMiyoRequest(url string) *MiyoRequest {
return &MiyoRequest{
url,
map[string]string{
"Accept": "application/json",
},
}
}
func (th *MiyoRequest) Execute() ([]byte, error) {
client := &http.Client{Timeout: 60 * time.Second}
req, err := http.NewRequest(http.MethodGet, th.url, nil)
if err != nil {
return []byte{}, err
}
for k, v := range th.headers {
req.Header.Set(k, v)
}
resp, err := client.Do(req)
if err != nil {
return []byte{}, err
}
defer resp.Body.Close()
dec := json.NewDecoder(resp.Body)
var miyoResp MiyoResponse
err = dec.Decode(&miyoResp)
if err != nil {
return []byte{}, err
}
if miyoResp.RetCode != 0 {
return []byte{}, fmt.Errorf("errcode: %d, errmsg: %s", miyoResp.RetCode, miyoResp.Message)
}
return miyoResp.Data, nil
}
func (th *MiyoRequest) SetHeader(k, v string) {
th.headers[k] = v
}

@ -0,0 +1,42 @@
package mihoyo
type GenshinDailyNote struct {
CurrentResin int `json:"current_resin"`
MaxResin int `json:"max_resin"`
ResinRecoveryTime string `json:"resin_recovery_time"`
FinishedTaskNum int `json:"finished_task_num"`
TotalTaskNum int `json:"total_task_num"`
IsExtraTaskRewardReceived bool `json:"is_extra_task_reward_received"`
RemainResinDiscountNum int `json:"remain_resin_discount_num"`
ResinDiscountNumLimit int `json:"resin_discount_num_limit"`
CurrentExpeditionNum int `json:"current_expedition_num"`
MaxExpeditionNum int `json:"max_expedition_num"`
Expeditions []GameRoleExpedition `json:"expeditions"`
CurrentHomeCoin int `json:"current_home_coin"`
MaxHomeCoin int `json:"max_home_coin"`
HomeCoinRecoveryTime string `json:"home_coin_recovery_time"`
CalendarUrl string `json:"calendar_url"`
Transformer TransformerInfo `json:"transformer"`
}
type GameRoleExpedition struct {
AvatarSideIconLink string `json:"avatar_side_icon"`
Status string `json:"status"`
RemainedTime string `json:"remained_time"`
}
type TransformerInfo struct {
Obtained bool `json:"obtained"`
RecTime TransformerRecTime `json:"recovery_time"`
Wiki string `json:"wiki"`
Noticed bool `json:"noticed"`
LatestJobId string `json:"latest_job_id"`
}
type TransformerRecTime struct {
Day int `json:"Day"`
Hour int `json:"Hour"`
Minute int `json:"Minute"`
Second int `json:"Second"`
Reached bool `json:"reached"`
}

@ -0,0 +1,77 @@
package mihoyo
import (
"GenshinImpact/global"
"GenshinImpact/thirdpart"
"fmt"
"strconv"
)
func BeginWorkDay() {
note, err := GetGenshinDailyNote(global.MiCookie, global.MiUid, global.MiServer)
if err != nil {
fmt.Println(err.Error())
thirdpart.SendWechat("请求米哈游服务器失败:" + err.Error())
}
if note.CurrentResin >= global.NoticeResinLimit {
thirdpart.SendWechat("树脂达到限制:" + strconv.Itoa(note.CurrentResin))
NoticeTransformer(note)
NoticeHomeCoin(note)
}
if !note.IsExtraTaskRewardReceived {
if note.FinishedTaskNum < 4 {
thirdpart.SendWechat("今日委托任务未完成")
} else {
thirdpart.SendWechat("今日委托奖励未领取")
}
NoticeTransformer(note)
NoticeHomeCoin(note)
}
}
func BeginWorkEnd() {
note, err := GetGenshinDailyNote(global.MiCookie, global.MiUid, global.MiServer)
if err != nil {
fmt.Println(err.Error())
thirdpart.SendWechat("请求米哈游服务器失败:" + err.Error())
}
if note.CurrentResin >= global.NoticeResinLimit {
thirdpart.SendWechat("树脂达到限制:" + strconv.Itoa(note.CurrentResin))
NoticeTransformer(note)
NoticeHomeCoin(note)
}
if !note.IsExtraTaskRewardReceived {
if note.FinishedTaskNum < 4 {
thirdpart.SendWechat("今日委托任务未完成")
} else {
thirdpart.SendWechat("今日委托奖励未领取")
}
NoticeTransformer(note)
NoticeHomeCoin(note)
}
//周末再统计boss周本信息
NoticeWeeklyBoos(note)
}
func NoticeHomeCoin(note *GenshinDailyNote) {
if note.CurrentHomeCoin >= global.NoticeHomeCoinLimit {
thirdpart.SendWechat("洞天宝钱达到限制:" + strconv.Itoa(note.CurrentHomeCoin))
}
}
func NoticeWeeklyBoos(note *GenshinDailyNote) {
if note.RemainResinDiscountNum > 0 {
thirdpart.SendWechat("本周BOOS未刷完剩余" + strconv.Itoa(note.RemainResinDiscountNum) + "次")
}
}
func NoticeTransformer(note *GenshinDailyNote) {
if note.Transformer.RecTime.Reached {
thirdpart.SendWechat("参量质变仪已就绪")
}
}

@ -0,0 +1,78 @@
package mihoyo
import (
"GenshinImpact/global"
"GenshinImpact/utils"
"encoding/json"
"errors"
"fmt"
"strings"
)
type GameRoleList struct {
List []GameRole `json:"list"`
}
type GameRole struct {
Uid string `json:"game_uid"`
NickName string `json:"nickname"`
Region string `json:"region"`
RegionName string `json:"region_name"`
}
func GetUserGameRoles(cookie string) ([]GameRole, error) {
mr := NewMiyoRequest("https://api-takumi.mihoyo.com/binding/api/getUserGameRolesByCookie?game_biz=hk4e_cn")
mr.SetHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) miHoYoBBS/2.11.1")
mr.SetHeader("Referer", "https://webstatic.mihoyo.com/app/community-game-records/index.html?v=6")
mr.SetHeader("Cookie", cookie)
mr.SetHeader("X-Requested-With", "com.mihoyo.hyperion")
data, err := mr.Execute()
if err != nil {
return nil, err
}
roleList := GameRoleList{}
json.Unmarshal(data, &roleList)
if len(roleList.List) == 0 {
return nil, errors.New("没有找到绑定的角色")
}
return roleList.List, nil
}
func GetUserGameRoleByUid(cookie string, uid string) (*GameRole, error) {
roles, err := GetUserGameRoles(cookie)
if err != nil {
return nil, err
}
for i := range roles {
if roles[i].Uid == uid {
return &roles[i], nil
}
}
return nil, errors.New("没有找到UID为" + uid + "的角色")
}
func GetGenshinDailyNote(cookie, uid, server string) (*GenshinDailyNote, error) {
dailyNoteApi := func(useOld string) string {
if strings.EqualFold(useOld, "yes") {
return "https://api-takumi.mihoyo.com/game_record/app/genshin/api/dailyNote"
} else {
return "https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/dailyNote"
}
}(global.UseOldApi)
url := fmt.Sprintf("%s?server=%s&role_id=%s", dailyNoteApi, server, uid)
mr := NewMiyoRequest(url)
mr.SetHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) miHoYoBBS/2.11.1")
mr.SetHeader("Referer", "https://webstatic.mihoyo.com/app/community-game-records/index.html?v=6")
mr.SetHeader("Cookie", cookie)
mr.SetHeader("X-Requested-With", "com.mihoyo.hyperion")
appType, appVersion, DS := utils.GetDS(mr.url, "")
mr.SetHeader("x-rpc-client_type", appType)
mr.SetHeader("x-rpc-app_version", appVersion)
mr.SetHeader("DS", DS)
data, err := mr.Execute()
if err != nil {
return nil, err
}
dailyNote := GenshinDailyNote{}
json.Unmarshal(data, &dailyNote)
return &dailyNote, nil
}

@ -0,0 +1,91 @@
package mihoyo
import (
"GenshinImpact/global"
"fmt"
"testing"
)
func TestGetUserGameRoles(t *testing.T) {
//cookie := "_MHYUUc0da99476341-03ea061453bd79-b7a193d-1fa400-17c0da994774b4; mi18nLang=zh-cn; _ga_6BQ6ZYZ4YR=GS1.1.1633508240.1.1.1633508446.0; _ga_YQPW66MJ73=GS1.1.1634521273.2.1.1634521348.0; _gid=GA1.2.1068721196.1635730970; ltoken=Idy4cRzSH6WpeJ8FumxXkQTSwanMDNrOGRJmNXtW; ltuid=285923115;cookie_token=8PnCRXkDdLuOO3ARsZ2R4q026Rz0zSuXHtYtzxlF; account_id=285923115; _ga_9TTX3TE5YL=GS1.1.1635824302.10.0.1635824302.0;CNZZDATA1275023096=469636296-1634047771-%7C1635902038; _ga=GA1.2.601055352.1632719707; _ga_4PPV2TWM03=GS1.1.1635905077.4.1.1635905272.0; _gat_gtag_UA_133007358_5=1"
//cookie := "UM_distin4-4f52-4efa-86fe-0fc38bab41bd; CNZZDATA1274689524=1398771365-1657883224-%7C1657883224; DEVICEFP_SEED_ID=79a5168fe5fe2d89; DEVICEFP_SEED_TIME=1657883475835; DEVICEFP=38d7eab17bad9; login_uid=285923115; login_ticket=mnve82eLl77Crj48JvUMSrOR20b9qSCD5TJLPIPe"
roles, err := GetUserGameRoles(global.MiCookie)
if err != nil {
fmt.Println(err.Error())
return
}
for index, role := range roles {
fmt.Println(index)
fmt.Println(role.Region)
fmt.Println(role.RegionName)
fmt.Println(role.NickName)
fmt.Println(role.Uid)
}
//0
//cn_gf01
//天空岛
//十里坡
//186044778
}
func TestGetUserGameRoleByUid(t *testing.T) {
cookie := "_MHYa994774b4; mi18nLang=zh-cn; _ga_6BQ6ZYZ4YR=GS1.1.1633508240.1.1.1633508446.0; _ga_YQPW66MJ73=GS1.1.1634521273.2.1.1634521348.0; _gid=GA1.2.1068721196.1635730970; ltoken=Idy4cRzSH6WpeJ8FumxXkQTSwanMDNrOGRJmNXtW; ltuid=285923115;cookie_token=8PnCRXkDdLuOO3ARsZ2R4q026Rz0zSuXHtYtzxlF; account_id=285923115; _ga_9TTX3TE5YL=GS1.1.1635824302.10.0.1635824302.0;CNZZDATA1275023096=469636296-1634047771-%7C1635902038; _ga=GA1.2.601055352.1632719707; _ga_4PPV2TWM03=GS1.1.1635905077.4.1.1635905272.0; _gat_gtag_UA_133007358_5=1"
uid := "1000000"
role, err := GetUserGameRoleByUid(cookie, uid)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(role.Region)
fmt.Println(role.RegionName)
fmt.Println(role.NickName)
fmt.Println(role.Uid)
}
// test for GenshinDailyNote
func TestAlert(t *testing.T) {
//test for Alert
note, err := GetGenshinDailyNote(global.MiCookie, global.MiUid, global.MiServer)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(note)
fmt.Println(note.CurrentResin)
}
func TestGetGenshinDailyNote(t *testing.T) {
cookie := "_MHYU.1.1.1633508446.0; _ga_YQPW66MJ73=GS1.1.1634521273.2.1.1634521348.0; _gid=GA1.2.1068721196.1635730970; ltoken=Idy4cRzSH6WpeJ8FumxXkQTSwanMDNrOGRJmNXtW; ltuid=285923115;cookie_token=8PnCRXkDdLuOO3ARsZ2R4q026Rz0zSuXHtYtzxlF; account_id=285923115; _ga_9TTX3TE5YL=GS1.1.1635824302.10.0.1635824302.0;CNZZDATA1275023096=469636296-1634047771-%7C1635902038; _ga=GA1.2.601055352.1632719707; _ga_4PPV2TWM03=GS1.1.1635905077.4.1.1635905272.0; _gat_gtag_UA_133007358_5=1"
uid := "100000"
server := "cn_gf01"
note, err := GetGenshinDailyNote(cookie, uid, server)
if err != nil {
fmt.Println(err.Error())
return
}
//fmt.Println(note.CurrentResin) //当前树脂
//fmt.Println(note.MaxResin) //树脂容量
//fmt.Println(note.ResinRecoveryTime) //树脂充满时间s
//fmt.Println(note.FinishedTaskNum) //树脂充满时间s
//fmt.Println(note.TotalTaskNum) //树脂充满时间s
//fmt.Println(note.IsExtraTaskRewardReceived) //树脂充满时间s
//fmt.Println(note.RemainResinDiscountNum) //树脂充满时间s
//fmt.Println(note.ResinDiscountNumLimit) //树脂充满时间s
//fmt.Println(note.CurrentExpeditionNum) //5
//fmt.Println(note.MaxExpeditionNum) //5
//fmt.Println(note.Expeditions) //[{https://upload-bbs.mihoyo.com/game_record/genshin/character_side_icon/UI_AvatarIcon_Side_Ambor.png Finished 0} {https://upload-bbs.mihoyo.com/game_record/genshin/character_side_icon/UI_AvatarIcon_Side_Fischl.png Finished 0} {https://upload-bbs.mihoyo.com/game_record/genshin/character_side_icon/UI_AvatarIcon_Side_Bennett.png Finished 0} {https://upload-bbs.mihoyo.com/game_record/genshin/character_side_icon/UI_AvatarIcon_Side_Sara.png Finished 0} {https://upload-bbs.mihoyo.com/game_record/genshin/character_side_icon/UI_AvatarIcon_Side_Shinobu.png Finished 0}]
//
//fmt.Println(note.CurrentHomeCoin) //洞天宝钱
//fmt.Println(note.MaxHomeCoin) //洞天宝钱
//fmt.Println(note.HomeCoinRecoveryTime) //充满时间s
//fmt.Println(note.CalendarUrl) //充满时间s
fmt.Println(note.Transformer) //{true {2 0 0 0 false}} 转化仪
fmt.Println(note.Transformer.RecTime.Reached)
NoticeTransformer(note)
//"transformer":{"obtained":true,"recovery_time":{"Day":2,"Hour":0,"Minute":0,"Second":0,"reached":false}
//{true {0 0 0 0 true} https://bbs.mihoyo.com/ys/obc/content/1562/detail?bbs_presentation_style=no_header false 0}
//{"current_resin":117,"max_resin":160,"resin_recovery_time":"20216","finished_task_num":0,"total_task_num":4,"is_extra_task_reward_received":false,"remain_resin_discount_num":0,"resin_discount_num_limit":3,"current_expedition_num":5,"max_expedition_num":5,"expeditions":[{"avatar_side_icon":"https://upload-bbs.mihoyo.com/game_record/genshin/character_side_icon/UI_AvatarIcon_Side_Ambor.png","status":"Finished","remained_time":"0"},{"avatar_side_icon":"https://upload-bbs.mihoyo.com/game_record/genshin/character_side_icon/UI_AvatarIcon_Side_Fischl.png","status":"Finished","remained_time":"0"},{"avatar_side_icon":"https://upload-bbs.mihoyo.com/game_record/genshin/character_side_icon/UI_AvatarIcon_Side_Bennett.png","status":"Finished","remained_time":"0"},{"avatar_side_icon":"https://upload-bbs.mihoyo.com/game_record/genshin/character_side_icon/UI_AvatarIcon_Side_Sara.png","status":"Finished","remained_time":"0"},{"avatar_side_icon":"https://upload-bbs.mihoyo.com/game_record/genshin/character_side_icon/UI_AvatarIcon_Side_Shinobu.png","status":"Finished","remained_time":"0"}],"current_home_coin":810,"max_home_coin":2400,"home_coin_recovery_time":"190773","calendar_url":"","transformer":{"obtained":true,"recovery_time":{"Day":2,"Hour":0,"Minute":0,"Second":0,"reached":false},"wiki":"https://bbs.mihoyo.com/ys/obc/content/1562/detail?bbs_presentation_style=no_header","noticed":false,"latest_job_id":"0"}}
}

@ -0,0 +1,62 @@
[![Build Status](https://xxx/api/badges/sre/GenshinImpact/status.svg)](https://xxx/GenshinImpact)
原神工具箱
***
## build amd64 on tx ecs
```bash
cd /root
rm -rf GenshinImpact
git clone https://git.sre.ink/go/GenshinImpact.git
cd GenshinImpact
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on GOPROXY="https://goproxy.cn,direct" go mod tidy
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on GOPROXY="https://goproxy.cn,direct" go build -v -a -o genshin.bin main.go
docker build -t sre/genshin:amd64 .
docker rm -f genshin
docker run --name genshin --restart always -d sre/genshin:amd64
docker logs -f genshin
```
## build arm64 on oracle
```bash
cd /root
rm -rf GenshinImpact
git clone https://git.sre.ink/go/GenshinImpact.git
cd GenshinImpact
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 GO111MODULE=on go mod tidy
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 GO111MODULE=on go build -v -a -o genshin.bin main.go
docker build -t sre/genshin:arm64 .
docker rm -f genshin
docker run --name genshin --restart always -d sre/genshin:arm64
docker logs -f genshin
```
# mihoyo bbs get cookie 获取米游社Cookie
将下列地址存为书签
```javascript
var cookie=document.cookie;var ask=confirm('Cookie:'+cookie+'\n\nDo you want to copy the cookie to the clipboard?');if(ask==true){copy(cookie);msg=cookie}else{msg='Cancel'}
```
登录后点击即可。
# up char
当期up占5星出率的50% 1个
当期up占4星出率的50% 3个
5星概率为0.6% 最多90次必出5星
4星概率为5.1% 其中角色2.55% 武器2.55% 最多10次必出4星
# up weapon
up5占5星出货75%
up4占4星出货75%
5星概率为0.7% 最多80次必出5星
4星概率为6% 其中角色3% 武器3% 最多10次必出4星
当起源到4星时 75%为up武器
如果本次不是当期up 下一个一定是up
# notice
https://github.com/dustoair/genshin-daily-notice
# Golang 定时任务 github/robfig/cron/v3
https://blog.csdn.net/zjbyough/article/details/113853582

@ -0,0 +1,114 @@
package thirdpart
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"reflect"
)
var WECOM_CID string = GetEnvDefault("WECOM_CID", "eeeeeeeee")
var WECOM_SECRET string = GetEnvDefault("WECOM_SECRET", "eeeeeeeeeeeeeeeeeeeeeeeee")
var WECOM_AID string = GetEnvDefault("WECOM_AID", "100000000")
var WECOM_TOUID string = GetEnvDefault("WECOM_TOUID", "eeeeeee")
var REDIS_STAT string = GetEnvDefault("REDIS_STAT", "OFF")
var REDIS_PASSWORD string = GetEnvDefault("REDIS_PASSWORD", "")
var ctx = context.Background()
func GetEnvDefault(key, defVal string) string {
val, ex := os.LookupEnv(key)
if !ex {
return defVal
}
return val
}
func praser_json(json_str string) map[string]interface{} {
var wecom_response map[string]interface{}
if string(json_str) != "" {
err := json.Unmarshal([]byte(string(json_str)), &wecom_response)
if err != nil {
log.Println("生成json字符串错误")
}
}
return wecom_response
}
func get_token(corpid, app_secret string) string {
resp, err := http.Get("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpid + "&corpsecret=" + app_secret)
if err != nil {
log.Println(err)
}
defer resp.Body.Close()
resp_data, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Println(err)
}
token_response := praser_json(string(resp_data))
return token_response["access_token"].(string)
}
func post_msg(text_msg, msg_type, post_url string) string {
type msg struct {
Content string `json:"content"`
}
type JsonData struct {
Touser string `json:"touser"`
Agentid string `json:"agentid"`
Msgtype string `json:"msgtype"`
Text msg `json:"text"`
Duplicate_check_interval int `json:"duplicate_check_interval"`
}
post_data := JsonData{
Touser: WECOM_TOUID,
Agentid: WECOM_AID,
Msgtype: msg_type,
Duplicate_check_interval: 600,
Text: msg{Content: text_msg},
}
post_json, _ := json.Marshal(post_data)
log.Println(string(post_json))
msg_req, err := http.NewRequest("POST", post_url, bytes.NewBuffer(post_json))
if err != nil {
log.Println(err)
}
msg_req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(msg_req)
if err != nil {
panic(err)
}
defer msg_req.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
return string(body)
}
func IsZero(v interface{}) (bool, error) {
t := reflect.TypeOf(v)
if !t.Comparable() {
return false, fmt.Errorf("type is not comparable: %v", t)
}
return v == reflect.Zero(t).Interface(), nil
}
func SendWechat(msg string) {
access_token := get_token(WECOM_CID, WECOM_SECRET)
post_url := "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + access_token
msg_type := "text"
post_status := post_msg(msg, msg_type, post_url)
log.Println(post_status)
post_response := praser_json(string(post_status))
log.Println(post_response)
errcode := post_response["errcode"]
_, err := IsZero(errcode)
if err != nil {
fmt.Printf("%v", err)
}
}

@ -0,0 +1,111 @@
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 true0
* timeRangeStrfalse, 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
}
Loading…
Cancel
Save