From 811632b6933bbb5bc8ed82d636de196491a452cd Mon Sep 17 00:00:00 2001 From: Julia Butenhoff Date: Tue, 19 Jul 2022 09:16:20 -0500 Subject: [PATCH] Save profile and save profile part - Need testing --- pom.xml | 5 ++ .../ArkOne/ArkOneController.java | 6 ++ .../ArkOne/Plugins/GalaxyPlugin.java | 77 ++++++++++++++++++- .../UBFunkeysServer/service/FileService.java | 2 +- .../service/impl/FileServiceImpl.java | 5 +- .../javagrinko/spring/tcp/Connection.java | 5 ++ .../javagrinko/spring/tcp/TcpConnection.java | 23 +++++- 7 files changed, 118 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index aea6ec8..1c7c280 100644 --- a/pom.xml +++ b/pom.xml @@ -76,6 +76,11 @@ spring-boot-configuration-processor true + + org.springframework + spring-test + 5.3.20 + diff --git a/src/main/java/com/icedberries/UBFunkeysServer/ArkOne/ArkOneController.java b/src/main/java/com/icedberries/UBFunkeysServer/ArkOne/ArkOneController.java index eb84357..423cd74 100644 --- a/src/main/java/com/icedberries/UBFunkeysServer/ArkOne/ArkOneController.java +++ b/src/main/java/com/icedberries/UBFunkeysServer/ArkOne/ArkOneController.java @@ -95,6 +95,12 @@ public class ArkOneController implements TcpHandler { case "vsu": responses.add(galaxyPlugin.VersionStatisticsRequest()); break; + case "sp": + responses.add(galaxyPlugin.SaveProfile(commandInfo, connection)); + break; + case "spp": + responses.add(galaxyPlugin.SaveProfilePart(commandInfo, connection)); + break; // Plugin 10 (Trunk) diff --git a/src/main/java/com/icedberries/UBFunkeysServer/ArkOne/Plugins/GalaxyPlugin.java b/src/main/java/com/icedberries/UBFunkeysServer/ArkOne/Plugins/GalaxyPlugin.java index a639fb5..6328bea 100644 --- a/src/main/java/com/icedberries/UBFunkeysServer/ArkOne/Plugins/GalaxyPlugin.java +++ b/src/main/java/com/icedberries/UBFunkeysServer/ArkOne/Plugins/GalaxyPlugin.java @@ -1,16 +1,91 @@ package com.icedberries.UBFunkeysServer.ArkOne.Plugins; +import com.icedberries.UBFunkeysServer.ArkOne.ArkOneParser; +import com.icedberries.UBFunkeysServer.service.FileService; +import javagrinko.spring.tcp.Connection; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.mock.web.MockMultipartFile; import org.springframework.stereotype.Service; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; +import java.io.IOException; +import java.io.StringReader; @Service public class GalaxyPlugin { + @Autowired + FileService fileService; + public String LoadProfileVersion() { - //TODO: IMPLEMENT THIS WITH PROFILE SAVING + //TODO: IMPLEMENT THIS AFTER PROFILE SAVING return ""; } public String VersionStatisticsRequest() { return ""; } + + public String SaveProfile(Element element, Connection connection) { + // Set the number of chunks left to save + //TODO: VERIFY THIS ATTRIBUTE NAME + connection.setChunksLeft(Integer.valueOf(element.getAttribute("c"))); + + // Clear save data + connection.setSaveData(""); + + return ""; + } + + public String SaveProfilePart(Element element, Connection connection) throws ParserConfigurationException, + TransformerException, IOException, SAXException { + // Start of response + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document resp = dBuilder.newDocument(); + Element rootElement = resp.createElement("h7_0"); + resp.appendChild(rootElement); + + // Continue appending to the saveData + //TODO: VERIFY THIS ELEMENT ATTRIBUTE + connection.setSaveData(element.getAttribute("v") + connection.getSaveData()); + + if (connection.getChunksLeft() == 1) { + Element subElement = resp.createElement("sp"); + + // Parse the current save + Document save = dBuilder.parse(new InputSource(new StringReader(connection.getSaveData()))); + save.getDocumentElement().normalize(); + Element rootSave = (Element)save.getFirstChild(); + + String profileName = rootSave.getAttribute("gname"); + if (!rootSave.getAttribute("sid").equals("")) { + subElement.setAttribute("v", String.valueOf(Integer.parseInt(rootSave.getAttribute("sid")) + 1)); + } else { + subElement.setAttribute("v", "1"); + } + + // Write to file + fileService.save(new MockMultipartFile("profile", "profile", "text/xml", connection.getSaveData().getBytes()), + profileName); + + rootElement.appendChild(subElement); + } else { + Element subElement = resp.createElement("rr"); + rootElement.appendChild(subElement); + + // Decrease the number of chunks by 1 + connection.setChunksLeft(connection.getChunksLeft() - 1); + } + + // Build response + return ArkOneParser.RemoveXMLTag(resp); + } } diff --git a/src/main/java/com/icedberries/UBFunkeysServer/service/FileService.java b/src/main/java/com/icedberries/UBFunkeysServer/service/FileService.java index 2cc5283..60d7d58 100644 --- a/src/main/java/com/icedberries/UBFunkeysServer/service/FileService.java +++ b/src/main/java/com/icedberries/UBFunkeysServer/service/FileService.java @@ -5,7 +5,7 @@ import org.springframework.web.multipart.MultipartFile; public interface FileService { - void save(MultipartFile file); + void save(MultipartFile file, String subDir); Resource load(String filename); } diff --git a/src/main/java/com/icedberries/UBFunkeysServer/service/impl/FileServiceImpl.java b/src/main/java/com/icedberries/UBFunkeysServer/service/impl/FileServiceImpl.java index 0f9f9ff..fc9a3ee 100644 --- a/src/main/java/com/icedberries/UBFunkeysServer/service/impl/FileServiceImpl.java +++ b/src/main/java/com/icedberries/UBFunkeysServer/service/impl/FileServiceImpl.java @@ -13,6 +13,7 @@ import java.net.MalformedURLException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; @Service public class FileServiceImpl implements FileService { @@ -26,9 +27,9 @@ public class FileServiceImpl implements FileService { } @Override - public void save(MultipartFile file) { + public void save(MultipartFile file, String subDir) { try { - Files.copy(file.getInputStream(), fileStorageLocation.resolve(file.getOriginalFilename())); + Files.copy(file.getInputStream(), fileStorageLocation.resolve(subDir).resolve(file.getOriginalFilename()), StandardCopyOption.REPLACE_EXISTING); } catch(Exception e) { throw new RuntimeException("Could not store the file. Error: " + e.getMessage()); } diff --git a/src/main/java/javagrinko/spring/tcp/Connection.java b/src/main/java/javagrinko/spring/tcp/Connection.java index b37d7fe..ebd8604 100644 --- a/src/main/java/javagrinko/spring/tcp/Connection.java +++ b/src/main/java/javagrinko/spring/tcp/Connection.java @@ -13,6 +13,11 @@ public interface Connection { void close() throws IOException; UUID getClientIdentifier(); void setClientIdentifier(UUID newId); + Integer getChunksLeft(); + void setChunksLeft(Integer chunksLeft); + + String getSaveData(); + void setSaveData(String saveData); interface Listener { void messageReceived(Connection connection, byte[] bytes) throws InvocationTargetException, IllegalAccessException; diff --git a/src/main/java/javagrinko/spring/tcp/TcpConnection.java b/src/main/java/javagrinko/spring/tcp/TcpConnection.java index 0c6e40f..be3a862 100644 --- a/src/main/java/javagrinko/spring/tcp/TcpConnection.java +++ b/src/main/java/javagrinko/spring/tcp/TcpConnection.java @@ -20,8 +20,9 @@ public class TcpConnection implements Connection { private OutputStream outputStream; private Socket socket; private List listeners = new CopyOnWriteArrayList<>(); - private UUID clientIdentifier = null; + private Integer chunksLeft = 0; + private String saveData = ""; TcpConnection(Socket socket) { this.socket = socket; @@ -106,4 +107,24 @@ public class TcpConnection implements Connection { public void setClientIdentifier(UUID newId) { this.clientIdentifier = newId; } + + @Override + public Integer getChunksLeft() { + return chunksLeft; + } + + @Override + public void setChunksLeft(Integer chunksLeft) { + this.chunksLeft = chunksLeft; + } + + @Override + public String getSaveData() { + return saveData; + } + + @Override + public void setSaveData(String saveData) { + this.saveData = saveData; + } }