feat(frontend): get login token from server
As of right now, we don't actually do anything with the token. But at
least we're actually able to get it. 😅
Caveats in implementation:
- UI now needs a pointer to player
- .env is now required for server auth (mentioned in README.md)
This commit is contained in:
parent
4c536581e1
commit
a1f6d8fe7f
1
frontend/.gitignore
vendored
Normal file
1
frontend/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
.env
|
6
frontend/README.md
Normal file
6
frontend/README.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Frontend Usage
|
||||
|
||||
You must create a `.env` file in the same folder as your game executable, with
|
||||
`BACKEND_URL` being a valid URL to a server running the [game server](../backend).
|
||||
Note that this isn't necessary if you're playing in a browser or using a download
|
||||
from itch.io
|
|
@ -6,6 +6,7 @@ require (
|
|||
github.com/devraza/ambition/frontend/player v0.0.0-00010101000000-000000000000
|
||||
github.com/devraza/ambition/frontend/ui v0.0.0-00010101000000-000000000000
|
||||
github.com/hajimehoshi/ebiten/v2 v2.5.5
|
||||
github.com/joho/godotenv v1.5.1
|
||||
)
|
||||
|
||||
require (
|
||||
|
|
|
@ -13,6 +13,8 @@ github.com/hajimehoshi/ebiten/v2 v2.5.5 h1:TJNoZsYJYUyFucwE56QRSgmZ+/cklUt1YrwpQ
|
|||
github.com/hajimehoshi/ebiten/v2 v2.5.5/go.mod h1:mnHSOVysTr/nUZrN1lBTRqhK4NG+T9NR3JsJP2rCppk=
|
||||
github.com/jezek/xgb v1.1.0 h1:wnpxJzP1+rkbGclEkmwpVFQWpuE2PUGNUzP8SbfFobk=
|
||||
github.com/jezek/xgb v1.1.0/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||
|
|
|
@ -11,12 +11,9 @@ import (
|
|||
|
||||
// Ebitengine
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
// "github.com/hajimehoshi/ebiten/v2/ebitenutil"
|
||||
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
|
||||
)
|
||||
|
||||
// Initialise the test player
|
||||
var testPlayer = p.GetPlayer()
|
||||
|
||||
// Create the `Game` struct
|
||||
type Game struct {
|
||||
ui u.UI
|
||||
|
@ -40,6 +37,7 @@ func (g *Game) Update() error {
|
|||
func (g *Game) Draw(screen *ebiten.Image) {
|
||||
// Draw the UI onto the screen
|
||||
g.ui.Base.Draw(screen)
|
||||
ebitenutil.DebugPrint(screen, g.activePlayer.JwtToken)
|
||||
}
|
||||
|
||||
// Layout implements Game
|
||||
|
@ -64,11 +62,9 @@ func main() {
|
|||
ebiten.SetWindowTitle(window_title)
|
||||
|
||||
// Initialise the game
|
||||
game := Game{
|
||||
// Initialise the UI
|
||||
activePlayer: testPlayer,
|
||||
ui: u.UiInit(window_width, window_height),
|
||||
}
|
||||
game := Game{}
|
||||
game.activePlayer = p.NewPlayer()
|
||||
game.ui = u.UiInit(window_width, window_height, &game.activePlayer)
|
||||
|
||||
// Log and exit on error
|
||||
if err := ebiten.RunGame(&game); err != nil {
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
package player
|
||||
|
||||
import ()
|
||||
import (
|
||||
s "github.com/devraza/ambition/frontend/server"
|
||||
"log"
|
||||
)
|
||||
|
||||
// The player struct
|
||||
type Player struct {
|
||||
JwtToken string
|
||||
Health int
|
||||
MaxHealth int
|
||||
Defence int
|
||||
|
@ -18,20 +22,40 @@ type Player struct {
|
|||
var level_gates = make(map[int]float32)
|
||||
var level_ambition = make(map[int]float32)
|
||||
|
||||
// TODO(midnadimple): Move player initialization to server upon login
|
||||
func GetPlayer() Player {
|
||||
func NewPlayer() Player {
|
||||
return Player{
|
||||
Health: 100,
|
||||
MaxHealth: 100,
|
||||
Defence: 0,
|
||||
Level: 1,
|
||||
Exp: 0.0,
|
||||
NextExp: 0.0,
|
||||
Ambition: 0.0, // NOTE(midnadimple): In the future this will be affected by player activity
|
||||
MaxAmbition: level_ambition[1], // NOTE(midnadimple): In the future this will be affected by player activity
|
||||
JwtToken: "",
|
||||
Health: 0,
|
||||
MaxHealth: 0,
|
||||
Defence: 0,
|
||||
Level: 0,
|
||||
Exp: 0.0,
|
||||
NextExp: 0.0,
|
||||
Ambition: 0.0,
|
||||
MaxAmbition: 0.0,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (p *Player) Init(name, password string) {
|
||||
// JWT Get Token
|
||||
jwt_token, err := s.GetUserJwtToken(name, password)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
p.JwtToken = jwt_token
|
||||
|
||||
// TODO(midnadimple): Get player data from server.
|
||||
p.Health = 100
|
||||
p.MaxHealth = 100
|
||||
p.Defence = 0
|
||||
p.Level = 1
|
||||
p.Exp = 0.0
|
||||
p.NextExp = 0.0
|
||||
p.Ambition = 0.0 // NOTE(midnadimple): In the future this will be affected by player activity
|
||||
p.MaxAmbition = level_ambition[1] // NOTE(midnadimple): In the future this will be affected by player activity
|
||||
}
|
||||
|
||||
// Formula for XP gain - extremely simple
|
||||
func gain(basexp float32, modifier float32) float32 {
|
||||
gain := basexp * modifier
|
||||
|
|
40
frontend/server/requests.go
Normal file
40
frontend/server/requests.go
Normal file
|
@ -0,0 +1,40 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"os"
|
||||
"errors"
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
// Needed for server url
|
||||
_ "github.com/joho/godotenv/autoload"
|
||||
)
|
||||
|
||||
var server_address = os.Getenv("BACKEND_URL")
|
||||
|
||||
func GetUserJwtToken(name, password string) (string, error) {
|
||||
if server_address == "" {
|
||||
return "", errors.New("no server url provided")
|
||||
}
|
||||
|
||||
post_body, _ := json.Marshal(map[string]string{
|
||||
"name": name,
|
||||
"password": password,
|
||||
})
|
||||
resp_body := bytes.NewBuffer(post_body)
|
||||
|
||||
resp, err := http.Post(server_address + "/user", "application/json", resp_body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(body), nil
|
||||
}
|
|
@ -1,21 +1,18 @@
|
|||
package ui
|
||||
|
||||
import (
|
||||
// Misc.
|
||||
"fmt"
|
||||
|
||||
// Image
|
||||
img "image"
|
||||
|
||||
// Ambition
|
||||
// p "github.com/devraza/ambition/frontend/player"
|
||||
p "github.com/devraza/ambition/frontend/player"
|
||||
|
||||
// EbitenUI
|
||||
"github.com/ebitenui/ebitenui/image"
|
||||
"github.com/ebitenui/ebitenui/widget"
|
||||
)
|
||||
|
||||
func makeLoginWindow(width, height int, root *widget.Container, shown *widget.Container) {
|
||||
func makeLoginWindow(width, height int, root *widget.Container, shown *widget.Container, player *p.Player) {
|
||||
// Define the contents of the login window
|
||||
loginContainer := widget.NewContainer(
|
||||
widget.ContainerOpts.BackgroundImage(image.NewNineSliceColor(ui.colors["gray"])),
|
||||
|
@ -62,9 +59,6 @@ func makeLoginWindow(width, height int, root *widget.Container, shown *widget.Co
|
|||
widget.CaretOpts.Size(defaultFace, 2),
|
||||
),
|
||||
widget.TextInputOpts.Placeholder("Username"),
|
||||
widget.TextInputOpts.SubmitHandler(func(args *widget.TextInputChangedEventArgs) {
|
||||
fmt.Println("Text Submitted: ", args.InputText)
|
||||
}),
|
||||
)
|
||||
passwordInput := widget.NewTextInput(
|
||||
widget.TextInputOpts.WidgetOpts(
|
||||
|
@ -91,9 +85,6 @@ func makeLoginWindow(width, height int, root *widget.Container, shown *widget.Co
|
|||
widget.TextInputOpts.Secure(true),
|
||||
|
||||
widget.TextInputOpts.Placeholder("Password"),
|
||||
widget.TextInputOpts.SubmitHandler(func(args *widget.TextInputChangedEventArgs) {
|
||||
fmt.Println("Text Submitted: ", args.InputText)
|
||||
}),
|
||||
)
|
||||
// Add the text inputs to the login window
|
||||
loginContainer.AddChild(usernameInput)
|
||||
|
@ -130,6 +121,7 @@ func makeLoginWindow(width, height int, root *widget.Container, shown *widget.Co
|
|||
}),
|
||||
// Button on-click handler
|
||||
widget.ButtonOpts.ClickedHandler(func(args *widget.ButtonClickedEventArgs) {
|
||||
player.Init(usernameInput.InputText, passwordInput.InputText)
|
||||
removeContainer(root, loginContainer)
|
||||
addContainer(root, shown)
|
||||
}),
|
||||
|
|
|
@ -22,14 +22,12 @@ import (
|
|||
// The UI struct
|
||||
type UI struct {
|
||||
Base ebitenui.UI
|
||||
player *p.Player
|
||||
colors map[string]color.RGBA
|
||||
width, height int
|
||||
textInput *widget.TextInput
|
||||
}
|
||||
|
||||
// Get the player from the `player` package
|
||||
var player = p.GetPlayer()
|
||||
|
||||
// The `hazakura` colorscheme (default)
|
||||
var hazakura = map[string]color.RGBA{
|
||||
// The monotone colors
|
||||
|
@ -62,9 +60,10 @@ var defaultFace, _ = makeFace(14, fonts.FiraRegular_ttf)
|
|||
var buttonImage, _ = loadButtonImage()
|
||||
|
||||
// Function for UI initialization
|
||||
func UiInit(width, height int) UI {
|
||||
func UiInit(width, height int, player *p.Player) UI {
|
||||
// Define the UI colors
|
||||
ui.colors = hazakura
|
||||
ui.player = player
|
||||
|
||||
// Get the window width/height
|
||||
ui.width = width
|
||||
|
@ -170,7 +169,7 @@ func UiInit(width, height int) UI {
|
|||
addContainer(leftBar, chatContainer)
|
||||
|
||||
// Create the login window
|
||||
makeLoginWindow(ui.width, ui.height, root, leftBar)
|
||||
makeLoginWindow(ui.width, ui.height, root, leftBar, player)
|
||||
|
||||
// Set the position and size of the left bar
|
||||
leftBar.SetLocation(img.Rect(0, 0, int(float32(width)/3.5), height))
|
||||
|
@ -246,7 +245,7 @@ func makeStatsBars(parent *widget.TabBookTab, ui UI, face font.Face) {
|
|||
},
|
||||
),
|
||||
// Set the min, max, and current values for each progressbar
|
||||
widget.ProgressBarOpts.Values(0, player.Health, player.MaxHealth),
|
||||
widget.ProgressBarOpts.Values(0, ui.player.Health, ui.player.MaxHealth),
|
||||
)
|
||||
parent.AddChild(health)
|
||||
parent.AddChild(health_progressbar)
|
||||
|
@ -281,7 +280,7 @@ func makeStatsBars(parent *widget.TabBookTab, ui UI, face font.Face) {
|
|||
},
|
||||
),
|
||||
// Set the min, max, and current values for each progressbar
|
||||
widget.ProgressBarOpts.Values(0, int(player.Exp), int(player.NextExp)),
|
||||
widget.ProgressBarOpts.Values(0, int(ui.player.Exp), int(ui.player.NextExp)),
|
||||
)
|
||||
parent.AddChild(level)
|
||||
parent.AddChild(level_progressbar)
|
||||
|
@ -316,7 +315,7 @@ func makeStatsBars(parent *widget.TabBookTab, ui UI, face font.Face) {
|
|||
},
|
||||
),
|
||||
// Set the min, max, and current values for each progressbar
|
||||
widget.ProgressBarOpts.Values(0, int(player.Ambition), int(player.MaxAmbition)),
|
||||
widget.ProgressBarOpts.Values(0, int(ui.player.Ambition), int(ui.player.MaxAmbition)),
|
||||
)
|
||||
parent.AddChild(ambition)
|
||||
parent.AddChild(ambition_progressbar)
|
||||
|
|
Reference in a new issue