mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-11-04 15:43:00 +00:00
Compare commits
70 Commits
v1.20.1-1.
...
v1.20.1-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18f3426f1d | ||
|
|
0ec46fe38e | ||
|
|
569de7fafb | ||
|
|
157ce4fa55 | ||
|
|
b9ed66983d | ||
|
|
d0fbec6c6b | ||
|
|
a683697e8c | ||
|
|
9e233a916f | ||
|
|
5a9e21ccc3 | ||
|
|
5f16909d4b | ||
|
|
00475b9bb0 | ||
|
|
018ce7c8a5 | ||
|
|
44726827b4 | ||
|
|
3cf914cb4c | ||
|
|
180156ff1c | ||
|
|
c6ba753568 | ||
|
|
9f45c91925 | ||
|
|
8344c0a5c2 | ||
|
|
a292d33830 | ||
|
|
341d1c7bc2 | ||
|
|
531eacfac7 | ||
|
|
1f3da5205c | ||
|
|
798ceefafe | ||
|
|
7c0f79fc3c | ||
|
|
b35cefc5dd | ||
|
|
69353a4fcf | ||
|
|
ff363dca5a | ||
|
|
1c51282426 | ||
|
|
4a3a1c9275 | ||
|
|
2557dd0af9 | ||
|
|
b5c0c6e104 | ||
|
|
876fd8ddb8 | ||
|
|
ee3b1343b5 | ||
|
|
b440b964b7 | ||
|
|
5dfc401b45 | ||
|
|
4344c3072f | ||
|
|
947001104d | ||
|
|
8711512769 | ||
|
|
9c0ce27ce6 | ||
|
|
c458360b18 | ||
|
|
09ad6c1905 | ||
|
|
0e1e8a72d3 | ||
|
|
7c1e8e1951 | ||
|
|
b03546a158 | ||
|
|
582713467f | ||
|
|
b6f41a0df5 | ||
|
|
594738a022 | ||
|
|
27f2ab364c | ||
|
|
5a43273757 | ||
|
|
97e28516fb | ||
|
|
676fb5fb53 | ||
|
|
63ba3fe274 | ||
|
|
749b3df227 | ||
|
|
b97634b717 | ||
|
|
1b8344d0a3 | ||
|
|
b42bc0a01a | ||
|
|
0cff73e2fc | ||
|
|
a892739f8e | ||
|
|
f8785a092f | ||
|
|
dd7e8fcefc | ||
|
|
29c8f96912 | ||
|
|
b9267ecbfc | ||
|
|
9d2c2db22b | ||
|
|
6660966320 | ||
|
|
16324e1eac | ||
|
|
32f5c38485 | ||
|
|
01fe949b3e | ||
|
|
c03fce275e | ||
|
|
0998acaa82 | ||
|
|
12a44fed6f |
@@ -27,7 +27,7 @@ indent_size = 2
|
||||
[*.yml]
|
||||
indent_size = 2
|
||||
|
||||
[{*.kt,*.kts}]
|
||||
[*.{kt,kts}]
|
||||
ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL
|
||||
ij_kotlin_continuation_indent_size = 4
|
||||
ij_kotlin_spaces_around_equality_operators = true
|
||||
@@ -39,3 +39,14 @@ ij_kotlin_allow_trailing_comma_on_call_site = true
|
||||
ij_kotlin_method_parameters_wrap = off
|
||||
ij_kotlin_call_parameters_wrap = off
|
||||
ij_kotlin_extends_list_wrap = off
|
||||
|
||||
ktlint_code_style = intellij_idea
|
||||
ktlint_standard_class-naming = disabled
|
||||
ktlint_standard_class-signature = disabled
|
||||
ktlint_standard_function-naming = disabled
|
||||
ktlint_standard_no-wildcard-imports = disabled
|
||||
|
||||
# FIXME: These two are disable right now as they're over-eager in putting things
|
||||
# on the same line. We should set max_line_length and handle this properly.
|
||||
ktlint_standard_function-signature = disabled
|
||||
ktlint_standard_function-expression-body = disabled
|
||||
|
||||
3
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
3
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
@@ -11,7 +11,8 @@ body:
|
||||
What version of Minecraft are you using? If your version is not listed, please try to reproduce on one of the supported versions.
|
||||
options:
|
||||
- 1.20.1
|
||||
- 1.21.x
|
||||
- 1.21.1
|
||||
- 1.21.7
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
|
||||
4
.github/workflows/main-ci.yml
vendored
4
.github/workflows/main-ci.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
- name: 📥 Set up Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: 17
|
||||
java-version: 21
|
||||
distribution: 'temurin'
|
||||
|
||||
- name: 📥 Setup Gradle
|
||||
@@ -87,7 +87,7 @@ jobs:
|
||||
- name: 📥 Set up Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: 17
|
||||
java-version: 21
|
||||
distribution: 'temurin'
|
||||
|
||||
- name: 📥 Setup Gradle
|
||||
|
||||
2
.github/workflows/make-doc.yml
vendored
2
.github/workflows/make-doc.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
- name: 📥 Set up Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: 17
|
||||
java-version: 21
|
||||
distribution: 'temurin'
|
||||
|
||||
- name: 📥 Setup Gradle
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.4.0
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
|
||||
@@ -28,7 +28,7 @@ Translations are managed through [CrowdIn], an online interface for managing lan
|
||||
In order to develop CC: Tweaked, you'll need to download the source code and then run it.
|
||||
|
||||
- Make sure you've got the following software installed:
|
||||
- Java Development Kit 17 (JDK). This can be downloaded from [Adoptium].
|
||||
- Java Development Kit 21 (JDK). This can be downloaded from [Adoptium].
|
||||
- [Git](https://git-scm.com/).
|
||||
- [NodeJS 20 or later][node].
|
||||
|
||||
@@ -88,8 +88,8 @@ You'll first need to [set up a development environment as above](#setting-up-a-d
|
||||
|
||||
Once this is set up, you can now run `./gradlew docWebsite`. This generates documentation from our Lua and Java code,
|
||||
writing the resulting HTML into `./projects/web/build/site`, which can then be opened in a browser. When iterating on
|
||||
documentation, you can instead run `./gradlew docWebsite -t`, which will rebuild documentation every time you change a
|
||||
file.
|
||||
documentation, you can instead run `./gradlew :web:assemble -x :web:compileTeaVM -t`, which will rebuild documentation
|
||||
every time you change a file.
|
||||
|
||||
Documentation is built using [illuaminate] which, while not currently documented (somewhat ironic), is largely the same
|
||||
as [ldoc][ldoc]. Documentation comments are written in Markdown, though note that we do not support many GitHub-specific
|
||||
@@ -101,7 +101,7 @@ about how you can build on that until you've covered everything!
|
||||
|
||||
[new-issue]: https://github.com/cc-tweaked/CC-Tweaked/issues/new/choose "Create a new issue"
|
||||
[community]: README.md#community "Get in touch with the community."
|
||||
[Adoptium]: https://adoptium.net/temurin/releases?version=17 "Download OpenJDK 17"
|
||||
[Adoptium]: https://adoptium.net/temurin/releases?version=21 "Download OpenJDK 21"
|
||||
[illuaminate]: https://github.com/SquidDev/illuaminate/ "Illuaminate on GitHub"
|
||||
[docs]: https://tweaked.cc/ "CC: Tweaked documentation"
|
||||
[ldoc]: http://stevedonovan.github.io/ldoc/ "ldoc, a Lua documentation generator."
|
||||
|
||||
@@ -4,13 +4,11 @@
|
||||
|
||||
import cc.tweaked.gradle.JUnitExt
|
||||
import net.fabricmc.loom.api.LoomGradleExtensionAPI
|
||||
import net.fabricmc.loom.util.gradle.SourceSetHelper
|
||||
import org.jetbrains.gradle.ext.*
|
||||
import org.jetbrains.gradle.ext.Application
|
||||
|
||||
plugins {
|
||||
publishing
|
||||
alias(libs.plugins.taskTree)
|
||||
alias(libs.plugins.githubRelease)
|
||||
alias(libs.plugins.gradleVersions)
|
||||
alias(libs.plugins.versionCatalogUpdate)
|
||||
@@ -70,7 +68,7 @@ idea.project.settings.runConfigurations {
|
||||
val fabricProject = evaluationDependsOn(":fabric")
|
||||
val classPathGroup = fabricProject.extensions.getByType<LoomGradleExtensionAPI>().mods
|
||||
.joinToString(File.pathSeparator + File.pathSeparator) { modSettings ->
|
||||
SourceSetHelper.getClasspath(modSettings, project).joinToString(File.pathSeparator) { it.absolutePath }
|
||||
modSettings.modFiles.joinToString(File.pathSeparator) { it.absolutePath }
|
||||
}
|
||||
|
||||
vmParameters = "-ea -Dfabric.classPathGroups=$classPathGroup"
|
||||
@@ -115,8 +113,12 @@ idea.project.settings.compiler.javac {
|
||||
.toMap()
|
||||
}
|
||||
|
||||
repositories() {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
versionCatalogUpdate {
|
||||
sortByKey = false
|
||||
pin { versions.addAll("fastutil", "guava", "netty", "slf4j") }
|
||||
keep { keepUnusedLibraries = true }
|
||||
keep { keepUnusedVersions = true }
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ repositories {
|
||||
name = "Fabric"
|
||||
content {
|
||||
includeGroup("net.fabricmc")
|
||||
includeGroup("net.fabricmc.unpick")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +70,6 @@ gradlePlugin {
|
||||
|
||||
versionCatalogUpdate {
|
||||
sortByKey = false
|
||||
keep { keepUnusedLibraries = true }
|
||||
keep { keepUnusedVersions = true }
|
||||
catalogFile = file("../gradle/libs.versions.toml")
|
||||
}
|
||||
|
||||
@@ -4,10 +4,7 @@
|
||||
|
||||
/** Default configuration for Fabric projects. */
|
||||
|
||||
import cc.tweaked.gradle.CCTweakedExtension
|
||||
import cc.tweaked.gradle.CCTweakedPlugin
|
||||
import cc.tweaked.gradle.IdeaRunConfigurations
|
||||
import cc.tweaked.gradle.MinecraftConfigurations
|
||||
import cc.tweaked.gradle.*
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
@@ -67,3 +64,19 @@ dependencies {
|
||||
tasks.ideaSyncTask {
|
||||
doLast { IdeaRunConfigurations(project).patch() }
|
||||
}
|
||||
|
||||
tasks.named("checkDependencyConsistency", DependencyCheck::class.java) {
|
||||
val libs = project.extensions.getByType<VersionCatalogsExtension>().named("libs")
|
||||
// Minecraft depends on lwjgl, but Fabric forces it to a more recent version
|
||||
for (lwjgl in listOf(
|
||||
"lwjgl",
|
||||
"lwjgl-glfw",
|
||||
"lwjgl-jemalloc",
|
||||
"lwjgl-openal",
|
||||
"lwjgl-opengl",
|
||||
"lwjgl-stb",
|
||||
"lwjgl-tinyfd",
|
||||
)) {
|
||||
override("org.lwjgl", lwjgl, "3.3.2")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
import cc.tweaked.gradle.CCTweakedExtension
|
||||
import cc.tweaked.gradle.CCTweakedPlugin
|
||||
import cc.tweaked.gradle.IdeaRunConfigurations
|
||||
import cc.tweaked.gradle.MinecraftConfigurations
|
||||
|
||||
plugins {
|
||||
@@ -20,7 +19,7 @@ val mcVersion: String by extra
|
||||
|
||||
legacyForge {
|
||||
val libs = project.extensions.getByType<VersionCatalogsExtension>().named("libs")
|
||||
version = "${mcVersion}-${libs.findVersion("forge").get()}"
|
||||
version = "$mcVersion-${libs.findVersion("forge").get()}"
|
||||
|
||||
parchment {
|
||||
minecraftVersion = libs.findVersion("parchmentMc").get().toString()
|
||||
|
||||
@@ -17,6 +17,8 @@ plugins {
|
||||
checkstyle
|
||||
id("com.diffplug.spotless")
|
||||
id("net.ltgt.errorprone")
|
||||
// Required for cross-project dependencies in Fabric
|
||||
id("net.fabricmc.fabric-loom-companion")
|
||||
}
|
||||
|
||||
val modVersion: String by extra
|
||||
@@ -28,9 +30,9 @@ version = modVersion
|
||||
base.archivesName.convention("cc-tweaked-$mcVersion-${project.name}")
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion= CCTweakedPlugin.JAVA_VERSION
|
||||
}
|
||||
toolchain { languageVersion = CCTweakedPlugin.JDK_VERSION }
|
||||
sourceCompatibility = CCTweakedPlugin.JAVA_VERSION
|
||||
targetCompatibility = CCTweakedPlugin.JAVA_VERSION
|
||||
|
||||
withSourcesJar()
|
||||
}
|
||||
@@ -79,20 +81,31 @@ dependencies {
|
||||
// Configure default JavaCompile tasks with our arguments.
|
||||
sourceSets.all {
|
||||
tasks.named(compileJavaTaskName, JavaCompile::class.java) {
|
||||
// Processing just gives us "No processor claimed any of these annotations", so skip that!
|
||||
options.compilerArgs.addAll(listOf("-Xlint", "-Xlint:-processing"))
|
||||
// Explicitly set release, as that limits the APIs we can use to the right version of Java.
|
||||
options.release = CCTweakedPlugin.JAVA_TARGET.asInt()
|
||||
|
||||
options.compilerArgs.addAll(
|
||||
listOf(
|
||||
"-Xlint",
|
||||
// Processing just gives us "No processor claimed any of these annotations", so skip that!
|
||||
"-Xlint:-processing",
|
||||
// We violate this pattern too often for it to be a helpful warning. Something to improve one day!
|
||||
"-Xlint:-this-escape",
|
||||
),
|
||||
)
|
||||
|
||||
options.errorprone {
|
||||
check("InvalidBlockTag", CheckSeverity.OFF) // Broken by @cc.xyz
|
||||
check("InvalidParam", CheckSeverity.OFF) // Broken by records.
|
||||
check("InlineMeSuggester", CheckSeverity.OFF) // Minecraft uses @Deprecated liberally
|
||||
// Too many false positives right now. Maybe we need an indirection for it later on.
|
||||
check("AssignmentExpression", CheckSeverity.OFF) // I'm a bad person.
|
||||
check("ReferenceEquality", CheckSeverity.OFF)
|
||||
check("EnumOrdinal", CheckSeverity.OFF) // For now. We could replace most of these with EnumMap.
|
||||
check("OperatorPrecedence", CheckSeverity.OFF) // For now.
|
||||
check("NonOverridingEquals", CheckSeverity.OFF) // Peripheral.equals makes this hard to avoid
|
||||
check("FutureReturnValueIgnored", CheckSeverity.OFF) // Too many false positives with Netty
|
||||
check("InvalidInlineTag", CheckSeverity.OFF) // Triggered by @snippet. Can be removed on Java 21.
|
||||
option("UnusedMethod:ExemptingMethodAnnotations", "dan200.computercraft.api.lua.LuaFunction")
|
||||
|
||||
check("NullAway", CheckSeverity.ERROR)
|
||||
option(
|
||||
@@ -115,7 +128,6 @@ tasks.compileTestJava {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tasks.withType(JavaCompile::class.java).configureEach {
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
@@ -149,7 +161,7 @@ tasks.javadoc {
|
||||
options {
|
||||
val stdOptions = this as StandardJavadocDocletOptions
|
||||
stdOptions.addBooleanOption("Xdoclint:all,-missing", true)
|
||||
stdOptions.links("https://docs.oracle.com/en/java/javase/17/docs/api/")
|
||||
stdOptions.links("https://docs.oracle.com/en/java/javase/21/docs/api/")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +176,7 @@ tasks.test {
|
||||
|
||||
tasks.withType(JacocoReport::class.java).configureEach {
|
||||
reports.xml.required = true
|
||||
reports.html.required =true
|
||||
reports.html.required = true
|
||||
}
|
||||
|
||||
project.plugins.withType(CCTweakedPlugin::class.java) {
|
||||
@@ -188,30 +200,23 @@ spotless {
|
||||
fun FormatExtension.defaults() {
|
||||
endWithNewline()
|
||||
trimTrailingWhitespace()
|
||||
indentWithSpaces(4)
|
||||
leadingTabsToSpaces(4)
|
||||
}
|
||||
|
||||
java {
|
||||
defaults()
|
||||
importOrder("", "javax|java", "\\#")
|
||||
removeUnusedImports()
|
||||
}
|
||||
|
||||
val ktlintConfig = mapOf(
|
||||
"ktlint_standard_no-wildcard-imports" to "disabled",
|
||||
"ktlint_standard_class-naming" to "disabled",
|
||||
"ktlint_standard_function-naming" to "disabled",
|
||||
"ij_kotlin_allow_trailing_comma" to "true",
|
||||
"ij_kotlin_allow_trailing_comma_on_call_site" to "true",
|
||||
)
|
||||
|
||||
kotlinGradle {
|
||||
defaults()
|
||||
ktlint().editorConfigOverride(ktlintConfig)
|
||||
ktlint()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
defaults()
|
||||
ktlint().editorConfigOverride(ktlintConfig)
|
||||
ktlint()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* See notes in [cc.tweaked.gradle.MinecraftConfigurations] for the general design behind these cursed ideas.
|
||||
*/
|
||||
|
||||
import cc.tweaked.gradle.CCTweakedPlugin
|
||||
import cc.tweaked.gradle.MinecraftConfigurations
|
||||
import cc.tweaked.gradle.clientClasses
|
||||
import cc.tweaked.gradle.commonClasses
|
||||
@@ -52,3 +53,5 @@ dependencies {
|
||||
|
||||
testImplementation(testFixtures(project))
|
||||
}
|
||||
|
||||
kotlin.compilerOptions.jvmTarget = CCTweakedPlugin.KOTLIN_TARGET
|
||||
|
||||
@@ -223,7 +223,7 @@ abstract class CCTweakedExtension(private val project: Project) {
|
||||
).resolve().single()
|
||||
}
|
||||
|
||||
private fun <T> gitProvider(default: T, command: List<String>, process: (String) -> T): Provider<T> {
|
||||
private fun <T: Any> gitProvider(default: T, command: List<String>, process: (String) -> T): Provider<T> {
|
||||
val baseResult = project.providers.exec {
|
||||
commandLine = listOf("git", "-C", project.rootDir.absolutePath) + command
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
package cc.tweaked.gradle
|
||||
|
||||
import org.gradle.api.JavaVersion
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.JavaPlugin
|
||||
@@ -13,6 +14,7 @@ import org.gradle.plugins.ide.idea.model.IdeaModel
|
||||
import org.jetbrains.gradle.ext.IdeaExtPlugin
|
||||
import org.jetbrains.gradle.ext.runConfigurations
|
||||
import org.jetbrains.gradle.ext.settings
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
|
||||
/**
|
||||
* Configures projects to match a shared configuration.
|
||||
@@ -42,6 +44,17 @@ class CCTweakedPlugin : Plugin<Project> {
|
||||
}
|
||||
|
||||
companion object {
|
||||
val JAVA_VERSION = JavaLanguageVersion.of(17)
|
||||
/**
|
||||
* The version we run with. We use Java 21 here, as our Gradle build requires that.
|
||||
*/
|
||||
val JDK_VERSION = JavaLanguageVersion.of(21)
|
||||
|
||||
/**
|
||||
* The Java version we target. Should be the same as what Minecraft uses.
|
||||
*/
|
||||
val JAVA_TARGET = JavaLanguageVersion.of(17)
|
||||
|
||||
val JAVA_VERSION = JavaVersion.toVersion(JAVA_TARGET.asInt())
|
||||
val KOTLIN_TARGET = JvmTarget.fromTarget(JAVA_TARGET.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,10 @@ abstract class DependencyCheck : DefaultTask() {
|
||||
overrides.putAll(project.provider { mutableMapOf(module.get().module.toString() to version) })
|
||||
}
|
||||
|
||||
fun override(group: String, module: String, version: String) {
|
||||
overrides.put("$group:$module", version)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a configuration to check.
|
||||
*/
|
||||
|
||||
@@ -5,10 +5,8 @@
|
||||
package cc.tweaked.gradle
|
||||
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.AbstractExecTask
|
||||
import org.gradle.api.tasks.OutputDirectory
|
||||
import java.io.File
|
||||
|
||||
abstract class ExecToDir : AbstractExecTask<ExecToDir>(ExecToDir::class.java) {
|
||||
@get:OutputDirectory
|
||||
|
||||
@@ -124,7 +124,7 @@ class CloseScope : AutoCloseable {
|
||||
}
|
||||
|
||||
/** Proxy method to avoid overload ambiguity. */
|
||||
fun <T> Property<T>.setProvider(provider: Provider<out T>) = set(provider)
|
||||
fun <T: Any> Property<T >.setProvider(provider: Provider<out T>) = set(provider)
|
||||
|
||||
/** Short-cut method to get the absolute path of a [FileSystemLocation] provider. */
|
||||
fun Provider<out FileSystemLocation>.getAbsolutePath(): String = get().asFile.absolutePath
|
||||
|
||||
@@ -25,7 +25,6 @@ import javax.xml.xpath.XPathFactory
|
||||
* Would be good to PR some (or all) of these changes upstream at some point.
|
||||
*
|
||||
* @see net.fabricmc.loom.configuration.ide.idea.IdeaSyncTask
|
||||
* @see net.minecraftforge.gradle.common.util.runs.IntellijRunGenerator
|
||||
*/
|
||||
internal class IdeaRunConfigurations(project: Project) {
|
||||
private val rootProject = project.rootProject
|
||||
@@ -35,22 +34,6 @@ internal class IdeaRunConfigurations(project: Project) {
|
||||
private val writer = TransformerFactory.newInstance().newTransformer()
|
||||
|
||||
private val ideaDir = rootProject.file(".idea/")
|
||||
private val buildDir: Lazy<String?> = lazy {
|
||||
val ideaMisc = ideaDir.resolve("misc.xml")
|
||||
|
||||
try {
|
||||
val doc = Files.newBufferedReader(ideaMisc.toPath()).use {
|
||||
documentBuilder.parse(InputSource(it))
|
||||
}
|
||||
val node =
|
||||
xpath.evaluate("//component[@name=\"ProjectRootManager\"]/output", doc, XPathConstants.NODE) as Node
|
||||
val attr = node.attributes.getNamedItem("url") as Attr
|
||||
attr.value.removePrefix("file://")
|
||||
} catch (e: Exception) {
|
||||
LOGGER.error("Failed to find root directory", e)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun patch() = synchronized(LOCK) {
|
||||
val runConfigDir = ideaDir.resolve("runConfigurations")
|
||||
@@ -58,10 +41,9 @@ internal class IdeaRunConfigurations(project: Project) {
|
||||
|
||||
Files.list(runConfigDir.toPath()).use {
|
||||
for (configuration in it) {
|
||||
val filename = configuration.fileName.toString();
|
||||
val filename = configuration.fileName.toString()
|
||||
when {
|
||||
filename.endsWith("_fabric.xml") -> patchFabric(configuration)
|
||||
filename.startsWith("forge_") && filename.endsWith(".xml") -> patchForge(configuration)
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
@@ -72,65 +54,6 @@ internal class IdeaRunConfigurations(project: Project) {
|
||||
setXml("//configuration", "folderName") { "Fabric" }
|
||||
}
|
||||
|
||||
private fun patchForge(path: Path) = withXml(path) {
|
||||
val configId = path.fileName.toString().removePrefix("forge_").removeSuffix(".xml")
|
||||
val sourceSet = forgeConfigs[configId]
|
||||
if (sourceSet == null) {
|
||||
LOGGER.error("[{}] Cannot map run configuration to a known source set", path)
|
||||
return@withXml
|
||||
}
|
||||
|
||||
setXml("//configuration", "folderName") { "Forge" }
|
||||
setXml("//configuration/module", "name") { "${rootProject.name}.forge.$sourceSet" }
|
||||
|
||||
if (buildDir.value == null) return@withXml
|
||||
setXml("//configuration/envs/env[@name=\"MOD_CLASSES\"]", "value") { classpath ->
|
||||
val classes = classpath!!.split(':')
|
||||
val newClasses = mutableListOf<String>()
|
||||
fun appendUnique(x: String) {
|
||||
if (!newClasses.contains(x)) newClasses.add(x)
|
||||
}
|
||||
|
||||
for (entry in classes) {
|
||||
if (!entry.contains("/out/")) {
|
||||
appendUnique(entry)
|
||||
continue
|
||||
}
|
||||
|
||||
val match = CLASSPATH_ENTRY.matchEntire(entry)
|
||||
if (match != null) {
|
||||
val modId = match.groups["modId"]!!.value
|
||||
val proj = match.groups["proj"]!!.value
|
||||
var component = match.groups["component"]!!.value
|
||||
if (component == "production") component = "main"
|
||||
|
||||
appendUnique(forgeModEntry(modId, proj, component))
|
||||
} else {
|
||||
LOGGER.warn("[{}] Unknown classpath entry {}", path, entry)
|
||||
appendUnique(entry)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure common code is on the classpath
|
||||
for (proj in listOf("common", "common-api")) {
|
||||
for (component in listOf("main", "client")) {
|
||||
appendUnique(forgeModEntry("computercraft", proj, component))
|
||||
}
|
||||
}
|
||||
|
||||
if (newClasses.any { it.startsWith("cctest%%") }) {
|
||||
appendUnique(forgeModEntry("cctest", "core", "testFixtures"))
|
||||
appendUnique(forgeModEntry("cctest", "common", "testFixtures"))
|
||||
appendUnique(forgeModEntry("cctest", "common", "testMod"))
|
||||
}
|
||||
|
||||
newClasses.joinToString(":")
|
||||
}
|
||||
}
|
||||
|
||||
private fun forgeModEntry(mod: String, project: String, component: String) =
|
||||
"$mod%%${buildDir.value}/production/${rootProject.name}.$project.$component"
|
||||
|
||||
private fun LocatedDocument.setXml(xpath: String, attribute: String, value: (String?) -> String) {
|
||||
val node = this@IdeaRunConfigurations.xpath.evaluate(xpath, document, XPathConstants.NODE) as Node?
|
||||
if (node == null) {
|
||||
@@ -159,16 +82,5 @@ internal class IdeaRunConfigurations(project: Project) {
|
||||
companion object {
|
||||
private val LOGGER = Logging.getLogger(IdeaRunConfigurations::class.java)
|
||||
private val LOCK = Any()
|
||||
|
||||
private val CLASSPATH_ENTRY =
|
||||
Regex("(?<modId>[a-z]+)%%\\\$PROJECT_DIR\\\$/projects/(?<proj>[a-z-]+)/out/(?<component>\\w+)/(?<type>[a-z]+)\$")
|
||||
|
||||
private val forgeConfigs = mapOf(
|
||||
"runClient" to "client",
|
||||
"runData" to "main",
|
||||
"runGameTestServer" to "testMod",
|
||||
"runServer" to "main",
|
||||
"runTestClient" to "testMod",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ class MinecraftConfigurations private constructor(private val project: Project)
|
||||
|
||||
// Set up an API configuration for clients (to ensure it's consistent with the main source set).
|
||||
val clientApi = configurations.maybeCreate(client.apiConfigurationName).apply {
|
||||
isVisible = false
|
||||
isCanBeConsumed = false
|
||||
isCanBeResolved = false
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package cc.tweaked.gradle
|
||||
|
||||
import groovy.util.Node
|
||||
import groovy.util.NodeList
|
||||
|
||||
object XmlUtil {
|
||||
fun findChild(node: Node, name: String): Node? = when (val child = node.get(name)) {
|
||||
is Node -> child
|
||||
is NodeList -> child.singleOrNull() as Node?
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,10 @@ SPDX-License-Identifier: MPL-2.0
|
||||
<module name="InvalidJavadocPosition" />
|
||||
<module name="JavadocBlockTagLocation" />
|
||||
<module name="JavadocMethod"/>
|
||||
<module name="JavadocType"/>
|
||||
<module name="JavadocType">
|
||||
<!-- Seems to complain about @hidden!? -->
|
||||
<property name="allowUnknownTags" value="true" />
|
||||
</module>
|
||||
<module name="JavadocStyle">
|
||||
<property name="checkHtml" value="false" />
|
||||
</module>
|
||||
@@ -143,7 +146,10 @@ SPDX-License-Identifier: MPL-2.0
|
||||
<module name="NoWhitespaceAfter">
|
||||
<property name="tokens" value="AT,INC,DEC,UNARY_MINUS,UNARY_PLUS,BNOT,LNOT,DOT,ARRAY_DECLARATOR,INDEX_OP,METHOD_REF" />
|
||||
</module>
|
||||
<module name="NoWhitespaceBefore" />
|
||||
<module name="NoWhitespaceBefore">
|
||||
<!-- Allow whitespace before "..." for @Nullable annotations -->
|
||||
<property name="tokens" value="COMMA,SEMI,POST_INC,POST_DEC,LABELED_STAT" />
|
||||
</module>
|
||||
<!-- TODO: Decide on an OperatorWrap style. -->
|
||||
<module name="ParenPad" />
|
||||
<module name="SeparatorWrap">
|
||||
|
||||
@@ -12,6 +12,7 @@ files:
|
||||
de: de_de # German
|
||||
es-ES: es_es # Spanish
|
||||
fr: fr_fr # French
|
||||
hu: hu_hu # Hungarian
|
||||
it: it_it # Italian
|
||||
ja: ja_jp # Japanese
|
||||
ko: ko_kr # Korean
|
||||
|
||||
@@ -10,7 +10,7 @@ kotlin.jvm.target.validation.mode=error
|
||||
|
||||
# Mod properties
|
||||
isUnstable=false
|
||||
modVersion=1.115.0
|
||||
modVersion=1.116.2
|
||||
|
||||
# Minecraft properties: We want to configure this here so we can read it in settings.gradle
|
||||
mcVersion=1.20.1
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
#This file is generated by updateDaemonJvm
|
||||
toolchainVersion=17
|
||||
toolchainVersion=21
|
||||
|
||||
@@ -23,17 +23,17 @@ netty = "4.1.82.Final"
|
||||
slf4j = "2.0.1"
|
||||
|
||||
# Core dependencies (independent of Minecraft)
|
||||
asm = "9.6"
|
||||
asm = "9.9"
|
||||
autoService = "1.1.1"
|
||||
checkerFramework = "3.42.0"
|
||||
cobalt = { strictly = "0.9.5" }
|
||||
commonsCli = "1.6.0"
|
||||
jetbrainsAnnotations = "24.1.0"
|
||||
jsr305 = "3.0.2"
|
||||
checkerFramework = "3.51.1"
|
||||
cobalt = { strictly = "0.9.7" }
|
||||
commonsCli = "1.10.0"
|
||||
jetbrainsAnnotations = "26.0.2-1"
|
||||
jspecify = "1.0.0"
|
||||
jzlib = "1.1.3"
|
||||
kotlin = "2.1.0"
|
||||
kotlin-coroutines = "1.10.1"
|
||||
nightConfig = "3.8.1"
|
||||
kotlin = "2.2.21"
|
||||
kotlin-coroutines = "1.10.2"
|
||||
nightConfig = "3.8.3"
|
||||
|
||||
# Minecraft mods
|
||||
emi = "1.0.8+1.20.1"
|
||||
@@ -46,36 +46,35 @@ oculus = "1.2.5"
|
||||
rei = "12.0.626"
|
||||
rubidium = "0.6.1"
|
||||
sodium = "mc1.20-0.4.10"
|
||||
create-forge = "0.5.1.f-33"
|
||||
create-fabric = "0.5.1-f-build.1467+mc1.20.1"
|
||||
create-forge = "6.0.0-9"
|
||||
create-fabric = "6.0.7.0+mc1.20.1-build.1716"
|
||||
|
||||
# Testing
|
||||
hamcrest = "2.2"
|
||||
jqwik = "1.8.2"
|
||||
junit = "5.11.4"
|
||||
junitPlatform = "1.11.4"
|
||||
hamcrest = "3.0"
|
||||
jqwik = "1.9.3"
|
||||
junit = "6.0.1"
|
||||
junitPlatform = "6.0.1"
|
||||
jmh = "1.37"
|
||||
|
||||
# Build tools
|
||||
cctJavadoc = "1.8.3"
|
||||
checkstyle = "10.14.1"
|
||||
errorProne-core = "2.27.0"
|
||||
errorProne-plugin = "3.1.0"
|
||||
fabric-loom = "1.9.2"
|
||||
cctJavadoc = "1.8.4"
|
||||
checkstyle = "12.1.1"
|
||||
errorProne-core = "2.43.0"
|
||||
errorProne-plugin = "4.3.0"
|
||||
fabric-loom = "1.12.3"
|
||||
githubRelease = "2.5.2"
|
||||
gradleVersions = "0.50.0"
|
||||
ideaExt = "1.1.7"
|
||||
illuaminate = "0.1.0-74-gf1551d5"
|
||||
lwjgl = "3.3.3"
|
||||
gradleVersions = "0.53.0"
|
||||
ideaExt = "1.3"
|
||||
illuaminate = "0.1.0-83-g1131f68"
|
||||
lwjgl = "3.3.6"
|
||||
minotaur = "2.8.7"
|
||||
modDevGradle = "2.0.74"
|
||||
nullAway = "0.10.25"
|
||||
shadow = "8.3.1"
|
||||
spotless = "6.23.3"
|
||||
taskTree = "2.1.1"
|
||||
teavm = "0.11.0-SQUID.1"
|
||||
vanillaExtract = "0.2.0"
|
||||
versionCatalogUpdate = "0.8.1"
|
||||
modDevGradle = "2.0.116"
|
||||
nullAway = "0.12.11"
|
||||
shadow = "9.2.2"
|
||||
spotless = "8.0.0"
|
||||
teavm = "0.13.0-SQUID.2"
|
||||
vanillaExtract = "0.2.1"
|
||||
versionCatalogUpdate = "1.0.1"
|
||||
|
||||
[libraries]
|
||||
# Normal dependencies
|
||||
@@ -89,7 +88,7 @@ fastutil = { module = "it.unimi.dsi:fastutil", version.ref = "fastutil" }
|
||||
forgeSpi = { module = "net.minecraftforge:forgespi", version.ref = "forgeSpi" }
|
||||
guava = { module = "com.google.guava:guava", version.ref = "guava" }
|
||||
jetbrainsAnnotations = { module = "org.jetbrains:annotations", version.ref = "jetbrainsAnnotations" }
|
||||
jsr305 = { module = "com.google.code.findbugs:jsr305", version.ref = "jsr305" }
|
||||
jspecify = { module = "org.jspecify:jspecify", version.ref = "jspecify" }
|
||||
jzlib = { module = "com.jcraft:jzlib", version.ref = "jzlib" }
|
||||
kotlin-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlin-coroutines" }
|
||||
kotlin-platform = { module = "org.jetbrains.kotlin:kotlin-bom", version.ref = "kotlin" }
|
||||
@@ -174,11 +173,10 @@ githubRelease = { id = "com.github.breadmoirai.github-release", version.ref = "g
|
||||
gradleVersions = { id = "com.github.ben-manes.versions", version.ref = "gradleVersions" }
|
||||
kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
|
||||
shadow = { id = "com.gradleup.shadow", version.ref = "shadow" }
|
||||
taskTree = { id = "com.dorongold.task-tree", version.ref = "taskTree" }
|
||||
versionCatalogUpdate = { id = "nl.littlerobots.version-catalog-update", version.ref = "versionCatalogUpdate" }
|
||||
|
||||
[bundles]
|
||||
annotations = ["jsr305", "checkerFramework", "jetbrainsAnnotations"]
|
||||
annotations = ["checkerFramework", "jetbrainsAnnotations", "jspecify"]
|
||||
kotlin = ["kotlin-stdlib", "kotlin-coroutines"]
|
||||
|
||||
# Minecraft
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
1064
package-lock.json
generated
1064
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -12,11 +12,11 @@
|
||||
"tslib": "^2.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-node-resolve": "^15.2.1",
|
||||
"@rollup/plugin-node-resolve": "^16.0.0",
|
||||
"@rollup/plugin-typescript": "^12.0.0",
|
||||
"@rollup/plugin-url": "^8.0.1",
|
||||
"@swc/core": "^1.3.92",
|
||||
"@types/node": "^22.0.0",
|
||||
"@types/node": "^24.0.0",
|
||||
"lightningcss": "^1.22.0",
|
||||
"preact-render-to-string": "^6.2.1",
|
||||
"rehype": "^13.0.0",
|
||||
|
||||
@@ -63,16 +63,25 @@ tasks.javadoc {
|
||||
""".trimIndent(),
|
||||
)
|
||||
|
||||
taglets("cc.tweaked.javadoc.SnippetTaglet")
|
||||
tagletPath(configurations.detachedConfiguration(dependencies.project(":lints")).toList())
|
||||
|
||||
val snippetSources = listOf(":common", ":fabric", ":forge").flatMap {
|
||||
project(it).sourceSets["examples"].allSource.sourceDirectories
|
||||
}
|
||||
inputs.files(snippetSources)
|
||||
jFlags("-Dcc.snippet-path=" + snippetSources.joinToString(File.pathSeparator) { it.absolutePath })
|
||||
addPathOption("-snippet-path").value = snippetSources
|
||||
}
|
||||
|
||||
// Include the core-api in our javadoc export. This is wrong, but it means we can export a single javadoc dump.
|
||||
source(project(":core-api").sourceSets.main.map { it.allJava })
|
||||
|
||||
options {
|
||||
this as StandardJavadocDocletOptions
|
||||
addBooleanOption("-allow-script-in-comments", true)
|
||||
bottom(
|
||||
"""
|
||||
<script src="https://cdn.jsdelivr.net/npm/prismjs@v1.29.0/components/prism-core.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/prismjs@v1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
|
||||
<link href=" https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.min.css " rel="stylesheet">
|
||||
""".trimIndent(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@ import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -14,8 +14,7 @@ import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
final class TurtleUpgradeModellers {
|
||||
private static final Transformation leftTransform = getMatrixFor(-0.4065f);
|
||||
|
||||
@@ -11,8 +11,7 @@ import net.minecraft.client.resources.model.ModelManager;
|
||||
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public interface ClientPlatformHelper {
|
||||
|
||||
@@ -10,8 +10,7 @@ import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser;
|
||||
import dan200.computercraft.impl.Services;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Backing interface for {@link ComputerCraftAPIClient}
|
||||
|
||||
@@ -26,8 +26,7 @@ import net.minecraft.core.Direction;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* The static entry point to the ComputerCraft API.
|
||||
|
||||
@@ -26,6 +26,20 @@ public class ComputerCraftTags {
|
||||
public static final TagKey<Item> WIRED_MODEM = make("wired_modem");
|
||||
public static final TagKey<Item> MONITOR = make("monitor");
|
||||
|
||||
/**
|
||||
* Floppy disks. Both the read/write version, and treasure disks.
|
||||
*
|
||||
* @since 1.116.0
|
||||
*/
|
||||
public static final TagKey<Item> DISKS = make("disks");
|
||||
|
||||
/**
|
||||
* All pocket computers.
|
||||
*
|
||||
* @since 1.116.0
|
||||
*/
|
||||
public static final TagKey<Item> POCKET_COMPUTERS = make("pocket_computers");
|
||||
|
||||
/**
|
||||
* Items which can be {@linkplain Item#use(Level, Player, InteractionHand) used} when calling
|
||||
* {@code turtle.place()}.
|
||||
|
||||
@@ -6,8 +6,8 @@ package dan200.computercraft.api.detail;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -8,8 +8,7 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A reference to a block in the world, used by block detail providers.
|
||||
|
||||
@@ -14,6 +14,7 @@ import java.util.Map;
|
||||
*
|
||||
* @param <T> The type of object that this provider can provide details for.
|
||||
* @see DetailRegistry
|
||||
* @see dan200.computercraft.api.detail An overview of the detail system.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface DetailProvider<T> {
|
||||
|
||||
@@ -17,6 +17,7 @@ import java.util.Map;
|
||||
* also in this package.
|
||||
*
|
||||
* @param <T> The type of object that this registry provides details for.
|
||||
* @see dan200.computercraft.api.detail An overview of the detail system.
|
||||
*/
|
||||
@ApiStatus.NonExtendable
|
||||
public interface DetailRegistry<T> {
|
||||
|
||||
@@ -17,6 +17,9 @@ public class VanillaDetailRegistries {
|
||||
* <p>
|
||||
* This instance's {@link DetailRegistry#getBasicDetails(Object)} is thread safe (assuming the stack is immutable)
|
||||
* and may be called from the computer thread.
|
||||
* <p>
|
||||
* This does not have special handling for {@linkplain ItemStack#isEmpty() empty item stacks}, and so the returned
|
||||
* details will be an empty stack of air. Callers should generally check for empty stacks before calling this.
|
||||
*/
|
||||
public static final DetailRegistry<ItemStack> ITEM_STACK = ComputerCraftAPIService.get().getItemStackDetailRegistry();
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
// SPDX-FileCopyrightText: 2025 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
/**
|
||||
* The detail system provides a standard way for mods to return descriptions of common game objects, such as blocks or
|
||||
* items, as well as registering additional detail to be included in those descriptions.
|
||||
* <p>
|
||||
* For instance, the built-in {@code turtle.getItemDetail()} method uses
|
||||
* {@linkplain dan200.computercraft.api.detail.VanillaDetailRegistries#ITEM_STACK in order to provide information about}
|
||||
* the selected item:
|
||||
*
|
||||
* <pre class="language language-lua">{@code
|
||||
* local item = turtle.getItemDetail(nil, true)
|
||||
* --[[
|
||||
* item = {
|
||||
* name = "minecraft:wheat",
|
||||
* displayName = "Wheat",
|
||||
* count = 1,
|
||||
* maxCount = 64,
|
||||
* tags = {},
|
||||
* }
|
||||
* ]]
|
||||
* }</pre>
|
||||
*
|
||||
* <h2>Built-in detail providers</h2>
|
||||
* While you can define your own detail providers (perhaps for types from your own mod), CC comes with several built-in
|
||||
* detail registries for vanilla and mod-loader objects:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link dan200.computercraft.api.detail.VanillaDetailRegistries}, for vanilla objects</li>
|
||||
* <li>{@code dan200.computercraft.api.detail.ForgeDetailRegistries} for Forge-specific objects</li>
|
||||
* <li>{@code dan200.computercraft.api.detail.FabricDetailRegistries} for Fabric-specific objects</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h2>Example: Returning details from methods</h2>
|
||||
* Here we define a {@code getHeldItem()} method for pocket computers which finds the currently held item of the player
|
||||
* and returns it to the user using {@link dan200.computercraft.api.detail.VanillaDetailRegistries#ITEM_STACK} and
|
||||
* {@link dan200.computercraft.api.detail.DetailRegistry#getDetails(java.lang.Object)}.
|
||||
*
|
||||
* {@snippet class=com.example.examplemod.ExamplePocketPeripheral region=details}
|
||||
*
|
||||
* <h2>Example: Registering custom detail registries</h2>
|
||||
* Here we define a new detail provider for items that includes the nutrition and saturation values in the returned object.
|
||||
*
|
||||
* {@snippet class=com.example.examplemod.ExampleMod region=details}
|
||||
*/
|
||||
package dan200.computercraft.api.detail;
|
||||
@@ -9,8 +9,7 @@ import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* An interface passed to {@link ILuaAPIFactory} in order to provide additional information
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
package dan200.computercraft.api.lua;
|
||||
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Construct an {@link ILuaAPI} for a computer.
|
||||
|
||||
@@ -12,8 +12,7 @@ import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Represents an item that can be placed in a disk drive and used by a Computer.
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
package dan200.computercraft.api.media;
|
||||
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* This interface is used to provide {@link IMedia} implementations for {@link ItemStack}.
|
||||
|
||||
@@ -6,8 +6,8 @@ package dan200.computercraft.api.media;
|
||||
|
||||
import dan200.computercraft.impl.ComputerCraftAPIService;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,8 +14,8 @@ import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,8 +7,7 @@ package dan200.computercraft.api.pocket;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.api.upgrades.UpgradeBase;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A peripheral which can be equipped to the back side of a pocket computer.
|
||||
|
||||
@@ -17,8 +17,7 @@ import net.minecraft.world.Container;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* The interface passed to turtle by turtles, providing methods that they can call.
|
||||
|
||||
@@ -9,8 +9,8 @@ import dan200.computercraft.api.upgrades.UpgradeBase;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.item.Items;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
/**
|
||||
@@ -27,7 +27,7 @@ import java.util.function.BiFunction;
|
||||
* <h3>Registering the upgrade serialiser</h3>
|
||||
* First, let's create a new class that implements {@link ITurtleUpgrade}. It is recommended to subclass
|
||||
* {@link AbstractTurtleUpgrade}, as that provides a default implementation of most methods.
|
||||
* <p>
|
||||
*
|
||||
* {@snippet class=com.example.examplemod.ExampleTurtleUpgrade region=body}
|
||||
* <p>
|
||||
* Now we must construct a new upgrade serialiser. In most cases, you can use one of the helper methods
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
package dan200.computercraft.api.turtle;
|
||||
|
||||
import net.minecraft.core.Direction;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Used to indicate the result of executing a turtle command.
|
||||
@@ -60,9 +59,9 @@ public final class TurtleCommandResult {
|
||||
|
||||
private final boolean success;
|
||||
private final @Nullable String errorMessage;
|
||||
private final @Nullable Object[] results;
|
||||
private final @Nullable Object @Nullable [] results;
|
||||
|
||||
private TurtleCommandResult(boolean success, @Nullable String errorMessage, @Nullable Object[] results) {
|
||||
private TurtleCommandResult(boolean success, @Nullable String errorMessage, @Nullable Object @Nullable [] results) {
|
||||
this.success = success;
|
||||
this.errorMessage = errorMessage;
|
||||
this.results = results;
|
||||
@@ -92,8 +91,7 @@ public final class TurtleCommandResult {
|
||||
*
|
||||
* @return The command's result, or {@code null} if it was a failure.
|
||||
*/
|
||||
@Nullable
|
||||
public Object[] getResults() {
|
||||
public @Nullable Object @Nullable [] getResults() {
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,8 +9,7 @@ import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* An upgrade (i.e. a {@link ITurtleUpgrade}) and its current upgrade data.
|
||||
|
||||
@@ -19,8 +19,8 @@ import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.Item;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@@ -28,8 +28,7 @@ import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Backing interface for {@link ComputerCraftAPI}
|
||||
|
||||
@@ -12,8 +12,7 @@ import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Abstraction layer for Forge and Fabric. See implementations for more details.
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
package dan200.computercraft.impl;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
package dan200.computercraft.impl;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ dependencies {
|
||||
clientApi(clientClasses(project(":common-api")))
|
||||
|
||||
compileOnly(libs.bundles.externalMods.common)
|
||||
compileOnly(variantOf(libs.create.forge) { classifier("slim") }) { isTransitive = false }
|
||||
clientCompileOnly(variantOf(libs.emi) { classifier("api") })
|
||||
|
||||
annotationProcessorEverywhere(libs.autoService)
|
||||
@@ -82,7 +81,7 @@ val luaJavadoc by tasks.registering(Javadoc::class) {
|
||||
options.addStringOption("project-root", rootProject.file(".").absolutePath)
|
||||
options.noTimestamp(false)
|
||||
|
||||
javadocTool = javaToolchains.javadocToolFor { languageVersion = CCTweakedPlugin.JAVA_VERSION }
|
||||
javadocTool = javaToolchains.javadocToolFor { languageVersion = CCTweakedPlugin.JDK_VERSION }
|
||||
}
|
||||
|
||||
val lintLua by tasks.registering(IlluaminateExec::class) {
|
||||
|
||||
@@ -38,8 +38,8 @@ import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
|
||||
@@ -46,8 +46,10 @@ import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.function.BiConsumer;
|
||||
@@ -63,6 +65,8 @@ import java.util.function.Supplier;
|
||||
* @see ModRegistry The common registry for actual game objects.
|
||||
*/
|
||||
public final class ClientRegistry {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ClientRegistry.class);
|
||||
|
||||
private ClientRegistry() {
|
||||
}
|
||||
|
||||
@@ -182,7 +186,18 @@ public final class ClientRegistry {
|
||||
}
|
||||
|
||||
public static void registerShaders(ResourceProvider resources, BiConsumer<ShaderInstance, Consumer<ShaderInstance>> load) throws IOException {
|
||||
RenderTypes.registerShaders(resources, load);
|
||||
RenderTypes.registerShaders(resources, (name, create, onLoaded) -> {
|
||||
ShaderInstance shader;
|
||||
try {
|
||||
shader = create.get();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to load {}", name, e);
|
||||
onLoaded.accept(null);
|
||||
return;
|
||||
}
|
||||
|
||||
load.accept(shader, onLoaded);
|
||||
});
|
||||
}
|
||||
|
||||
private record UnclampedPropertyFunction(
|
||||
|
||||
@@ -15,8 +15,8 @@ import net.minecraft.client.gui.components.ChatComponent;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.Mth;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,11 +26,11 @@ import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.file.Files;
|
||||
|
||||
@@ -11,8 +11,8 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.client.resources.TextureAtlasHolder;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// SPDX-FileCopyrightText: 2025 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.client.gui;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
/**
|
||||
* Supports for converting/translating key codes.
|
||||
*/
|
||||
public class KeyConverter {
|
||||
/**
|
||||
* GLFW's key events refer to the physical key code, rather than the "actual" key code (with keyboard layout
|
||||
* applied).
|
||||
* <p>
|
||||
* This makes sense for WASD-style input, but is a right pain for keyboard shortcuts — this function attempts to
|
||||
* translate those keys back to their "actual" key code. See also
|
||||
* <a href="https://github.com/glfw/glfw/issues/1502"> this discussion on GLFW's GitHub.</a>
|
||||
*
|
||||
* @param key The current key code.
|
||||
* @param scanCode The current scan code.
|
||||
* @return The translated key code.
|
||||
*/
|
||||
public static int physicalToActual(int key, int scanCode) {
|
||||
var name = GLFW.glfwGetKeyName(key, scanCode);
|
||||
if (name == null || name.length() != 1) return key;
|
||||
|
||||
// If we've got a single character as the key name, treat that as the ASCII value of the key,
|
||||
// and map that back to a key code.
|
||||
var character = name.charAt(0);
|
||||
|
||||
// 0-9 and A-Z map directly to their GLFW key (they're the same ASCII code).
|
||||
if ((character >= '0' && character <= '9') || (character >= 'A' && character <= 'Z')) return character;
|
||||
// a-z map to GLFW_KEY_{A,Z}
|
||||
if (character >= 'a' && character <= 'z') return GLFW.GLFW_KEY_A + (character - 'a');
|
||||
|
||||
return key;
|
||||
}
|
||||
}
|
||||
@@ -15,9 +15,9 @@ import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.inventory.MenuAccess;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Objects;
|
||||
|
||||
import static dan200.computercraft.core.util.Nullability.assertNonNull;
|
||||
|
||||
@@ -12,8 +12,8 @@ import net.minecraft.client.gui.components.MultiLineLabel;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
import static dan200.computercraft.core.util.Nullability.assertNonNull;
|
||||
|
||||
@@ -149,6 +149,7 @@ public final class PrintoutScreen extends AbstractContainerScreen<PrintoutMenu>
|
||||
// Skip rendering labels.
|
||||
}
|
||||
|
||||
@SuppressWarnings("ArrayRecordComponent")
|
||||
record PrintoutInfo(int pages, boolean book, TextBuffer[] text, TextBuffer[] colour) {
|
||||
public static final PrintoutInfo DEFAULT;
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.Tooltip;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
package dan200.computercraft.client.gui.widgets;
|
||||
|
||||
import com.mojang.blaze3d.vertex.Tesselator;
|
||||
import dan200.computercraft.client.gui.KeyConverter;
|
||||
import dan200.computercraft.client.render.RenderTypes;
|
||||
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
|
||||
import dan200.computercraft.core.terminal.Terminal;
|
||||
@@ -85,7 +86,7 @@ public class TerminalWidget extends AbstractWidget {
|
||||
}
|
||||
|
||||
if ((modifiers & GLFW.GLFW_MOD_CONTROL) != 0) {
|
||||
switch (key) {
|
||||
switch (KeyConverter.physicalToActual(key, scancode)) {
|
||||
case GLFW.GLFW_KEY_T -> {
|
||||
if (terminateTimer < 0) terminateTimer = 0;
|
||||
}
|
||||
@@ -121,7 +122,7 @@ public class TerminalWidget extends AbstractWidget {
|
||||
computer.keyUp(key);
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
switch (KeyConverter.physicalToActual(key, scancode)) {
|
||||
case GLFW.GLFW_KEY_T -> terminateTimer = -1;
|
||||
case GLFW.GLFW_KEY_R -> rebootTimer = -1;
|
||||
case GLFW.GLFW_KEY_S -> shutdownTimer = -1;
|
||||
|
||||
@@ -22,6 +22,7 @@ import net.minecraft.client.resources.model.Material;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.FastColor;
|
||||
import net.minecraft.world.inventory.InventoryMenu;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
/**
|
||||
* A model for {@linkplain PocketComputerItem pocket computers} placed on a lectern.
|
||||
@@ -46,8 +47,8 @@ public class LecternPocketModel {
|
||||
public static final float TERM_HEIGHT = 14.0f / 32.0f;
|
||||
|
||||
// The size of the texture. The texture is 36x36, but is at 2x resolution.
|
||||
private static final int TEXTURE_WIDTH = 36 / 2;
|
||||
private static final int TEXTURE_HEIGHT = 36 / 2;
|
||||
private static final int TEXTURE_WIDTH = 48 / 2;
|
||||
private static final int TEXTURE_HEIGHT = 48 / 2;
|
||||
|
||||
private final ModelPart root;
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.Direction;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector4f;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -26,8 +26,8 @@ import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,8 +13,7 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ServerGamePacketListener;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public interface ClientPlatformHelper extends dan200.computercraft.impl.client.ClientPlatformHelper {
|
||||
static ClientPlatformHelper get() {
|
||||
@@ -39,7 +38,7 @@ public interface ClientPlatformHelper extends dan200.computercraft.impl.client.C
|
||||
* @param overlayLight The current overlay light.
|
||||
* @param tints Block colour tints to apply to the model.
|
||||
*/
|
||||
void renderBakedModel(PoseStack transform, MultiBufferSource buffers, BakedModel model, int lightmapCoord, int overlayLight, @Nullable int[] tints);
|
||||
void renderBakedModel(PoseStack transform, MultiBufferSource buffers, BakedModel model, int lightmapCoord, int overlayLight, int @Nullable [] tints);
|
||||
|
||||
/**
|
||||
* Play a record at a particular position.
|
||||
|
||||
@@ -10,8 +10,8 @@ import dan200.computercraft.shared.computer.terminal.TerminalState;
|
||||
import dan200.computercraft.shared.network.client.PocketComputerDataMessage;
|
||||
import dan200.computercraft.shared.pocket.items.PocketComputerItem;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -8,8 +8,7 @@ import dan200.computercraft.shared.computer.core.ComputerState;
|
||||
import dan200.computercraft.shared.computer.terminal.NetworkedTerminal;
|
||||
import dan200.computercraft.shared.computer.terminal.TerminalState;
|
||||
import dan200.computercraft.shared.pocket.core.PocketServerComputer;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Clientside data about a pocket computer.
|
||||
|
||||
@@ -12,6 +12,7 @@ import dan200.computercraft.client.pocket.ClientPocketComputers;
|
||||
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
|
||||
import dan200.computercraft.core.terminal.Terminal;
|
||||
import dan200.computercraft.core.util.Colour;
|
||||
import dan200.computercraft.shared.ModRegistry;
|
||||
import dan200.computercraft.shared.lectern.CustomLecternBlockEntity;
|
||||
import dan200.computercraft.shared.media.items.PrintoutItem;
|
||||
import dan200.computercraft.shared.pocket.items.PocketComputerItem;
|
||||
@@ -57,9 +58,9 @@ public class CustomLecternRenderer implements BlockEntityRenderer<CustomLecternB
|
||||
poseStack.translate(0, -0.125f, 0);
|
||||
|
||||
var item = lectern.getItem();
|
||||
if (item.getItem() instanceof PrintoutItem printout) {
|
||||
if (item.getItem() instanceof PrintoutItem) {
|
||||
var vertexConsumer = LecternPrintoutModel.MATERIAL.buffer(buffer, RenderType::entitySolid);
|
||||
if (printout.getType() == PrintoutItem.Type.BOOK) {
|
||||
if (item.is(ModRegistry.Items.PRINTED_BOOK.get())) {
|
||||
printoutModel.renderBook(poseStack, vertexConsumer, packedLight, packedOverlay);
|
||||
} else {
|
||||
printoutModel.renderPages(poseStack, vertexConsumer, packedLight, packedOverlay, PrintoutItem.getPageCount(item));
|
||||
|
||||
@@ -14,8 +14,8 @@ import net.minecraft.client.renderer.entity.ItemRenderer;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.joml.Vector4f;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -39,7 +39,7 @@ public final class ModelRenderer {
|
||||
* @param overlayLight The current overlay light.
|
||||
* @param tints Block colour tints to apply to the model.
|
||||
*/
|
||||
public static void renderQuads(PoseStack transform, VertexConsumer buffer, List<BakedQuad> quads, int lightmapCoord, int overlayLight, @Nullable int[] tints) {
|
||||
public static void renderQuads(PoseStack transform, VertexConsumer buffer, List<BakedQuad> quads, int lightmapCoord, int overlayLight, int @Nullable [] tints) {
|
||||
var matrix = transform.last();
|
||||
var inverted = matrix.pose().determinant() < 0;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ package dan200.computercraft.client.render;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Axis;
|
||||
import dan200.computercraft.shared.ModRegistry;
|
||||
import dan200.computercraft.shared.media.items.PrintoutItem;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
@@ -51,7 +52,7 @@ public final class PrintoutItemRenderer extends ItemMapLikeRenderer {
|
||||
|
||||
private static void drawPrintout(PoseStack transform, MultiBufferSource render, ItemStack stack, int light) {
|
||||
var pages = PrintoutItem.getPageCount(stack);
|
||||
var book = ((PrintoutItem) stack.getItem()).getType() == PrintoutItem.Type.BOOK;
|
||||
var book = stack.is(ModRegistry.Items.PRINTED_BOOK.get());
|
||||
|
||||
double width = LINE_MAX_LENGTH * FONT_WIDTH + X_TEXT_MARGIN * 2;
|
||||
double height = LINES_PER_PAGE * FONT_HEIGHT + Y_TEXT_MARGIN * 2;
|
||||
|
||||
@@ -16,11 +16,11 @@ import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.ShaderInstance;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.ResourceProvider;
|
||||
import org.apache.commons.io.function.IOSupplier;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
@@ -68,9 +68,12 @@ public class RenderTypes {
|
||||
return Objects.requireNonNull(GameRenderer.getRendertypeTextShader(), "Text shader has not been registered");
|
||||
}
|
||||
|
||||
public static void registerShaders(ResourceProvider resources, BiConsumer<ShaderInstance, Consumer<ShaderInstance>> load) throws IOException {
|
||||
load.accept(
|
||||
new MonitorTextureBufferShader(
|
||||
public interface ShaderLoader {
|
||||
void tryLoad(String name, IOSupplier<ShaderInstance> create, Consumer<@Nullable ShaderInstance> accept) throws IOException;
|
||||
}
|
||||
|
||||
public static void registerShaders(ResourceProvider resources, ShaderLoader load) throws IOException {
|
||||
load.tryLoad("monitor shader", () -> new MonitorTextureBufferShader(
|
||||
resources,
|
||||
ComputerCraftAPI.MOD_ID + "/monitor_tbo",
|
||||
MONITOR_TBO.format()
|
||||
|
||||
@@ -23,8 +23,7 @@ import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public class TurtleBlockEntityRenderer implements BlockEntityRenderer<TurtleBlockEntity> {
|
||||
private static final ResourceLocation COLOUR_TURTLE_MODEL = new ResourceLocation(ComputerCraftAPI.MOD_ID, "block/turtle_colour");
|
||||
@@ -67,8 +66,8 @@ public class TurtleBlockEntityRenderer implements BlockEntityRenderer<TurtleBloc
|
||||
var matrix = transform.last().pose();
|
||||
var opacity = (int) (mc.options.getBackgroundOpacity(0.25f) * 255) << 24;
|
||||
var width = -font.width(label) / 2.0f;
|
||||
font.drawInBatch(label, width, (float) 0, 0x20ffffff, false, matrix, buffers, Font.DisplayMode.SEE_THROUGH, opacity, lightmapCoord);
|
||||
font.drawInBatch(label, width, (float) 0, 0xffffffff, false, matrix, buffers, Font.DisplayMode.NORMAL, 0, lightmapCoord);
|
||||
font.drawInBatch(label, width, 0, 0x20ffffff, false, matrix, buffers, Font.DisplayMode.SEE_THROUGH, opacity, lightmapCoord);
|
||||
font.drawInBatch(label, width, 0, 0xffffffff, false, matrix, buffers, Font.DisplayMode.NORMAL, 0, lightmapCoord);
|
||||
|
||||
transform.popPose();
|
||||
}
|
||||
@@ -127,7 +126,7 @@ public class TurtleBlockEntityRenderer implements BlockEntityRenderer<TurtleBloc
|
||||
transform.popPose();
|
||||
}
|
||||
|
||||
private void renderModel(PoseStack transform, MultiBufferSource buffers, int lightmapCoord, int overlayLight, ResourceLocation modelLocation, @Nullable int[] tints) {
|
||||
private void renderModel(PoseStack transform, MultiBufferSource buffers, int lightmapCoord, int overlayLight, ResourceLocation modelLocation, int @Nullable [] tints) {
|
||||
var modelManager = Minecraft.getInstance().getItemRenderer().getItemModelShaper().getModelManager();
|
||||
renderModel(transform, buffers, lightmapCoord, overlayLight, ClientPlatformHelper.get().getModel(modelManager, modelLocation), tints);
|
||||
}
|
||||
@@ -143,7 +142,7 @@ public class TurtleBlockEntityRenderer implements BlockEntityRenderer<TurtleBloc
|
||||
* @param tints Tints for the quads, as an array of RGB values.
|
||||
* @see net.minecraft.client.renderer.block.ModelBlockRenderer#renderModel
|
||||
*/
|
||||
private void renderModel(PoseStack transform, MultiBufferSource renderer, int lightmapCoord, int overlayLight, BakedModel model, @Nullable int[] tints) {
|
||||
private void renderModel(PoseStack transform, MultiBufferSource renderer, int lightmapCoord, int overlayLight, BakedModel model, int @Nullable [] tints) {
|
||||
ClientPlatformHelper.get().renderBakedModel(transform, renderer, model, lightmapCoord, overlayLight, tints);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,11 +27,11 @@ import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
||||
import org.joml.Matrix3f;
|
||||
import org.joml.Matrix4f;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
import org.lwjgl.opengl.GL31;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
|
||||
@@ -11,12 +11,12 @@ import dan200.computercraft.client.render.vbo.DirectVertexBuffer;
|
||||
import dan200.computercraft.shared.peripheral.monitor.ClientMonitor;
|
||||
import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
import org.lwjgl.opengl.GL30;
|
||||
import org.lwjgl.opengl.GL31;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
@@ -14,12 +14,12 @@ import dan200.computercraft.core.terminal.TextBuffer;
|
||||
import dan200.computercraft.core.util.Colour;
|
||||
import net.minecraft.client.renderer.ShaderInstance;
|
||||
import net.minecraft.server.packs.resources.ResourceProvider;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.lwjgl.opengl.GL13;
|
||||
import org.lwjgl.opengl.GL31;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@ import dan200.computercraft.shared.peripheral.speaker.SpeakerPeripheral;
|
||||
import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition;
|
||||
import net.minecraft.client.sounds.AudioStream;
|
||||
import net.minecraft.client.sounds.SoundEngine;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.lwjgl.BufferUtils;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
@@ -10,8 +10,7 @@ import dan200.computercraft.shared.peripheral.speaker.EncodedAudio;
|
||||
import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* An instance of a speaker, which is either playing a {@link DfpwmStream} stream or a normal sound.
|
||||
@@ -25,7 +24,7 @@ public class SpeakerInstance {
|
||||
SpeakerInstance() {
|
||||
}
|
||||
|
||||
private void pushAudio(EncodedAudio buffer) {
|
||||
private void pushAudio(EncodedAudio buffer, float volume) {
|
||||
var sound = this.sound;
|
||||
|
||||
var stream = currentStream;
|
||||
@@ -33,18 +32,30 @@ public class SpeakerInstance {
|
||||
var exhausted = stream.isEmpty();
|
||||
stream.push(buffer);
|
||||
|
||||
// If we've got nothing left in the buffer, enqueue an additional one just in case.
|
||||
if (exhausted && sound != null && sound.stream == stream && stream.channel != null && stream.executor != null) {
|
||||
if (sound == null) return;
|
||||
|
||||
var volumeChanged = sound.setVolume(volume);
|
||||
|
||||
if ((exhausted || volumeChanged) && sound.stream == stream && stream.channel != null && stream.executor != null) {
|
||||
var actualStream = sound.stream;
|
||||
stream.executor.execute(() -> {
|
||||
var channel = Nullability.assertNonNull(actualStream.channel);
|
||||
if (!channel.stopped()) channel.pumpBuffers(1);
|
||||
if (channel.stopped()) return;
|
||||
|
||||
// If we've got nothing left in the buffer, enqueue an additional one just in case.
|
||||
if (exhausted) channel.pumpBuffers(1);
|
||||
|
||||
// Update the attenuation if the volume has changed: SoundEngine.tickNonPaused updates the volume
|
||||
// itself, but leaves the attenuation unchanged. We mirror the logic of SoundEngine.play here.
|
||||
if (volumeChanged) {
|
||||
channel.linearAttenuation(Math.max(volume, 1) * sound.getSound().getAttenuationDistance());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void playAudio(SpeakerPosition position, float volume, EncodedAudio buffer) {
|
||||
pushAudio(buffer);
|
||||
pushAudio(buffer, volume);
|
||||
|
||||
var soundManager = Minecraft.getInstance().getSoundManager();
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ import net.minecraft.client.sounds.SoundBufferLibrary;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
@@ -83,4 +83,10 @@ public class SpeakerSound extends AbstractSoundInstance implements TickableSound
|
||||
public @Nullable AudioStream getStream() {
|
||||
return stream;
|
||||
}
|
||||
|
||||
boolean setVolume(float volume) {
|
||||
if (volume == this.volume) return false;
|
||||
this.volume = volume;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.api.turtle.TurtleSide;
|
||||
import dan200.computercraft.shared.turtle.upgrades.TurtleModem;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@@ -106,6 +106,8 @@ public final class LanguageProvider implements DataProvider {
|
||||
add(ComputerCraftTags.Items.TURTLE, "Turtles");
|
||||
add(ComputerCraftTags.Items.WIRED_MODEM, "Wired modems");
|
||||
add(ComputerCraftTags.Items.MONITOR, "Monitors");
|
||||
add(ComputerCraftTags.Items.DISKS, "Disks");
|
||||
add(ComputerCraftTags.Items.POCKET_COMPUTERS, "Pocket Computers");
|
||||
|
||||
// Turtle/pocket upgrades
|
||||
add("upgrade.minecraft.diamond_sword.adjective", "Melee");
|
||||
@@ -183,7 +185,6 @@ public final class LanguageProvider implements DataProvider {
|
||||
// Metrics
|
||||
add(Metrics.COMPUTER_TASKS, "Tasks");
|
||||
add(Metrics.SERVER_TASKS, "Server tasks");
|
||||
add(Metrics.JAVA_ALLOCATION, "Java Allocations");
|
||||
add(Metrics.PERIPHERAL_OPS, "Peripheral calls");
|
||||
add(Metrics.FS_OPS, "Filesystem operations");
|
||||
add(Metrics.HTTP_REQUESTS, "HTTP requests");
|
||||
|
||||
@@ -10,8 +10,8 @@ import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@@ -98,6 +98,8 @@ class TagProvider {
|
||||
tags.copy(ComputerCraftTags.Blocks.TURTLE, ComputerCraftTags.Items.TURTLE);
|
||||
tags.tag(ComputerCraftTags.Items.WIRED_MODEM).add(ModRegistry.Items.WIRED_MODEM.get(), ModRegistry.Items.WIRED_MODEM_FULL.get());
|
||||
tags.copy(ComputerCraftTags.Blocks.MONITOR, ComputerCraftTags.Items.MONITOR);
|
||||
tags.tag(ComputerCraftTags.Items.DISKS).add(ModRegistry.Items.DISK.get(), ModRegistry.Items.TREASURE_DISK.get());
|
||||
tags.tag(ComputerCraftTags.Items.POCKET_COMPUTERS).add(ModRegistry.Items.POCKET_COMPUTER_NORMAL.get(), ModRegistry.Items.POCKET_COMPUTER_ADVANCED.get());
|
||||
|
||||
tags.tag(ItemTags.PIGLIN_LOVED).add(
|
||||
ModRegistry.Items.COMPUTER_ADVANCED.get(), ModRegistry.Items.TURTLE_ADVANCED.get(),
|
||||
|
||||
@@ -6,7 +6,7 @@ import dan200.computercraft.api.lua.Coerced;
|
||||
import dan200.computercraft.api.lua.ILuaAPI;
|
||||
import dan200.computercraft.api.lua.LuaFunction;
|
||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* An example API that will be available on every turtle. This demonstrates both registering an API, and how to write
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.example.examplemod;
|
||||
import com.example.examplemod.data.TurtleDataProvider;
|
||||
import com.example.examplemod.peripheral.FurnacePeripheral;
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.api.detail.VanillaDetailRegistries;
|
||||
import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser;
|
||||
|
||||
/**
|
||||
@@ -34,6 +35,16 @@ public final class ExampleMod {
|
||||
ComputerCraftAPI.registerGenericSource(new FurnacePeripheral());
|
||||
// @end region=generic_source
|
||||
|
||||
// @start region=details
|
||||
VanillaDetailRegistries.ITEM_STACK.addProvider((out, stack) -> {
|
||||
var food = stack.getItem().getFoodProperties();
|
||||
if (food == null) return;
|
||||
|
||||
out.put("saturation", food.getSaturationModifier());
|
||||
out.put("nutrition", food.getNutrition());
|
||||
});
|
||||
// @end region=details
|
||||
|
||||
ExampleAPI.register();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.example.examplemod;
|
||||
|
||||
import dan200.computercraft.api.detail.DetailRegistry;
|
||||
import dan200.computercraft.api.detail.VanillaDetailRegistries;
|
||||
import dan200.computercraft.api.lua.LuaFunction;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.api.pocket.IPocketAccess;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An example peripheral for pocket computers. This currently doesn't have an associated upgrade — it mostly exists to
|
||||
* demonstrate other functionality.
|
||||
*/
|
||||
public class ExamplePocketPeripheral implements IPeripheral {
|
||||
private final IPocketAccess pocket;
|
||||
|
||||
public ExamplePocketPeripheral(IPocketAccess pocket) {
|
||||
this.pocket = pocket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "example";
|
||||
}
|
||||
|
||||
/**
|
||||
* An example of using {@linkplain DetailRegistry detail registries} to get the current player's held item.
|
||||
*
|
||||
* @return The item details, or {@code null} if the player is not holding an item.
|
||||
*/
|
||||
// @start region=details
|
||||
@LuaFunction(mainThread = true)
|
||||
public final @Nullable Map<String, ?> getHeldItem() {
|
||||
if (!(pocket.getEntity() instanceof LivingEntity entity)) return null;
|
||||
|
||||
var heldItem = entity.getItemInHand(InteractionHand.MAIN_HAND);
|
||||
return heldItem.isEmpty() ? null : VanillaDetailRegistries.ITEM_STACK.getDetails(heldItem);
|
||||
}
|
||||
// @end region=details
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable IPeripheral other) {
|
||||
return other instanceof ExamplePocketPeripheral o && pocket == o.pocket;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package com.example.examplemod.peripheral;
|
||||
import dan200.computercraft.api.lua.LuaFunction;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import net.minecraft.world.level.block.entity.BrewingStandBlockEntity;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A peripheral that adds a {@code getFuel()} method to brewing stands. This demonstrates the usage of
|
||||
|
||||
@@ -4,7 +4,7 @@ import dan200.computercraft.api.lua.LuaFunction;
|
||||
import dan200.computercraft.api.peripheral.AttachedComputerSet;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A peripheral that tracks what computers it is attached to.
|
||||
|
||||
@@ -205,7 +205,9 @@
|
||||
"item.computercraft.treasure_disk": "Floppy Disk",
|
||||
"itemGroup.computercraft": "ComputerCraft",
|
||||
"tag.item.computercraft.computer": "Computers",
|
||||
"tag.item.computercraft.disks": "Disks",
|
||||
"tag.item.computercraft.monitor": "Monitors",
|
||||
"tag.item.computercraft.pocket_computers": "Pocket Computers",
|
||||
"tag.item.computercraft.turtle": "Turtles",
|
||||
"tag.item.computercraft.wired_modem": "Wired modems",
|
||||
"tracking_field.computercraft.avg": "%s (avg)",
|
||||
@@ -215,7 +217,6 @@
|
||||
"tracking_field.computercraft.http_download.name": "HTTP download",
|
||||
"tracking_field.computercraft.http_requests.name": "HTTP requests",
|
||||
"tracking_field.computercraft.http_upload.name": "HTTP upload",
|
||||
"tracking_field.computercraft.java_allocation.name": "Java Allocations",
|
||||
"tracking_field.computercraft.max": "%s (max)",
|
||||
"tracking_field.computercraft.peripheral.name": "Peripheral calls",
|
||||
"tracking_field.computercraft.server_tasks.name": "Server tasks",
|
||||
|
||||
@@ -11,7 +11,6 @@ import dan200.computercraft.api.filesystem.Mount;
|
||||
import dan200.computercraft.api.filesystem.WritableMount;
|
||||
import dan200.computercraft.api.lua.GenericSource;
|
||||
import dan200.computercraft.api.lua.ILuaAPIFactory;
|
||||
import dan200.computercraft.api.media.MediaProvider;
|
||||
import dan200.computercraft.api.media.PrintoutContents;
|
||||
import dan200.computercraft.api.network.PacketNetwork;
|
||||
import dan200.computercraft.api.network.wired.WiredElement;
|
||||
@@ -36,8 +35,8 @@ import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -93,11 +92,6 @@ public abstract class AbstractComputerCraftAPI implements ComputerCraftAPIServic
|
||||
return BundledRedstone.getDefaultOutput(world, pos, side);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void registerMediaProvider(MediaProvider provider) {
|
||||
MediaProviders.register(provider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final PacketNetwork getWirelessNetwork(MinecraftServer server) {
|
||||
return ServerContext.get(server).wirelessNetwork();
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
// Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||
//
|
||||
// SPDX-License-Identifier: LicenseRef-CCPL
|
||||
|
||||
package dan200.computercraft.impl;
|
||||
|
||||
import dan200.computercraft.api.media.IMedia;
|
||||
import dan200.computercraft.api.media.MediaProvider;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public final class MediaProviders {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MediaProviders.class);
|
||||
|
||||
private static final Set<MediaProvider> providers = new LinkedHashSet<>();
|
||||
|
||||
private MediaProviders() {
|
||||
}
|
||||
|
||||
public static synchronized void register(MediaProvider provider) {
|
||||
Objects.requireNonNull(provider, "provider cannot be null");
|
||||
providers.add(provider);
|
||||
}
|
||||
|
||||
public static @Nullable IMedia get(ItemStack stack) {
|
||||
if (stack.isEmpty()) return null;
|
||||
|
||||
// Try the handlers in order:
|
||||
for (var mediaProvider : providers) {
|
||||
try {
|
||||
var media = mediaProvider.getMedia(stack);
|
||||
if (media != null) return media;
|
||||
} catch (Exception e) {
|
||||
// Mod misbehaved, ignore it
|
||||
LOG.error("Media provider " + mediaProvider + " errored.", e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user