123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- package main
- import (
- "fmt"
- "log"
- "math/rand"
- "net/http"
- glws "git.alfi.li/gamelang/frontend/webserver"
- gamelangpb "git.alfi.li/gamelang/protobuf/gamelang"
- "github.com/labstack/echo/v4"
- )
- func worldEndpoints(jg *JeopardyGameServer) []glws.Endpoint {
- endpoints := []glws.Endpoint{}
- endpoints = append(endpoints, glws.Endpoint{"GET", "/world", func(ctx echo.Context) error {
- ok, _ := jg.webserver.CheckSess(ctx)
- if !ok {
- log.Print("/World: not logged in")
- return ctx.String(http.StatusUnauthorized, "not logged in")
- }
- data := struct {
- Worlds []gamelangpb.World
- }{
- Worlds: func() []gamelangpb.World {
- worlds := jg.wm.List()
- return worlds
- }(),
- }
- err := ctx.Render(http.StatusOK, "worldlobby", data)
- if err != nil {
- log.Print(err)
- }
- return err
- }})
- endpoints = append(endpoints, glws.Endpoint{"POST", "/world", func(ctx echo.Context) error {
- ok, _ := jg.webserver.CheckSess(ctx)
- if !ok {
- log.Print("/World: not logged in")
- return ctx.String(http.StatusUnauthorized, "not logged in")
- }
- worldname := ctx.FormValue("worldname")
- world := &gamelangpb.World{Name: worldname}
- lobbygame := CraftLobbygame(fmt.Sprintf("%s\uffff%s", world.GetName(), "lobby"))
- world.Games = []string{lobbygame.Name}
- log.Println("/World: creating world_\n", world)
- id := rand.Uint32()
- world.Id = id
- _, err := jg.wm.Create(*world)
- if err != nil {
- log.Println("error creating world", err)
- return ctx.String(http.StatusInternalServerError, "error creating world")
- }
- err = jg.jeopardymanager.Create(lobbygame)
- if err != nil {
- log.Println("error creating world", err)
- return ctx.String(http.StatusInternalServerError, "error creating world")
- }
- return ctx.Redirect(http.StatusFound, "/world")
- }})
- endpoints = append(endpoints, glws.Endpoint{"POST", "/world/join", func(ctx echo.Context) error {
- log.Print("join attemt")
- ok, user := jg.webserver.CheckSess(ctx)
- if !ok {
- log.Print("/World/join: not logged in")
- return ctx.String(http.StatusUnauthorized, "not logged in")
- }
- worldname := ctx.FormValue("worldname")
- log.Println("joining", user.Name, "to", worldname)
- joinworld := gamelangpb.World{Name: worldname, Users: []*gamelangpb.User{}}
- joinworld.Users = append(joinworld.Users, &user)
- err := jg.wm.Join(worldname, &user)
- if err != nil {
- log.Printf("error joining %s to %s\n%s", user.Name, worldname, err.Error())
- return ctx.String(501, "join failed")
- }
- log.Println("join of", user.Name, "to", worldname, "complete")
- return ctx.Redirect(302, "/world")
- }})
- return endpoints
- return endpoints
- }
- func worldHandler(jg JeopardyGameServer) []glwss.Handler{} {
- handler := []glwss.Handler{}
- handler = append(handler, glwss.Handler{MType: "world:create", Callback: func(msg glwss.WSMsg, user gamelangpb.User) (glwss.WSMsg, error) {
- createWorld := gamelangpb.World{Name: msg.Payload}
- lobbygame := CraftLobbygame(fmt.Sprintf("%s\uffff%s", createWorld.GetName(), "lobby"))
- createWorld.Games = []string{lobbygame.Name}
- id := rand.Uint32()
- createWorld.Id = id
- _, err := jg.wm.Create(*&createWorld)
- if err != nil {
- remsg := glwss.WSMsg{Mtype: "world:create", Payload: "failed"}
- return remsg, err
- }
- err = jg.jeopardymanager.Create(lobbygame)
- if err != nil {
- remsg := glwss.WSMsg{Mtype: "world:create", Payload: "failed"}
- return remsg, err
- }
- log.Println("world:create created Lobbygame:\n", lobbygame)
- createworldJSON, _ := json.Marshal(createWorld)
- remsg := glwss.WSMsg{Mtype: "world:create", Payload: string(createworldJSON)}
- return remsg, nil
- }})
- handler = append(handler, glwss.Handler{MType: "world:remove", Callback: func(msg glwss.WSMsg, user gamelangpb.User) (glwss.WSMsg, error) {
- err := jg.wm.Remove(msg.Payload)
- if err != nil {
- remsg := glwss.WSMsg{Mtype: "world:remove", Payload: "failed"}
- return remsg, err
- }
- remsg := glwss.WSMsg{Mtype: "world:remove", Payload: "success"}
- return remsg, nil
- }})
- handler = append(handler, glwss.Handler{MType: "world:join", Callback: func(msg glwss.WSMsg, user gamelangpb.User) (glwss.WSMsg, error) {
- worldname := msg.Payload
- err := jg.wm.Join(worldname, &user)
- if err != nil {
- remsg := glwss.WSMsg{Mtype: "world:join", Payload: "failed"}
- return remsg, err
- }
- remsg := glwss.WSMsg{Mtype: "world:join", Payload: "success"}
- return remsg, nil
- }})
- handler = append(handler, glwss.Handler{MType: "world:list", Callback: func(msg glwss.WSMsg, user gamelangpb.User) (glwss.WSMsg, error) {
- log.Print("world:list")
- worldlist := jg.wm.List()
- worldlistJSON, err := json.Marshal(worldlist)
- if err != nil {
- log.Print(err.Error())
- msg := glwss.WSMsg{Mtype: "world:list", Payload: "failed"}
- return msg, err
- }
- log.Print("world:list", "sending list")
- remsg := glwss.WSMsg{Mtype: "world:list", Payload: string(worldlistJSON)}
- return remsg, nil
- }})
- handler = append(handler, glwss.Handler{MType: "game:get", Callback: func(msg glwss.WSMsg, user gamelangpb.User) (glwss.WSMsg, error) {
- log.Println("game:get new get request:\n\"", msg.Payload, "\"")
- var world gamelangpb.World
- worldname := msg.Payload
- worlds := jg.wm.List()
- for _, world = range worlds {
- if world.GetName() == worldname {
- log.Println("sending world\n", world)
- break
- }
- }
- log.Println("game:get got world:\n\"", world, "\"")
- lobbygame := gljeopardypb.Jeopardy{}
- commongame := gljeopardypb.Jeopardy{}
- usergame := gljeopardypb.Jeopardy{}
- for _, game := range world.GetGames() {
- log.Println("searching games", game)
- if game == fmt.Sprintf("%s\uffff%s", world.GetName(), "lobby") {
- log.Println("found lobbygame", game)
- searchGame := gljeopardypb.Jeopardy{Name: game}
- lobbygame = jg.jeopardymanager.Get(searchGame)
- }
- if game == fmt.Sprintf("%s\uffff%s", world.GetName(), "common") {
- log.Println("found commongame", game)
- searchGame := gljeopardypb.Jeopardy{Name: game}
- commongame = jg.jeopardymanager.Get(searchGame)
- }
- if user.Name == strings.Split(game, "\uffff")[1] {
- log.Println("found usergame", game)
- searchGame := gljeopardypb.Jeopardy{Name: game}
- usergame = jg.jeopardymanager.Get(searchGame)
- break
- }
- }
- returngame := gljeopardypb.Jeopardy{}
- if usergame.Name == fmt.Sprintf("%s\uffff%s", world.GetName(), user.Name) {
- log.Println("sending usergame", usergame.Name)
- returngame = usergame
- } else if commongame.Name == fmt.Sprintf("%s\uffff%s", world.GetName(), "common") {
- log.Println("sending commongame", commongame.Name)
- returngame = commongame
- } else if lobbygame.Name == fmt.Sprintf("%s\uffff%s", world.GetName(), "lobby") {
- log.Println("sending lobbygame", lobbygame.Name)
- returngame = lobbygame
- } else {
- // if get returned empty game
- returngame = CraftLobbygame(fmt.Sprintf("%s\uffff%s", world.GetName(), "lobby"))
- jg.jeopardymanager.Create(returngame)
- log.Print("could not find lobbygame, so created one")
- }
- gameJSON, err := json.Marshal(returngame)
- if err != nil {
- remsg := glwss.WSMsg{Mtype: "game:get", Payload: "failed"}
- return remsg, err
- }
- log.Println("game:get sending game:\n", string(gameJSON))
- remsg := glwss.WSMsg{Mtype: "game:get", Payload: string(gameJSON)}
- return remsg, nil
- }})
- handler = append(handler, glwss.Handler{MType: "game:start", Callback: func(msg glwss.WSMsg, user gamelangpb.User) (glwss.WSMsg, error) {
- log.Println("game:start new start request:\n", msg.Payload)
- startgame := gljeopardypb.Jeopardy{}
- err := json.Unmarshal([]byte(msg.Payload), &startgame)
- if err != nil {
- log.Printf("game:start - err unmarshalling startgame \"%s\"\n%s", msg, err.Error())
- remsg := glwss.WSMsg{Mtype: "game:start", Payload: "failed"}
- return remsg, err
- }
- var startworld gamelangpb.World
- worlds := jg.wm.List()
- for _, startworld = range worlds {
- if startworld.GetName() == strings.Split(startgame.Name, "\uffff")[0] {
- log.Println("sending world\n", startworld)
- break
- }
- }
- if err != nil {
- log.Printf("game:start - err unmarshalling startworld \"%s\"\n%s", msg, err.Error())
- remsg := glwss.WSMsg{Mtype: "game:start", Payload: "failed"}
- return remsg, err
- }
- // start game
- for _, option := range startgame.Options {
- if option.Key == "common game" && option.Bool {
- newGame := jg.jeopardymanager.CraftGame(rand.Uint32(), fmt.Sprintf("%s\uffffcommon", startworld.Name), startgame.Options...)
- jg.jeopardymanager.Create(*newGame)
- jg.wm.AddGame(startworld.Name, startworld.Name)
- jsonGame, err := json.Marshal(newGame)
- if err != nil {
- log.Printf("write: err marshalling game \"%s\"\n%s", msg, err.Error())
- }
- remsg := glwss.WSMsg{Mtype: "game:get", Payload: string(jsonGame)}
- if err != nil {
- log.Printf("write: err marshalling msg \"%s\"\n%s", msg, err.Error())
- }
- for _, user := range startworld.Users {
- go jg.wssserver.Write(user.Name, remsg)
- }
- }
- }
- remsg := glwss.WSMsg{Mtype: "game:start", Payload: "sucess"}
- return remsg, nil
- }})
- handler = append(handler, glwss.Handler{MType: "game:mod", Callback: func(msg glwss.WSMsg, user gamelangpb.User) (glwss.WSMsg, error) {
- modgame := &gljeopardypb.Jeopardy{}
- err := json.Unmarshal([]byte(msg.Payload), modgame)
- if err != nil {
- log.Printf("game:mod - err unmarshalling msg \"%s\"\n%s", msg, err.Error())
- remsg := glwss.WSMsg{Mtype: "game:mod", Payload: "failed"}
- return remsg, nil
- }
- jg.jeopardymanager.Modify(*modgame)
- var world gamelangpb.World
- worlds := jg.wm.List()
- for _, world = range worlds {
- if world.GetName() == strings.Split(modgame.Name, "\uffff")[0] {
- log.Println("sending world\n", world)
- break
- }
- }
- if err != nil {
- log.Printf("game:mod - err getting world msg \"%s\"\n%s", msg, err.Error())
- remsg := glwss.WSMsg{Mtype: "game:mod", Payload: "failed"}
- return remsg, nil
- }
- notify := glwss.WSMsg{Mtype: "game:get", Payload: msg.Payload}
- for _, user := range world.Users {
- go jg.wssserver.Write(user.Name, notify)
- }
- jg.jeopardymanager.CheckWin()
- remsg := glwss.WSMsg{Mtype: "game:mod", Payload: "success"}
- return remsg, nil
- }})
- handler = append(handler, glwss.Handler{MType: "game:event", Callback: func(msg glwss.WSMsg, user gamelangpb.User) (glwss.WSMsg, error) {
- newevent := &gljeopardypb.Event{}
- err := json.Unmarshal([]byte(msg.Payload), newevent)
- if err != nil {
- log.Printf("game:event - err unmarshalling msg \"%s\"\n%s", msg, err.Error())
- remsg := glwss.WSMsg{Mtype: "game:event", Payload: "failed"}
- return remsg, nil
- }
- newevent.Username = user.Name
- log.Println("game:event new event", newevent)
- worldgamename := strings.Split(newevent.Gamename, "\uffff")
- worldname := worldgamename[0]
- gamename := worldgamename[1]
- // if the game is not a common game add all games from that world to neighborgames
- if gamename != "common" {
- var world gamelangpb.World
- worlds := jg.wm.List()
- for _, world = range worlds {
- if world.GetName() == worldname {
- log.Println("sending world\n", world)
- break
- }
- }
- if err != nil {
- log.Printf("workNotifications - err getting world msg \"%s\"\n%s", worldname, err.Error())
- remsg := glwss.WSMsg{Mtype: "game:mod", Payload: "failed"}
- return remsg, nil
- }
- for _, game := range world.Games {
- if strings.Split(game, "\uffff")[1] != "lobby" {
- newevent.Neighborgames = append(newevent.Neighborgames, game)
- }
- }
- }
- err = jg.jeopardymanager.HandleEvent(*newevent)
- if err != nil {
- if err.Error() == "game finished" {
- reevent := gljeopardypb.Event{Type: "Win", Gamename: newevent.Gamename}
- eventJson, err := json.Marshal(reevent)
- if err != nil {
- log.Printf("workNotifications - err marshalling event \"%s\"\n%s", reevent, err.Error())
- }
- notify := glwss.WSMsg{Mtype: "game:event", Payload: string(eventJson)}
- return notify, nil
- }
- return glwss.WSMsg{Mtype: "game:event", Payload: "failed"}, err
- }
- remsg := glwss.WSMsg{Mtype: "game:event", Payload: "success"}
- jg.jeopardymanager.CheckWin()
- return remsg, nil
- }})
- return handler
- }
|