safedata viewer
This commit is contained in:
parent
c22481fcf0
commit
4c041a8969
12 changed files with 413 additions and 4 deletions
5
.settings/org.eclipse.core.resources.prefs
Normal file
5
.settings/org.eclipse.core.resources.prefs
Normal file
|
@ -0,0 +1,5 @@
|
|||
eclipse.preferences.version=1
|
||||
encoding//src/test/java=UTF-8
|
||||
encoding//src/test/resources=UTF-8
|
||||
encoding/<project>=UTF-8
|
||||
encoding/src=UTF-8
|
11
pom.xml
11
pom.xml
|
@ -52,7 +52,16 @@
|
|||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.2.13</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.15</version> <!-- oder die neueste Version -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>31.0.1-jre</version> <!-- oder die neueste Version -->
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
|
|
|
@ -67,7 +67,7 @@ public class GuiData {
|
|||
|
||||
public void IndexData(ArrayList<String> migrate) throws IOException {
|
||||
DatabaseManager mgr = new DatabaseManager();
|
||||
mgr.queryData("levels");
|
||||
|
||||
|
||||
File filelength = new File("C:\\ExtremeDemonList\\levels");
|
||||
File[] filelengthindex = filelength.listFiles();
|
||||
|
|
68
src/gui/AttemptsProgress.java
Normal file
68
src/gui/AttemptsProgress.java
Normal file
|
@ -0,0 +1,68 @@
|
|||
package gui;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
|
||||
import data.FetchData;
|
||||
import data.ManageFiles;
|
||||
|
||||
public class AttemptsProgress {
|
||||
|
||||
JProgressBar bar = new JProgressBar();
|
||||
JTextArea area = new JTextArea();
|
||||
JScrollPane scroll = new JScrollPane(area);
|
||||
JFrame main = new JFrame("Updater");
|
||||
|
||||
|
||||
public void build() {
|
||||
|
||||
|
||||
main.setSize(400, 300);
|
||||
main.setLayout(null);
|
||||
main.setResizable(false);
|
||||
main.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
||||
|
||||
JLabel info = new JLabel("Speicherstand wird gelesen...");
|
||||
info.setBounds(120, 1, 500, 30);
|
||||
|
||||
|
||||
area.setEditable(false);
|
||||
area.setLineWrap(true);
|
||||
area.setWrapStyleWord(true);
|
||||
|
||||
|
||||
|
||||
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
|
||||
scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||
scroll.setBounds(1, 60, 383, 201);
|
||||
|
||||
FetchData data = new FetchData();
|
||||
|
||||
bar.setBounds(1, 29, 382, 30);
|
||||
bar.setMinimum(0);
|
||||
bar.setMaximum(data.allLevels().size() - 1);
|
||||
bar.setStringPainted(true);
|
||||
|
||||
main.add(info);
|
||||
main.add(scroll);
|
||||
main.add(bar);
|
||||
main.setVisible(true);
|
||||
|
||||
}
|
||||
|
||||
public void update(String level, int attempts, int selection, int index) {
|
||||
bar.setValue(index);
|
||||
area.append(level + " >>> " + attempts + " Attempts\n");
|
||||
area.setCaretPosition(area.getDocument().getLength());
|
||||
}
|
||||
|
||||
public void close() {
|
||||
JOptionPane.showMessageDialog(null, "Attempts wurden erfolgreich übertragen.", "Fertig", JOptionPane.INFORMATION_MESSAGE);
|
||||
main.dispose();
|
||||
}
|
||||
|
||||
}
|
|
@ -229,7 +229,11 @@ public class MainGUI {
|
|||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
data.modifyData(data.getLevelname().get(index), comp[index], Integer.parseInt(attempts.getText()));
|
||||
if(!(comp[index] == Boolean.parseBoolean(data.getCompleted().get(index))) || !(attempts.getText().equals(data.getAttempts().get(index) + ""))) {
|
||||
data.modifyData(data.getLevelname().get(index), comp[index], Integer.parseInt(attempts.getText()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(!comp[index]) {
|
||||
contents.setBackground(Color.WHITE);
|
||||
|
|
|
@ -1,6 +1,17 @@
|
|||
package gui;
|
||||
|
||||
import java.awt.Button;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import readsafefile.SafeFileManager;
|
||||
import settingsfunctions.ReadAttempts;
|
||||
|
||||
public class SettingsGui {
|
||||
|
||||
|
@ -12,6 +23,78 @@ public class SettingsGui {
|
|||
settings.setSize(500, 500);
|
||||
settings.setVisible(true);
|
||||
|
||||
int val = 120;
|
||||
int valold = 20;
|
||||
|
||||
StringBuilder str = new StringBuilder();
|
||||
|
||||
int jbuffer = 0;
|
||||
|
||||
for(int i = 0; i <= 3; i++) {
|
||||
for(int j = 0; j <= 100; j++) {
|
||||
str.append("_");
|
||||
jbuffer = j;
|
||||
}
|
||||
JLabel separator = new JLabel(str.toString());
|
||||
separator.setBounds(0, valold, 500, 30);
|
||||
separator.setVisible(true);
|
||||
settings.add(separator);
|
||||
|
||||
valold += val;
|
||||
|
||||
str.delete(0, jbuffer);
|
||||
}
|
||||
|
||||
JLabel datenbank = new JLabel("Spielstand");
|
||||
datenbank.setBounds(1, 10, 100, 30);
|
||||
datenbank.setFont(new Font(null, Font.BOLD, 16));
|
||||
datenbank.setVisible(true);
|
||||
|
||||
JLabel data = new JLabel("Datenbank");
|
||||
data.setBounds(1, 130, 100, 30);
|
||||
data.setFont(new Font(null, Font.BOLD, 16));
|
||||
|
||||
Button refresh = new Button("Speicherstand neu laden");
|
||||
refresh.setBounds(250, 86, 150, 30);
|
||||
refresh.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
SafeFileManager mgr = new SafeFileManager();
|
||||
try {
|
||||
mgr.DecryptSafeFile();
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Button button = new Button("Attempts Indexieren");
|
||||
button.setBounds(60, 86, 150, 30);
|
||||
button.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
ReadAttempts atts = new ReadAttempts();
|
||||
try {
|
||||
atts.readAttempts();
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Button delete = new Button("Datenbank löschen");
|
||||
delete.setBounds(150, 206, 150, 30);
|
||||
|
||||
settings.add(button);
|
||||
settings.add(datenbank);
|
||||
settings.add(refresh);
|
||||
settings.add(data);
|
||||
settings.add(delete);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package main;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.zip.DataFormatException;
|
||||
|
||||
import data.FetchData;
|
||||
import data.ManageFiles;
|
||||
|
@ -8,11 +9,14 @@ import database.DatabaseManager;
|
|||
import filestructure.CreateFileStructure;
|
||||
import gui.LoadMenu;
|
||||
import preload.PreChecks;
|
||||
import readsafefile.DecryptXOR;
|
||||
import readsafefile.ReadAttemptsFromXML;
|
||||
import readsafefile.SafeFileManager;
|
||||
import settingsfunctions.LoadSettings;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
public static void main(String[] args) throws IOException, DataFormatException {
|
||||
|
||||
LoadMenu load = new LoadMenu();
|
||||
load.onLoad();
|
||||
|
|
|
@ -8,4 +8,6 @@
|
|||
requires jdash.common;
|
||||
requires jlayer;
|
||||
requires java.sql;
|
||||
requires java.xml;
|
||||
requires org.apache.commons.codec;
|
||||
}
|
67
src/readsafefile/DecryptXOR.java
Normal file
67
src/readsafefile/DecryptXOR.java
Normal file
|
@ -0,0 +1,67 @@
|
|||
package readsafefile;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.zip.DataFormatException;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.Inflater;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
public class DecryptXOR {
|
||||
|
||||
private static final String[] SAVES = {"CCGameManager.dat"};
|
||||
private static final int XOR_KEY = 11;
|
||||
|
||||
private static byte[] xor(byte[] data, int key) {
|
||||
byte[] result = new byte[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
result[i] = (byte) (data[i] ^ key);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static byte[] decrypt(String data) throws IOException {
|
||||
byte[] decodedData = Base64.decodeBase64(data.replace('-', '+').replace('_', '/'));
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream(decodedData);
|
||||
GZIPInputStream gzipInputStream = new GZIPInputStream(bis);
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[1024];
|
||||
int bytesRead;
|
||||
while ((bytesRead = gzipInputStream.read(buffer)) != -1) {
|
||||
bos.write(buffer, 0, bytesRead);
|
||||
}
|
||||
gzipInputStream.close();
|
||||
bis.close();
|
||||
bos.close();
|
||||
return bos.toByteArray();
|
||||
}
|
||||
|
||||
public static void decryptAndWriteFiles() throws IOException {
|
||||
String appDataPath = System.getenv("LOCALAPPDATA") + "\\GeometryDash\\";
|
||||
for (String save : SAVES) {
|
||||
File inputFile = new File(appDataPath + save);
|
||||
if (!inputFile.exists()) {
|
||||
System.err.println("Input file not found: " + inputFile.getAbsolutePath());
|
||||
continue;
|
||||
}
|
||||
byte[] encryptedData = new byte[(int) inputFile.length()];
|
||||
try (FileInputStream fis = new FileInputStream(inputFile)) {
|
||||
fis.read(encryptedData);
|
||||
}
|
||||
|
||||
byte[] decryptedData = decrypt(new String(xor(encryptedData, XOR_KEY)));
|
||||
File outputFile = new File("C:\\ExtremeDemonList\\userdata\\" + save + ".xml");
|
||||
try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(outputFile), StandardCharsets.UTF_8)) {
|
||||
osw.write(new String(decryptedData, StandardCharsets.UTF_8));
|
||||
}
|
||||
System.out.println("File decrypted and written: " + outputFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
83
src/readsafefile/ReadAttemptsFromXML.java
Normal file
83
src/readsafefile/ReadAttemptsFromXML.java
Normal file
|
@ -0,0 +1,83 @@
|
|||
package readsafefile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
public class ReadAttemptsFromXML {
|
||||
|
||||
public String getAttempts(String level) {
|
||||
String atts = "0";
|
||||
try {
|
||||
// Pfad zur XML-Datei
|
||||
String filePath = "C:\\ExtremeDemonList\\userdata\\CCGameManager.dat.xml";
|
||||
|
||||
|
||||
// XML-Datei einlesen und als DOM-Dokument parsen
|
||||
File xmlFile = new File(filePath);
|
||||
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
|
||||
Document doc = dBuilder.parse(xmlFile);
|
||||
doc.getDocumentElement().normalize();
|
||||
|
||||
// Nach dem Eintrag für "Theory of Everything" suchen
|
||||
NodeList levelNodes = doc.getElementsByTagName("d");
|
||||
int index = 1;
|
||||
for (int i = 0; i < levelNodes.getLength(); i++) {
|
||||
|
||||
Node levelNode = levelNodes.item(i);
|
||||
if (levelNode.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element levelElement = (Element) levelNode;
|
||||
NodeList nameNodes = levelElement.getElementsByTagName("s");
|
||||
for (int j = 0; j < nameNodes.getLength(); j++) {
|
||||
Node nameNode = nameNodes.item(j);
|
||||
if (nameNode.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element nameElement = (Element) nameNode;
|
||||
String name = nameElement.getTextContent();
|
||||
if (name.equalsIgnoreCase(level)) {
|
||||
// Wenn der Name übereinstimmt, die Anzahl der Versuche extrahieren
|
||||
NodeList keyNodes = levelElement.getElementsByTagName("k");
|
||||
for (int k = 0; k < keyNodes.getLength(); k++) {
|
||||
Node keyNode = keyNodes.item(k);
|
||||
if (keyNode.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element keyElement = (Element) keyNode;
|
||||
String key = keyElement.getTextContent();
|
||||
if (key.equals("k18") && index == 2) {
|
||||
// Wert des Schlüssels "k18" (Versuche) ausgeben
|
||||
NodeList valueNodes = levelElement.getElementsByTagName("i");
|
||||
Node valueNode = valueNodes.item(k);
|
||||
atts = valueNode.getTextContent(); // Sobald die Anzahl der Versuche gefunden wurde, die Schleife beenden
|
||||
}
|
||||
|
||||
if(key.equals("GS_7")) {
|
||||
NodeList valueNodes = levelElement.getElementsByTagName("i");
|
||||
Node valueNode = valueNodes.item(k);
|
||||
System.out.println(valueNode.getTextContent() + " = practice percent");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return atts;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
56
src/readsafefile/SafeFileManager.java
Normal file
56
src/readsafefile/SafeFileManager.java
Normal file
|
@ -0,0 +1,56 @@
|
|||
package readsafefile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import data.FetchData;
|
||||
import database.Sqlite;
|
||||
import gui.AttemptsProgress;
|
||||
|
||||
public class SafeFileManager {
|
||||
|
||||
public void DecryptSafeFile() throws IOException {
|
||||
DecryptXOR dec = new DecryptXOR();
|
||||
dec.decryptAndWriteFiles();
|
||||
}
|
||||
|
||||
public void ReadIndexAttempts() throws IOException {
|
||||
|
||||
AttemptsProgress prog = new AttemptsProgress();
|
||||
prog.build();
|
||||
|
||||
Thread thread = new Thread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
|
||||
|
||||
Sqlite database = new Sqlite("levels");
|
||||
database.queryData("levels");
|
||||
FetchData fetch = new FetchData();
|
||||
try {
|
||||
fetch.getGithubString();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
ReadAttemptsFromXML read = new ReadAttemptsFromXML();
|
||||
|
||||
String attempts;
|
||||
|
||||
for(int i = 0; i < fetch.allLevels().size(); i++) {
|
||||
|
||||
attempts = read.getAttempts(database.getLevelname().get(i));
|
||||
|
||||
prog.update(database.getLevelname().get(i), Integer.parseInt(attempts), 1, i);
|
||||
database.modifyData(database.getLevelname().get(i), Boolean.parseBoolean(database.getCompleted().get(i)), Integer.parseInt(attempts));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
thread.start();
|
||||
}
|
||||
}
|
28
src/settingsfunctions/ReadAttempts.java
Normal file
28
src/settingsfunctions/ReadAttempts.java
Normal file
|
@ -0,0 +1,28 @@
|
|||
package settingsfunctions;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import readsafefile.SafeFileManager;
|
||||
|
||||
public class ReadAttempts {
|
||||
|
||||
public void readAttempts() throws IOException {
|
||||
int response = JOptionPane.showConfirmDialog(null, "Es werden nun von allen Extreme Demons die Attempts in die Datenbank geschrieben. Dies kann eine Weile dauern. Trotzdem fortfahren?", "Attempts Einlesen", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
|
||||
if (response == JOptionPane.YES_OPTION) {
|
||||
SafeFileManager mgr = new SafeFileManager();
|
||||
|
||||
File file = new File("C:\\ExtremeDemonList\\userdata\\CCGameManager.dat.xml");
|
||||
|
||||
if(!file.exists()) {
|
||||
mgr.DecryptSafeFile();
|
||||
}
|
||||
|
||||
mgr.ReadIndexAttempts();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue