diff options
Diffstat (limited to 'jws/epibazaar/item-producer/src/main')
25 files changed, 1273 insertions, 0 deletions
diff --git a/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/converter/ItemProducerConverter.java b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/converter/ItemProducerConverter.java new file mode 100644 index 0000000..cb81247 --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/converter/ItemProducerConverter.java @@ -0,0 +1,126 @@ +package fr.epita.assistants.item_producer.converter; + +import fr.epita.assistants.common.aggregate.ItemAggregate; +import fr.epita.assistants.common.aggregate.ResetInventoryAggregate; +import fr.epita.assistants.common.api.request.StartRequest; +import fr.epita.assistants.common.api.response.*; +import fr.epita.assistants.item_producer.data.model.PlayerModel; +import fr.epita.assistants.item_producer.domain.entity.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ItemProducerConverter { + public static StartEntity Start(StartRequest r) { + if (r.getMapPath() == null || r.getMapPath().isEmpty()) + return null; + return new StartEntity(r.getMapPath(), null); + } + + public static Map<ItemAggregate.ResourceType, Float> DeleteItems(ResetInventoryAggregate items) { + Map<ItemAggregate.ResourceType, Float> map = new HashMap<>(); + for (ItemAggregate i : items.getItems()) { + map.merge(i.getType(), i.getQuantity(), Float::sum); + } + return map; + } + + public static MoveEntity Move(PlayerModel playerMove) { + return new MoveEntity(playerMove.getPosX(), playerMove.getPosY()); + } + + public static List<List<String>> RLEtoMap(String rle) { + List<String> lines = List.of(rle.split(";")); + List<List<String>> map = new ArrayList<>(); + for (int k = 0; k < lines.size(); k++) { + map.add(new ArrayList<>()); + for (int i = 0; i < lines.get(k).length(); i++) { + for (int j = 0; j < lines.get(k).charAt(i) - '0'; j++) { + String type = ItemAggregate.ResourceType.getResource(lines.get(k).charAt(i + 1)).toString(); + map.get(k).add(type); + } + i++; + } + } + return map; + } + + public static String MapToRLE(List<List<String>> map) { + List<String> rows = new ArrayList<>(); + for (List<String> resourceRow : map) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < resourceRow.size(); i++) { + int j; + // count sequence of this resource type + String s = resourceRow.get(i); + for (j = i; j < resourceRow.size() && s.equals(resourceRow.get(j)); j++) { + continue; + } + int tmp = j; + j -= i; + i = tmp - 1; + while (j > 9) { + sb.append('9'); + sb.append(ItemAggregate.ResourceType.valueOf(s).getItemInfo().getValue()); + j -= 9; + } + if (j > 0) { + sb.append(j); + sb.append(ItemAggregate.ResourceType.valueOf(s).getItemInfo().getValue()); + } + } + rows.add(sb.toString()); + } + return String.join(";", rows); + } + + public static StartEntity Collect(String resource) { + List<List<String>> map = new ArrayList<>(); + map.add(new ArrayList<>()); + map.getFirst().add(resource); + return new StartEntity(null, MapToRLE(map)); + } + + public static PlayerEntity ResponseToEntity(PlayerResponse r) { + return new PlayerEntity(r.getPosX(), r.getPosY(), r.getLastMove(), r.getLastCollect(), + r.getMoveSpeedMultiplier(), r.getStaminaMultiplier(), r.getCollectRateMultiplier()); + } + + public static StartEntity ResponseToEntity(StartResponse r) { + return new StartEntity(null, MapToRLE(r.getMap())); + } + + public static StartResponse EntityToResponse(StartEntity e) { + if (e == null) + return null; + return new StartResponse(RLEtoMap(e.getRle())); + } + public static ItemResponse EntityToResponse(ItemEntity e) { + return new ItemResponse(e.getId(), e.getQuantity(), e.getType()); + } + + public static ItemsResponse EntityToResponse(ItemsEntity e) { + if (e == null) + return null; + return new ItemsResponse(e.getItems().stream().map(ItemProducerConverter::EntityToResponse).toList()); + } + + public static PlayerResponse EntityToResponse(PlayerEntity e) { + if (e == null) + return null; + return new PlayerResponse(e.getPosX(), e.getPosY(), e.getLastMove(), e.getLastCollect(), + e.getMoveSpeedMultiplier(), e.getStaminaMultiplier(), e.getCollectRateMultiplier()); + } + + public static MoveResponse EntityToResponse(MoveEntity e) { + if (e == null) + return null; + return new MoveResponse(e.getPosX(), e.getPosY()); + } + + public static UpgradeCostResponse EntityToResponse(UpgradeCostEntity e) { + return null; + } +} diff --git a/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/data/model/GameModel.java b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/data/model/GameModel.java new file mode 100644 index 0000000..7cca88c --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/data/model/GameModel.java @@ -0,0 +1,19 @@ +package fr.epita.assistants.item_producer.data.model; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +@Entity +@Setter +@Table(name = "game") +public class GameModel { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + Long id; + String map; +} diff --git a/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/data/model/ItemModel.java b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/data/model/ItemModel.java new file mode 100644 index 0000000..68d765a --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/data/model/ItemModel.java @@ -0,0 +1,28 @@ +package fr.epita.assistants.item_producer.data.model; + +import fr.epita.assistants.common.aggregate.ItemAggregate; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +@Entity +@Setter +@Table(name = "item") +public class ItemModel { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + Long id; + @Enumerated(value = EnumType.STRING) + ItemAggregate.ResourceType type; + Float quantity; + + public ItemModel(float quantity, ItemAggregate.ResourceType type) { + this.quantity = quantity; + this.type = type; + } +} diff --git a/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/data/model/PlayerModel.java b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/data/model/PlayerModel.java new file mode 100644 index 0000000..943b5a3 --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/data/model/PlayerModel.java @@ -0,0 +1,37 @@ +package fr.epita.assistants.item_producer.data.model; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.time.LocalDateTime; + +@Getter +@Setter +@Entity +@AllArgsConstructor +@NoArgsConstructor +@Table(name = "player") +public class PlayerModel { + Float collectRateMultiplier; + Float moveSpeedMultiplier; + Integer posX; + Integer posY; + Float staminaMultiplier; + LocalDateTime lastCollect; + LocalDateTime lastMove; + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + Long id; + + public PlayerModel(float collectRateMultiplier, float moveSpeedMultiplier, int posX, int posY, float staminaMultiplier, LocalDateTime lastCollect, LocalDateTime lastMove) { + this.collectRateMultiplier = collectRateMultiplier; + this.moveSpeedMultiplier = moveSpeedMultiplier; + this.posX = posX; + this.posY = posY; + this.staminaMultiplier = staminaMultiplier; + this.lastCollect = lastCollect; + this.lastMove = lastMove; + } +} diff --git a/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/data/repository/GameRepository.java b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/data/repository/GameRepository.java new file mode 100644 index 0000000..e48f844 --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/data/repository/GameRepository.java @@ -0,0 +1,59 @@ +package fr.epita.assistants.item_producer.data.repository; + +import fr.epita.assistants.common.aggregate.ItemAggregate; +import fr.epita.assistants.item_producer.converter.ItemProducerConverter; +import fr.epita.assistants.item_producer.data.model.GameModel; +import io.quarkus.hibernate.orm.panache.PanacheRepository; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.transaction.Transactional; + +import java.util.List; + +@ApplicationScoped +public class GameRepository implements PanacheRepository<GameModel> { + @Transactional + public String getMap() { + return getGame().getMap(); + } + + private GameModel getGame() { + return findAll().firstResult(); + } + + @Transactional + public boolean isEmpty() { + return count() == 0; + } + + @Transactional + public void clearDB() { + deleteAll(); + } + + @Transactional + public void addEntry(String rle) { + GameModel game = new GameModel(); + game.setMap(rle); + persist(game); + } + + @Transactional + public boolean isValidCollect(int x, int y) { + List<List<String>> map = ItemProducerConverter.RLEtoMap(getMap()); + return ItemAggregate.ResourceType.valueOf(map.get(y).get(x)).getItemInfo().isCollectable(); + } + + @Transactional + public void setToGround(int x, int y) { + List<List<String>> map = ItemProducerConverter.RLEtoMap(getMap()); + map.get(y).set(x, ItemAggregate.ResourceType.GROUND.toString()); + String rle = ItemProducerConverter.MapToRLE(map); + update("map = ?1 where id = ?2", rle, getGame().getId()); + } + + @Transactional + public String collectResource(int posX, int posY) { + List<List<String>> map = ItemProducerConverter.RLEtoMap(getMap()); + return map.get(posY).get(posX); + } +} diff --git a/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/data/repository/ItemRepository.java b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/data/repository/ItemRepository.java new file mode 100644 index 0000000..b46311f --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/data/repository/ItemRepository.java @@ -0,0 +1,50 @@ +package fr.epita.assistants.item_producer.data.repository; + +import fr.epita.assistants.common.aggregate.ItemAggregate; +import fr.epita.assistants.item_producer.data.model.ItemModel; +import io.quarkus.hibernate.orm.panache.PanacheRepository; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.transaction.Transactional; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +@ApplicationScoped +public class ItemRepository implements PanacheRepository<ItemModel> { + @Transactional + public void deleteItems(Map<ItemAggregate.ResourceType, Float> toDelete) { + for (ItemAggregate.ResourceType type : toDelete.keySet()) { + ItemModel item = find("type = ?1", type).firstResult(); + if (item != null) + update("quantity = ?1 where type = ?2", item.getQuantity() - toDelete.get(type), type); + } + } + + @Transactional + public List<ItemModel> getItems() { + return find("where quantity > 0").stream().toList(); + } + + @Transactional + public Optional<ItemModel> exists(ItemAggregate.ResourceType type) { + return find("type = ?1", type).firstResultOptional(); + } + + @Transactional + public void addItem(ItemAggregate.ResourceType type, Float amount) { + ItemModel res = new ItemModel(amount, type); + persist(res); + } + + // amount should already be the updated amount + @Transactional + public void fillInventory(ItemAggregate.ResourceType type, Float amount) { + update("quantity = ?1 where type = ?2", amount, type); + } + + @Transactional + public List<ItemModel> getMoney() { + return find("where type = ?1", ItemAggregate.ResourceType.MONEY).stream().toList(); + } +} diff --git a/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/data/repository/PlayerRepository.java b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/data/repository/PlayerRepository.java new file mode 100644 index 0000000..b5bcde7 --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/data/repository/PlayerRepository.java @@ -0,0 +1,62 @@ +package fr.epita.assistants.item_producer.data.repository; + +import fr.epita.assistants.common.aggregate.ItemAggregate; +import fr.epita.assistants.common.utils.Direction; +import fr.epita.assistants.item_producer.converter.ItemProducerConverter; +import fr.epita.assistants.item_producer.data.model.PlayerModel; +import io.quarkus.hibernate.orm.panache.PanacheRepository; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.transaction.Transactional; + +import java.time.LocalDateTime; +import java.util.List; + +@ApplicationScoped +public class PlayerRepository implements PanacheRepository<PlayerModel> { + @Transactional + public void clearDB() { + deleteAll(); + } + + @Transactional + public void addEntry() { + PlayerModel player = new PlayerModel(1, 1, 0, 0, 1, null, null); + persist(player); + } + + @Transactional + public PlayerModel getFirstPlayer() { + return findAll().firstResult(); + } + + @Transactional + public boolean isValidMove(Direction direction, String rle) { + PlayerModel playerModel = getFirstPlayer(); + int x = playerModel.getPosX() + direction.getPoint().getPosX(); + int y = playerModel.getPosY() + direction.getPoint().getPosY(); + List<List<String>> map = ItemProducerConverter.RLEtoMap(rle); + return y >= 0 && x >= 0 && x < map.getFirst().size() && y < map.getFirst().size() && ItemAggregate.ResourceType.valueOf(map.get(y).get(x)).getItemInfo().isWalkable(); + } + + @Transactional + public void movePlayer(Direction direction) { + PlayerModel player = getFirstPlayer(); + update("posX = ?1, posY = ?2, lastMove = ?3 where id = ?4", player.getPosX() + direction.getPoint().getPosX() + , player.getPosY() + direction.getPoint().getPosY(), LocalDateTime.now(), player.getId()); + } + + public void updateMoveSpeed(Float newSpeed) { + PlayerModel player = getFirstPlayer(); + update("moveSpeedMultiplier = ?1 where id = ?2", newSpeed, player.getId()); + } + + public void updateCollectRate(Float newRate) { + PlayerModel player = getFirstPlayer(); + update("collectRateMultiplier = ?1 where id = ?2", newRate, player.getId()); + } + + public void updateStamina(Float newStamina) { + PlayerModel player = getFirstPlayer(); + update("staminaMultiplier = ?1 where id = ?2", newStamina, player.getId()); + } +} diff --git a/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/GameEntity.java b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/GameEntity.java new file mode 100644 index 0000000..e248cb5 --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/GameEntity.java @@ -0,0 +1,4 @@ +package fr.epita.assistants.item_producer.domain.entity; + +public class GameEntity { +} diff --git a/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/ItemEntity.java b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/ItemEntity.java new file mode 100644 index 0000000..a8b666d --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/ItemEntity.java @@ -0,0 +1,13 @@ +package fr.epita.assistants.item_producer.domain.entity; + +import fr.epita.assistants.common.aggregate.ItemAggregate; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class ItemEntity { + long id; + float quantity; + ItemAggregate.ResourceType type; +} diff --git a/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/ItemsEntity.java b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/ItemsEntity.java new file mode 100644 index 0000000..b03b373 --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/ItemsEntity.java @@ -0,0 +1,13 @@ +package fr.epita.assistants.item_producer.domain.entity; + +import fr.epita.assistants.common.api.response.ItemResponse; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.List; + +@Getter +@AllArgsConstructor +public class ItemsEntity { + List<ItemEntity> items; +} diff --git a/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/MoveEntity.java b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/MoveEntity.java new file mode 100644 index 0000000..72ea511 --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/MoveEntity.java @@ -0,0 +1,11 @@ +package fr.epita.assistants.item_producer.domain.entity; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class MoveEntity { + int posX; + int posY; +} diff --git a/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/PlayerEntity.java b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/PlayerEntity.java new file mode 100644 index 0000000..0913c3f --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/PlayerEntity.java @@ -0,0 +1,18 @@ +package fr.epita.assistants.item_producer.domain.entity; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.time.LocalDateTime; + +@AllArgsConstructor +@Getter +public class PlayerEntity { + int posX; + int posY; + LocalDateTime lastMove; + LocalDateTime lastCollect; + float moveSpeedMultiplier; + float staminaMultiplier; + float collectRateMultiplier; +} diff --git a/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/StartEntity.java b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/StartEntity.java new file mode 100644 index 0000000..44a4961 --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/StartEntity.java @@ -0,0 +1,11 @@ +package fr.epita.assistants.item_producer.domain.entity; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class StartEntity { + String mapPath; + String rle; +} diff --git a/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/UpgradeCostEntity.java b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/UpgradeCostEntity.java new file mode 100644 index 0000000..fac79e0 --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/entity/UpgradeCostEntity.java @@ -0,0 +1,12 @@ +package fr.epita.assistants.item_producer.domain.entity; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class UpgradeCostEntity { + float upgradeCollectCost; + float upgradeMoveCost; + float upgradeStaminaCost; +} diff --git a/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/service/ErwenService.java b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/service/ErwenService.java new file mode 100644 index 0000000..fb3a507 --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/service/ErwenService.java @@ -0,0 +1,4 @@ +package fr.epita.assistants.item_producer.domain.service; + +public class ErwenService { +} diff --git a/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/service/ItemProducerService.java b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/service/ItemProducerService.java new file mode 100644 index 0000000..2a224c7 --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/domain/service/ItemProducerService.java @@ -0,0 +1,199 @@ +package fr.epita.assistants.item_producer.domain.service; + +import fr.epita.assistants.common.aggregate.ItemAggregate; +import fr.epita.assistants.common.aggregate.ResetInventoryAggregate; +import fr.epita.assistants.common.api.response.*; +import fr.epita.assistants.common.command.*; +import fr.epita.assistants.common.utils.Direction; +import fr.epita.assistants.item_producer.converter.ItemProducerConverter; +import fr.epita.assistants.item_producer.data.model.ItemModel; +import fr.epita.assistants.item_producer.data.model.PlayerModel; +import fr.epita.assistants.item_producer.data.repository.GameRepository; +import fr.epita.assistants.item_producer.data.repository.ItemRepository; +import fr.epita.assistants.item_producer.data.repository.PlayerRepository; +import fr.epita.assistants.item_producer.domain.entity.*; +import io.smallrye.reactive.messaging.annotations.Broadcast; +import jakarta.enterprise.context.ApplicationScoped; +import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.eclipse.microprofile.reactive.messaging.Channel; +import org.eclipse.microprofile.reactive.messaging.Emitter; + +import jakarta.inject.Inject; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@ApplicationScoped +public class ItemProducerService { + @ConfigProperty(name = "JWS_TICK_DURATION") + String tps; + @ConfigProperty(name = "JWS_DELAY_MOVEMENT") + String movementDelay; + @ConfigProperty(name = "JWS_DELAY_COLLECT") + String collectDelay; + @ConfigProperty(name = "JWS_UPGRADE_COLLECT_COST") + String upgradeCollectCost; + @ConfigProperty(name = "JWS_UPGRADE_MOVE_COST") + String upgradeMoveCost; + @ConfigProperty(name = "JWS_UPGRADE_STAMINA_COST") + String upgradeStaminaCost; + @ConfigProperty(name = "JWS_UPGRADE_MULTIPLIER") + String upgradeMultiplier; + @Inject + PlayerRepository playerRepository; + @Inject + GameRepository gameRepository; + @Inject + ItemRepository itemRepository; + + @Inject + @Channel("reset-inventory-command") + @Broadcast + Emitter<ResetInventoryCommand> resetInventoryCommandEmitter; + @Inject + @Channel("collect-item-command") + @Broadcast + Emitter<CollectItemCommand> collectItemCommandEmitter; + @Inject + @Channel("upgrade-movement-speed-command") + @Broadcast + Emitter<UpgradeMovementSpeedCommand> upgradeMovementSpeedCommandEmitter; + @Inject + @Channel("upgrade-stamina-command") + @Broadcast + Emitter<UpgradeStaminaCommand> upgradeStaminaCommandEmitter; + @Inject + @Channel("upgrade-collect-rate-command") + @Broadcast + Emitter<UpgradeCollectRateCommand> upgradeCollectRateCommandEmitter; + + public StartEntity startGame(StartEntity startEntity) { + if (startEntity == null) + return null; + gameRepository.clearDB(); + playerRepository.clearDB(); + try (Stream<String> stream = Files.lines(Paths.get(startEntity.getMapPath()))) { + if (new File(startEntity.getMapPath()).isDirectory()) + return null; + String rle = stream.collect(Collectors.joining(";")); + gameRepository.addEntry(rle); + playerRepository.addEntry(); + resetInventoryCommandEmitter.send(new ResetInventoryCommand()); + return new StartEntity(null, rle); + } catch (IOException e) { + return null; + } + } + + public void clearItems(ResetInventoryAggregate items) { + itemRepository.deleteItems(ItemProducerConverter.DeleteItems(items)); + } + + public ItemsEntity getAllItems() { + return new ItemsEntity(itemRepository.getItems().stream().map(m -> new ItemEntity(m.getId(), + m.getQuantity(), m.getType())).toList()); + } + + public boolean isGameRunning() { + return !gameRepository.isEmpty(); + } + + public boolean canMove() { + long tickRate = Long.parseLong(tps); + long moveDelay = Long.parseLong(movementDelay); + PlayerEntity player = getCurrentPlayer(); + return player.getLastMove() == null || player.getLastMove().plus((long) (moveDelay * tickRate * player.getMoveSpeedMultiplier()), + ChronoUnit.MILLIS).isBefore(LocalDateTime.now()); + } + + public boolean canCollect() { + long tickRate = Long.parseLong(tps); + long collectDelayLong = Long.parseLong(collectDelay); + PlayerEntity player = getCurrentPlayer(); + return player.getLastCollect() == null || player.getLastCollect().plus((long) (collectDelayLong * tickRate * player.getMoveSpeedMultiplier()), + ChronoUnit.MILLIS).isBefore(LocalDateTime.now()); + } + + public PlayerEntity getCurrentPlayer() { + PlayerModel p = playerRepository.getFirstPlayer(); + return new PlayerEntity(p.getPosX(), p.getPosY(), p.getLastMove(), p.getLastCollect(), + p.getMoveSpeedMultiplier(), p.getStaminaMultiplier(), p.getCollectRateMultiplier()); + } + + public UpgradeCostEntity getUpgradeCosts() { + return new UpgradeCostEntity(Float.parseFloat(upgradeCollectCost), + Float.parseFloat(upgradeMoveCost), Float.parseFloat(upgradeStaminaCost)); + } + + public MoveEntity move(Direction direction) { + if (direction == null) + return null; + if (!playerRepository.isValidMove(direction, gameRepository.getMap())) + return null; + playerRepository.movePlayer(direction); + return ItemProducerConverter.Move(playerRepository.getFirstPlayer()); + } + + public StartEntity collect() { + PlayerEntity player = getCurrentPlayer(); + if (!gameRepository.isValidCollect(player.getPosX(), player.getPosY())) + return null; + String item = gameRepository.collectResource(player.getPosX(), player.getPosY()); + gameRepository.setToGround(player.getPosX(), player.getPosY()); + collectItemCommandEmitter.send(new CollectItemCommand(ItemAggregate.ResourceType.valueOf(item), + player.getCollectRateMultiplier())); + return ItemProducerConverter.Collect(item); + } + + public void collectItem(ItemAggregate agr) { + Optional<ItemModel> item = itemRepository.exists(agr.getType()); + if (item.isPresent()) { + itemRepository.fillInventory(agr.getType(), agr.getQuantity()); + } else { + itemRepository.addItem(agr.getType(), agr.getQuantity()); + } + } + + public Double getMoney() { + List<ItemModel> entries = itemRepository.getMoney(); + if (entries.isEmpty()) + return null; + return entries.stream().mapToDouble(m -> m.getQuantity().doubleValue()).sum(); + } + + public void upgradeMove() { + upgradeMovementSpeedCommandEmitter.send(new UpgradeMovementSpeedCommand(Float.parseFloat(upgradeMoveCost))); + } + + public void updateMove() { + playerRepository.updateMoveSpeed(getCurrentPlayer().getMoveSpeedMultiplier() - Float.parseFloat(upgradeMultiplier)); + } + + public void upgradeCollect() { + upgradeCollectRateCommandEmitter.send(new UpgradeCollectRateCommand(Float.parseFloat(upgradeMoveCost))); + } + + public void updateCollect() { + playerRepository.updateCollectRate(getCurrentPlayer().getCollectRateMultiplier() - Float.parseFloat(upgradeMultiplier)); + } + + public void upgradeStamina() { + upgradeStaminaCommandEmitter.send(new UpgradeStaminaCommand(Float.parseFloat(upgradeMoveCost))); + } + + public void updateStamina() { + playerRepository.updateStamina(getCurrentPlayer().getStaminaMultiplier() - Float.parseFloat(upgradeMultiplier)); + } + + public void pay(Float newMoney) { + itemRepository.fillInventory(ItemAggregate.ResourceType.MONEY, newMoney); + } +} diff --git a/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/presentation/rest/HelloWorldResource.java b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/presentation/rest/HelloWorldResource.java new file mode 100644 index 0000000..9f9cb70 --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/presentation/rest/HelloWorldResource.java @@ -0,0 +1,19 @@ +package fr.epita.assistants.item_producer.presentation.rest; + +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; + +@Path("/hello") +@Produces(MediaType.TEXT_PLAIN) +@Consumes(MediaType.TEXT_PLAIN) +public class HelloWorldResource { + @GET @Path("/") + public String helloWorld() { + return "Hello World!"; + } + + @GET @Path("/{name}") + public String helloWorld(@PathParam("name") String name) { + return "Hello " + name + "!"; + } +} diff --git a/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/presentation/rest/ItemProducerResource.java b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/presentation/rest/ItemProducerResource.java new file mode 100644 index 0000000..fcebee9 --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/presentation/rest/ItemProducerResource.java @@ -0,0 +1,154 @@ +package fr.epita.assistants.item_producer.presentation.rest; + +import fr.epita.assistants.common.api.request.MoveRequest; +import fr.epita.assistants.common.api.request.StartRequest; +import fr.epita.assistants.common.api.response.MoveResponse; +import fr.epita.assistants.common.api.response.StartResponse; +import fr.epita.assistants.common.utils.ErrorInfo; +import fr.epita.assistants.item_producer.converter.ItemProducerConverter; +import fr.epita.assistants.item_producer.domain.service.ItemProducerService; +import jakarta.inject.Inject; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +@Path("/") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class ItemProducerResource { + @Inject + ItemProducerService itemProducerService; + + @Path("/") + @GET + public Response getInventory() { + Response.ResponseBuilder rb; + if (!itemProducerService.isGameRunning()) + rb = Response.status(Response.Status.BAD_REQUEST).entity(new ErrorInfo("Game is not running")); + else + rb = Response.ok(ItemProducerConverter.EntityToResponse(itemProducerService.getAllItems())); + return rb.build(); + } + + @Path("player") + @GET + public Response getPlayer() { + Response.ResponseBuilder rb; + if (!itemProducerService.isGameRunning()) + rb = Response.status(Response.Status.BAD_REQUEST).entity(new ErrorInfo("Game is not running")); + else + rb = Response.ok(ItemProducerConverter.EntityToResponse(itemProducerService.getCurrentPlayer())); + return rb.build(); + } + @Path("start") + @POST + public Response start(StartRequest startRequest) { + StartResponse r = ItemProducerConverter.EntityToResponse(itemProducerService.startGame(ItemProducerConverter.Start(startRequest))); + Response.ResponseBuilder res; + if (r == null) + res = Response.status(Response.Status.BAD_REQUEST).entity(new ErrorInfo("Bad request for /start")); + else + res = Response.ok(r); + return res.build(); + } + @Path("upgrades") + @GET + public Response getUpgrades() { + Response.ResponseBuilder rb; + if (!itemProducerService.isGameRunning()) + rb = Response.status(Response.Status.BAD_REQUEST).entity(new ErrorInfo("Game is not running")); + else + rb = Response.ok(ItemProducerConverter.EntityToResponse(itemProducerService.getUpgradeCosts())); + return rb.build(); + } + + @Path("collect") + @POST + public Response collect() { + Response.ResponseBuilder rb; + if (!itemProducerService.isGameRunning()) + rb = Response.status(Response.Status.BAD_REQUEST).entity(new ErrorInfo("Game is not running")); + else if (!itemProducerService.canCollect()) + rb = Response.status(Response.Status.TOO_MANY_REQUESTS).entity(new ErrorInfo("Input too early, wait " + + "before trying to move again")); + else { + StartResponse rep = ItemProducerConverter.EntityToResponse(itemProducerService.collect()); + if (rep == null) + rb = Response.status(Response.Status.BAD_REQUEST).entity(new ErrorInfo("Can't collect on this tile")); + else + rb = Response.ok(rep); + } + return rb.build(); + } + + @Path("move") + @POST + public Response move(MoveRequest moveRequest) { + Response.ResponseBuilder rb; + if (!itemProducerService.isGameRunning()) + rb = Response.status(Response.Status.BAD_REQUEST).entity(new ErrorInfo("Game is not running")); + else if (!itemProducerService.canMove()) + rb = Response.status(Response.Status.TOO_MANY_REQUESTS).entity(new ErrorInfo("Input too early, wait " + + "before trying to move again")); + else { + MoveResponse rep = ItemProducerConverter.EntityToResponse(itemProducerService.move(moveRequest.getDirection())); + if (rep == null) + rb = Response.status(Response.Status.BAD_REQUEST).entity(new ErrorInfo("Tried to move out of bounds " + + "(or maybe you felt like you were Jesus)")); + else + rb = Response.ok(rep); + } + return rb.build(); + } + + @Path("upgrade/collect") + @PATCH + public Response upgradeCollect() { + Response.ResponseBuilder rb; + if (!itemProducerService.isGameRunning()) + rb = Response.status(Response.Status.BAD_REQUEST).entity(new ErrorInfo("Game is not running.")); + else if (itemProducerService.getMoney() == null) + rb = Response.status(Response.Status.NOT_FOUND).entity(new ErrorInfo("No money was found.")); + else if (itemProducerService.getMoney() < itemProducerService.getUpgradeCosts().getUpgradeCollectCost()) + rb = Response.status(Response.Status.BAD_REQUEST).entity(new ErrorInfo("You are poor.")); + else { + itemProducerService.upgradeCollect(); + rb = Response.noContent(); + } + return rb.build(); + } + + @Path("upgrade/move") + @PATCH + public Response upgradeMove() { + Response.ResponseBuilder rb; + if (!itemProducerService.isGameRunning()) + rb = Response.status(Response.Status.BAD_REQUEST).entity(new ErrorInfo("Game is not running.")); + else if (itemProducerService.getMoney() == null) + rb = Response.status(Response.Status.NOT_FOUND).entity(new ErrorInfo("No money was found.")); + else if (itemProducerService.getMoney() < itemProducerService.getUpgradeCosts().getUpgradeMoveCost()) + rb = Response.status(Response.Status.BAD_REQUEST).entity(new ErrorInfo("You are poor.")); + else { + itemProducerService.upgradeMove(); + rb = Response.noContent(); + } + return rb.build(); + } + + @Path("upgrade/stamina") + @PATCH + public Response upgradeStamina() { + Response.ResponseBuilder rb; + if (!itemProducerService.isGameRunning()) + rb = Response.status(Response.Status.BAD_REQUEST).entity(new ErrorInfo("Game is not running.")); + else if (itemProducerService.getMoney() == null) + rb = Response.status(Response.Status.NOT_FOUND).entity(new ErrorInfo("No money was found.")); + else if (itemProducerService.getMoney() < itemProducerService.getUpgradeCosts().getUpgradeStaminaCost()) + rb = Response.status(Response.Status.BAD_REQUEST).entity(new ErrorInfo("You are poor.")); + else { + itemProducerService.upgradeStamina(); + rb = Response.noContent(); + } + return rb.build(); + } +} diff --git a/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/presentation/subscriber/AggregateSubscriber.java b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/presentation/subscriber/AggregateSubscriber.java new file mode 100644 index 0000000..c6f3231 --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/java/fr/epita/assistants/item_producer/presentation/subscriber/AggregateSubscriber.java @@ -0,0 +1,47 @@ +package fr.epita.assistants.item_producer.presentation.subscriber; + +import fr.epita.assistants.common.aggregate.ItemAggregate; +import fr.epita.assistants.common.aggregate.ResetInventoryAggregate; +import fr.epita.assistants.common.aggregate.UpgradeItemProducerAggregate; +import fr.epita.assistants.item_producer.domain.service.ItemProducerService; +import io.smallrye.reactive.messaging.annotations.Broadcast; +import jakarta.inject.Inject; +import org.eclipse.microprofile.reactive.messaging.Incoming; + +public class AggregateSubscriber { + @Inject + ItemProducerService itemProducerService; + + @Broadcast + @Incoming("reset-inventory-aggregate") + public void commandListener(ResetInventoryAggregate aggregate) { + itemProducerService.clearItems(aggregate); + } + + @Broadcast + @Incoming("collect-item-aggregate") + public void commandListener(ItemAggregate agr) { + itemProducerService.collectItem(agr); + } + + @Broadcast + @Incoming("upgrade-collect-rate-aggregate") + public void collectCommandListener(UpgradeItemProducerAggregate agr) { + itemProducerService.pay(agr.getNewMoney()); + itemProducerService.updateCollect(); + } + + @Broadcast + @Incoming("upgrade-movement-speed-aggregate") + public void moveCommandListener(UpgradeItemProducerAggregate agr) { + itemProducerService.pay(agr.getNewMoney()); + itemProducerService.updateMove(); + } + + @Broadcast + @Incoming("upgrade-stamina-aggregate") + public void staminaCommandListener(UpgradeItemProducerAggregate agr) { + itemProducerService.pay(agr.getNewMoney()); + itemProducerService.updateStamina(); + } +} diff --git a/jws/epibazaar/item-producer/src/main/resources/application.properties b/jws/epibazaar/item-producer/src/main/resources/application.properties new file mode 100644 index 0000000..498479f --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/resources/application.properties @@ -0,0 +1,13 @@ +%dev.quarkus.http.port=8081 +quarkus.datasource.db-kind=postgresql +quarkus.datasource.username=postgres +quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/item_producer?currentSchema=public +quarkus.transaction-manager.default-transaction-timeout=3000s +quarkus.hibernate-orm.log.queries-slower-than-ms=200 +quarkus.http.cors=true +quarkus.http.cors.origins=* +quarkus.hibernate-orm.database.generation=drop-and-create + +quarkus.kafka.devservices.image-name=reg.undercloud.cri.epita.fr/docker/redpandadata/redpanda:v24.1.2 +quarkus.devservices.enabled=true +%test.quarkus.devservices.enabled=false diff --git a/jws/epibazaar/item-producer/src/main/resources/db/migration/V1__Init.sql b/jws/epibazaar/item-producer/src/main/resources/db/migration/V1__Init.sql new file mode 100644 index 0000000..0eede01 --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/resources/db/migration/V1__Init.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS "game" +( + id SERIAL PRIMARY KEY NOT NULL, + map TEXT NOT NULL +); + +CREATE TABLE IF NOT EXISTS "item" +( + id SERIAL PRIMARY KEY NOT NULL, + + type VARCHAR(64) NOT NULL, + quantity FLOAT NOT NULL +); + +CREATE TABLE IF NOT EXISTS "player" +( + id SERIAL PRIMARY KEY NOT NULL, + pos_x INTEGER NOT NULL, + pos_y INTEGER NOT NULL, + last_move TIMESTAMP, + last_collect TIMESTAMP, + move_speed_multiplier FLOAT NOT NULL, + stamina_multiplier FLOAT NOT NULL, + collect_rate_multiplier FLOAT NOT NULL +); diff --git a/jws/epibazaar/item-producer/src/main/resources/maps/custom.epimap b/jws/epibazaar/item-producer/src/main/resources/maps/custom.epimap new file mode 100644 index 0000000..5b510f3 --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/resources/maps/custom.epimap @@ -0,0 +1,16 @@ +2G4R3W5G2R +5G3W4R2G2W +6R3G2W5G +3W5G6R2W +4G3R4W5G +2W5R3G4W2G +6G4R3W3G +4R6G3W3R +5G2W5R4G +3W5R4G3W1G +2G6W3R5G +4W5G3R4W +3G4R5W4G +5R3G6W2R +2W5G4R5W +9G7G
\ No newline at end of file diff --git a/jws/epibazaar/item-producer/src/main/resources/maps/huge.epimap b/jws/epibazaar/item-producer/src/main/resources/maps/huge.epimap new file mode 100644 index 0000000..d8384bd --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/resources/maps/huge.epimap @@ -0,0 +1,30 @@ +9G9G9G3G +8G3W3R2G2R2G2W1R4G1R2G +7G2W1G3R1W1G1R1W2G1R1G1R1G1R1G2W2R1G +1G1W4G1R1G1W1R5G2R4G1R1W1R2G1W3G +1G1W1R2G2R1G1W2R3G2W2G2O3G2R3G1W1G +1G1W1G2W7G4O3G2O3R3G2W1G +1G1R4G1R3G1R3G2O3G2O2R3G2W2G +4G3R3G3R8O3R2G1W3G +4G3R1G5R4O2G1W2R1G2R5G +4G9R1G3O9G4G +5G4R2W2O1R5O2G3W1R5G +3G4R2G8O1G7W1G2W2G +3G1R1G2R1G1W9O1W2G1R2W6G +1G1R1G2R2G1R1W1G6O4W9O1G +1G4R1G2R1W1G3O1G2O5W1G7O1G +1G1W2R1W1G1R1G2W3O2R1O4W1G1R7O1G +5G3W3G2O1G1W1G3W1G1W1G7O1G +1G2R2G2W4R2O3G3W1R1G1W1G1R5O1G +1G1W1R1G2R4W1R1G1R1G3R2W5G5O1G +1G2R2G1R2W1R2G6R1W1G9O1O1G +2G2W9R2R3W2G9O1G +6G3W2G4R3W2G2O1W6O1G +1G3R2G3W2G3R1G3W2R2O1R6O1G +1G3R1G1W3R2W1R2G2W1G3R2O1R1O1G1O1G1W1O1G +3G2W1G2R1G2R2G2W3G1R1W2G2R1G1W1G1R1O1G +3G1W1R3G2R4G1R2G1W1G1R2W2R1G1W3R1G +1G4W1G3R2W3G2R3W1R2W3R1G2R2G +2G3W1G2R6G2R2G2R1G1W1G2W1G1R1G1W1G +2G3W1G1W1G4W9G1G2R1W1G2R2G +9G9G9G3G
\ No newline at end of file diff --git a/jws/epibazaar/item-producer/src/main/resources/maps/pretty.epimap b/jws/epibazaar/item-producer/src/main/resources/maps/pretty.epimap new file mode 100644 index 0000000..3699c22 --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/resources/maps/pretty.epimap @@ -0,0 +1,16 @@ +9G7G +2G6O3G4R1G +2G5O4G3R2G +2G4O4G3W2G1G +2G3O4G5W1G1G +2G3O3G5W3G +2G3G4W4G3R +2G3R3G4W3O1G +1G2R3G4W4O2G +1G3G3W6O3G +1G2W4G5O4G +1G2W3G4R3G3G +1G3R4G4R1G3G +1G5R4G4R2G +1G5R3G6G1G +9G7G diff --git a/jws/epibazaar/item-producer/src/main/resources/openapi.yaml b/jws/epibazaar/item-producer/src/main/resources/openapi.yaml new file mode 100644 index 0000000..16e0465 --- /dev/null +++ b/jws/epibazaar/item-producer/src/main/resources/openapi.yaml @@ -0,0 +1,287 @@ +--- +openapi: 3.1.0 +tags: +- name: Game Management +- name: Player Actions +- name: Upgrades +paths: + /: + get: + summary: Retrieve all inventory resources + description: Fetch all resources currently available in the inventory. + x-quarkus-openapi-method-ref: m98752433_-1109396335 + tags: + - Game Management + responses: + "200": + description: Resources successfully retrieved. + content: + application/json: + schema: + $ref: "#/components/schemas/ItemsResponse" + "400": + description: The game is not running. + servers: + - url: http://localhost:8081/ + /collect: + post: + summary: Collect resources + description: Collect the resource available on the player's current tile. + x-quarkus-openapi-method-ref: m98752433_799402137 + tags: + - Player Actions + responses: + "200": + description: Resource successfully collected and sent to inventory. + content: + application/json: + schema: + $ref: "#/components/schemas/StartResponse" + "400": + description: Invalid tile or the game is not running. + "429": + description: Player has recently collected and must wait before collecting + again. + servers: + - url: http://localhost:8081/ + /move: + post: + summary: Move player + description: "Move the player in the specified direction (left, right, up, or\ + \ down)." + x-quarkus-openapi-method-ref: m98752433_-1586243046 + tags: + - Player Actions + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/MoveRequest" + required: true + responses: + "200": + description: Player successfully moved. + content: + application/json: + schema: + $ref: "#/components/schemas/MoveResponse" + "400": + description: Invalid direction or the game is not running. + "429": + description: Player has recently moved and must wait before moving again. + servers: + - url: http://localhost:8081/ + /player: + get: + summary: Retrieve player information + description: Fetch information about the current player. + x-quarkus-openapi-method-ref: m98752433_-1988770431 + tags: + - Game Management + responses: + "200": + description: Player information successfully retrieved. + content: + application/json: + schema: + $ref: "#/components/schemas/PlayerResponse" + "400": + description: The game is not running. + servers: + - url: http://localhost:8081/ + /start: + post: + summary: Start the game + description: Initialize and start the item-producer game. Synchronizes the database + with the `Inventory` service. + x-quarkus-openapi-method-ref: m98752433_677674067 + tags: + - Game Management + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/StartRequest" + required: true + responses: + "200": + description: The game started successfully. + content: + application/json: + schema: + $ref: "#/components/schemas/StartResponse" + "400": + description: Invalid `path` provided. + servers: + - url: http://localhost:8081/ + /upgrade/collect: + patch: + summary: Upgrade collection rate + description: Increase the amount of resources collected per action. + x-quarkus-openapi-method-ref: m98752433_274012880 + tags: + - Upgrades + responses: + "204": + description: Collection rate upgrade successfully applied. + "400": + description: Insufficient funds or the game is not running. + "404": + description: The money was not found. + servers: + - url: http://localhost:8081/ + /upgrade/move: + patch: + summary: Upgrade move speed + description: Decrease the tick rate required for the player to move. + x-quarkus-openapi-method-ref: m98752433_1889564488 + tags: + - Upgrades + responses: + "204": + description: Move speed upgrade successfully applied. + "400": + description: Insufficient funds or the game is not running. + "404": + description: The money was not found. + servers: + - url: http://localhost:8081/ + /upgrade/stamina: + patch: + summary: Upgrade stamina + description: Decrease the tick rate required to collect resources. + x-quarkus-openapi-method-ref: m98752433_-1142370765 + tags: + - Upgrades + responses: + "204": + description: Stamina upgrade successfully applied. + "400": + description: Insufficient funds or the game is not running. + "404": + description: The money was not found. + servers: + - url: http://localhost:8081/ + /upgrades: + get: + summary: Retrieve upgrade costs + description: Fetch the costs of all available upgrades. + x-quarkus-openapi-method-ref: m98752433_-99503618 + tags: + - Game Management + responses: + "200": + description: Upgrade costs successfully retrieved. + content: + application/json: + schema: + $ref: "#/components/schemas/UpgradeCostResponse" + "400": + description: The game is not running. + servers: + - url: http://localhost:8081/ +components: + schemas: + Direction: + type: string + enum: + - UP + - DOWN + - RIGHT + - LEFT + ItemResponse: + type: object + properties: + id: + type: integer + format: int32 + quantity: + type: number + format: float + type: + $ref: "#/components/schemas/ResourceType" + ItemsResponse: + type: object + properties: + itemsResponse: + type: array + items: + $ref: "#/components/schemas/ItemResponse" + LocalDateTime: + type: string + format: date-time + examples: + - 2022-03-10T12:15:50 + MoveRequest: + type: object + properties: + direction: + $ref: "#/components/schemas/Direction" + MoveResponse: + type: object + properties: + posX: + type: integer + format: int32 + posY: + type: integer + format: int32 + PlayerResponse: + type: object + properties: + posX: + type: integer + format: int32 + posY: + type: integer + format: int32 + lastMove: + $ref: "#/components/schemas/LocalDateTime" + lastCollect: + $ref: "#/components/schemas/LocalDateTime" + moveSpeedMultiplier: + type: number + format: float + staminaMultiplier: + type: number + format: float + collectRateMultiplier: + type: number + format: float + ResourceType: + type: string + enum: + - MONEY + - GROUND + - WATER + - ROCK + - WOOD + StartRequest: + type: object + properties: + mapPath: + type: string + StartResponse: + type: object + properties: + map: + type: array + items: + type: array + items: + $ref: "#/components/schemas/ResourceType" + UpgradeCostResponse: + type: object + properties: + upgradeCollectCost: + type: number + format: float + upgradeMoveCost: + type: number + format: float + upgradeStaminaCost: + type: number + format: float +info: + title: item-producer API + version: 1.0.0 |
