added possibility to buy facilities and ships

This commit is contained in:
helori_ollivier
2025-11-24 09:07:56 +01:00
parent ca22b2f79e
commit 0671b4bac2
34 changed files with 389 additions and 43 deletions

2
mvnw vendored
View File

@@ -1,4 +1,4 @@
#!/bin/sh
()#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file

View File

@@ -5,6 +5,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@@ -15,7 +16,8 @@ public class SpringSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth.anyRequest().permitAll());
http.authorizeHttpRequests(auth -> auth.anyRequest().permitAll())
.csrf(AbstractHttpConfigurer::disable);
return http.build();
}
}

View File

@@ -1,4 +1,4 @@
package bzh.risotto.galactik.api.controler;
package bzh.risotto.galactik.api.controller;
import bzh.risotto.galactik.api.model.Corpo;
import bzh.risotto.galactik.api.service.CorpoService;
@@ -8,8 +8,6 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Optional;
@RestController
@RequestMapping("/corpo")
public class CorpoController {
@@ -27,7 +25,7 @@ public class CorpoController {
}
@GetMapping("/{corpoId}")
public Optional<Corpo> getCorpos(@PathVariable Long corpoId) {
public Corpo getCorpos(@PathVariable Long corpoId) {
return this.corpoService.getCorpo(corpoId);
}
}

View File

@@ -1,4 +1,4 @@
package bzh.risotto.galactik.api.controler;
package bzh.risotto.galactik.api.controller;
import bzh.risotto.galactik.api.model.Facility;
import bzh.risotto.galactik.api.service.FacilityService;

View File

@@ -0,0 +1,57 @@
package bzh.risotto.galactik.api.controller;
import bzh.risotto.galactik.api.model.Facility;
import bzh.risotto.galactik.api.model.Ship;
import bzh.risotto.galactik.api.service.MarketService;
import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/market")
public class MarketController {
private final MarketService marketService;
@Autowired
public MarketController(MarketService marketService) {
this.marketService = marketService;
}
@GetMapping("/facilities")
public List<Facility> getFacilities() {
return marketService.getFacilities();
}
@PostMapping(value = "/facilities/buy", consumes = MediaType.APPLICATION_JSON_VALUE)
public Facility buyFacilities(@RequestBody JsonNode data) {
long facilityId = Long.parseLong(data.get("facilityId").asText());
long corpoId = Long.parseLong(data.get("corpoId").asText());
return marketService.buyFacilities(facilityId, corpoId);
}
@GetMapping("/ships")
public List<Ship> getShips() {
return marketService.getShips();
}
@PostMapping(value = "/ships/buy", consumes = MediaType.APPLICATION_JSON_VALUE)
public Ship buyShip(@RequestBody JsonNode data) {
long facilityId = Long.parseLong(data.get("shipId").asText());
long corpoId = Long.parseLong(data.get("corpoId").asText());
return marketService.buyShip(facilityId, corpoId);
}
}

View File

@@ -1,4 +1,4 @@
package bzh.risotto.galactik.api.controler;
package bzh.risotto.galactik.api.controller;
import bzh.risotto.galactik.api.service.ModuleService;
import bzh.risotto.galactik.api.model.Module;

View File

@@ -1,4 +1,4 @@
package bzh.risotto.galactik.api.controler;
package bzh.risotto.galactik.api.controller;
import bzh.risotto.galactik.api.model.Planet;
import bzh.risotto.galactik.api.service.PlanetService;

View File

@@ -1,4 +1,4 @@
package bzh.risotto.galactik.api.controler;
package bzh.risotto.galactik.api.controller;
import bzh.risotto.galactik.api.model.Ressource;
import bzh.risotto.galactik.api.service.RessourceService;

View File

@@ -1,4 +1,4 @@
package bzh.risotto.galactik.api.controler;
package bzh.risotto.galactik.api.controller;
import bzh.risotto.galactik.api.model.Ship;
import bzh.risotto.galactik.api.service.ShipService;

View File

@@ -1,4 +1,4 @@
package bzh.risotto.galactik.api.controler;
package bzh.risotto.galactik.api.controller;
import bzh.risotto.galactik.api.model.Star;
import bzh.risotto.galactik.api.service.StarService;

View File

@@ -0,0 +1,13 @@
package bzh.risotto.galactik.api.exceptions;
public class CorpoNotFoundException extends RuntimeException {
public CorpoNotFoundException(Long id) {
super("Corpo: " + id + " not found");
}
public CorpoNotFoundException(String msg) {
super(msg);
}
}

View File

@@ -0,0 +1,13 @@
package bzh.risotto.galactik.api.exceptions;
public class FacilityNotFoundException extends RuntimeException {
public FacilityNotFoundException(Long id) {
super("Facilty: " + id + " not found");
}
public FacilityNotFoundException(String msg) {
super(msg);
}
}

View File

@@ -0,0 +1,12 @@
package bzh.risotto.galactik.api.exceptions;
public class NotEnoughtRessourceException extends RuntimeException {
public NotEnoughtRessourceException(long ressourceId, long corpoId) {
super("corpo: " + corpoId + " has not enough resource of type: " + ressourceId);
}
public NotEnoughtRessourceException(String msg) {
super(msg);
}
}

View File

@@ -0,0 +1,13 @@
package bzh.risotto.galactik.api.exceptions;
public class RessourceNotFoundException extends RuntimeException {
public RessourceNotFoundException(int ressourceId) {
super("Ressource: " + ressourceId + " not found");
}
public RessourceNotFoundException(String msg) {
super(msg);
}
}

View File

@@ -0,0 +1,12 @@
package bzh.risotto.galactik.api.exceptions;
public class ShipNotFoundException extends RuntimeException {
public ShipNotFoundException(long shipId) {
super("Ship: " + shipId + " not found");
}
public ShipNotFoundException(String message) {
super(message);
}
}

View File

@@ -2,6 +2,8 @@ package bzh.risotto.galactik.api.model;
import jakarta.persistence.*;
import lombok.Data;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import java.util.List;
@@ -13,14 +15,11 @@ public class Corpo {
@Id
@Column(name = "c_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private long id;
@Column(name = "c_name")
private String name;
@Column(name = "c_money")
private Double money;
@OneToMany()
@JoinTable(
name = "corpo_ressource",
@@ -29,7 +28,8 @@ public class Corpo {
)
private List<Ressource> ressources;
@OneToMany(fetch = FetchType.LAZY)
@OneToMany()
@Fetch(FetchMode.JOIN)
@JoinColumn(name = "s_propritary")
private List<Ship> ships;
@@ -38,6 +38,7 @@ public class Corpo {
private List<Planet> planets;
@OneToMany()
@Fetch(FetchMode.JOIN)
@JoinColumn(name = "f_proprietary", referencedColumnName = "c_id")
private List<Facility> facilities;
}

View File

@@ -8,12 +8,12 @@ import java.util.Date;
@Data
@Entity
@Table(name = "facility")
public class Facility {
public class Facility implements Item {
@Id
@Column(name = "f_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private long id;
@OneToOne()
@JoinColumn(name = "f_type", referencedColumnName = "ft_id")
@@ -30,5 +30,19 @@ public class Facility {
private Integer planet;
@Column(name = "f_proprietary")
private Integer corpo;
private long corpo;
public Facility copy() {
Facility f = new Facility();
//f.setId(this.id);
f.setFacilityType(this.facilityType);
f.setProcessingRessource(this.processingRessource);
f.setStartTime(this.startTime);
f.setPlanet(this.planet);
f.setCorpo(this.corpo);
return f;
}
}

View File

@@ -11,11 +11,14 @@ public class FacilityType {
@Id
@Column(name = "ft_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private long id;
@Column(name = "ft_name")
private String name;
@Column(name = "ft_value")
private int value;
@OneToOne()
@JoinColumn(name = "ft_ressource_in", referencedColumnName = "rt_id")
private RessourceType ressourceIn;

View File

@@ -0,0 +1,9 @@
package bzh.risotto.galactik.api.model;
public interface Item {
public long getId();
public Item copy();
}

View File

@@ -11,7 +11,7 @@ public class Module {
@Id
@Column(name = "m_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private long id;
@Column(name = "m_name")
private String name;

View File

@@ -12,7 +12,7 @@ public class Planet {
@Id
@Column(name = "p_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private long id;
@Column(name = "p_name")
private String name;

View File

@@ -11,12 +11,12 @@ public class Ressource {
@Id
@Column(name = "r_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private long id;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "r_type", referencedColumnName = "rt_id")
private RessourceType type;
@Column(name = "r_quantity")
private Integer quantity;
private int quantity;
}

View File

@@ -10,7 +10,7 @@ public class RessourceType {
@Id
@Column(name = "rt_id")
private Long id;
private long id;
@Column(name = "rt_name")
private String name;

View File

@@ -2,24 +2,29 @@ package bzh.risotto.galactik.api.model;
import jakarta.persistence.*;
import lombok.Data;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import java.util.List;
@Entity
@Data
@Table(name = "ship")
public class Ship {
public class Ship implements Item {
@Id
@Column(name = "s_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private long id;
@Column(name = "s_name")
private String name;
@Column(name = "s_propritary")
private long proprietary;
@Column(name = "s_value")
private float value;
private int value;
@Column(name = "s_size")
private int size;
@@ -31,6 +36,7 @@ public class Ship {
private float speed;
@OneToMany()
@Fetch(FetchMode.JOIN)
@JoinTable(
name = "ship_modules",
joinColumns = @JoinColumn(name = "sm_ship_id"),
@@ -39,5 +45,20 @@ public class Ship {
List<Module> modules;
@Column(name = "s_planet")
private int planet;
private Integer planet;
@Override
public Item copy() {
Ship ship = new Ship();
ship.setName(this.name);
ship.setProprietary(this.proprietary);
ship.setModules(this.modules);
ship.setPlanet(this.planet);
ship.setValue(this.value);
ship.setSize(this.size);
ship.setPower(this.power);
ship.setSpeed(this.speed);
return ship;
}
}

View File

@@ -13,16 +13,16 @@ public class Star {
@Id
@Column(name = "st_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private long id;
@Column(name = "st_name")
private String name;
@Column(name = "pos_x")
private Double posX;
private double posX;
@Column(name = "pos_y")
private Double posY;
private double posY;
@OneToMany()
@JoinColumn(name = "p_star")

View File

@@ -1,11 +1,15 @@
package bzh.risotto.galactik.api.service;
import bzh.risotto.galactik.api.model.Corpo;
import bzh.risotto.galactik.api.exceptions.CorpoNotFoundException;
import bzh.risotto.galactik.api.exceptions.NotEnoughtRessourceException;
import bzh.risotto.galactik.api.exceptions.RessourceNotFoundException;
import bzh.risotto.galactik.api.model.*;
import bzh.risotto.galactik.api.repository.CorpoRepository;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Data
@@ -14,16 +18,86 @@ public class CorpoService {
private final CorpoRepository corpoRepository;
private FacilityService facilityService;
private ShipService shipService;
@Autowired
public CorpoService(CorpoRepository corpoRepository) {
public CorpoService(CorpoRepository corpoRepository, FacilityService facilityService, ShipService shipService) {
this.corpoRepository = corpoRepository;
this.facilityService = facilityService;
this.shipService = shipService;
}
public Iterable<Corpo> getCorpos() {
return this.corpoRepository.findAll();
}
public Optional<Corpo> getCorpo(Long id) {
return this.corpoRepository.findById(id);
public Corpo getCorpo(long id) {
Optional<Corpo> res = this.corpoRepository.findById(id);
if (res.isEmpty()) {
throw new CorpoNotFoundException(id);
}
return res.get();
}
public void addFacilities(Facility facility, long corpoId) {
Corpo corpo = this.getCorpo(corpoId);
facility.setCorpo(corpoId);
List<Facility> facilities = corpo.getFacilities();
facilities.add(facility);
corpo.setFacilities(facilities);
this.facilityService.save(facility);
this.corpoRepository.save(corpo);
}
public void addShip(Ship ship, long corpoId) {
Corpo corpo = this.getCorpo(corpoId);
ship.setProprietary(corpoId);
List<Ship> ships = corpo.getShips();
ships.add(ship);
corpo.setShips(ships);
this.shipService.save(ship);
this.corpoRepository.save(corpo);
}
public boolean updateRessource(long ressourceId, int value, long corpoId) {
boolean res = false;
Corpo corpo = this.getCorpo(corpoId);
Ressource ressource = null;
for (Ressource r : corpo.getRessources()) {
if (ressourceId == r.getId()) {
ressource = r;
}
}
if (ressource == null) {
throw new RessourceNotFoundException("ressource :" + ressourceId + "not found for corpo: " + corpoId);
}
if (ressource.getQuantity() <= value) {
throw new NotEnoughtRessourceException(ressourceId, corpoId);
}
else {
res = true;
// edit qt by reference
ressource.setQuantity(ressource.getQuantity() + value);
}
corpoRepository.save(corpo);
return res;
}
}

View File

@@ -23,8 +23,13 @@ public class FacilityService {
return this.facilityRepository.findAll();
}
public Optional<Facility> getFacility(Long id) {
public Optional<Facility> getFacility(long id) {
return this.facilityRepository.findById(id);
}
public void save(Facility facility) {
this.facilityRepository.save(facility);
}
}

View File

@@ -0,0 +1,88 @@
package bzh.risotto.galactik.api.service;
import bzh.risotto.galactik.api.exceptions.FacilityNotFoundException;
import bzh.risotto.galactik.api.exceptions.ShipNotFoundException;
import bzh.risotto.galactik.api.model.Corpo;
import bzh.risotto.galactik.api.model.Facility;
import bzh.risotto.galactik.api.model.Item;
import bzh.risotto.galactik.api.model.Ship;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.crossstore.ChangeSetPersister;
import org.springframework.stereotype.Service;
import javax.swing.text.html.parser.Entity;
import java.util.List;
import java.util.Optional;
@Data
@Service
public class MarketService {
private CorpoService corpoService;
private Long marketCorpoId;
private Corpo marketCorpo;
@Autowired
public MarketService(CorpoService corpoService) {
this.corpoService = corpoService;
this.marketCorpoId = 1L;
this.marketCorpo = corpoService.getCorpo(marketCorpoId);
}
public List<Facility> getFacilities() {
return this.marketCorpo.getFacilities();
}
public Facility buyFacilities(long facilityId, long corpoId) {
List<Facility> facilities = this.marketCorpo.getFacilities();
Facility facility = findItem(facilities, facilityId);
if (facility == null) {
throw new FacilityNotFoundException("Facility not found (" + facilityId + ") in corpo (" + this.marketCorpoId + ")");
}
boolean status = corpoService.updateRessource(4, -facility.getFacilityType().getValue(), corpoId);
if (status) {
corpoService.addFacilities(facility, corpoId);
}
return facility;
}
public List<Ship> getShips() {
return this.marketCorpo.getShips();
}
public Ship buyShip(long shipId, long corpoId) {
List<Ship> ships = this.marketCorpo.getShips();
Ship ship = this.findItem(ships, shipId);
if (ship == null) {
throw new ShipNotFoundException(shipId);
}
boolean status = corpoService.updateRessource(4, -ship.getValue(), corpoId);
if (status) {
corpoService.addShip(ship, corpoId);
}
return ship;
}
private <C extends Item> C findItem(List<C> items, long itemId) {
C item = null;
for (C i : items) {
if (itemId == i.getId()) {
item = (C) i.copy();
}
}
return item;
}
}

View File

@@ -24,7 +24,7 @@ public class ModuleService {
return this.moduleRepository.findAll();
}
public Optional<Module> getModule(Long id) {
public Optional<Module> getModule(long id) {
return this.moduleRepository.findById(id);
}
}

View File

@@ -23,7 +23,7 @@ public class PlanetService {
return this.planetRepository.findAll();
}
public Optional<Planet> getPlanet(Long id) {
public Optional<Planet> getPlanet(long id) {
return this.planetRepository.findById(id);
}
}

View File

@@ -23,7 +23,7 @@ public class RessourceService {
return this.ressourceRepository.findAll();
}
public Optional<Ressource> getRessource(Long id) {
public Optional<Ressource> getRessource(long id) {
return this.ressourceRepository.findById(id);
}

View File

@@ -23,8 +23,11 @@ public class ShipService {
return this.shipRepository.findAll();
}
public Optional<Ship> getShip(Long id) {
public Optional<Ship> getShip(long id) {
return this.shipRepository.findById(id);
}
public void save(Ship ship) {
this.shipRepository.save(ship);
}
}

View File

@@ -23,7 +23,7 @@ public class StarService {
return starRepository.findAll();
}
public Optional<Star> getStar(Long id) {
public Optional<Star> getStar(long id) {
return starRepository.findById(id);
}
}

View File

@@ -6,6 +6,14 @@ server.port=8081
# spring security
spring.profiles.active=dev
spring.mvc.log-request-details=true
# log
logging.level.root=debug
logging.level.risotto=debug
logging.level.org.springframework.boot.autoconfigure.tomcat=debug
logging.level.org.springframework.boot.autoconfigure.sql=debug
# sql
spring.datasource.url=jdbc:mysql://localhost:3306/galactifeur
spring.datasource.username=gltk_user