Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Something #2

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: Java CI with Maven

permissions:
contents: write

on:
push:
branches: [ "master" ]
tags:
- v*
pull_request:
branches: [ "master" ]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up JDK 20
uses: actions/setup-java@v3
with:
java-version: '20'
distribution: 'temurin'
cache: maven
- name: Build with Maven
run: mvn package --file pom.xml

# Drafts your next Release notes as Pull Requests are merged into "master"
- name: Release Dependency
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
files: exporter/target/exporter-*-jar-with-dependencies.jar
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ exe/*
exporter/target/*
savecrypt/target/*
target/*
honeyhunter-*.txt
mhw-wiki-db-*.txt
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ $ mvn package

# Usage
```
$ java -jar exporter\target\exporter-1.2-jar-with-dependencies.jar PATH_TO_SAVE_FILE
$ java -jar exporter\target\exporter-1.4-jar-with-dependencies.jar PATH_TO_SAVE_FILE
```

# To do
Expand Down
28 changes: 22 additions & 6 deletions exporter/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,32 @@
<parent>
<groupId>io.github.clicksilver.exporter</groupId>
<artifactId>mhw_decos_exporter</artifactId>
<version>1.2</version>
<version>1.4</version>
</parent>

<name>exporter</name>
<artifactId>exporter</artifactId>
<version>1.2</version>
<version>1.4</version>
<packaging>jar</packaging>

<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>20</source>
<target>20</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
Expand Down Expand Up @@ -44,10 +60,10 @@

<dependencies>
<dependency>
<groupId>io.github.legendff.mhw.save</groupId>
<artifactId>savecrypt</artifactId>
<version>1.2</version>
</dependency>
<groupId>com.github.LEGENDFF</groupId>
<artifactId>mhw-Savecrypt</artifactId>
<version>bdbc8af322</version>
</dependency>
</dependencies>

</project>
108 changes: 81 additions & 27 deletions exporter/src/main/java/io/github/clicksilver/exporter/App.java
Original file line number Diff line number Diff line change
@@ -1,50 +1,55 @@
package io.github.clicksilver.exporter;

import java.io.FileWriter;
import java.lang.String;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.file.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

import io.github.legendff.mhw.save.Savecrypt;
import io.github.clicksilver.exporter.LocalizeMapping.ILocalizeMapping;
import io.github.clicksilver.exporter.LocalizeMapping.en_US;
import io.github.clicksilver.exporter.LocalizeMapping.ja_JP;
import io.github.clicksilver.exporter.LocalizeMapping.zh_TW;

public class App {

// Decoration item IDs
static final int kMinJewelId = 727;
static final int kMaxJewelId = 2275;
static final int kNumDecos = kMaxJewelId - kMinJewelId + 1;

// 10 pages, 50 jewels per page
static final int kDecoInventorySize = 50 * 10;
static final int kDecoInventorySize = 50 * 10;

// 8 bytes per jewel, (4 for ID + 4 for count)
static final int kNumBytesPerDeco = 8;

// direct offsets into the decrypted save, where each decorations list starts
static final int kSaveSlotDecosOffsets[] = new int[]{4302696, 6439464, 8576232};
static final int kSaveSlotDecosOffsets[] = new int[] { 4302696, 6439464, 8576232 };

public static void main(String[] args) {
if (args.length == 0) {
JFrame frame = new JFrame();
JOptionPane.showMessageDialog(frame, "No input save file detected.\n\n" +
"Drag save file onto the executable.",
"ERROR", JOptionPane.INFORMATION_MESSAGE);
"Drag save file onto the executable.",
"ERROR", JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
}
byte[] bytes;
// byte[] bytes;
Path p = Paths.get(args[0]);
try {
byte[] save = Files.readAllBytes(p);
byte[] decrypted_save = io.github.legendff.mhw.save.Savecrypt.decryptSave(save);

for (int i=0; i<3; ++i) {
for (int i = 0; i < 3; ++i) {
// Get actual decoration counts from the decrypted save.
int[] decorationCounts = getJewelCounts(decrypted_save, kSaveSlotDecosOffsets[i]);

// If there are no decorations counted, skip this save file.
if (decorationCounts == null) {
continue;
Expand All @@ -63,7 +68,7 @@ public static void main(String[] args) {
honeyFile.write("\n");
}
honeyFile.close();
} catch(Exception e) {
} catch (Exception e) {
JFrame frame = new JFrame();
JOptionPane.showMessageDialog(frame, "Failed to write honey hunter output");
}
Expand All @@ -77,21 +82,55 @@ public static void main(String[] args) {
.write("WARNING: Unequip all decorations before using this" + " otherwise the count will be wrong.");
wikidbFile.write("\n");
wikidbFile.write("\n");
wikidbFile.write(outputWikiDB(decorationCounts));
wikidbFile.write(outputWikiDB(decorationCounts, "en-US"));
wikidbFile.write("\n");
}
wikidbFile.close();
} catch (Exception e) {
JFrame frame = new JFrame();
JOptionPane.showMessageDialog(frame, "Failed to write mhw-wiki-db output");
}

try {
wikidbFile = new FileWriter("mhw-wiki-db-tw-" + String.valueOf(i + 1) + ".txt");
if (decorationCounts != null) {
wikidbFile
.write("WARNING: Unequip all decorations before using this" + " otherwise the count will be wrong.");
wikidbFile.write("\n");
wikidbFile.write("\n");
wikidbFile.write(outputWikiDB(decorationCounts, "zh-TW"));
wikidbFile.write("\n");
}
wikidbFile.close();
} catch (Exception e) {
JFrame frame = new JFrame();
JOptionPane.showMessageDialog(frame,
String.format("Failed to write mhw-wiki-db-tw output\r\nbecause %s)", e.getMessage()));
}

try {
wikidbFile = new FileWriter("mhw-wiki-db-jp-" + String.valueOf(i + 1) + ".txt");
if (decorationCounts != null) {
wikidbFile
.write("WARNING: Unequip all decorations before using this" + " otherwise the count will be wrong.");
wikidbFile.write("\n");
wikidbFile.write("\n");
wikidbFile.write(outputWikiDB(decorationCounts, "ja-JP"));
wikidbFile.write("\n");
}
wikidbFile.close();
} catch (Exception e) {
JFrame frame = new JFrame();
JOptionPane.showMessageDialog(frame,
String.format("Failed to write mhw-wiki-db-jp output\r\nbecause %s)", e.getMessage()));
}
}

JFrame frame = new JFrame();
JOptionPane.showMessageDialog(frame, "Successfully exported decorations",
"COMPLETE", JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
} catch(Exception e) {
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
JFrame frame = new JFrame();
Expand All @@ -103,29 +142,44 @@ public static void main(String[] args) {
}

public static void printJewels(int[] counts) {
for (int i=0; i<counts.length; ++i) {
for (int i = 0; i < counts.length; ++i) {
String name = DecorationNames.getDecorationName(i + kMinJewelId);
int count = counts[i];
if(name.length() != 0 && count != 0) {
if (name.length() != 0 && count != 0) {
System.out.println(name + ": " + counts[i]);
}
}
}
public static String outputWikiDB(int[] counts) {

public static String outputWikiDB(int[] counts, String lang) {
StringBuilder contents = new StringBuilder("");
contents.append("{");
for (int i=0; i<counts.length; ++i) {
for (int i = 0; i < counts.length; ++i) {
String name = DecorationNames.getDecorationName(i + kMinJewelId);
if (name.length() == 0) {
continue;
}
int count = Math.min(counts[i], HoneyHunter.getMaxCountFromName(name));
contents.append("\"");
contents.append(name);

ILocalizeMapping mapping;
switch (lang) {
case "zh-TW":
mapping = new zh_TW();
break;
case "ja-JP":
mapping = new ja_JP();
break;
default:
mapping = new en_US();
break;
}

contents.append(mapping.Map(name));

contents.append("\":");
contents.append(count);
if (i != counts.length-1) {
if (i != counts.length - 1) {
contents.append(",");
}
}
Expand All @@ -137,7 +191,7 @@ public static String outputHoneyHunter(int[] counts) {
int hhCounts[] = new int[HoneyHunter.kNumDecos];
Arrays.fill(hhCounts, 0);

for (int i=0; i<counts.length; ++i) {
for (int i = 0; i < counts.length; ++i) {
String name = DecorationNames.getDecorationName(i + kMinJewelId);
if (name.length() == 0) {
continue;
Expand All @@ -152,7 +206,7 @@ public static String outputHoneyHunter(int[] counts) {

StringBuilder contents = new StringBuilder("");
contents.append(hhCounts[0]);
for (int i=1; i<hhCounts.length; ++i) {
for (int i = 1; i < hhCounts.length; ++i) {
contents.append(",");
contents.append(hhCounts[i]);
}
Expand All @@ -163,16 +217,16 @@ public static int[] getJewelCounts(byte[] bytes, int offset) {
int counts[] = new int[kNumDecos];

ByteBuffer buf = ByteBuffer.wrap(bytes, offset, kDecoInventorySize * kNumBytesPerDeco);

// NOTE: Java is dumb about bytes.
buf.order(ByteOrder.LITTLE_ENDIAN);

boolean anyNonZero = false;

for (int i=0; i<kDecoInventorySize; i++) {
for (int i = 0; i < kDecoInventorySize; i++) {
int jewelId = buf.getInt();
int jewelCount = buf.getInt();
if(jewelId == 0) {
if (jewelId == 0) {
// missing owned deco, which is not an invalid deco
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public static String getDecorationName(int id) {
if (id == 2011) { return "Mirewalker Jewel+ 4"; }
if (id == 2012) { return "Specimen Jewel+ 4"; }
if (id == 2013) { return "Sonorous Jewel+ 4"; }
if (id == 2014) { return "Hard Botany Jewel+ 4"; }
if (id == 2014) { return "Hard Botany Jewel 4"; }
if (id == 2015) { return "Hard Geology Jewel 4"; }
if (id == 2016) { return "Hard Survival Jewel 4"; }
if (id == 2017) { return "Hard Specimen Jewel 4"; }
Expand Down
Loading