func main() { flag.Usage = func() { fmt.Fprintf(os.Stderr, "\nUsage: %s [-v] [config]\n", os.Args[0]) } verbose := flag.Bool("v", false, "a bool") flag.Parse() if !*verbose { e := logger.Initialize("hooktftp") if e != nil { log.Fatal("Failed to initialize logger") } } if len(flag.Args()) > 0 { CONFIG_PATH = flag.Args()[0] } logger.Info("Reading hooks from %s", CONFIG_PATH) configData, err := ioutil.ReadFile(CONFIG_PATH) if err != nil { logger.Crit("Failed to read config: %s", err) return } conf, err := config.ParseYaml(configData) if err != nil { logger.Crit("Failed to parse config: %s", err) return } for _, hookDef := range conf.HookDefs { logger.Notice("Compiling hook %s", hookDef) // Create new hookDef variable for the hookDef pointer for each loop // iteration. Go reuses the hookDef variable and if we pass pointer to // that terrible things happen. newPointer := hookDef hook, err := hooks.CompileHook(&newPointer) if err != nil { logger.Crit("Failed to compile hook %s: %s", hookDef, err) return } HOOKS = append(HOOKS, hook) } if conf.Port == "" { conf.Port = "69" } addr, err := net.ResolveUDPAddr("udp", ":"+conf.Port) if err != nil { logger.Crit("Failed to resolve address: %s", err) return } server, err := tftp.NewTFTPServer(addr) if err != nil { logger.Crit("Failed to listen: %s", err) return } logger.Notice("Listening on %d", conf.Port) if conf.User != "" { err := DropPrivileges(conf.User) if err != nil { logger.Crit("Failed to drop privileges to '%s' error: %v", conf.User, err) return } currentUser, _ := user.Current() logger.Notice("Dropped privileges to %s", currentUser) } if conf.User == "" && syscall.Getuid() == 0 { logger.Warning("Running as root and 'user' is not set in %s", CONFIG_PATH) } for { res, err := server.Accept() if err != nil { logger.Err("Bad tftp request: %s", err) continue } go handleRRQ(res) } logger.Close() }
func main() { // 独自のLoggerを使用 InitLogger() logger := GetLogger() defer logger.Close() // master ban var master *TBan var tesuu int = 0 //player := NewPlayer("Slide") //player := NewPlayer("Random") player := NewPlayer("Main") // 将棋所とのやりとり // TODO:いつでも返答すべきコマンドは常時listenするイメージで。GoRoutineとChannelを使えばよさげ scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { text := scanner.Text() logger.Req(text) switch text { // エンジン登録時は、usiとquitのみ入力される。 case "usi": respUSI(logger) case "quit": // TODO 終了前処理 os.Exit(0) case "setoption name USI_Ponder value true": // TODO 設定を保存する case "setoption name USI_Hash value 256": // TODO 設定を保存する case "isready": master = CreateInitialState() tesuu = 0 Resp("readyok", logger) case "usinewgame": // TODO: モードを切り替えるべきか。 case "gameover": // TODO: 対局待ち状態に戻る。 default: if s.HasPrefix(text, "position") { logger.Trace(text) split_text := s.Split(text, " ") // 通常の対局 // position startpos moves 7g7f 8b7b 2g2f is_sfen := false if split_text[1] == "sfen" { is_sfen = true // 局面編集からの検討だとこのように // position sfen lnsgkgsnl/1r5b1/1pppppppp/p8/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1 moves 2g2f sfen_index := s.Index(text, "sfen") moves_index := s.Index(text, "moves") var sfen_str string if moves_index == -1 { sfen_str = text[sfen_index:] } else { sfen_str = text[sfen_index : moves_index-1] } master = FromSFEN(sfen_str) } if is_sfen { // こちらのルートはどうすればいいのか不明。デッドコピーとしておく。 for index, value := range split_text { if index < 7 { continue } // 何度も一手ずつ反映する必要はないので、スキップしている。 if index-7 < tesuu { continue } logger.Trace("to apply: " + value) master.ApplyMove(value, true, true, true) logger.Trace(master.Display()) tesuu++ } // resp("info string "+text, logger) } else { for index, value := range split_text { if index < 3 { continue } // 何度も一手ずつ反映する必要はないので、スキップしている。 if index-3 < tesuu { continue } logger.Trace("to apply: " + value) master.ApplyMove(value, true, true, true) logger.Trace(master.Display()) logger.Trace(master.ToSFEN(true)) tesuu++ } } } else if s.HasPrefix(text, "go") { split_text := s.Split(text, " ") btime := split_text[2] wtime := split_text[4] teban := *(master.Teban) var ms int = 0 if teban { ms, _ = strconv.Atoi(btime) } else { ms, _ = strconv.Atoi(wtime) } bestmove, score := player.Search(master, ms) if len(bestmove) < 6 { master.ApplyMove(bestmove, true, true, true) logger.Trace(master.Display()) logger.Trace(master.ToSFEN(true)) tesuu++ } Resp(("info time 0 depth 1 nodes 1 score cp " + ToDisplayScore(score, teban) + " pv " + bestmove), logger) bestmove_str := "bestmove " + bestmove Resp(bestmove_str, logger) } } } }