package controller /* TODO: Препроцессинг и сохранение приказов Когда приказ (последовательность команд) поступает на сервер, игрок получает уведомление о том, что его команды приняты к производству. Каждая команда из приказа проверяется на корректность и получает отдельное подтверждение. Игрок может послать любое количество приказов по своему усмотрению, однако, каждый новый приказ отменяет предыдущий. Таким образом, можно исправить неверно составленный приказ, но при этом необходимо повторить те команды, которые были отданы верно. К счастью, программа-клиент помогает игроку не запутаться в этом процессе и берёт на себя контроль за целостностью приказов. !!! Убедиться, что раса не покинула игру. При производстве хода раса может быть исключена по TTL=0. В этом случае нужно игнорировать некоторые приказы, например, передачу ей кораблей. */ import ( "strings" "github.com/google/uuid" e "github.com/iliadenisov/galaxy/internal/error" "github.com/iliadenisov/galaxy/internal/model/game" ) func (c Controller) RaceID(actor string) (uuid.UUID, error) { ri, err := c.Cache.validRace(actor) if err != nil { return uuid.Nil, err } return c.Cache.g.Race[ri].ID, nil } func (c Controller) RaceQuit(actor string) error { ri, err := c.Cache.validRace(actor) if err != nil { return err } c.Cache.g.Race[ri].TTL = 3 return nil } func (c Controller) RaceVote(actor, acceptor string) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } rec, err := c.Cache.validRace(acceptor) if err != nil { return err } c.Cache.g.Race[ri].VoteFor = c.Cache.g.Race[rec].ID return nil } func (c Controller) RaceRelation(actor, acceptor string, v string) error { rel, ok := game.ParseRelation(v) if !ok { return e.NewUnknownRelationError(v) } ri, err := c.Cache.validActor(actor) if err != nil { return err } other, err := c.Cache.validRace(acceptor) if err != nil { return err } return c.Cache.UpdateRelation(ri, other, rel) } func (c *Controller) ShipClassCreate(actor, typeName string, drive float64, ammo int, weapons, shileds, cargo float64) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } return c.Cache.ShipClassCreate(ri, typeName, drive, ammo, weapons, shileds, cargo) } func (c *Controller) ShipClassMerge(actor, name, targetName string) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } return c.Cache.shipClassMerge(ri, name, targetName) } func (c *Controller) ShipClassRemove(actor, typeName string) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } return c.Cache.shipClassRemove(ri, typeName) } func (c *Controller) ShipGroupLoad(actor string, groupID uuid.UUID, cargoType string, quantity float64) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } ct, ok := game.CargoTypeSet[strings.ToLower(cargoType)] if !ok { return e.NewCargoTypeInvalidError(cargoType) } return c.Cache.shipGroupLoad(ri, groupID, ct, quantity) } func (c *Controller) ShipGroupUnload(actor string, groupID uuid.UUID, quantity float64) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } return c.Cache.shipGroupUnload(ri, groupID, quantity) } func (c *Controller) ShipGroupSend(actor string, groupID uuid.UUID, planetNumber uint) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } return c.Cache.shipGroupSend(ri, groupID, planetNumber) } func (c *Controller) ShipGroupUpgrade(actor string, groupID uuid.UUID, techInput string, limitLevel float64) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } return c.Cache.shipGroupUpgrade(ri, groupID, techInput, limitLevel) } func (c *Controller) ShipGroupMerge(actor string) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } c.Cache.shipGroupMerge(ri) return nil } func (c *Controller) ShipGroupBreak(actor string, groupID, newID uuid.UUID, quantity uint) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } return c.Cache.ShipGroupBreak(ri, groupID, newID, quantity) } func (c *Controller) ShipGroupDismantle(actor string, groupID uuid.UUID) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } return c.Cache.shipGroupDismantle(ri, groupID) } func (c *Controller) ShipGroupTransfer(actor, acceptor string, groupID uuid.UUID) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } riAccept, err := c.Cache.validRace(acceptor) if err != nil { return err } return c.Cache.shipGroupTransfer(ri, riAccept, groupID) } func (c *Controller) ShipGroupJoinFleet(actor, fleetName string, groupID uuid.UUID) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } return c.Cache.ShipGroupJoinFleet(ri, fleetName, groupID) } func (c *Controller) FleetMerge(actor, fleetSourceName, fleetTargetName string) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } return c.Cache.fleetMerge(ri, fleetSourceName, fleetTargetName) } func (c *Controller) FleetSend(actor, fleetName string, planetNumber uint) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } fi, ok := c.Cache.fleetIndex(ri, fleetName) if !ok { return e.NewEntityNotExistsError("fleet %q", fleetName) } return c.Cache.FleetSend(ri, fi, planetNumber) } func (c *Controller) ScienceCreate(actor, typeName string, drive, weapons, shields, cargo float64) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } return c.Cache.ScienceCreate(ri, typeName, drive, weapons, shields, cargo) } func (c *Controller) ScienceRemove(actor, typeName string) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } return c.Cache.ScienceRemove(ri, typeName) } func (c *Controller) PlanetRename(actor string, planetNumber int, name string) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } return c.Cache.PlanetRename(ri, planetNumber, name) } func (c *Controller) PlanetProduce(actor string, planetNumber int, prodType, subject string) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } var prod game.ProductionType switch game.ProductionType(strings.ToUpper(prodType)) { case game.ProductionMaterial: prod = game.ProductionMaterial case game.ProductionCapital: prod = game.ProductionCapital case game.ResearchDrive: prod = game.ResearchDrive case game.ResearchWeapons: prod = game.ResearchWeapons case game.ResearchShields: prod = game.ResearchShields case game.ResearchCargo: prod = game.ResearchCargo case game.ResearchScience: prod = game.ResearchScience case game.ProductionShip: prod = game.ProductionShip default: return e.NewProductionInvalidError(prodType) } return c.Cache.PlanetProduce(ri, planetNumber, prod, subject) } func (c *Controller) PlanetRouteSet(actor, loadType string, origin, destination uint) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } rt, ok := game.RouteTypeSet[strings.ToLower(loadType)] if !ok { return e.NewCargoTypeInvalidError(loadType) } return c.Cache.PlanetRouteSet(ri, rt, origin, destination) } func (c *Controller) PlanetRouteRemove(actor, loadType string, origin uint) error { ri, err := c.Cache.validActor(actor) if err != nil { return err } rt, ok := game.RouteTypeSet[strings.ToLower(loadType)] if !ok { return e.NewCargoTypeInvalidError(loadType) } return c.Cache.PlanetRouteRemove(ri, rt, origin) }