123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661 |
- package main
- import (
- "context"
- "encoding/json"
- "fmt"
- "html/template"
- "io"
- "log"
- "math/rand"
- "net/http"
- "strings"
- glws "git.alfi.li/gamelang/frontend/webserver"
- glwss "git.alfi.li/gamelang/frontend/wsserver"
- bingoman "git.alfi.li/gamelang/games/bingo/bingoManager"
- gamelangpb "git.alfi.li/gamelang/protobuf/gamelang"
- glbingopb "git.alfi.li/gamelang/protobuf/gamelang-bingo"
- userman "git.alfi.li/gamelang/systems/usermanager"
- worldman "git.alfi.li/gamelang/systems/worldmanager"
- "github.com/labstack/echo/v4"
- "gopkg.in/gcfg.v1"
- )
- // Template wraps go's html template
- type Template struct {
- templates *template.Template
- }
- // Render renders a Template
- func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
- return t.templates.ExecuteTemplate(w, name, data)
- }
- func initTemplates(e *echo.Echo) {
- t := &Template{
- templates: template.Must(template.ParseGlob("public/*.html")),
- }
- e.Renderer = t
- }
- type BingoConfig struct {
- Http struct {
- ListenIP string
- ListenPort string
- }
- WS struct {
- ListenIP string
- ListenPort string
- }
- Manager struct {
- UserManager string
- WorldManager string
- BingoManager string
- }
- }
- func getDefaultConfig() BingoConfig {
- bc := BingoConfig{}
- bc.Http.ListenIP = "127.0.0.1"
- bc.Http.ListenPort = "8080"
- bc.WS.ListenIP = "127.0.0.1"
- bc.WS.ListenPort = "8081"
- bc.Manager.UserManager = "localhost:9090"
- bc.Manager.WorldManager = "localhost:9091"
- bc.Manager.BingoManager = "localhost:9092"
- return bc
- }
- type BingoGame struct {
- um *userman.UserManager //gamelangpb.UserServiceClient
- wm *worldman.WorldManager //gamelangpb.WorldServiceClient
- bingomanager *bingoman.BingoManager
- webserver *glws.Webserver
- wssserver *glwss.WSServer
- notichan chan glbingopb.Event
- config BingoConfig
- }
- func (bg *BingoGame) Init(config BingoConfig) {
- //init userclient
- //userconn, err := grpc.Dial(config.Manager.UserManager, grpc.WithInsecure())
- //if err != nil {
- // panic(err.Error())
- //}
- //defer userconn.Close()
- bg.um = userman.NewUserManager([]string{}) //gamelangpb.NewUserServiceClient(userconn)
- //init wm
- //worldconn, err := grpc.Dial(config.Manager.WorldManager, grpc.WithInsecure())
- //if err != nil {
- // panic(err.Error())
- //}
- //defer worldconn.Close()
- bg.wm = worldman.NewWorldManager([]string{}) //gamelangpb.NewWorldServiceClient(worldconn)
- bg.notichan = make(chan glbingopb.Event)
- bg.bingomanager = bingoman.NewBingoManager([]string{}, bg.notichan)
- go bg.workNotifications()
- //init webserver
- wsConfig := glws.Config{}
- wsConfig.Http.ListenIP = config.Http.ListenIP
- wsConfig.Http.ListenPort = config.Http.ListenPort
- bg.webserver = glws.NewWebserver(wsConfig)
- }
- func (bg *BingoGame) workNotifications() {
- for {
- log.Print("waiting for notification")
- event := <-bg.notichan
- log.Println("new notification", event)
- eventJson, err := json.Marshal(event)
- if err != nil {
- log.Printf("workNotifications - err marshalling event \"%s\"\n%s", event, err.Error())
- }
- notify := glwss.WSMsg{Mtype: "game:event", Payload: string(eventJson)}
- worldgamename := strings.Split(event.Gamename, "\uffff")
- worldname := worldgamename[0]
- gamename := worldgamename[1]
- // if the game is a common game or its a win event all players have to be notified
- if gamename == "common" || event.Type == "Win" {
- world := gamelangpb.World{}
- worlds := bg.wm.List()
- for _, world := range worlds {
- if world.GetName() == worldname {
- log.Println("sending world\n", world)
- break
- }
- }
- //world, err := bg.wm.GetWorld(context.Background(), &gamelangpb.World{Name: worldname})
- if err != nil {
- log.Printf("workNotifications - err getting world msg \"%s\"\n%s", worldname, err.Error())
- return
- }
- for _, user := range world.Users {
- go bg.wssserver.Write(user.Name, notify)
- }
- } else {
- bg.wssserver.Write(event.Username, notify)
- }
- }
- }
- // RenderEndpoints returns the endpoints that are served by the webserver
- func (bg *BingoGame) RenderEndpoints() []glws.Endpoint {
- endpoints := []glws.Endpoint{}
- endpoints = append(endpoints, glws.Endpoint{"GET", "/",
- func(ctx echo.Context) error {
- log.Print("/: get")
- ok, user := bg.webserver.CheckSess(ctx)
- if !ok {
- log.Print("/: not found")
- return ctx.Redirect(301, "/login")
- }
- data := struct {
- Username string
- Worlds []gamelangpb.World
- Items []string
- }{
- Username: user.Name,
- Worlds: func() []gamelangpb.World {
- worlds := bg.wm.List()
- return worlds
- }(),
- Items: []string{
- "user",
- "world",
- },
- }
- log.Printf("/: user \"%v\" found", user.Name)
- return ctx.Render(http.StatusOK, "index", data)
- }})
- endpoints = append(endpoints, glws.Endpoint{"GET", "/user", func(ctx echo.Context) error {
- log.Print("/user: get")
- log.Print("/user: sending register form")
- return ctx.Render(http.StatusOK, "registerform", "")
- }})
- // POST to /user creates a user
- endpoints = append(endpoints, glws.Endpoint{"POST", "/user", func(ctx echo.Context) error {
- username := ctx.FormValue("username")
- password := ctx.FormValue("password")
- log.Printf("new user request: %v", username)
- newUser := gamelangpb.User{Name: username, Password: []byte(password)}
- id := rand.Uint32()
- name := newUser.GetName()
- _, err := bg.um.Create(id, name, password)
- //user, err := bg.userclient.CreateUser(context.Background(), &newUser)
- if err != nil {
- return ctx.String(501, "user creation failed")
- }
- bg.webserver.NewSession(newUser, ctx)
- log.Printf("new user created: %v", username)
- return ctx.Redirect(302, "/")
- }})
- endpoints = append(endpoints, glws.Endpoint{"GET", "/login", func(ctx echo.Context) error {
- log.Print("/login: get")
- // check if the login page was called with failed parameter (set by /login POST)
- failedBefore := false
- if value := ctx.FormValue("failed"); value == "1" {
- failedBefore = true
- }
- ok, user := bg.webserver.CheckSess(ctx)
- if ok {
- // logged in
- log.Printf("/login: user %v logged in", user.Name)
- return ctx.String(http.StatusOK, "hello, "+user.Name+"\nyou are logged in.")
- }
- // not logged in
- log.Print("/login: not logged in")
- return ctx.Render(http.StatusOK, "loginform", failedBefore)
- }})
- endpoints = append(endpoints, glws.Endpoint{"POST", "/login", func(ctx echo.Context) error {
- log.Print("/login: post")
- username := ctx.FormValue("username")
- password := ctx.FormValue("password")
- // if the session is already set, the user is already logged in
- ok, _ := bg.webserver.CheckSess(ctx)
- if ok {
- return ctx.String(http.StatusOK, "you are already logged in.")
- }
- log.Printf("user login attempt: %v", username)
- //checkuser := gamelangpb.User{Name: username, Password: []byte(password)}
- user, ok := bg.um.Check(username, password) //bg.userclient.CheckUser(context.Background(), &checkuser)
- if ok { //err == nil {
- bg.webserver.NewSession(user, ctx)
- log.Printf("user login suceeded: %v", username)
- return ctx.String(http.StatusOK, "hello, "+username+"\nyou are now logged in.")
- }
- log.Printf("user login failed: %v\n%s", username)
- return ctx.Redirect(302, "/login?failed=1")
- }})
- endpoints = append(endpoints, glws.Endpoint{"GET", "/admin", func(ctx echo.Context) error {
- log.Print("/admin: get")
- ok, user := bg.webserver.CheckSess(ctx)
- if !ok {
- log.Print("/admin: not logged in")
- return ctx.String(http.StatusUnauthorized, "not logged in")
- }
- log.Println("/admin:", user.Name)
- if user.Admin != true && user.Name != "admin" {
- log.Println("/admin: user is not an admin", user.Name)
- return ctx.String(http.StatusUnauthorized, "you are not an admin")
- }
- data := struct {
- Users []gamelangpb.User
- Sessions map[string]gamelangpb.User
- Worlds []gamelangpb.World
- }{
- Users: func() []gamelangpb.User {
- users := bg.um.List()
- return users
- }(),
- Sessions: bg.webserver.ListSess(),
- Worlds: func() []gamelangpb.World {
- worlds := bg.wm.List()
- return worlds
- }(),
- }
- err := ctx.Render(http.StatusOK, "admin", data)
- if err != nil {
- log.Println(err)
- }
- return err
- }})
- // worldbuilder
- // Get to /World returns register form
- endpoints = append(endpoints, glws.Endpoint{"GET", "/world", func(ctx echo.Context) error {
- ok, _ := bg.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 := bg.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, _ := bg.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 := bg.wm.Create(*world)
- if err != nil {
- log.Println("error creating world", err)
- return ctx.String(http.StatusInternalServerError, "error creating world")
- }
- err = bg.bingomanager.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 := bg.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 := bg.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
- }
- //RenderHandler renders the endpoints that will be served via websocket
- func (bg *BingoGame) RenderHandler() []glwss.Handler {
- handler := []glwss.Handler{}
- handler = append(handler, glwss.Handler{MType: "echo", Callback: func(msg glwss.WSMsg, user gamelangpb.User) (glwss.WSMsg, error) {
- log.Printf("echo from \"%v\" with \"%s\"", user, msg.Payload)
- remsg := glwss.WSMsg{Mtype: "echo", Payload: msg.Payload}
- return remsg, nil
- }})
- 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 := bg.wm.Create(*&createWorld)
- if err != nil {
- remsg := glwss.WSMsg{Mtype: "world:create", Payload: "failed"}
- return remsg, err
- }
- err = bg.bingomanager.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 := bg.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 := bg.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 := bg.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 := bg.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 := glbingopb.Bingo{}
- commongame := glbingopb.Bingo{}
- usergame := glbingopb.Bingo{}
- 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 := glbingopb.Bingo{Name: game}
- lobbygame = bg.bingomanager.Get(searchGame)
- }
- if game == fmt.Sprintf("%s\uffff%s", world.GetName(), "common") {
- log.Println("found commongame", game)
- searchGame := glbingopb.Bingo{Name: game}
- commongame = bg.bingomanager.Get(searchGame)
- }
- if user.Name == strings.Split(game, "\uffff")[1] {
- log.Println("found usergame", game)
- searchGame := glbingopb.Bingo{Name: game}
- usergame = bg.bingomanager.Get(searchGame)
- break
- }
- }
- returngame := glbingopb.Bingo{}
- 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"))
- bg.bingomanager.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 := glbingopb.Bingo{}
- 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
- }
- searchworld := gamelangpb.World{Name: strings.Split(startgame.Name, "\uffff")[0]}
- startworld, err := bg.wm.GetWorld(context.Background(), &searchworld)
- 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 := bg.bingomanager.CraftGame(rand.Uint32(), fmt.Sprintf("%s\uffffcommon", startworld.Name), startgame.Textlist, startgame.Numrows, startgame.Numcols, startgame.Options...)
- bg.bingomanager.Create(newGame)
- addworld := gamelangpb.World{Name: startworld.Name, Games: []string{newGame.Name}}
- bg.wm.AddGameWorld(context.Background(), &addworld)
- 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 bg.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 := &glbingopb.Bingo{}
- 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
- }
- bg.bingomanager.Modify(*modgame)
- searchworld := gamelangpb.World{Name: strings.Split(modgame.Name, "\uffff")[0]}
- world, err := bg.wm.GetWorld(context.Background(), &searchworld)
- 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 bg.wssserver.Write(user.Name, notify)
- }
- bg.bingomanager.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 := &glbingopb.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" {
- world, err := bg.wm.GetWorld(context.Background(), &gamelangpb.World{Name: worldname})
- 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 = bg.bingomanager.HandleEvent(*newevent)
- if err != nil {
- if err.Error() == "game finished" {
- reevent := glbingopb.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"}
- bg.bingomanager.CheckWin()
- return remsg, nil
- }})
- return handler
- }
- func CraftLobbygame(name string) glbingopb.Bingo {
- lobbygame := glbingopb.Bingo{Name: name}
- lobbygame.Options = append(lobbygame.Options, &glbingopb.Option{Key: "unique fields", Bool: true, Type: 1})
- lobbygame.Options = append(lobbygame.Options, &glbingopb.Option{Key: "common game", Bool: true, Type: 1})
- lobbygame.Numcols = 5
- lobbygame.Numrows = 5
- lobbygame.Textlist = []string{"word"}
- return lobbygame
- }
- func main() {
- var config BingoConfig
- err := gcfg.ReadFileInto(&config, "config")
- if err != nil {
- if strings.Count(err.Error(), "no such file or directory") > 0 {
- config = getDefaultConfig()
- } else {
- log.Fatal(err)
- }
- }
- log.Print("config read")
- log.Printf("%+v", config)
- bingogame := BingoGame{}
- bingogame.Init(config)
- bingogame.webserver.InitEndpoints(bingogame.RenderEndpoints())
- go bingogame.webserver.Run()
- bingogame.wssserver = glwss.NewWSServer([]string{}, bingogame.userclient)
- handler := bingogame.RenderHandler()
- keys := ""
- for _, k := range handler {
- keys = fmt.Sprintf("%s\n%v", keys, k)
- }
- log.Println("available MTypes:\n", keys, "\n----")
- bingogame.wssserver.RegisterHandler(handler)
- http.HandleFunc("/ws", bingogame.wssserver.WebsocketHandler)
- log.Println("websocket listening on", fmt.Sprintf("%s:%s", config.WS.ListenIP, config.WS.ListenPort))
- log.Print(http.ListenAndServe(fmt.Sprintf("%s:%s", config.WS.ListenIP, config.WS.ListenPort), nil).Error())
- }
|