603 lines
31 KiB
Java

package at.reisinger.server.objects;
import at.reisinger.obj.*;
import at.reisinger.obj.Package;
import at.reisinger.server.DBConnection;
import at.reisinger.server.helper.JsonHelper;
import at.reisinger.server.helper.ResponseHelper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.PrintStream;
import java.util.*;
/**
* Erstellt und sendet eine Response anhand des Requests
* @author Georg Reisinger
*/
public class Response {
private final PrintStream out;
private final String url;
private final String payload;
private final String authString;
/**
* Nimmt die Daten des requests und generiert eine Response
* @param url Request Url
* @param cmd Request CMD
* @param out out Print Stream
* @param authString Der MsgHandler
* @param payload Payload des Requests
*/
public Response(String url, String cmd, PrintStream out, String authString, String payload){
this.authString = authString;
this.url = url;
this.out = out;
this.payload = payload;
if (this.url != null) {
switch (cmd) {
case "GET":
if (login()) {
getMethodes();
} else {
sendResponse("Login Error", "401");
}
break;
case "POST":
try {
postMethodes();
} catch (JsonProcessingException e) {
e.printStackTrace();
}
break;
case "PUT":
if (login()) {
putMethodes();
} else {
sendResponse("Login Error", "401");
}
break;
case "DELETE":
if (login()) {
deleteMethodes();
} else {
sendResponse("Login Error", "401");
}
break;
default:
sendResponse("", "405");
break;
}
}
}
/**
* Alle Get Methoden
* Nur für angemeldete user erreichbar
*/
private void getMethodes(){
if (this.url.startsWith("/users")) {
String username = this.url.substring(this.url.lastIndexOf('/') + 1);
User user;
user = new DBConnection().getUser(username);
if (user != null){
String userJson = JsonHelper.userToJson(user);
if(userJson != null && !userJson.isEmpty()){
sendResponse(userJson, "200");
}
}else{
sendResponse("", "500");
}
} else if (this.url.startsWith("/cards")) {
String username = basicAuthGetUsername(this.authString);
Cards allCards = new DBConnection().getCards(username);
String jsonCards = JsonHelper.objToJson(allCards);
if (jsonCards != null && !jsonCards.isEmpty()){
sendResponse(jsonCards, "200");
}else{
sendResponse("", "500");
}
}else if(this.url.startsWith("/deck")) {
String format = this.url.substring(this.url.lastIndexOf('?') + 1);
String username = basicAuthGetUsername(this.authString);
ArrayList<String> allCards = new DBConnection().getDeck(username);
Cards deck;
Object tmp;
if(format.startsWith("format=plain")){
tmp = allCards;
}else{
deck = new DBConnection().getCardsFromIDList(allCards);
tmp = deck;
}
String jsonCards = JsonHelper.objToJson(tmp);
if (jsonCards != null && !jsonCards.isEmpty()) {
sendResponse(jsonCards, "200");
} else {
sendResponse("", "500");
}
}else if(this.url.startsWith("/tradings")) {
ArrayList<TradingDeal> allDeals = new DBConnection().getAllTradingDeals();
if(allDeals != null && !allDeals.isEmpty()){
String json = JsonHelper.objToJson(allDeals);
if(json != null && !json.equals("")){
sendResponse(json, "200");
}else{
sendResponse("", "500");
}
}else{
sendResponse("", "500");
}
}else if(this.url.startsWith("/score")) {
String username = basicAuthGetUsername(this.authString);
if (username != null && !username.isEmpty()){
int lastBallteId = new DBConnection().getLastBattleIdUser(username);
if (lastBallteId > -1){
Map<String, String> map = new DBConnection().getBattleLog(lastBallteId + "");
if(map != null && !map.isEmpty()){
sendResponse("BATTLE #" + map.get("id") + "\nSCORE\n" + map.get("playerone") + "(#Player1) |vs| " + map.get("playertwo") + "(#Player2) \n" + map.get("playeronescore") + "(#Player1) |vs| " + map.get("playertwoscore") + "(#Player2) \nGame LOG:\n" + ResponseHelper.logLineBreak(map.get("log")), "200");
}else {
sendResponse("Konnte Battle log nicht holen", "500");
}
}else {
sendResponse("Last Battle ID error", "500");
}
}else{
sendResponse("Login Error", "401");
}
}else if(this.url.startsWith("/stats")) {
String username = basicAuthGetUsername(this.authString);
if (username != null && !username.isEmpty()) {
ArrayList<String> battleIds = new DBConnection().getAllBattleIdUser(username);
if (battleIds != null && !battleIds.isEmpty()){
StringBuilder resString = new StringBuilder();
for(String i : battleIds){
Map<String, String> map = new DBConnection().getBattleLog(i + "");
if(map != null && !map.isEmpty()){
resString = new StringBuilder("BATTLE #" + map.get("id") + "\nSCORE\n" + map.get("playerone") + "(#Player1) |vs| " + map.get("playertwo") + "(#Player2) \n" + map.get("playeronescore") + "(#Player1) |vs| " + map.get("playertwoscore") + "(#Player2) \nGame LOG:\n");
resString.append(ResponseHelper.logLineBreak(map.get("log")));
}else {
sendResponse("Konnte Battle log nicht holen", "500");
}
}
sendResponse(resString.toString(), "200");
}else {
sendResponse("Konnte Battle ids ned holen", "500");
}
}else{
sendResponse("Login Error", "401");
}
}else{
sendResponse("", "204");
}
}
/**
* Vergleicht das angegebene PW mit dem gespeicherten PW, True wenn richtig
* @param username User aus DB
* @param password PW zu User aus DB
* @param compareTo Base64 String von Basic Auth
* @return True if Login is correct, false if incorrect
*/
private boolean basicAuth(String username, String password, String compareTo){
String authStringEnc = basicAuthBase64(username, password);
return compareTo.equals(authStringEnc);
}
/**
* Erstellt den basicAuth Base64 Token aus Username und Passwort
* @param username Username für den Token
* @param password Passwort für den Token
* @return Der Base64 BasicAtuth String
*/
private String basicAuthBase64(String username, String password){
String authString = username + ":" + password;
byte[] authEncBytes = Base64.getEncoder().encode(authString.getBytes());
return new String(authEncBytes);
}
/**
* Aus dem Base64 BasicAuth String wird der Username extrahiert
* @param authString Base64 BasicAuth String aus dem der Username ausgelesen werden soll
* @return Der Username der in dem Base64 BasicAuth String ist
*/
private String basicAuthGetUsername(String authString) {
String[] values;
if (authString != null) {
byte[] credDecoded = Base64.getDecoder().decode(authString);
String credentials = new String(credDecoded);
values = credentials.split(":", 2);
}else{
values = null;
}
return Objects.requireNonNull(values)[0];
}
/**
* Alle Post Methoden, siehe API beschreibung für genauere details
*
* Kann auch von nicht angemeldeten usern erreicht werden.
* login() wird hier verwendet
* @throws JsonProcessingException Fehler beim de-/serialisieren
*/
private void postMethodes() throws JsonProcessingException {
if (this.url.startsWith("/users")) {
Map<String, Object> map = JsonHelper.jsonPayloadToMap(this.payload);
String username = (String) Objects.requireNonNull(map).get("Username");
String password = (String) map.get("Password");
User newUser = new User(new Credentials(username, password), username, username, "not implemented", new Coins(20), "BIO", "IMAGE");
DBConnection con = new DBConnection();
if(!con.addUser(newUser.getCredentials().getUsername(), newUser.getCredentials().getPasswort(), newUser.getCredentials().getUsername(), newUser.getEmail(), newUser.getBio(), newUser.getImage())){
sendResponse("", "409");
}
String userJson = JsonHelper.userToJson(newUser);
if(userJson != null) {
sendResponse(userJson, "201");
}else{
sendResponse("", "500");
}
}else if (this.url.startsWith("/sessions")) {
Map<String, Object> map = JsonHelper.jsonPayloadToMap(this.payload);
String username = (String) Objects.requireNonNull(map).get("Username");
String password = (String) map.get("Password");
User user;
DBConnection con = new DBConnection();
user = con.getUser(username);
String authString = basicAuthBase64(user.getCredentials().getUsername(), user.getCredentials().getPasswort());
if(basicAuth(username, password, authString)){
sendResponse(authString, "200");
}else{
sendResponse("Login Error", "401");
}
}else if (this.url.startsWith("/packages")) {
if (basicAuth("admin", "istrator", this.authString)) {
ObjectMapper objectMapper = new ObjectMapper();
ArrayList<Card> listCards = objectMapper.readValue(this.payload, new TypeReference<>() {
});
Package packageCards = new Package(new Cards(listCards), new DBConnection().nextPackageId() + "", 5);
if (!new DBConnection().addPackage(packageCards)) {
sendResponse("", "500");
} else {
String packageJson = JsonHelper.objToJson(packageCards);
if (packageJson != null) {
sendResponse(packageJson, "201");
} else {
sendResponse("", "500");
}
}
} else {
sendResponse("Login Error", "401");
}
}else if (this.url.startsWith("/transactions/packages")) {
if (login()) {
DBConnection db = new DBConnection();
Package newPackage = db.userAcquirePackage(basicAuthGetUsername(this.authString));
if (newPackage == null) {
sendResponse("", "500");
} else {
String packageJson = JsonHelper.objToJson(newPackage);
if (packageJson == null) {
sendResponse("", "500");
} else {
sendResponse(packageJson, "200");
}
}
}else{
sendResponse("Login Error", "401");
}
}else if (this.url.startsWith("/tradings")) {
if(login()) {
String dotradeid = this.url.substring(this.url.lastIndexOf('/') + 1);
if (!dotradeid.isEmpty() && !dotradeid.equals("tradings")) {
//DO TRADE
String username = basicAuthGetUsername(this.authString);
if (username != null && !username.isEmpty()) {
ArrayList<TradingDeal> tradingDealArrayList = new DBConnection().getAllTradingDeals();
TradingDeal tradingDeal = null;
if (tradingDealArrayList != null && !tradingDealArrayList.isEmpty()) {
for (TradingDeal tr : tradingDealArrayList) {
if (tr.getId().equals(dotradeid)) {
tradingDeal = tr;
}
}
Card card = new DBConnection().getCardFromID(this.payload);
if (card != null) {
if (tradingDeal != null) {
if (tradingDeal.cardOk(card)) {
String json = JsonHelper.objToJson(card);
if (json != null && !json.isEmpty()) {
if (new DBConnection().addUserCard(username, tradingDeal.getCardToTrade().getName())) {
if (new DBConnection().delUserCard(tradingDeal.getUsername(), tradingDeal.getCardToTrade().getName())) {
if (new DBConnection().deleteTradingDeal(tradingDeal.getId())) {
if (new DBConnection().delUserCard(username, card.getName())) {
if (new DBConnection().addUserCard(tradingDeal.getUsername(), card.getName())) {
sendResponse(json, "200");
} else {
sendResponse("ERROR --> Add Card to: " + tradingDeal.getUsername(), "500");
}
} else {
sendResponse("ERROR --> Del Card from: " + username, "500");
}
} else {
sendResponse("Error --> Del Trading Deal", "500");
}
} else {
sendResponse("ERROR --> Del Card from: " + tradingDeal.getUsername(), "500");
}
} else {
sendResponse("ERROR --> Add Card to: " + username, "500");
}
} else {
sendResponse("ERROR --> JSON Empty", "500");
}
} else {
sendResponse("ERROR --> Trading Deal not ok", "500");
}
} else {
sendResponse("ERROR --> Trading Deal not exist", "500");
}
} else {
sendResponse("ERROR --> Card not exist", "500");
}
} else {
sendResponse("ERROR --> Trading Deal not exist", "500");
}
} else {
sendResponse("ERROR --> Username empty", "401");
}
} else {
//CREATE TRADING DEAL
Map<String, Object> map = JsonHelper.jsonPayloadToMap(this.payload);
String id = (String) Objects.requireNonNull(map).get("Id");
String cardtotrade = (String) map.get("CardToTrade");
String type = (String) map.get("Type");
double mindamage = Double.parseDouble(map.get("MinimumDamage") + "");
String username = basicAuthGetUsername(this.authString);
if (username != null) {
Card cardtoTradeC = new DBConnection().getCardFromID(cardtotrade);
if (cardtoTradeC != null) {
TradingDeal tradingDeal = new TradingDeal(id, cardtoTradeC, mindamage, type, username);
String tradingJson = JsonHelper.objToJson(tradingDeal);
ArrayList<String> deckCards = new DBConnection().getDeck(username);
if (deckCards != null) {
if (deckCards.contains(cardtotrade)) {
new DBConnection().delDeck(username);
}
if (new DBConnection().addTradingdeal(tradingDeal.getUsername(), tradingDeal.getId(), tradingDeal.getRequiredMinDamage(), tradingDeal.getRequiredCardType().name(), tradingDeal.getRequiredElementType().name(), tradingDeal.getCardToTrade().getName())) {
if (new DBConnection().updateCardLock(tradingDeal.getCardToTrade().getName(), true)) {
sendResponse(Objects.requireNonNull(JsonHelper.objToJson(tradingDeal)), "201");
} else {
sendResponse("", "500");
}
} else {
sendResponse("", "500");
}
} else {
sendResponse("", "500");
}
sendResponse(Objects.requireNonNull(tradingJson), "201");
} else {
sendResponse("", "500");
}
} else {
sendResponse("", "500");
}
}
}
}else if (this.url.startsWith("/battle")) {
if(login()){
String username = basicAuthGetUsername(this.authString);
if (username != null && !username.isEmpty()) {
List<String> deckNamen = new DBConnection().getDeck(username);
if (deckNamen != null && !deckNamen.isEmpty()) {
Cards deck = new DBConnection().getCardsFromIDList(deckNamen);
if(deck != null && deck.getCards().size() == 4) {
Battle openBattle = new DBConnection().getOpenBattle();
if (openBattle == null) {
//Creator player Mode
if(new DBConnection().addBattle(username)){
sendResponse("Du bist: #PLAYER 1\nBattle Einladung wurde erstellt von: " + username + "(#PLAYER1) \nSobald ein 2. Spieler dem Battle beitritt, kann das ergebnis mit /score abgefragt werden.","200");
}else {
sendResponse("", "500");
}
} else {
//Join game player
User player2 = new DBConnection().getUser(username);
if(player2 != null){
openBattle.setPlayer2(player2);
openBattle.setDeckPlayer2(deck);
if(new DBConnection().delBattleEinladung(openBattle.getId() + "")) {
if (openBattle.doFight()){
System.out.println(JsonHelper.objToJson(openBattle.getLog().size()));
if (new DBConnection().addBattleLog(openBattle.getId() + "", openBattle.getPlayer1().getName(), openBattle.getPlayer2().getName(), openBattle.getScorePlayer1() + "", openBattle.getScorePlayer2() + "", openBattle.getLog().toString())) {
if (new DBConnection().delDeck(openBattle.getPlayer1().getCredentials().getUsername()) && new DBConnection().delDeck(openBattle.getPlayer2().getCredentials().getUsername())) {
//DEL OLD DECK CARDS
ArrayList<String> oldDeck1 = new ArrayList<>();
for (Card ca : openBattle.getDeckPlayer1Init().getCards()) {
oldDeck1.add(ca.getName());
}
ArrayList<String> oldDeck2 = new ArrayList<>();
for (Card ca : openBattle.getDeckPlayer2Init().getCards()) {
oldDeck2.add(ca.getName());
}
//DEL NEW CARDS IF EXIST
Cards player1cards = new DBConnection().getCards(openBattle.getPlayer1().getCredentials().getUsername());
for (Card ca : openBattle.getDeckPlayer1().getCards()) {
oldDeck1.add(ca.getName());
}
if (player1cards.getCards() != null && !player1cards.getCards().isEmpty()) {
for (String ca : oldDeck1) {
if (!new DBConnection().delUserCard(openBattle.getPlayer1().getCredentials().getUsername(), ca)) {
sendResponse("Error Deleting user card1: " + ca, "500");
}
}
}
Cards player2cards = new DBConnection().getCards(openBattle.getPlayer2().getCredentials().getUsername());
for (Card ca : openBattle.getDeckPlayer2().getCards()) {
oldDeck2.add(ca.getName());
}
if (player2cards.getCards() != null && !player2cards.getCards().isEmpty()) {
for (String ca : oldDeck2) {
if (!new DBConnection().delUserCard(openBattle.getPlayer2().getCredentials().getUsername(), ca)) {
sendResponse("Error Deleting user card2: " + ca, "500");
}
}
}
//ADD CARDS TO DECK
for (Card ca : openBattle.getDeckPlayer1().getCards()) {
if (!new DBConnection().addUserCard(openBattle.getPlayer1().getCredentials().getUsername(), ca.getName())) {
sendResponse("Error adding card to user1: " + ca.getName(), "500");
}
}
for (Card ca : openBattle.getDeckPlayer2().getCards()) {
if (!new DBConnection().addUserCard(openBattle.getPlayer2().getCredentials().getUsername(), ca.getName())) {
sendResponse("Error adding card to user2: " + ca.getName(), "500");
}
}
sendResponse("Du bist: #PLAYER 2\nBattle --> " + openBattle.getPlayer1().getName() + "(#PLAYER1) |vs| " + openBattle.getPlayer2().getName() + "(#PLAYER2)\nErgebnisse unter /score abrufbar", "200");
}
} else {
sendResponse("Battle Log konnte ned geschrieben werden", "500"); //ERROR
}
}else {
sendResponse("Battle konnte ned durchgeführt werden", "500");
}
}else{
sendResponse("Battle einladung konnte ned akzeptiert werden", "500"); //ERROR
}
}else{
sendResponse("GET User error", "500"); //ERROR
}
}
}else {
sendResponse("Nur "+ Objects.requireNonNull(deck).getCards().size()+" von 4 Karten im Deck. \nMach zuerst POST /deck [ID, ID, ID, ID] um dein Deck korrekt zu befüllen","424");
}
}else {
sendResponse("Deck ist nicht gesetzt","424");
}
}else {
sendResponse("", "500");
}
}else {
sendResponse("Login Error", "401");
}
} else{
sendResponse("", "405");
}
}
/**
* Prüft den Login, anhand des BasicAuth Base64 String
* @return True wenn login daten korrekt, sonst false
*/
private boolean login(){
if(this.authString != null && !this.authString.isEmpty()){
String username = basicAuthGetUsername(this.authString);
User user;
user = new DBConnection().getUser(username);
return basicAuth(user.getCredentials().getUsername(), user.getCredentials().getPasswort(), this.authString);
}else{
return false;
}
}
/**
* Alle Put Methoden
* Nur für angemeldete user erreichbar
*/
private void putMethodes(){
if (this.url.startsWith("/users")) {
String username = this.url.substring(this.url.lastIndexOf('/') + 1);
User user;
user = new DBConnection().getUser(username);
if(user != null) {
Map<String, Object> map = JsonHelper.jsonPayloadToMap(this.payload);
String bio = (String) Objects.requireNonNull(map).get("Bio");
String image = (String) map.get("Image");
String name = (String) map.get("Name");
user.setBio(bio);
user.setImage(image);
user.setNachname(name);
if (new DBConnection().updateUser(username, user.getBio(), user.getImage(), user.getNachname())) {
sendResponse(JsonHelper.userToJson(user), "200");
} else {
sendResponse("", "500");
}
}else{
sendResponse("", "500");
}
}else if(this.url.startsWith("/deck")) {
List<String> deckIds = JsonHelper.jsonPayloadToList(this.payload);
if (deckIds != null && deckIds.size() == 4){
if (new DBConnection().setDeck(basicAuthGetUsername(this.authString), deckIds)){
Cards deck = new DBConnection().getCardsFromIDList(deckIds);
String deckJson = JsonHelper.objToJson(deck);
if (deck != null && deckJson != null){
sendResponse(deckJson, "200");
}else {
sendResponse("", "500");
}
}else {
sendResponse("", "500");
}
}else{
sendResponse(Objects.requireNonNull(deckIds).size() + " von 4 Karten sind im Deck.","500");
}
}
}
/**
* Alle Delete Methoden, siehe API beschreibung für genauere details
* Nur für angemeldete user erreichbar
*/
private void deleteMethodes(){
if (this.url.startsWith("/tradings")) {
String tradeid = this.url.substring(this.url.lastIndexOf('/') + 1);
ArrayList<TradingDeal> allTradingDeals = new DBConnection().getAllTradingDeals();
TradingDeal tr = null;
if (allTradingDeals != null && !allTradingDeals.isEmpty()) {
for (TradingDeal i : allTradingDeals) {
if (i.getId().equals(tradeid)) {
tr = i;
}
}
if (tr != null) {
if (new DBConnection().deleteTradingDeal(tradeid)) {
if (new DBConnection().updateCardLock(tr.getCardToTrade().getName(), false))
sendResponse("", "204");
} else {
sendResponse("", "500");
}
}else{
sendResponse("", "500");
}
}
}
}
/**
* Sendet eine Response
* @param responseText Text der zu senden ist
* @param code Http code
*/
private void sendResponse(String responseText, String code){
out.print("HTTP/1.0 "+code+"\r\n");
out.print("Server: Apache/0.8.4\r\n");
out.print("Content-Type: text/plain\r\n");
out.print("Content-Length: "+responseText.length()+"\r\n");
out.print("\r\n");
out.print(responseText);
}
}