Merge pull request #40 from GTNewHorizons/unified-build-script

Unified build script
This commit is contained in:
Martin Robertz 2021-12-20 09:59:52 +01:00 committed by GitHub
commit 2618389715
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 880 additions and 1371 deletions

View File

@ -0,0 +1,27 @@
if [[ -d "run/crash-reports" ]]; then
echo "Crash reports detected:"
cat $directory/*
exit 1
fi
if grep --quiet "Fatal errors were detected" server.log; then
echo "Fatal errors detected:"
cat server.log
exit 1
fi
if grep --quiet "The state engine was in incorrect state ERRORED and forced into state SERVER_STOPPED" server.log; then
echo "Server force stopped:"
cat server.log
exit 1
fi
if grep --quiet 'Done .+ For help, type "help" or "?"' server.log; then
echo "Server didn't finish startup:"
cat server.log
exit 1
fi
echo "No crash reports detected"
exit 0

45
.github/workflows/build-and-test.yml vendored Normal file
View File

@ -0,0 +1,45 @@
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
name: Build and test
on:
pull_request:
branches: [ master, main ]
push:
branches: [ master, main ]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set up JDK 8
uses: actions/setup-java@v2
with:
java-version: '8'
distribution: 'adopt'
cache: gradle
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Setup the workspace
run: ./gradlew setupCIWorkspace
- name: Build the mod
run: ./gradlew build
- name: Run server for 1.5 minutes
run: |
mkdir run
echo "eula=true" > run/eula.txt
timeout 90 ./gradlew runServer | tee --append server.log || true
- name: Test no errors reported during server run
run: |
chmod +x .github/scripts/test-no-error-reports.sh
.github/scripts/test-no-error-reports.sh

61
.github/workflows/release-tags.yml vendored Normal file
View File

@ -0,0 +1,61 @@
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
name: Release tagged build
on:
push:
tags:
- '*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set release version
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- name: Set up JDK 8
uses: actions/setup-java@v2
with:
java-version: '8'
distribution: 'adopt'
cache: gradle
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Setup the workspace
run: ./gradlew setupCIWorkspace
- name: Build the mod
run: ./gradlew build
- name: Release under current tag
uses: "marvinpinto/action-automatic-releases@latest"
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: "${{ env.RELEASE_VERSION }}"
prerelease: false
title: "${{ env.RELEASE_VERSION }}"
files: build/libs/*.jar
- name: Set repository owner and name
run: |
echo "REPOSITORY_OWNER=${GITHUB_REPOSITORY%/*}" >> $GITHUB_ENV
echo "REPOSITORY_NAME=${GITHUB_REPOSITORY#*/}" >> $GITHUB_ENV
- name: Publish package
run: ./gradlew publish
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ARTIFACT_GROUP_ID: com.github.${{ env.REPOSITORY_OWNER }}
ARTIFACT_ID: "${{ env.REPOSITORY_NAME }}"
ARTIFACT_VERSION: "${{ env.RELEASE_VERSION }}"
REPOSITORY_NAME: "${{ env.REPOSITORY_NAME }}"
REPOSITORY_OWNER: "${{ env.REPOSITORY_OWNER }}"

62
.gitignore vendored
View File

