diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | README.md | 51 | ||||
-rw-r--r-- | bots/amaterasu.x86-32.asm | 35 | ||||
-rw-r--r-- | bots/pancake.x86-32.asm | 7 | ||||
-rw-r--r-- | go.mod | 1 | ||||
-rw-r--r-- | go.sum | 2 | ||||
-rwxr-xr-x | run.sh | 2 | ||||
-rw-r--r-- | src/battle.go | 177 | ||||
-rw-r--r-- | src/db.go | 6 | ||||
-rw-r--r-- | src/main.go | 4 | ||||
-rw-r--r-- | src/user.go | 16 | ||||
-rw-r--r-- | templates/battleSingle.html | 266 | ||||
-rw-r--r-- | templates/nav.html | 4 | ||||
-rw-r--r-- | vendor/modules.txt | 2 |
14 files changed, 415 insertions, 160 deletions
diff --git a/.gitignore b/.gitignore index f0b11c5..1d306c2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ main.db sessions.db server.log - result/ +.DS_Store diff --git a/README.md b/README.md index 525915d..8d996a1 100644 --- a/README.md +++ b/README.md @@ -20,3 +20,54 @@ If you want to clone from git.emile.space, you can currently do so like this: git clone git://git.emile.space/r2wars-web.git git clone git://git.emile.space/hefe.git ``` + +## Usage + +``` +; CGO_ENABLED=0 SESSION_KEY=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa go run ./src --help +Usage of /var/folders/bt/2db5y4ds5yq2y9m29tt8g5dm0000gn/T/go-build1055665732/b001/exe/src: + -databasepath string + The path to the main database (default "./main.db") + -h string + The host to listen on (shorthand) (default "127.0.0.1") + -host string + The host to listen on (default "127.0.0.1") + -logfilepath string + The path to the log file (default "./server.log") + -p int + The port to listen on (shorthand) (default 8080) + -port int + The port to listen on (default 8080) + -sessiondbpath string + The path to the session database (default "./sesions.db") + -templates string + The path to the templates used (default "./templates") +``` + +## Architecture + +There are essentially the following objects which are all linked to each other (using a table joining their ids): + +- User + - You, the player +- Bots + - The bots to be run within a battle +- Battles + - An arena in which bots can be placed and run. Constraints on what bots can be added are defined here +- Architectures + - The archs supported by r2 in order to be used by bots and battles +- Bits + - The bits (8, 16, 32, 64) supported by r2 in order to be used by bots and battles + +## TODO + +- [ ] Add user creating battle as default owner +- [ ] Allow adding other users as owners to battles +- [ ] Implement submitting bots +- [ ] Implement running the battle +- [ ] Add a "start battle now" button +- [ ] Add a "battle starts at this time" field into the battle +- [ ] Figure out how time is stored and restored with the db +- [ ] Do some magic to display the current fight backlog with all info +- [ ] After having added a bot to a battle with the right arch, the arch can be changed + When updating the bot, make sure that it is still valid in all currently linked battles diff --git a/bots/amaterasu.x86-32.asm b/bots/amaterasu.x86-32.asm new file mode 100644 index 0000000..55d38df --- /dev/null +++ b/bots/amaterasu.x86-32.asm @@ -0,0 +1,35 @@ +start: + mov ebp, 0x3e0 + mov esp, 0x3e0 + ; lea eax, [end + 0x20] + ; lea ebx, [start - 0x20] + mov eax, 0xffffffff + mov ebx, 0xffffffff + mov ecx, 0xffffffff + mov edx, 0xffffffff + mov edi, 0xffffffff + mov esi, 0xffffffff + +bot_loop: + ; cmp esp, eax + ; cmovbe esp, ebx + + ; push 128 bytes at once + pushad + pushad + pushad + pushad + + ; push again + pushad + pushad + pushad + pushad + + ; jmp to beginning once again + cmp esp, 0x10 + cmovz esp, ebp + jmp bot_loop + +end: + nop \ No newline at end of file diff --git a/bots/pancake.x86-32.asm b/bots/pancake.x86-32.asm new file mode 100644 index 0000000..25eda04 --- /dev/null +++ b/bots/pancake.x86-32.asm @@ -0,0 +1,7 @@ +call rest +rest: + pop esp +rep: + add esp, 64 + pusha + jmp rep diff --git a/go.mod b/go.mod index b897dd4..9a6722a 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,6 @@ require ( github.com/gorilla/securecookie v1.1.2 github.com/gorilla/sessions v1.3.0 github.com/radareorg/r2pipe-go v0.2.1 - github.com/xiaoqidun/entps v1.32.0 golang.org/x/crypto v0.26.0 modernc.org/sqlite v1.32.0 ) diff --git a/go.sum b/go.sum index 5022658..6ba4f7d 100644 --- a/go.sum +++ b/go.sum @@ -28,8 +28,6 @@ github.com/radareorg/r2pipe-go v0.2.1 h1:2bVIi7qHPQCdjjngcJbQO2VHSqPaRBt5LUAMk2u github.com/radareorg/r2pipe-go v0.2.1/go.mod h1:HNUWNjS7SjzhZ7McDLhvIBSOLz1X9DNLjj4J52pAj3Y= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/xiaoqidun/entps v1.32.0 h1:shF2tBvry0F0wYlqeWpj7SUbq6fYS6cmHGDp5ZShKqg= -github.com/xiaoqidun/entps v1.32.0/go.mod h1:42K0gnlDRuO4sc5GWmpFXz40kB81LjabFu/kK9BzKXI= golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= diff --git a/run.sh b/run.sh index 64b35c5..fea0921 100755 --- a/run.sh +++ b/run.sh @@ -1,3 +1,3 @@ set +e -CGO_ENABLED=0 SESSION_KEY=aes1Itheich4aeQu9Ouz7ahcaiVoogh9 go run ./... -h "" +CGO_ENABLED=0 SESSION_KEY=aes1Itheich4aeQu9Ouz7ahcaiVoogh9 go run ./src diff --git a/src/battle.go b/src/battle.go index e30cebd..01e9f8d 100644 --- a/src/battle.go +++ b/src/battle.go @@ -23,6 +23,7 @@ type Battle struct { Archs []Arch Bits []Bit RawOutput string + MaxRounds int } ////////////////////////////////////////////////////////////////////////////// @@ -32,8 +33,8 @@ func BattleGetAll() ([]Battle, error) { return globalState.GetAllBattles() } -func BattleCreate(name string, public bool) (int, error) { - return globalState.InsertBattle(Battle{Name: name, Public: public}) +func BattleCreate(name string, public bool, owner User) (int, error) { + return globalState.InsertBattle(Battle{Name: name, Public: public}, owner) } func BattleLinkBot(botid int, battleid int) error { @@ -64,10 +65,15 @@ func BattleSaveRawOutput(battleid int, rawOutput string) error { return globalState.UpdateBattleRawOutput(battleid, rawOutput) } +func BattleDeleteID(battleid int) error { + return globalState.DeleteBattleByID(battleid) +} + ////////////////////////////////////////////////////////////////////////////// // DATABASE -func (s *State) InsertBattle(battle Battle) (int, error) { +func (s *State) InsertBattle(battle Battle, owner User) (int, error) { + // create the battle res, err := s.db.Exec("INSERT INTO battles VALUES(NULL,?,?,?);", time.Now(), battle.Name, battle.Public) if err != nil { log.Println(err) @@ -79,6 +85,14 @@ func (s *State) InsertBattle(battle Battle) (int, error) { log.Println(err) return -1, err } + + // insert the owner into the battle_owner rel + _, err = s.db.Exec("INSERT INTO owner_battle_rel VALUES (?, ?)", owner.ID, battle.ID) + if err != nil { + log.Println(err) + return -1, err + } + return int(id), nil } @@ -219,6 +233,7 @@ func (s *State) GetBattleByIdDeep(id int) (Battle, error) { var battlename string var battlepublic bool var battlerawoutput string + var battlemaxrounds int var botids string var botnames string @@ -239,10 +254,15 @@ func (s *State) GetBattleByIdDeep(id int) (Battle, error) { // TODO(emile): go deeper! we could fetch battle -> bot -> arch (so fetching the linked arch // for the given bot) + // COALESCE is used to set default values + // TODO(emile): do fancy migrations instead of the COALESCE stuff for setting defaults if + // no value is set beforehand + err := s.db.QueryRow(` SELECT DISTINCT ba.id, ba.name, ba.public, COALESCE(ba.raw_output, ""), + COALESCE(ba.max_rounds, 100), COALESCE(group_concat(DISTINCT bb.bot_id), ""), COALESCE(group_concat(DISTINCT bo.name), ""), COALESCE(group_concat(DISTINCT ub.user_id), ""), @@ -267,7 +287,7 @@ func (s *State) GetBattleByIdDeep(id int) (Battle, error) { WHERE ba.id=? GROUP BY ba.id; - `, id).Scan(&battleid, &battlename, &battlepublic, &battlerawoutput, &botids, &botnames, &userids, &usernames, &archids, &archnames, &bitids, &bitnames) + `, id).Scan(&battleid, &battlename, &battlepublic, &battlerawoutput, &battlemaxrounds, &botids, &botnames, &userids, &usernames, &archids, &archnames, &bitids, &bitnames) if err != nil { log.Println(err) return Battle{}, err @@ -361,6 +381,7 @@ func (s *State) GetBattleByIdDeep(id int) (Battle, error) { Archs: archs, Bits: bits, RawOutput: battlerawoutput, + MaxRounds: battlemaxrounds, }, nil } @@ -373,6 +394,35 @@ func (s *State) UpdateBattleRawOutput(battleid int, rawOutput string) error { return nil } +// This deletes a battle and all links to users, bots, architectures and bits +func (s *State) DeleteBattleByID(battleid int) error { + _, err := s.db.Exec(` + DELETE FROM battles WHERE battleid = ?; + + DELETE FROM user_battle_rel WHERE battleid = ?; + DELETE FROM bot_battle_rel WHERE battleid = ?; + DELETE FROM arch_battle_rel WHERE battleid = ?; + DELETE FROM bit_battle_rel WHERE battleid = ?; + `, battleid, battleid, battleid, battleid, battleid) + + if err != nil { + log.Println(err) + return err + } + + _, err = s.db.Exec(` + DELETE FROM battles + WHERE battleid = ? + `, battleid) + + if err != nil { + log.Println(err) + return err + } + + return nil +} + ////////////////////////////////////////////////////////////////////////////// // HTTP @@ -498,6 +548,20 @@ func battleNewHandler(w http.ResponseWriter, r *http.Request) { t.ExecuteTemplate(w, "battleNew", data) case "POST": + data := map[string]interface{}{} + + session, _ := globalState.sessions.Get(r, "session") + username := session.Values["username"].(string) + + // get data needed + user, err := UserGetUserFromUsername(username) + if err != nil { + log.Println(err) + data["err"] = "Could not fetch the user" + } else { + data["user"] = user + } + // parse the post parameters r.ParseForm() name := r.Form.Get("name") @@ -538,7 +602,7 @@ func battleNewHandler(w http.ResponseWriter, r *http.Request) { if name != "" { // create the battle itself log.Println("Creating battle") - battleid, err := BattleCreate(name, public) + battleid, err := BattleCreate(name, public, user) if err != nil { log.Println(err) msg := "ERROR: Could not create due to internal reasons" @@ -631,6 +695,20 @@ func battleQuickHandler(w http.ResponseWriter, r *http.Request) { t.ExecuteTemplate(w, "battleQuick", data) case "POST": + data := map[string]interface{}{} + + session, _ := globalState.sessions.Get(r, "session") + username := session.Values["username"].(string) + + // get data needed + user, err := UserGetUserFromUsername(username) + if err != nil { + log.Println(err) + data["err"] = "Could not fetch the user" + } else { + data["user"] = user + } + // parse the post parameters r.ParseForm() @@ -658,7 +736,7 @@ func battleQuickHandler(w http.ResponseWriter, r *http.Request) { // create the battle itself log.Println("Creating battle") - battleid, err := BattleCreate("quick", public) + battleid, err := BattleCreate("quick", public, user) if err != nil { log.Println(err) msg := "ERROR: Could not create due to internal reasons" @@ -872,6 +950,20 @@ func battleSingleHandler(w http.ResponseWriter, r *http.Request) { // at this point, we're sure the user is allowed to edit the battle + data := map[string]interface{}{} + + session, _ := globalState.sessions.Get(r, "session") + username := session.Values["username"].(string) + + // get data needed + user, err := UserGetUserFromUsername(username) + if err != nil { + log.Println(err) + data["err"] = "Could not fetch the user" + } else { + data["user"] = user + } + r.ParseForm() log.Println("r.Form: ", r.Form) @@ -919,7 +1011,7 @@ func battleSingleHandler(w http.ResponseWriter, r *http.Request) { return } - new_battle := Battle{int(battleid), form_name, []Bot{}, []User{}, public, []Arch{}, []Bit{}, ""} + new_battle := Battle{int(battleid), form_name, []Bot{}, []User{user}, public, []Arch{}, []Bit{}, "", 100} log.Println("Updating battle...") err = BattleUpdate(new_battle) @@ -1220,12 +1312,65 @@ func battleRunHandler(w http.ResponseWriter, r *http.Request) { // delete a battle // TODO(emile): finish implementing the deletion of battles -// func battleDeleteHandler(w http.ResponseWriter, r *http.Request) { -// switch r.Method { -// case "DELETE": - -// http.Redirect(w, r, fmt.Sprintf("/battle?res=%s", battleid, msg), http.StatusSeeOther) -// default: -// http.Redirect(w, r, "/", http.StatusMethodNotAllowed) -// } -// } +func battleDeleteHandler(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + battleid, err := strconv.Atoi(vars["id"]) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte("500 - Invalid battle id")) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + redir_target := fmt.Sprintf("/battle/%d?res=%%s", battleid) + + switch r.Method { + case "POST": // can't send a DELETE with pure HTML... + + // get the current user + session, _ := globalState.sessions.Get(r, "session") + username := session.Values["username"] + if username == nil { + http.Redirect(w, r, "/login", http.StatusSeeOther) + return + } + viewer, err := UserGetUserFromUsername(username.(string)) + if err != nil { + log_and_redir_with_msg(w, r, err, redir_target, "Could not get the id for your username") + return + } + + // get the battle + battle, err := BattleGetByIdDeep(int(battleid)) + if err != nil { + log_and_redir_with_msg(w, r, err, redir_target, "Could not get the battle given the id provided") + return + } + + battle_owned_by_requesting_user := false + for _, owner := range battle.Owners { + + // if the requesting users id is equal to an owners id, we're allowed to delete + // the battle + if viewer.ID == owner.ID { + battle_owned_by_requesting_user = true + break + } + } + + // check that the user that created the battle is the current user, if not, return + if battle_owned_by_requesting_user == false { + msg := "You aren't in the owners list of the battle, so you can't delete this battle" + log_and_redir_with_msg(w, r, err, redir_target, msg) + return + } + + BattleDeleteID(battleid) + + msg := "Successfully deleted the battle" + http.Redirect(w, r, fmt.Sprintf("/battle/%d?res=%s", battleid, msg), http.StatusSeeOther) + default: + log.Println("expected POST, got ", r.Method) + http.Redirect(w, r, "/", http.StatusMethodNotAllowed) + } +} diff --git a/src/db.go b/src/db.go index 426ac52..42dc2d4 100644 --- a/src/db.go +++ b/src/db.go @@ -24,6 +24,7 @@ CREATE TABLE IF NOT EXISTS battles ( name TEXT, public BOOLEAN, raw_output TEXT + max_rounds INTEGER ); CREATE TABLE IF NOT EXISTS archs ( id INTEGER NOT NULL PRIMARY KEY, @@ -90,6 +91,11 @@ CREATE TABLE IF NOT EXISTS user_battle_rel ( battle_id INTEGER, PRIMARY KEY(user_id, battle_id) ); +CREATE TABLE IF NOT EXISTS owner_battle_rel ( + user_id INTEGER, + battle_id INTEGER, + PRIMARY KEY(user_id, battle_id) +); CREATE TABLE IF NOT EXISTS bot_battle_rel ( bot_id INTEGER, battle_id INTEGER, diff --git a/src/main.go b/src/main.go index 20c245a..c789cf8 100644 --- a/src/main.go +++ b/src/main.go @@ -30,7 +30,7 @@ func initFlags() { flag.StringVar(&logFilePath, "logfilepath", "./server.log", "The path to the log file") flag.StringVar(&databasePath, "databasepath", "./main.db", "The path to the main database") - flag.StringVar(&sessiondbPath, "sessiondbpath", "./sesions.db", "The path to the session database") + flag.StringVar(&sessiondbPath, "sessiondbpath", "./sessions.db", "The path to the session database") flag.StringVar(&templatesPath, "templates", "./templates", "The path to the templates used") } @@ -92,7 +92,7 @@ func main() { auth_needed.HandleFunc("/battle/quick", battleQuickHandler) auth_needed.HandleFunc("/battle/{id}/submit", battleSubmitHandler) auth_needed.HandleFunc("/battle/{id}/run", battleRunHandler) - // auth_needed.HandleFunc("/battle/{id}/delete", battleDeleteHandler) + auth_needed.HandleFunc("/battle/{id}/delete", battleDeleteHandler) log.Printf("[i] HTTP Server running on %s:%d\n", host, port) log.Fatal(http.ListenAndServe(fmt.Sprintf("%s:%d", host, port), r)) diff --git a/src/user.go b/src/user.go index d55c9d8..1fd9358 100644 --- a/src/user.go +++ b/src/user.go @@ -119,7 +119,9 @@ func (s *State) UpdateUserUsername(id int, new_username string) error { // Links the given bot to the given user in the user_bot_rel table func (s *State) LinkUserBot(username string, botid int) error { - _, err := s.db.Exec("INSERT INTO user_bot_rel VALUES ((SELECT id FROM users WHERE name=?), ?)", username, botid) + _, err := s.db.Exec(` + INSERT INTO user_bot_rel + VALUES ((SELECT id FROM users WHERE name=?), ?)`, username, botid) if err != nil { return err } else { @@ -153,7 +155,11 @@ func (s *State) GetUserFromUsername(username string) (User, error) { // Returns the bots belonging to the given user // TODO(emile): Also fetch the bits and the archs for displaying in the single battle page. In order to do so, join in both those tables func (s *State) GetUserBotsUsername(username string) ([]Bot, error) { - rows, err := s.db.Query("SELECT id, name, source FROM bots b LEFT JOIN user_bot_rel ub ON ub.bot_id = b.id WHERE ub.user_id=(SELECT id FROM users WHERE name=?)", username) + rows, err := s.db.Query(` + SELECT id, name, source + FROM bots b + LEFT JOIN user_bot_rel ub ON ub.bot_id = b.id + WHERE ub.user_id=(SELECT id FROM users WHERE name=?)`, username) defer rows.Close() if err != nil { return nil, err @@ -175,7 +181,11 @@ func (s *State) GetUserBotsUsername(username string) ([]Bot, error) { // Returns the bots belonging to the given user func (s *State) GetUserBotsId(id int) ([]Bot, error) { - rows, err := s.db.Query("SELECT id, name, source FROM bots b LEFT JOIN user_bot_rel ub ON ub.bot_id = b.id WHERE ub.user_id=?", id) + rows, err := s.db.Query(` + SELECT id, name, source + FROM bots b + LEFT JOIN user_bot_rel ub ON ub.bot_id = b.id + WHERE ub.user_id=?`, id) defer rows.Close() if err != nil { return nil, err diff --git a/templates/battleSingle.html b/templates/battleSingle.html index b5bb6d6..267a0df 100644 --- a/templates/battleSingle.html +++ b/templates/battleSingle.html @@ -11,116 +11,115 @@ <a href="#settings">Settings</a> <a href="#registered-bots">Registered Bots</a> <a href="#output">Output</a> +<a href="#debug">Debug</a> </pre> <span id="settings"></span> <h2><a href="#settings">Settings</a></h2> - <form id="delete" method="DELETE" action="/battle/{{ .battle.ID }}/delete"> - </form> - <table> - <form id="battle" method="POST" action="/battle/{{ .battle.ID }}"> - <tr> - <td><label for="name">Name:</label></td> - <td><input class="border" type="text" id="name" name="name" value="{{ .battle.Name }}"></td> - </tr> - - <!-- - <tr> - <td><label for="latestBotSubmission">Latest Bot Submission</label></td> - <td><input - class="border" - type="datetime-local" - id="latestBotSubmission" - name="latestBotSubmission" - value="2024-11-08T12:00" - ></td> - </tr> - - <tr> - <td><label for="battleStart">Battle Start</label></td> - <td><input - class="border" - type="datetime-local" - id="battleStart" - name="battleStart" - value="2024-11-08T16:00" - ></td> - </tr> - - <tr> - <td><label for="owners">Owners:</label></td> - <td> - {{ range $idx, $usr := .battle.Owners }}{{if $idx}},{{end}}<a href="/user/{{ $usr.ID }}">{{ $usr.Name }}</a>{{ end }} - </td> - </tr> - --> - - <tr> - <td><label for="bots">Bots submitted:</label></td> - <td> - {{ range $idx, $bot := .battle.Bots }}{{if $idx}},{{end}}<a href="/bot/{{ $bot.ID }}">{{ $bot.Name }}</a>{{ end }} + <tbody> + <form id="battle" method="POST" action="/battle/{{ .battle.ID }}"> + <tr> + <td><label for="name">Name:</label></td> + <td><input class="border" type="text" id="name" name="name" value="{{ .battle.Name }}"></td> + </tr> + + <!-- + <tr> + <td><label for="latestBotSubmission">Latest Bot Submission</label></td> + <td><input + class="border" + type="datetime-local" + id="latestBotSubmission" + name="latestBotSubmission" + value="2024-11-08T12:00" + ></td> + </tr> + + <tr> + <td><label for="battleStart">Battle Start</label></td> + <td><input + class="border" + type="datetime-local" + id="battleStart" + name="battleStart" + value="2024-11-08T16:00" + ></td> + </tr> + + <tr> + <td><label for="owners">Owners:</label></td> + <td> + {{ range $idx, $usr := .battle.Owners }}{{if $idx}},{{end}}<a href="/user/{{ $usr.ID }}">{{ $usr.Name }}</a>{{ end }} + </td> + </tr> + --> + + <tr> + <td><label for="bots">Bots submitted:</label></td> + <td> + {{ range $idx, $bot := .battle.Bots }}{{if $idx}},{{end}}<a href="/bot/{{ $bot.ID }}">{{ $bot.Name }}</a>{{ end }} + </td> + </tr> + + <!-- + <tr> + <td><label for="public">Public?</label></td> + <td><input type="checkbox" id="public" name="public" {{ if .battle.Public }}checked{{end}}/></td> + </tr> + --> + + <tr> + <td>Archs</td> + <td> + {{ range $idx, $arch := .archs }}{{if $idx}},{{end}} + <input + type="checkbox" + class="check-with-label" + name="arch-{{$arch.ID}}" + id="arch-{{$arch.ID}}" + {{if $arch.Enabled}}checked{{end}}/> + <label class="label-for-check" for="arch-{{$arch.ID}}">{{$arch.Name}}</label> + {{- end }} + </td> </td> - </tr> - <!-- - <tr> - <td><label for="public">Public?</label></td> - <td><input type="checkbox" id="public" name="public" {{ if .battle.Public }}checked{{end}}/></td> - </tr> - --> - - <tr> - <td>Archs</td> - <td> - {{ range $idx, $arch := .archs }}{{if $idx}},{{end}} + <tr> + <td>Bits</td> + <td>{{ range $idx, $bit := .bits }}{{if $idx}},{{end}} <input type="checkbox" class="check-with-label" - name="arch-{{$arch.ID}}" - id="arch-{{$arch.ID}}" - {{if $arch.Enabled}}checked{{end}}/> - <label class="label-for-check" for="arch-{{$arch.ID}}">{{$arch.Name}}</label> - {{- end }} - </td> - </td> + id="bit-{{$bit.ID}}" + name="bit-{{$bit.ID}}" + {{if $bit.Enabled}}checked{{end}}/> + <label class="label-for-check" for="bit-{{$bit.ID}}">{{$bit.Name}}</label> + {{- end }} + </td> + </tr> + + <tr> + <td></td> + <td> + <table> + <tr> + <td style="width: 33%;"><input class="border" type="submit" value="Save"></td> + <td style="width: 33%;"></td> + <td style="width: 33%; "> + <!--<input type="submit" value="Delete this battle" form="delete" style="border: 1px solid red; ">--> + </td> + </tr> + </table> + </td> + </tr> + </form> - <tr> - <td>Bits</td> - <td>{{ range $idx, $bit := .bits }}{{if $idx}},{{end}} - <input - type="checkbox" - class="check-with-label" - id="bit-{{$bit.ID}}" - name="bit-{{$bit.ID}}" - {{if $bit.Enabled}}checked{{end}}/> - <label class="label-for-check" for="bit-{{$bit.ID}}">{{$bit.Name}}</label> - {{- end }} - </td> - </td> - - <tr> - <td></td> - <td> - <table> - <tr> - <td style="width: 33%;"><input class="border" type="submit" value="Save"></td> - <td style="width: 33%;"></td> - <td style="width: 33%; "> - <input type="submit" value="Delete this battle" form="delete" style="border: 1px solid red; "> - </td> - </tr> - </table> - </td> - </tr> - - </form> {{ if .res }} <tr> <td></td> - <td>{{ .res }}</td> + <td><div style="border: 1px solid blue; padding: 1ex">{{ .res }}</div></td> </tr> {{ end }} @@ -131,41 +130,38 @@ {{ if .myBots }} - <form method="POST" action="/battle/{{ .battle.ID }}/submit"> - <tr> - <td><label for="name">My Bots</label></td> - <td style="width: 100%;"> - <table style="width: 100%;"> - - {{ range $bot := .myBots }} - <tr class="trhover"> - <td style="text-align: center; vertical-align: middle; width: 2ex;"> - <input - type="checkbox" - id="bot-{{$bot.ID}}" - name="bot-{{$bot.ID}}" - value="{{$bot.ID}}" - {{ range $bbot := $.battle.Bots }} - {{ if eq $bot.ID $bbot.ID }}checked{{ end }} - {{ end }} - /> - <label for="bot-{{$bot.ID}}"> - <a href="/bot/{{$bot.ID}}">{{$bot.Name}}</a> - </label> - </td> - <td style="vertical-align: middle"> - </td> - </tr> - {{ end }} - - - </table> - </td> - </tr> - <tr> - <td colspan="5"><input class="border" type="submit" value="Submit bots"></td> - </tr> - </form> + <form method="POST" action="/battle/{{ .battle.ID }}/submit"> + <tr> + <td><label for="name">My Bots</label></td> + <td style="width: 100%;"> + <table style="width: 100%;"> + {{ range $bot := .myBots }} + <tr class="trhover"> + <td style="text-align: center; vertical-align: middle; width: 2ex;"> + <input + type="checkbox" + id="bot-{{$bot.ID}}" + name="bot-{{$bot.ID}}" + value="{{$bot.ID}}" + {{ range $bbot := $.battle.Bots }} + {{ if eq $bot.ID $bbot.ID }}checked{{ end }} + {{ end }} + /> + <label for="bot-{{$bot.ID}}"> + <a href="/bot/{{$bot.ID}}">{{$bot.Name}}</a> + </label> + </td> + <td style="vertical-align: middle"> + </td> + </tr> + {{ end }} + </table> + </td> + </tr> + <tr> + <td colspan="5"><input class="border" type="submit" value="Submit bots"></td> + </tr> + </form> {{ else }} @@ -176,6 +172,7 @@ {{ end }} + </tbody> <table> <br> @@ -184,6 +181,12 @@ <input class="border" type="submit" value="Run the Battle"> </form> + <br><br> + + <form id="delete" method="POST" action="/battle/{{ .battle.ID }}/delete"> + <input type="submit" value="Delete this battle" form="delete" style="border: 1px solid red; "> + </form> + <span id="registered bots"></span> <h2><a href="#registered-bots">Registered Bots</a></h2> @@ -194,7 +197,10 @@ <pre>{{ .battle.RawOutput }}</pre> - <span id="current-standings"></span> + <span id="debug"></span> + <h2><a href="#debug">Debug</a></h2> + + <pre>{{ .battle }}</pre> </body> {{ template "footer" . }} {{ end }} diff --git a/templates/nav.html b/templates/nav.html index 117f48a..cd710cb 100644 --- a/templates/nav.html +++ b/templates/nav.html @@ -1,7 +1,7 @@ {{ define "nav" }} <header> - <p style="margin: 1ex 0; display: block; width: 100%; background-color: red; color: white;"> - EARLY BETA - Data can be deleted at random! + <p style="margin: 1ex 0; display: block; width: 100%; background-color: #ffaa00; color: white;"> + EARLY BETA - Data can be deleted at random! - insecure af but almost functional </p> <a href="/">r2wa.rs</a> diff --git a/vendor/modules.txt b/vendor/modules.txt index 7f035d7..e5c09e7 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -36,8 +36,6 @@ github.com/radareorg/r2pipe-go # github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec ## explicit; go 1.12 github.com/remyoudompheng/bigfft -# github.com/xiaoqidun/entps v1.32.0 -## explicit; go 1.20 # golang.org/x/crypto v0.26.0 ## explicit; go 1.20 golang.org/x/crypto/argon2 |