From c38f7762f4be118cdb31e4583a5aa0b1e74a8b6c Mon Sep 17 00:00:00 2001 From: arnaucube Date: Fri, 14 Jun 2019 23:29:16 +0200 Subject: [PATCH] add UpgradeBuilding functionallity --- cmd/server.go | 2 +- constants/constants.go | 29 ++++++++++++++++++++ endpoint/handlers.go | 53 +++++++++++++++++++++++++++++++++++-- endpoint/serve.go | 7 ++++- models/planet.go | 7 ++--- models/user.go | 46 +++++++++++++++++++++++++++++--- services/gamesrv/gamesrv.go | 36 ++++++++++++++++++++----- services/usersrv/usersrv.go | 13 +++++++-- test/test.py | 32 +++++++++++++++++++++- 9 files changed, 205 insertions(+), 20 deletions(-) diff --git a/cmd/server.go b/cmd/server.go index aec3d64..2f80eb5 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -35,7 +35,7 @@ func start(c *cli.Context) error { return err } - apiService := endpoint.Serve(config.C, db, userservice) + apiService := endpoint.Serve(config.C, db, userservice, gameservice) apiService.Run(config.C.Server.ServiceApi) return nil diff --git a/constants/constants.go b/constants/constants.go index ef934f6..fa64582 100644 --- a/constants/constants.go +++ b/constants/constants.go @@ -1,5 +1,9 @@ package constants +import ( + "github.com/arnaucube/gogame/models" +) + // game constants const GALAXYSIZE = 50 @@ -31,3 +35,28 @@ var EnergyMineLevels = []int64{ 5, 10, } + +// BuildingsNeededResources hold +// map with all the buildings, that each one is a map with the levels of the buildings with the needed ressources +var BuildingsNeededResources = map[string]map[int64]models.Resources{ + "metalplant": map[int64]models.Resources{ + 1: models.Resources{ + Metal: 50, + Crystal: 50, + Deuterium: 50, + Energy: 50, + }, + 2: models.Resources{ + Metal: 70, + Crystal: 70, + Deuterium: 70, + Energy: 70, + }, + 3: models.Resources{ + Metal: 90, + Crystal: 90, + Deuterium: 90, + Energy: 90, + }, + }, +} diff --git a/endpoint/handlers.go b/endpoint/handlers.go index d1dd5c8..d7828c0 100644 --- a/endpoint/handlers.go +++ b/endpoint/handlers.go @@ -1,8 +1,11 @@ package endpoint import ( + "fmt" + "github.com/fatih/color" "github.com/gin-gonic/gin" + "gopkg.in/mgo.v2/bson" ) func fail(c *gin.Context, err error, msg string) { @@ -64,14 +67,14 @@ func handleLogin(c *gin.Context) { func handleGetResources(c *gin.Context) { userid := c.Param("userid") - user, err := userservice.GetUserById(userid) + user, err := userservice.GetUserById(bson.ObjectIdHex(userid)) if err != nil { fail(c, err, "error on getting user") return } resources, err := user.GetResources() if err != nil { - fail(c, err, "error on getting user") + fail(c, err, "error on getting user resources") return } @@ -80,3 +83,49 @@ func handleGetResources(c *gin.Context) { "resources": resources, }) } + +func handleGetUserPlanets(c *gin.Context) { + userid := c.Param("userid") + + planets, err := userservice.GetUserPlanetsById(bson.ObjectIdHex(userid)) + if err != nil { + fail(c, err, "error on getting user planets") + return + } + + c.JSON(200, gin.H{ + "planets": planets, + }) +} + +type BuildMsg struct { + PlanetId string + Building string +} + +func handlePostUpgradeBuilding(c *gin.Context) { + userid := c.Param("userid") + var buildMsg BuildMsg + err := c.BindJSON(&buildMsg) + if err != nil { + fail(c, err, "error parsing json") + return + } + fmt.Println(buildMsg) + + user, err := userservice.GetUserById(bson.ObjectIdHex(userid)) + if err != nil { + fail(c, err, "error on getting user") + return + } + + planet, err := gameservice.UpgradeBuilding(user, bson.ObjectIdHex(buildMsg.PlanetId), buildMsg.Building) + if err != nil { + fail(c, err, "error upgrading building") + return + } + + c.JSON(200, gin.H{ + "planet": planet, + }) +} diff --git a/endpoint/serve.go b/endpoint/serve.go index 8d791f7..6e5350f 100644 --- a/endpoint/serve.go +++ b/endpoint/serve.go @@ -3,6 +3,7 @@ package endpoint import ( "github.com/arnaucube/gogame/config" "github.com/arnaucube/gogame/database" + "github.com/arnaucube/gogame/services/gamesrv" "github.com/arnaucube/gogame/services/usersrv" "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" @@ -11,6 +12,7 @@ import ( var serverConfig config.Config var db *database.Db var userservice *usersrv.Service +var gameservice *gamesrv.Service func newApiService() *gin.Engine { api := gin.Default() @@ -22,12 +24,15 @@ func newApiService() *gin.Engine { // TODO add jwt checker api.GET("/resources/:userid", handleGetResources) + api.GET("/planets/:userid", handleGetUserPlanets) + api.POST("/buildings/:userid", handlePostUpgradeBuilding) return api } -func Serve(cnfg config.Config, _db *database.Db, _userservice *usersrv.Service) *gin.Engine { +func Serve(cnfg config.Config, _db *database.Db, _userservice *usersrv.Service, _gameservice *gamesrv.Service) *gin.Engine { serverConfig = cnfg db = _db userservice = _userservice + gameservice = _gameservice return newApiService() } diff --git a/models/planet.go b/models/planet.go index 1d3afcf..5683e68 100644 --- a/models/planet.go +++ b/models/planet.go @@ -2,7 +2,8 @@ package models import "gopkg.in/mgo.v2/bson" -type BuildingsList struct { +/* +BuildingsList MetalMine int64 CrystalMine int64 DeuteriumMine int64 @@ -11,11 +12,11 @@ type BuildingsList struct { RoboticsFactory int64 Shipyard int64 RessearchLab int64 -} +*/ type Planet struct { Id bson.ObjectId `json:"id" bson:"_id,omitempty"` Size int64 // fields/slots Name string OwnerId bson.ObjectId - Buildings BuildingsList + Buildings map[string]int64 } diff --git a/models/user.go b/models/user.go index be57a20..8cd5a11 100644 --- a/models/user.go +++ b/models/user.go @@ -1,6 +1,7 @@ package models import ( + "errors" "fmt" "time" @@ -42,6 +43,12 @@ func NewUser(db *database.Db, name, password, email string) (*User, error) { Password: password, Email: email, LastUpdated: time.Now(), + Resources: Resources{ + Metal: 500, + Crystal: 500, + Deuterium: 500, + Energy: 500, + }, } err := db.Users.Insert(newUser) if err != nil { @@ -117,10 +124,10 @@ func (u *User) GetResources() (*Resources, error) { for _, planet := range planets { fmt.Println("planet", planet) // TODO find correct formulas - metalGrowth = metalGrowth + ((1 + planet.Buildings.MetalMine) * int64(delta)) - crystalGrowth = crystalGrowth + ((1 * planet.Buildings.CrystalMine) * int64(delta)) - deuteriumGrowth = deuteriumGrowth + ((1 * planet.Buildings.DeuteriumMine) * int64(delta)) - energyGrowth = energyGrowth + ((1 * planet.Buildings.EnergyMine) * int64(delta)) + metalGrowth = metalGrowth + ((1 + planet.Buildings["metalmine"]) * int64(delta)) + crystalGrowth = crystalGrowth + ((1 + planet.Buildings["crystalmine"]) * int64(delta)) + deuteriumGrowth = deuteriumGrowth + ((1 + planet.Buildings["deuteriummine"]) * int64(delta)) + energyGrowth = energyGrowth + ((1 + planet.Buildings["energymine"]) * int64(delta)) } // calculate newAmount = oldAmount + growth u.Resources.Metal = u.Resources.Metal + metalGrowth @@ -137,3 +144,34 @@ func (u *User) GetResources() (*Resources, error) { // return user return &u.Resources, nil } + +// SpendResources checks if user has enough resources, then substracts the resources, and updates the amounts in the database +func (u *User) SpendResources(r Resources) error { + err := u.GetFromDb() + if err != nil { + return err + } + if u.Resources.Metal < r.Metal { + return errors.New("not enough metal resources") + } + if u.Resources.Crystal < r.Crystal { + return errors.New("not enough crystal resources") + } + if u.Resources.Deuterium < r.Deuterium { + return errors.New("not enough deuterium resources") + } + if u.Resources.Energy < r.Energy { + return errors.New("not enough energy resources") + } + + u.Resources.Metal = u.Resources.Metal - r.Metal + u.Resources.Crystal = u.Resources.Crystal - r.Crystal + u.Resources.Deuterium = u.Resources.Deuterium - r.Deuterium + u.Resources.Energy = u.Resources.Energy - r.Energy + + err = u.StoreInDb() + if err != nil { + return err + } + return nil +} diff --git a/services/gamesrv/gamesrv.go b/services/gamesrv/gamesrv.go index 554f1c7..598b5bb 100644 --- a/services/gamesrv/gamesrv.go +++ b/services/gamesrv/gamesrv.go @@ -29,13 +29,14 @@ func (srv Service) CreatePlanet(userId bson.ObjectId) (*models.SolarSystem, *mod Size: size, Name: name, OwnerId: userId, - Buildings: models.BuildingsList{ - MetalMine: 1, - CrystalMine: 1, - DeuteriumMine: 1, - EnergyMine: 1, - }, } + // in case that wants to start with resources plants + // newPlanet.Buildings = make(map[string]int64) + // newPlanet.Buildings["metalplant"] = 1 + // newPlanet.Buildings["crystalplant"] = 1 + // newPlanet.Buildings["deuteriumplant"] = 1 + // newPlanet.Buildings["energyplant"] = 1 + err := srv.db.Planets.Insert(newPlanet) if err != nil { return nil, nil, err @@ -90,3 +91,26 @@ func (srv Service) PutPlanetInSolarSystem(position int64, planet *models.Planet) return &solarSystem, err } + +func (srv Service) UpgradeBuilding(user *models.User, planetid bson.ObjectId, building string) (*models.Planet, error) { + // get planet + var planet models.Planet + err := srv.db.Planets.Find(bson.M{"_id": planetid}).One(&planet) + if err != nil { + return nil, err + } + + // get current building level, and get the needed resources for next level + resourcesNeeded := constants.BuildingsNeededResources[building][planet.Buildings[building]+1] + + // if user have enough resources to upgrade the building, upgrade the building + err = user.SpendResources(resourcesNeeded) + if err != nil { + return nil, err + } + // upgrade level of building in planet + planet.Buildings[building] += 1 + // store planet in db + err = srv.db.Planets.Update(bson.M{"_id": planet.Id}, planet) + return &planet, nil +} diff --git a/services/usersrv/usersrv.go b/services/usersrv/usersrv.go index 9805d7a..f2ad783 100644 --- a/services/usersrv/usersrv.go +++ b/services/usersrv/usersrv.go @@ -82,15 +82,24 @@ func (srv Service) Login(email, password string) (*string, *models.User, error) return &tokenString, user, err } -func (srv Service) GetUserById(userid string) (*models.User, error) { +func (srv Service) GetUserById(userid bson.ObjectId) (*models.User, error) { var userDb models.UserDb - err := srv.db.Users.Find(bson.M{"_id": bson.ObjectIdHex(userid)}).One(&userDb) + err := srv.db.Users.Find(bson.M{"_id": userid}).One(&userDb) if err != nil { return nil, err } return models.UserDbToUser(srv.db, userDb), nil } +func (srv Service) GetUserPlanetsById(userid bson.ObjectId) ([]*models.Planet, error) { + var planets []*models.Planet + err := srv.db.Planets.Find(bson.M{"ownerid": userid}).All(&planets) + if err != nil { + return nil, err + } + return planets, err +} + // func (srv Service) GetUser(id bson.ObjectId) (*models.User, error) { // // update user stats // user := getUserFromDB diff --git a/test/test.py b/test/test.py index 39e4d7d..770a5bf 100644 --- a/test/test.py +++ b/test/test.py @@ -41,11 +41,41 @@ t.rStatus("get /resources", r) jsonR = r.json() print(jsonR) -time.sleep(4) +time.sleep(1) r = requests.get(URL + "/resources/"+ userid) t.rStatus("get /resources", r) jsonR = r.json() print(jsonR) +r = requests.get(URL + "/resources/"+ userid) +t.rStatus("get /resources", r) +jsonR = r.json() +print(jsonR) + +r = requests.get(URL + "/planets/"+userid) +t.rStatus("post /planets/:userid", r) +jsonR = r.json() +print(jsonR) +print(jsonR["planets"][0]) +planetid = jsonR["planets"][0]["id"] + +d = { + "planetid": planetid, + "building": "metalplant", +} +r = requests.post(URL + "/buildings/"+userid, json=d) +t.rStatus("post /building/:userid", r) +jsonR = r.json() +print(jsonR) + +d = { + "planetid": planetid, + "building": "ressearchlab", +} +r = requests.post(URL + "/buildings/"+userid, json=d) +t.rStatus("post /building/:userid", r) +jsonR = r.json() +print(jsonR) + t.printScores()