@ -1,33 +1,31 @@
# Gradle
/.gradle
/build
# Eclipse
/.classpath
/.project
/.settings
/bin
# IntelliJ IDEA
/*.iml
/*.ipr
/*.iws
/.idea
/out
# Debugging
/eclipse
/run
# OS X
.DS_Store
# VSCode
/.vscode
.gradle
.settings
/.idea/
/run/
/build/
/eclipse/
.classpath
.project
/bin/
/config/
/crash-reports/
/logs/
options.txt
/saves/
usernamecache.json
banned-ips.json
banned-players.json
eula.txt
ops.json
server.properties
servers.dat
usercache.json
whitelist.json
/out/
*.iml
*.ipr
*.iws
src/main/resources/mixins.*.json
*.bat
/saves
/logs
/config
/options.txt
/usernamecache.json
/classes
*.DS_Store
!gradlew.bat

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "src/api/java/thaumcraft/api"]
path = src/api/java/thaumcraft/api
url = https://github.com/Azanor/thaumcraft-api.git

View File

@ -1,17 +0,0 @@
sudo: false
language: scala
scala: 2.11.1
jdk: oraclejdk8
dist: trusty
notifications:
email: false
env:
global: TERM=dumb
install: ./gradlew setupCIWorkspace
script: ./gradlew build
cache:
directories:
- $HOME/.gradle/caches

3
addon.gradle Normal file
View File

@ -0,0 +1,3 @@
minecraft {
replace "@VERSION@", versionDetails().lastTag
}

View File

@ -1,14 +1,31 @@
//version: 29197fa3cf1ea6ef5c07884a613171d01c026d1d
/*
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/SinTh0r4s/ExampleMod1.7.10/blob/main/build.gradle for updates.
*/
import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import java.util.concurrent.TimeUnit
buildscript {
repositories {
mavenCentral()
maven {
name = "gt"
url = "https://gregtech.overminddl1.com/"
name = "forge"
url = "https://maven.minecraftforge.net"
}
maven {
name = "sonatype"
url = "https://oss.sonatype.org/content/repositories/snapshots/"
}
maven {
name = "Scala CI dependencies"
url = "https://repo1.maven.org/maven2/"
}
maven {
name = "jitpack"
url = "https://jitpack.io"
@ -25,292 +42,521 @@ plugins {
id("org.ajoberstar.grgit") version("3.1.1")
id("com.github.johnrengelman.shadow") version("4.0.4")
id("com.palantir.git-version") version("0.12.3")
id("maven-publish")
}
apply plugin: 'scala'
apply plugin: 'forge'
apply plugin: 'idea'
tasks.withType(ScalaCompile) {
scalaCompileOptions.additionalParameters = ["-deprecation:false"]
def projectJavaVersion = JavaLanguageVersion.of(8)
java {
toolchain {
languageVersion.set(projectJavaVersion)
}
}
idea {
module {
inheritOutputDirs = true
downloadJavadoc = true
downloadSources = true
}
}
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")
String javaSourceDir = "src/main/java/"
String scalaSourceDir = "src/main/scala/"
String targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/")
String targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/")
if((getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists()) == false) {
throw new GradleException("Could not resolve \"modGroup\"! Could not find " + targetPackageJava + " or " + targetPackageScala)
}
if(apiPackage) {
targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
if((getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists()) == false) {
throw new GradleException("Could not resolve \"apiPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala)
}
}
if(accessTransformersFile) {
String targetFile = "src/main/resources/META-INF/" + accessTransformersFile
if(getFile(targetFile).exists() == false) {
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("\\.", "/")
if((getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists()) == false) {
throw new GradleException("Could not resolve \"mixinsPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala)
}
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"
if((getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists()) == false) {
throw new GradleException("Could not resolve \"mixinPlugin\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava)
}
}
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"
if((getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists()) == false) {
throw new GradleException("Could not resolve \"coreModClass\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava)
}
}
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
'git config core.fileMode false'.execute()
// Pulls version from git tag
try {
version = minecraftVersion + "-" + gitVersion()
}
catch (Exception e) {
throw new IllegalStateException("This mod must be version controlled by Git AND the repository must provide at least one tag!");
}
group = modGroup
if(project.hasProperty("customArchiveBaseName") && customArchiveBaseName) {
archivesBaseName = customArchiveBaseName
}
else {
archivesBaseName = modId
}
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, versionDetails().lastTag
}
if(gradleTokenGroupName) {
replace gradleTokenGroupName, modGroup
}
}
}
if(file("addon.gradle").exists()) {
apply from: "addon.gradle"
}
apply from: 'repositories.gradle'
configurations {
implementation.extendsFrom(shadowImplementation)
}
repositories {
maven {
name = "mightypirates"
url = "https://maven.cil.li/"
metadataSources {
mavenPom()
artifact()
}
}
// These are necessary because some parts of the maven repo is weirdly structured, this needs to be fixed.
ivy {
name 'weird maven repos'
artifactPattern "https://maven.cil.li/[module]/[revision]/[module]-[revision].[ext]"
metadataSources {
ivyDescriptor()
artifact()
}
}
ivy {
name 'weird maven repos 2'
artifactPattern "https://maven.cil.li/[module]/[revision]/[module]-[revision]-[classifier].[ext]"
metadataSources {
ivyDescriptor()
artifact()
}
}
maven {
name "Mobius Repo"
url "http://mobiusstrip.eu/maven"
allowInsecureProtocol true
metadataSources {
mavenPom()
artifact()
}
}
maven {
name = "ic2"
url = "https://maven.ic2.player.to/"
metadataSources {
mavenPom()
artifact()
}
}
maven {
name = "gt"
name = "Overmind forge repo mirror"
url = "https://gregtech.overminddl1.com/"
}
ivy {
name 'gtnh_download_source'
artifactPattern "http://downloads.gtnewhorizons.com/Mods_for_Jenkins/[module]-[revision].[ext]"
allowInsecureProtocol true
if(usesMixins.toBoolean()) {
maven {
name = "sponge"
url = "https://repo.spongepowered.org/repository/maven-public"
}
maven {
url = "https://jitpack.io"
}
}
maven { // GalacticGreg, YAMCore,..
name 'UsrvDE'
url "http://jenkins.usrv.eu:8081/nexus/content/repositories/releases/"
allowInsecureProtocol true
}
maven {
url "http://downloads.gtnewhorizons.com/Mods_for_Jenkins/"
allowInsecureProtocol true
}
maven {
name = "jitpack"
url = "https://jitpack.io"
}
maven {
name = "curse.maven"
url = "https://cursemaven.com"
}
}
group = "li.cil.oc"
archivesBaseName = "OpenComputers"
// Define properties file
ext.configFile = file "build.properties"
configFile.withReader {
// Load config. It shall from now be referenced as simply config or project.config
def prop = new Properties()
prop.load(it)
project.ext.config = new ConfigSlurper().parse prop
}
configurations {
embedded
implementation.extendsFrom embedded
}
dependencies {
compileOnly "com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:master-SNAPSHOT:dev"
compileOnly "com.github.GTNewHorizons:NotEnoughItems:master-SNAPSHOT:dev"
compileOnly "com.github.GTNewHorizons:EnderStorage:master-SNAPSHOT:dev"
compileOnly "com.github.GTNewHorizons:waila:master-SNAPSHOT:dev"
compileOnly "com.github.GTNewHorizons:ForgeMultipart:master-SNAPSHOT:dev"
compileOnly "com.github.GTNewHorizons:GT5-Unofficial:master-SNAPSHOT:dev"
compileOnly "com.github.GTNewHorizons:ForestryMC:master-SNAPSHOT:dev"
compileOnly "com.github.GTNewHorizons:Railcraft:master-SNAPSHOT:dev"
compileOnly "com.github.GTNewHorizons:ThaumicEnergistics:master-SNAPSHOT:dev"
compileOnly "com.github.GTNewHorizons:ExtraCells2:master-SNAPSHOT:dev"
compileOnly "com.github.GTNewHorizons:EnderIO:master-SNAPSHOT:dev"
compileOnly ("com.github.GTNewHorizons:Galacticraft:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly ("appeng:RotaryCraft:${project.config.rotc_version}:api") {
transitive = false
}
compileOnly "com.mod-buildcraft:buildcraft:7.1.23:dev"
compileOnly "thaumcraft:Thaumcraft:1.7.10-4.2.3.5:dev"
compileOnly "curse.maven:mekanism-268560:2475797" //mekanism - not needed in GTNH, won't build without
compileOnly "codechicken:WR-CBE:${project.config.minecraft_version}-${project.config.wrcbe_version}:dev"
compileOnly "com.bluepowermod:BluePower:${project.config.bluepower.version}:deobf"
compileOnly "igwmod:IGW-Mod-1.7.10:${project.config.igwmod.version}:userdev"
compileOnly "li.cil.tis3d:TIS-3D:${project.config.tis3d.version}:dev"
compileOnly "net.industrial-craft:industrialcraft-2:${project.config.ic2.version}:dev"
compileOnly "dev.modwarriors.notenoughkeys:NotEnoughKeys:${project.config.minecraft_version}-${project.config.nek.version}:deobf-dev"
compileOnly "qmunity:QmunityLib:${project.config.qmunitylib.version}:deobf"
compileOnly "tmech:TMechworks:${project.config.minecraft_version}-${project.config.tmech.version}:deobf"
compileOnly ("mrtjp:ProjectRed:${project.config.projred.version}:dev") {
exclude module: 'CoFHCore'
}
compileOnly name: 'redlogic', version: project.config.redlogic.version, ext: 'jar'
compileOnly name: 'MineFactoryReloaded', version: project.config.mfr.version, ext: 'jar'
compileOnly name: 'ComputerCraft', version: project.config.cc.version, ext: 'jar'
compileOnly name: 'BloodMagic', version: project.config.bloodmagic.version, ext: 'jar'
compileOnly name: 'CoFHLib', version: config.cofhlib.version, ext: 'jar'
implementation 'com.google.code.findbugs:jsr305:3.0.2' // Annotations used by google libs.
embedded files('libs/OpenComputers-JNLua.jar', 'libs/OpenComputers-LuaJ.jar')
testCompile "org.mockito:mockito-all:1.10.19"
testCompile "org.scalactic:scalactic_2.11:2.2.6"
testCompile "org.scalatest:scalatest_2.11:2.2.6"
}
version = "${project.config.mod_version}" ?: "1"
println config.minecraft_version + "-" + config.forge_version
def getGitRef() {
try {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-parse', '--short', 'HEAD'
standardOutput = stdout
}
return stdout.toString().trim()
} catch (Throwable e) {
return "unknown"
}
}
if (System.getenv("PROMOTED_NUMBER") != null)
version += ".${System.getenv("PROMOTED_NUMBER")}"
else if (System.getenv("BUILD_NUMBER") != null)
version += ".${System.getenv("BUILD_NUMBER")}"
else
version += "+" + getGitRef()
ext.simpleVersion = version
version = "MC${config.minecraft_version}-${project.version}"
def root = project.projectDir.parentFile
runClient {
jvmArgs '-Dfml.coreMods.load=li.cil.oc.common.launch.TransformerLoader'
}
runServer {
jvmArgs '-Dfml.coreMods.load=li.cil.oc.common.launch.TransformerLoader'
}
if (JavaVersion.current().isJava8Compatible()) {
allprojects {
tasks.withType(Javadoc) {
options.addStringOption('Xdoclint:none', '-quiet')
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")
// using 0.8 to workaround a issue in 0.7 which fails mixin application
compile("org.spongepowered:mixin:0.7.11-SNAPSHOT") {
// 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.3.3:dev")
}
}
configurations {
embedded
implementation.extendsFrom embedded
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()) {
getFile("/src/main/resources/mixins." + modId + ".json").text = """{
"required": true,
"minVersion": "0.7.11",
"package": "${modGroup}.${mixinsPackage}",
"plugin": "${modGroup}.${mixinPlugin}",
"refmap": "${mixingConfigRefMap}",
"target": "@env(DEFAULT)",
"compatibilityLevel": "JAVA_8"
}
minecraft {
version = config.minecraft_version + "-" + config.forge_version + "-" + config.minecraft_version
replace "@VERSION@", project.simpleVersion
//replace "/*@MCVERSIONDEP@*/", ", acceptedMinecraftVersions = \"[${config.minecraft.version},${config.minecraft.version}+)\""
"""
}
}
processResources {
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
expand 'version': project.simpleVersion, 'mcversion': config.minecraft.version
}
from(sourceSets.main.resources.srcDirs) {
include 'application.conf'
filter { line ->
line.replaceAll("@VERSION@", project.simpleVersion)
}
}
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
exclude 'application.conf'
}
// Move access transformer to META-INF
rename '(.+_at.cfg)', 'META-INF/$1'
task relocateShadowJar(type: ConfigureShadowRelocation) {
target = tasks.shadowJar
prefix = modGroup + ".shadow"
}
def commonManifest = {
attributes FMLCorePlugin: "li.cil.oc.common.launch.TransformerLoader"
attributes FMLCorePluginContainsFMLMod: "true"
attributes FMLAT: "oc_at.cfg"
shadowJar {
manifest {
attributes(getManifestAttributes())
}
minimize() // This will only allow shading for actually used classes
configurations = [project.configurations.shadowImplementation]
dependsOn(relocateShadowJar)
}
jar {
exclude "cofh/**"
exclude "mods/**"
configurations.embedded.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"
]
}
}
classifier = 'universal'
manifest commonManifest
}
javadoc {
include 'li/cil/oc/api/**'
}
runClient {
def arguments = []
// because the normal default jar task has been modified to be obfuscated
task deobfJar(type: Jar) {
from sourceSets.main.output
exclude "cofh/**"
exclude "mods/**"
configurations.embedded.each { dep ->
from(project.zipTree(dep)) {
exclude 'META-INF', 'META-INF/**'
}
if(usesMixins.toBoolean()) {
arguments += [
"--mods=../build/libs/$modId-${version}.jar",
"--tweakClass org.spongepowered.asm.launch.MixinTweaker"
]
}
classifier = 'dev'
manifest commonManifest
if(developmentEnvironmentUserName) {
arguments += [
"--username",
developmentEnvironmentUserName
]
}
args(arguments)
}
task apiJar(type: Jar) {
from sourceSets.main.output
from sourceSets.main.java
classifier = 'api'
include 'li/cil/oc/api/**'
runServer {
def arguments = []
if (usesMixins.toBoolean()) {
arguments += [
"--mods=../build/libs/$modId-${version}.jar",
"--tweakClass org.spongepowered.asm.launch.MixinTweaker"
]
}
args(arguments)
}
task javadocJar(type: Jar, dependsOn: javadoc) {
from 'build/docs/javadoc'
classifier 'javadoc'
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
// replace stuff in mcmod.info, nothing else
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
// replace version and mcversion
expand "minecraftVersion": project.minecraft.version,
"modVersion": versionDetails().lastTag,
"modId": modId,
"modName": modName
}
if(usesMixins.toBoolean()) {
from refMap
}
// copy everything else, thats not the mcmod.info
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
}
}
def getManifestAttributes() {
def manifestAttributes = [:]
if(containsMixinsAndOrCoreModOnly.toBoolean() == false && (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() == false
]
}
return manifestAttributes
}
task sourcesJar(type: Jar) {
from sourceSets.main.java
from sourceSets.main.scala
classifier = 'sources'
from (sourceSets.main.allJava)
from (file("$projectDir/LICENSE"))
getArchiveClassifier().set('sources')
}
task shadowDevJar(type: ShadowJar) {
from sourceSets.main.output
getArchiveClassifier().set("dev")
manifest {
attributes(getManifestAttributes())
}
minimize() // This will only allow shading for actually used classes
configurations = [project.configurations.shadowImplementation]
}
task relocateShadowDevJar(type: ConfigureShadowRelocation) {
target = tasks.shadowDevJar
prefix = modGroup + ".shadow"
}
task circularResolverJar(type: Jar) {
dependsOn(relocateShadowDevJar)
dependsOn(shadowDevJar)
enabled = false
}
task devJar(type: Jar) {
from sourceSets.main.output
getArchiveClassifier().set("dev")
manifest {
attributes(getManifestAttributes())
}
if(usesShadowedDependencies.toBoolean()) {
dependsOn(circularResolverJar)
enabled = false
}
}
task apiJar(type: Jar) {
from (sourceSets.main.allJava) {
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 {
archives deobfJar
archives apiJar
archives javadocJar
archives sourcesJar
}
// this is needed for IntelliJ so we don't have to copy over the assets manually every time
idea {
module {
outputDir = file('build/classes/main')
archives devJar
if(apiPackage) {
archives apiJar
}
}
// publishing
publishing {
publications {
maven(MavenPublication) {
artifact source: jar
artifact source: sourcesJar, classifier: "src"
artifact source: devJar, classifier: "dev"
if (apiPackage) {
artifact source: apiJar, classifier: "api"
}
groupId = System.getenv("ARTIFACT_GROUP_ID") ?: group
artifactId = System.getenv("ARTIFACT_ID") ?: project.name
version = System.getenv("ARTIFACT_VERSION") ?: project.version
}
}
repositories {
maven {
String owner = System.getenv("REPOSITORY_OWNER") ?: "Unknown"
String repositoryName = System.getenv("REPOSITORY_NAME") ?: "Unknown"
String githubRepositoryUrl = "https://maven.pkg.github.com/$owner/$repositoryName"
name = "GitHubPackages"
url = githubRepositoryUrl
credentials {
username = System.getenv("GITHUB_ACTOR") ?: "NONE"
password = System.getenv("GITHUB_TOKEN") ?: "NONE"
}
}
}
}
// Updating
task updateBuildScript {
doLast {
if (performBuildScriptUpdate(projectDir.toString())) return
print("Build script already up-to-date!")
}
}
if (isNewBuildScriptVersionAvailable(projectDir.toString())) {
if (autoUpdateBuildScript.toBoolean()) {
performBuildScriptUpdate(projectDir.toString())
} else {
println("Build script update available! Run 'gradle updateBuildScript'")
}
}
static URL availableBuildScriptUrl() {
new URL("https://raw.githubusercontent.com/SinTh0r4s/ExampleMod1.7.10/main/build.gradle")
}
boolean performBuildScriptUpdate(String projectDir) {
if (isNewBuildScriptVersionAvailable(projectDir)) {
def buildscriptFile = getFile("build.gradle")
availableBuildScriptUrl().withInputStream { i -> buildscriptFile.withOutputStream { it << i } }
print("Build script updated. Please REIMPORT the project or RESTART your IDE!")
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'
}
// Helper methods
def checkPropertyExists(String propertyName) {
if (project.hasProperty(propertyName) == false) {
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/SinTh0r4s/ExampleMod1.7.10/blob/main/gradle.properties")
}
}
def getFile(String relativePath) {
return new File(projectDir, relativePath)
}

View File

@ -1,43 +0,0 @@
minecraft_version=1.7.10
forge_version=10.13.4.1614
mod_version=1.7.5.16-GTNH
rotc_version=V5c
wrcbe_version=1.4.1.2
ae2.version=rv3-beta-31
bc.version=7.0.9
bloodmagic.cf=2223/203
bloodmagic.version=1.3.0a-1
bluepower.version=0.2.928
cc.cf=2228/723
cc.version=1.73
ccl.version=1.1.3.140
cofhlib.cf=2230/207
cofhlib.version=[1.7.10]1.0.0RC7-127
coloredlights.version=1.3.7.35
coloredlights.build=35
ec.cf=2242/839
ec.version=deobf-1.7.10-2.2.73b129
eio.cf=2219/296
eio.version=1.7.10-2.3.0.429_beta
es.version=1.4.5.24
fmp.version=1.1.0.308
forestry.version=4.4.0.0
gc.build=3
gc.version=3.0.7
ic2.version=2.2.828-experimental
igwmod.version=1.1.3-18
mekanism.build=5
mekanism.version=7.1.2
mfr.cf=2229/626
mfr.version=[1.7.10]2.8.0RC8-86
nek.version=2.0.0b4
projred.version=1.7.10-4.6.2.82
qmunitylib.version=0.1.105
rc.cf=2219/321
rc.version=1.7.10-9.4.0.0
redlogic.version=59.0.3
tis3d.version=MC1.7.10-1.2.4.70
tmech.version=75.0afb56c
re.version=3.0.0.342
cofhcore.cf=2246/697
cofhcore.version=[1.7.10]3.0.3B4-302-dev

123
dependencies.gradle Normal file
View File

@ -0,0 +1,123 @@
// Add your dependencies here
dependencies {
shadowImplementation files("dependencies/OpenComputers-JNLua.jar")
shadowImplementation files("dependencies/OpenComputers-LuaJ.jar")
compile("com.google.code.findbugs:jsr305:3.0.2")
compileOnly("com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:EnderStorage:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:GT5-Unofficial:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:ForestryMC:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:Railcraft:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:NotEnoughItems:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:ForgeMultipart:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:CodeChickenLib:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:CodeChickenCore:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:waila:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:Galacticraft:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:TinkersMechworks:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:ProjectRed:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:BloodMagic:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:ThaumicEnergistics:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:ExtraCells2:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:EnderIO:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:Avaritiaddons:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:gendustry:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:WirelessRedstone-CBE:unified-build-script-SNAPSHOT:dev") {
transitive = false
}
compileOnly("appeng:RotaryCraft:V5c:api") {
transitive = false
}
compileOnly("com.bluepowermod:BluePower:0.2.928:deobf") {
transitive = false
}
compileOnly("igwmod:IGW-Mod-1.7.10:1.1.3-18:userdev") {
transitive = false
}
compileOnly("li.cil.tis3d:TIS-3D:MC1.7.10-1.2.4.70:dev") {
transitive = false
}
compileOnly("dev.modwarriors.notenoughkeys:NotEnoughKeys:1.7.10-2.0.0b4:deobf-dev") {
transitive = false
}
compileOnly("qmunity:QmunityLib:0.1.105:deobf") {
transitive = false
}
compileOnly("com.mod-buildcraft:buildcraft:7.1.23:dev") {
transitive = false
}
compileOnly("thaumcraft:Thaumcraft:1.7.10-4.2.3.5:dev") {
transitive = false
}
compileOnly("curse.maven:mekanism-268560:2475797") {
transitive = false
}
compileOnly("net.industrial-craft:industrialcraft-2:2.2.828-experimental:dev") {
transitive = false
}
compileOnly("curse.maven:minefactory-reloaded-66672:2366150") {
transitive = false
}
compileOnly("curse.maven:computercraft-67504:2269339") {
transitive = false
}
compileOnly("curse.maven:cofh-lib-220333:2388748") {
transitive = false
}
compileOnly("curse.maven:agricraft-225635:2284133") {
transitive = false
}
compileOnly("curse.maven:stargatetech-2-226769:2230351") {
transitive = false
}
compileOnly files("dependencies/redlogic-59.1.13.jar")
compileOnly files("dependencies/ic2classic-api.zip")
compileOnly files("dependencies/factorization-api.zip")
compileOnly files("dependencies/ColoredLightsCore-1.3.7.39.jar")
testCompile("org.mockito:mockito-all:1.10.19")
testCompile("org.scalactic:scalactic_2.11:2.2.6")
testCompile("org.scalatest:scalatest_2.11:2.2.6")
}

Binary file not shown.

BIN
dependencies/redlogic-59.1.13.jar vendored Normal file

Binary file not shown.

64
gradle.properties Normal file
View File

@ -0,0 +1,64 @@
modName = OpenComputers
# This is a case-sensitive string to identify your mod. Convention is to use lower case.
modId = OpenComputers
modGroup = li.cil.oc
# 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/
# Will update your build.gradle automatically whenever an update is available
autoUpdateBuildScript = false
minecraftVersion = 1.7.10
forgeVersion = 10.13.4.1614
# Select a username for testing your mod with breakpoints. You may leave this empty for a random user name 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
developmentEnvironmentUserName = "Developer"
# Define a source file of your project with:
# public static final String VERSION = "GRADLETOKEN_VERSION";
# The string's content will be replaced with your mods 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 =
gradleTokenModId =
gradleTokenModName =
gradleTokenVersion =
gradleTokenGroupName =
# 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
apiPackage = api
# Specify the configuration file for Forge's access transformers here. I must be placed into /src/main/resources/META-INF/
# Example value: mymodid_at.cfg
accessTransformersFile = oc_at.cfg
# 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 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
coreModClass = common.launch.TransformerLoader
# 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 = false
# 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.
usesShadowedDependencies = true
# Optional parameter to customize the produced artifacts. Use this to preserver artifact naming when migrating older
# projects. New projects should not use this parameter.
#customArchiveBaseName =

Binary file not shown.

2
jitpack.yml Normal file
View File

@ -0,0 +1,2 @@
before_install:
- ./gradlew setupCIWorkspace

Binary file not shown.

26
repositories.gradle Normal file
View File

@ -0,0 +1,26 @@
// Add any additional repositories for your dependencies here
repositories {
maven {
name = "mightypirates"
url = "https://maven.cil.li/"
metadataSources {
mavenPom()
artifact()
}
}
maven {
name = "ic2"
url = "https://maven.ic2.player.to/"
metadataSources {
mavenPom()
artifact()
}
}
maven {
url "https://cursemaven.com"
}
maven {
url = "https://jitpack.io"
}
}

View File

@ -1 +0,0 @@
rootProject.name = "OpenComputers"

View File

@ -1,15 +0,0 @@
package lordfokas.stargatetech2.api;
import lordfokas.stargatetech2.api.bus.IBusDevice;
import lordfokas.stargatetech2.api.bus.IBusDriver;
import lordfokas.stargatetech2.api.bus.IBusInterface;
/**
* A factory for private classes that implement
* interfaces from the public API.
*
* @author LordFokas
*/
public interface IFactory {
public IBusInterface getIBusInterface(IBusDevice device, IBusDriver driver);
}

View File

@ -1,34 +0,0 @@
package lordfokas.stargatetech2.api;
import java.util.Collection;
import net.minecraft.item.ItemStack;
/**
* The way to get ItemStacks added to the game by StargateTech 2
*
* @author LordFokas
*/
public interface IStackManager {
/**
* Used to fetch an ItemStack by it's name, with a default size of 1.
*
* @param stack The stack we want to fetch.
* @return The stack, or null if none was found.
*/
public ItemStack get(String stack);
/**
* Used to fetch an ItemStack by it's name with a given size.
*
* @param stack The stack we want to fetch.
* @param size The size the stack comes with. Must be in the range 1 - 64.
* @return The stack, or null if none was found.
*/
public ItemStack get(String stack, int size);
/**
* @return A list with the names of all the existing stacks.
*/
public Collection<String> getAllStacks();
}

View File

@ -1,33 +0,0 @@
package lordfokas.stargatetech2.api;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraftforge.fluids.Fluid;
import lordfokas.stargatetech2.api.stargate.IStargateNetwork;
import lordfokas.stargatetech2.api.stargate.IStargatePlacer;
public interface IStargateTechAPI {
/**
* @return The Fluid instance corresponding to Ionized Particles.
*/
public Fluid getIonizedParticlesFluidInstance();
/**
* @return The creative inventory tab used by StargateTech 2.
*/
public CreativeTabs getStargateTab();
/**
* @return The IStargateNetwork singleton instance.
*/
public IStargateNetwork getStargateNetwork();
/**
* @return The IStargatePlacer singleton instance, a.k.a Seeding Ship for the fans.
*/
public IStargatePlacer getSeedingShip();
/**
* @return The current IFactory instance.
*/
public IFactory getFactory();
}

View File

@ -1,27 +0,0 @@
package lordfokas.stargatetech2.api;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
/**
* Implemented by blocks that run special actions when clicked with a TabletPC in hand.
* The default action in StargateTech2 is opening a special GUI.
*
* @author LordFokas
*/
public interface ITabletAccess {
/**
* Make the block run a special action when activated with a TabletPC.
* This method is only called on the client side.
* Implementations requiring server side should use packets.
*
* @param player The player activating the block.
* @param world The world the block is in.
* @param x The block's X coordinate.
* @param y The block's Y coordinate.
* @param z The block's Z coordinate.
* @return True if a special action was executed, false otherwise.
*/
public boolean onTabletAccess(EntityPlayer player, World world, int x, int y, int z);
}

View File

@ -1,16 +0,0 @@
package lordfokas.stargatetech2.api;
public abstract class StargateTechAPI implements IStargateTechAPI {
protected static IStargateTechAPI apiInstance;
/**
* StargateTech's API is abstract, and it's implementation is not visible in the API package.
* All available methods in IStargateTechAPI are implemented elsewhere.
* This method allows you to retrieve an instance of that implementation.
*
* @return a concrete implementation of IStargateTechAPI
*/
public static IStargateTechAPI api(){
return apiInstance;
}
}

View File

@ -1,40 +0,0 @@
package lordfokas.stargatetech2.api.bus;
import cpw.mods.fml.common.eventhandler.Event;
import net.minecraft.world.World;
public class BusEvent extends Event{
public final World world;
public final int x, y, z;
protected BusEvent(World world, int x, int y, int z){
this.world = world;
this.x = x;
this.y = y;
this.z = z;
}
/**
* Fire this event on Forge's BUS_EVENT to add the IBusDevice
* in this location to a bus network, if any is available.
*
* @author LordFokas
*/
public static final class AddToNetwork extends BusEvent{
public AddToNetwork(World world, int x, int y, int z) {
super(world, x, y, z);
}
}
/**
* Fire this event on Forge's BUS_EVENT to remove the IBusDevice
* in this location from any connected bus networks.
*
* @author LordFokas
*/
public static final class RemoveFromNetwork extends BusEvent{
public RemoveFromNetwork(World world, int x, int y, int z) {
super(world, x, y, z);
}
}
}

View File

@ -1,93 +0,0 @@
package lordfokas.stargatetech2.api.bus;
import java.util.LinkedList;
public abstract class BusPacket<R>{
private LinkedList<R> responses;
private final short sender;
private final short target;
private final boolean hasLIP;
/**
* @param sender The address of the Device that is sending this packet.
* @param target The address of the Device(s) that should receive this packet.
* @param hasLIP Whether or not this packet supports being converted to a plain text (LIP) format.
*/
protected BusPacket(short sender, short target, boolean hasLIP){
this.responses = new LinkedList();
this.sender = sender;
this.target = target;
this.hasLIP = hasLIP;
}
/**
* @return The address of the device that sent this packet.
*/
public final short getSender(){
return sender;
}
/**
* @return The address of the device(s) that should receive this packet.
*/
public final short getTarget(){
return target;
}
/**
* @return The ID of the protocol this packet corresponds to.
*/
public final int getProtocolID(){
return BusProtocols.getProtocolID(this.getClass());
}
/**
* @return A plain text (LIP) version of this packet, if it has one.
*/
public final BusPacketLIP getPlainText(){
if(this instanceof BusPacketLIP){
return (BusPacketLIP) this;
}else if(hasLIP){
BusPacketLIP lip = new BusPacketLIP(sender, target);
fillPlainText(lip);
lip.finish();
return lip;
}
return null;
}
/**
* Used by subclasses to convert themselves to plain text format.
*
* @param lip The Lazy Intercom Protocol (LIP) packet we're filling with our data.
*/
protected abstract void fillPlainText(BusPacketLIP lip);
/**
* @return Whether or not this packet supports conversion to the LIP format.
*/
public final boolean hasPlainText(){
return hasLIP;
}
/**
* Adds a response to this packet that to give the sender some feedback.
* The object type depends on the packet subclass.
*
* Note that clients converting the packet to LIP format
* lose the ability to send feedback.
*
* @param response The response to add.
*/
public final void addResponse(R response){
if(response == null) throw new IllegalArgumentException("A Response cannot be null!");
responses.add(response);
}
/**
* @return All the responses other clients added to this packet.
*/
public final LinkedList<R> getResponses(){
return new LinkedList<R>(responses);
}
}

View File

@ -1,112 +0,0 @@
package lordfokas.stargatetech2.api.bus;
import java.util.ArrayList;
import java.util.Hashtable;
/**
* LIP - Lazy Intercom Protocol<br>
* <br>
* Baptized by sciguyryan (often found in #ThermalExpansion and #StargateTech on esper.net's IRC),
* this is the universal plain text format used in the Abstract Bus.<br>
* <br>
* Any packet can choose to be convertible to this format, allowing for any class anywhere to
* read data from a packet which has an unknown and / or private class by asking it to convert to
* a text format. This removes all the problems with type casting and such.
*
* @author LordFokas
*/
public final class BusPacketLIP extends BusPacket<String> {
private boolean isEditable = true;
private LIPMetadata metadata = null;
private Hashtable<String, String> data = new Hashtable();
/**
* Defines optional metadata that helps sorting this packet out / figuring out what to do with this.
* The fact this is a plain text protocol makes the possibilities so vague it'd be impossible to
* guess what kind of data this packet carries.
*
* @author LordFokas
*/
public static final class LIPMetadata{
public final String modID;
public final String deviceName;
public final String playerName;
/**
* Example: new LIPMetadata("StargateTech2", "shieldEmitter", "LordFokas");
*
* @param modID The ID of the mod that generated this packet. PLEASE do fill this one.
* @param deviceName The name (or a unique identifier) of the type of machine that generated this.
* @param playerName The name of the player that made this packet be generated, if any.
*/
public LIPMetadata(String modID, String deviceName, String playerName){
this.modID = modID;
this.deviceName = deviceName;
this.playerName = playerName;
}
}
public BusPacketLIP(short sender, short target) {
super(sender, target, true);
}
/**
* @param metadata The LIPMetadata object to set to this packet.
*/
public void setMetadata(LIPMetadata metadata){
if(isEditable && this.metadata == null){
this.metadata = metadata;
}
}
/**
* @return The LIPMetadata object on this object. May be null.
*/
public LIPMetadata getMetadata(){
return metadata;
}
@Override // We don't need this. At all.
protected void fillPlainText(BusPacketLIP lip){}
/**
* Finish creating this packet.
* As soon as you call this, it can no longer be modified.
*/
public void finish(){
isEditable = false;
}
/**
* @return A list of all the keys for the data on this packet.
*/
public ArrayList<String> getEntryList(){
ArrayList<String> entries = new ArrayList();
entries.addAll(data.keySet());
return entries;
}
/**
* Add a new entry to this packet.
* If the key already exists the entry is ignored.
*
* @param key The key under which to send the data.
* @param val The data to send.
*/
public void set(String key, String val){
if(isEditable && !data.containsKey(key)){
data.put(key.toLowerCase(), val);
}
}
/**
* Get the value stored under that key, if any.
* Case Insensitive.
*
* @param key The key under which the data is stored.
* @return The data stored under that key, if any, null otherwise.
*/
public String get(String key){
return data.get(key.toLowerCase());
}
}

View File

@ -1,39 +0,0 @@
package lordfokas.stargatetech2.api.bus;
import java.util.LinkedList;
public final class BusPacketNetScan extends BusPacket<Void> {
private LinkedList<Device> devices = new LinkedList();
public BusPacketNetScan(short target) {
super((short)0xFFFF, target, false);
}
// We're not using this
@Override protected void fillPlainText(BusPacketLIP lip){}
public void addDevice(Device device){
devices.add(device);
}
public LinkedList<Device> getDevices(){
return new LinkedList<Device>(devices);
}
public static final class Device{
public final String description, name;
public final short address;
public final boolean enabled;
public final int x, y, z;
public Device(String desc, String name, short address, boolean enabled, int x, int y, int z){
this.description = desc;
this.name = name;
this.address = address;
this.enabled = enabled;
this.x = x;
this.y = y;
this.z = z;
}
}
}

View File

@ -1,38 +0,0 @@
package lordfokas.stargatetech2.api.bus;
import java.util.ArrayList;
public final class BusProtocols {
private static final ArrayList<Class<? extends BusPacket>> protocols = new ArrayList();
/**
* Add a protocol to the list, if it doesn't exist yet.
*
* @param packetClass the class of the packet corresponding to the protocol we're adding.
* @return the id of the protocol we just added.
*/
public static final int addProtocol(Class<? extends BusPacket> packetClass){
if(!protocols.contains(packetClass)){
protocols.add(packetClass);
}
return protocols.indexOf(packetClass);
}
/**
* Gives you the id of the protocol correspondig to a given packet class.
*
* @param packetClass the class of the packet for which we want to know the protocol ID.
* @return the ID of the protocol corresponding to the packet class.
*/
public static final int getProtocolID(Class<? extends BusPacket> packetClass){
return protocols.indexOf(packetClass);
}
private BusProtocols(){}
// A list of all the protocols implemented by StargateTech 2
public static final int PROTOCOL_LIP = addProtocol(BusPacketLIP.class);
public static final int PROTOCOL_NETSCAN = addProtocol(BusPacketNetScan.class);
}

View File

@ -1,41 +0,0 @@
package lordfokas.stargatetech2.api.bus;
import net.minecraft.world.World;
/**
* To be implemented by Tile Entities that wish
* to access the Abstract Bus.
*
* @author LordFokas
*/
public interface IBusDevice {
/**
* Returns the IBusInterfaces that exist on that
* side of the Tile Entity. It may be multiple
* values or null.
*
* @param side The side of the block that is being queried.
* @return This side's IBusInterface, if any.
*/
public IBusInterface[] getInterfaces(int side);
/**
* @return This device's worldObj.
*/
public World getWorld();
/**
* @return This device's X Coordinate.
*/
public int getXCoord();
/**
* @return This device's Y Coordinate.
*/
public int getYCoord();
/**
* @return This device's Z Coordinate.
*/
public int getZCoord();
}

View File

@ -1,65 +0,0 @@
package lordfokas.stargatetech2.api.bus;
/**
* This provides a level of abstraction over the IBusInterface.
* Implement to your own liking.
*
* @author LordFokas
*/
public interface IBusDriver {
/**
* Used to check if this device should receive a specific
* packet type from this sender. If true is returned,
* handlePacket() is called afterwards.
*
* @param sender The Bus address of the packet's sender.
* @param protocolID The unique ID of this packet type.
* @param hasLIP whether the packet can be converted to the LIP format or not.
* @return Whether the device will accept this packet or not.
*/
public boolean canHandlePacket(short sender, int protocolID, boolean hasLIP);
/**
* Called by the network to have this device handle a packet.
*
* @param packet The packet to be handled.
*/
public void handlePacket(BusPacket packet);
/**
* Used to make the IBusDriver give all packets in its send
* queue, one by one, to the IBusInterface so that it can
* send them accross the network.
*
* @return The next BusPacket in the queue, if any, null otherise.
*/
public BusPacket getNextPacketToSend();
/**
* Called by the hardware representation (IBusInterface)
* to check if it's active or not.
* Inactive interfaces cannot send or receive packets.
*
* @return Whether this interface is active or not.
*/
public boolean isInterfaceEnabled();
/**
* Called by this Driver's Interface to check it's own address.
*
* @return The address of this IBusDriver's IBusInterface.
*/
public short getInterfaceAddress();
/**
* @return this driver's short name.<br>
* Should be readable and indicate what kind of device it is.<br>
* <b>Example:</b> Shield Controller
*/
public String getShortName();
/**
* @return a short description of what this device is.
*/
public String getDescription();
}

View File

@ -1,35 +0,0 @@
package lordfokas.stargatetech2.api.bus;
import net.minecraft.nbt.NBTTagCompound;
/**
* <b>DO NOT IMPLEMENT THIS INTERFACE!</b> To get an instance use
* <i>StargateTechAPI.api().getFactory().getIBusInterface()</i>;
*
* @author LordFokas
*/
public interface IBusInterface {
/**
* Makes the IBusInterface call its IBusDriver's
* getNextPacketToSend() method repeatedly until it returns
* null. Every packet returned by that method will be sent
* across the network.
*/
public void sendAllPackets();
/**
* Serialize this object.
*
* @param nbt The tag compound where this object's data is.
* @param tag The name of the tag under which this object's data is stored.
*/
public void writeToNBT(NBTTagCompound nbt, String tag);
/**
* Unserialize this object.
*
* @param nbt The tag compound where this object's data is.
* @param tag The name of the tag under which this object's data is stored.
*/
public void readFromNBT(NBTTagCompound nbt, String tag);
}

View File

@ -1,82 +0,0 @@
package lordfokas.stargatetech2.api.stargate;
public class Address {
private Symbol[] symbols;
public static Address create(Symbol[] symbols){
try{
boolean used[] = new boolean[40];
if(symbols.length < 7) throw new Exception("Address too short: " + symbols.length);
if(symbols.length > 9) throw new Exception("Address too long: " + symbols.length);
for(int i = 0; i < used.length; i++){
used[i] = (i == 0);
}
for(Symbol symbol : symbols){
if(symbol == null || symbol == Symbol.VOID){
throw new Exception("Invalid Symbol.");
}
if(used[symbol.ordinal()]){
throw new Exception("Repeated Symbol.");
}
used[symbol.ordinal()] = true;
}
return new Address(symbols);
}catch(Exception e){
return null;
}
}
private Address(Symbol[] symbols){
this.symbols = symbols;
}
public int length(){
return symbols.length;
}
public Symbol getSymbol(int symbol){
if(symbol >= 0 && symbol < length()){
return symbols[symbol];
}else{
return Symbol.VOID;
}
}
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append(getSymbol(0).toString());
sb.append(getSymbol(1).toString().toLowerCase());
sb.append(getSymbol(2).toString().toLowerCase());
sb.append(" ");
sb.append(getSymbol(3).toString());
sb.append(getSymbol(4).toString().toLowerCase());
sb.append(getSymbol(5).toString().toLowerCase());
sb.append(" ");
sb.append(getSymbol(6).toString());
sb.append(getSymbol(7).toString().toLowerCase());
sb.append(getSymbol(8).toString().toLowerCase());
return sb.toString();
}
@Override
public boolean equals(Object o){
if(o instanceof Address){
Address a = (Address) o;
if(a.length() == length()){
for(int i = 0; i < length(); i++){
if(symbols[i] != a.symbols[i]){
return false;
}
}
return true;
}
}
return false;
}
@Override
public int hashCode(){
return length();
}
}

View File

@ -1,22 +0,0 @@
package lordfokas.stargatetech2.api.stargate;
public enum DialError{
// Dialing Errors
SOURCE_ADDRESS_NOT_FOUND,
TARGET_ADDRESS_NOT_FOUND,
SOURCE_WORLD_NOT_FOUND,
TARGET_WORLD_NOT_FOUND,
CANNOT_DIAL_SAME_WORLD,
FAILED_CHUNKLOADING_SOURCE,
FAILED_CHUNKLOADING_TARGET,
SOURCE_GATE_NOT_FOUND,
TARGET_GATE_NOT_FOUND,
NOT_ENOUGH_POWER,
TARGET_GATE_BUSY,
SOURCE_GATE_BUSY,
// Logic
DIALING_EVENT_CANCELED,
SUCCESSFULLY_DIALED,
UNKNOWN_LOGIC_ERROR;
}

View File

@ -1,37 +0,0 @@
package lordfokas.stargatetech2.api.stargate;
import cpw.mods.fml.common.eventhandler.Cancelable;
public abstract class DialEvent extends StargateEvent {
public final Address sourceAddress;
public final Address destAddress;
public final int duration;
public DialEvent(Address src, Address dst, int dur) {
sourceAddress = src;
destAddress = dst;
duration = dur;
}
@Cancelable
public static class Pre extends DialEvent {
public Pre(Address src, Address dst, int dur) {
super(src, dst, dur);
}
}
public static class Success extends DialEvent {
public Success(Address src, Address dst, int dur) {
super(src, dst, dur);
}
}
public static class Error extends DialEvent {
public final DialError error;
public Error(Address src, Address dst, DialError error) {
super(src, dst, -1);
this.error = error;
}
}
}

View File

@ -1,21 +0,0 @@
package lordfokas.stargatetech2.api.stargate;
public interface IDynamicWorldLoader {
/**
* @param address The address we're creating a new world for.
* @return Whether or not this loader will create a new world for this non-existing address.
*/
public boolean willCreateWorldFor(Address address);
/**
* Actually create a new world for this address.
* <b>This world must not exist already!</b>
* Do not forget to use the seedingShip to place a stargate on this world, or the pending
* wormhole will not connect.
*
* @param address The address we're creating a new world for.
* @param seedingShip The IStargatePlacer we'll use to place our stargate.
*/
public void loadWorldFor(Address address, IStargatePlacer seedingShip);
}

View File

@ -1,80 +0,0 @@
package lordfokas.stargatetech2.api.stargate;
import net.minecraft.world.World;
public interface IStargateNetwork {
/**
* @return Whether the Stargate Network is loaded (working) or not.
*/
public boolean isLoaded();
/**
* @param address The string representation of an address. (e.g. "Proclarush Taonas At")
* @return an address object if the string is a valid address, null otherwise.
*/
public Address parseAddress(String address);
/**
* Checks if a given address exists in the network or not.
* (i.e., if this address maps to a physical Stargate)
*
* @param address the address we want to check.
* @return whether the address exists or not.
*/
public boolean addressExists(Address address);
/**
* Returns the address of the Stargate in a specific location if it exists or null otherwise.
*
* @param world The world the target Stargate is in.
* @param x The target Stargate's X coordinate.
* @param y The target Stargate's Y coordinate.
* @param z The target Stargate's Z coordinate.
* @return The Stargate's address, or null if the location doesn't contain a Stargate.
*/
public Address getAddressOf(World world, int x, int y, int z);
/**
* Returns the address of the Stargate nearest to the specified location, or null if there is no gate within the specified radius
* @param world The world the target Stargate is in.
* @param x The target Stargate's X coordinate.
* @param y The target Stargate's Y coordinate.
* @param z The target Stargate's Z coordinate.
* @param radius The maximum radius to look for a Stargate. Use -1 to search the whole world.
* @return The Stargate's address, or null if no Stargate was found
*/
public Address findNearestStargate(World world, int x, int y, int z, int radius);
/**
* Register a new IDynamicWorldLoader.
*
* @param dwl The IDynamicWorldLoader to register.
*/
public void registerDynamicWorldLoader(IDynamicWorldLoader dwl);
/**
* Unregister a known IDynamicWorldLoader.
*
* @param dwl The IDynamicWorldLoader to unregister.
*/
public void unregisterDynamicWorldLoader(IDynamicWorldLoader dwl);
/**
* Reserve an address prefix for your DWL.
* If a Stargate attempts to dial a world with that prefix,
* your DWL is given exclusivity in generating that world.
*
* @param dwl Your IDynamicWorldLoader
* @param prefix And array of exactly 3 non-null and non-void symbols representing a dimension.
* @return whether or not the prefix has been successfully reserved.
*/
public boolean reserveDimensionPrefix(IDynamicWorldLoader dwl, Symbol[] prefix);
/**
* Checks if the specified prefix is associated with a dimension or reserved by a {@link IDynamicWorldLoader}.
*
* @param prefix An array of exactly 3 non-null and non-void symbols representing a dimension.
* @return Whether or not the prefix is either used or reserved.
*/
public boolean prefixExists(Symbol[] prefix);
}

View File

@ -1,17 +0,0 @@
package lordfokas.stargatetech2.api.stargate;
import net.minecraft.world.World;
public interface IStargatePlacer {
/**
* Attempts to place a Stargate in the givel location.
*
* @param w Our world.
* @param x The stargate base's (bottom center block) X coord.
* @param y The stargate base's (bottom center block) Y coord.
* @param z The stargate base's (bottom center block) Z coord.
* @param facing The direction the stargate should be facing. Should be a value in [0 - 3].
* @return Whether the Stargate was placed or not.
*/
public boolean placeStargate(World w, int x, int y, int z, int facing);
}

View File

@ -1,16 +0,0 @@
package lordfokas.stargatetech2.api.stargate;
/**
* Represents a Stargate ring.
* Stargate "base" blocks contain the ring, so they implement this as well.
*
* All you can get from the Stargate ring is the address.
*
* @author LordFokas
*/
public interface ITileStargate {
/**
* @return This Stargate's address. null values are possible on the client side.
*/
public Address getAddress();
}

View File

@ -1,30 +0,0 @@
package lordfokas.stargatetech2.api.stargate;
/**
* Represents a Stargate base block (the block that supports the stargate).
*
* It contains all the important logic in the Stargate,
* like dialing, Iris control and power usage.
*
* Because the ring is inside the block that supports it, it is possible to
* call the same methods you can call on a ring.
*
* @see ITileStargate
*
* @author LordFokas
*/
public interface ITileStargateBase extends ITileStargate{
public enum DialMethod{
MANUAL, // Dialing Computers
AUTO // DHDs
}
/**
* Used to try making the Stargate dial an address.
*
* @param address The address this Stargate should dial.
* @param timeout How many seconds the connection will last. (1 - 38; default: 38);
* @return whether the dialing sequence started (true) or failed (false).
*/
public DialError dial(Address address, int timeout, DialMethod method);
}

View File

@ -1,38 +0,0 @@
package lordfokas.stargatetech2.api.stargate;
import cpw.mods.fml.common.eventhandler.Cancelable;
import cpw.mods.fml.common.eventhandler.Event;
import net.minecraft.world.World;
public abstract class StargateEvent extends Event {
private static abstract class PhysicalGateEvent extends StargateEvent {
public final Address address;
public final World world;
public final int xCoord;
public final int yCoord;
public final int zCoord;
public PhysicalGateEvent(Address addr, World world, int x, int y, int z) {
this.xCoord = x;
this.yCoord = y;
this.zCoord = z;
this.world = world;
this.address = addr;
}
}
@Cancelable
public static class StargateWrenched extends PhysicalGateEvent {
public StargateWrenched(Address addr, World world, int x, int y, int z) {
super(addr, world, x, y, z);
}
}
public static class StargateDestroyed extends PhysicalGateEvent {
public StargateDestroyed(Address addr, World world, int x, int y, int z) {
super(addr, world, x, y, z);
}
}
}

View File

@ -1,63 +0,0 @@
package lordfokas.stargatetech2.api.stargate;
public enum Symbol {
VOID(""),
AT ("At"), // 1
AL ("Al"), // 2
CLA ("Cla"), // 3
UR ("Ur"), // 4
ON ("On"), // 5
DEH ("Deh"), // 6
EC ("Ec"), // 7
MIG ("Mig"), // 8
AM ("Am"), // 9
RUM ("Rum"), // 10
AR ("Ar"), // 11
VA ("Va"), // 12
COR ("Cor"), // 13
PRA ("Pra"), // 14
OM ("Om"), // 15
ET ("Et"), // 16
AS ("As"), // 17
US ("Us"), // 18
GON ("Gon"), // 19
ORM ("Orm"), // 20
EM ("Em"), // 21
AC ("Ac"), // 22
OTH ("Oth"), // 23
LOS ("Los"), // 24
LAN ("Lan"), // 25
EST ("Est"), // 26
CRO ("Cro"), // 27
SIL ("Sil"), // 28
TA ("Ta"), // 29
BREI("Brei"), // 30
RUSH("Rush"), // 31
ERP ("Erp"), // 32
SET ("Set"), // 33
ULF ("Ulf"), // 34
PRO ("Pro"), // 35
SAL ("Sal"), // 36
TIS ("Tis"), // 37
MAC ("Mac"), // 38
IRT ("Irt"); // 39
private String name;
private Symbol(String name){
this.name = name;
}
public static Symbol get(int s){
if(s >= 0 && s <= 39){
return values()[s];
}else{
return VOID;
}
}
@Override
public String toString(){
return name;
}
}

View File

@ -1,28 +0,0 @@
package lordfokas.stargatetech2.api.world;
import net.minecraft.world.World;
import cpw.mods.fml.common.eventhandler.Event;
import cpw.mods.fml.common.eventhandler.Event.HasResult;
@HasResult
public class EventWorldGen extends Event {
public final World world;
public final int chunkX;
public final int chunkZ;
public final GenType type;
public EventWorldGen(World world, int cX, int cZ, GenType type) {
this.world = world;
this.chunkX = cX;
this.chunkZ = cZ;
this.type = type;
}
public static enum GenType {
STARGATE,
LOOT_POD,
VEIN_NAQUADAH;
}
}

@ -1 +0,0 @@
Subproject commit ced30ed35097d53cdb2a843d705477e52896e54b

View File

@ -1,9 +1,9 @@
[{
"modid": "OpenComputers",
"name": "OpenComputers",
"modid": "${modId}",
"name": "${modName}",
"description": "This mod adds modular computers and robots that can be programmed in Lua.",
"version": "${version}",
"mcversion": "${mcversion}",
"version": "${modVersion}",
"mcversion": "${minecraftVersion}",
"url": "https://oc.cil.li/",
"authorList": ["Florian 'Sangar' Nuecke", "Johannes 'Lord Joda' Lohrer", "Everyone who contributed to the mod on Github - thank you!"],
"credits" : "Inspired by a couple of other mods, most notably ComputerCraft.",

View File

@ -7,6 +7,7 @@ import li.cil.oc.api.machine.Context;
import li.cil.oc.api.network.ManagedEnvironment;
import li.cil.oc.api.prefab.DriverSidedTileEntity;
import li.cil.oc.integration.ManagedTileEntityEnvironment;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import org.apache.commons.lang3.text.WordUtils;
@ -29,7 +30,7 @@ public final class DriverSecureTile extends DriverSidedTileEntity {
@Callback(doc = "function(name:string):boolean -- Returns whether the player with the given name can access the component")
public Object[] canPlayerAccess(final Context context, final Arguments args) {
return new Object[]{tileEntity.canPlayerAccess(args.checkString(0))};
return new Object[]{tileEntity.canPlayerAccess(MinecraftServer.getServer().getConfigurationManager().func_152612_a(args.checkString(0)))};
}
@Callback(doc = "function():string -- Returns the type of the access.")

View File

@ -9,7 +9,7 @@ object EventHandlerProjectRed {
player.getHeldItem.getItem match {
case wrench: IScrewdriver =>
if (changeDurability) {
wrench.damageScrewdriver(player.getEntityWorld, player)
wrench.damageScrewdriver(player, player.getHeldItem)
true
}
else true