Compare commits

..
17 Commits
Author SHA1 Message Date
Martin Robertz 99e35345d1 update 2024-07-02 23:29:08 +02:00
Jason Mitchell 7f78ceb921 Bye bye DepLoader 2024-07-01 12:33:39 -07:00
Raven Szewczyk 4686fe8fa1 [ci skip] upgraded build system 2024-02-04 19:57:37 +00:00
Martin Robertz c5b8594660 update bs+gitignore 2024-01-11 23:14:18 +01:00
Raven Szewczyk 7b0ab21823 [ci skip] upgraded build system 2024-01-08 21:24:42 +00:00
Jason Mitchell dd1abf7ac4 Angelica Compat
Depends on https://github.com/GTNewHorizons/CodeChickenLib/pull/14
2023-12-24 10:31:02 -08:00
bombcar 20b1e28074 update BS and spotlessApply (#11) 2023-11-29 22:14:41 +01:00
Jason Mitchell cc15e4cec6 Add Curse/Modrinth projects (#10) 2023-02-02 22:07:24 -08:00
Raven Szewczyk 83f5eac8d8 [ci skip] upgraded build system 2023-01-31 09:51:52 +00:00
Raven Szewczyk 2cf7226306 Actually fix the broken version/modid this time 2023-01-30 11:50:18 +00:00
Raven Szewczyk 6273a1e71a Use version substitution in CCC mod container 2023-01-30 11:39:47 +00:00
Raven Szewczyk b52d844ed6 Release with RFG 2023-01-30 11:14:43 +00:00
Raven Szewczyk 331a5fcd3f [ci skip] Add git-blame-ignore-revs for spotlessApply 2023-01-30 11:13:51 +00:00
Raven Szewczyk 955a875d42 [ci skip] spotlessApply with the new settings 2023-01-30 11:13:51 +00:00
Raven Szewczyk b45ef7230d [ci skip] Update buildscript to RetroFuturaGradle 2023-01-30 11:13:50 +00:00
Raven Szewczyk de334d86f6 [ci skip] Fix addon.gradle for RFG 2023-01-30 11:13:42 +00:00
Raven Szewczyk acdf6d754f Update buildscript (#9)
* Update buildscript

* Bump CCL
2023-01-05 12:09:05 +00:00
73 changed files with 962 additions and 2112 deletions

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
# Ignore spotlessApply reformat
955a875d42bd8f725d389ef8c4f571824f2ae0c8
+36 -27
View File
@@ -1,35 +1,44 @@
* text eol=lf
*.jar binary
*.[jJ][aA][rR] binary
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.tif binary
*.tiff binary
*.ico binary
*.svg text
*.eps binary
*.[pP][nN][gG] binary
*.[jJ][pP][gG] binary
*.[jJ][pP][eE][gG] binary
*.[gG][iI][fF] binary
*.[tT][iI][fF] binary
*.[tT][iI][fF][fF] binary
*.[iI][cC][oO] binary
*.[sS][vV][gG] text
*.[eE][pP][sS] binary
*.[xX][cC][fF] binary
*.kar binary
*.m4a binary
*.mid binary
*.midi binary
*.mp3 binary
*.ogg binary
*.ra binary
*.[kK][aA][rR] binary
*.[mM]4[aA] binary
*.[mM][iI][dD] binary
*.[mM][iI][dD][iI] binary
*.[mM][pP]3 binary
*.[oO][gG][gG] binary
*.[rR][aA] binary
*.7z binary
*.gz binary
*.tar binary
*.tgz binary
*.zip binary
*.7[zZ] binary
*.[gG][zZ] binary
*.[tT][aA][rR] binary
*.[tT][gG][zZ] binary
*.[zZ][iI][pP] binary
*.patch -text
*.[tT][cC][nN] binary
*.[sS][oO] binary
*.[dD][lL][lL] binary
*.[dD][yY][lL][iI][bB] binary
*.[pP][sS][dD] binary
*.[tT][tT][fF] binary
*.[oO][tT][fF] binary
*.bat text eol=crlf
*.cmd text eol=crlf
*.ps1 text eol=crlf
*.[pP][aA][tT][cC][hH] -text
*autogenerated binary
*.[bB][aA][tT] text eol=crlf
*.[cC][mM][dD] text eol=crlf
*.[pP][sS]1 text eol=crlf
*[aA][uU][tT][oO][gG][eE][nN][eE][rR][aA][tT][eE][dD]* binary
+1
View File
@@ -26,3 +26,4 @@ whitelist.json
*.ipr
*.iws
src/main/resources/mixins.*.json
*.bat
+3 -3
View File
@@ -1,8 +1,8 @@
minecraft {
if (replaceGradleTokenInFile) {
replaceIn "CodeChickenCorePlugin.java"
tagReplacementFiles.add "CodeChickenCorePlugin.java"
if(gradleTokenVersion) {
replace gradleTokenVersion, versionDetails().lastTag
injectedTags.put gradleTokenVersion, versionDetails().lastTag
}
}
}
}
+2 -965
View File
@@ -1,968 +1,5 @@
//version: 1661114848
/*
DO NOT CHANGE THIS FILE!
Also, you may replace this file at any time if there is an update available.
Please check https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/main/build.gradle for updates.
*/
//version: 1707058017
import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.internal.logging.text.StyledTextOutput.Style
import org.gradle.internal.logging.text.StyledTextOutputFactory
import java.nio.file.Files
import java.nio.file.Paths
import java.util.concurrent.TimeUnit
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
import java.util.zip.ZipOutputStream
buildscript {
repositories {
mavenCentral()
maven {
name 'forge'
url 'https://maven.minecraftforge.net'
}
maven {
// GTNH ForgeGradle Fork
name = "GTNH Maven"
url = "http://jenkins.usrv.eu:8081/nexus/content/groups/public/"
}
maven {
name 'sonatype'
url 'https://oss.sonatype.org/content/repositories/snapshots/'
}
maven {
name 'Scala CI dependencies'
url 'https://repo1.maven.org/maven2/'
}
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:1.2.9'
}
}
plugins {
id 'java-library'
id 'idea'
id 'eclipse'
id 'scala'
id 'maven-publish'
id 'org.jetbrains.kotlin.jvm' version '1.5.30' apply false
id 'org.jetbrains.kotlin.kapt' version '1.5.30' apply false
id 'com.google.devtools.ksp' version '1.5.30-1.0.0' apply false
id 'org.ajoberstar.grgit' version '4.1.1'
id 'com.github.johnrengelman.shadow' version '4.0.4'
id 'com.palantir.git-version' version '0.13.0' apply false
id 'de.undercouch.download' version '5.0.1'
id 'com.github.gmazzo.buildconfig' version '3.0.3' apply false
id 'com.diffplug.spotless' version '6.7.2' apply false
}
boolean settingsupdated = verifySettingsGradle()
settingsupdated = verifyGitAttributes() || settingsupdated
if (settingsupdated)
throw new GradleException("Settings has been updated, please re-run task.")
dependencies {
implementation 'com.diffplug:blowdryer:1.6.0'
}
apply plugin: 'com.diffplug.blowdryer'
if (project.file('.git/HEAD').isFile()) {
apply plugin: 'com.palantir.git-version'
}
def out = services.get(StyledTextOutputFactory).create('an-output')
apply plugin: 'forge'
def projectJavaVersion = JavaLanguageVersion.of(8)
java {
toolchain {
languageVersion.set(projectJavaVersion)
}
}
idea {
module {
inheritOutputDirs = true
downloadJavadoc = true
downloadSources = true
}
}
boolean disableSpotless = project.hasProperty("disableSpotless") ? project.disableSpotless.toBoolean() : false
if (!disableSpotless) {
apply plugin: 'com.diffplug.spotless'
apply from: Blowdryer.file('spotless.gradle')
}
if (JavaVersion.current() != JavaVersion.VERSION_1_8) {
throw new GradleException("This project requires Java 8, but it's running on " + JavaVersion.current())
}
checkPropertyExists("modName")
checkPropertyExists("modId")
checkPropertyExists("modGroup")
checkPropertyExists("autoUpdateBuildScript")
checkPropertyExists("minecraftVersion")
checkPropertyExists("forgeVersion")
checkPropertyExists("replaceGradleTokenInFile")
checkPropertyExists("gradleTokenModId")
checkPropertyExists("gradleTokenModName")
checkPropertyExists("gradleTokenVersion")
checkPropertyExists("gradleTokenGroupName")
checkPropertyExists("apiPackage")
checkPropertyExists("accessTransformersFile")
checkPropertyExists("usesMixins")
checkPropertyExists("mixinPlugin")
checkPropertyExists("mixinsPackage")
checkPropertyExists("coreModClass")
checkPropertyExists("containsMixinsAndOrCoreModOnly")
checkPropertyExists("usesShadowedDependencies")
checkPropertyExists("developmentEnvironmentUserName")
boolean noPublishedSources = project.hasProperty("noPublishedSources") ? project.noPublishedSources.toBoolean() : false
boolean usesMixinDebug = project.hasProperty('usesMixinDebug') ?: project.usesMixins.toBoolean()
boolean forceEnableMixins = project.hasProperty('forceEnableMixins') ? project.forceEnableMixins.toBoolean() : false
String channel = project.hasProperty('channel') ? project.channel : 'stable'
String mappingsVersion = project.hasProperty('mappingsVersion') ? project.mappingsVersion : '12'
String javaSourceDir = "src/main/java/"
String scalaSourceDir = "src/main/scala/"
String kotlinSourceDir = "src/main/kotlin/"
String targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/")
String targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/")
String targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/")
if (!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) {
throw new GradleException("Could not resolve \"modGroup\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin)
}
if (apiPackage) {
targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
if (!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) {
throw new GradleException("Could not resolve \"apiPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin)
}
}
if (accessTransformersFile) {
String targetFile = "src/main/resources/META-INF/" + accessTransformersFile
if (!getFile(targetFile).exists()) {
throw new GradleException("Could not resolve \"accessTransformersFile\"! Could not find " + targetFile)
}
}
if (usesMixins.toBoolean()) {
if (mixinsPackage.isEmpty() || mixinPlugin.isEmpty()) {
throw new GradleException("\"mixinPlugin\" requires \"mixinsPackage\" and \"mixinPlugin\" to be set!")
}
targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
if (!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) {
throw new GradleException("Could not resolve \"mixinsPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin)
}
String targetFileJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".java"
String targetFileScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".scala"
String targetFileScalaJava = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".java"
String targetFileKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".kt"
if (!(getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists() || getFile(targetFileKotlin).exists())) {
throw new GradleException("Could not resolve \"mixinPlugin\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava + " or " + targetFileKotlin)
}
}
if (coreModClass) {
String targetFileJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".java"
String targetFileScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".scala"
String targetFileScalaJava = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".java"
String targetFileKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".kt"
if (!(getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists() || getFile(targetFileKotlin).exists())) {
throw new GradleException("Could not resolve \"coreModClass\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava + " or " + targetFileKotlin)
}
}
configurations.all {
resolutionStrategy.cacheChangingModulesFor(0, TimeUnit.SECONDS)
// Make sure GregTech build won't time out
System.setProperty("org.gradle.internal.http.connectionTimeout", 120000 as String)
System.setProperty("org.gradle.internal.http.socketTimeout", 120000 as String)
}
// Fix Jenkins' Git: chmod a file should not be detected as a change and append a '.dirty' to the version
try {
'git config core.fileMode false'.execute()
}
catch (Exception ignored) {
out.style(Style.Failure).println("git isn't installed at all")
}
// Pulls version first from the VERSION env and then git tag
String identifiedVersion
String versionOverride = System.getenv("VERSION") ?: null
try {
identifiedVersion = versionOverride == null ? gitVersion() : versionOverride
}
catch (Exception ignored) {
out.style(Style.Failure).text(
'This mod must be version controlled by Git AND the repository must provide at least one tag,\n' +
'or the VERSION override must be set! ').style(Style.SuccessHeader).text('(Do NOT download from GitHub using the ZIP option, instead\n' +
'clone the repository, see ').style(Style.Info).text('https://gtnh.miraheze.org/wiki/Development').style(Style.SuccessHeader).println(' for details.)'
)
versionOverride = 'NO-GIT-TAG-SET'
identifiedVersion = versionOverride
}
version = minecraftVersion + '-' + identifiedVersion
ext {
modVersion = identifiedVersion
}
if (identifiedVersion == versionOverride) {
out.style(Style.Failure).text('Override version to ').style(Style.Identifier).text(modVersion).style(Style.Failure).println('!\7')
}
group = modGroup
if (project.hasProperty("customArchiveBaseName") && customArchiveBaseName) {
archivesBaseName = customArchiveBaseName
} else {
archivesBaseName = modId
}
def arguments = []
def jvmArguments = []
if (usesMixins.toBoolean() || forceEnableMixins) {
arguments += [
"--tweakClass org.spongepowered.asm.launch.MixinTweaker"
]
if (usesMixinDebug.toBoolean()) {
jvmArguments += [
"-Dmixin.debug.countInjections=true",
"-Dmixin.debug.verbose=true",
"-Dmixin.debug.export=true"
]
}
}
minecraft {
version = minecraftVersion + '-' + forgeVersion + '-' + minecraftVersion
runDir = 'run'
if (replaceGradleTokenInFile) {
replaceIn replaceGradleTokenInFile
if (gradleTokenModId) {
replace gradleTokenModId, modId
}
if (gradleTokenModName) {
replace gradleTokenModName, modName
}
if (gradleTokenVersion) {
replace gradleTokenVersion, modVersion
}
if (gradleTokenGroupName) {
replace gradleTokenGroupName, modGroup
}
}
clientIntellijRun {
args(arguments)
jvmArgs(jvmArguments)
if (developmentEnvironmentUserName) {
args("--username", developmentEnvironmentUserName)
}
}
serverIntellijRun {
args(arguments)
jvmArgs(jvmArguments)
}
}
if (file('addon.gradle').exists()) {
apply from: 'addon.gradle'
}
apply from: 'repositories.gradle'
configurations {
implementation.extendsFrom(shadowImplementation) // TODO: remove after all uses are refactored
implementation.extendsFrom(shadowCompile)
implementation.extendsFrom(shadeCompile)
}
repositories {
maven {
name 'Overmind forge repo mirror'
url 'https://gregtech.overminddl1.com/'
}
if (usesMixins.toBoolean() || forceEnableMixins) {
maven {
name 'sponge'
url 'https://repo.spongepowered.org/repository/maven-public'
}
maven {
url 'https://jitpack.io'
}
}
}
dependencies {
if (usesMixins.toBoolean()) {
annotationProcessor('org.ow2.asm:asm-debug-all:5.0.3')
annotationProcessor('com.google.guava:guava:24.1.1-jre')
annotationProcessor('com.google.code.gson:gson:2.8.6')
annotationProcessor('org.spongepowered:mixin:0.8-SNAPSHOT')
}
if (usesMixins.toBoolean() || forceEnableMixins) {
// using 0.8 to workaround a issue in 0.7 which fails mixin application
compile('com.github.GTNewHorizons:SpongePoweredMixin:0.7.12-GTNH') {
// Mixin includes a lot of dependencies that are too up-to-date
exclude module: 'launchwrapper'
exclude module: 'guava'
exclude module: 'gson'
exclude module: 'commons-io'
exclude module: 'log4j-core'
}
compile('com.github.GTNewHorizons:SpongeMixins:1.5.0')
}
}
apply from: 'dependencies.gradle'
def mixingConfigRefMap = 'mixins.' + modId + '.refmap.json'
def refMap = "${tasks.compileJava.temporaryDir}" + File.separator + mixingConfigRefMap
def mixinSrg = "${tasks.reobf.temporaryDir}" + File.separator + "mixins.srg"
task generateAssets {
if (usesMixins.toBoolean()) {
def mixinConfigFile = getFile("/src/main/resources/mixins." + modId + ".json");
if (!mixinConfigFile.exists()) {
mixinConfigFile.text = """{
"required": true,
"minVersion": "0.7.11",
"package": "${modGroup}.${mixinsPackage}",
"plugin": "${modGroup}.${mixinPlugin}",
"refmap": "${mixingConfigRefMap}",
"target": "@env(DEFAULT)",
"compatibilityLevel": "JAVA_8",
"mixins": [],
"client": [],
"server": []
}
"""
}
}
}
task relocateShadowJar(type: ConfigureShadowRelocation) {
target = tasks.shadowJar
prefix = modGroup + ".shadow"
}
shadowJar {
project.configurations.shadeCompile.each { dep ->
from(project.zipTree(dep)) {
exclude 'META-INF', 'META-INF/**'
}
}
manifest {
attributes(getManifestAttributes())
}
minimize() // This will only allow shading for actually used classes
configurations = [
project.configurations.shadowImplementation,
project.configurations.shadowCompile
]
dependsOn(relocateShadowJar)
}
jar {
project.configurations.shadeCompile.each { dep ->
from(project.zipTree(dep)) {
exclude 'META-INF', 'META-INF/**'
}
}
manifest {
attributes(getManifestAttributes())
}
if (usesShadowedDependencies.toBoolean()) {
dependsOn(shadowJar)
enabled = false
}
}
reobf {
if (usesMixins.toBoolean()) {
addExtraSrgFile mixinSrg
}
}
afterEvaluate {
if (usesMixins.toBoolean()) {
tasks.compileJava {
options.compilerArgs += [
"-AreobfSrgFile=${tasks.reobf.srg}",
"-AoutSrgFile=${mixinSrg}",
"-AoutRefMapFile=${refMap}",
// Elan: from what I understand they are just some linter configs so you get some warning on how to properly code
"-XDenableSunApiLintControl",
"-XDignore.symbol.file"
]
}
}
}
runClient {
if (developmentEnvironmentUserName) {
arguments += [
"--username",
developmentEnvironmentUserName
]
}
args(arguments)
jvmArgs(jvmArguments)
}
runServer {
args(arguments)
jvmArgs(jvmArguments)
}
tasks.withType(JavaExec).configureEach {
javaLauncher.set(
javaToolchains.launcherFor {
languageVersion = projectJavaVersion
}
)
}
processResources {
// this will ensure that this task is redone when the versions change.
inputs.property "version", project.version
inputs.property "mcversion", project.minecraft.version
exclude("spotless.gradle")
// replace stuff in mcmod.info, nothing else
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
// replace modVersion and minecraftVersion
expand "minecraftVersion": project.minecraft.version,
"modVersion": modVersion,
"modId": modId,
"modName": modName
}
if (usesMixins.toBoolean()) {
from refMap
}
// copy everything else that's not the mcmod.info
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
exclude 'spotless.gradle'
}
}
def getManifestAttributes() {
def manifestAttributes = [:]
if (!containsMixinsAndOrCoreModOnly.toBoolean() && (usesMixins.toBoolean() || coreModClass)) {
manifestAttributes += ["FMLCorePluginContainsFMLMod": true]
}
if (accessTransformersFile) {
manifestAttributes += ["FMLAT": accessTransformersFile.toString()]
}
if (coreModClass) {
manifestAttributes += ["FMLCorePlugin": modGroup + "." + coreModClass]
}
if (usesMixins.toBoolean()) {
manifestAttributes += [
"TweakClass" : "org.spongepowered.asm.launch.MixinTweaker",
"MixinConfigs" : "mixins." + modId + ".json",
"ForceLoadAsMod": !containsMixinsAndOrCoreModOnly.toBoolean()
]
}
return manifestAttributes
}
task sourcesJar(type: Jar) {
from(sourceSets.main.allSource)
from(file("$projectDir/LICENSE"))
getArchiveClassifier().set('sources')
}
task shadowDevJar(type: ShadowJar) {
project.configurations.shadeCompile.each { dep ->
from(project.zipTree(dep)) {
exclude 'META-INF', 'META-INF/**'
}
}
from sourceSets.main.output
getArchiveClassifier().set("dev")
manifest {
attributes(getManifestAttributes())
}
minimize() // This will only allow shading for actually used classes
configurations = [
project.configurations.shadowImplementation,
project.configurations.shadowCompile
]
}
task relocateShadowDevJar(type: ConfigureShadowRelocation) {
target = tasks.shadowDevJar
prefix = modGroup + ".shadow"
}
task circularResolverJar(type: Jar) {
dependsOn(relocateShadowDevJar)
dependsOn(shadowDevJar)
enabled = false
}
task devJar(type: Jar) {
project.configurations.shadeCompile.each { dep ->
from(project.zipTree(dep)) {
exclude 'META-INF', 'META-INF/**'
}
}
from sourceSets.main.output
getArchiveClassifier().set("dev")
manifest {
attributes(getManifestAttributes())
}
if (usesShadowedDependencies.toBoolean()) {
dependsOn(circularResolverJar)
enabled = false
}
}
task apiJar(type: Jar) {
from(sourceSets.main.allSource) {
include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + '/**'
}
from(sourceSets.main.output) {
include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + '/**'
}
from(sourceSets.main.resources.srcDirs) {
include("LICENSE")
}
getArchiveClassifier().set('api')
}
artifacts {
if (!noPublishedSources) {
archives sourcesJar
}
archives devJar
if (apiPackage) {
archives apiJar
}
}
// The gradle metadata includes all of the additional deps that we disabled from POM generation (including forgeBin with no groupID),
// and isn't strictly needed with the POM so just disable it.
tasks.withType(GenerateModuleMetadata) {
enabled = false
}
// workaround variable hiding in pom processing
def projectConfigs = project.configurations
publishing {
publications {
maven(MavenPublication) {
from components.java
if (usesShadowedDependencies.toBoolean()) {
artifact source: shadowJar, classifier: ""
}
if (!noPublishedSources) {
artifact source: sourcesJar, classifier: "sources"
}
artifact source: usesShadowedDependencies.toBoolean() ? shadowDevJar : devJar, classifier: "dev"
if (apiPackage) {
artifact source: apiJar, classifier: "api"
}
groupId = System.getenv("ARTIFACT_GROUP_ID") ?: "com.github.GTNewHorizons"
artifactId = System.getenv("ARTIFACT_ID") ?: project.name
// Using the identified version, not project.version as it has the prepended 1.7.10
version = System.getenv("RELEASE_VERSION") ?: identifiedVersion
// remove extra garbage from minecraft and minecraftDeps configuration
pom.withXml {
def badArtifacts = [:].withDefault { [] as Set<String> }
for (configuration in [
projectConfigs.minecraft,
projectConfigs.minecraftDeps
]) {
for (dependency in configuration.allDependencies) {
badArtifacts[dependency.group == null ? "" : dependency.group] += dependency.name
}
}
// example for specifying extra stuff to ignore
// badArtifacts["org.example.group"] += "artifactName"
Node pomNode = asNode()
pomNode.dependencies.'*'.findAll() {
badArtifacts[it.groupId.text()].contains(it.artifactId.text())
}.each() {
it.parent().remove(it)
}
}
}
}
repositories {
maven {
url = "http://jenkins.usrv.eu:8081/nexus/content/repositories/releases"
credentials {
username = System.getenv("MAVEN_USER") ?: "NONE"
password = System.getenv("MAVEN_PASSWORD") ?: "NONE"
}
}
}
}
// Updating
task updateBuildScript {
doLast {
if (performBuildScriptUpdate(projectDir.toString())) return
print("Build script already up-to-date!")
}
}
if (!project.getGradle().startParameter.isOffline() && isNewBuildScriptVersionAvailable(projectDir.toString())) {
if (autoUpdateBuildScript.toBoolean()) {
performBuildScriptUpdate(projectDir.toString())
} else {
out.style(Style.SuccessHeader).println("Build script update available! Run 'gradle updateBuildScript'")
}
}
static URL availableBuildScriptUrl() {
new URL("https://raw.githubusercontent.com/GTNewHorizons/ExampleMod1.7.10/master/build.gradle")
}
static URL exampleSettingsGradleUrl() {
new URL("https://raw.githubusercontent.com/GTNewHorizons/ExampleMod1.7.10/master/settings.gradle.example")
}
static URL exampleGitAttributesUrl() {
new URL("https://raw.githubusercontent.com/GTNewHorizons/ExampleMod1.7.10/master/.gitattributes")
}
boolean verifyGitAttributes() {
def gitattributesFile = getFile(".gitattributes")
if (!gitattributesFile.exists()) {
println("Downloading default .gitattributes")
exampleGitAttributesUrl().withInputStream { i -> gitattributesFile.withOutputStream { it << i } }
exec {
workingDir '.'
commandLine 'git', 'add', '--renormalize', '.'
}
return true
}
return false
}
boolean verifySettingsGradle() {
def settingsFile = getFile("settings.gradle")
if (!settingsFile.exists()) {
println("Downloading default settings.gradle")
exampleSettingsGradleUrl().withInputStream { i -> settingsFile.withOutputStream { it << i } }
return true
}
return false
}
boolean performBuildScriptUpdate(String projectDir) {
if (isNewBuildScriptVersionAvailable(projectDir)) {
def buildscriptFile = getFile("build.gradle")
availableBuildScriptUrl().withInputStream { i -> buildscriptFile.withOutputStream { it << i } }
out.style(Style.Success).print("Build script updated. Please REIMPORT the project or RESTART your IDE!")
boolean settingsupdated = verifySettingsGradle()
settingsupdated = verifyGitAttributes() || settingsupdated
if (settingsupdated)
throw new GradleException("Settings has been updated, please re-run task.")
return true
}
return false
}
boolean isNewBuildScriptVersionAvailable(String projectDir) {
Map parameters = ["connectTimeout": 2000, "readTimeout": 2000]
String currentBuildScript = getFile("build.gradle").getText()
String currentBuildScriptHash = getVersionHash(currentBuildScript)
String availableBuildScript = availableBuildScriptUrl().newInputStream(parameters).getText()
String availableBuildScriptHash = getVersionHash(availableBuildScript)
boolean isUpToDate = currentBuildScriptHash.empty || availableBuildScriptHash.empty || currentBuildScriptHash == availableBuildScriptHash
return !isUpToDate
}
static String getVersionHash(String buildScriptContent) {
String versionLine = buildScriptContent.find("^//version: [a-z0-9]*")
if (versionLine != null) {
return versionLine.split(": ").last()
}
return ""
}
configure(updateBuildScript) {
group = 'forgegradle'
description = 'Updates the build script to the latest version'
}
// Parameter Deobfuscation
task deobfParams {
doLast {
String mcpDir = "$project.gradle.gradleUserHomeDir/caches/minecraft/de/oceanlabs/mcp/mcp_$channel/$mappingsVersion"
String mcpZIP = "$mcpDir/mcp_$channel-$mappingsVersion-${minecraftVersion}.zip"
String paramsCSV = "$mcpDir/params.csv"
download.run {
src "https://maven.minecraftforge.net/de/oceanlabs/mcp/mcp_$channel/$mappingsVersion-$minecraftVersion/mcp_$channel-$mappingsVersion-${minecraftVersion}.zip"
dest mcpZIP
overwrite false
}
if (!file(paramsCSV).exists()) {
println("Extracting MCP archive ...")
unzip(mcpZIP, mcpDir)
}
println("Parsing params.csv ...")
Map<String, String> params = new HashMap<>()
Files.lines(Paths.get(paramsCSV)).forEach { line ->
String[] cells = line.split(",")
if (cells.length > 2 && cells[0].matches("p_i?\\d+_\\d+_")) {
params.put(cells[0], cells[1])
}
}
out.style(Style.Success).println("Modified ${replaceParams(file("$projectDir/src/main/java"), params)} files!")
out.style(Style.Failure).println("Don't forget to verify that the code still works as before!\n It could be broken due to duplicate variables existing now\n or parameters taking priority over other variables.")
}
}
static int replaceParams(File file, Map<String, String> params) {
int fileCount = 0
if (file.isDirectory()) {
for (File f : file.listFiles()) {
fileCount += replaceParams(f, params)
}
return fileCount
}
println("Visiting ${file.getName()} ...")
try {
String content = new String(Files.readAllBytes(file.toPath()))
int hash = content.hashCode()
params.forEach { key, value ->
content = content.replaceAll(key, value)
}
if (hash != content.hashCode()) {
Files.write(file.toPath(), content.getBytes("UTF-8"))
return 1
}
} catch (Exception e) {
e.printStackTrace()
}
return 0
}
// Credit: bitsnaps (https://gist.github.com/bitsnaps/00947f2dce66f4bbdabc67d7e7b33681)
static unzip(String zipFileName, String outputDir) {
byte[] buffer = new byte[16384]
ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFileName))
ZipEntry zipEntry = zis.getNextEntry()
while (zipEntry != null) {
File newFile = new File(outputDir + File.separator, zipEntry.name)
if (zipEntry.isDirectory()) {
if (!newFile.isDirectory() && !newFile.mkdirs()) {
throw new IOException("Failed to create directory $newFile")
}
} else {
// fix for Windows-created archives
File parent = newFile.parentFile
if (!parent.isDirectory() && !parent.mkdirs()) {
throw new IOException("Failed to create directory $parent")
}
// write file content
FileOutputStream fos = new FileOutputStream(newFile)
int len = 0
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len)
}
fos.close()
}
zipEntry = zis.getNextEntry()
}
zis.closeEntry()
zis.close()
}
configure(deobfParams) {
group = 'forgegradle'
description = 'Rename all obfuscated parameter names inherited from Minecraft classes'
}
// Dependency Deobfuscation
def deobf(String sourceURL) {
try {
URL url = new URL(sourceURL)
String fileName = url.getFile()
//get rid of directories:
int lastSlash = fileName.lastIndexOf("/")
if (lastSlash > 0) {
fileName = fileName.substring(lastSlash + 1)
}
//get rid of extension:
if (fileName.endsWith(".jar") || fileName.endsWith(".litemod")) {
fileName = fileName.substring(0, fileName.lastIndexOf("."))
}
String hostName = url.getHost()
if (hostName.startsWith("www.")) {
hostName = hostName.substring(4)
}
List parts = Arrays.asList(hostName.split("\\."))
Collections.reverse(parts)
hostName = String.join(".", parts)
return deobf(sourceURL, "$hostName/$fileName")
} catch (Exception e) {
return deobf(sourceURL, "deobf/${sourceURL.hashCode()}")
}
}
// The method above is to be preferred. Use this method if the filename is not at the end of the URL.
def deobf(String sourceURL, String rawFileName) {
String bon2Version = "2.5.1"
String fileName = URLDecoder.decode(rawFileName, "UTF-8")
String cacheDir = "$project.gradle.gradleUserHomeDir/caches"
String bon2Dir = "$cacheDir/forge_gradle/deobf"
String bon2File = "$bon2Dir/BON2-${bon2Version}.jar"
String obfFile = "$cacheDir/modules-2/files-2.1/${fileName}.jar"
String deobfFile = "$cacheDir/modules-2/files-2.1/${fileName}-deobf.jar"
if (file(deobfFile).exists()) {
return files(deobfFile)
}
String mappingsVer
String remoteMappings = project.hasProperty('remoteMappings') ? project.remoteMappings : 'https://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/'
if (remoteMappings) {
String id = "${forgeVersion.split("\\.")[3]}-$minecraftVersion"
String mappingsZIP = "$cacheDir/forge_gradle/maven_downloader/de/oceanlabs/mcp/mcp_snapshot_nodoc/$id/mcp_snapshot_nodoc-${id}.zip"
zipMappings(mappingsZIP, remoteMappings, bon2Dir)
mappingsVer = "snapshot_$id"
} else {
mappingsVer = "${channel}_$mappingsVersion"
}
download.run {
src "http://jenkins.usrv.eu:8081/nexus/content/repositories/releases/com/github/parker8283/BON2/$bon2Version-CUSTOM/BON2-$bon2Version-CUSTOM-all.jar"
dest bon2File
quiet true
overwrite false
}
download.run {
src sourceURL
dest obfFile
quiet true
overwrite false
}
exec {
commandLine 'java', '-jar', bon2File, '--inputJar', obfFile, '--outputJar', deobfFile, '--mcVer', minecraftVersion, '--mappingsVer', mappingsVer, '--notch'
workingDir bon2Dir
standardOutput = new FileOutputStream("${deobfFile}.log")
}
return files(deobfFile)
}
def zipMappings(String zipPath, String url, String bon2Dir) {
File zipFile = new File(zipPath)
if (zipFile.exists()) {
return
}
String fieldsCache = "$bon2Dir/data/fields.csv"
String methodsCache = "$bon2Dir/data/methods.csv"
download.run {
src "${url}fields.csv"
dest fieldsCache
quiet true
}
download.run {
src "${url}methods.csv"
dest methodsCache
quiet true
}
zipFile.getParentFile().mkdirs()
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))
zos.putNextEntry(new ZipEntry("fields.csv"))
Files.copy(Paths.get(fieldsCache), zos)
zos.closeEntry()
zos.putNextEntry(new ZipEntry("methods.csv"))
Files.copy(Paths.get(methodsCache), zos)
zos.closeEntry()
zos.close()
}
// Helper methods
def checkPropertyExists(String propertyName) {
if (!project.hasProperty(propertyName)) {
throw new GradleException("This project requires a property \"" + propertyName + "\"! Please add it your \"gradle.properties\". You can find all properties and their description here: https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/main/gradle.properties")
}
}
def getFile(String relativePath) {
return new File(projectDir, relativePath)
id 'com.gtnewhorizons.gtnhconvention'
}
+1 -1
View File
@@ -1,5 +1,5 @@
// Add your dependencies here
dependencies {
compile('com.github.GTNewHorizons:CodeChickenLib:1.1.5.3:dev')
api('com.github.GTNewHorizons:CodeChickenLib:1.3.0:dev')
}
+146 -23
View File
@@ -1,60 +1,183 @@
# ExampleMod tag to use as Blowdryer (Spotless, etc.) settings version, leave empty to disable.
# LOCAL to test local config updates.
gtnh.settings.blowdryerTag = 0.2.0
# Human-readable mod name, available for mcmod.info population.
modName = CodeChicken Core
# This is a case-sensitive string to identify your mod. Convention is to use lower case.
# Case-sensitive identifier string, available for mcmod.info population and used for automatic mixin JSON generation.
# Conventionally lowercase.
modId = CodeChickenCore
# Root package of the mod, used to find various classes in other properties,
# mcmod.info substitution, enabling assertions in run tasks, etc.
modGroup = codechicken
# WHY is there no version field?
# The build script relies on git to provide a version via tags. It is super easy and will enable you to always know the
# code base or your binary. Check out this tutorial: https://blog.mattclemente.com/2017/10/13/versioning-with-git-tags/
# Whether to use modGroup as the maven publishing group.
# Due to a history of using JitPack, the default is com.github.GTNewHorizons for all mods.
useModGroupForPublishing = false
# Will update your build.gradle automatically whenever an update is available
# Updates your build.gradle and settings.gradle automatically whenever an update is available.
autoUpdateBuildScript = false
# Version of Minecraft to target
minecraftVersion = 1.7.10
# Version of Minecraft Forge to target
forgeVersion = 10.13.4.1614
# Select a username for testing your mod with breakpoints. You may leave this empty for a random username each time you
# restart Minecraft in development. Choose this dependent on your mod:
# Do you need consistent player progressing (for example Thaumcraft)? -> Select a name
# Do you need to test how your custom blocks interacts with a player that is not the owner? -> leave name empty
# Specify an MCP channel for dependency deobfuscation and the deobfParams task.
channel = stable
# Specify an MCP mappings version for dependency deobfuscation and the deobfParams task.
mappingsVersion = 12
# Defines other MCP mappings for dependency deobfuscation.
remoteMappings = https\://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/
# Select a default username for testing your mod. You can always override this per-run by running
# `./gradlew runClient --username=AnotherPlayer`, or configuring this command in your IDE.
developmentEnvironmentUserName = Developer
# Define a source file of your project with:
# Enables using modern Java syntax (up to version 17) via Jabel, while still targeting JVM 8.
# See https://github.com/bsideup/jabel for details on how this works.
enableModernJavaSyntax = false
# Enables injecting missing generics into the decompiled source code for a better coding experience.
# Turns most publicly visible List, Map, etc. into proper List<E>, Map<K, V> types.
enableGenericInjection = false
# Generate a class with a String field for the mod version named as defined below.
# If generateGradleTokenClass is empty or not missing, no such class will be generated.
# If gradleTokenVersion is empty or missing, the field will not be present in the class.
generateGradleTokenClass = codechicken.core.asm.Tags
# Name of the token containing the project's current version to generate/replace.
gradleTokenVersion = VERSION
# [DEPRECATED]
# Multiple source files can be defined here by providing a comma-separated list: Class1.java,Class2.java,Class3.java
# public static final String VERSION = "GRADLETOKEN_VERSION";
# The string's content will be replaced with your mod's version when compiled. You should use this to specify your mod's
# version in @Mod([...], version = VERSION, [...])
# Leave these properties empty to skip individual token replacements
replaceGradleTokenInFile = CodeChickenCoreModContainer.java
gradleTokenModId = GRADLETOKEN_MODID
gradleTokenModName = GRADLETOKEN_MODNAME
gradleTokenVersion = GRADLETOKEN_VERSION
gradleTokenGroupName =
# version in @Mod([...], version = VERSION, [...]).
# Leave these properties empty to skip individual token replacements.
replaceGradleTokenInFile =
# In case your mod provides an API for other mods to implement you may declare its package here. Otherwise, you can
# leave this property empty.
# Example value: apiPackage = api + modGroup = com.myname.mymodid -> com.myname.mymodid.api
# Example value: (apiPackage = api) + (modGroup = com.myname.mymodid) -> com.myname.mymodid.api
apiPackage =
# Specify the configuration file for Forge's access transformers here. It must be placed into /src/main/resources/META-INF/
# Example value: mymodid_at.cfg
# There can be multiple files in a space-separated list.
# Example value: mymodid_at.cfg nei_at.cfg
accessTransformersFile =
# Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled!
usesMixins = false
# Specify the location of your implementation of IMixinPlugin. Leave it empty otherwise.
# Adds some debug arguments like verbose output and class export.
usesMixinDebug = false
# Specify the location of your implementation of IMixinConfigPlugin. Leave it empty otherwise.
mixinPlugin =
# Specify the package that contains all of your Mixins. You may only place Mixins in this package or the build will fail!
mixinsPackage =
# Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin!
# This parameter is for legacy compatibility only
# Example value: coreModClass = asm.FMLPlugin + modGroup = com.myname.mymodid -> com.myname.mymodid.asm.FMLPlugin
# Example value: (coreModClass = asm.FMLPlugin) + (modGroup = com.myname.mymodid) -> com.myname.mymodid.asm.FMLPlugin
coreModClass = core.launch.CodeChickenCorePlugin
# If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod ( = some class
# that is annotated with @Mod) you want this to be true. When in doubt: leave it on false!
containsMixinsAndOrCoreModOnly = true
# If enabled, you may use 'shadowImplementation' for dependencies. They will be integrated in your jar. It is your
# responsibility check the licence and request permission for distribution, if required.
# Enables Mixins even if this mod doesn't use them, useful if one of the dependencies uses mixins.
forceEnableMixins = false
# If enabled, you may use 'shadowCompile' for dependencies. They will be integrated into your jar. It is your
# responsibility to check the license and request permission for distribution if required.
usesShadowedDependencies = false
# If disabled, won't remove unused classes from shadowed dependencies. Some libraries use reflection to access
# their own classes, making the minimization unreliable.
minimizeShadowedDependencies = true
# If disabled, won't rename the shadowed classes.
relocateShadowedDependencies = true
# Adds the GTNH maven, CurseMaven, Modrinth, and some more well-known 1.7.10 repositories.
includeWellKnownRepositories = true
# Change these to your Maven coordinates if you want to publish to a custom Maven repository instead of the default GTNH Maven.
# Authenticate with the MAVEN_USER and MAVEN_PASSWORD environment variables.
# If you need a more complex setup disable maven publishing here and add a publishing repository to addon.gradle.
usesMavenPublishing = true
# Maven repository to publish the mod to.
# mavenPublishUrl = https\://nexus.gtnewhorizons.com/repository/releases/
# Publishing to Modrinth requires you to set the MODRINTH_TOKEN environment variable to your current Modrinth API token.
#
# The project's ID on Modrinth. Can be either the slug or the ID.
# Leave this empty if you don't want to publish to Modrinth.
modrinthProjectId = codechickencore-unofficial
# The project's relations on Modrinth. You can use this to refer to other projects on Modrinth.
# Syntax: scope1-type1:name1;scope2-type2:name2;...
# Where scope can be one of [required, optional, incompatible, embedded],
# type can be one of [project, version],
# and the name is the Modrinth project or version slug/id of the other mod.
# Example: required-project:fplib;optional-project:gasstation;incompatible-project:gregtech
# Note: GTNH Mixins is automatically set as a required dependency if usesMixins = true
modrinthRelations =
# Publishing to CurseForge requires you to set the CURSEFORGE_TOKEN environment variable to one of your CurseForge API tokens.
#
# The project's numeric ID on CurseForge. You can find this in the About Project box.
# Leave this empty if you don't want to publish on CurseForge.
curseForgeProjectId = 746279
# The project's relations on CurseForge. You can use this to refer to other projects on CurseForge.
# Syntax: type1:name1;type2:name2;...
# Where type can be one of [requiredDependency, embeddedLibrary, optionalDependency, tool, incompatible],
# and the name is the CurseForge project slug of the other mod.
# Example: requiredDependency:railcraft;embeddedLibrary:cofhlib;incompatible:buildcraft
# Note: UniMixins is automatically set as a required dependency if usesMixins = true.
curseForgeRelations =
# Optional parameter to customize the produced artifacts. Use this to preserve artifact naming when migrating older
# projects. New projects should not use this parameter.
# customArchiveBaseName =
# Optional parameter to have the build automatically fail if an illegal version is used.
# This can be useful if you e.g. only want to allow versions in the form of '1.1.xxx'.
# The check is ONLY performed if the version is a git tag.
# Note: the specified string must be escaped, so e.g. 1\\.1\\.\\d+ instead of 1\.1\.\d+
# versionPattern =
# Uncomment to prevent the source code from being published.
# noPublishedSources = true
# Uncomment this to disable Spotless checks.
# This should only be uncommented to keep it easier to sync with upstream/other forks.
# That is, if there is no other active fork/upstream, NEVER change this.
# disableSpotless = true
# Uncomment this to disable Checkstyle checks (currently wildcard import check).
# disableCheckstyle = true
# Override the IDEA build type. Valid values are: "" (leave blank, do not override), "idea" (force use native IDEA build), "gradle"
# (force use delegated build).
# This is meant to be set in $HOME/.gradle/gradle.properties.
# e.g. add "systemProp.org.gradle.project.ideaOverrideBuildType=idea" will override the build type to be native build.
# WARNING: If you do use this option, it will overwrite whatever you have in your existing projects. This might not be what you want!
# Usually there is no need to uncomment this here as other developers do not necessarily use the same build type as you.
# ideaOverrideBuildType = idea
# Whether IDEA should run spotless checks when pressing the Build button.
# This is meant to be set in $HOME/.gradle/gradle.properties.
# ideaCheckSpotlessOnBuild = true
Binary file not shown.
+3 -1
View File
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+178 -117
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env sh
#!/bin/sh
#
# Copyright 2015 the original author or authors.
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,78 +17,111 @@
#
##############################################################################
##
## Gradle start up script for UN*X
##
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (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
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
MAX_FD=maximum
warn () {
echo "$*"
}
} >&2
die () {
echo
echo "$*"
echo
exit 1
}
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -97,92 +130,120 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
Vendored
+25 -33
View File
@@ -14,7 +14,7 @@
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,10 +25,14 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@@ -37,13 +41,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@@ -51,48 +55,36 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
-8
View File
@@ -1,12 +1,4 @@
// Add any additional repositiroes for your dependencies here
repositories {
maven {
name 'GTNH Maven'
url 'http://jenkins.usrv.eu:8081/nexus/content/groups/public/'
allowInsecureProtocol
}
maven {
url 'https://jitpack.io'
}
}
+19 -6
View File
@@ -1,10 +1,23 @@
pluginManagement {
repositories {
maven {
// RetroFuturaGradle
name "GTNH Maven"
url "https://nexus.gtnewhorizons.com/repository/public/"
mavenContent {
includeGroup("com.gtnewhorizons")
includeGroupByRegex("com\\.gtnewhorizons\\..+")
}
}
gradlePluginPortal()
mavenCentral()
mavenLocal()
}
}
plugins {
id 'com.diffplug.blowdryerSetup' version '1.6.0'
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.23'
}
apply plugin: 'com.diffplug.blowdryerSetup'
blowdryerSetup {
github('GTNewHorizons/ExampleMod1.7.10', 'tag', '0.1.5')
//devLocal '.' // Use this when testing config updates locally
}
@@ -1,108 +1,22 @@
package codechicken.core;
import codechicken.core.launch.CodeChickenCorePlugin;
import com.google.common.base.Function;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.versioning.ComparableVersion;
import cpw.mods.fml.relauncher.FMLInjectionData;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.StatCollector;
public class CCUpdateChecker {
private static final ArrayList<String> updates = new ArrayList<String>();
private static class ThreadUpdateCheck extends Thread {
private final URL url;
private final Function<String, Void> handler;
public static void tick() {}
public ThreadUpdateCheck(URL url, Function<String, Void> handler) {
this.url = url;
this.handler = handler;
setName("CodeChicken Update Checker");
}
@Override
public void run() {
try {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
BufferedReader read = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String ret = read.readLine();
read.close();
if (ret == null) ret = "";
handler.apply(ret);
} catch (SocketTimeoutException ignored) {
} catch (UnknownHostException ignored) {
} catch (IOException iox) {
iox.printStackTrace();
}
}
}
public static void tick() {
Minecraft mc = Minecraft.getMinecraft();
if (!mc.inGameHasFocus) return;
synchronized (updates) {
for (String s : updates) mc.thePlayer.addChatMessage(new ChatComponentText(s));
updates.clear();
}
}
public static void addUpdateMessage(String s) {
synchronized (updates) {
updates.add(s);
}
}
public static void addUpdateMessage(String s) {}
public static String mcVersion() {
return (String) FMLInjectionData.data()[4];
}
public static void updateCheck(final String mod, final String version) {
updateCheck(
"http://www.chickenbones.net/Files/notification/version.php?" + "version="
+ mcVersion() + "&" + "file="
+ mod,
new Function<String, Void>() {
@Override
public Void apply(String ret) {
if (!ret.startsWith("Ret: ")) {
CodeChickenCorePlugin.logger.error(
"Failed to check update for " + mod + " returned: " + ret);
return null;
}
ComparableVersion newversion = new ComparableVersion(ret.substring(5));
if (newversion.compareTo(new ComparableVersion(version)) > 0)
addUpdateMessage(
StatCollector.translateToLocalFormatted("codechickencore.update", newversion, mod));
return null;
}
});
}
public static void updateCheck(final String mod, final String version) {}
public static void updateCheck(String mod) {
updateCheck(mod, Loader.instance().getIndexedModList().get(mod).getVersion());
}
public static void updateCheck(String mod) {}
public static void updateCheck(String url, Function<String, Void> handler) {
try {
new ThreadUpdateCheck(new URL(url), handler).start();
} catch (MalformedURLException e) {
CodeChickenCorePlugin.logger.error("Malformed URL: " + url, e);
}
}
public static void updateCheck(String url, Function<String, Void> handler) {}
}
@@ -1,12 +1,5 @@
package codechicken.core;
import codechicken.core.launch.CodeChickenCorePlugin;
import codechicken.lib.asm.ASMHelper;
import com.google.common.collect.ImmutableList;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModClassLoader;
import cpw.mods.fml.relauncher.CoreModManager;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@@ -15,10 +8,22 @@ import java.util.HashSet;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import net.minecraft.launchwrapper.Launch;
import org.objectweb.asm.tree.ClassNode;
import com.google.common.collect.ImmutableList;
import codechicken.core.launch.CodeChickenCorePlugin;
import codechicken.lib.asm.ASMHelper;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModClassLoader;
import cpw.mods.fml.relauncher.CoreModManager;
public class ClassDiscoverer {
public IStringMatcher matcher;
public String[] superclasses;
public ArrayList<Class<?>> classes;
@@ -35,13 +40,12 @@ public class ClassDiscoverer {
}
public ClassDiscoverer(Class<?>... superclasses) {
this(
new IStringMatcher() {
public boolean matches(String test) {
return true;
}
},
superclasses);
this(new IStringMatcher() {
public boolean matches(String test) {
return true;
}
}, superclasses);
}
public ArrayList<Class<?>> findClasses() {
@@ -79,10 +83,8 @@ public class ClassDiscoverer {
}
private void findClasspathMods() {
List<String> knownLibraries = ImmutableList.<String>builder()
.addAll(modClassLoader.getDefaultLibraries())
.addAll(CoreModManager.getLoadedCoremods())
.build();
List<String> knownLibraries = ImmutableList.<String>builder().addAll(modClassLoader.getDefaultLibraries())
.addAll(CoreModManager.getLoadedCoremods()).build();
File[] minecraftSources = modClassLoader.getParentSources();
HashSet<String> searchedSources = new HashSet<String>();
for (File minecraftSource : minecraftSources) {
@@ -98,7 +100,8 @@ public class ClassDiscoverer {
readFromZipFile(minecraftSource);
} catch (Exception e) {
CodeChickenCorePlugin.logger.error(
"Failed to scan " + minecraftSource.getAbsolutePath() + ", the zip file is invalid", e);
"Failed to scan " + minecraftSource.getAbsolutePath() + ", the zip file is invalid",
e);
}
}
} else if (minecraftSource.isDirectory()) {
@@ -1,10 +1,5 @@
package codechicken.core;
import codechicken.core.internal.CCCEventHandler;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.network.NetworkManager;
@@ -12,7 +7,14 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.world.World;
import codechicken.core.internal.CCCEventHandler;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class ClientUtils extends CommonUtils {
private static Minecraft mc() {
return Minecraft.getMinecraft();
}
@@ -22,7 +24,7 @@ public class ClientUtils extends CommonUtils {
}
public static boolean inWorld() // TODO unused
{
{
return mc().getNetHandler() != null;
}
@@ -59,8 +61,8 @@ public class ClientUtils extends CommonUtils {
public static void enhanceSupportersList(Object mod) {
ModContainer mc = FMLCommonHandler.instance().findContainerFor(mod);
mc.getMetadata().description =
mc.getMetadata().description.replace("Supporters:", EnumChatFormatting.AQUA + "Supporters:");
mc.getMetadata().description = mc.getMetadata().description
.replace("Supporters:", EnumChatFormatting.AQUA + "Supporters:");
GuiModListScroll.register(mod);
}
}
@@ -1,14 +1,17 @@
package codechicken.core;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.relauncher.FMLInjectionData;
import java.io.File;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.relauncher.FMLInjectionData;
public class CommonUtils {
public static boolean isClient() {
return FMLCommonHandler.instance().getSide().isClient();
}
@@ -1,7 +1,39 @@
package codechicken.core;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL11.GL_ALWAYS;
import static org.lwjgl.opengl.GL11.GL_EQUAL;
import static org.lwjgl.opengl.GL11.GL_KEEP;
import static org.lwjgl.opengl.GL11.GL_PACK_ALIGNMENT;
import static org.lwjgl.opengl.GL11.GL_REPLACE;
import static org.lwjgl.opengl.GL11.GL_STENCIL_INDEX;
import static org.lwjgl.opengl.GL11.GL_STENCIL_TEST;
import static org.lwjgl.opengl.GL11.GL_UNPACK_ALIGNMENT;
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE;
import static org.lwjgl.opengl.GL11.GL_ZERO;
import static org.lwjgl.opengl.GL11.glColorMask;
import static org.lwjgl.opengl.GL11.glDisable;
import static org.lwjgl.opengl.GL11.glEnable;
import static org.lwjgl.opengl.GL11.glPixelStorei;
import static org.lwjgl.opengl.GL11.glReadPixels;
import static org.lwjgl.opengl.GL11.glStencilFunc;
import static org.lwjgl.opengl.GL11.glStencilOp;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.List;
import javax.imageio.ImageIO;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.MinecraftForgeClient;
import org.lwjgl.BufferUtils;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import codechicken.core.launch.CodeChickenCorePlugin;
import codechicken.lib.gui.GuiDraw;
@@ -10,21 +42,9 @@ import cpw.mods.fml.client.GuiModList;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.ModMetadata;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.List;
import javax.imageio.ImageIO;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.MinecraftForgeClient;
import org.lwjgl.BufferUtils;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
public class GuiModListScroll {
private static List<ModContainer> scrollMods = new LinkedList<ModContainer>();
public static void register(Object mod) {
@@ -45,9 +65,8 @@ public class GuiModListScroll {
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glReadPixels(0, 0, d.width, d.height, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, buf);
for (int i = 0; i < d.width; i++)
for (int j = 0; j < d.height; j++)
img.setRGB(i, d.height - j - 1, buf.get(j * d.width + i) == 0 ? 0 : 0xFFFFFF);
for (int i = 0; i < d.width; i++) for (int j = 0; j < d.height; j++)
img.setRGB(i, d.height - j - 1, buf.get(j * d.width + i) == 0 ? 0 : 0xFFFFFF);
try {
ImageIO.write(img, "png", new File("stencil" + x + ".png"));
} catch (IOException e) {
@@ -109,9 +128,7 @@ public class GuiModListScroll {
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
String description = selectedMod.getMetadata().description;
int height = GuiDraw.fontRenderer
.listFormattedStringToWidth(description, x2 - x1)
.size()
int height = GuiDraw.fontRenderer.listFormattedStringToWidth(description, x2 - x1).size()
* GuiDraw.fontRenderer.FONT_HEIGHT;
boolean needsScroll = height > y2 - y1draw;
@@ -142,8 +159,8 @@ public class GuiModListScroll {
}
/**
* Does not add the last 10 px space before the description normally starts
* Ignores empty child mods expecting a background draw overwrite
* Does not add the last 10 px space before the description normally starts Ignores empty child mods expecting a
* background draw overwrite
*/
private static int calcDescY(GuiModList gui, ModContainer mod) {
ModMetadata meta = mod.getMetadata();
@@ -3,5 +3,6 @@ package codechicken.core;
import net.minecraft.entity.player.EntityPlayerMP;
public interface IGuiPacketSender {
void sendPacket(EntityPlayerMP player, int windowId);
}
@@ -1,5 +1,6 @@
package codechicken.core;
public interface IStringMatcher {
public boolean matches(String test);
}
@@ -3,6 +3,7 @@ package codechicken.core;
import codechicken.core.launch.CodeChickenCorePlugin;
public class ProfileTimer {
public double decay;
public long startTime;
public long nanoTime;
@@ -1,13 +1,15 @@
package codechicken.core;
import codechicken.lib.asm.ObfMapping;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import codechicken.lib.asm.ObfMapping;
public class ReflectionManager {
public static HashMap<Class<?>, Class<?>> primitiveWrappers = new HashMap<Class<?>, Class<?>>();
static {
@@ -27,12 +29,12 @@ public class ReflectionManager {
if (primitive == Long.class && Long.class.isInstance(obj)) return true;
if ((primitive == Long.class || primitive == Integer.class) && Integer.class.isInstance(obj)) return true;
if ((primitive == Long.class || primitive == Integer.class || primitive == Short.class)
&& Short.class.isInstance(obj)) return true;
if ((primitive == Long.class
|| primitive == Integer.class
|| primitive == Short.class
|| primitive == Byte.class)
&& Integer.class.isInstance(obj)) return true;
&& Short.class.isInstance(obj))
return true;
if ((primitive == Long.class || primitive == Integer.class
|| primitive == Short.class
|| primitive == Byte.class) && Integer.class.isInstance(obj))
return true;
if (primitive == Double.class && Double.class.isInstance(obj)) return true;
if ((primitive == Double.class || primitive == Float.class) && Float.class.isInstance(obj)) return true;
@@ -64,7 +66,7 @@ public class ReflectionManager {
public static void setField(Class<?> class1, Object instance, String name, Object value)
throws IllegalArgumentException, IllegalAccessException {
setField(class1, instance, new String[] {name}, value);
setField(class1, instance, new String[] { name }, value);
}
public static void setField(Class<?> class1, Object instance, String[] names, Object value)
@@ -95,19 +97,15 @@ public class ReflectionManager {
}
/**
* Static function
* void return type
* single name
* Static function void return type single name
*/
public static void callMethod(Class<?> class1, String name, Object... params)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
callMethod(class1, null, new String[] {name}, params);
callMethod(class1, null, new String[] { name }, params);
}
/**
* Static function
* void return type
* single name
* Static function void return type single name
*/
public static void callMethod(Class<?> class1, String[] names, Object... params)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
@@ -115,12 +113,11 @@ public class ReflectionManager {
}
/**
* void return type
* single name
* void return type single name
*/
public static void callMethod(Class<?> class1, Object instance, String name, Object... params)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
callMethod(class1, null, instance, new String[] {name}, params);
callMethod(class1, null, instance, new String[] { name }, params);
}
/**
@@ -132,12 +129,11 @@ public class ReflectionManager {
}
/**
* Static method
* single name
* Static method single name
*/
public static <R> R callMethod(Class<?> class1, Class<R> returntype, String name, Object... params)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
return callMethod(class1, returntype, null, new String[] {name}, params);
return callMethod(class1, returntype, null, new String[] { name }, params);
}
/**
@@ -153,14 +149,12 @@ public class ReflectionManager {
*/
public static <R> R callMethod(Class<?> class1, Class<R> returntype, Object instance, String name, Object... params)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
return callMethod(class1, returntype, instance, new String[] {name}, params);
return callMethod(class1, returntype, instance, new String[] { name }, params);
}
public static <R> R callMethod(
Class<?> class1, Class<R> returntype, Object instance, String[] names, Object... params)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
nextMethod:
for (Method method : class1.getDeclaredMethods()) {
public static <R> R callMethod(Class<?> class1, Class<R> returntype, Object instance, String[] names,
Object... params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
nextMethod: for (Method method : class1.getDeclaredMethods()) {
boolean match = false;
for (String name : names) {
if (method.getName().equals(name)) {
@@ -204,8 +198,7 @@ public class ReflectionManager {
public static <T> T newInstance(Class<T> class1, Object... params)
throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
nextMethod:
for (Constructor<?> constructor : class1.getDeclaredConstructors()) {
nextMethod: for (Constructor<?> constructor : class1.getDeclaredConstructors()) {
Class<?>[] paramtypes = constructor.getParameterTypes();
if (paramtypes.length != params.length) continue;
+15 -10
View File
@@ -1,20 +1,24 @@
package codechicken.core;
import codechicken.lib.asm.ObfMapping;
import com.mojang.authlib.GameProfile;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.Container;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.IChatComponent;
import com.mojang.authlib.GameProfile;
import codechicken.lib.asm.ObfMapping;
public class ServerUtils extends CommonUtils {
public static MinecraftServer mc() {
return MinecraftServer.getServer();
}
@@ -49,17 +53,18 @@ public class ServerUtils extends CommonUtils {
static {
try {
field_152661_c = ReflectionManager.getField(new ObfMapping(
"net/minecraft/server/management/PlayerProfileCache", "field_152661_c", "[Ljava/util/Map;"));
c_ProfileEntry = ServerUtils.class
.getClassLoader()
field_152661_c = ReflectionManager.getField(
new ObfMapping(
"net/minecraft/server/management/PlayerProfileCache",
"field_152661_c",
"[Ljava/util/Map;"));
c_ProfileEntry = ServerUtils.class.getClassLoader()
.loadClass("net.minecraft.server.management.PlayerProfileCache$ProfileEntry");
func_152668_a = c_ProfileEntry.getDeclaredMethod(new ObfMapping(
func_152668_a = c_ProfileEntry.getDeclaredMethod(
new ObfMapping(
"net/minecraft/server/management/PlayerProfileCache$ProfileEntry",
"func_152668_a",
"()Lcom/mojang/authlib/GameProfile;")
.toRuntime()
.s_name);
"()Lcom/mojang/authlib/GameProfile;").toRuntime().s_name);
func_152668_a.setAccessible(true);
} catch (Exception e) {
@@ -6,7 +6,9 @@ import java.util.List;
import java.util.Map.Entry;
public class TaskProfiler {
public static class ProfilerResult {
public final String name;
public final long time;
public final double fraction;
@@ -1,13 +1,16 @@
package codechicken.core.asm;
import codechicken.lib.asm.ObfMapping;
import com.google.common.collect.ImmutableBiMap;
import cpw.mods.fml.common.asm.transformers.AccessTransformer;
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
import java.io.IOException;
import java.lang.reflect.Field;
import com.google.common.collect.ImmutableBiMap;
import codechicken.lib.asm.ObfMapping;
import cpw.mods.fml.common.asm.transformers.AccessTransformer;
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
public class CodeChickenAccessTransformer extends AccessTransformer {
private static boolean makeAllPublic;
private static Field f_classNameBiMap;
private static Object emptyMap = ImmutableBiMap.of();
@@ -20,12 +23,10 @@ public class CodeChickenAccessTransformer extends AccessTransformer {
private void loadPublicConfig() {
if (ObfMapping.obfuscated) return;
makeAllPublic = CodeChickenCoreModContainer.config
.getTag("dev.runtimePublic")
.setComment(
"Enabling this setting will make all minecraft classes public at runtime in MCP just as they are in modloader."
+ "\nYou should ONLY use this when you are testing with a mod that relies on runtime publicity and doesn't include access transformers."
+ "\nSuch mods are doing the wrong thing and should be fixed.")
makeAllPublic = CodeChickenCoreModContainer.config.getTag("dev.runtimePublic").setComment(
"Enabling this setting will make all minecraft classes public at runtime in MCP just as they are in modloader."
+ "\nYou should ONLY use this when you are testing with a mod that relies on runtime publicity and doesn't include access transformers."
+ "\nSuch mods are doing the wrong thing and should be fixed.")
.getBooleanValue(false);
if (!makeAllPublic) return;
@@ -1,25 +1,31 @@
package codechicken.core.asm;
import codechicken.core.CCUpdateChecker;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
import net.minecraftforge.common.MinecraftForge;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import codechicken.core.ClientUtils;
import codechicken.core.featurehack.LiquidTextures;
import codechicken.core.internal.CCCEventHandler;
import codechicken.core.launch.CodeChickenCorePlugin;
import codechicken.lib.config.ConfigFile;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import cpw.mods.fml.common.*;
import cpw.mods.fml.common.DummyModContainer;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.LoadController;
import cpw.mods.fml.common.ModMetadata;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.VersionParser;
import cpw.mods.fml.common.versioning.VersionRange;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
import net.minecraftforge.common.MinecraftForge;
public class CodeChickenCoreModContainer extends DummyModContainer {
public static ConfigFile config;
public static void loadConfig() {
@@ -34,9 +40,9 @@ public class CodeChickenCoreModContainer extends DummyModContainer {
private static ModMetadata getModMetadata() {
final ModMetadata modMetadata = new ModMetadata();
modMetadata.name = "GRADLETOKEN_MODNAME";
modMetadata.modId = "GRADLETOKEN_MODID";
modMetadata.version = "GRADLETOKEN_VERSION";
modMetadata.name = "CodeChicken Core";
modMetadata.modId = "CodeChickenCore";
modMetadata.version = Tags.VERSION;
return modMetadata;
}
@@ -68,8 +74,6 @@ public class CodeChickenCoreModContainer extends DummyModContainer {
@Subscribe
public void init(FMLInitializationEvent event) {
if (event.getSide().isClient()) {
if (config.getTag("checkUpdates").getBooleanValue(true)) CCUpdateChecker.updateCheck(getModId());
ClientUtils.enhanceSupportersList("CodeChickenCore");
FMLCommonHandler.instance().bus().register(new CCCEventHandler());
@@ -1,19 +1,23 @@
package codechicken.core.asm;
import codechicken.lib.asm.ASMHelper;
import codechicken.lib.asm.ClassHeirachyManager;
import codechicken.lib.asm.ObfMapping;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import net.minecraft.launchwrapper.IClassTransformer;
import net.minecraft.launchwrapper.LaunchClassLoader;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import codechicken.lib.asm.ASMHelper;
import codechicken.lib.asm.ClassHeirachyManager;
import codechicken.lib.asm.ObfMapping;
public class DefaultImplementationTransformer implements IClassTransformer {
private static LaunchClassLoader cl = (LaunchClassLoader) ClassHeirachyManager.class.getClassLoader();
private static ClassNode getClassNode(String name) {
@@ -25,6 +29,7 @@ public class DefaultImplementationTransformer implements IClassTransformer {
}
static class InterfaceImpl {
public final String iname;
public ArrayList<MethodNode> impls = new ArrayList<MethodNode>();
@@ -35,11 +40,10 @@ public class DefaultImplementationTransformer implements IClassTransformer {
for (MethodNode method : inode.methods) names.add(method.name + method.desc);
ClassNode cnode = getClassNode(cname);
for (MethodNode method : cnode.methods)
if (names.contains(method.name + method.desc)) {
impls.add(method);
method.desc = new ObfMapping(cnode.name, method.name, method.desc).toRuntime().s_desc;
}
for (MethodNode method : cnode.methods) if (names.contains(method.name + method.desc)) {
impls.add(method);
method.desc = new ObfMapping(cnode.name, method.name, method.desc).toRuntime().s_desc;
}
}
public boolean patch(ClassNode cnode) {
@@ -13,13 +13,16 @@ import java.util.Map;
import java.util.Stack;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import net.minecraft.launchwrapper.IClassTransformer;
import net.minecraft.launchwrapper.Launch;
import net.minecraft.launchwrapper.LaunchClassLoader;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Opcodes;
public class DelegatedTransformer implements IClassTransformer {
private static ArrayList<IClassTransformer> delegatedTransformers;
private static Method m_defineClass;
private static Field f_cachedClasses;
@@ -27,8 +30,8 @@ public class DelegatedTransformer implements IClassTransformer {
public DelegatedTransformer() {
delegatedTransformers = new ArrayList<IClassTransformer>();
try {
m_defineClass = ClassLoader.class.getDeclaredMethod(
"defineClass", String.class, byte[].class, Integer.TYPE, Integer.TYPE);
m_defineClass = ClassLoader.class
.getDeclaredMethod("defineClass", String.class, byte[].class, Integer.TYPE, Integer.TYPE);
m_defineClass.setAccessible(true);
f_cachedClasses = LaunchClassLoader.class.getDeclaredField("cachedClasses");
f_cachedClasses.setAccessible(true);
@@ -53,9 +56,10 @@ public class DelegatedTransformer implements IClassTransformer {
if (bytes == null) {
String resourceName = transformer.replace('.', '/') + ".class";
ZipEntry entry = jar.getEntry(resourceName);
if (entry == null)
throw new Exception("Failed to add transformer: " + transformer + ". Entry not found in jar file "
+ jarFile.getName());
if (entry == null) throw new Exception(
"Failed to add transformer: " + transformer
+ ". Entry not found in jar file "
+ jarFile.getName());
bytes = readFully(jar.getInputStream(entry));
}
@@ -63,14 +67,12 @@ public class DelegatedTransformer implements IClassTransformer {
defineDependancies(bytes, jar, jarFile);
Class<?> clazz = defineClass(transformer, bytes);
if (!IClassTransformer.class.isAssignableFrom(clazz))
throw new Exception(
"Failed to add transformer: " + transformer + " is not an instance of IClassTransformer");
if (!IClassTransformer.class.isAssignableFrom(clazz)) throw new Exception(
"Failed to add transformer: " + transformer + " is not an instance of IClassTransformer");
IClassTransformer classTransformer;
try {
classTransformer = (IClassTransformer)
clazz.getDeclaredConstructor(File.class).newInstance(jarFile);
classTransformer = (IClassTransformer) clazz.getDeclaredConstructor(File.class).newInstance(jarFile);
} catch (NoSuchMethodException nsme) {
classTransformer = (IClassTransformer) clazz.newInstance();
}
@@ -5,6 +5,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
@@ -12,9 +13,11 @@ import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class DependancyLister extends ClassVisitor {
private static Pattern classdesc = Pattern.compile("L(.+?);");
private class DependancyMethodLister extends MethodVisitor {
public DependancyMethodLister(int api) {
super(api);
}
@@ -6,5 +6,5 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Target({ ElementType.TYPE })
public @interface InterfaceDependancies {}
@@ -1,5 +1,28 @@
package codechicken.core.asm;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import net.minecraft.launchwrapper.IClassTransformer;
import net.minecraft.launchwrapper.Launch;
import net.minecraft.launchwrapper.LaunchClassLoader;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import codechicken.lib.asm.ASMHelper;
import codechicken.lib.asm.ASMInit;
import codechicken.lib.asm.CC_ClassWriter;
@@ -7,30 +30,17 @@ import codechicken.lib.asm.ObfMapping;
import codechicken.obfuscator.IHeirachyEvaluator;
import codechicken.obfuscator.ObfuscationMap.ObfuscationEntry;
import codechicken.obfuscator.ObfuscationRun;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import cpw.mods.fml.common.asm.transformers.AccessTransformer;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;
import java.util.Map.Entry;
import net.minecraft.launchwrapper.IClassTransformer;
import net.minecraft.launchwrapper.Launch;
import net.minecraft.launchwrapper.LaunchClassLoader;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
public class MCPDeobfuscationTransformer implements IClassTransformer, Opcodes, IHeirachyEvaluator {
static {
ASMInit.init();
}
public static class LoadPlugin implements IFMLLoadingPlugin {
@Override
public String[] getASMTransformerClass() {
return new String[0];
@@ -72,8 +82,8 @@ public class MCPDeobfuscationTransformer implements IClassTransformer, Opcodes,
try {
f_transformers = LaunchClassLoader.class.getDeclaredField("transformers");
f_modifiers = AccessTransformer.class.getDeclaredField("modifiers");
Class<?> c_Modifier =
Class.forName(AccessTransformer.class.getName() + "$Modifier", false, Launch.classLoader);
Class<?> c_Modifier = Class
.forName(AccessTransformer.class.getName() + "$Modifier", false, Launch.classLoader);
f_Modifier_name = c_Modifier.getDeclaredField("name");
f_Modifier_desc = c_Modifier.getDeclaredField("desc");
@@ -110,8 +120,7 @@ public class MCPDeobfuscationTransformer implements IClassTransformer, Opcodes,
public static void load() {
CodeChickenCoreModContainer.loadConfig();
if (CodeChickenCoreModContainer.config
.getTag("dev.deobfuscate")
if (CodeChickenCoreModContainer.config.getTag("dev.deobfuscate")
.setComment("set to true to completely deobfuscate mcp names")
.getBooleanValue(!ObfMapping.obfuscated)) {
run = new ObfuscationRun(
@@ -120,8 +129,7 @@ public class MCPDeobfuscationTransformer implements IClassTransformer, Opcodes,
ObfuscationRun.fillDefaults(new HashMap<String, String>()));
run.obf.setHeirachyEvaluator(instance);
run.setQuiet().parseMappings();
Collections.addAll(
excludedPackages, run.config.get("excludedPackages").split(";"));
Collections.addAll(excludedPackages, run.config.get("excludedPackages").split(";"));
if (ObfMapping.obfuscated) {
ObfMapping.loadMCPRemapper();
@@ -151,8 +159,12 @@ public class MCPDeobfuscationTransformer implements IClassTransformer, Opcodes,
private byte[] injectCallback(byte[] bytes) {
ClassNode cnode = ASMHelper.createClassNode(bytes);
MethodNode mnode = ASMHelper.findMethod(new ObfMapping(cnode.name, "<clinit>", "()V"), cnode);
mnode.instructions.insert(new MethodInsnNode(
INVOKESTATIC, "codechicken/core/asm/MCPDeobfuscationTransformer", "loadCallback", "()V"));
mnode.instructions.insert(
new MethodInsnNode(
INVOKESTATIC,
"codechicken/core/asm/MCPDeobfuscationTransformer",
"loadCallback",
"()V"));
return ASMHelper.createBytes(cnode, 0);
}
@@ -205,8 +217,7 @@ public class MCPDeobfuscationTransformer implements IClassTransformer, Opcodes,
try {
byte[] bytes = Launch.classLoader.getClassBytes(name);
if (bytes != null) return ObfuscationRun.getParents(ASMHelper.createClassNode(bytes));
} catch (IOException ignored) {
}
} catch (IOException ignored) {}
// clear the miss cache because the library containing it might be loaded later
Launch.classLoader.clearNegativeEntries(Collections.singleton(name));
return null;
@@ -1,18 +1,22 @@
package codechicken.core.asm;
import static org.objectweb.asm.Opcodes.*;
import static org.objectweb.asm.Opcodes.ASM4;
import codechicken.lib.asm.ObfMapping;
import java.io.File;
import java.io.PrintWriter;
import net.minecraft.launchwrapper.Launch;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.util.Printer;
import org.objectweb.asm.util.TraceMethodVisitor;
import codechicken.lib.asm.ObfMapping;
public class MethodASMifier extends ClassVisitor {
PrintWriter printWriter;
ObfMapping method;
Printer asmifier;
@@ -1,20 +1,28 @@
package codechicken.core.asm;
import static codechicken.lib.asm.InsnComparator.*;
import static codechicken.lib.asm.InsnComparator.findOnce;
import codechicken.lib.asm.*;
import codechicken.lib.asm.ModularASMTransformer.MethodReplacer;
import codechicken.lib.asm.ModularASMTransformer.MethodTransformer;
import codechicken.lib.asm.ModularASMTransformer.MethodWriter;
import codechicken.lib.config.ConfigTag;
import java.util.Map;
import net.minecraft.launchwrapper.IClassTransformer;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.MethodNode;
import codechicken.lib.asm.ASMBlock;
import codechicken.lib.asm.ASMInit;
import codechicken.lib.asm.ASMReader;
import codechicken.lib.asm.ModularASMTransformer;
import codechicken.lib.asm.ModularASMTransformer.MethodReplacer;
import codechicken.lib.asm.ModularASMTransformer.MethodTransformer;
import codechicken.lib.asm.ModularASMTransformer.MethodWriter;
import codechicken.lib.asm.ObfMapping;
import codechicken.lib.config.ConfigTag;
public class TweakTransformer implements IClassTransformer, Opcodes {
static {
ASMInit.init();
}
@@ -25,43 +33,42 @@ public class TweakTransformer implements IClassTransformer, Opcodes {
public static void load() {
CodeChickenCoreModContainer.loadConfig();
tweaks = CodeChickenCoreModContainer.config
.getTag("tweaks")
.setComment("Various tweaks that can be applied to game mechanics.")
.useBraces();
tweaks = CodeChickenCoreModContainer.config.getTag("tweaks")
.setComment("Various tweaks that can be applied to game mechanics.").useBraces();
tweaks.removeTag("persistantLava");
if (tweaks.getTag("environmentallyFriendlyCreepers")
.setComment(
"If set to true, creepers will not destroy landscape. (A version of mobGriefing setting just for creepers)")
if (tweaks.getTag("environmentallyFriendlyCreepers").setComment(
"If set to true, creepers will not destroy landscape. (A version of mobGriefing setting just for creepers)")
.getBooleanValue(false)) {
transformer.add(new MethodReplacer(
new ObfMapping("net/minecraft/entity/monster/EntityCreeper", "func_146077_cc", "()V"),
blocks.get("d_environmentallyFriendlyCreepers"),
blocks.get("environmentallyFriendlyCreepers")));
transformer.add(
new MethodReplacer(
new ObfMapping("net/minecraft/entity/monster/EntityCreeper", "func_146077_cc", "()V"),
blocks.get("d_environmentallyFriendlyCreepers"),
blocks.get("environmentallyFriendlyCreepers")));
}
if (!tweaks.getTag("softLeafReplace")
.setComment("If set to false, leaves will only replace air when growing")
if (!tweaks.getTag("softLeafReplace").setComment("If set to false, leaves will only replace air when growing")
.getBooleanValue(false)) {
transformer.add(new MethodWriter(
ACC_PUBLIC,
new ObfMapping(
"net/minecraft/block/Block",
"canBeReplacedByLeaves",
"(Lnet/minecraft/world/IBlockAccess;III)Z"),
blocks.get("softLeafReplace")));
transformer.add(
new MethodWriter(
ACC_PUBLIC,
new ObfMapping(
"net/minecraft/block/Block",
"canBeReplacedByLeaves",
"(Lnet/minecraft/world/IBlockAccess;III)Z"),
blocks.get("softLeafReplace")));
}
if (tweaks.getTag("doFireTickOut")
.setComment(
"If set to true and doFireTick is disabled in the game rules, fire will still dissipate if it's not over a fire source")
if (tweaks.getTag("doFireTickOut").setComment(
"If set to true and doFireTick is disabled in the game rules, fire will still dissipate if it's not over a fire source")
.getBooleanValue(true)) {
transformer.add(
new MethodTransformer(new ObfMapping(
"net/minecraft/block/BlockFire",
"func_149674_a",
"(Lnet/minecraft/world/World;IIILjava/util/Random;)V")) {
new MethodTransformer(
new ObfMapping(
"net/minecraft/block/BlockFire",
"func_149674_a",
"(Lnet/minecraft/world/World;IIILjava/util/Random;)V")) {
@Override
public void transform(MethodNode mv) {
ASMBlock needle = blocks.get("n_doFireTick");
@@ -79,10 +86,12 @@ public class TweakTransformer implements IClassTransformer, Opcodes {
.setComment("If set to true two adjacent water source blocks will not generate a third.")
.getBooleanValue(false)) {
transformer.add(
new MethodTransformer(new ObfMapping(
"net/minecraft/block/BlockDynamicLiquid",
"func_149674_a",
"(Lnet/minecraft/world/World;IIILjava/util/Random;)V")) {
new MethodTransformer(
new ObfMapping(
"net/minecraft/block/BlockDynamicLiquid",
"func_149674_a",
"(Lnet/minecraft/world/World;IIILjava/util/Random;)V")) {
@Override
public void transform(MethodNode mv) {
ASMBlock needle = blocks.get("finiteWater");
@@ -1,7 +1,7 @@
package codechicken.core.commands;
import codechicken.core.ServerUtils;
import java.util.List;
import net.minecraft.command.ICommand;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
@@ -15,8 +15,12 @@ import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.DimensionManager;
import codechicken.core.ServerUtils;
public abstract class CoreCommand implements ICommand {
public class WCommandSender implements ICommandSender {
public ICommandSender wrapped;
public WCommandSender(ICommandSender sender) {
@@ -125,10 +129,8 @@ public abstract class CoreCommand implements ICommand {
@Override
public boolean canCommandSenderUseCommand(ICommandSender var1) {
if (OPOnly()) {
if (var1 instanceof EntityPlayer)
return MinecraftServer.getServer()
.getConfigurationManager()
.func_152596_g(((EntityPlayer) var1).getGameProfile());
if (var1 instanceof EntityPlayer) return MinecraftServer.getServer().getConfigurationManager()
.func_152596_g(((EntityPlayer) var1).getGameProfile());
else if (var1 instanceof MinecraftServer) return true;
else return false;
}
@@ -11,6 +11,7 @@ import net.minecraft.world.ChunkPosition;
import net.minecraft.world.WorldServer;
public abstract class PlayerCommand extends CoreCommand {
@Override
public boolean canCommandSenderUseCommand(ICommandSender var1) {
if (!super.canCommandSenderUseCommand(var1)) return false;
@@ -26,8 +27,8 @@ public abstract class PlayerCommand extends CoreCommand {
public abstract void handleCommand(WorldServer world, EntityPlayerMP player, String[] args);
public ChunkPosition getPlayerLookingAtBlock(EntityPlayerMP player, float reach) {
Vec3 vec3d =
Vec3.createVectorHelper(player.posX, (player.posY + 1.6200000000000001D) - player.yOffset, player.posZ);
Vec3 vec3d = Vec3
.createVectorHelper(player.posX, (player.posY + 1.6200000000000001D) - player.yOffset, player.posZ);
Vec3 vec3d1 = player.getLook(1.0F);
Vec3 vec3d2 = vec3d.addVector(vec3d1.xCoord * reach, vec3d1.yCoord * reach, vec3d1.zCoord * reach);
MovingObjectPosition hit = player.worldObj.rayTraceBlocks(vec3d, vec3d2);
@@ -39,8 +40,8 @@ public abstract class PlayerCommand extends CoreCommand {
}
public Entity getPlayerLookingAtEntity(EntityPlayerMP player, float reach) {
Vec3 vec3d =
Vec3.createVectorHelper(player.posX, (player.posY + 1.6200000000000001D) - player.yOffset, player.posZ);
Vec3 vec3d = Vec3
.createVectorHelper(player.posX, (player.posY + 1.6200000000000001D) - player.yOffset, player.posZ);
Vec3 vec3d1 = player.getLook(1.0F);
Vec3 vec3d2 = vec3d.addVector(vec3d1.xCoord * reach, vec3d1.yCoord * reach, vec3d1.zCoord * reach);
MovingObjectPosition hit = player.worldObj.rayTraceBlocks(vec3d, vec3d2);
@@ -4,6 +4,7 @@ import net.minecraft.command.ICommandSender;
import net.minecraft.server.MinecraftServer;
public abstract class ServerCommand extends CoreCommand {
@Override
public void processCommand(ICommandSender var1, String[] var2) {
handleCommand(var2, (MinecraftServer) var1);
@@ -5,7 +5,9 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
public class EntityRenderHook extends Entity {
public static interface IRenderCallback {
public void render(float frame, int pass);
public boolean shouldRenderInPass(int pass);
@@ -5,7 +5,9 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
public class EntityUpdateHook extends Entity {
public static interface IUpdateCallback {
public void onUpdate();
public boolean isValid();
@@ -6,6 +6,7 @@ import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class FeatureHack {
private static boolean updateHookEnabled = false;
private static boolean renderHookEnabled = false;
@@ -1,14 +1,17 @@
package codechicken.core.featurehack;
import codechicken.lib.asm.ObfMapping;
import java.lang.reflect.Field;
import java.util.Map;
import net.minecraft.item.Item;
import net.minecraft.util.ObjectIntIdentityMap;
import net.minecraft.util.RegistryNamespaced;
import net.minecraft.util.RegistrySimple;
import codechicken.lib.asm.ObfMapping;
public class GameDataManipulator {
public static Field f_registryObjects;
public static Field f_underlyingIntegerMap;
@@ -16,15 +19,13 @@ public class GameDataManipulator {
try {
f_registryObjects = RegistrySimple.class.getDeclaredField(
new ObfMapping("net/minecraft/util/RegistrySimple", "field_82596_a", "Ljava/util/Map;")
.toRuntime()
.s_name);
.toRuntime().s_name);
f_registryObjects.setAccessible(true);
f_underlyingIntegerMap = RegistryNamespaced.class.getDeclaredField(new ObfMapping(
f_underlyingIntegerMap = RegistryNamespaced.class.getDeclaredField(
new ObfMapping(
"net/minecraft/util/RegistryNamespaced",
"field_148759_a",
"Lnet/minecraft/util/ObjectIntIdentityMap;")
.toRuntime()
.s_name);
"Lnet/minecraft/util/ObjectIntIdentityMap;").toRuntime().s_name);
f_underlyingIntegerMap.setAccessible(true);
} catch (Exception e) {
throw new RuntimeException(e);
@@ -1,5 +1,12 @@
package codechicken.core.featurehack;
import java.lang.reflect.Field;
import net.minecraft.init.Blocks;
import net.minecraft.util.IIcon;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.common.MinecraftForge;
import codechicken.core.ReflectionManager;
import codechicken.core.asm.TweakTransformer;
import codechicken.core.featurehack.mc.TextureLavaFX;
@@ -8,13 +15,9 @@ import codechicken.core.featurehack.mc.TextureWaterFX;
import codechicken.core.featurehack.mc.TextureWaterFlowFX;
import codechicken.lib.asm.ObfMapping;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import java.lang.reflect.Field;
import net.minecraft.init.Blocks;
import net.minecraft.util.IIcon;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.common.MinecraftForge;
public class LiquidTextures {
public static IIcon[] newTextures = new IIcon[4];
public static boolean replaceLava;
@@ -23,14 +26,10 @@ public class LiquidTextures {
private static Field field_tex;
public static void init() {
replaceWater = TweakTransformer.tweaks
.getTag("replaceWaterFX")
.setComment("Set this to true to use the pre1.5 water textures")
.getBooleanValue(false);
replaceLava = TweakTransformer.tweaks
.getTag("replaceLavaFX")
.setComment("Set this to true to use the pre1.5 lava textures")
.getBooleanValue(false);
replaceWater = TweakTransformer.tweaks.getTag("replaceWaterFX")
.setComment("Set this to true to use the pre1.5 water textures").getBooleanValue(false);
replaceLava = TweakTransformer.tweaks.getTag("replaceLavaFX")
.setComment("Set this to true to use the pre1.5 lava textures").getBooleanValue(false);
if (replaceWater) {
newTextures[0] = new TextureWaterFX().texture;
newTextures[1] = new TextureWaterFlowFX().texture;
@@ -4,9 +4,11 @@ import net.minecraft.client.renderer.entity.Render;
import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.MinecraftForgeClient;
import org.lwjgl.opengl.GL11;
public class RenderEntityRenderHook extends Render {
@Override
public void doRender(Entity entity, double x, double y, double z, float f, float frame) {
EntityRenderHook hook = (EntityRenderHook) entity;
@@ -5,6 +5,7 @@ import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
public class RenderNull extends Render {
@Override
public void doRender(Entity var1, double var2, double var4, double var6, float var8, float var9) {}
@@ -3,23 +3,23 @@ package codechicken.core.featurehack;
import static net.minecraftforge.common.util.ForgeDirection.UP;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.world.World;
public class TweakTransformerHelper {
public static void quenchFireTick(World world, int x, int y, int z, Random rand) {
Block base = world.getBlock(x, y - 1, z);
boolean supported = (base != null && base.isFireSource(world, x, y - 1, z, UP));
if (!Blocks.fire.canPlaceBlockAt(world, x, y, z)
|| !supported
&& world.isRaining()
&& (world.canLightningStrikeAt(x, y, z)
|| world.canLightningStrikeAt(x - 1, y, z)
|| world.canLightningStrikeAt(x + 1, y, z)
|| world.canLightningStrikeAt(x, y, z - 1)
|| world.canLightningStrikeAt(x, y, z + 1))) world.setBlockToAir(x, y, z);
if (!Blocks.fire.canPlaceBlockAt(world, x, y, z) || !supported && world.isRaining()
&& (world.canLightningStrikeAt(x, y, z) || world.canLightningStrikeAt(x - 1, y, z)
|| world.canLightningStrikeAt(x + 1, y, z)
|| world.canLightningStrikeAt(x, y, z - 1)
|| world.canLightningStrikeAt(x, y, z + 1)))
world.setBlockToAir(x, y, z);
else {
int meta = world.getBlockMetadata(x, y, z);
if (meta < 15) world.setBlockMetadataWithNotify(x, y, z, meta + rand.nextInt(3) / 2, 0);
@@ -1,13 +1,15 @@
package codechicken.core.featurehack.mc;
import net.minecraft.util.MathHelper;
import codechicken.lib.colour.ColourRGBA;
import codechicken.lib.render.TextureFX;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.util.MathHelper;
@SideOnly(Side.CLIENT)
public class TextureLavaFX extends TextureFX {
protected float[] field_76876_g = new float[256];
protected float[] field_76878_h = new float[256];
protected float[] field_76879_i = new float[256];
@@ -52,16 +54,16 @@ public class TextureLavaFX extends TextureFX {
this.field_76878_h[var1 + var2 * tileSizeBase] = var3 / 10.0F
+ (this.field_76879_i[(var1 + 0 & tileSizeMask) + (var2 + 0 & tileSizeMask) * tileSizeBase]
+ this.field_76879_i[
(var1 + 1 & tileSizeMask) + (var2 + 0 & tileSizeMask) * tileSizeBase]
+ this.field_76879_i[
(var1 + 1 & tileSizeMask) + (var2 + 1 & tileSizeMask) * tileSizeBase]
+ this.field_76879_i[
(var1 + 0 & tileSizeMask) + (var2 + 1 & tileSizeMask) * tileSizeBase])
+ this.field_76879_i[(var1 + 1 & tileSizeMask)
+ (var2 + 0 & tileSizeMask) * tileSizeBase]
+ this.field_76879_i[(var1 + 1 & tileSizeMask)
+ (var2 + 1 & tileSizeMask) * tileSizeBase]
+ this.field_76879_i[(var1 + 0 & tileSizeMask)
+ (var2 + 1 & tileSizeMask) * tileSizeBase])
/ 4.0F
* 0.8F;
this.field_76879_i[var1 + var2 * tileSizeBase] +=
this.field_76877_j[var1 + var2 * tileSizeBase] * 0.01F;
this.field_76879_i[var1 + var2 * tileSizeBase] += this.field_76877_j[var1 + var2 * tileSizeBase]
* 0.01F;
if (this.field_76879_i[var1 + var2 * tileSizeBase] < 0.0F) {
this.field_76879_i[var1 + var2 * tileSizeBase] = 0.0F;
@@ -1,13 +1,15 @@
package codechicken.core.featurehack.mc;
import net.minecraft.util.MathHelper;
import codechicken.lib.colour.ColourRGBA;
import codechicken.lib.render.TextureFX;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.util.MathHelper;
@SideOnly(Side.CLIENT)
public class TextureLavaFlowFX extends TextureFX {
protected float[] field_76871_g = new float[256];
protected float[] field_76874_h = new float[256];
protected float[] field_76875_i = new float[256];
@@ -60,16 +62,16 @@ public class TextureLavaFlowFX extends TextureFX {
this.field_76874_h[var1 + var2 * tileSizeBase] = var3 / 10.0F
+ (this.field_76875_i[(var1 + 0 & tileSizeMask) + (var2 + 0 & tileSizeMask) * tileSizeBase]
+ this.field_76875_i[
(var1 + 1 & tileSizeMask) + (var2 + 0 & tileSizeMask) * tileSizeBase]
+ this.field_76875_i[
(var1 + 1 & tileSizeMask) + (var2 + 1 & tileSizeMask) * tileSizeBase]
+ this.field_76875_i[
(var1 + 0 & tileSizeMask) + (var2 + 1 & tileSizeMask) * tileSizeBase])
+ this.field_76875_i[(var1 + 1 & tileSizeMask)
+ (var2 + 0 & tileSizeMask) * tileSizeBase]
+ this.field_76875_i[(var1 + 1 & tileSizeMask)
+ (var2 + 1 & tileSizeMask) * tileSizeBase]
+ this.field_76875_i[(var1 + 0 & tileSizeMask)
+ (var2 + 1 & tileSizeMask) * tileSizeBase])
/ 4.0F
* 0.8F;
this.field_76875_i[var1 + var2 * tileSizeBase] +=
this.field_76872_j[var1 + var2 * tileSizeBase] * 0.01F;
this.field_76875_i[var1 + var2 * tileSizeBase] += this.field_76872_j[var1 + var2 * tileSizeBase]
* 0.01F;
if (this.field_76875_i[var1 + var2 * tileSizeBase] < 0.0F) {
this.field_76875_i[var1 + var2 * tileSizeBase] = 0.0F;
@@ -7,6 +7,7 @@ import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class TextureWaterFX extends TextureFX {
/** red RGB value for water texture */
protected float[] red = new float[256];
@@ -7,6 +7,7 @@ import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class TextureWaterFlowFX extends TextureFX {
protected float[] field_76880_g = new float[256];
protected float[] field_76883_h = new float[256];
protected float[] field_76884_i = new float[256];
@@ -51,15 +52,15 @@ public class TextureWaterFlowFX extends TextureFX {
var3 += this.field_76880_g[var5 + var6 * tileSizeBase];
}
this.field_76883_h[var1 + var2 * tileSizeBase] =
var3 / 3.2F + this.field_76884_i[var1 + var2 * tileSizeBase] * 0.8F;
this.field_76883_h[var1 + var2 * tileSizeBase] = var3 / 3.2F
+ this.field_76884_i[var1 + var2 * tileSizeBase] * 0.8F;
}
}
for (var1 = 0; var1 < tileSizeBase; ++var1) {
for (var2 = 0; var2 < tileSizeBase; ++var2) {
this.field_76884_i[var1 + var2 * tileSizeBase] +=
this.field_76881_j[var1 + var2 * tileSizeBase] * 0.05F;
this.field_76884_i[var1 + var2 * tileSizeBase] += this.field_76881_j[var1 + var2 * tileSizeBase]
* 0.05F;
if (this.field_76884_i[var1 + var2 * tileSizeBase] < 0.0F) {
this.field_76884_i[var1 + var2 * tileSizeBase] = 0.0F;
@@ -6,6 +6,7 @@ import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidTank;
public class ExtendedFluidTank implements IFluidTank {
private FluidStack fluid;
private boolean changeType;
private int capacity;
@@ -1,6 +1,5 @@
package codechicken.core.fluid;
import codechicken.lib.inventory.InventoryUtils;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@@ -11,7 +10,10 @@ import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidHandler;
import codechicken.lib.inventory.InventoryUtils;
public class FluidUtils {
public static int B = FluidContainerRegistry.BUCKET_VOLUME;
public static FluidStack water = new FluidStack(FluidRegistry.WATER, 1000);
public static FluidStack lava = new FluidStack(FluidRegistry.LAVA, 1000);
@@ -68,8 +70,7 @@ public class FluidUtils {
}
public static NBTTagCompound write(FluidStack fluid, NBTTagCompound tag) {
return fluid == null || fluid.getFluid() == null
? new NBTTagCompound()
return fluid == null || fluid.getFluid() == null ? new NBTTagCompound()
: fluid.writeToNBT(new NBTTagCompound());
}
@@ -5,6 +5,7 @@ import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidHandler;
public class TankAccess {
public IFluidHandler tank;
public ForgeDirection side;
@@ -1,11 +1,14 @@
package codechicken.core.gui;
import com.google.common.base.Objects;
import java.util.Map;
import java.util.TreeMap;
import com.google.common.base.Objects;
public class ClickCounter<T> {
public class ClickCount {
public T clicked;
public long time;
public int count;
@@ -3,9 +3,11 @@ package codechicken.core.gui;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
public class GuiCCButton extends GuiWidget {
public String text;
public String actionCommand;
private boolean isEnabled = true;
@@ -32,8 +34,7 @@ public class GuiCCButton extends GuiWidget {
public void mouseClicked(int x, int y, int button) {
if (isEnabled && pointInside(x, y) && actionCommand != null) {
sendAction(actionCommand, button);
Minecraft.getMinecraft()
.getSoundHandler()
Minecraft.getMinecraft().getSoundHandler()
.playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 1.0F));
}
}
@@ -52,8 +53,8 @@ public class GuiCCButton extends GuiWidget {
int state = getButtonTex(mousex, mousey);
drawTexturedModalRect(x, y, 0, 46 + state * 20, width / 2, height / 2); // top left
drawTexturedModalRect(x + width / 2, y, 200 - width / 2, 46 + state * 20, width / 2, height / 2); // top right
drawTexturedModalRect(
x, y + height / 2, 0, 46 + state * 20 + 20 - height / 2, width / 2, height / 2); // bottom left
drawTexturedModalRect(x, y + height / 2, 0, 46 + state * 20 + 20 - height / 2, width / 2, height / 2); // bottom
// left
drawTexturedModalRect(
x + width / 2,
y + height / 2,
@@ -2,9 +2,11 @@ package codechicken.core.gui;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.util.ChatAllowedCharacters;
import org.lwjgl.input.Keyboard;
public class GuiCCTextField extends GuiWidget {
private String text;
private boolean isFocused;
private boolean isEnabled;
@@ -63,10 +65,9 @@ public class GuiCCTextField extends GuiWidget {
public void keyTyped(char c, int keycode) {
if (!isEnabled || !isFocused) return;
/*if(c == '\t')//tab
{
parentGuiScreen.selectNextField();
}*/
/*
* if(c == '\t')//tab { parentGuiScreen.selectNextField(); }
*/
if (c == '\026') // paste
{
String s = GuiScreen.getClipboardString();
@@ -90,8 +91,7 @@ public class GuiCCTextField extends GuiWidget {
}
public boolean canAddChar(char c) {
return allowedCharacters == null
? ChatAllowedCharacters.isAllowedCharacter(c)
return allowedCharacters == null ? ChatAllowedCharacters.isAllowedCharacter(c)
: allowedCharacters.indexOf(c) >= 0;
}
@@ -1,14 +1,18 @@
package codechicken.core.gui;
import codechicken.lib.gui.GuiDraw;
import java.awt.Point;
import java.util.ArrayList;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import codechicken.lib.gui.GuiDraw;
public class GuiScreenWidget extends GuiScreen implements IGuiActionListener {
public ArrayList<GuiWidget> widgets = new ArrayList<GuiWidget>();
public int xSize, ySize, guiTop, guiLeft;
@@ -1,10 +1,13 @@
package codechicken.core.gui;
import java.awt.Dimension;
import java.awt.Rectangle;
import codechicken.lib.math.MathHelper;
import codechicken.lib.vec.Rectangle4i;
import java.awt.*;
public abstract class GuiScrollPane extends GuiWidget {
protected int scrollclicky = -1;
protected float scrollpercent;
protected int scrollmousey;
@@ -28,7 +31,10 @@ public abstract class GuiScrollPane extends GuiWidget {
public Rectangle windowBounds() {
return new Rectangle(
x + marginleft, y + margintop, width - marginleft - marginright, height - margintop - marginbottom);
x + marginleft,
y + margintop,
width - marginleft - marginright,
height - margintop - marginbottom);
}
public abstract int contentHeight();
@@ -103,13 +109,8 @@ public abstract class GuiScrollPane extends GuiWidget {
Rectangle w = windowBounds();
int barempty = height - sbar.height;
if (button == 0
&& sbar.height < height
&& // the scroll bar can move (not full length)
mx >= sbar.x
&& mx <= sbar.x + sbar.width
&& my >= y
&& my <= y + height) // in the scroll pane
if (button == 0 && sbar.height < height && // the scroll bar can move (not full length)
mx >= sbar.x && mx <= sbar.x + sbar.width && my >= y && my <= y + height) // in the scroll pane
{
if (my < sbar.y) {
percentscrolled = (my - y) / (float) barempty;
@@ -126,14 +127,12 @@ public abstract class GuiScrollPane extends GuiWidget {
}
/**
* Mouse down on slot area
* Coordinates relative to slot content area
* Mouse down on slot area Coordinates relative to slot content area
*/
public void slotDown(int mx, int my, int button) {}
/**
* Mouse up on slot area
* Coordinates relative to slot content area
* Mouse up on slot area Coordinates relative to slot content area
*/
public void slotUp(int mx, int my, int button) {}
@@ -141,7 +140,7 @@ public abstract class GuiScrollPane extends GuiWidget {
public void mouseMovedOrUp(int mx, int my, int button) {
Rectangle w = windowBounds();
if (isScrolling() && button == 0) // we were scrolling and we released mouse
scrollclicky = -1;
scrollclicky = -1;
else if (w.contains(mx, my)) slotUp(mx - w.x, my - w.y + scrolledPixels(), button);
}
@@ -1,9 +1,11 @@
package codechicken.core.gui;
import java.awt.*;
import java.awt.Rectangle;
import org.lwjgl.input.Keyboard;
public abstract class GuiScrollSlot extends GuiScrollPane {
protected String actionCommand;
public boolean focused;
protected ClickCounter<Integer> click = new ClickCounter<Integer>();
@@ -8,6 +8,7 @@ import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.util.ResourceLocation;
public class GuiWidget extends Gui {
protected static final ResourceLocation guiTex = new ResourceLocation("textures/gui/widgets.png");
public GuiScreen parentScreen;
@@ -1,5 +1,6 @@
package codechicken.core.gui;
public interface IGuiActionListener {
public void actionPerformed(String actionCommand, Object... params);
}
@@ -1,6 +1,7 @@
package codechicken.core.internal;
import codechicken.core.CCUpdateChecker;
import net.minecraftforge.client.event.GuiScreenEvent;
import codechicken.core.GuiModListScroll;
import cpw.mods.fml.client.GuiModList;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
@@ -8,16 +9,15 @@ import cpw.mods.fml.common.gameevent.TickEvent;
import cpw.mods.fml.common.gameevent.TickEvent.Phase;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraftforge.client.event.GuiScreenEvent;
public class CCCEventHandler {
public static int renderTime;
public static float renderFrame;
@SubscribeEvent
public void clientTick(TickEvent.ClientTickEvent event) {
if (event.phase == Phase.END) {
CCUpdateChecker.tick();
renderTime++;
}
}
@@ -1,17 +1,21 @@
package codechicken.core.inventory;
import java.awt.Point;
import java.util.ArrayList;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.inventory.Container;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import codechicken.core.gui.GuiWidget;
import codechicken.core.gui.IGuiActionListener;
import codechicken.lib.gui.GuiDraw;
import java.awt.Point;
import java.util.ArrayList;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.inventory.Container;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
public class GuiContainerWidget extends GuiContainer implements IGuiActionListener {
public ArrayList<GuiWidget> widgets = new ArrayList<GuiWidget>();
public GuiContainerWidget(Container inventorySlots) {
@@ -1,17 +1,7 @@
package codechicken.core.launch;
import codechicken.core.asm.*;
import codechicken.lib.config.ConfigTag;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
import cpw.mods.fml.common.versioning.VersionParser;
import cpw.mods.fml.relauncher.CoreModManager;
import cpw.mods.fml.relauncher.FMLInjectionData;
import cpw.mods.fml.relauncher.IFMLCallHook;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin.MCVersion;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin.TransformerExclusions;
import java.awt.*;
import java.awt.Desktop;
import java.awt.GraphicsEnvironment;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
@@ -22,20 +12,39 @@ import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import javax.swing.JEditorPane;
import javax.swing.JOptionPane;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@TransformerExclusions(value = {"codechicken.core.asm", "codechicken.obfuscator"})
import codechicken.core.asm.CodeChickenCoreModContainer;
import codechicken.core.asm.DelegatedTransformer;
import codechicken.core.asm.MCPDeobfuscationTransformer;
import codechicken.core.asm.Tags;
import codechicken.core.asm.TweakTransformer;
import codechicken.lib.config.ConfigTag;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
import cpw.mods.fml.common.versioning.VersionParser;
import cpw.mods.fml.relauncher.CoreModManager;
import cpw.mods.fml.relauncher.FMLInjectionData;
import cpw.mods.fml.relauncher.IFMLCallHook;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin.MCVersion;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin.TransformerExclusions;
@TransformerExclusions(value = { "codechicken.core.asm", "codechicken.obfuscator" })
@MCVersion("1.7.10")
public class CodeChickenCorePlugin implements IFMLLoadingPlugin, IFMLCallHook {
public static final String mcVersion = "[1.7.10]";
@Deprecated
public static final String version = "1.1.3-unused";
public static final String version = Tags.VERSION;
public static File minecraftDir;
public static String currentMcVersion;
@@ -47,27 +56,25 @@ public class CodeChickenCorePlugin implements IFMLLoadingPlugin, IFMLCallHook {
minecraftDir = (File) FMLInjectionData.data()[6];
currentMcVersion = (String) FMLInjectionData.data()[4];
DepLoader.load();
injectDeobfPlugin();
}
private void injectDeobfPlugin() {
try {
Class<?> wrapperClass = Class.forName("cpw.mods.fml.relauncher.CoreModManager$FMLPluginWrapper");
Constructor wrapperConstructor = wrapperClass.getConstructor(
String.class, IFMLLoadingPlugin.class, File.class, Integer.TYPE, String[].class);
Constructor wrapperConstructor = wrapperClass
.getConstructor(String.class, IFMLLoadingPlugin.class, File.class, Integer.TYPE, String[].class);
Field f_loadPlugins = CoreModManager.class.getDeclaredField("loadPlugins");
wrapperConstructor.setAccessible(true);
f_loadPlugins.setAccessible(true);
((List) f_loadPlugins.get(null))
.add(
2,
wrapperConstructor.newInstance(
"CCCDeobfPlugin",
new MCPDeobfuscationTransformer.LoadPlugin(),
null,
0,
new String[0]));
((List) f_loadPlugins.get(null)).add(
2,
wrapperConstructor.newInstance(
"CCCDeobfPlugin",
new MCPDeobfuscationTransformer.LoadPlugin(),
null,
0,
new String[0]));
} catch (Exception e) {
logger.error("Failed to inject MCPDeobfuscation Transformer", e);
}
@@ -88,13 +95,13 @@ public class CodeChickenCorePlugin implements IFMLLoadingPlugin, IFMLCallHook {
ep.setEditable(false);
ep.setOpaque(false);
ep.addHyperlinkListener(new HyperlinkListener() {
@Override
public void hyperlinkUpdate(HyperlinkEvent event) {
try {
if (event.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED))
Desktop.getDesktop().browse(event.getURL().toURI());
} catch (Exception ignored) {
}
} catch (Exception ignored) {}
}
});
@@ -134,45 +141,43 @@ public class CodeChickenCorePlugin implements IFMLLoadingPlugin, IFMLCallHook {
}
public static void systemCheck(ConfigTag checkRAM) {
long minBytes = parseSize(checkRAM.getTag("minRAM")
.setComment("Amount of RAM minimum this modpack needs to load")
.getValue("3GB"));
long minBytes = parseSize(
checkRAM.getTag("minRAM").setComment("Amount of RAM minimum this modpack needs to load")
.getValue("3GB"));
if (Runtime.getRuntime().maxMemory() < minBytes) {
String err = "You should have at least " + humanReadableByteCountBin(minBytes)
+ " of RAM but you have only allocated "
+ humanReadableByteCountBin(Runtime.getRuntime().maxMemory()) + ".";
+ humanReadableByteCountBin(Runtime.getRuntime().maxMemory())
+ ".";
logger.error(err);
JEditorPane ep = new JEditorPane(
"text/html",
"<html>" + err + "<br>"
+ checkRAM.getTag("modPack")
.setComment("Name of the modpack")
"<html>" + err
+ "<br>"
+ checkRAM.getTag("modPack").setComment("Name of the modpack")
.getValue("Unidentified ModPack")
+ " seriously won't run without enough RAM. "
+ checkRAM.getTag("wiki")
.setComment("Webpage describing RAM settings")
.getValue(
"See <a href=\"https://downloadmoreram.com\">DownloadMoreRam.com</a> for details.")
+ checkRAM.getTag("wiki").setComment("Webpage describing RAM settings").getValue(
"See <a href=\"https://downloadmoreram.com\">DownloadMoreRam.com</a> for details.")
+ "<br>Recommended values are between "
+ checkRAM.getTag("recRAM")
.setComment("Lower bound of recommended RAM")
.getValue("4GB") + " and "
+ checkRAM.getTag("recRAMUpper")
.setComment("Upper bound of recommended RAM")
+ checkRAM.getTag("recRAM").setComment("Lower bound of recommended RAM").getValue("4GB")
+ " and "
+ checkRAM.getTag("recRAMUpper").setComment("Upper bound of recommended RAM")
.getValue("6GB")
+ ". Check your launcher's JVM arguments." + "</html>");
+ ". Check your launcher's JVM arguments."
+ "</html>");
ep.setEditable(false);
ep.setOpaque(false);
ep.addHyperlinkListener(new HyperlinkListener() {
@Override
public void hyperlinkUpdate(HyperlinkEvent event) {
try {
if (event.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED))
Desktop.getDesktop().browse(event.getURL().toURI());
} catch (Exception ignored) {
}
} catch (Exception ignored) {}
}
});
@@ -185,12 +190,9 @@ public class CodeChickenCorePlugin implements IFMLLoadingPlugin, IFMLCallHook {
@Override
public String[] getASMTransformerClass() {
versionCheck(mcVersion, "CodeChickenCore");
return new String[] {
"codechicken.lib.asm.ClassHeirachyManager",
"codechicken.core.asm.TweakTransformer",
"codechicken.core.asm.DelegatedTransformer",
"codechicken.core.asm.DefaultImplementationTransformer"
};
return new String[] { "codechicken.lib.asm.ClassHeirachyManager", "codechicken.core.asm.TweakTransformer",
"codechicken.core.asm.DelegatedTransformer", "codechicken.core.asm.DefaultImplementationTransformer",
"codechicken.lib.asm.RedirectorTransformer" };
}
@Override
@@ -215,13 +217,12 @@ public class CodeChickenCorePlugin implements IFMLLoadingPlugin, IFMLCallHook {
public Void call() {
CodeChickenCoreModContainer.loadConfig();
ConfigTag checkRAM;
checkRAM = CodeChickenCoreModContainer.config
.getTag("checks")
.setComment("Configuration options for checking various requirements for a modpack.")
.useBraces();
checkRAM = CodeChickenCoreModContainer.config.getTag("checks")
.setComment("Configuration options for checking various requirements for a modpack.").useBraces();
if (checkRAM.getTag("checkRAM")
.setComment("If set to true, check RAM available for Minecraft before continuing to load")
.getBooleanValue(false)) systemCheck(checkRAM);
.getBooleanValue(false))
systemCheck(checkRAM);
TweakTransformer.load();
scanCodeChickenMods();
@@ -1,52 +1,26 @@
package codechicken.core.launch;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.Box;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import cpw.mods.fml.common.versioning.ComparableVersion;
import cpw.mods.fml.relauncher.FMLInjectionData;
import cpw.mods.fml.relauncher.FMLLaunchHandler;
import cpw.mods.fml.relauncher.IFMLCallHook;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin.MCVersion;
import java.awt.*;
import java.awt.Dialog.ModalityType;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.*;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import net.minecraft.launchwrapper.LaunchClassLoader;
import sun.misc.URLClassPath;
import sun.net.util.URLUtil;
/**
* For autodownloading stuff.
* This is really unoriginal, mostly ripped off FML, credits to cpw.
* For autodownloading stuff. This is really unoriginal, mostly ripped off FML, credits to cpw.
*/
@MCVersion("1.7.10")
public class DepLoader implements IFMLLoadingPlugin, IFMLCallHook {
private static ByteBuffer downloadBuffer = ByteBuffer.allocateDirect(1 << 23);
private static final String owner = "CB's DepLoader";
private static DepLoadInst inst;
public interface IDownloadDisplay {
void resetProgress(int sizeGuess);
void setPokeThread(Thread currentThread);
@@ -64,135 +38,44 @@ public class DepLoader implements IFMLLoadingPlugin, IFMLCallHook {
@SuppressWarnings("serial")
public static class Downloader extends JOptionPane implements IDownloadDisplay {
private JDialog container;
private JLabel currentActivity;
private JProgressBar progress;
boolean stopIt;
Thread pokeThread;
private Box makeProgressPanel() {
Box box = Box.createVerticalBox();
box.add(Box.createRigidArea(new Dimension(0, 10)));
JLabel welcomeLabel = new JLabel("<html><b><font size='+1'>" + owner
+ " is setting up your minecraft environment</font></b></html>");
box.add(welcomeLabel);
welcomeLabel.setAlignmentY(LEFT_ALIGNMENT);
welcomeLabel =
new JLabel("<html>Please wait, " + owner + " has some tasks to do before you can play</html>");
welcomeLabel.setAlignmentY(LEFT_ALIGNMENT);
box.add(welcomeLabel);
box.add(Box.createRigidArea(new Dimension(0, 10)));
currentActivity = new JLabel("Currently doing ...");
box.add(currentActivity);
box.add(Box.createRigidArea(new Dimension(0, 10)));
progress = new JProgressBar(0, 100);
progress.setStringPainted(true);
box.add(progress);
box.add(Box.createRigidArea(new Dimension(0, 30)));
return box;
return null;
}
@Override
public JDialog makeDialog() {
if (container != null) return container;
setMessageType(JOptionPane.INFORMATION_MESSAGE);
setMessage(makeProgressPanel());
setOptions(new Object[] {"Stop"});
addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getSource() == Downloader.this && evt.getPropertyName() == VALUE_PROPERTY) {
requestClose("This will stop minecraft from launching\nAre you sure you want to do this?");
}
}
});
container = new JDialog(null, "Hello", ModalityType.MODELESS);
container.setResizable(false);
container.setLocationRelativeTo(null);
container.add(this);
this.updateUI();
container.pack();
container.setMinimumSize(container.getPreferredSize());
container.setVisible(true);
container.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
container.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
requestClose(
"Closing this window will stop minecraft from launching\nAre you sure you wish to do this?");
}
});
return container;
return null;
}
protected void requestClose(String message) {
int shouldClose = JOptionPane.showConfirmDialog(
container,
message,
"Are you sure you want to stop?",
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE);
if (shouldClose == JOptionPane.YES_OPTION) container.dispose();
stopIt = true;
if (pokeThread != null) pokeThread.interrupt();
}
protected void requestClose(String message) {}
@Override
public void updateProgressString(String progressUpdate, Object... data) {
// FMLLog.finest(progressUpdate, data);
if (currentActivity != null) currentActivity.setText(String.format(progressUpdate, data));
}
public void updateProgressString(String progressUpdate, Object... data) {}
@Override
public void resetProgress(int sizeGuess) {
if (progress != null) progress.getModel().setRangeProperties(0, 0, 0, sizeGuess, false);
}
public void resetProgress(int sizeGuess) {}
@Override
public void updateProgress(int fullLength) {
if (progress != null) progress.getModel().setValue(fullLength);
}
public void updateProgress(int fullLength) {}
@Override
public void setPokeThread(Thread currentThread) {
this.pokeThread = currentThread;
}
public void setPokeThread(Thread currentThread) {}
@Override
public boolean shouldStopIt() {
return stopIt;
return true;
}
@Override
public void showErrorDialog(String name, String url) {
JEditorPane ep = new JEditorPane(
"text/html",
"<html>" + owner
+ " was unable to download required library " + name
+ "<br>Check your internet connection and try restarting or download it manually from"
+ "<br><a href=\""
+ url + "\">" + url + "</a> and put it in your mods folder" + "</html>");
ep.setEditable(false);
ep.setOpaque(false);
ep.addHyperlinkListener(new HyperlinkListener() {
@Override
public void hyperlinkUpdate(HyperlinkEvent event) {
try {
if (event.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED))
Desktop.getDesktop().browse(event.getURL().toURI());
} catch (Exception e) {
}
}
});
JOptionPane.showMessageDialog(null, ep, "A download error has occurred", JOptionPane.ERROR_MESSAGE);
}
public void showErrorDialog(String name, String url) {}
}
public static class DummyDownloader implements IDownloadDisplay {
@Override
public void resetProgress(int sizeGuess) {}
@@ -220,6 +103,7 @@ public class DepLoader implements IFMLLoadingPlugin, IFMLCallHook {
}
public static class VersionedFile {
public final Pattern pattern;
public final String filename;
public final ComparableVersion version;
@@ -244,6 +128,7 @@ public class DepLoader implements IFMLLoadingPlugin, IFMLCallHook {
}
public static class Dependency {
public String url;
public VersionedFile file;
@@ -261,313 +146,13 @@ public class DepLoader implements IFMLLoadingPlugin, IFMLCallHook {
}
public static class DepLoadInst {
private File modsDir;
private File v_modsDir;
private IDownloadDisplay downloadMonitor;
private JDialog popupWindow;
private Map<String, Dependency> depMap = new HashMap<String, Dependency>();
private HashSet<String> depSet = new HashSet<String>();
public DepLoadInst() {}
public DepLoadInst() {
String mcVer = (String) FMLInjectionData.data()[4];
File mcDir = (File) FMLInjectionData.data()[6];
modsDir = new File(mcDir, "mods");
v_modsDir = new File(mcDir, "mods/" + mcVer);
if (!v_modsDir.exists()) v_modsDir.mkdirs();
}
private void addClasspath(String name) {
try {
((LaunchClassLoader) DepLoader.class.getClassLoader())
.addURL(new File(v_modsDir, name).toURI().toURL());
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
private void deleteMod(File mod) {
if (mod.delete()) return;
try {
ClassLoader cl = DepLoader.class.getClassLoader();
URL url = mod.toURI().toURL();
Field f_ucp = URLClassLoader.class.getDeclaredField("ucp");
Field f_loaders = URLClassPath.class.getDeclaredField("loaders");
Field f_lmap = URLClassPath.class.getDeclaredField("lmap");
f_ucp.setAccessible(true);
f_loaders.setAccessible(true);
f_lmap.setAccessible(true);
URLClassPath ucp = (URLClassPath) f_ucp.get(cl);
Closeable loader = ((Map<String, Closeable>) f_lmap.get(ucp)).remove(URLUtil.urlNoFragString(url));
if (loader != null) {
loader.close();
((List<?>) f_loaders.get(ucp)).remove(loader);
}
} catch (Exception e) {
e.printStackTrace();
}
if (!mod.delete()) {
mod.deleteOnExit();
String msg = owner + " was unable to delete file " + mod.getPath()
+ " the game will now try to delete it on exit. If this dialog appears again, delete it manually.";
CodeChickenCorePlugin.logger.error(msg);
if (!GraphicsEnvironment.isHeadless())
JOptionPane.showMessageDialog(null, msg, "An update error has occurred", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
}
private void download(Dependency dep) {
popupWindow = (JDialog) downloadMonitor.makeDialog();
File libFile = new File(v_modsDir, dep.file.filename);
try {
URL libDownload = new URL(dep.url + '/' + dep.file.filename);
downloadMonitor.updateProgressString("Downloading file %s", libDownload.toString());
CodeChickenCorePlugin.logger.debug("Downloading file " + libDownload);
URLConnection connection = libDownload.openConnection();
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.setRequestProperty("User-Agent", "" + owner + " Downloader");
int sizeGuess = connection.getContentLength();
download(connection.getInputStream(), sizeGuess, libFile);
downloadMonitor.updateProgressString("Download complete");
CodeChickenCorePlugin.logger.trace("Download complete");
scanDepInfo(libFile);
} catch (Exception e) {
libFile.delete();
if (downloadMonitor.shouldStopIt()) {
CodeChickenCorePlugin.logger.error(
"You have stopped the downloading operation before it could complete");
System.exit(1);
return;
}
downloadMonitor.showErrorDialog(dep.file.filename, dep.url + '/' + dep.file.filename);
throw new RuntimeException("A download error occured", e);
}
}
private void download(InputStream is, int sizeGuess, File target) throws Exception {
if (sizeGuess > downloadBuffer.capacity())
throw new Exception(String.format(
"The file %s is too large to be downloaded by " + owner + " - the download is invalid",
target.getName()));
downloadBuffer.clear();
int bytesRead, fullLength = 0;
downloadMonitor.resetProgress(sizeGuess);
try {
downloadMonitor.setPokeThread(Thread.currentThread());
byte[] smallBuffer = new byte[1024];
while ((bytesRead = is.read(smallBuffer)) >= 0) {
downloadBuffer.put(smallBuffer, 0, bytesRead);
fullLength += bytesRead;
if (downloadMonitor.shouldStopIt()) {
break;
}
downloadMonitor.updateProgress(fullLength);
}
is.close();
downloadMonitor.setPokeThread(null);
downloadBuffer.limit(fullLength);
downloadBuffer.position(0);
} catch (InterruptedIOException e) {
// We were interrupted by the stop button. We're stopping now.. clear interruption flag.
Thread.interrupted();
throw new Exception("Stop");
} catch (IOException e) {
throw e;
}
try {
/*String cksum = generateChecksum(downloadBuffer);
if (cksum.equals(validationHash))
{*/
if (!target.exists()) target.createNewFile();
downloadBuffer.position(0);
FileOutputStream fos = new FileOutputStream(target);
fos.getChannel().write(downloadBuffer);
fos.close();
/*}
else
{
throw new RuntimeException(String.format("The downloaded file %s has an invalid checksum %s (expecting %s). The download did not succeed correctly and the file has been deleted. Please try launching again.", target.getName(), cksum, validationHash));
}*/
} catch (Exception e) {
throw e;
}
}
private String checkExisting(Dependency dep) {
for (File f : modsDir.listFiles()) {
VersionedFile vfile = new VersionedFile(f.getName(), dep.file.pattern);
if (!vfile.matches() || !vfile.name.equals(dep.file.name)) continue;
if (f.renameTo(new File(v_modsDir, f.getName()))) continue;
deleteMod(f);
}
for (File f : v_modsDir.listFiles()) {
VersionedFile vfile = new VersionedFile(f.getName(), dep.file.pattern);
if (!vfile.matches() || !vfile.name.equals(dep.file.name)) continue;
int cmp = vfile.version.compareTo(dep.file.version);
if (cmp < 0) {
CodeChickenCorePlugin.logger.warn("Deleted old version " + f.getName());
deleteMod(f);
return null;
}
if (cmp > 0) {
CodeChickenCorePlugin.logger.warn("Warning: version of " + dep.file.name + ", " + vfile.version
+ " is newer than request " + dep.file.version);
return f.getName();
}
return f.getName(); // found dependency
}
return null;
}
public void load() {
scanDepInfos();
if (depMap.isEmpty()) return;
loadDeps();
activateDeps();
}
private void activateDeps() {
for (Dependency dep : depMap.values()) if (dep.coreLib) addClasspath(dep.existing);
}
private void loadDeps() {
downloadMonitor = FMLLaunchHandler.side().isClient() ? new Downloader() : new DummyDownloader();
try {
while (!depSet.isEmpty()) {
Iterator<String> it = depSet.iterator();
Dependency dep = depMap.get(it.next());
it.remove();
load(dep);
}
} finally {
if (popupWindow != null) {
popupWindow.setVisible(false);
popupWindow.dispose();
}
}
}
private void load(Dependency dep) {
dep.existing = checkExisting(dep);
if (dep.existing == null) // download dep
{
download(dep);
dep.existing = dep.file.filename;
}
}
private List<File> modFiles() {
List<File> list = new LinkedList<File>();
list.addAll(Arrays.asList(modsDir.listFiles()));
list.addAll(Arrays.asList(v_modsDir.listFiles()));
return list;
}
private void scanDepInfos() {
for (File file : modFiles()) {
if (!file.getName().endsWith(".jar") && !file.getName().endsWith(".zip")) continue;
scanDepInfo(file);
}
}
private void scanDepInfo(File file) {
try {
ZipFile zip = new ZipFile(file);
ZipEntry e = zip.getEntry("dependancies.info");
if (e == null) e = zip.getEntry("dependencies.info");
if (e != null) loadJSon(zip.getInputStream(e));
zip.close();
} catch (Exception e) {
CodeChickenCorePlugin.logger.error(
"Failed to load dependencies.info from " + file.getName() + " as JSON");
e.printStackTrace();
}
}
private void loadJSon(InputStream input) throws IOException {
InputStreamReader reader = new InputStreamReader(input);
JsonElement root = new JsonParser().parse(reader);
if (root.isJsonArray()) loadJSonArr(root);
else loadJson(root.getAsJsonObject());
reader.close();
}
private void loadJSonArr(JsonElement root) throws IOException {
for (JsonElement node : root.getAsJsonArray()) loadJson(node.getAsJsonObject());
}
private void loadJson(JsonObject node) throws IOException {
boolean obfuscated =
((LaunchClassLoader) DepLoader.class.getClassLoader()).getClassBytes("net.minecraft.world.World")
== null;
String testClass = node.get("class").getAsString();
if (DepLoader.class.getResource("/" + testClass.replace('.', '/') + ".class") != null) return;
String repo = node.get("repo").getAsString();
String filename = node.get("file").getAsString();
if (!obfuscated && node.has("dev")) filename = node.get("dev").getAsString();
boolean coreLib = node.has("coreLib") && node.get("coreLib").getAsBoolean();
Pattern pattern = null;
try {
if (node.has("pattern"))
pattern = Pattern.compile(node.get("pattern").getAsString());
} catch (PatternSyntaxException e) {
CodeChickenCorePlugin.logger.error("Invalid filename pattern: " + node.get("pattern"));
e.printStackTrace();
}
if (pattern == null) pattern = Pattern.compile("(\\w+).*?([\\d\\.]+)[-\\w]*\\.[^\\d]+");
VersionedFile file = new VersionedFile(filename, pattern);
if (!file.matches()) throw new RuntimeException("Invalid filename format for dependency: " + filename);
addDep(new Dependency(repo, file, coreLib));
}
private void addDep(Dependency newDep) {
if (mergeNew(depMap.get(newDep.file.name), newDep)) {
depMap.put(newDep.file.name, newDep);
depSet.add(newDep.file.name);
}
}
private boolean mergeNew(Dependency oldDep, Dependency newDep) {
if (oldDep == null) return true;
Dependency newest = newDep.file.version.compareTo(oldDep.file.version) > 0 ? newDep : oldDep;
newest.coreLib = newDep.coreLib || oldDep.coreLib;
return newest == newDep;
}
public void load() {}
}
public static void load() {
if (inst == null) {
inst = new DepLoadInst();
inst.load();
}
}
public static void load() {}
@Override
public String[] getASMTransformerClass() {
@@ -1,10 +1,11 @@
package codechicken.obfuscator;
import static org.objectweb.asm.tree.AbstractInsnNode.*;
import static org.objectweb.asm.tree.AbstractInsnNode.LDC_INSN;
import static org.objectweb.asm.tree.AbstractInsnNode.METHOD_INSN;
import codechicken.lib.asm.ObfMapping;
import java.util.LinkedList;
import java.util.List;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
@@ -12,7 +13,10 @@ import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import codechicken.lib.asm.ObfMapping;
public class ConstantObfuscator implements Opcodes {
public ObfRemapper obf;
public List<ObfMapping> descCalls = new LinkedList<ObfMapping>();
public List<ObfMapping> classCalls = new LinkedList<ObfMapping>();
@@ -3,6 +3,7 @@ package codechicken.obfuscator;
import java.io.OutputStream;
public class DummyOutputStream extends OutputStream {
public static DummyOutputStream instance = new DummyOutputStream();
@Override
@@ -1,9 +1,11 @@
package codechicken.obfuscator;
import codechicken.obfuscator.ObfuscationMap.ObfuscationEntry;
import java.util.List;
import codechicken.obfuscator.ObfuscationMap.ObfuscationEntry;
public interface IHeirachyEvaluator {
/**
* @param desc The mapping descriptor of the class to evaluate heirachy for
* @return A list of parents (srg or obf names)
@@ -3,6 +3,7 @@ package codechicken.obfuscator;
import java.io.PrintStream;
public interface ILogStreams {
public PrintStream err();
public PrintStream out();
@@ -4,6 +4,7 @@ import codechicken.lib.asm.ObfMapping;
import codechicken.obfuscator.ObfuscationMap.ObfuscationEntry;
public class ObfDirection {
public boolean obfuscate;
public boolean srg;
public boolean srg_cst;
@@ -1,9 +1,11 @@
package codechicken.obfuscator;
import codechicken.obfuscator.ObfuscationMap.ObfuscationEntry;
import org.objectweb.asm.commons.Remapper;
import codechicken.obfuscator.ObfuscationMap.ObfuscationEntry;
public class ObfRemapper extends Remapper {
public final ObfuscationMap obf;
public ObfDirection dir;
@@ -1,8 +1,5 @@
package codechicken.obfuscator;
import codechicken.lib.asm.ObfMapping;
import com.google.common.base.Function;
import com.google.common.collect.ArrayListMultimap;
import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
@@ -10,8 +7,15 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.google.common.base.Function;
import com.google.common.collect.ArrayListMultimap;
import codechicken.lib.asm.ObfMapping;
public class ObfuscationMap {
public class ObfuscationEntry {
public final ObfMapping obf;
public final ObfMapping srg;
public final ObfMapping mcp;
@@ -24,6 +28,7 @@ public class ObfuscationMap {
}
private class ClassEntry extends ObfuscationEntry {
public Map<String, ObfuscationEntry> mcpMap = new HashMap<String, ObfuscationEntry>();
public Map<String, ObfuscationEntry> srgMap = new HashMap<String, ObfuscationEntry>();
public Map<String, ObfuscationEntry> obfMap = new HashMap<String, ObfuscationEntry>();
@@ -81,8 +86,8 @@ public class ObfuscationMap {
return addEntry(new ObfMapping(obf_owner, obf_name, ""), new ObfMapping(srg_owner, srg_name, ""));
}
public ObfuscationEntry addMethod(
String obf_owner, String obf_name, String obf_desc, String srg_owner, String srg_name, String srg_desc) {
public ObfuscationEntry addMethod(String obf_owner, String obf_name, String obf_desc, String srg_owner,
String srg_name, String srg_desc) {
return addEntry(new ObfMapping(obf_owner, obf_name, obf_desc), new ObfMapping(srg_owner, srg_name, srg_desc));
}
@@ -161,10 +166,8 @@ public class ObfuscationMap {
private ObfuscationEntry getOrCreateClassEntry(String name) {
ObfuscationEntry e = lookupObfClass(name);
if (e == null) e = lookupMcpClass(name);
if (e == null)
e = addClass(
name,
name); // if the class isn't in obf or srg maps, it must be a custom mod class with no name change.
if (e == null) e = addClass(name, name); // if the class isn't in obf or srg maps, it must be a custom mod class
// with no name change.
return e;
}
@@ -207,7 +210,7 @@ public class ObfuscationMap {
public static String[] splitLast(String s, char c) {
int i = s.lastIndexOf(c);
return new String[] {s.substring(0, i), s.substring(i + 1)};
return new String[] { s.substring(0, i), s.substring(i + 1) };
}
public static String[] split4(String s, char c) {
@@ -230,6 +233,7 @@ public class ObfuscationMap {
log.out().println("Parsing " + srgs.getName());
Function<String, Void> function = new Function<String, Void>() {
@Override
public Void apply(String line) {
int hpos = line.indexOf('#');
@@ -261,6 +265,7 @@ public class ObfuscationMap {
log.out().println("Parsing " + csv.getName());
Function<String, Void> function = new Function<String, Void>() {
@Override
public Void apply(String line) {
if (line.startsWith("func_") || line.startsWith("field_")) {
@@ -1,6 +1,5 @@
package codechicken.obfuscator;
import com.google.common.base.Function;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
@@ -9,11 +8,15 @@ import java.text.DecimalFormat;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.commons.RemappingClassAdapter;
import org.objectweb.asm.tree.ClassNode;
import com.google.common.base.Function;
public class ObfuscationRun implements ILogStreams {
public final ObfDirection obfDir;
public final ObfuscationMap obf;
public final ObfRemapper obfMapper;
@@ -98,27 +101,24 @@ public class ObfuscationRun implements ILogStreams {
}
public static Map<String, String> fillDefaults(Map<String, String> config) {
if (!config.containsKey("excludedPackages"))
config.put(
"excludedPackages",
"java/;sun/;javax/;scala/;" + "argo/;org/lwjgl/;org/objectweb/;org/bouncycastle/;com/google/");
if (!config.containsKey("excludedPackages")) config.put(
"excludedPackages",
"java/;sun/;javax/;scala/;" + "argo/;org/lwjgl/;org/objectweb/;org/bouncycastle/;com/google/");
if (!config.containsKey("ignore")) config.put("ignore", ".");
if (!config.containsKey("classConstantCalls"))
config.put(
"classConstantCalls",
"codechicken/lib/asm/ObfMapping.<init>(Ljava/lang/String;)V,"
+ "codechicken/lib/asm/ObfMapping.subclass(Ljava/lang/String;)Lcodechicken/lib/asm/ObfMapping;,"
+ "codechicken/lib/asm/ObfMapping.<init>(Lcodechicken/lib/asm/ObfMapping;Ljava/lang/String;)V");
if (!config.containsKey("descConstantCalls"))
config.put(
"descConstantCalls",
"codechicken/lib/asm/ObfMapping.<init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V,"
+ "org/objectweb/asm/MethodVisitor.visitFieldInsn(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V,"
+ "org/objectweb/asm/tree/MethodNode.visitFieldInsn(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V,"
+ "org/objectweb/asm/MethodVisitor.visitMethodInsn(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V,"
+ "org/objectweb/asm/tree/MethodNode.visitMethodInsn(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V,"
+ "org/objectweb/asm/tree/MethodInsnNode.<init>(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V,"
+ "org/objectweb/asm/tree/FieldInsnNode.<init>(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
if (!config.containsKey("classConstantCalls")) config.put(
"classConstantCalls",
"codechicken/lib/asm/ObfMapping.<init>(Ljava/lang/String;)V,"
+ "codechicken/lib/asm/ObfMapping.subclass(Ljava/lang/String;)Lcodechicken/lib/asm/ObfMapping;,"
+ "codechicken/lib/asm/ObfMapping.<init>(Lcodechicken/lib/asm/ObfMapping;Ljava/lang/String;)V");
if (!config.containsKey("descConstantCalls")) config.put(
"descConstantCalls",
"codechicken/lib/asm/ObfMapping.<init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V,"
+ "org/objectweb/asm/MethodVisitor.visitFieldInsn(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V,"
+ "org/objectweb/asm/tree/MethodNode.visitFieldInsn(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V,"
+ "org/objectweb/asm/MethodVisitor.visitMethodInsn(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V,"
+ "org/objectweb/asm/tree/MethodNode.visitMethodInsn(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V,"
+ "org/objectweb/asm/tree/MethodInsnNode.<init>(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V,"
+ "org/objectweb/asm/tree/FieldInsnNode.<init>(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
return config;
}
@@ -135,9 +135,8 @@ public class ObfuscationRun implements ILogStreams {
}
public static void processFiles(File dir, Function<File, Void> function, boolean recursive) {
for (File file : dir.listFiles())
if (file.isDirectory() && recursive) processFiles(file, function, recursive);
else function.apply(file);
for (File file : dir.listFiles()) if (file.isDirectory() && recursive) processFiles(file, function, recursive);
else function.apply(file);
}
public static void deleteDir(File directory, boolean remove) {
@@ -173,7 +172,7 @@ public class ObfuscationRun implements ILogStreams {
File fields = new File(mapDir, "fields.csv");
if (!fields.exists()) throw new RuntimeException("Could not find fields.csv");
return new File[] {srgs, methods, fields};
return new File[] { srgs, methods, fields };
}
public long startTime() {
@@ -196,8 +195,8 @@ public class ObfuscationRun implements ILogStreams {
public void finish(boolean errored) {
long millis = System.currentTimeMillis() - startTime;
out().println((errored ? "Errored after" : "Done in ") + new DecimalFormat("0.00").format(millis / 1000D)
+ "s");
out().println(
(errored ? "Errored after" : "Done in ") + new DecimalFormat("0.00").format(millis / 1000D) + "s");
finished = true;
}
@@ -3,6 +3,7 @@ package codechicken.obfuscator;
import java.io.PrintStream;
public class SystemLogStreams implements ILogStreams {
public static SystemLogStreams inst = new SystemLogStreams();
@Override
+1 -1
View File
@@ -7,6 +7,6 @@
"version": "${modVersion}",
"mcversion": "${minecraftVersion}",
"url": "http://www.minecraftforum.net/topic/909223",
"authorList": ["ChickenBones"]
"authorList": ["ChickenBones", "GTNH Team"]
}]
}