Files
CatServer/build.gradle
Calen 616089ba8e CatServer 1.20.1 (#928)
* Some updates

修改一些小问题

FoxServerLauncher#main
        launchArgs = Arrays.copyOf(launchArgs, launchArgs.length + args.length);
        System.arraycopy(args, 0, launchArgs, launchArgs.length, args.length);
如果有自带启动参数 会ArrayIndexOutOfBoundsException

ShearsDispenseItemBehavior#tryShearLivingEntity
在循环里ShearsDispenseItemBehavior.catserver$shearBukkitBlock.getAndSet(null),下一轮循环读到的会是null
在if里ShearsDispenseItemBehavior.catserver$shearBukkitBlock.getAndSet(null),如果没有进入if则catserver$shearBukkitBlock无法被重置
同时改用CatServerCaptures

ServerLevel#tickPassenger
bukkit加的p_8664_.postTick()处理生物通过地狱门时的传送,应该和p_8664_.rideTick()同时受forge加入的if(p_8664_.canUpdate())控制

ServerGamePacketListenerImpl#onDisconnect
cat注释掉的
// this.server.getPlayerList().remove(this.player); // CatServer - fix dupe player logout
但bukkit并没有留这一行
少了bukkit留下的this.player.disconnect();
看起来像是留错了诶(?)

ServerHandshakePacketListenerImpl#handleIntention
spigot的bug
这些翻译key被spigot换成String后应该是TextComponent(ChatMessage)
spigot1.20.1已修复

Entity#changeDimension
return前pop profiler

调用ServerLevel.makeObsidianPlatform时增加bukkit的this参数
                  ServerLevel.makeObsidianPlatform(serverLevel, this);

ItemEntity#tick
似乎把bukkit的patch放错位置了

bukkit:
             if (!this.level.isClientSide && this.age >= 6000) {
+                // CraftBukkit start - fire ItemDespawnEvent
+                if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemDespawnEvent(this).isCancelled()) {
+                    this.age = 0;
+                    return;
+                }
+                // CraftBukkit end
                 this.discard();
             }

LivingEntity#checkFallDamage
forge的.setPos(p_20993_)

LivingEntity#private void addEatEffect(ItemStack p_21064_, Level p_21065_, LivingEntity p_21066_)
重置cause为默认值UNKNOWN

LivingEntity#damageEntity0
改为bukkit的写法 用tag

LivingEntity#randomTeleport
flag和flag1写反辣

