Compare commits

..

No commits in common. "b8727c04a0fcad6a16763c277daf539b6939d4c2" and "d9c6bd7e73673396f13595546edd687b0b3a8b9d" have entirely different histories.

19 changed files with 121 additions and 253 deletions

1
.gitattributes vendored
View file

@ -1,4 +1,3 @@
gradlew* linguist-vendored gradlew* linguist-vendored
gradle/wrapper/* linguist-vendored gradle/wrapper/* linguist-vendored
*.bat text eol=crlf

View file

@ -17,7 +17,7 @@ jobs:
java-version: 17 java-version: 17
- name: Setup Gradle - name: Setup Gradle
uses: gradle/actions/setup-gradle@v4 uses: gradle/actions/setup-gradle@v3
- name: Execute Gradle build - name: Execute Gradle build
run: ./gradlew build run: ./gradlew build

View file

@ -7,4 +7,4 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4.1.1 - uses: actions/checkout@v4.1.1
- uses: gradle/actions/wrapper-validation@v4 - uses: gradle/wrapper-validation-action@v2.0.0

38
.github/workflows/init.yml vendored Normal file
View file

@ -0,0 +1,38 @@
name: Initialize Template Repo
on:
- push
permissions:
contents: write
jobs:
cleanup:
name: "Initialize Repo"
runs-on: ubuntu-latest
if: github.event.repository.name != 'Forge1.8.9Template'
steps:
- name: Checkout repository
uses: actions/checkout@v4.1.1
- name: Initialize Repo
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
owner=$(echo $GITHUB_REPOSITORY | cut -d/ -f1 | tr '[:upper:]' '[:lower:]')
name=$(echo $GITHUB_REPOSITORY | cut -d/ -f2 | tr '[:upper:]' '[:lower:]' | tr -d "-" | tr -d ".")
pack_name="com.github.${owner,,}.${name,,}"
proj_name="$(echo $GITHUB_REPOSITORY | cut -d/ -f2)"
modid="$(echo $name | sed 's/[^a-z]//g')"
./make-my-own.sh "$pack_name" "$proj_name" "$modid"
git add .
git commit -F- <<EOF
Initialize template repository proper
Set package name to $pack_name
Set project name to $proj_name
Set modid to $modid
EOF
- name: Push changes
uses: ad-m/github-push-action@v0.8.0
with:
branch: ${{ github.ref }}
github_token: ${{ secrets.GITHUB_TOKEN }}

View file

@ -2,16 +2,14 @@
**For other templates, do check out the [other branches of this repository](https://github.com/romangraef/Forge1.8.9Template/branches/all)** **For other templates, do check out the [other branches of this repository](https://github.com/romangraef/Forge1.8.9Template/branches/all)**
## Usage To get started, clone this repository.
In `build.gradle.kts`, replace the values of `baseGroup` and `group` with your own names.
In `settings.gradle.kts` change `rootProject.name` to your desired mod id.
Check out https://moddev.nea.moe/ for a full tutorial on legacy modding. The `com.example` package needs to be renamed to match the value of `baseGroup`.
Alternatively, read here for a basic overview on how to use this repository. If you don't want mixins (which allow for modifying vanilla code), then you can remove the references to mixins from
the `build.gradle.kts` at the lines specified with comments and the `com.example.mixin` package.
To get started, [Use this template](https://github.com/new?template_name=Forge1.8.9Template&template_owner=nea89o).
> [!WARNING]
> Do not Fork or Clone or Download ZIP this template. If you "use" this template a custom mod id will be generated. You can do that manually using the `make-my-own` script, if you are on linux. If not, just click the use this template button. If you want to use kotlin or make a 1.12 mod check the "Include all branches" and change the default branch in https://github.com/yourname/yourreponame/branches
This project uses [DevAuth](https://github.com/DJtheRedstoner/DevAuth) per default, so you can log in using your real This project uses [DevAuth](https://github.com/DJtheRedstoner/DevAuth) per default, so you can log in using your real
minecraft account. If you don't need that, you can remove it from the buildscript. minecraft account. If you don't need that, you can remove it from the buildscript.
@ -27,13 +25,6 @@ To export your project, run the `gradle build` task, and give other people the
file `build/libs/<modid>-<version>.jar`. Ignore the jars in the `build/badjars` folder. Those are intermediary jars that file `build/libs/<modid>-<version>.jar`. Ignore the jars in the `build/badjars` folder. Those are intermediary jars that
are used by the build system but *do not work* in a normal forge installation. are used by the build system but *do not work* in a normal forge installation.
If you don't want mixins (which allow for modifying vanilla code), then you can remove the references to mixins from
the `build.gradle.kts` at the lines specified with comments and the `com.example.mixin` package.
If you don't want access transformers (which allow for making methods public/non-final) you can delete the
`accesstransformer.cfg` file. If you make a change to the `accesstransformers.cfg` you might need to rebuild your
project using `./gradlew build --refresh-dependencies`.
### For those who have not an attention span ### For those who have not an attention span
[![Youtube Tutorial](https://i.ytimg.com/vi/nWzHlomdCgc/maxresdefault.jpg)](https://www.youtube.com/watch?v=nWzHlomdCgc) [![Youtube Tutorial](https://i.ytimg.com/vi/nWzHlomdCgc/maxresdefault.jpg)](https://www.youtube.com/watch?v=nWzHlomdCgc)

View file

@ -15,7 +15,6 @@ val mcVersion: String by project
val version: String by project val version: String by project
val mixinGroup = "$baseGroup.mixin" val mixinGroup = "$baseGroup.mixin"
val modid: String by project val modid: String by project
val transformerFile = file("src/main/resources/accesstransformer.cfg")
// Toolchains: // Toolchains:
java { java {
@ -29,6 +28,7 @@ loom {
"client" { "client" {
// If you don't want mixins, remove these lines // If you don't want mixins, remove these lines
property("mixin.debug", "true") property("mixin.debug", "true")
property("asmhelper.verbose", "true")
arg("--tweakClass", "org.spongepowered.asm.launch.MixinTweaker") arg("--tweakClass", "org.spongepowered.asm.launch.MixinTweaker")
} }
} }
@ -45,10 +45,6 @@ loom {
pack200Provider.set(dev.architectury.pack200.java.Pack200Adapter()) pack200Provider.set(dev.architectury.pack200.java.Pack200Adapter())
// If you don't want mixins, remove this lines // If you don't want mixins, remove this lines
mixinConfig("mixins.$modid.json") mixinConfig("mixins.$modid.json")
if (transformerFile.exists()) {
println("Installing access transformer")
accessTransformer(transformerFile)
}
} }
// If you don't want mixins, remove these lines // If you don't want mixins, remove these lines
mixin { mixin {
@ -85,7 +81,7 @@ dependencies {
annotationProcessor("org.spongepowered:mixin:0.8.5-SNAPSHOT") annotationProcessor("org.spongepowered:mixin:0.8.5-SNAPSHOT")
// If you don't want to log in with your real minecraft account, remove this line // If you don't want to log in with your real minecraft account, remove this line
runtimeOnly("me.djtheredstoner:DevAuth-forge-legacy:1.2.1") runtimeOnly("me.djtheredstoner:DevAuth-forge-legacy:1.1.2")
} }
@ -95,7 +91,7 @@ tasks.withType(JavaCompile::class) {
options.encoding = "UTF-8" options.encoding = "UTF-8"
} }
tasks.withType(org.gradle.jvm.tasks.Jar::class) { tasks.withType(Jar::class) {
archiveBaseName.set(modid) archiveBaseName.set(modid)
manifest.attributes.run { manifest.attributes.run {
this["FMLCorePluginContainsFMLMod"] = "true" this["FMLCorePluginContainsFMLMod"] = "true"
@ -104,8 +100,6 @@ tasks.withType(org.gradle.jvm.tasks.Jar::class) {
// If you don't want mixins, remove these lines // If you don't want mixins, remove these lines
this["TweakClass"] = "org.spongepowered.asm.launch.MixinTweaker" this["TweakClass"] = "org.spongepowered.asm.launch.MixinTweaker"
this["MixinConfigs"] = "mixins.$modid.json" this["MixinConfigs"] = "mixins.$modid.json"
if (transformerFile.exists())
this["FMLAT"] = "${modid}_at.cfg"
} }
} }
@ -113,13 +107,13 @@ tasks.processResources {
inputs.property("version", project.version) inputs.property("version", project.version)
inputs.property("mcversion", mcVersion) inputs.property("mcversion", mcVersion)
inputs.property("modid", modid) inputs.property("modid", modid)
inputs.property("basePackage", baseGroup) inputs.property("mixinGroup", mixinGroup)
filesMatching(listOf("mcmod.info", "mixins.$modid.json")) { filesMatching(listOf("mcmod.info", "mixins.$modid.json")) {
expand(inputs.properties) expand(inputs.properties)
} }
rename("accesstransformer.cfg", "META-INF/${modid}_at.cfg") rename("(.+_at.cfg)", "META-INF/$1")
} }
@ -131,16 +125,16 @@ val remapJar by tasks.named<net.fabricmc.loom.task.RemapJarTask>("remapJar") {
tasks.jar { tasks.jar {
archiveClassifier.set("without-deps") archiveClassifier.set("without-deps")
destinationDirectory.set(layout.buildDirectory.dir("intermediates")) destinationDirectory.set(layout.buildDirectory.dir("badjars"))
} }
tasks.shadowJar { tasks.shadowJar {
destinationDirectory.set(layout.buildDirectory.dir("intermediates")) destinationDirectory.set(layout.buildDirectory.dir("badjars"))
archiveClassifier.set("non-obfuscated-with-deps") archiveClassifier.set("all-dev")
configurations = listOf(shadowImpl) configurations = listOf(shadowImpl)
doLast { doLast {
configurations.forEach { configurations.forEach {
println("Copying dependencies into mod: ${it.files}") println("Copying jars into mod: ${it.files}")
} }
} }

View file

@ -1,6 +1,6 @@
loom.platform=forge loom.platform=forge
org.gradle.jvmargs=-Xmx2g org.gradle.jvmargs=-Xmx2g
baseGroup = xyz.stachel.bonzotimer baseGroup = com.example
mcVersion = 1.8.9 mcVersion = 1.8.9
modid = bonzo-timer modid = examplemod
version = 1.0.0 version = 1.0.0

Binary file not shown.

View file

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

2
gradlew vendored
View file

@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.

20
gradlew.bat vendored
View file

@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2 echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo. 1>&2 echo.
echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation. 1>&2 echo location of your Java installation.
goto fail goto fail
@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto execute
echo. 1>&2 echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo. 1>&2 echo.
echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation. 1>&2 echo location of your Java installation.
goto fail goto fail

36
make-my-own.sh Executable file
View file

@ -0,0 +1,36 @@
#!/usr/bin/env bash
print_help() {
echo "$0 <new package name> <project name> <modid>"
}
if [ "$#" -ne "3" ]; then
print_help
exit 0
fi
base=$(dirname "$(readlink -f "$0")")
echo "Updating $base"
package_name="$1"
project_name="$2"
modid="$3"
package_dir=$(echo "$package_name" | tr . /)
echo "Setting package name to $package_name"
echo "Setting project name to $project_name"
echo "Setting package dir to $package_dir"
echo "Setting mod id to $modid"
(
set -x
find "$base"/src/main -type f -exec sed -i s/examplemod/"$modid"/g\;s/com.example/"$package_name"/g {} +
sed -i s/com.example/"$package_name"/g\;s/examplemod/"$modid"/g "$base"/gradle.properties
sed -i s/examplemod/"$project_name"/g "$base"/settings.gradle.kts
mkdir -p "$base"/src/main/java/"$package_dir"
mkdir -p "$base"/src/main/kotlin/"$package_dir"
mv "$base"/src/main/java/com/example/* "$base"/src/main/java/"$package_dir"
mv "$base"/src/main/kotlin/com/example/* "$base"/src/main/kotlin/"$package_dir"
mv "$base"/src/main/resources/mixins.examplemod.json "$base"/src/main/resources/mixins."$modid".json
rm "$base"/.github/workflows/init.yml
rm "$(readlink -f $0)"
)
echo "All done"
echo "Now go commit those changes"

View file

@ -7,7 +7,7 @@ pluginManagement {
maven("https://maven.fabricmc.net") maven("https://maven.fabricmc.net")
maven("https://maven.minecraftforge.net/") maven("https://maven.minecraftforge.net/")
maven("https://repo.spongepowered.org/maven/") maven("https://repo.spongepowered.org/maven/")
maven("https://repo.essential.gg/repository/maven-releases/") maven("https://repo.sk1er.club/repository/maven-releases/")
} }
resolutionStrategy { resolutionStrategy {
eachPlugin { eachPlugin {
@ -23,4 +23,4 @@ plugins {
} }
rootProject.name = "bonzo-timer" rootProject.name = "examplemod"

View file

@ -1,16 +1,13 @@
package xyz.stachel.bonzotimer; package com.example;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLInitializationEvent;
@Mod(modid = "bonzo-timer", useMetadata=true) @Mod(modid = "examplemod", useMetadata=true)
public class ExampleMod { public class ExampleMod {
@Mod.EventHandler @Mod.EventHandler
public void init(FMLInitializationEvent event) { public void init(FMLInitializationEvent event) {
System.out.println("Dirt: " + Blocks.dirt.getUnlocalizedName()); System.out.println("Dirt: " + Blocks.dirt.getUnlocalizedName());
// Below is a demonstration of an access-transformed class access.
System.out.println("Color State: " + new GlStateManager.Color());
} }
} }

View file

@ -1,4 +1,4 @@
package xyz.stachel.bonzotimer.mixin; package com.example.mixin;
import net.minecraft.client.gui.GuiMainMenu; import net.minecraft.client.gui.GuiMainMenu;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;

View file

@ -1,188 +0,0 @@
package xyz.stachel.bonzotimer.init;
import org.spongepowered.asm.lib.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* A mixin plugin to automatically discover all mixins in the current JAR.
* <p>
* This mixin plugin automatically scans your entire JAR (or class directory, in case of an in-IDE launch) for classes inside of your
* mixin package and registers those. It does this recursively for sub packages of the mixin package as well. This means you will need
* to only have mixin classes inside of your mixin package, which is good style anyway.
*
* @author Linnea Gräf
*/
public class AutoDiscoveryMixinPlugin implements IMixinConfigPlugin {
private static final List<AutoDiscoveryMixinPlugin> mixinPlugins = new ArrayList<>();
public static List<AutoDiscoveryMixinPlugin> getMixinPlugins() {
return mixinPlugins;
}
private String mixinPackage;
@Override
public void onLoad(String mixinPackage) {
this.mixinPackage = mixinPackage;
mixinPlugins.add(this);
}
/**
* Resolves the base class root for a given class URL. This resolves either the JAR root, or the class file root.
* In either case the return value of this + the class name will resolve back to the original class url, or to other
* class urls for other classes.
*/
public URL getBaseUrlForClassUrl(URL classUrl) {
String string = classUrl.toString();
if (classUrl.getProtocol().equals("jar")) {
try {
return new URL(string.substring(4).split("!")[0]);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
if (string.endsWith(".class")) {
try {
return new URL(string.replace("\\", "/")
.replace(getClass().getCanonicalName()
.replace(".", "/") + ".class", ""));
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
return classUrl;
}
/**
* Get the package that contains all the mixins. This value is set by mixin itself using {@link #onLoad}.
*/
public String getMixinPackage() {
return mixinPackage;
}
/**
* Get the path inside the class root to the mixin package
*/
public String getMixinBaseDir() {
return mixinPackage.replace(".", "/");
}
/**
* A list of all discovered mixins.
*/
private List<String> mixins = null;
/**
* Try to add mixin class ot the mixins based on the filepath inside of the class root.
* Removes the {@code .class} file suffix, as well as the base mixin package.
* <p><b>This method cannot be called after mixin initialization.</p>
*
* @param className the name or path of a class to be registered as a mixin.
*/
public void tryAddMixinClass(String className) {
String norm = (className.endsWith(".class") ? className.substring(0, className.length() - ".class".length()) : className)
.replace("\\", "/")
.replace("/", ".");
if (norm.startsWith(getMixinPackage() + ".") && !norm.endsWith(".")) {
mixins.add(norm.substring(getMixinPackage().length() + 1));
}
}
/**
* Search through the JAR or class directory to find mixins contained in {@link #getMixinPackage()}
*/
@Override
public List<String> getMixins() {
if (mixins != null) return mixins;
System.out.println("Trying to discover mixins");
mixins = new ArrayList<>();
URL classUrl = getClass().getProtectionDomain().getCodeSource().getLocation();
System.out.println("Found classes at " + classUrl);
Path file;
try {
file = Paths.get(getBaseUrlForClassUrl(classUrl).toURI());
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
System.out.println("Base directory found at " + file);
if (Files.isDirectory(file)) {
walkDir(file);
} else {
walkJar(file);
}
System.out.println("Found mixins: " + mixins);
return mixins;
}
/**
* Search through directory for mixin classes based on {@link #getMixinBaseDir}.
*
* @param classRoot The root directory in which classes are stored for the default package.
*/
private void walkDir(Path classRoot) {
System.out.println("Trying to find mixins from directory");
try (Stream<Path> classes = Files.walk(classRoot.resolve(getMixinBaseDir()))) {
classes.map(it -> classRoot.relativize(it).toString())
.forEach(this::tryAddMixinClass);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* Read through a JAR file, trying to find all mixins inside.
*/
private void walkJar(Path file) {
System.out.println("Trying to find mixins from jar file");
try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(file))) {
ZipEntry next;
while ((next = zis.getNextEntry()) != null) {
tryAddMixinClass(next.getName());
zis.closeEntry();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
@Override
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
@Override
public String getRefMapperConfig() {
return null;
}
@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
return true;
}
@Override
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
}
}

View file

@ -1,2 +0,0 @@
public net.minecraft.client.renderer.GlStateManager$Color

View file

@ -1,8 +0,0 @@
{
"package": "${basePackage}.mixin",
"plugin": "${basePackage}.init.AutoDiscoveryMixinPlugin",
"refmap": "mixins.${modid}.refmap.json",
"minVersion": "0.7",
"compatibilityLevel": "JAVA_8",
"__comment": "You do not need to manually register mixins in this template. Check the auto discovery mixin plugin for more info."
}

View file

@ -0,0 +1,11 @@
{
"package": "${mixinGroup}",
"refmap": "mixins.${modid}.refmap.json",
"minVersion": "0.7",
"compatibilityLevel": "JAVA_8",
"mixins": [
],
"client": [
"MixinGuiMainMenu"
]
}