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/player v0.0.0-00010101000000-000000000000
|
||||||
github.com/devraza/ambition/frontend/ui 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/hajimehoshi/ebiten/v2 v2.5.5
|
||||||
|
github.com/joho/godotenv v1.5.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
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/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 h1:wnpxJzP1+rkbGclEkmwpVFQWpuE2PUGNUzP8SbfFobk=
|
||||||
github.com/jezek/xgb v1.1.0/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
|
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/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||||
|
|
|
@ -11,12 +11,9 @@ import (
|
||||||
|
|
||||||
// Ebitengine
|
// Ebitengine
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
"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
|
// Create the `Game` struct
|
||||||
type Game struct {
|
type Game struct {
|
||||||
ui u.UI
|
ui u.UI
|
||||||
|
@ -40,6 +37,7 @@ func (g *Game) Update() error {
|
||||||
func (g *Game) Draw(screen *ebiten.Image) {
|
func (g *Game) Draw(screen *ebiten.Image) {
|
||||||
// Draw the UI onto the screen
|
// Draw the UI onto the screen
|
||||||
g.ui.Base.Draw(screen)
|
g.ui.Base.Draw(screen)
|
||||||
|
ebitenutil.DebugPrint(screen, g.activePlayer.JwtToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Layout implements Game
|
// Layout implements Game
|
||||||
|
@ -64,11 +62,9 @@ func main() {
|
||||||
ebiten.SetWindowTitle(window_title)
|
ebiten.SetWindowTitle(window_title)
|
||||||
|
|
||||||
// Initialise the game
|
// Initialise the game
|
||||||
game := Game{
|
game := Game{}
|
||||||
// Initialise the UI
|
game.activePlayer = p.NewPlayer()
|
||||||
activePlayer: testPlayer,
|
game.ui = u.UiInit(window_width, window_height, &game.activePlayer)
|
||||||
ui: u.UiInit(window_width, window_height),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log and exit on error
|
// Log and exit on error
|
||||||
if err := ebiten.RunGame(&game); err != nil {
|
if err := ebiten.RunGame(&game); err != nil {
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
package player
|
package player
|
||||||
|
|
||||||
import ()
|
import (
|
||||||
|
s "github.com/devraza/ambition/frontend/server"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
// The player struct
|
// The player struct
|
||||||
type Player struct {
|
type Player struct {
|
||||||
|
JwtToken string
|
||||||
Health int
|
Health int
|
||||||
MaxHealth int
|
MaxHealth int
|
||||||
Defence int
|
Defence int
|
||||||
|
@ -18,20 +22,40 @@ type Player struct {
|
||||||
var level_gates = make(map[int]float32)
|
var level_gates = make(map[int]float32)
|
||||||
var level_ambition = make(map[int]float32)
|
var level_ambition = make(map[int]float32)
|
||||||
|
|
||||||
// TODO(midnadimple): Move player initialization to server upon login
|
func NewPlayer() Player {
|
||||||
func GetPlayer() Player {
|
|
||||||
return Player{
|
return Player{
|
||||||
Health: 100,
|
JwtToken: "",
|
||||||
MaxHealth: 100,
|
Health: 0,
|
||||||
|
MaxHealth: 0,
|
||||||
Defence: 0,
|
Defence: 0,
|
||||||
Level: 1,
|
Level: 0,
|
||||||
Exp: 0.0,
|
Exp: 0.0,
|
||||||
NextExp: 0.0,
|
NextExp: 0.0,
|
||||||
Ambition: 0.0, // NOTE(midnadimple): In the future this will be affected by player activity
|
Ambition: 0.0,
|
||||||
MaxAmbition: level_ambition[1], // NOTE(midnadimple): In the future this will be affected by player activity
|
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
|
// Formula for XP gain - extremely simple
|
||||||
func gain(basexp float32, modifier float32) float32 {
|
func gain(basexp float32, modifier float32) float32 {
|
||||||
gain := basexp * modifier
|
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
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// Misc.
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
// Image
|
// Image
|
||||||
img "image"
|
img "image"
|
||||||
|
|
||||||
// Ambition
|
// Ambition
|
||||||
// p "github.com/devraza/ambition/frontend/player"
|
p "github.com/devraza/ambition/frontend/player"
|
||||||
|
|
||||||
// EbitenUI
|
// EbitenUI
|
||||||
"github.com/ebitenui/ebitenui/image"
|
"github.com/ebitenui/ebitenui/image"
|
||||||
"github.com/ebitenui/ebitenui/widget"
|
"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
|
// Define the contents of the login window
|
||||||
loginContainer := widget.NewContainer(
|
loginContainer := widget.NewContainer(
|
||||||
widget.ContainerOpts.BackgroundImage(image.NewNineSliceColor(ui.colors["gray"])),
|
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.CaretOpts.Size(defaultFace, 2),
|
||||||
),
|
),
|
||||||
widget.TextInputOpts.Placeholder("Username"),
|
widget.TextInputOpts.Placeholder("Username"),
|
||||||
widget.TextInputOpts.SubmitHandler(func(args *widget.TextInputChangedEventArgs) {
|
|
||||||
fmt.Println("Text Submitted: ", args.InputText)
|
|
||||||
}),
|
|
||||||
)
|
)
|
||||||
passwordInput := widget.NewTextInput(
|
passwordInput := widget.NewTextInput(
|
||||||
widget.TextInputOpts.WidgetOpts(
|
widget.TextInputOpts.WidgetOpts(
|
||||||
|
@ -91,9 +85,6 @@ func makeLoginWindow(width, height int, root *widget.Container, shown *widget.Co
|
||||||
widget.TextInputOpts.Secure(true),
|
widget.TextInputOpts.Secure(true),
|
||||||
|
|
||||||
widget.TextInputOpts.Placeholder("Password"),
|
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
|
// Add the text inputs to the login window
|
||||||
loginContainer.AddChild(usernameInput)
|
loginContainer.AddChild(usernameInput)
|
||||||
|
@ -130,6 +121,7 @@ func makeLoginWindow(width, height int, root *widget.Container, shown *widget.Co
|
||||||
}),
|
}),
|
||||||
// Button on-click handler
|
// Button on-click handler
|
||||||
widget.ButtonOpts.ClickedHandler(func(args *widget.ButtonClickedEventArgs) {
|
widget.ButtonOpts.ClickedHandler(func(args *widget.ButtonClickedEventArgs) {
|
||||||
|
player.Init(usernameInput.InputText, passwordInput.InputText)
|
||||||
removeContainer(root, loginContainer)
|
removeContainer(root, loginContainer)
|
||||||
addContainer(root, shown)
|
addContainer(root, shown)
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -22,14 +22,12 @@ import (
|
||||||
// The UI struct
|
// The UI struct
|
||||||
type UI struct {
|
type UI struct {
|
||||||
Base ebitenui.UI
|
Base ebitenui.UI
|
||||||
|
player *p.Player
|
||||||
colors map[string]color.RGBA
|
colors map[string]color.RGBA
|
||||||
width, height int
|
width, height int
|
||||||
textInput *widget.TextInput
|
textInput *widget.TextInput
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the player from the `player` package
|
|
||||||
var player = p.GetPlayer()
|
|
||||||
|
|
||||||
// The `hazakura` colorscheme (default)
|
// The `hazakura` colorscheme (default)
|
||||||
var hazakura = map[string]color.RGBA{
|
var hazakura = map[string]color.RGBA{
|
||||||
// The monotone colors
|
// The monotone colors
|
||||||
|
@ -62,9 +60,10 @@ var defaultFace, _ = makeFace(14, fonts.FiraRegular_ttf)
|
||||||
var buttonImage, _ = loadButtonImage()
|
var buttonImage, _ = loadButtonImage()
|
||||||
|
|
||||||
// Function for UI initialization
|
// Function for UI initialization
|
||||||
func UiInit(width, height int) UI {
|
func UiInit(width, height int, player *p.Player) UI {
|
||||||
// Define the UI colors
|
// Define the UI colors
|
||||||
ui.colors = hazakura
|
ui.colors = hazakura
|
||||||
|
ui.player = player
|
||||||
|
|
||||||
// Get the window width/height
|
// Get the window width/height
|
||||||
ui.width = width
|
ui.width = width
|
||||||
|
@ -170,7 +169,7 @@ func UiInit(width, height int) UI {
|
||||||
addContainer(leftBar, chatContainer)
|
addContainer(leftBar, chatContainer)
|
||||||
|
|
||||||
// Create the login window
|
// 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
|
// Set the position and size of the left bar
|
||||||
leftBar.SetLocation(img.Rect(0, 0, int(float32(width)/3.5), height))
|
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
|
// 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)
|
||||||
parent.AddChild(health_progressbar)
|
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
|
// 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)
|
||||||
parent.AddChild(level_progressbar)
|
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
|
// 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)
|
||||||
parent.AddChild(ambition_progressbar)
|
parent.AddChild(ambition_progressbar)
|
||||||
|
|
Reference in a new issue