github.com/loomnetwork/gamechain@v0.0.0-20200406110549-36c47eb97a92/tools/gamechain-debugger/controller/main.go (about) 1 package controller 2 3 import ( 4 "archive/zip" 5 "bytes" 6 "fmt" 7 "io" 8 "io/ioutil" 9 "log" 10 "net/http" 11 "os" 12 "os/exec" 13 "strings" 14 15 "github.com/gorilla/mux" 16 "github.com/loomnetwork/gamechain/tools/gamechain-debugger/view" 17 ) 18 19 type MainController struct { 20 gamechainDebugger *view.View 21 clientStateDebugger *view.View 22 cliDebugger *view.View 23 privateKeyFilePath string 24 cliFilePath string 25 } 26 27 func NewMainController(cliFilePath string, privateKeyFilePath string) *MainController { 28 mc := MainController{ 29 gamechainDebugger: view.NewView("base", "gamechain_debugger.html"), 30 clientStateDebugger: view.NewView("base", "client_state_debugger.html"), 31 cliDebugger: view.NewView("base", "cli_debugger.html"), 32 cliFilePath: cliFilePath, 33 privateKeyFilePath: privateKeyFilePath, 34 } 35 return &mc 36 } 37 38 func WriteFile(filename string, fileContent []byte) error { 39 err := ioutil.WriteFile(filename, fileContent, 0777) 40 if err != nil { 41 return err 42 } 43 return nil 44 } 45 46 func (MainController *MainController) RunMatchCmd(matchId string, cmdName string) ([]byte, error) { 47 cmd := exec.Command(MainController.cliFilePath, cmdName, "-k", MainController.privateKeyFilePath, "-m", matchId, "-O", "json") 48 var out bytes.Buffer 49 var stderr bytes.Buffer 50 cmd.Stdout = &out 51 cmd.Stderr = &stderr 52 53 err := cmd.Run() 54 if err != nil { 55 fmt.Println(cmd.Stderr) 56 return out.Bytes(), err 57 } 58 59 return out.Bytes(), nil 60 } 61 62 func ZipFiles(filename string, files []string) error { 63 64 newZipFile, err := os.Create(filename) 65 if err != nil { 66 return err 67 } 68 defer newZipFile.Close() 69 70 zipWriter := zip.NewWriter(newZipFile) 71 defer zipWriter.Close() 72 73 for _, file := range files { 74 if err = AddFileToZip(zipWriter, file); err != nil { 75 return err 76 } 77 } 78 return nil 79 } 80 81 func AddFileToZip(zipWriter *zip.Writer, filename string) error { 82 83 fileToZip, err := os.Open(filename) 84 if err != nil { 85 return err 86 } 87 defer fileToZip.Close() 88 89 info, err := fileToZip.Stat() 90 if err != nil { 91 return err 92 } 93 94 header, err := zip.FileInfoHeader(info) 95 if err != nil { 96 return err 97 } 98 99 header.Name = filename 100 header.Method = zip.Deflate 101 102 writer, err := zipWriter.CreateHeader(header) 103 if err != nil { 104 return err 105 } 106 _, err = io.Copy(writer, fileToZip) 107 return err 108 } 109 110 func (MainController *MainController) GamechainDebugger(w http.ResponseWriter, r *http.Request) { 111 MainController.gamechainDebugger.Render(w, nil) 112 } 113 func (MainController *MainController) ClientStateDebugger(w http.ResponseWriter, r *http.Request) { 114 MainController.clientStateDebugger.Render(w, nil) 115 } 116 func (MainController *MainController) CliDebugger(w http.ResponseWriter, r *http.Request) { 117 MainController.cliDebugger.Render(w, nil) 118 } 119 func (MainController *MainController) RunCli(w http.ResponseWriter, r *http.Request) { 120 keys, ok := r.URL.Query()["args"] 121 if !ok || len(keys[0]) < 1 { 122 log.Println("Url Param 'args' is missing") 123 return 124 } 125 126 args := strings.Split(keys[0], " ") 127 128 cmd := exec.Command(MainController.cliFilePath, args...) 129 var out bytes.Buffer 130 var stderr bytes.Buffer 131 cmd.Stdout = &out 132 cmd.Stderr = &stderr 133 134 err := cmd.Run() 135 if err != nil { 136 fmt.Println(cmd.Stderr) 137 w.Write([]byte(stderr.Bytes())) 138 return 139 } 140 w.Header().Set("Content-Type", "application/json") 141 w.Write(out.Bytes()) 142 143 } 144 func (MainController *MainController) SaveState(w http.ResponseWriter, r *http.Request) { 145 vars := mux.Vars(r) 146 MatchId := vars["MatchId"] 147 148 gameState, err := MainController.RunMatchCmd(MatchId, "get_game_state") 149 if err != nil { 150 w.Header().Set("Content-Type", "application/json") 151 w.Write([]byte(err.Error())) 152 return 153 } 154 initState, err := MainController.RunMatchCmd(MatchId, "get_initial_game_state") 155 if err != nil { 156 w.Header().Set("Content-Type", "application/json") 157 w.Write([]byte(err.Error())) 158 return 159 } 160 match, err := MainController.RunMatchCmd(MatchId, "get_match") 161 if err != nil { 162 w.Write([]byte(err.Error())) 163 return 164 } 165 166 gameStateFilename := "./tmp/game_state.json" 167 initStateFilename := "./tmp/init_game_state.json" 168 matchFilename := "./tmp/match.json" 169 170 os.Mkdir("./tmp", 0777) 171 if err := WriteFile(initStateFilename, initState); err != nil { 172 w.Write([]byte(err.Error())) 173 return 174 } 175 176 if err := WriteFile(gameStateFilename, gameState); err != nil { 177 w.Write([]byte(err.Error())) 178 return 179 } 180 if err := WriteFile(matchFilename, match); err != nil { 181 w.Write([]byte(err.Error())) 182 return 183 } 184 185 if err := ZipFiles("match_data.zip", []string{gameStateFilename, initStateFilename, matchFilename}); err != nil { 186 w.Write([]byte(err.Error())) 187 return 188 } 189 190 os.RemoveAll("./tmp/") 191 192 dbFile, err := ioutil.ReadFile("match_data.zip") 193 if err != nil { 194 fmt.Fprintf(w, "%s", err) 195 } 196 b := bytes.NewBuffer(dbFile) 197 filename := "match_data_" + MatchId + ".zip" 198 w.Header().Set("Content-Disposition", "attachment; filename="+filename) 199 w.Header().Set("Content-Type", r.Header.Get("Content-Type")) 200 if _, err := b.WriteTo(w); err != nil { 201 fmt.Fprintf(w, "%s", err) 202 } 203 204 } 205 func (MainController *MainController) GetState(w http.ResponseWriter, r *http.Request) { 206 vars := mux.Vars(r) 207 MatchId := vars["MatchId"] 208 output, err := MainController.RunMatchCmd(MatchId, "get_game_state") 209 if err != nil { 210 w.Header().Set("Content-Type", "application/json") 211 w.Write([]byte(err.Error())) 212 return 213 } 214 w.Header().Set("Content-Type", "application/json") 215 w.Write(output) 216 }