func (api apiHelper) FetchRoom(c *gin.Context) (*g.Room, error) { roomId := c.Param("room") room := g.FetchRoom(g.RefID(uuid.FromStringOrNil(roomId))) if room == nil { return nil, errors.New("room not found") } return room, nil }
func playerIDHeaderRequired() gin.HandlerFunc { return func(c *gin.Context) { playerID := apiHelper{}.GetRequestPlayerID(c) if playerID.Equal(g.RefID(uuid.Nil)) { c.JSON(http.StatusUnauthorized, gin.H{}) c.Abort() } else { c.Next() } } }
func (api apiV1C) getPlayerLocation(c *gin.Context) { room, err := api.helpers.FetchRoom(c) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"errors": err.Error()}) return } currentPlayer := room.GetPlayer(api.helpers.GetRequestPlayerID(c)) locationPlayer := room.GetPlayer(g.RefID(uuid.FromStringOrNil(c.Param("player")))) if currentPlayer == nil || locationPlayer == nil { c.JSON(http.StatusForbidden, gin.H{"errors": "player not found"}) return } if currentPlayer.RefID() != locationPlayer.RefID() { c.JSON(http.StatusForbidden, gin.H{"errors": "incorrect player uuid"}) return } location := room.FindPlayerLocation(locationPlayer) if location == nil { c.JSON(http.StatusInternalServerError, gin.H{"errors": "location incorrect"}) return } type monsterRepresent struct { *g.RefIDObj g.PosObj SubType string `json:"subType"` Name string `json:"name"` HP int `json:"hp"` } monsters := []apiData{} for _, m := range room.Monsters().InLocation(location).Lives() { monster := monsterRepresent{ &m.RefIDObj, m.PosObj, m.Render, m.Name(), m.HP, } monsters = append(monsters, serializeToAPIData(monster)) } type placeItemRepresent struct { *g.RefIDObj g.PosObj Name string `json:"name"` } locationItems := []apiData{} for _, item := range room.PlaceItems() { if item.InLocation(location) { item := placeItemRepresent{ &item.RefIDObj, item.PosObj, item.String(), } locationItems = append(locationItems, serializeToAPIData(item)) } } type weaponRepresent struct { RefID uuid.UUID `json:"id"` Name string `json:"name"` Description string `json:"description"` } rightHandWeapons := make([]weaponRepresent, 0) var rightHandWeapon weaponRepresent { weapon := locationPlayer.CurrentWeapon() rightHandWeapon = weaponRepresent{uuid.UUID(weapon.RefID()), weapon.Name, weaponDescription(&weapon)} } for _, weapon := range locationPlayer.GetWeapons() { rightHandWeapons = append(rightHandWeapons, weaponRepresent{uuid.UUID(weapon.RefID()), weapon.Name, weaponDescription(weapon)}) } type inventoryRepresent struct { RefID uuid.UUID `json:"id"` Name string `json:"name"` Description string `json:"description"` } inventoryItems := make([]inventoryRepresent, 0) for _, item := range locationPlayer.GetItems() { inventoryItems = append(inventoryItems, inventoryRepresent{uuid.UUID(item.RefID()), item.Name, item.Description}) } playerRepresent := struct { *g.RefIDObj g.PosObj HP int `json:"hitPoints"` MP int `json:"manaPoints"` Inventory []inventoryRepresent `json:"inventory"` Weapons []weaponRepresent `json:"weapons"` RightHand weaponRepresent `json:"rightHand"` Steps int `json:"steps"` }{ &locationPlayer.RefIDObj, locationPlayer.PosObj, locationPlayer.HP, locationPlayer.MP, inventoryItems, rightHandWeapons, rightHandWeapon, locationPlayer.Steps(), } response := gin.H{ "location": serializeToAPIData(location), "monsters": monsters, "player": serializeToAPIData(playerRepresent), "items": locationItems, "statusPanel": gin.H{"letter": "Lasciate ogni speranza, voi ch'entrate"}, "finished": room.IsFinished(), } c.JSON(http.StatusOK, response) }
func (api apiHelper) GetRequestPlayerID(c *gin.Context) g.RefID { playerID := c.Request.Header.Get(HeaderPlayerID) return g.RefID(uuid.FromStringOrNil(playerID)) }
func (api apiV1C) playerCommands(c *gin.Context) { room, err := api.helpers.FetchRoom(c) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"errors": err.Error()}) return } player := room.GetPlayer(api.helpers.GetRequestPlayerID(c)) if player == nil { c.JSON(http.StatusForbidden, gin.H{"errors": "player not found"}) return } location := room.FindPlayerLocation(player) if location == nil { c.JSON(http.StatusInternalServerError, gin.H{"errors": "location incorrect"}) return } if room.IsFinished() { c.JSON(http.StatusBadRequest, gin.H{"errors": "game finished"}) return } var action apiPlayerCommands if err := c.BindJSON(&action); err != nil { c.JSON(http.StatusBadRequest, gin.H{"errors": err.Error()}) return } if !player.IsLive() { c.JSON(http.StatusBadRequest, gin.H{"errors": "player is dead"}) return } if len(action.Commands) == 0 { c.JSON(http.StatusBadRequest, gin.H{"errors": "commands empty"}) return } result := make([]string, 0) command := action.Commands[0] switch command["type"] { case "move": if direct, ok := availableDirects[command["direct"]]; !ok { c.JSON(http.StatusBadRequest, gin.H{"errors": "unknown command"}) return } else { player.ResetStats() for idx := range player.SideEffects { player.SideEffects[idx].Exec(player, &player.SideEffects[idx]) result = append(result, "Применен эффект: "+player.SideEffects[idx].Name()) } player.PackSideEffects() result = append(result, movement.MovePlayer(room, location, player, direct)...) } case "change-right-hand": weaponID, err := uuid.FromString(command["weaponID"]) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"errors": "invalid weaponID"}) return } weapon := player.GetWeapon(g.RefID(weaponID)) if weapon == nil { c.JSON(http.StatusBadRequest, gin.H{"errors": "invalid weaponID"}) return } if err := player.ChangeRightHandWeapon(weapon.RefID()); err != nil { c.JSON(http.StatusBadRequest, gin.H{"errors": err}) return } result = append(result, "Смена оружия: "+weapon.Name) case "use-item": itemID, err := uuid.FromString(command["itemID"]) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"errors": "invalid itemID"}) return } item := player.GetItem(g.RefID(itemID)) if item.Usable { result = append(result, g.PlayerUseItem(player, item)...) } default: c.JSON(http.StatusBadRequest, gin.H{"errors": "unknown command"}) return } if room.IsFinished() { c.JSON(http.StatusCreated, gin.H{"result": result}) return } for idx, placeItem := range room.PlaceItems() { if player.PosEqual(placeItem.PosObj) { player.AddToInventory(placeItem.Item) room.SetNullItem(idx) if item, ok := placeItem.Item.(fmt.Stringer); ok { result = append(result, "Подобран предмет: "+item.String()) } else { result = append(result, "Подобран предмет...") } } } for _, monster := range room.Monsters().InLocation(room.FindPlayerLocation(player)).Lives() { result = append(result, npc.MoveToPlayer(room, location, monster, player)...) } c.JSON(http.StatusCreated, gin.H{"result": result}) }