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  }