diff --git a/cmd/v2/lib/common/constant.go b/cmd/v2/lib/common/constant.go index 15984dd3a..522351d0a 100644 --- a/cmd/v2/lib/common/constant.go +++ b/cmd/v2/lib/common/constant.go @@ -23,5 +23,6 @@ const ( const ( BOLTDB_NAME = "my.db" BOLTDB_BUCKETNAME = "robotBucket" - BUCKET_CONF = "gen" + BUCKET_LUBANCONF = "lubanConf" + BUCKET_SSHCONF = "sshConf" ) diff --git a/cmd/v2/lib/common/lang.go b/cmd/v2/lib/common/lang.go index 6e15edcbe..43b1f030a 100644 --- a/cmd/v2/lib/common/lang.go +++ b/cmd/v2/lib/common/lang.go @@ -92,6 +92,7 @@ const ( TOOLBAR_GEN = "生成代码" TOOLBAR_SEC = "密码器" TOOLBAR_WEL = "欢迎" + TOOLBAR_TERM = "终端" //monitor APP_MONITOR_TITLE_ID = "编号" diff --git a/cmd/v2/model/item.go b/cmd/v2/model/item.go index 7b37d229c..d5f68c385 100644 --- a/cmd/v2/model/item.go +++ b/cmd/v2/model/item.go @@ -17,8 +17,8 @@ func NewItemModelList() *ItemModelList { func (s *ItemModelList) AsInterfaceArray() []interface{} { rs := make([]interface{}, len(s.DataList)) - for i := range s.DataList { - rs[i] = s.DataList[i] + for i, v := range s.DataList { + rs[i] = v } return rs } diff --git a/cmd/v2/model/ssh.go b/cmd/v2/model/ssh.go new file mode 100644 index 000000000..524789cbb --- /dev/null +++ b/cmd/v2/model/ssh.go @@ -0,0 +1,7 @@ +package model + +type SSHModel struct { + Ip string + UserName string + Password string +} diff --git a/cmd/v2/service/dbServer.go b/cmd/v2/service/dbServer.go index 7b75de9b5..288d0d527 100644 --- a/cmd/v2/service/dbServer.go +++ b/cmd/v2/service/dbServer.go @@ -6,7 +6,6 @@ import ( "go_dreamfactory/cmd/v2/lib/common" "go_dreamfactory/cmd/v2/model" "log" - "sync" "time" "github.com/boltdb/bolt" @@ -14,9 +13,12 @@ import ( ) type DbService interface { - Save(conf *model.GenTool) error - Update() error - Get(key string) *model.GenTool + // 保存鲁班工具配置 + SaveLubanConf(conf *model.GenTool) error + // 获取鲁班工具配置 + GetLubanConf(key string) *model.GenTool + // 保存SSH连接信息 + SaveSSHConf(conf *model.SSHModel) error } type DbServiceImpl struct { @@ -33,11 +35,11 @@ func GetDbService() DbService { return dbservice } -func (this *DbServiceImpl) Save(conf *model.GenTool) error { +func (this *DbServiceImpl) save(key string, model interface{}) error { boltDb = GetBoltDb() defer boltDb.Close() if err := boltDb.Update(func(tx *bolt.Tx) error { - b, err2 := json.Marshal(conf) + b, err2 := json.Marshal(model) if err2 != nil { return err } @@ -45,7 +47,7 @@ func (this *DbServiceImpl) Save(conf *model.GenTool) error { if c == nil { return fmt.Errorf("Bucket %s not found!", common.BOLTDB_BUCKETNAME) } - return c.Put([]byte(common.BUCKET_CONF), b) + return c.Put([]byte(key), b) }); err != nil { logrus.Errorf("save err: %v", err) return err @@ -53,42 +55,66 @@ func (this *DbServiceImpl) Save(conf *model.GenTool) error { return nil } -func (this *DbServiceImpl) Get(key string) *model.GenTool { +func (this *DbServiceImpl) get(key string, model interface{}) (b *bolt.Bucket, err error) { boltDb = GetBoltDb() - defer boltDb.Close() - conf := &model.GenTool{} - if err := boltDb.View(func(tx *bolt.Tx) error { - c := tx.Bucket([]byte(common.BOLTDB_BUCKETNAME)) - if c == nil { + if err = boltDb.View(func(tx *bolt.Tx) error { + b = tx.Bucket([]byte(common.BOLTDB_BUCKETNAME)) + if b == nil { return fmt.Errorf("Bucket %s not found!", common.BOLTDB_BUCKETNAME) } - - val := c.Get([]byte(key)) - if err := json.Unmarshal(val, conf); err != nil { - logrus.Errorf("get gen conf err:%v", err) - return err - } return nil }); err != nil { logrus.Errorf("get db conf err: %v", err) - return nil + return nil, err } - return conf + return b, nil } -func (this *DbServiceImpl) Update() error { - return nil +func (this *DbServiceImpl) SaveLubanConf(conf *model.GenTool) error { + return this.save(common.BUCKET_LUBANCONF, conf) +} + +func (this *DbServiceImpl) GetLubanConf(key string) *model.GenTool { + defer boltDb.Close() + model := &model.GenTool{} + if b, err := this.get(key, model); err != nil { + return nil + } else { + val := b.Get([]byte(key)) + if err = json.Unmarshal(val, model); err != nil { + logrus.Errorf("get gen conf err:%v", err) + return nil + } + } + return model +} + +func (this *DbServiceImpl) SaveSSHConf(conf *model.SSHModel) error { + return this.save(common.BUCKET_SSHCONF, conf) +} + +func (this *DbServiceImpl) GetSSHConf(key string) *model.SSHModel { + defer boltDb.Close() + model := &model.SSHModel{} + if b, err := this.get(key, model); err != nil { + return nil + } else { + val := b.Get([]byte(key)) + if err = json.Unmarshal(val, model); err != nil { + logrus.Errorf("get gen conf err:%v", err) + return nil + } + } + return model } var ( boltDb *bolt.DB bucket *bolt.Bucket - once sync.Once err error ) func GetBoltDb() *bolt.DB { - // once.Do(func() { boltDb, err = bolt.Open(common.BOLTDB_NAME, 0600, &bolt.Options{Timeout: 5 * time.Second}) if err != nil { log.Fatal(err) @@ -106,6 +132,5 @@ func GetBoltDb() *bolt.DB { } return nil }) - // }) return boltDb } diff --git a/cmd/v2/service/pttService.go b/cmd/v2/service/pttService.go index 45c0699ca..cb13cf159 100644 --- a/cmd/v2/service/pttService.go +++ b/cmd/v2/service/pttService.go @@ -61,6 +61,7 @@ func (p *PttServiceImpl) SendToClient(mainType, subType string, rsp proto.Messag now := time.Now() if err = p.connService.SendMsg(msg, rsp); err != nil { logrus.WithField("err", err).Error(err) + return err } p.obs.Notify(observer.EVENT_RST, now) return diff --git a/cmd/v2/service/sshService.go b/cmd/v2/service/sshService.go new file mode 100644 index 000000000..9da6c4607 --- /dev/null +++ b/cmd/v2/service/sshService.go @@ -0,0 +1,98 @@ +package service + +import ( + "fmt" + "io/ioutil" + "net" + "time" + + "golang.org/x/crypto/ssh" +) + +type SSHService struct { +} + +func NewSSHService() *SSHService { + return &SSHService{} +} + +func (ss *SSHService) Connect(user, password, host, key string, port int, cipherList []string) (*ssh.Session, error) { + var ( + auth []ssh.AuthMethod //认证方式 + addr string + clientConfig *ssh.ClientConfig + client *ssh.Client + config ssh.Config + session *ssh.Session + err error + ) + auth = make([]ssh.AuthMethod, 0) + if key == "" { + // 密码认证 + auth = append(auth, ssh.Password(password)) + } else { + // 秘钥认证 + pemBytes, err := ioutil.ReadFile(key) + if err != nil { + return nil, err + } + + var signer ssh.Signer + if password == "" { + signer, err = ssh.ParsePrivateKey(pemBytes) + } else { + signer, err = ssh.ParsePrivateKeyWithPassphrase(pemBytes, []byte(password)) + } + + if err != nil { + return nil, err + } + // 加载秘钥 + auth = append(auth, ssh.PublicKeys(signer)) + } + + // 设置ssh 的配置参数 + if len(cipherList) == 0 { + config = ssh.Config{ + // 连接所允许的加密算法, go的SSH包允许的算法 + Ciphers: []string{"aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "aes192-cbc", "aes256-cbc"}, + } + } else { + config = ssh.Config{ + Ciphers: cipherList, + } + } + + clientConfig = &ssh.ClientConfig{ + User: user, + Auth: auth, + Timeout: time.Second * 30, + Config: config, + // 默认密钥不受信任时,Go 的 ssh 包会在 HostKeyCallback 里把连接干掉(1.8 之后加的应该)。但是我们使用用户名密码连接的时候,这个太正常了,所以让他 return nil 就好了 + HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error { + return nil + }, + } + addr = fmt.Sprintf("%s:%d", host, port) + + if client, err = ssh.Dial("tcp", addr, clientConfig); err != nil { + return nil, err + } + + if session, err = client.NewSession(); err != nil { + return nil, err + } + + // 使用 session.Shell() 模拟终端时,所建立的终端参数 + modes := ssh.TerminalModes{ + ssh.ECHO: 0, //disable echoing + ssh.TTY_OP_ISPEED: 14400, //input speed=14.4kbaud + ssh.TTY_OP_OSPEED: 14400, + } + + if err := session.RequestPty("xterm", 80, 40, modes); err != nil { + return nil, err + } + + return session, nil +} diff --git a/cmd/v2/service/ssh_test.go b/cmd/v2/service/ssh_test.go new file mode 100644 index 000000000..a7cd1ef36 --- /dev/null +++ b/cmd/v2/service/ssh_test.go @@ -0,0 +1,53 @@ +package service + +import ( + "bytes" + "strings" + "testing" +) + +const ( + username = "root" + password = "Legu.cc()123" + ip = "10.0.0.9" + port = 22 + cmd = "ls" + cmds = "cd /home/liwei/go_dreamfactory&&git pull&&exit" //exit结尾,否则程序不会退出 +) + +func TestSSHConnect(t *testing.T) { + ciphers := []string{} + ssh := &SSHService{} + + session, err := ssh.Connect(username, password, ip, "", port, ciphers) + if err != nil { + t.Fatal(err) + } + defer session.Close() + + cmdlist := strings.Split(cmds, "&&") + stdinBuf, err := session.StdinPipe() + if err != nil { + t.Fatal(err) + } + + var stdoutBuf, errBuf bytes.Buffer + session.Stdout = &stdoutBuf + session.Stderr = &errBuf + + if err := session.Shell(); err != nil { + t.Error(err) + } + + for _, c := range cmdlist { + c = c + "\n" + stdinBuf.Write([]byte(c)) + } + + session.Wait() + t.Logf(stdoutBuf.String() + errBuf.String()) + // if err := session.Run(cmd); err != nil { + // t.Logf("run err: %v", err) + // } + // t.Logf("res: %v", session.Stdout) +} diff --git a/cmd/v2/ui/app_interface.go b/cmd/v2/ui/app_interface.go index d0baaa835..726a1ba64 100644 --- a/cmd/v2/ui/app_interface.go +++ b/cmd/v2/ui/app_interface.go @@ -24,6 +24,7 @@ var ( &appWelcome{}, &appGen{}, &appLock{}, + &appTerm{}, } ) diff --git a/cmd/v2/ui/protocol.go b/cmd/v2/ui/protocol.go index 0f71c6603..8a80f470a 100644 --- a/cmd/v2/ui/protocol.go +++ b/cmd/v2/ui/protocol.go @@ -291,6 +291,19 @@ var ( Req: &pb.TaskListReq{}, Rsp: &pb.TaskListResp{}, Enabled: true, + Print: func(rsp proto.Message) string { + in := rsp.(*pb.UserMessage) + out := &pb.TaskListResp{} + if !comm.ProtoUnmarshal(in, out) { + return errors.New("unmarshal err").Error() + } + + var formatStr strings.Builder + for i, v := range out.List { + formatStr.WriteString(fmt.Sprintf("%d- %v\n", (i + 1), v)) + } + return formatStr.String() + }, }, ff(comm.ModuleTask, task.TaskSubTypeActiveList): { NavLabel: "活跃度列表", @@ -321,8 +334,6 @@ var ( Desc: "英雄列表", MainType: string(comm.ModuleHero), SubType: hero.HeroSubTypeList, - Req: &pb.HeroListReq{}, - Rsp: &pb.HeroListResp{}, Print: func(rsp proto.Message) string { in := rsp.(*pb.UserMessage) out := &pb.HeroListResp{} diff --git a/cmd/v2/ui/tool_gen.go b/cmd/v2/ui/tool_gen.go index 90c5a94d3..13f6368f7 100644 --- a/cmd/v2/ui/tool_gen.go +++ b/cmd/v2/ui/tool_gen.go @@ -30,7 +30,7 @@ func (this *appGen) LazyInit(obs observer.Observer) error { this.tabItem = container.NewTabItemWithIcon(common.TOOLBAR_GEN, theme.ContentCopyIcon(), nil) // load - gt := service.GetDbService().Get(common.BUCKET_CONF) + gt := service.GetDbService().GetLubanConf(common.BUCKET_LUBANCONF) logrus.Debugf("%v", gt) content := container.NewMax() @@ -40,29 +40,29 @@ func (this *appGen) LazyInit(obs observer.Observer) error { serverAddr.PlaceHolder = "服务器地址 例如: 10.0.1.11" projectDir := widget.NewEntry() - projectDir.PlaceHolder = "项目目录 例如: E:\\projects\\workspace\\go_dreamfactory" + projectDir.PlaceHolder = "项目目录 例如: E:\\projects\\workspace\\go_dreamfactory\\" workDir := widget.NewEntry() - workDir.PlaceHolder = "LuBan目录 例如: E:\\svn\\dreamworks\\client\\dreamworks\\ExcelFile" + workDir.PlaceHolder = "LuBan目录 例如: E:\\svn\\dreamworks\\client\\dreamworks\\ExcelFile\\" // client client := widget.NewEntry() - client.PlaceHolder = "配置Luban Client.exe路径 例如: \\Luban.Client\\Luban.Client.exe" + client.PlaceHolder = "配置Luban Client.exe路径 例如: Luban.Client\\Luban.Client.exe" //define define := widget.NewEntry() define.PlaceHolder = "定义文件" - define.Text = "\\Defines\\__root__.xml" + define.Text = "Defines\\__root__.xml" // output outputCodeDir := widget.NewEntry() - outputCodeDir.Text = "\\sys\\configure\\structs" + outputCodeDir.Text = "sys\\configure\\structs" outputJsonDir := widget.NewEntry() - outputJsonDir.Text = "\\bin\\json" + outputJsonDir.Text = "bin\\json" //input inputDir := widget.NewEntry() - inputDir.Text = "\\Datas" + inputDir.Text = "Datas" //genType var genTypeText string @@ -75,7 +75,7 @@ func (this *appGen) LazyInit(obs observer.Observer) error { serverAddr.Text = gt.ServerAddr projectDir.Text = gt.ProjectDir //"E:\\projects\\workspace\\go_dreamfactory" workDir.Text = gt.WorkDir // "E:\\svn\\dreamworks\\client\\dreamworks\\ExcelFile" - client.Text = gt.Client //"\\Luban.Client\\Luban.Client.exe" + client.Text = gt.Client //"Luban.Client\\Luban.Client.exe" genType.Selected = gt.GenType genTypeText = gt.GenType } @@ -107,7 +107,7 @@ func (this *appGen) LazyInit(obs observer.Observer) error { } saveBtn := widget.NewButtonWithIcon("保存配置", theme.DocumentSaveIcon(), func() { - if err := service.GetDbService().Save(&model.GenTool{ + if err := service.GetDbService().SaveLubanConf(&model.GenTool{ ServerAddr: serverAddr.Text, ProjectDir: projectDir.Text, Client: client.Text, @@ -139,12 +139,12 @@ func (this *appGen) LazyInit(obs observer.Observer) error { commandStr := `%s -h %s -j cfg -- -d %s --input_data_dir %s --output_code_dir %s --output_data_dir %s --gen_types %s --go:bright_module_name bright -s server` arg := fmt.Sprintf(commandStr, - fmt.Sprintf("%s\\%s", workDir.Text, client.Text), + fmt.Sprintf("%s%s", workDir.Text, client.Text), serverAddr.Text, - fmt.Sprintf("%s\\%s", workDir.Text, define.Text), - fmt.Sprintf("%s\\%s", workDir.Text, inputDir.Text), - fmt.Sprintf("%s\\%s", projectDir.Text, outputCodeDir.Text), - fmt.Sprintf("%s\\%s", projectDir.Text, outputJsonDir.Text), + fmt.Sprintf("%s%s", workDir.Text, define.Text), + fmt.Sprintf("%s%s", workDir.Text, inputDir.Text), + fmt.Sprintf("%s%s", projectDir.Text, outputCodeDir.Text), + fmt.Sprintf("%s%s", projectDir.Text, outputJsonDir.Text), getType(), ) diff --git a/cmd/v2/ui/tool_ssh.go b/cmd/v2/ui/tool_ssh.go new file mode 100644 index 000000000..6470d2e6d --- /dev/null +++ b/cmd/v2/ui/tool_ssh.go @@ -0,0 +1,76 @@ +package ui + +import ( + "go_dreamfactory/cmd/v2/lib/common" + "go_dreamfactory/cmd/v2/service/observer" + + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/container" + "fyne.io/fyne/v2/theme" + "fyne.io/fyne/v2/widget" + "golang.org/x/crypto/ssh" + "golang.org/x/crypto/ssh/terminal" +) + +type appTerm struct { + appAdapter + + obs observer.Observer +} + +type termResizer struct { + widget.Icon + + term *terminal.Terminal + debug bool + sess *ssh.Session + win fyne.Window +} + +func (this *appTerm) LazyInit(obs observer.Observer) error { + this.obs = obs + + this.tabItem = container.NewTabItemWithIcon(common.TOOLBAR_TERM, theme.ContentCopyIcon(), nil) + content := container.NewMax() + content.Objects = []fyne.CanvasObject{} + + //cmd input + multiEntry := widget.NewMultiLineEntry() + multiEntry.PlaceHolder = "命令输入,使用;分隔" + + //config + ip := widget.NewEntry() + userName := widget.NewEntry() + password := widget.NewPasswordEntry() + + configForm := widget.NewForm( + &widget.FormItem{Text: "IP:", Widget: ip}, + &widget.FormItem{Text: "用户名:", Widget: userName}, + &widget.FormItem{Text: "密码:", Widget: password}, + ) + saveBtn := widget.NewButtonWithIcon("保存配置", theme.DocumentSaveIcon(), func() { + + }) + connBtn := widget.NewButtonWithIcon("连接", theme.ConfirmIcon(), func() { + + }) + btns := container.NewGridWithColumns(2, saveBtn, connBtn) + + //term + t := &termResizer{win: toolWin.w} + t.ExtendBaseWidget(t) + + split := container.NewVSplit(container.NewGridWithColumns(2, + multiEntry, + container.NewBorder(configForm, btns, widget.NewSeparator(), nil)), t) + split.Offset = 0.3 + content.Objects = append(content.Objects, split) + + this.tabItem.Content = content + + return nil +} + +func (a *appTerm) GetAppName() string { + return common.TOOLBAR_TERM +} diff --git a/cmd/v2/ui/toolwindow.go b/cmd/v2/ui/toolwindow.go index 515d344dd..2616d79e6 100644 --- a/cmd/v2/ui/toolwindow.go +++ b/cmd/v2/ui/toolwindow.go @@ -40,6 +40,10 @@ func NewToolWindow(ui *UIImpl) ToolWindow { openApp1(common.TOOLBAR_SEC) }), + widget.NewToolbarAction(theme.ContentUndoIcon(), func() { + openApp1(common.TOOLBAR_TERM) + }), + widget.NewToolbarSpacer(), widget.NewToolbarAction(theme.HelpIcon(), func() { showAbout() diff --git a/cmd/v2/ui/toy_userinfo.go b/cmd/v2/ui/toy_userinfo.go index 018d92896..28017a828 100644 --- a/cmd/v2/ui/toy_userinfo.go +++ b/cmd/v2/ui/toy_userinfo.go @@ -122,6 +122,7 @@ func (this *toyUserInfo) dataListener() { rsp := &pb.UserModifynameResp{} if !comm.ProtoUnmarshal(data, rsp) { logrus.Error("unmarshal err") + return } // updatename this.setProp(2, common.USERINFO_NAME, rsp.Name) @@ -162,6 +163,7 @@ func (this *toyUserInfo) dataListener() { rsp := &pb.UserResChangePush{} if !comm.ProtoUnmarshal(data.Msg, rsp) { logrus.Error("unmarshal err") + return } this.setProp(5, common.USERINFO_GOLD, rsp.Gold) } diff --git a/cmd/v2/ui/views/hero_list.go b/cmd/v2/ui/views/hero_list.go index 0d6733532..e1e266c4b 100644 --- a/cmd/v2/ui/views/hero_list.go +++ b/cmd/v2/ui/views/hero_list.go @@ -80,7 +80,6 @@ func (this *HeroListView) CreateView(t *model.TestCase) fyne.CanvasObject { this.subWindows.itemListData.DataList = append(this.subWindows.itemListData.DataList, fm) } } - this.subWindows.reloadListData() split := container.NewHSplit(this.subWindows.dataListWidget, container.NewVBox(starBtn, lvBtn)) split.Offset = 1 @@ -118,7 +117,8 @@ func (this *HeroListView) dataListener() { rsp := &pb.HeroListResp{} if !comm.ProtoUnmarshal(data, rsp) { - logrus.Error("unmarshal err") + logrus.Error("hero_list unmarshal err") + return } this.heroList = rsp.List diff --git a/cmd/v2/ui/views/task_list.go b/cmd/v2/ui/views/task_list.go index 934d99eb9..09d00b6d5 100644 --- a/cmd/v2/ui/views/task_list.go +++ b/cmd/v2/ui/views/task_list.go @@ -10,6 +10,7 @@ import ( "go_dreamfactory/comm" "go_dreamfactory/modules/task" "go_dreamfactory/pb" + "time" "fyne.io/fyne/v2" "fyne.io/fyne/v2/container" @@ -71,7 +72,9 @@ func (this *TaskListView) CreateView(t *model.TestCase) fyne.CanvasObject { func (this *TaskListView) dataListener() { this.obs.AddListener(observer.EVENT_REQ_RSP, observer.Listener{ OnNotify: func(d interface{}, args ...interface{}) { + time.Sleep(time.Millisecond * 20) data := d.(*pb.UserMessage) + logrus.Debugf("%s %s ...", data.MainType, data.SubType) if !(data.MainType == string(comm.ModuleTask) && data.SubType == task.TaskSubTypeList) { return @@ -79,7 +82,8 @@ func (this *TaskListView) dataListener() { rsp := &pb.TaskListResp{} if !comm.ProtoUnmarshal(data, rsp) { - logrus.Error("unmarshal err") + logrus.Error("task_list unmarshal err") + return } this.itemListData = model.NewItemModelList() diff --git a/go.mod b/go.mod index 6af4142c0..73cb6e93d 100644 --- a/go.mod +++ b/go.mod @@ -41,9 +41,12 @@ require ( gopkg.in/yaml.v2 v2.4.0 ) +require golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect + require ( fyne.io/systray v1.10.1-0.20220621085403-9a2652634e93 // indirect github.com/PuerkitoBio/goquery v1.8.0 // indirect + github.com/agiledragon/gomonkey/v2 v2.8.0 github.com/akutz/memconn v0.1.0 // indirect github.com/andybalholm/cascadia v1.3.1 // indirect github.com/apache/thrift v0.16.0 // indirect @@ -163,7 +166,7 @@ require ( go.opentelemetry.io/otel/trace v1.6.3 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/zap v1.17.0 // indirect - golang.org/x/crypto v0.0.0-20220408190544-5352b0902921 // indirect + golang.org/x/crypto v0.0.0-20220824171710-5757bc0c5503 // indirect golang.org/x/image v0.0.0-20220601225756-64ec528b34cd // indirect golang.org/x/mobile v0.0.0-20211207041440-4e6c2922fdee // indirect golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect diff --git a/go.sum b/go.sum index be3b1bb8c..c0fb847ec 100644 --- a/go.sum +++ b/go.sum @@ -60,6 +60,8 @@ github.com/Pallinder/go-randomdata v1.2.0 h1:DZ41wBchNRb/0GfsePLiSwb0PHZmT67XY00 github.com/Pallinder/go-randomdata v1.2.0/go.mod h1:yHmJgulpD2Nfrm0cR9tI/+oAgRqCQQixsA8HyRZfV9Y= github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U= github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI= +github.com/agiledragon/gomonkey/v2 v2.8.0 h1:u2K2nNGyk0ippzklz1CWalllEB9ptD+DtSXeCX5O000= +github.com/agiledragon/gomonkey/v2 v2.8.0/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY= github.com/akavel/rsrc v0.10.2/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/akutz/memconn v0.1.0 h1:NawI0TORU4hcOMsMr11g7vwlCdkYeLKXBcxWu2W/P8A= github.com/akutz/memconn v0.1.0/go.mod h1:Jo8rI7m0NieZyLI5e2CDlRdRqRRB4S7Xp77ukDjH+Fw= @@ -828,6 +830,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220408190544-5352b0902921 h1:iU7T1X1J6yxDr0rda54sWGkHgOp5XJrqm79gcNlC2VM= golang.org/x/crypto v0.0.0-20220408190544-5352b0902921/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220824171710-5757bc0c5503 h1:vJ2V3lFLg+bBhgroYuRfyN583UzVveQmIXjc8T/y3to= +golang.org/x/crypto v0.0.0-20220824171710-5757bc0c5503/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1039,6 +1043,7 @@ golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/modules/rtask/api_choose.go b/modules/rtask/api_choose.go index db4999e4c..a66799bf2 100644 --- a/modules/rtask/api_choose.go +++ b/modules/rtask/api_choose.go @@ -3,6 +3,7 @@ package rtask import ( "go_dreamfactory/comm" "go_dreamfactory/pb" + "go_dreamfactory/utils" "google.golang.org/protobuf/proto" ) @@ -54,6 +55,12 @@ func (this *apiComp) Choose(session comm.IUserSession, req *pb.RtaskChooseReq) ( } // 更新完成的任务 + //验证该任务是否已完成 + if _, ok := utils.Findx(frtaskArr.RtaskIds, req.RtaskId); ok { + code = pb.ErrorCode_RtaskFinished + return + } + frtaskArr.RtaskIds = append(frtaskArr.RtaskIds, req.RtaskId) if rtask.FrtaskIds == nil { rtask.FrtaskIds = make(map[int32]*pb.FrtaskIds) @@ -69,7 +76,10 @@ func (this *apiComp) Choose(session comm.IUserSession, req *pb.RtaskChooseReq) ( //发奖励 code = this.moduleRtask.DispenseRes(session, conf.Reward, true) - rsp := &pb.RtaskChooseResp{} + rsp := &pb.RtaskChooseResp{ + RtaskId: req.RtaskId, + ChooseId: req.ChooseId, + } if err := session.SendMsg(string(this.moduleRtask.GetType()), RtaskSubTypeChoose, rsp); err != nil { code = pb.ErrorCode_SystemError diff --git a/modules/rtask/model_rtask.go b/modules/rtask/model_rtask.go index 4c88ca270..c8b057ac8 100644 --- a/modules/rtask/model_rtask.go +++ b/modules/rtask/model_rtask.go @@ -73,7 +73,7 @@ func (this *ModelRtask) checkCondi(uid string, condiId int32) (ok bool) { //验证限定条件 if condi, ok := this.moduleRtask.rtaskHandleMap[condiId]; ok { if ok = condi.fn(uid, condi.cfg); !ok { - log.Infof("uid: %v do rtask %v condition not reach", uid, condiId) + log.Debugf("uid: %v do rtask %v condition not reach", uid, condiId) return false } return true @@ -105,8 +105,10 @@ func (this *ModelRtask) HeroLvTarget(uid string, cfg *cfg.GameRdtaskCondiData) ( h := heroModule.(comm.IHero) var hero *pb.DBHero for _, v := range h.GetHeroList(uid) { + // 查找指定英雄 if cast.ToString(cfg.Data1) == v.HeroID { hero = v + break } } if hero != nil { @@ -127,6 +129,7 @@ func (this *ModelRtask) EquipNum(uid string, cfg *cfg.GameRdtaskCondiData) (ok b for _, v := range h.GetHeroList(uid) { if cast.ToString(cfg.Data1) == v.HeroID { hero = v + break } } @@ -167,8 +170,8 @@ func (this *ModelRtask) TaskDay(uid string, cfg *cfg.GameRdtaskCondiData) (ok bo } itask := taskModule.(comm.ITask) - - if task := itask.GetTaskById(uid, cfg.Data1); task == nil { + var task *pb.DBTask + if task = itask.GetTaskById(uid, cfg.Data1); task == nil { return false } else { //任务完成 @@ -192,6 +195,7 @@ func (this *ModelRtask) HeroStarTarget(uid string, cfg *cfg.GameRdtaskCondiData) for _, v := range h.GetHeroList(uid) { if cast.ToString(cfg.Data1) == v.HeroID { hero = v + break } } diff --git a/pb/rtask_msg.pb.go b/pb/rtask_msg.pb.go index a0c84aeef..c65c785ec 100644 --- a/pb/rtask_msg.pb.go +++ b/pb/rtask_msg.pb.go @@ -270,6 +270,9 @@ type RtaskChooseResp struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + RtaskId int32 `protobuf:"varint,1,opt,name=rtaskId,proto3" json:"rtaskId"` //任务ID + ChooseId int32 `protobuf:"varint,2,opt,name=chooseId,proto3" json:"chooseId"` //选项配置ID } func (x *RtaskChooseResp) Reset() { @@ -304,6 +307,20 @@ func (*RtaskChooseResp) Descriptor() ([]byte, []int) { return file_rtask_rtask_msg_proto_rawDescGZIP(), []int{5} } +func (x *RtaskChooseResp) GetRtaskId() int32 { + if x != nil { + return x.RtaskId + } + return 0 +} + +func (x *RtaskChooseResp) GetChooseId() int32 { + if x != nil { + return x.ChooseId + } + return 0 +} + // 任务完成推送 type RtaskFinishPush struct { state protoimpl.MessageState @@ -466,18 +483,22 @@ var file_rtask_rtask_msg_proto_rawDesc = []byte{ 0x6f, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x71, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x72, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x68, 0x6f, 0x6f, 0x73, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x08, 0x63, 0x68, 0x6f, 0x6f, 0x73, 0x65, 0x49, 0x64, 0x22, 0x11, 0x0a, + 0x01, 0x28, 0x05, 0x52, 0x08, 0x63, 0x68, 0x6f, 0x6f, 0x73, 0x65, 0x49, 0x64, 0x22, 0x47, 0x0a, 0x0f, 0x52, 0x74, 0x61, 0x73, 0x6b, 0x43, 0x68, 0x6f, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x22, 0x2b, 0x0a, 0x0f, 0x52, 0x74, 0x61, 0x73, 0x6b, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x50, - 0x75, 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x72, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x22, 0x2d, 0x0a, - 0x11, 0x52, 0x74, 0x61, 0x73, 0x6b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, - 0x65, 0x71, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x07, 0x72, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x22, 0x2e, 0x0a, 0x12, - 0x52, 0x74, 0x61, 0x73, 0x6b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x07, 0x72, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x42, 0x06, 0x5a, 0x04, - 0x2e, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x18, 0x0a, 0x07, 0x72, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x07, 0x72, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x68, + 0x6f, 0x6f, 0x73, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x63, 0x68, + 0x6f, 0x6f, 0x73, 0x65, 0x49, 0x64, 0x22, 0x2b, 0x0a, 0x0f, 0x52, 0x74, 0x61, 0x73, 0x6b, 0x46, + 0x69, 0x6e, 0x69, 0x73, 0x68, 0x50, 0x75, 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x74, 0x61, + 0x73, 0x6b, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x72, 0x74, 0x61, 0x73, + 0x6b, 0x49, 0x64, 0x22, 0x2d, 0x0a, 0x11, 0x52, 0x74, 0x61, 0x73, 0x6b, 0x47, 0x65, 0x74, 0x52, + 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x74, 0x61, 0x73, + 0x6b, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x72, 0x74, 0x61, 0x73, 0x6b, + 0x49, 0x64, 0x22, 0x2e, 0x0a, 0x12, 0x52, 0x74, 0x61, 0x73, 0x6b, 0x47, 0x65, 0x74, 0x52, 0x65, + 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x74, 0x61, 0x73, + 0x6b, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x72, 0x74, 0x61, 0x73, 0x6b, + 0x49, 0x64, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var (