Skip to content

Commit 499fbc2

Browse files
committed
Initial commit
0 parents  commit 499fbc2

File tree

12 files changed

+87502
-0
lines changed

12 files changed

+87502
-0
lines changed

.github/automatic.gif

2.7 MB
Loading

.github/manual.gif

878 KB
Loading

.gitignore

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
.metadata/**
2+
.recommenders/**
3+
.settings/**
4+
bin/**
5+
target/**
6+
**/psd/**
7+
*.class
8+
*.dtd
9+
*.sh
10+
*.bat
11+
*.lnk
12+
13+
.classpath
14+
.project
15+
16+
# IntelliJ IDEA Project stuff
17+
.idea/
18+
out/
19+
*.iws
20+
*.iml
21+
*___jb_*___
22+
/target/

CONTRIBUTING.md

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Recaf plugin workspace
2+
3+
This is a sample maven workspace for creating plugins for Recaf `2.X`.
4+
5+
## Plugin documentation
6+
7+
The official documentation can be found here: [Recaf Docs:Plugins](https://col-e.github.io/Recaf/doc-advanced-plugin.html).
8+
9+
The source and javadoc artifacts are also available and can be fetched in your IDE workspace.
10+
11+
## Building & modification
12+
13+
Once you've downloaded or cloned the repository, you can compile with `mvn clean package`.
14+
This will generate the file `target/plugin-{VERSION}.jar`. To add your plugin to Recaf:
15+
16+
1. Navigate to the `plugins` folder.
17+
- Windows: `%HOMEPATH%/Recaf/plugins`
18+
- Linux: `$HOME/Recaf/plugins`
19+
2. Copy your plugin jar into this folder
20+
3. Run Recaf to verify your plugin loads.

README.md

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<div align="center">
2+
3+
# Recaf4Forge
4+
5+
Inspired by [Luyten4Forge](https://github.com/KevinPriv/Luyten4Forge)
6+
7+
![VERSION](https://img.shields.io/github/v/release/1fxe/Recaf4Forge?style=flat-square)
8+
![ISSUES](https://img.shields.io/github/issues/1fxe/Recaf4Forge?style=flat-square)
9+
10+
</div>
11+
12+
## What is this?
13+
14+
This is a plugin for Recaf which can automatically detects a Minecraft Forge Mods version using the mcmod.info and
15+
applies the correct mapping.
16+
17+
The mappings are stored in this jar file, so you don't have to manually find them.
18+
19+
It currently works for 1.8, 1.8.9 and 1.9.4
20+
21+
### Example Usage
22+
23+
<details>
24+
<summary>Click here to see an example of automatic mappings</summary>
25+
26+
![Automatic Example](.github/automatic.gif)
27+
28+
</details>
29+
30+
<details>
31+
<summary>Click here to see an example of manual mappings</summary>
32+
33+
![Manual Example](.github/manual.gif)
34+
35+
</details>
36+
37+
## TODO
38+
39+
- Extract source to relevant forge MDK
40+
- Add support for other versions
41+
- Add translations?
42+
43+
### Contributing
44+
45+
See [Contributing](CONTRIBUTING.md)

pom.xml

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
<!-- Your personal package -->
5+
<groupId>dev.fxe</groupId>
6+
<artifactId>recaf4forge</artifactId>
7+
<version>1.0.0</version>
8+
<name>Recaf4Forge</name>
9+
<properties>
10+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
11+
</properties>
12+
<!-- Additional repo's -->
13+
<repositories>
14+
<repository>
15+
<id>jitpack.io</id>
16+
<url>https://jitpack.io</url>
17+
</repository>
18+
</repositories>
19+
<!-- Dependencies, most are inferred by Recaf's own dependency list -->
20+
<dependencies>
21+
<dependency>
22+
<groupId>com.github.Col-E</groupId>
23+
<artifactId>recaf</artifactId>
24+
<version>2.4.0</version>
25+
</dependency>
26+
</dependencies>
27+
<build>
28+
<plugins>
29+
<plugin>
30+
<artifactId>maven-compiler-plugin</artifactId>
31+
<version>3.7.0</version>
32+
<configuration>
33+
<source>1.8</source>
34+
<target>1.8</target>
35+
</configuration>
36+
</plugin>
37+
</plugins>
38+
</build>
39+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package dev.fxe.recaf_forge;
2+
3+
import me.coley.recaf.ui.controls.ExceptionAlert;
4+
import org.apache.commons.io.IOUtils;
5+
import org.jline.utils.Log;
6+
7+
import java.io.File;
8+
import java.io.FileOutputStream;
9+
import java.io.InputStream;
10+
import java.nio.file.Path;
11+
12+
/**
13+
* @author Filip
14+
*/
15+
public class ExtractMappings {
16+
17+
public static Path getMappingsPath(String resourcePath) {
18+
try (InputStream in = ExtractMappings.class.getResourceAsStream(resourcePath)) {
19+
String[] strings = resourcePath.split("\\.");
20+
String suffix = strings[strings.length - 1];
21+
if (in != null) {
22+
File tempFile = File.createTempFile(String.valueOf(in.hashCode()), suffix);
23+
tempFile.deleteOnExit();
24+
try (FileOutputStream out = new FileOutputStream(tempFile)) {
25+
byte[] array = IOUtils.toByteArray(in);
26+
out.write(array);
27+
return tempFile.toPath();
28+
} catch (Exception ex) {
29+
ExceptionAlert.show(ex, "Failed to create mappings file");
30+
}
31+
} else {
32+
Log.info("InputStream is null");
33+
}
34+
} catch (Exception ex) {
35+
ExceptionAlert.show(ex, "Failed to read resources");
36+
}
37+
return null;
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package dev.fxe.recaf_forge;
2+
3+
import com.eclipsesource.json.Json;
4+
import com.eclipsesource.json.JsonValue;
5+
import javafx.scene.control.Menu;
6+
import javafx.scene.control.MenuItem;
7+
import me.coley.recaf.config.Conf;
8+
import me.coley.recaf.mapping.MappingImpl;
9+
import me.coley.recaf.mapping.Mappings;
10+
import me.coley.recaf.plugin.api.ConfigurablePlugin;
11+
import me.coley.recaf.plugin.api.MenuProviderPlugin;
12+
import me.coley.recaf.plugin.api.WorkspacePlugin;
13+
import me.coley.recaf.ui.controls.ActionMenuItem;
14+
import me.coley.recaf.ui.controls.ExceptionAlert;
15+
import me.coley.recaf.util.struct.ListeningMap;
16+
import me.coley.recaf.workspace.Workspace;
17+
import org.jline.utils.Log;
18+
import org.plugface.core.annotations.Plugin;
19+
20+
import java.nio.file.Path;
21+
import java.util.concurrent.CompletableFuture;
22+
import java.util.concurrent.ExecutorService;
23+
import java.util.concurrent.Executors;
24+
25+
/**
26+
* @author Filip
27+
*/
28+
@Plugin(name = "Recaf4Forge")
29+
public class Recaf4Forge implements ConfigurablePlugin, MenuProviderPlugin, WorkspacePlugin {
30+
31+
private final String[] versions = {"1.8", "1.8.9", "1.9.4"};
32+
private final ExecutorService executor = Executors.newSingleThreadExecutor();
33+
private Workspace currentWorkspace = null;
34+
private String currentVersion = "None";
35+
36+
@Conf(value = "Automatically apply mappings", noTranslate = true)
37+
private boolean autoApply = false;
38+
39+
@Override
40+
public String getName() {
41+
return "Recaf4Forge";
42+
}
43+
44+
@Override
45+
public String getVersion() {
46+
return "1.0";
47+
}
48+
49+
@Override
50+
public String getDescription() {
51+
return "Recaf4Forge will automatically try apply the correct mappings for a forge mod";
52+
}
53+
54+
@Override
55+
public Menu createMenu() {
56+
MenuItem[] itemList = new MenuItem[versions.length];
57+
int index = 0;
58+
for (String version : versions) {
59+
MenuItem item = new ActionMenuItem(version, () -> {
60+
currentVersion = version;
61+
applyMapping();
62+
});
63+
itemList[index] = item;
64+
index++;
65+
}
66+
return new Menu(getName(), null, itemList);
67+
}
68+
69+
@Override
70+
public void onClosed(Workspace workspace) {
71+
currentWorkspace = null;
72+
}
73+
74+
75+
@Override
76+
public void onOpened(Workspace workspace) {
77+
currentWorkspace = workspace;
78+
if (this.autoApply) {
79+
CompletableFuture.runAsync(this::detectVersion, executor);
80+
}
81+
}
82+
83+
private void detectVersion() {
84+
ListeningMap<String, byte[]> data = currentWorkspace.getPrimary().getFiles();
85+
byte[] mcModInfo = data.get("mcmod.info");
86+
JsonValue jsonValue = Json.parse(new String(mcModInfo));
87+
String version = jsonValue.asArray().get(0).asObject().get("mcversion").asString();
88+
for (String s : versions) {
89+
if (s.equalsIgnoreCase(version)) {
90+
currentVersion = version;
91+
applyMapping();
92+
return;
93+
}
94+
}
95+
Log.info(getName() + " Failed to find mod version");
96+
currentVersion = "";
97+
}
98+
99+
private void applyMapping() {
100+
String path = "/mappings/" + currentVersion.replaceAll("\\.", "_") + "/mappings.srg";
101+
Path mappingPath = ExtractMappings.getMappingsPath(path);
102+
if (mappingPath == null) {
103+
Log.info(getName() + " Could not find mappings");
104+
return;
105+
}
106+
try {
107+
Mappings mappings = MappingImpl.SRG.create(mappingPath, currentWorkspace);
108+
mappings.setCheckFieldHierarchy(true);
109+
mappings.setCheckMethodHierarchy(true);
110+
mappings.accept(currentWorkspace.getPrimary());
111+
} catch (Exception ex) {
112+
ExceptionAlert.show(ex, getName() + " Failed to apply mappings");
113+
}
114+
}
115+
116+
@Override
117+
public String getConfigTabTitle() {
118+
return getName();
119+
}
120+
}

src/main/resources/icon.png

10.9 KB
Loading

0 commit comments

Comments
 (0)