forge
      boolean flag = false;
      BlockPos blockpos = BlockPos.containing(p_20985_, p_20986_, p_20987_);
      Level level = this.level();
      if (level.hasChunkAt(blockpos)) {
         boolean flag1 = false;

         if (flag1) {
            this.teleportTo(p_20985_, d3, p_20987_);
bukkit
        boolean flag1 = false;
        BlockPosition blockposition = BlockPosition.containing(d0, d1, d2);
        World world = this.level();
        if (world.hasChunkAt(blockposition)) {
            boolean flag2 = false;

             if (flag2) {
-                this.teleportTo(d0, d6, d2);

+                this.setPos(d3, d4, d5);
+                if (flag1) {
+                    if (!(this instanceof EntityPlayer)) {

cat
      boolean flag = false;
      BlockPos blockpos = new BlockPos(p_20985_, p_20986_, p_20987_);
      Level level = this.level;
      if (level.hasChunkAt(blockpos)) {
         boolean flag1 = false;

         if (flag) {
            var cause = CatServerCaptures.getCatServerCaptures().getCaptureTeleportCause();
            // CraftBukkit start - Teleport event
            // this.teleportTo(p_20985_, d3, p_20987_);

            this.setPos(d0, d1, d2);
            if (flag1) {
               if (!(this instanceof ServerPlayer)) {

LivingEntity#heal
      this.resetRegainReason();
保证不进if也能重置
NaturalSpawner#spawnCategoryForPosition
p_47040_.addFreshEntityWithPassengers(mob);用capture传入的reason在ServerLevelAccessor#addFreshEntityWithPassengers未被接收
同时修改ServerLevelAccessor

Mob#convertTo
确保catserver$spawnReason重置
同时改用CatServerCaptures

ZombieVillager#tick
bukkit的
         super.tick();
+        this.lastTick = MinecraftServer.currentTick; // CraftBukkit
     }

net.minecraft.world.entity.player.Player#public void causeFoodExhaustion(float p_36400_)
this.catserver$causeFoodReason.getAndSet)在if里 如果没有进if的话catserver$causeFoodReason无法重置
同时改用CatServerCaptures

ThrownPotion#applySplash
bukkit的entity1

Raid#tick
似乎有一个bukkit的callRaidStopEvent的位置串了

AbstractMinecart#setDragAir
vanilla
this.setDeltaMovement(this.getDeltaMovement().scale(0.95D));
forge
this.setDeltaMovement(this.getDeltaMovement().scale(getDragAir()));
bukkit+cat
-            this.setDeltaMovement(this.getDeltaMovement().scale(0.95D));
+            // CraftBukkit start - replace magic numbers with our variables
+            this.setDeltaMovement(new Vec3D(this.getDeltaMovement().x * this.flyingX, this.getDeltaMovement().y * this.flyingY, this.getDeltaMovement().z * this.flyingZ));
+            // CraftBukkit end

这样的话 似乎forge的dragAir会失效
forge的xyz用同一个scale bukkit用3个 没法在保证各自正常功能的情况下用同一组scale来统一两边 所以用同相乘的关系
         this.setDeltaMovement(new Vec3(this.getDeltaMovement().x * this.flyingX, this.getDeltaMovement().y * this.flyingY, this.getDeltaMovement().z * this.flyingZ).scale(getDragAir()));

ChestMenu#getBukkitView
bukkit
      if (this.container instanceof PlayerInventory) { -> net.minecraft.world.entity.player.PlayerInventory(official:net.minecraft.world.entity.player.Inventory)

cat
      if (this.container instanceof PlayerInventory) { -> org.bukkit.inventory.PlayerInventory

EnchantmentMenu#slotsChanged
j用forge的float类型
改用独立的数组循环索引k

ArmorItem#dispenseArmor
bukkit
    public static boolean dispenseArmor(ISourceBlock isourceblock, ItemStack itemstack) {

            ItemStack itemstack1 = itemstack.split(1);

            if (event.isCancelled()) {
                itemstack.grow(1);
                return false;
            }

            if (!event.getItem().equals(craftItem)) {
                itemstack.grow(1);

cat
         ItemStack itemstack = p_40400_.split(1);

         if (event.isCancelled()) {
            itemstack.grow(1);
            return false;
         }
         if (!event.getItem().equals(craftItem)) {
            itemstack.grow(1);
            // Chain to handler for new item

应该是p_40400_

BaseSpawner/MobSpawnerAbstract#serverTick+CraftEventFactory#callSpawnerSpawnEvent
补充spigot patch(这个在1.20.1转为craftbukkit patch)
spigot1182

                        // Spigot Start
                        if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, blockposition).isCancelled()) {
                            Entity vehicle = entity.getVehicle();
                            if (vehicle != null) {
                                vehicle.discard();
                            }
                            for (Entity passenger : entity.getIndirectPassengers()) {
                                passenger.discard();
                            }
                            continue;
                        }
                        // Spigot End

CraftEventFactory
    public static SpawnerSpawnEvent callSpawnerSpawnEvent(Entity spawnee, BlockPos pos) {
        org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity entity = spawnee.getBukkitEntity();
        BlockState state = entity.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()).getState();
        if (!(state instanceof org.bukkit.block.CreatureSpawner)) {
            state = null;
        }

        SpawnerSpawnEvent event = new SpawnerSpawnEvent(entity, (org.bukkit.block.CreatureSpawner) state);
        entity.getServer().getPluginManager().callEvent(event);
        return event;
    }

BigDripleafBlock#private static void setTilt(BlockState p_152278_, Level p_152279_, BlockPos p_152280_, Tilt p_152281_)
循环调用了 似乎应该调用下面那个
顺便加个强转

CommandBlock#neighborChanged
flag和flag1

bukkit
                boolean flag1 = world.hasNeighborSignal(blockposition);
                boolean flag2 = tileentitycommand.isPowered();
                // CraftBukkit start
                org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ());
                int old = flag2 ? 15 : 0;
                int current = flag1 ? 15 : 0;

                BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bukkitBlock, old, current);
                world.getCraftServer().getPluginManager().callEvent(eventRedstone);
                flag1 = eventRedstone.getNewCurrent() > 0;
                // CraftBukkit end

cat
            boolean flag = p_51839_.hasNeighborSignal(p_51840_);
            boolean flag1 = commandblockentity.isPowered();
            // CraftBukkit start
            org.bukkit.block.Block bukkitBlock = p_51839_.getWorld().getBlockAt(p_51840_.getX(), p_51840_.getY(), p_51840_.getZ());
            int old = flag1 ? 15 : 0;
            int current = flag1 ? 15 : 0;
            BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bukkitBlock, old, current);
            p_51839_.getCraftServer().getPluginManager().callEvent(eventRedstone);
            flag1 = eventRedstone.getNewCurrent() > 0;
            // CraftBukkit end

AbstractFurnaceBlockEntity#getTotalCookTime
bukkit的patch

BeaconBlockEntity
#applyEffect
#applyEffects
, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.BEACON);

BeehiveBlockEntity
#releaseOccupant
#releaseAllOccupants
确保重置catserver$isForceReleaseAllOccupants catserver$isForceReleaseOccupant

BrewingStandBlockEntity#doBrew
确保catserver$captureBrewBlockEntity重置
同时改用CatServerCaptures

实现// CatServer TODO: missing BrewEvent result

HopperBlockEntity#ejectItems
bukkit
+                        ItemStack itemstack1 = addItem(iinventory, iinventory1, CraftItemStack.asNMSCopy(event.getItem()), enumdirection);
cat
                  ItemStack itemstack1 = addItem(p_155566_, p_155566_, CraftItemStack.asNMSCopy(event.getItem()), direction);

iinventory是method传入的漏斗p_155566_
iinventory1是getAttachedContainer返回的目标tileentity

HopperBlockEntity#private static boolean tryTakeInItemFromSlot(Hopper p_59355_, Container p_59356_, int p_59357_, Direction p_59358_)
考虑mod里implements Hopper的其他BlockEntity/Entity

FireBlock#updateShape
bukkit
+            if (!(generatoraccess instanceof World)) { -> net.minecraft.world.level.Level
cat
         if (!(p_53461_ instanceof World)) { -> org.bukkit.World

MushroomBlock#growMushroom
bukkit1201+1182
+        BlockSapling.treeType = (this == Blocks.BROWN_MUSHROOM) ? TreeType.BROWN_MUSHROOM : TreeType.BROWN_MUSHROOM; // CraftBukkit
cat1182
      SaplingBlock.treeType = (this == Blocks.BROWN_MUSHROOM) ? TreeType.BROWN_MUSHROOM : TreeType.BROWN_MUSHROOM; // CraftBukkit
bukkit12110
            BlockSapling.treeType = (this == Blocks.BROWN_MUSHROOM) ? TreeType.BROWN_MUSHROOM : TreeType.RED_MUSHROOM; // CraftBukkit

bukkit的bug

PistonBaseBlock#moveBlocks
BlockPos和Direction

bukkit
    private boolean moveBlocks(World world, BlockPosition blockposition, EnumDirection enumdirection, boolean flag) {
        BlockPosition blockposition1 = blockposition.relative(enumdirection);

            EnumDirection enumdirection1 = flag ? enumdirection : enumdirection.getOpposite();

+            final org.bukkit.block.Block bblock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ());

+                event = new BlockPistonExtendEvent(bblock, blocks, CraftBlock.notchToBlockFace(enumdirection1));
+            } else {
+                event = new BlockPistonRetractEvent(bblock, blocks, CraftBlock.notchToBlockFace(enumdirection1));

cat
   private boolean moveBlocks(Level p_60182_, BlockPos p_60183_, Direction p_60184_, boolean p_60185_) {
      BlockPos blockpos = p_60183_.relative(p_60184_);

         Direction direction = p_60185_ ? p_60184_ : p_60184_.getOpposite();

         final org.bukkit.block.Block bblock = p_60182_.getWorld().getBlockAt(blockpos.getX(), blockpos.getY(), blockpos.getZ());

            event = new BlockPistonExtendEvent(bblock, blocks, CraftBlock.notchToBlockFace(p_60184_));
         } else {
            event = new BlockPistonRetractEvent(bblock, blocks, CraftBlock.notchToBlockFace(p_60184_));

RedStoneOreBlock#private static void interact(BlockState p_55493_, Level p_55494_, BlockPos p_55495_)
setBlock保留if (!p_55493_.getValue(LIT))判断

* [1.18.2] Update capture value name

* CatServer 1.20.1

* Simple cleanups
2026-02-13 23:30:28 +08:00

1610 lines
75 KiB
Groovy

buildscript {
repositories {
mavenLocal()
maven { url = 'https://maven.minecraftforge.net/' }
mavenCentral()
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:[6.0.11,6.2)'
classpath "dev.vankka:gradle-plugin:2.0.0"
}
}
import net.minecraftforge.forge.tasks.checks.CheckATs
import net.minecraftforge.forge.tasks.checks.CheckExcs
import net.minecraftforge.forge.tasks.checks.CheckPatches
import net.minecraftforge.forge.tasks.checks.CheckSAS
import net.minecraftforge.forge.tasks.checks.CheckTask
import net.minecraftforge.forge.tasks.FixPatchImports // 1.20.1
import java.nio.file.Files
import net.minecraftforge.forge.tasks.*
import static net.minecraftforge.forge.tasks.Util.*
import net.minecraftforge.gradle.common.tasks.ApplyBinPatches
import net.minecraftforge.gradle.common.tasks.CheckJarCompatibility
import net.minecraftforge.gradle.common.tasks.DownloadMavenArtifact
import net.minecraftforge.gradle.common.tasks.ExtractInheritance
import net.minecraftforge.gradle.common.tasks.SignJar
import net.minecraftforge.gradle.userdev.tasks.RenameJar
import org.apache.tools.ant.filters.ReplaceTokens
import org.gradle.plugins.ide.eclipse.model.SourceFolder
import org.objectweb.asm.Opcodes // 1.20.1
plugins {
id 'com.github.ben-manes.versions' version '0.46.0'
id 'net.minecraftforge.gradleutils' version '[2.2,2.3)'
id 'eclipse'
id 'de.undercouch.download' version '5.4.0'
}
Util.init() //Init all our extension methods!
def gitVersion = 'git rev-parse --short HEAD'.execute().text.trim()
ext {
JAR_SIGNER = null
MAPPING_CHANNEL = 'official'
MAPPING_VERSION = '1.20.1'
MC_VERSION = '1.20.1'
MCP_VERSION = '20230612.114412'
SPI_VERSION = '7.0.1'
ACCESSTRANSFORMERS_VERSION = '8.0.4'
COREMODS_VERSION = '5.2.4'
EVENTBUS_VERSION = '6.0.5'
MODLAUNCHER_VERSION = '10.0.9'
SECUREJARHANDLER_VERSION = '2.1.10'
BOOTSTRAPLAUNCHER_VERSION = '1.1.2'
ASM_VERSION = '9.8'
INSTALLER_VERSION = '2.2.+'
MIXIN_VERSION = '0.8.5'
JARJAR_VERSION = '0.3.19'
// CatServer start - 1.20.1 from Forge
JETBRAINS_ANNOTATIONS_VERSION = '23.0.0'
MERGETOOL_VERSION = '1.1.5'
LOG4J_VERSION = '2.19.0'
SLF4J_API_VERSION = '2.0.1'
GUAVA_VERSION = '31.1-jre'
GSON_VERSION = '2.10'
APACHE_MAVEN_ARTIFACT_VERSION = '3.9.6'
APACHE_COMMONS_LANG3_VERSION = '3.12.0'
NIGHTCONFIG_VERSION = '3.6.4'
MOJANG_LOGGING_VERSION = '1.1.1'
JOPT_SIMPLE_VERSION = '5.0.4'
TERMINALCONSOLEAPPENDER_VERSION = '1.2.0'
JLINE_VERSION = '3.12.+'
COMMONS_IO_VERSION = '2.11.0'
// CatServer end
// Paper
adventureVersion = '4.14.0'
GIT_INFO = gradleutils.gitInfo
FORGE_VERSION = "47.4.10"
VERSION = "1.20.1-$FORGE_VERSION"
CATSERVER_VERSION = "1.20.1-" + gitVersion
// FML_VERSION = gradleutils.getFilteredMCTagOffsetBranchVersion(true, 'FML', MC_VERSION)
BINPATCH_TOOL = 'net.minecraftforge:binarypatcher:1.1.1:fatjar'
INSTALLER_TOOLS = 'net.minecraftforge:installertools:1.4.1'
JAR_SPLITTER = 'net.minecraftforge:jarsplitter:1.1.4'
FART = 'net.minecraftforge:ForgeAutoRenamingTool:0.1.22:all'
MIN_TAG_FOR_CHANGELOG = "41.0"
// remove :fatjar
BIN_PATCHER = BINPATCH_TOOL.substring(0, BINPATCH_TOOL.length() - 1 - BINPATCH_TOOL.split(':')[3].length())
}
println('Version: ' + VERSION +
' Java: ' + System.getProperty('java.version') +
' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ')' +
' Arch: ' + System.getProperty('os.arch'))
task downloadVersionManifest(type: Download) {
src 'https://piston-meta.mojang.com/mc/game/version_manifest_v2.json'
dest file('build/versions/version_manifest.json')
useETag 'all'
onlyIfModified true
quiet true
}
task downloadJson(type: Download, dependsOn: downloadVersionManifest) {
inputs.file downloadVersionManifest.dest
src { downloadVersionManifest.dest.json.versions.find{ it.id == MC_VERSION }.url }
dest file("build/versions/${MC_VERSION}/version.json")
useETag 'all'
onlyIfModified true
quiet true
}
['client', 'server'].each { id ->
task "download${id.capitalize()}Raw"(type: Download, dependsOn: downloadJson) {
inputs.file downloadJson.dest
src { downloadJson.dest.json.downloads.get(id).url }
dest file("build/versions/${MC_VERSION}/${id}.jar")
useETag 'all'
onlyIfModified true
quiet true
}
}
subprojects {
apply plugin: 'eclipse'
apply plugin: 'java'
group = 'net.minecraftforge'
version = VERSION
//println(name + ' Version: ' + version)
repositories {
mavenLocal()
mavenCentral()
maven {
name = 'forge'
url = 'https://maven.minecraftforge.net/'
}
maven { url 'https://hub.spigotmc.org/nexus/content/groups/public/' }
}
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
tasks.withType(Javadoc).configureEach {
options.tags = [
'apiNote:a:<em>API Note:</em>',
'implSpec:a:<em>Implementation Requirements:</em>',
'implNote:a:<em>Implementation Note:</em>'
]
options.addStringOption('Xdoclint:all,-missing', '-public')
}
}
project(':mcp') {
apply plugin: 'net.minecraftforge.gradle.mcp'
tasks.withType(AbstractPublishToMaven.class).forEach{tsk -> tsk.enabled = false } // We don't want to publish anything
mcp {
config MC_VERSION + '-' + MCP_VERSION
pipeline = 'joined'
}
}
project(':clean') {
evaluationDependsOn(':mcp')
apply plugin: 'net.minecraftforge.gradle.patcher'
tasks.withType(AbstractPublishToMaven.class).forEach{tsk -> tsk.enabled = false } // We don't want to publish anything
dependencies {
implementation 'net.minecraftforge:forgespi:' + SPI_VERSION
}
patcher {
parent = project(':mcp')
mcVersion = MC_VERSION
patchedSrc = file('src/main/java')
mappings channel: MAPPING_CHANNEL, version: MAPPING_VERSION
runs {
clean_client {
client true
taskName 'clean_client'
ideaModule "${rootProject.name}.${project.name}.main"
main 'net.minecraft.client.main.Main'
workingDirectory project.file('run')
args '--gameDir', '.'
args '--version', MC_VERSION
args '--assetsDir', downloadAssets.output
args '--assetIndex', '{asset_index}'
args '--accessToken', '0'
}
clean_server {
client false
taskName 'clean_server'
ideaModule "${rootProject.name}.${project.name}.main"
main 'net.minecraft.server.Main'
workingDirectory project.file('run')
}
}
}
}
def sharedDeps = {
moduleonly "cpw.mods:securejarhandler:${SECUREJARHANDLER_VERSION}"
moduleonly "org.ow2.asm:asm:${ASM_VERSION}"
moduleonly "org.ow2.asm:asm-commons:${ASM_VERSION}"
moduleonly "org.ow2.asm:asm-tree:${ASM_VERSION}"
moduleonly "org.ow2.asm:asm-util:${ASM_VERSION}"
moduleonly "org.ow2.asm:asm-analysis:${ASM_VERSION}"
moduleonly "cpw.mods:bootstraplauncher:${BOOTSTRAPLAUNCHER_VERSION}"
moduleonly "net.minecraftforge:JarJarFileSystems:${JARJAR_VERSION}"
installer "cpw.mods:securejarhandler:${SECUREJARHANDLER_VERSION}"
installer "org.ow2.asm:asm:${ASM_VERSION}"
installer "org.ow2.asm:asm-commons:${ASM_VERSION}"
installer "org.ow2.asm:asm-tree:${ASM_VERSION}"
installer "org.ow2.asm:asm-util:${ASM_VERSION}"
installer "org.ow2.asm:asm-analysis:${ASM_VERSION}"
installer "net.minecraftforge:accesstransformers:${ACCESSTRANSFORMERS_VERSION}"
installer 'org.antlr:antlr4-runtime:4.9.1' // Dep of AccessTransformer
installer "net.minecraftforge:eventbus:${EVENTBUS_VERSION}"
installer "net.minecraftforge:forgespi:${SPI_VERSION}"
installer "net.minecraftforge:coremods:${COREMODS_VERSION}"
installer "cpw.mods:modlauncher:${MODLAUNCHER_VERSION}"
installer 'net.minecraftforge:unsafe:0.2.+'
installer "net.minecraftforge:mergetool:${MERGETOOL_VERSION}:api"
installer "com.electronwill.night-config:core:${NIGHTCONFIG_VERSION}"
installer "com.electronwill.night-config:toml:${NIGHTCONFIG_VERSION}"
installer "org.apache.maven:maven-artifact:${APACHE_MAVEN_ARTIFACT_VERSION}"
installer 'org.apache.commons:commons-lang3:3.12.0'
installer 'net.jodah:typetools:0.6.3'
installer "net.minecrell:terminalconsoleappender:${TERMINALCONSOLEAPPENDER_VERSION}"
installer "org.jline:jline-reader:${JLINE_VERSION}" // Dep of TerminaalConsoleeAppender
installer "org.jline:jline-terminal:${JLINE_VERSION}" // Dep of TerminaalConsoleeAppender
installer 'org.jline:jline-terminal-jansi:3.12.1'
installer "org.spongepowered:mixin:${MIXIN_VERSION}"
installer 'org.openjdk.nashorn:nashorn-core:15.3'
installer "net.minecraftforge:JarJarSelector:${JARJAR_VERSION}"
installer "net.minecraftforge:JarJarMetadata:${JARJAR_VERSION}"
// bukkit
moduleonly 'commons-lang:commons-lang:2.6'
moduleonly 'commons-codec:commons-codec:1.10'
installer 'org.yaml:snakeyaml:2.0'
compileOnly 'org.jetbrains:annotations:24.0.1'
// craftbukkit
installer 'org.fusesource.jansi:jansi:1.18'
installer 'jline:jline:2.12.1'
installer 'com.googlecode.json-simple:json-simple:1.1.1'
installer 'org.xerial:sqlite-jdbc:3.42.0.0'
installer 'mysql:mysql-connector-java:8.0.33'
installer 'org.apache.logging.log4j:log4j-iostreams:2.19.0'
installer 'net.md-5:SpecialSource:1.10.0'
// spigot
installer 'net.md-5:bungeecord-chat:1.20-R0.1'
// paper
/*
installer "org.spongepowered:configurate-yaml:4.2.0"
installer "net.kyori:adventure-bom:${adventureVersion}"
installer "net.kyori:adventure-api:${adventureVersion}"
installer "net.kyori:adventure-text-minimessage:${adventureVersion}"
installer "net.kyori:adventure-text-serializer-gson:${adventureVersion}"
installer "net.kyori:adventure-text-serializer-legacy:${adventureVersion}"
installer "net.kyori:adventure-text-serializer-plain:${adventureVersion}"
installer "net.kyori:adventure-text-logger-slf4j:${adventureVersion}"
*/
/*
installer 'org.lwjgl:lwjgl:3.2.2'
installer 'org.lwjgl:lwjgl-glfw:3.2.2'
installer 'org.lwjgl:lwjgl-opengl:3.2.2'
installer 'org.lwjgl:lwjgl-stb:3.2.2'
*/
}
def sharedFmlonlyForge = { Project prj ->
['Client', 'Server', 'Joined'].each { side ->
['slim', 'extra'].each { type ->
prj.task([type: DownloadMavenArtifact], "download${side}${type.capitalize()}") {
artifact = "net.minecraft:${side.toLowerCase()}:${MC_VERSION}-${MCP_VERSION}:${type}"
}
}
if (side.equals('Joined')) {
prj.task([type: DownloadMavenArtifact], "createJoinedSRG") {
artifact = "net.minecraft:joined:${MC_VERSION}-${MCP_VERSION}:srg"
}
} else {
prj.task([type: RenameJar, dependsOn: prj.tasks.createMcp2Srg], "create${side}SRG") {
tool = FART
args = [
'--input', '{input}',
'--output', '{output}',
'--names', '{mappings}',
'--ann-fix', '--ids-fix', '--src-fix', '--record-fix'
]
mappings = prj.tasks.createMcp2Srg.srg
input = prj.tasks.getByName("download${side}Slim").output
output = prj.file("build/create${side}SRG/output.jar")
}
}
def gen = prj.tasks.getByName("gen${side}BinPatches")
def createSRG = prj.tasks.getByName("create${side}SRG")
gen.dependsOn(createSRG)
gen.tool = BINPATCH_TOOL
gen.cleanJar = createSRG.output
prj.task([type: ApplyBinPatches, dependsOn: gen], "apply${side}BinPatches") {
clean = gen.cleanJar
patch = gen.output
tool = BINPATCH_TOOL
}
}
prj.task([type: DownloadMavenArtifact], 'downloadInstaller') {
artifact = "net.minecraftforge:installer:${INSTALLER_VERSION}:shrunk"
changing = true
}
prj.tasks.userdevConfig {
def launchPrefix = prj.name == "forge" ? "forge" : "fml"
getArtifacts(prj, prj.configurations.installer, true).each { key, lib -> libraries.add(lib.name) }
getArtifacts(prj, prj.configurations.moduleonly, true).each { key, lib ->
libraries.add(lib.name)
modules.add(lib.name)
}
for (child in prj.ext.PACKED_DEPS) {
libraries.add(Util.getMavenDep(rootProject.tasks.findByPath(child)))
}
//libraries.add("${project.group}:${project.name}:${project.version}:launcher")
inject = '' // We don't have a userdev sourceset anymore. Empty as a gradle workaround...
runs {
client {
environment 'MOD_CLASSES', '{source_roots}'
environment 'MCP_MAPPINGS', '{mcp_mappings}'
// Natives are loaded from the classpath now in all cases
// property 'nativesDirectory', '{natives}'
if (prj.name == 'forge') {
property 'forge.enableGameTest', 'true'
}
args '--launchTarget', "${launchPrefix}clientuserdev"
args '--version', 'MOD_DEV'
args '--assetIndex', '{asset_index}'
args '--assetsDir', '{assets_root}'
}
server {
environment 'MOD_CLASSES', '{source_roots}'
environment 'MCP_MAPPINGS', '{mcp_mappings}'
if (prj.name == 'forge') {
property 'forge.enableGameTest', 'true'
}
args '--launchTarget', "${launchPrefix}serveruserdev"
}
if (prj.name == 'forge') {
gameTestServer {
environment 'MOD_CLASSES', '{source_roots}'
environment 'MCP_MAPPINGS', '{mcp_mappings}'
args '--launchTarget', "${launchPrefix}gametestserveruserdev"
}
}
data {
environment 'MOD_CLASSES', '{source_roots}'
environment 'MCP_MAPPINGS', '{mcp_mappings}'
args '--launchTarget', "${launchPrefix}datauserdev"
args '--assetIndex', '{asset_index}'
args '--assetsDir', '{assets_root}'
}
}
}
def userdevRuns = prj.tasks.userdevConfig.runs
for (def run : prj.patcher.runs + userdevRuns) {
if (run.parents) continue // We already added this to the parent run config
//run.property 'bsl.debug', 'true'
run.main 'cpw.mods.bootstraplauncher.BootstrapLauncher'
run.args '--gameDir', '.'
run.args '--fml.forgeVersion', FORGE_VERSION
run.args '--fml.mcVersion', MC_VERSION
run.args '--fml.forgeGroup', prj.group
run.args '--fml.mcpVersion', MCP_VERSION
run.jvmArgs '-Djava.net.preferIPv6Addresses=system'
if (run.name.contains('client')) {
run.client true
} else {
run.client false
}
// SecureJarHandler bootstrap values.
run.property 'ignoreList', prj.configurations.moduleonly.files.collect {it.name.replaceAll(/([-_]([.\d]*\d+)|\.jar$)/, '') }.join(',') + ",client-extra,fmlcore,fmlearlydisplay,javafmllanguage,lowcodelanguage,mclanguage,${prj.name}-"
// FIXME: Without this jna doesn't work at runtime. Someone figure out why please?
run.property 'mergeModules', 'jna-5.12.1.jar,jna-platform-5.12.1.jar'
if (userdevRuns.contains(run)) {
run.property 'legacyClassPath.file', '{minecraft_classpath_file}'
run.jvmArgs '-p', '{modules}'
} else {
run.property 'legacyClassPath.file', '{runtime_classpath_file}'
run.jvmArgs '-p', prj.configurations.moduleonly.files.collect { it.path }.join(File.pathSeparator)
}
run.jvmArgs '--add-modules', 'ALL-MODULE-PATH'
// Additions to these JVM module args should be mirrored to server_files/args.txt and other similar blocks in the buildscript
run.jvmArgs '--add-opens', 'java.base/java.util.jar=cpw.mods.securejarhandler'
run.jvmArgs '--add-opens', 'java.base/java.lang.invoke=cpw.mods.securejarhandler'
run.jvmArgs '--add-exports', 'java.base/sun.security.util=cpw.mods.securejarhandler'
run.jvmArgs '--add-exports', 'jdk.naming.dns/com.sun.jndi.dns=java.naming'
}
for (def run : prj.patcher.runs) {
if (run.parents) continue // We already added this to the parent run config
run.workingDirectory prj.file('run')
if (run.name.contains('client') || run.name.contains('data')) {
// Natives are loaded from the classpath now in all cases
// run.property 'nativesDirectory', prj.extractNatives.output.get().asFile
run.args '--assetsDir', prj.downloadAssets.output
run.args '--assetIndex', "{asset_index}"
}
if (run.name.contains('client')) {
run.property 'org.lwjgl.system.SharedLibraryExtractDirectory', 'lwjgl_dll'
run.args '--username', 'Dev'
run.args '--version', prj.name
run.args '--uuid', '0'
run.args '--accessToken', '0'
run.args '--userType', 'mojang'
run.args '--versionType', 'release'
}
if (prj.name == 'forge') {
run.environment 'FORGE_SPEC', prj.SPEC_VERSION
}
}
eclipse.project.resourceFilter {
appliesTo = 'FOLDERS'
type = 'EXCLUDE_ALL'
matcher {
id = 'org.eclipse.ui.ide.multiFilter'
arguments = '1.0-name-matches-false-false-run'
}
}
def MODULE_PATH = Util.getArtifactsOffline(prj, prj.configurations.moduleonly, false).values().collect{"libraries/${it.downloads.artifact.path}"}
def tokens = [
TASK: prj.name.equals('forge') ? 'forgeserver' : 'fmlserver',
MAVEN_PATH: prj.ext.MAVEN_PATH.toString(),
FORGE_VERSION: FORGE_VERSION,
MC_VERSION: MC_VERSION,
MCP_VERSION: MCP_VERSION,
FORGE_GROUP: prj.group,
IGNORE_LIST: Util.getArtifactsOffline(prj, prj.configurations.moduleonly, false).values().collect{it.downloads.artifact.path.rsplit('/', 1)[1]}.join(','),
MODULES: 'ALL-MODULE-PATH'
]
prj.task('makeClasspathFiles') {
doLast {
def CLASS_PATH = Util.getArtifactsOffline(prj, prj.configurations.installer, false).values().collect{"libraries/${it.downloads.artifact.path}"} +
[
'libraries/' + Util.getMavenPath(rootProject.tasks.findByPath(':fmlloader:jar')),
"libraries/net/minecraft/server/${MC_VERSION}-${MCP_VERSION}/server-${MC_VERSION}-${MCP_VERSION}-extra.jar"
]
def claimed = CLASS_PATH.collect{ it.rsplit('/', 2)[0] }.toSet() // Allow us to override versions
CLASS_PATH +=
(
[
"libraries/com/github/oshi/oshi-core/6.2.2/oshi-core-6.2.2.jar",
"libraries/com/google/code/gson/gson/2.10.1/gson-2.10.1.jar",
"libraries/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar",
"libraries/com/google/guava/guava/31.1-jre/guava-31.1-jre.jar",
"libraries/com/mojang/authlib/4.0.43/authlib-4.0.43.jar",
"libraries/com/mojang/brigadier/1.1.8/brigadier-1.1.8.jar",
"libraries/com/mojang/datafixerupper/6.0.8/datafixerupper-6.0.8.jar",
"libraries/com/mojang/javabridge/1.2.24/javabridge-1.2.24.jar",
"libraries/com/mojang/logging/1.1.1/logging-1.1.1.jar",
"libraries/commons-codec/commons-codec/1.10/commons-codec-1.10.jar",
"libraries/commons-io/commons-io/2.11.0/commons-io-2.11.0.jar",
"libraries/io/netty/netty-transport-native-unix-common/4.1.82.Final/netty-transport-native-unix-common-4.1.82.Final.jar",
"libraries/io/netty/netty-transport-native-epoll/4.1.82.Final/netty-transport-native-epoll-4.1.82.Final-linux-aarch_64.jar",
"libraries/io/netty/netty-transport-native-epoll/4.1.82.Final/netty-transport-native-epoll-4.1.82.Final-linux-x86_64.jar",
"libraries/io/netty/netty-transport-classes-epoll/4.1.82.Final/netty-transport-classes-epoll-4.1.82.Final.jar",
"libraries/io/netty/netty-transport/4.1.82.Final/netty-transport-4.1.82.Final.jar",
"libraries/io/netty/netty-resolver/4.1.82.Final/netty-resolver-4.1.82.Final.jar",
"libraries/io/netty/netty-handler/4.1.82.Final/netty-handler-4.1.82.Final.jar",
"libraries/io/netty/netty-common/4.1.82.Final/netty-common-4.1.82.Final.jar",
"libraries/io/netty/netty-codec/4.1.82.Final/netty-codec-4.1.82.Final.jar",
"libraries/io/netty/netty-buffer/4.1.82.Final/netty-buffer-4.1.82.Final.jar",
"libraries/it/unimi/dsi/fastutil/8.5.9/fastutil-8.5.9.jar",
"libraries/net/java/dev/jna/jna/5.12.1/jna-5.12.1.jar",
"libraries/net/java/dev/jna/jna-platform/5.12.1/jna-platform-5.12.1.jar",
"libraries/net/sf/jopt-simple/jopt-simple/5.0.4/jopt-simple-5.0.4.jar",
"libraries/org/apache/commons/commons-lang3/3.12.0/commons-lang3-3.12.0.jar",
"libraries/org/apache/logging/log4j/log4j-api/2.19.0/log4j-api-2.19.0.jar",
"libraries/org/apache/logging/log4j/log4j-core/2.19.0/log4j-core-2.19.0.jar",
"libraries/org/apache/logging/log4j/log4j-slf4j2-impl/2.19.0/log4j-slf4j2-impl-2.19.0.jar",
"libraries/org/joml/joml/1.10.5/joml-1.10.5.jar", // 1.20.1
"libraries/org/slf4j/slf4j-api/2.0.1/slf4j-api-2.0.1.jar",
// plugin-only handled in FoxServerLauncher
"libraries/plugin-only/org/apache/maven/maven-model/3.9.6/maven-model-3.9.6.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/maven-model-builder/3.9.6/maven-model-builder-3.9.6.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/maven-resolver-provider/3.9.6/maven-resolver-provider-3.9.6.jar",
"libraries/plugin-only/org/apache/maven/maven-builder-support/3.9.6/maven-builder-support-3.9.6.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/maven-repository-metadata/3.9.6/maven-repository-metadata-3.9.6.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/resolver/maven-resolver-api/1.9.18/maven-resolver-api-1.9.18.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/resolver/maven-resolver-impl/1.9.18/maven-resolver-impl-1.9.18.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/resolver/maven-resolver-spi/1.9.18/maven-resolver-spi-1.9.18.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/resolver/maven-resolver-util/1.9.18/maven-resolver-util-1.9.18.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/resolver/maven-resolver-named-locks/1.9.18/maven-resolver-named-locks-1.9.18.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/resolver/maven-resolver-connector-basic/1.9.18/maven-resolver-connector-basic-1.9.18.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/resolver/maven-resolver-transport-file/1.9.18/maven-resolver-transport-file-1.9.18.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/resolver/maven-resolver-transport-http/1.9.18/maven-resolver-transport-http-1.9.18.jar", // 1.20.1
"libraries/org/apache/http/httpclient/4.5.14/httpclient-4.5.14.jar", // 1.20.1
"libraries/org/apache/http/httpcore/4.4.14/httpcore-4.4.14.jar", // 1.20.1
"libraries/javax/inject/1/javax.inject-1.jar", // 1.20.1
"libraries/org/apache/commons/logging/jcl-over-slf4j/1.7.36/jcl-over-slf4j-1.7.36.jar", // 1.20.1
"libraries/org/eclipse/sisu/org.eclipse.sisu.inject/0.3.5/org.eclipse.sisu.inject-0.3.5.jar", // 1.20.1
"libraries/org/codehaus/plexus/interpolation/plexus-interpolation/1.26/plexus-interpolation-1.26.jar", // 1.20.1
"libraries/org/codehaus/plexus/util/plexus-utils/3.5.1/plexus-utils-3.5.1.jar", // 1.20.1
"libraries/com/google/protobuf/protobuf-java/3.21.9/protobuf-java-3.21.9.jar" // 1.20.1
].findAll { it.startsWith('libraries/') && !claimed.contains(it.rsplit('/', 2)[0]) }
)
configure(prj.installerJar) {
from(rootProject.file('server_files/args.txt')) {
filter(ReplaceTokens, tokens: tokens + [MODULE_PATH: MODULE_PATH.join(';'), CLASS_PATH: CLASS_PATH.join(';')])
rename { 'data/win_args.txt' }
}
from(rootProject.file('server_files/args.txt')) {
filter(ReplaceTokens, tokens: tokens + [MODULE_PATH: MODULE_PATH.join(':'), CLASS_PATH: CLASS_PATH.join(':')])
rename { 'data/unix_args.txt' }
}
}
}
}
/*
prj.afterEvaluate {
prj.installerJar {
dependsOn('makeClasspathFiles')
from(rootProject.file('server_files/')) {
exclude 'args.txt'
filter(ReplaceTokens, tokens: tokens)
into('data/')
//rename 'run.sh', "run_forge_${VERSION.replace('-', '_').sh"
//rename 'run.bat', "run_forge_${VERSION.replace('-', '_').bat"
}
}
}
*/
}
def symlink = file("$rootDir/fmlonly/src/fmlcommon")
def symlinkValid = symlink.exists() && symlink.directory
if (symlinkValid)
project(':fmlonly') {
evaluationDependsOn(':mcp')
apply plugin: 'java-library'
apply plugin: 'net.minecraftforge.gradle.patcher'
ext {
MCP_ARTIFACT = project(':mcp').mcp.config.get()
PACKED_DEPS = [':fmlcore:jar', ':fmlloader:jar', ':fmlearlydisplay:jar', ':javafmllanguage:jar', ':lowcodelanguage:jar', ':mclanguage:jar']
MAVEN_PATH = "${group.replace('.', '/')}/${project.name}/${VERSION}"
}
sourceSets {
main {
java {
srcDirs = ["$rootDir/fmlonly/src/fmlcommon/java", "$rootDir/fmlonly/src/main/java"]
}
resources {
srcDirs = ["$rootDir/fmlonly/src/fmlcommon/resources", "$rootDir/fmlonly/src/main/resources"]
}
}
}
configurations {
modu0leonly
installer {
// Don't pull all libraries, if we're missing something, add it to the installer list so the installer knows to download it.
transitive = false
}
api.extendsFrom(installer)
}
// TODO: Better coordination between project dependencies and the installer.
dependencies {
implementation project(':fmlcore')
implementation project(':fmlloader')
implementation project(':fmlearlydisplay')
implementation project(':javafmllanguage')
implementation project(':lowcodelanguage')
implementation project(':mclanguage')
runtimeOnly "cpw.mods:bootstraplauncher:${BOOTSTRAPLAUNCHER_VERSION}"
}
dependencies sharedDeps
patcher {
parent = project(':mcp')
mcVersion = MC_VERSION
patchedSrc = file('src/main/java')
mappings channel: MAPPING_CHANNEL, version: MAPPING_VERSION
runs {
fmlonly_client {
args '--launchTarget', 'fmlclientdev'
ideaModule "${rootProject.name}.${project.name}.main"
mods {
minecraft { source sourceSets.main }
}
}
fmlonly_server {
args '--launchTarget', 'fmlserverdev'
ideaModule "${rootProject.name}.${project.name}.main"
mods {
minecraft { source sourceSets.main }
}
}
}
}
sharedFmlonlyForge.call(project)
task launcherJson(type: LauncherJson) {
packedDependencies = [':fmlloader:jar',':fmlearlydisplay:jar']
doFirst {
def fmlonly_client = project(':fmlonly').patcher.runs.fmlonly_client
json = [
_comment_: comment,
id: id,
time: timestamp,
releaseTime: timestamp,
type: 'release',
mainClass: 'cpw.mods.bootstraplauncher.BootstrapLauncher',
inheritsFrom: MC_VERSION,
logging: {},
arguments: [
game: ['--launchTarget', 'fmlclient',
'--fml.forgeVersion', FORGE_VERSION,
'--fml.mcVersion', MC_VERSION,
'--fml.forgeGroup', project.group,
'--fml.mcpVersion', MCP_VERSION],
jvm: ["-DignoreList=${fmlonly_client.properties.ignoreList},\${version_name}.jar",
"-DmergeModules=${fmlonly_client.properties.mergeModules}",
'-DlibraryDirectory=${library_directory}',
'-p', Util.getArtifactsOffline(project, configurations.moduleonly, false).values().collect{"\${library_directory}/${it.downloads.artifact.path}"}.join('${classpath_separator}'),
'--add-modules', 'ALL-MODULE-PATH',
// Additions to these JVM module args should be mirrored to server_files/args.txt and other similar blocks in the buildscript
'--add-opens', 'java.base/java.util.jar=cpw.mods.securejarhandler',
'--add-opens', 'java.base/java.lang.invoke=cpw.mods.securejarhandler',
'--add-exports', 'java.base/sun.security.util=cpw.mods.securejarhandler',
'--add-exports', 'jdk.naming.dns/com.sun.jndi.dns=java.naming'
]
],
libraries: []
]
}
}
task installerJson(type: InstallerJson, dependsOn: 'signUniversalJar') {
packedDependencies = PACKED_DEPS
doFirst {
def libs = libraries
json = [
_comment_: launcherJson.comment,
spec: 1,
profile: project.name,
version: launcherJson.id,
path: null,
minecraft: MC_VERSION,
serverJarPath: '{LIBRARY_DIR}/net/minecraft/server/{MINECRAFT_VERSION}/server-{MINECRAFT_VERSION}.jar',
welcome: "Welcome to the simple FML installer.",
data: [
MAPPINGS: [
client: "[${MCP_ARTIFACT.group}:${MCP_ARTIFACT.name}:${MCP_ARTIFACT.version}:mappings@txt]",
server: "[${MCP_ARTIFACT.group}:${MCP_ARTIFACT.name}:${MCP_ARTIFACT.version}:mappings@txt]"
],
MOJMAPS: [
client: "[net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:mappings@txt]",
server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:mappings@txt]"
],
MERGED_MAPPINGS: [
client: "[${MCP_ARTIFACT.group}:${MCP_ARTIFACT.name}:${MCP_ARTIFACT.version}:mappings-merged@txt]",
server: "[${MCP_ARTIFACT.group}:${MCP_ARTIFACT.name}:${MCP_ARTIFACT.version}:mappings-merged@txt]"
],
MC_UNPACKED: [
client: "[net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:unpacked]",
server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:unpacked]"
],
MC_SLIM: [
client: "[net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:slim]",
server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:slim]"
],
MC_SLIM_SHA: [
client: "'${downloadClientSlim.output.get().asFile.sha1()}'",
server: "'${downloadServerSlim.output.get().asFile.sha1()}'"
],
MC_EXTRA: [
client: "[net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:extra]",
server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:extra]"
],
MC_EXTRA_SHA: [
client: "'${downloadClientExtra.output.get().asFile.sha1()}'",
server: "'${downloadServerExtra.output.get().asFile.sha1()}'"
],
MC_SRG: [
client: "[net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:srg]",
server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:srg]"
],
/*MC_SRG_SHA: [
client: "'${createClientSRG.output.sha1()}'",
server: "'${createServerSRG.output.sha1()}'"
],*/
MCP_VERSION: [
client: "'${MCP_VERSION}'",
server: "'${MCP_VERSION}'"
]
],
processors: [
[
sides: ['server'],
jar: INSTALLER_TOOLS,
classpath: getClasspath(project, libs, INSTALLER_TOOLS),
args: [
'--task', 'EXTRACT_FILES',
'--archive', '{INSTALLER}',
'--from', 'data/run.sh',
'--to', '{ROOT}/run.sh',
'--exec', '{ROOT}/run.sh',
//'--from', "data/run_fml_${VERSION.replace('-', '_').sh",
//'--to', '{ROOT}/run_fml_${VERSION.replace('-', '_').sh',
//'--exec', '{ROOT}/run_fml_${VERSION.replace('-', '_').sh',
'--from', 'data/run.bat',
'--to', '{ROOT}/run.bat',
//'--from', 'data/run_fml_${VERSION.replace('-', '_').bat',
//'--to', '{ROOT}/run_fml_${VERSION.replace('-', '_').bat',
'--from', 'data/user_jvm_args.txt',
'--to', '{ROOT}/user_jvm_args.txt',
'--optional', '{ROOT}/user_jvm_args.txt',
'--from', 'data/win_args.txt',
'--to', "{ROOT}/libraries/${MAVEN_PATH}/win_args.txt",
'--from', 'data/unix_args.txt',
'--to', "{ROOT}/libraries/${MAVEN_PATH}/unix_args.txt"
]
], [
sides: ['server'],
jar: INSTALLER_TOOLS,
classpath: getClasspath(project, libs, INSTALLER_TOOLS),
args: [
'--task', 'BUNDLER_EXTRACT',
'--input', '{MINECRAFT_JAR}',
'--output', '{ROOT}/libraries/',
'--libraries'
]
], [
sides: ['server'],
jar: INSTALLER_TOOLS,
classpath: getClasspath(project, libs, INSTALLER_TOOLS),
args: [
'--task', 'BUNDLER_EXTRACT',
'--input', '{MINECRAFT_JAR}',
'--output', '{MC_UNPACKED}',
'--jar-only'
]
], [
jar: INSTALLER_TOOLS,
classpath: getClasspath(project, libs, INSTALLER_TOOLS),
args: [
'--task', 'MCP_DATA',
'--input', "[${MCP_ARTIFACT.descriptor}]",
'--output', '{MAPPINGS}',
'--key', 'mappings'
]
], [
jar: INSTALLER_TOOLS,
classpath: getClasspath(project, libs, INSTALLER_TOOLS),
args: [
'--task', 'DOWNLOAD_MOJMAPS',
'--version', MC_VERSION,
'--side', '{SIDE}',
'--output', '{MOJMAPS}'
]
], [
jar: INSTALLER_TOOLS,
classpath: getClasspath(project, libs, INSTALLER_TOOLS),
args: [
'--task', 'MERGE_MAPPING',
'--left', '{MAPPINGS}',
'--right', '{MOJMAPS}',
'--output', '{MERGED_MAPPINGS}',
'--classes', '--reverse-right'
]
], [
sides: ['client'],
jar: JAR_SPLITTER,
classpath: getClasspath(project, libs, JAR_SPLITTER),
args: [
'--input', '{MINECRAFT_JAR}',
'--slim', '{MC_SLIM}',
'--extra', '{MC_EXTRA}',
'--srg', '{MERGED_MAPPINGS}'
],
outputs: [
'{MC_SLIM}': '{MC_SLIM_SHA}',
'{MC_EXTRA}': '{MC_EXTRA_SHA}'
]
], [
sides: ['server'],
jar: JAR_SPLITTER,
classpath: getClasspath(project, libs, JAR_SPLITTER),
args: [
'--input', '{MC_UNPACKED}',
'--slim', '{MC_SLIM}',
'--extra', '{MC_EXTRA}',
'--srg', '{MERGED_MAPPINGS}'
],
outputs: [
'{MC_SLIM}': '{MC_SLIM_SHA}',
'{MC_EXTRA}': '{MC_EXTRA_SHA}'
]
], [
jar: FART,
classpath: getClasspath(project, libs, FART),
args: [
'--input', '{MC_SLIM}',
'--output', '{MC_SRG}',
'--names', '{MERGED_MAPPINGS}',
'--ann-fix', '--ids-fix', '--src-fix', '--record-fix'
]/*,
outputs: [
'{MC_SRG}': '{MC_SRG_SHA}'
]
*/
]
]
]
getClasspath(project, libs, MCP_ARTIFACT.descriptor) //Tell it to download mcp_config
}
}
task installerJar(type: InstallerJar) {
packedDependencies = PACKED_DEPS
from(extraTxts)
}
publishing {
publications {
mavenJava(MavenPublication) {
artifact universalJar
artifact installerJar
artifact userdevJar
artifact sourcesJar
}
}
}
// Since we need the modules in the bootstrap, we need to make sure they are compiled before we do each run
afterEvaluate { prepareRuns.dependsOn(PACKED_DEPS) }
}
project(':forge') {
evaluationDependsOn(':clean')
apply plugin: 'java-library'
apply plugin: 'net.minecraftforge.gradle.patcher'
apply plugin: 'dev.vankka.dependencydownload.plugin'
sourceSets {
main {
java {
srcDirs = [
"$rootDir/src/main/java",
"$rootDir/src/fmlcommon/java",
"$rootDir/src/snapshots/java"
]
}
resources {
srcDirs = [
"$rootDir/src/main/resources",
"$rootDir/src/generated/resources",
"$rootDir/src/fmlcommon/resources"
]
}
}
}
//Eclipse adds the sourcesets twice, once where we tell it to, once in the projects folder. No idea why. So delete them
eclipse.classpath.file.whenMerged { cls -> cls.entries.removeIf { e -> e instanceof SourceFolder && e.path.startsWith('src/') && !e.path.startsWith('src/main/') } }
ext {
SPEC_VERSION = gradleutils.gitInfo.tag
// The new versioning sceme is <MCVersion>-<ForgeMC>.<RB>.<CommitsSinceRB>
// ForgeMC is a unique identifier for every MC version we have supported.
// Essentially, the same as the old, except dropping the first number, and the builds are no longer unique.
MCP_ARTIFACT = project(':mcp').mcp.config.get()
VERSION_JSON = project(':mcp').file('build/mcp/downloadJson/version.json')
PACKED_DEPS = [':fmlcore:jar', ':fmlloader:jar', ':fmlearlydisplay:jar', ':javafmllanguage:jar', ':lowcodelanguage:jar', ':mclanguage:jar']
MAVEN_PATH = "${group.replace('.', '/')}/${project.name}/${VERSION}"
}
configurations {
installer {
// Don't pull all libraries, if we're missing something, add it to the installer list so the installer knows to download it.
transitive = false
}
moduleonly
api.extendsFrom(installer)
autolibraries
autolibraries.extendsFrom(installer)
autolibraries.extendsFrom(moduleonly)
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
testImplementation 'org.junit.vintage:junit-vintage-engine:5.+'
testImplementation 'org.opentest4j:opentest4j:1.2.0' // needed for junit 5
testImplementation 'org.hamcrest:hamcrest-all:1.3' // needs advanced matching for list order
implementation project(':fmlcore')
implementation project(':fmlloader')
implementation project(':fmlearlydisplay')
implementation project(':javafmllanguage')
implementation project(':lowcodelanguage')
implementation project(':mclanguage')
runtimeOnly "cpw.mods:bootstraplauncher:${BOOTSTRAPLAUNCHER_VERSION}"
}
dependencies sharedDeps
patcher {
excs.from file("$rootDir/src/main/resources/forge.exc")
parent = project(':clean')
patches = file("$rootDir/patches/minecraft")
patchedSrc = file('src/main/java')
srgPatches = true
accessTransformers.from file("$rootDir/src/main/resources/META-INF/accesstransformer.cfg")
sideAnnotationStrippers.from file("$rootDir/src/main/resources/forge.sas")
runs {
forge_client {
property 'eventbus.checkTypesOnDispatch', 'true'
args '--launchTarget', 'forgeclientdev'
ideaModule "${rootProject.name}.${project.name}.main"
mods {
minecraft { source sourceSets.main }
}
}
forge_test_client {
parent runs.forge_client
taskName 'forge_test_client'
property 'forge.enableGameTest', 'true'
environment 'MOD_CLASSES', 'dummy' // Needed to work around FG limitation, FG will replace this!
ideaModule "${rootProject.name}.${project.name}.test"
mods {
tests { sources sourceSets.test }
}
}
forge_server {
args '--launchTarget', 'forgeserverdev'
ideaModule "${rootProject.name}.${project.name}.main"
mods {
minecraft { source sourceSets.main }
}
}
forge_test_server {
parent runs.forge_server
taskName 'forge_test_server'
property 'forge.enableGameTest', 'true'
environment 'MOD_CLASSES', 'dummy' // Needed to work around FG limitation, FG will replace this!
ideaModule "${rootProject.name}.${project.name}.test"
mods {
tests { sources sourceSets.test }
}
}
forge_gameTestServer {
taskName 'forge_gameTestServer'
args '--launchTarget', 'forgegametestserverdev'
ideaModule "${rootProject.name}.${project.name}.main"
mods {
minecraft { source sourceSets.main }
}
}
forge_test_gameTestServer {
parent runs.forge_gameTestServer
taskName 'forge_test_gameTestServer'
ideaModule "${rootProject.name}.${project.name}.test"
mods {
tests { sources sourceSets.test }
}
}
def forgeDataArgs = [
'--mod', 'forge',
'--all',
'--output', rootProject.file('src/generated/resources/'),
'--validate',
'--existing', sourceSets.main.resources.srcDirs[0]
]
forge_data {
taskName 'forge_data'
args '--launchTarget', 'forgedatadev'
ideaModule "${rootProject.name}.${project.name}.main"
mods {
minecraft { source sourceSets.main }
}
args forgeDataArgs
}
forge_test_data {
parent runs.forge_data
taskName 'forge_test_data'
environment 'MOD_CLASSES', 'dummy' // Needed to work around FG limitation, FG will replace this!
ideaModule "${rootProject.name}.${project.name}.test"
mods {
tests { sources sourceSets.test }
}
afterEvaluate {
// Clear forge's main datagen args
args.removeAll {
forgeDataArgs.contains(it instanceof File ? (it as File).absolutePath : it.toString())
}
args '--flat', '--all', '--validate',
'--mod', 'data_gen_test',
'--mod', 'piston_event_test',
'--mod', 'global_loot_test',
'--mod', 'scaffolding_test',
'--mod', 'custom_tag_types_test',
'--mod', 'new_model_loader_test',
'--mod', 'remove_tag_datagen_test',
'--mod', 'tag_based_tool_types',
'--mod', 'custom_transformtype_test',
'--mod', 'data_pack_registries_test',
'--mod', 'biome_modifiers_test',
'--mod', 'structure_modifiers_test',
'--mod', 'custom_preset_editor_test',
'--output', rootProject.file('src/generated_test/resources/'),
'--existing', sourceSets.main.resources.srcDirs[0],
'--existing', sourceSets.test.resources.srcDirs[0]
}
}
}
}
ext {
MANIFESTS = [
'/': [
'Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
'GitCommit': gradleutils.gitInfo.abbreviatedId,
'Git-Branch': gradleutils.gitInfo.branch,
'FML-System-Mods': 'forge'
] as LinkedHashMap,
'net/minecraftforge/versions/forge/': [
'Specification-Title': 'Forge',
'Specification-Vendor': 'Forge Development LLC',
'Specification-Version': SPEC_VERSION,
'Implementation-Title': project.group,
'Implementation-Version': project.version.substring(MC_VERSION.length() + 1),
'Implementation-Vendor': 'Forge Development LLC'
] as LinkedHashMap,
'net/minecraftforge/versions/mcp/': [
'Specification-Title': 'Minecraft',
'Specification-Vendor': 'Mojang',
'Specification-Version': MC_VERSION,
'Implementation-Title': 'MCP',
'Implementation-Version': MCP_VERSION,
'Implementation-Vendor': 'Forge'
] as LinkedHashMap,
'net/minecraftforge/fml/javafmlmod/': [
'Specification-Title': 'Mod Language Provider',
'Specification-Vendor': 'Forge Development LLC',
'Specification-Version': '1',
'Implementation-Title': 'FML Java Mod',
'Implementation-Version': SPEC_VERSION,
'Implementation-Vendor': 'Forge'
] as LinkedHashMap,
'net/minecraftforge/fml/mclanguageprovider/': [
'Specification-Title': 'Mod Language Provider',
'Specification-Vendor': 'Forge Development LLC',
'Specification-Version': '1',
'Implementation-Title': 'Minecraft Language Mod Provider',
'Implementation-Version': '1',
'Implementation-Vendor': 'Forge'
] as LinkedHashMap,
'net/minecraftforge/fml/loading/': [
'Specification-Title': 'Launcher',
'Specification-Vendor': 'Forge Development LLC',
'Specification-Version': '1',
'Implementation-Title': 'FML Launcher',
'Implementation-Version': SPEC_VERSION,
'Implementation-Vendor': 'Forge'
] as LinkedHashMap,
'cpw/mods/bootstraplauncher/': [
'Specification-Title': 'bootstraplauncher',
'Specification-Vendor': 'forge',
'Specification-Version': '1',
'Implementation-Title': 'bootstraplauncher',
'Implementation-Version': '1.1.2+1.1.2+main.09c1f998',
'Implementation-Vendor': 'Forge',
'Implementation-Timestamp': '2022-07-05T21:40:10.035180220Z',
'Git-Commit': '09c1f998',
'Git-Branch': 'main'
] as LinkedHashMap,
'catserver/server/': [
'Specification-Title' : MCP_VERSION,
'Specification-Vendor' : 'CatServerMC',
'Specification-Version': project.version.substring(MC_VERSION.length() + 1),
'Implementation-Title' : 'CatServer',
'Implementation-Version': '1.20.1-' + gitVersion,
'Implementation-Vendor' : 'CatServerMC'
] as LinkedHashMap,
'org/bukkit/craftbukkit/v1_20_R1/': [
'Specification-Title' : MCP_VERSION,
'Specification-Vendor' : 'SpigotMC',
'Specification-Version': '1.20.1',
'Implementation-Title' : 'Spigot',
'Implementation-Version': '1.20.1-' + gitVersion,
'Implementation-Vendor' : 'SpigotMC'
] as LinkedHashMap,
'io/izzel/arclight/': [
'Implementation-Title' : "Arclight",
'Implementation-Vendor' : 'Arclight Team',
] as LinkedHashMap
]
}
task crowdin(type: Crowdin) {
key = project.hasProperty('crowdinKey') ? project.crowdinKey : null
//TODO: Merge our english.json?
}
sharedFmlonlyForge.call(project)
task downloadLibraries(type: DownloadLibraries, dependsOn: ':mcp:setupMCP') {
input = VERSION_JSON
output = rootProject.file('build/libraries/')
}
task extractInheritance(type: ExtractInheritance, dependsOn: [downloadLibraries]) {
tool = INSTALLER_TOOLS + ':fatjar'
args.add '--annotations'
input = genJoinedBinPatches.cleanJar
libraries.addAll downloadLibraries.librariesOutput.map { rf -> Files.readAllLines(rf.asFile.toPath()).stream().map(File::new).collect(java.util.stream.Collectors.toList()) }
}
task findFieldInstanceChecks(type: FieldCompareFinder, dependsOn: ['createJoinedSRG']) {
jar = createJoinedSRG.output
output = rootProject.file('src/main/resources/coremods/field_to_instanceof.json')
fields {
/* 1.17 changed most things to use Tags. So this isn't nessasary anymore so just make an empty list
bows {
cls = 'net/minecraft/world/item/Items'
name = 'f_42411_'
replacement = 'net/minecraft/world/item/BowItem'
}
crossbows {
cls = 'net/minecraft/world/item/Items'
name = 'f_42717_'
replacement = 'net/minecraft/world/item/CrossbowItem'
}
*/
}
}
task findFinalizeSpawnTargets(type: BytecodePredicateFinder, dependsOn: ['createJoinedSRG']) {
jar = createJoinedSRG.output
output = rootProject.file('src/main/resources/coremods/finalize_spawn_targets.json')
predicate = {
parent, node, insn ->
'net/minecraft/world/level/BaseSpawner' != parent.name // Ignore this class as we special case it.
&& insn.getOpcode() == Opcodes.INVOKEVIRTUAL
&& insn.name.equals('m_6518_')
&& insn.desc.equals('(Lnet/minecraft/world/level/ServerLevelAccessor;Lnet/minecraft/world/DifficultyInstance;Lnet/minecraft/world/entity/MobSpawnType;Lnet/minecraft/world/entity/SpawnGroupData;Lnet/minecraft/nbt/CompoundTag;)Lnet/minecraft/world/entity/SpawnGroupData;')
}
}
tasks.register('validateDeprecations', ValidateDeprecations) {
input = tasks.jar.archiveFile
mcVersion = MC_VERSION
}
tasks.jar.finalizedBy 'validateDeprecations'
tasks.register('checkAll') {
dependsOn 'checkLicenses'
group = 'checks'
}
tasks.register('checkAllAndFix') {
dependsOn 'findFinalizeSpawnTargets', 'findFieldInstanceChecks', 'checkLicenses'
group = 'checks'
}
CheckTask.registerTask(tasks, 'ATs', CheckATs) {
dependsOn extractInheritance, createSrg2Mcp
ats.from patcher.accessTransformers
inheritance = extractInheritance.output
mappings = createSrg2Mcp.output
}
CheckTask.registerTask(tasks, 'SAS', CheckSAS) {
dependsOn extractInheritance
sass.from patcher.sideAnnotationStrippers
inheritance = extractInheritance.output
}
CheckTask.registerTask(tasks, 'Excs', CheckExcs) {
dependsOn jar
binary = jar.archiveFile.get().asFile
excs.from patcher.excs
}
CheckTask.registerTask(tasks, 'Patches', CheckPatches) {
dependsOn genPatches
patchDir = file("$rootDir/patches")
patchesWithS2SArtifact = [
'minecraft/net/minecraft/client/renderer/ViewArea.java.patch',
'minecraft/net/minecraft/data/models/blockstates/Variant.java.patch',
]
}
tasks.register('fixPatchImports', FixPatchImports) {
clean.set(rootProject.file('projects/clean/src/main/java'))
patched.set(rootProject.file('projects/forge/src/main/java'))
}
genPatches {
autoHeader true
lineEnding = '\n'
}
def baseForgeVersionProperty = project.objects.property(String)
baseForgeVersionProperty.set(project.provider { getLatestForgeVersion(MC_VERSION) }.map { MC_VERSION + '-' + it })
baseForgeVersionProperty.finalizeValueOnRead()
def jarCompatibilityTaskSetup = { task ->
task.group = 'jar compatibility'
task.onlyIf {
baseForgeVersionProperty.getOrNull() != null
}
}
tasks.register('setupCheckJarCompatibility', SetupCheckJarCompatibility) {
inputVersion = baseForgeVersionProperty
}
tasks.register('applyBaseCompatibilityJarBinPatches', ApplyBinPatches) {
jarCompatibilityTaskSetup(it)
clean = project.tasks.createJoinedSRG.output
patch = project.tasks.named('setupCheckJarCompatibility').flatMap { it.baseBinPatchesOutput }
output = project.layout.buildDirectory.dir(name).map { it.file('output.jar') }
}
tasks.register('mergeBaseForgeJar', MergeJars) {
jarCompatibilityTaskSetup(it)
inputJars.from(project.tasks.named('applyBaseCompatibilityJarBinPatches').flatMap { it.output })
inputJars.from(baseForgeVersionProperty.map { inputVersion ->
def output = project.layout.buildDirectory.dir(name).map { it.file("forge-${inputVersion}-universal.jar") }.get().asFile
project.rootProject.extensions.download.run {
src "https://maven.minecraftforge.net/net/minecraftforge/forge/${inputVersion}/forge-${inputVersion}-universal.jar"
dest output
}
return output
})
}
tasks.register('checkJarCompatibility', CheckJarCompatibility) {
jarCompatibilityTaskSetup(it)
dependsOn 'setupCheckJarCompatibility'
baseJar = project.tasks.named('mergeBaseForgeJar').flatMap { it.output }
baseLibraries.from(project.tasks.named('createJoinedSRG').flatMap { it.output })
inputJar = project.tasks.named('reobfJar').flatMap { it.output }
concreteLibraries.from(project.PACKED_DEPS.collect { project.rootProject.tasks.getByPath(it).archiveFile })
commonLibraries.from(project.configurations.minecraftImplementation)
commonLibraries.from(project.configurations.installer)
commonLibraries.from(project.configurations.moduleonly)
}
task launcherJson(type: LauncherJson) {
packedDependencies = [':fmlloader:jar',':fmlearlydisplay:jar']
doFirst {
def forge_client = project(':forge').patcher.runs.forge_client
json = [
_comment_: comment,
id: id,
time: timestamp,
releaseTime: timestamp,
type: 'release',
mainClass: 'cpw.mods.bootstraplauncher.BootstrapLauncher',
inheritsFrom: MC_VERSION,
logging: {},
arguments: [
game: ['--launchTarget', 'forgeclient',
'--fml.forgeVersion', FORGE_VERSION,
'--fml.mcVersion', MC_VERSION,
'--fml.forgeGroup', project.group,
'--fml.mcpVersion', MCP_VERSION],
jvm: ['-Djava.net.preferIPv6Addresses=system',
"-DignoreList=${forge_client.properties.ignoreList},\${version_name}.jar",
"-DmergeModules=${forge_client.properties.mergeModules}",
'-DlibraryDirectory=${library_directory}',
'-p', Util.getArtifactsOffline(project, configurations.moduleonly, false).values().collect{'${library_directory}/' + it.downloads.artifact.path}.join('${classpath_separator}'),
'--add-modules', 'ALL-MODULE-PATH',
// Additions to these JVM module args should be mirrored to server_files/args.txt and other similar blocks in the buildscript
'--add-opens', 'java.base/java.util.jar=cpw.mods.securejarhandler',
'--add-opens', 'java.base/java.lang.invoke=cpw.mods.securejarhandler',
'--add-exports', 'java.base/sun.security.util=cpw.mods.securejarhandler',
'--add-exports', 'jdk.naming.dns/com.sun.jndi.dns=java.naming'
]
],
libraries: []
]
}
}
// task generateLibraries(type: dev.vankka.dependencydownload.task.GenerateDependencyDownloadResourceTask) {
// var conf = providers.provider { configurations.autolibraries }
// configuration = conf
// file = "data/libraries.txt"
// // Not necessary to include in the resource
// includeShadowJarRelocations = false
// }
task buildCatServer(type: Jar, dependsOn: [genServerBinPatches]) {
archiveClassifier = 'server'
archiveExtension = 'jar'
archiveBaseName = 'CatServer'
archiveVersion = CATSERVER_VERSION
destinationDirectory = file('build/libs')
def CLASS_PATH = Util.getArtifactsOffline(project, project.configurations.installer, false).values().collect { "libraries/${it.downloads.artifact.path}" } +
[
'libraries/' + Util.getMavenPath(rootProject.tasks.findByPath(':fmlloader:jar')),
"libraries/net/minecraft/server/${MC_VERSION}-${MCP_VERSION}/server-${MC_VERSION}-${MCP_VERSION}-extra.jar",
]
def claimed = CLASS_PATH.collect { it.rsplit('/', 2)[0] }.toSet() // Allow us to override versions
CLASS_PATH +=
(
[
"libraries/com/github/oshi/oshi-core/6.2.2/oshi-core-6.2.2.jar",
"libraries/com/google/code/gson/gson/2.10.1/gson-2.10.1.jar",
"libraries/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar",
"libraries/com/google/guava/guava/31.1-jre/guava-31.1-jre.jar",
"libraries/com/mojang/authlib/4.0.43/authlib-4.0.43.jar",
"libraries/com/mojang/brigadier/1.1.8/brigadier-1.1.8.jar",
"libraries/com/mojang/datafixerupper/6.0.8/datafixerupper-6.0.8.jar",
"libraries/com/mojang/javabridge/1.2.24/javabridge-1.2.24.jar",
"libraries/com/mojang/logging/1.1.1/logging-1.1.1.jar",
"libraries/commons-codec/commons-codec/1.10/commons-codec-1.10.jar",
"libraries/commons-io/commons-io/2.11.0/commons-io-2.11.0.jar",
"libraries/io/netty/netty-transport-native-unix-common/4.1.82.Final/netty-transport-native-unix-common-4.1.82.Final.jar",
"libraries/io/netty/netty-transport-native-epoll/4.1.82.Final/netty-transport-native-epoll-4.1.82.Final-linux-aarch_64.jar",
"libraries/io/netty/netty-transport-native-epoll/4.1.82.Final/netty-transport-native-epoll-4.1.82.Final-linux-x86_64.jar",
"libraries/io/netty/netty-transport-classes-epoll/4.1.82.Final/netty-transport-classes-epoll-4.1.82.Final.jar",
"libraries/io/netty/netty-transport/4.1.82.Final/netty-transport-4.1.82.Final.jar",
"libraries/io/netty/netty-resolver/4.1.82.Final/netty-resolver-4.1.82.Final.jar",
"libraries/io/netty/netty-handler/4.1.82.Final/netty-handler-4.1.82.Final.jar",
"libraries/io/netty/netty-common/4.1.82.Final/netty-common-4.1.82.Final.jar",
"libraries/io/netty/netty-codec/4.1.82.Final/netty-codec-4.1.82.Final.jar",
"libraries/io/netty/netty-buffer/4.1.82.Final/netty-buffer-4.1.82.Final.jar",
"libraries/it/unimi/dsi/fastutil/8.5.9/fastutil-8.5.9.jar",
"libraries/net/java/dev/jna/jna/5.12.1/jna-5.12.1.jar",
"libraries/net/java/dev/jna/jna-platform/5.12.1/jna-platform-5.12.1.jar",
"libraries/net/sf/jopt-simple/jopt-simple/5.0.4/jopt-simple-5.0.4.jar",
"libraries/org/apache/commons/commons-lang3/3.12.0/commons-lang3-3.12.0.jar",
"libraries/org/apache/logging/log4j/log4j-api/2.19.0/log4j-api-2.19.0.jar",
"libraries/org/apache/logging/log4j/log4j-core/2.19.0/log4j-core-2.19.0.jar",
"libraries/org/apache/logging/log4j/log4j-slf4j2-impl/2.19.0/log4j-slf4j2-impl-2.19.0.jar",
"libraries/org/joml/joml/1.10.5/joml-1.10.5.jar", // 1.20.1
"libraries/org/slf4j/slf4j-api/2.0.1/slf4j-api-2.0.1.jar",
// plugin-only handled in FoxServerLauncher
"libraries/plugin-only/org/apache/maven/maven-model/3.9.6/maven-model-3.9.6.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/maven-model-builder/3.9.6/maven-model-builder-3.9.6.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/maven-resolver-provider/3.9.6/maven-resolver-provider-3.9.6.jar",
"libraries/plugin-only/org/apache/maven/maven-builder-support/3.9.6/maven-builder-support-3.9.6.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/maven-repository-metadata/3.9.6/maven-repository-metadata-3.9.6.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/resolver/maven-resolver-api/1.9.18/maven-resolver-api-1.9.18.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/resolver/maven-resolver-impl/1.9.18/maven-resolver-impl-1.9.18.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/resolver/maven-resolver-spi/1.9.18/maven-resolver-spi-1.9.18.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/resolver/maven-resolver-util/1.9.18/maven-resolver-util-1.9.18.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/resolver/maven-resolver-named-locks/1.9.18/maven-resolver-named-locks-1.9.18.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/resolver/maven-resolver-connector-basic/1.9.18/maven-resolver-connector-basic-1.9.18.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/resolver/maven-resolver-transport-file/1.9.18/maven-resolver-transport-file-1.9.18.jar", // 1.20.1
"libraries/plugin-only/org/apache/maven/resolver/maven-resolver-transport-http/1.9.18/maven-resolver-transport-http-1.9.18.jar", // 1.20.1
"libraries/org/apache/http/httpclient/4.5.14/httpclient-4.5.14.jar", // 1.20.1
"libraries/org/apache/http/httpcore/4.4.14/httpcore-4.4.14.jar", // 1.20.1
"libraries/javax/inject/1/javax.inject-1.jar", // 1.20.1
"libraries/org/apache/commons/logging/jcl-over-slf4j/1.7.36/jcl-over-slf4j-1.7.36.jar", // 1.20.1
"libraries/org/eclipse/sisu/org.eclipse.sisu.inject/0.3.5/org.eclipse.sisu.inject-0.3.5.jar", // 1.20.1
"libraries/org/codehaus/plexus/interpolation/plexus-interpolation/1.26/plexus-interpolation-1.26.jar", // 1.20.1
"libraries/org/codehaus/plexus/util/plexus-utils/3.5.1/plexus-utils-3.5.1.jar", // 1.20.1
"libraries/com/google/protobuf/protobuf-java/3.21.9/protobuf-java-3.21.9.jar" // 1.20.1
].findAll { it.startsWith('libraries/') && !claimed.contains(it.rsplit('/', 2)[0]) }
)
def MODULE_PATH = Util.getArtifactsOffline(project, project.configurations.moduleonly, false).values().collect { "libraries/${it.downloads.artifact.path}" }
def tokens = [
TASK : project.name.equals('forge') ? 'forgeserver' : 'fmlserver',
MAVEN_PATH : project.ext.MAVEN_PATH.toString(),
FORGE_VERSION: FORGE_VERSION,
MC_VERSION : MC_VERSION,
MCP_VERSION : MCP_VERSION,
FORGE_GROUP : project.group,
IGNORE_LIST : Util.getArtifactsOffline(project, project.configurations.moduleonly, false).values().collect { it.downloads.artifact.path.rsplit('/', 1)[1] }.join(','),
MODULES : 'ALL-MODULE-PATH'
]
doFirst {
MANIFESTS.each { pkg, values ->
if (pkg == '/') {
manifest.attributes(values += [
'Premain-Class': 'foxlaunch.legacy.JarLoader',
'Launcher-Agent-Class': 'foxlaunch.legacy.JarLoader',
'Main-Class': 'foxlaunch.FoxServerLauncher',
'Installer-Class-Path': CLASS_PATH.toString().replace("[", "").replace("]", "").replace(",", "")
])
} else {
manifest.attributes(values, pkg)
}
}
}
//println(CLASS_PATH)
dependsOn rootProject.project('foxlaunch').tasks.jar
from(
zipTree(new File(rootProject.project('foxlaunch').getProjectDir(), 'build/libs/foxlaunch-1.0.0.jar'))
)
from(genServerBinPatches.output) {
rename { 'data/server.lzma' }
}
from(universalJar) {
rename { 'data/forge-' + MC_VERSION + '-' + FORGE_VERSION + '-universal.jar' }
}
from(project(':fmlloader').tasks.jar.outputs) {
rename { 'data/fmlloader-' + MC_VERSION + '-' + FORGE_VERSION + '.jar' }
}
from(project(':fmlcore').tasks.jar.outputs) {
rename { 'data/fmlcore-' + MC_VERSION + '-' + FORGE_VERSION + '.jar' }
}
from(project(':fmlearlydisplay').tasks.jar.outputs) {
rename { 'data/fmlearlydisplay-' + MC_VERSION + '-' + FORGE_VERSION + '.jar' }
}
from(project(':javafmllanguage').tasks.jar.outputs) {
rename { 'data/javafmllanguage-' + MC_VERSION + '-' + FORGE_VERSION + '.jar' }
}
from(project(':mclanguage').tasks.jar.outputs) {
rename { 'data/mclanguage-' + MC_VERSION + '-' + FORGE_VERSION + '.jar' }
}
from(project(':lowcodelanguage').tasks.jar.outputs) {
rename { 'data/lowcodelanguage-' + MC_VERSION + '-' + FORGE_VERSION + '.jar'}
}
from(rootProject.file('server_files/libraries.txt')) {
filter(ReplaceTokens, tokens: [CLASS_PATH: CLASS_PATH.join(';')])
rename { 'data/libraries-launch.txt' }
}
// from(generateLibraries)
from(rootProject.file('server_libs/installertools-1.2.10.jar')) {
rename { 'data/installertools-1.2.10.jar' }
}
from(rootProject.file('server_libs/jarsplitter-1.1.4.jar')) {
rename { 'data/jarsplitter-1.1.4.jar' }
}
from(rootProject.file('server_libs/ForgeAutoRenamingTool-0.1.22.jar')) {
rename { 'data/ForgeAutoRenamingTool-0.1.22.jar' }
}
from(rootProject.file('server_libs/binarypatcher-1.0.12.jar')) {
rename { 'data/binarypatcher-1.0.12.jar' }
}
from(rootProject.file('server_libs/srgutils-0.4.11.jar')) {
rename { 'data/srgutils-0.4.11.jar' }
}
from(rootProject.file('server_libs/fastcsv-2.0.0.jar')) {
rename { 'data/fastcsv-2.0.0.jar' }
}
}
universalJar {
// add crowdin locales
from { crowdin.output.present && crowdin.output.get().asFile.exists() ? zipTree(crowdin.output) : null}
dependsOn crowdin
duplicatesStrategy = 'exclude'
doFirst {
MANIFESTS.each{ pkg, values ->
if (pkg == '/') {
manifest.attributes(values)
} else {
manifest.attributes(values, pkg)
}
}
}
}
tasks.register('genAllData') {
dependsOn 'forge_data', 'forge_mdk_data', 'forge_test_data'
}
tasks.eclipse.dependsOn('genEclipseRuns')
if (project.hasProperty('UPDATE_MAPPINGS')) {
extractRangeMap {
sources.from sourceSets.test.java.srcDirs
addDependencies compileTestJava.classpath
}
applyRangeMap {
sources.from sourceSets.test.java.srcDirs
}
sourceSets.test.java.srcDirs.each { extractMappedNew.addTarget it }
}
// Since we need the modules in the bootstrap, we need to make sure they are compiled before we do each run
afterEvaluate { prepareRuns.dependsOn(PACKED_DEPS) }
tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation
options.compilerArgs << "-Xlint:-unchecked" << "-Xlint:-deprecation" << "-Xlint:-dep-ann" << "-Xlint:-removal" // CatServer - ignore warnings
}
}
//evaluationDependsOnChildren()
task setup() { //These must be strings so that we can do lazy resolution. Else we need evaluationDependsOnChildren above
dependsOn ':clean:extractMapped'
if (symlinkValid)
dependsOn ':fmlonly:extractMapped'
dependsOn ':forge:extractMapped'
}
task doChecks {
dependsOn ':forge:checkJarCompatibility'
dependsOn ':forge:publish'
}
if (symlinkValid)
project.gradle.startParameter.excludedTaskNames.add(':fmlonly:genPatches')
if (!System.env.TEAMCITY_VERSION)
project.gradle.startParameter.excludedTaskNames.add(':clean:genPatches')
//Also output FMLOnly when building a version.
if (System.env.TEAMCITY_VERSION) {
//Only setup the CI environment if and only if the environment variables are set.
tasks.configureTeamCity {
doLast {
println "##teamcity[buildNumber '${project(':forge').version}']"
println "##teamcity[setParameter name='env.PUBLISHED_JAVA_ARTIFACT_VERSION' value='${project(':forge').version}']"
println "##teamcity[setParameter name='env.PUBLISHED_JAVA_FML_ARTIFACT_VERSION' value='${project(':fmlonly').version}']"
}
}
}