Skip to content
Draft
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
3 changes: 2 additions & 1 deletion .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: 'recursive'
- name: Checkout workflows repo
uses: actions/checkout@v4
with:
Expand All @@ -42,7 +43,7 @@ jobs:
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Compile the mod
run: ./gradlew --build-cache --info --stacktrace assemble
run: ./gradlew --build-cache --info --stacktrace :core:test assemble
- name: Attach compilation artifacts
uses: actions/upload-artifact@v4
with:
Expand Down
9 changes: 8 additions & 1 deletion .github/workflows/release-tags.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 32
submodules: 'recursive'

- name: Set up JDK versions
uses: actions/setup-java@v4
Expand Down Expand Up @@ -70,7 +71,13 @@ jobs:
-f tag_name="${RELEASE_VERSION}" \
--jq ".body" > "${CHANGELOG_FILE}"
cat "${CHANGELOG_FILE}"
gh release create "${RELEASE_VERSION}" -F "${CHANGELOG_FILE}" $PRERELEASE ./build/libs/*.jar
# Upload only the production reobfuscated mod jar (exclude -dev, -slim, -sources).
mapfile -t RELEASE_JARS < <(find build/libs -maxdepth 1 -name '*.jar' ! -name '*-dev*' ! -name '*-slim*' ! -name '*-sources*')
if [[ ${#RELEASE_JARS[@]} -eq 0 ]]; then
echo "No production jar found in build/libs"
exit 1
fi
gh release create "${RELEASE_VERSION}" -F "${CHANGELOG_FILE}" $PRERELEASE "${RELEASE_JARS[@]}"
shell: bash
continue-on-error: true
env:
Expand Down
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[submodule "core"]
path = core
url = https://github.com/kuba6000/AE2-Web-Integration.git
branch = core
5 changes: 4 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {
id 'idea'
id 'maven-publish'
alias libs.plugins.modDevGradle
//alias libs.plugins.shadow
alias libs.plugins.shadow
alias libs.plugins.spotless
alias libs.plugins.lombok
id 'com.palantir.git-version' version '4.0.0' apply false // 0.13.0 is the last jvm8 supporting version
Expand Down Expand Up @@ -103,6 +103,9 @@ obfuscation {

apply from: "$rootDir/gradle/scripts/jars.gradle"
apply from: "$rootDir/gradle/scripts/moddevgradle.gradle"
if (findProperty('usesShadowedDependencies')?.toString()?.toBoolean()) {
apply from: "$rootDir/gradle/scripts/shadow.gradle"
}
apply from: "$rootDir/gradle/scripts/repositories.gradle"
apply from: "$rootDir/dependencies.gradle"
apply from: "$rootDir/gradle/scripts/resources.gradle"
Expand Down
1 change: 1 addition & 0 deletions core
Submodule core added at eb7a31
3 changes: 3 additions & 0 deletions dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ dependencies {
require("[${forge.versions.mixinExtras.get()},)")
}

// Core submodule (pure Java — no Forge/MC/AE2 references)
implementation project(':core')

// AE2
modImplementation(forge.ae2)
modCompileOnly(forge.ae2wtlib)
Expand Down
7 changes: 7 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,10 @@ mod_license = LGPL-3.0 license
mod_url = https://github.com/kuba6000/AE2-Web-Integration
mod_issue_tracker = https://github.com/kuba6000/AE2-Web-Integration/issues/
maven_group =

# Shadow core submodule into the production jar (see gradle/scripts/shadow.gradle)
usesShadowedDependencies = true
# Shadow minimize() resolves runtimeClasspath at configuration time and needs MCP
# artifacts; that breaks fresh CI before createMinecraftArtifacts runs (MDG).
minimizeShadowedDependencies = false
relocateShadowedDependencies = true
8 changes: 7 additions & 1 deletion gradle/scripts/jars.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,13 @@ base {
}

afterEvaluate {
reobfJar.archiveClassifier = ""
if (findProperty('usesShadowedDependencies')?.toString()?.toBoolean()) {
tasks.named('reobfShadowJar').configure {
archiveClassifier = ''
}
} else {
reobfJar.archiveClassifier = ''
}
tasks.withType(org.gradle.jvm.tasks.Jar).configureEach {
destinationDirectory = file('build/libs/')
manifest.attributes([
Expand Down
63 changes: 63 additions & 0 deletions gradle/scripts/shadow.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
def shadowRelocationPrefix = 'pl.kuba6000.ae2webintegration.shadow'

configurations {
coreShadow {
canBeConsumed = false
canBeResolved = true
}
}

dependencies {
coreShadow(project(':core')) {
transitive = true
}
}

tasks.named('shadowJar').configure {
dependsOn(':core:jar', 'createMinecraftArtifacts')
archiveClassifier = 'dev'
configurations = [project.configurations.coreShadow]

dependencies {
exclude(dependency('org.apache.logging.log4j:log4j-api:.*'))
exclude(dependency('org.apache.logging.log4j:log4j-core:.*'))
}

if (findProperty('minimizeShadowedDependencies')?.toString()?.toBoolean() != false) {
minimize()
}
if (findProperty('relocateShadowedDependencies')?.toString()?.toBoolean() != false) {
relocate('com.google', "${shadowRelocationPrefix}.com.google")
relocate('org.apache.commons', "${shadowRelocationPrefix}.org.apache.commons")
relocate('commons-io', "${shadowRelocationPrefix}.commons-io")
relocate('club.minnced', "${shadowRelocationPrefix}.club.minnced")
relocate(
'pl.kuba6000.ae2webintegration.core',
"${shadowRelocationPrefix}.pl.kuba6000.ae2webintegration.core")
}
}

tasks.named('jar', Jar).configure {
enabled = false
finalizedBy(tasks.named('shadowJar'))
}

obfuscation {
reobfuscate(tasks.named('shadowJar'), sourceSets.main) {
archiveClassifier = ''
}
}

// MDG still wires reobfJar for the disabled plain jar task — turn it off to avoid clashing with reobfShadowJar.
tasks.named('reobfJar').configure {
enabled = false
}

configurations.runtimeElements.outgoing.artifacts.clear()
configurations.apiElements.outgoing.artifacts.clear()
configurations.runtimeElements.outgoing.artifact(tasks.named('shadowJar'))
configurations.apiElements.outgoing.artifact(tasks.named('shadowJar'))

configurations.named('shadowRuntimeElements') {
outgoing.artifacts.clear()
}
2 changes: 2 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ dependencyResolutionManagement {
}

rootProject.name = "${mod_id}"

include ':core'
Original file line number Diff line number Diff line change
@@ -1,44 +1,72 @@
package pl.kuba6000.ae2webintegration.ae2interface;

import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.event.server.ServerStartedEvent;
import net.minecraftforge.event.server.ServerStoppingEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.IExtensionPoint;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.config.ModConfig;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.network.NetworkConstants;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import pl.kuba6000.ae2webintegration.ae2interface.commands.CommandBuilder;
import pl.kuba6000.ae2webintegration.ae2interface.config.Config;
import pl.kuba6000.ae2webintegration.ae2interface.implementations.AE;
import pl.kuba6000.ae2webintegration.ae2interface.platform.Platform;
import pl.kuba6000.ae2webintegration.ae2interface.proxy.CommonProxy;
import pl.kuba6000.ae2webintegration.core.CommandBootstrap;
import pl.kuba6000.ae2webintegration.core.api.IAEWebInterface;

@Mod(value = AE2WebIntegration.MODID)
@Mod.EventBusSubscriber(modid = AE2WebIntegration.MODID)
public class AE2WebIntegration {

public static final String MODID = "ae2webintegration_interface";
public static final String MODID = "ae2webintegration";
public static final Logger LOG = LogManager.getLogger(MODID);

private static final CommonProxy PROXY = new CommonProxy();

public AE2WebIntegration() {
Platform platform = new Platform();
String version = ModLoadingContext.get()
.getActiveContainer()
.getModInfo()
.getVersion()
.toString();

// Register config before anything that depends on it
ModLoadingContext.get()
.registerExtensionPoint(
IExtensionPoint.DisplayTest.class,
() -> new IExtensionPoint.DisplayTest(() -> NetworkConstants.IGNORESERVERONLY, (a, b) -> true));
// SecurityCache.registerOpPlayer(
// IAEWebInterface.getInstance()
// .getAEWebGameProfile());
.registerConfig(ModConfig.Type.COMMON, Config.SPEC, "ae2webintegration/ae2webintegration.toml");

// Delegate remaining init to the proxy
PROXY.preInit(platform, version);
}

@Mod.EventBusSubscriber(modid = MODID, bus = Mod.EventBusSubscriber.Bus.MOD)
private static class eventHandler {
private static class ModEventHandler {

@SubscribeEvent
public static void commonSetup(FMLCommonSetupEvent event) {
// This is where you can do common setup tasks
IAEWebInterface.getInstance()
.initAEInterface(AE.instance);
}
}

@SubscribeEvent
public static void commandsRegister(RegisterCommandsEvent event) {
CommandBootstrap.init(new CommandBuilder(event.getDispatcher()));
}

@SubscribeEvent
public static void serverStarted(ServerStartedEvent event) {
PROXY.onServerStarted();
}

@SubscribeEvent
public static void serverStopping(ServerStoppingEvent event) {
PROXY.onServerStopping();
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
package pl.kuba6000.ae2webintegration.core;
package pl.kuba6000.ae2webintegration.ae2interface;

import static pl.kuba6000.ae2webintegration.core.AE2WebIntegration.MODID;

import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

import pl.kuba6000.ae2webintegration.core.AE2Controller;
import pl.kuba6000.ae2webintegration.core.UpdateNotifier;
import pl.kuba6000.ae2webintegration.core.ae2request.sync.ISyncedRequest;
import pl.kuba6000.ae2webintegration.core.utils.VersionChecker;
import pl.kuba6000.ae2webintegration.core.api.PlayerIdentity;

@Mod.EventBusSubscriber(modid = MODID)
@Mod.EventBusSubscriber(modid = AE2WebIntegration.MODID)
public class FMLEventHandler {

@SubscribeEvent
Expand All @@ -32,13 +30,11 @@ public static void tick(TickEvent.ServerTickEvent event) {
@SubscribeEvent
public static void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) {
Player player = event.getEntity();
if (!(player instanceof ServerPlayer)) return;
if (Config.INSTANCE.CHECK_FOR_UPDATES.get() && VersionChecker.isOutdated() && player.hasPermissions(4)) {
player.sendSystemMessage(
Component.literal(
ChatFormatting.GREEN.toString() + ChatFormatting.BOLD
+ "----> AE2WebIntegration -> New version detected! Consider updating at https://github.com/kuba6000/AE2-Web-Integration/releases/latest"));
}
}
if (!(player instanceof ServerPlayer serverPlayer)) return;
if (!serverPlayer.hasPermissions(4)) return;

PlayerIdentity identity = new PlayerIdentity(serverPlayer.getUUID(), serverPlayer.getScoreboardName());
PlayerMessenger messenger = new PlayerMessenger();
UpdateNotifier.notifyPlayerIfOutdated(messenger, identity);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package pl.kuba6000.ae2webintegration.ae2interface;

import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.server.ServerLifecycleHooks;

import pl.kuba6000.ae2webintegration.core.api.IPlayerMessenger;
import pl.kuba6000.ae2webintegration.core.api.PlayerIdentity;

public class PlayerMessenger implements IPlayerMessenger {

@Override
public void sendMessage(PlayerIdentity player, String message) {
if (ServerLifecycleHooks.getCurrentServer() == null) return;
ServerPlayer serverPlayer = ServerLifecycleHooks.getCurrentServer()
.getPlayerList()
.getPlayer(player.uuid);
if (serverPlayer != null) {
serverPlayer.sendSystemMessage(
Component.literal(message)
.withStyle(ChatFormatting.GREEN, ChatFormatting.BOLD));
}
}
}
Loading
Loading