├── .editorconfig ├── .github └── workflows │ ├── build.yml │ └── release.yml ├── .gitignore ├── LICENSE ├── README.md ├── beelightful ├── README.md ├── build.gradle └── src │ └── main │ ├── java │ └── dev │ │ └── triphora │ │ └── beelightful │ │ └── mixin │ │ └── BeeEntityMixin.java │ └── resources │ └── assets │ └── beelightful │ └── icon.png ├── build.gradle ├── buildSrc ├── build.gradle └── src │ └── main │ └── java │ └── dev │ └── triphora │ └── gradle │ ├── ConfigurationExtension.java │ ├── Constants.java │ ├── Generator.java │ ├── MixinsJson.java │ ├── MixinsJsonGenerator.java │ ├── QuiltModJson.java │ ├── QuiltModJsonGenerator.java │ └── Side.java ├── clean_logs ├── LICENSE ├── README.md ├── build.gradle └── src │ └── main │ ├── java │ └── dev │ │ └── triphora │ │ └── clean_logs │ │ ├── CleanLogs.java │ │ ├── Config.java │ │ ├── ConfigHelper.java │ │ ├── JavaUtilLog4jFilter.java │ │ └── SystemPrintFilter.java │ └── resources │ └── assets │ └── clean_logs │ └── icon.png ├── compass_commands ├── README.md ├── build.gradle └── src │ └── main │ ├── java │ └── dev │ │ └── triphora │ │ └── compass_commands │ │ ├── CompassCommandsClient.java │ │ └── CompassCommandsServer.java │ └── resources │ └── assets │ └── compass_commands │ ├── icon.png │ └── lang │ └── en_us.json ├── emmod ├── LICENSE ├── README.md ├── build.gradle ├── src │ └── main │ │ └── java │ │ └── dev │ │ └── triphora │ │ └── emmod │ │ ├── NarratorOffTransformer.java │ │ └── mixin │ │ └── MinecraftClientMixin.java └── unsafe-1.7.1.jar ├── gradle.properties ├── gradle └── libs.versions.toml ├── only_pink_sheeps ├── README.md ├── build.gradle └── src │ └── main │ ├── java │ └── dev │ │ └── triphora │ │ └── only_pink_sheeps │ │ └── mixin │ │ └── SheepEntityMixin.java │ └── resources │ └── assets │ └── only_pink_sheeps │ └── icon.png ├── orientation ├── LICENSE ├── README.md ├── build.gradle └── src │ └── main │ ├── java │ └── dev │ │ └── triphora │ │ └── orientation │ │ └── Orientation.java │ └── resources │ └── assets │ └── orientation │ ├── icon.png │ └── lang │ └── en_us.json ├── repeat_no_more ├── README.md ├── build.gradle └── src │ └── main │ ├── java │ └── dev │ │ └── triphora │ │ └── repeat_no_more │ │ ├── RepeatNoMore.java │ │ └── mixin │ │ └── RepeaterBlockMixin.java │ └── resources │ └── assets │ └── repeat_no_more │ ├── icon.png │ └── lang │ └── en_us.json ├── settings.gradle └── wake_up_time ├── README.md ├── build.gradle └── src └── main ├── java └── dev │ └── triphora │ └── wake_up_time │ └── WakeUpTime.java └── resources └── assets └── wake_up_time ├── icon.png └── lang ├── en_us.json └── ru_ru.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | indent_style = tab 9 | indent_size = 1 10 | tab_width = 2 11 | ij_any_field_annotation_wrap = off 12 | ij_any_parameter_annotation_wrap = off 13 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: [ push, pull_request ] 3 | 4 | jobs: 5 | build: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v3 9 | - uses: actions/setup-java@v3 10 | with: 11 | distribution: adopt 12 | java-version: 17 13 | - uses: gradle/gradle-build-action@v2 14 | with: 15 | gradle-version: release-candidate 16 | arguments: build 17 | cache-read-only: ${{ github.repository_owner != 'emmods' }} 18 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | project: 6 | type: choice 7 | description: Project to publish 8 | required: true 9 | options: 10 | - beelightful 11 | - clean_logs 12 | - compass_commands 13 | - only_pink_sheeps 14 | - orientation 15 | - repeat_no_more 16 | - wake_up_time 17 | version_name: 18 | type: string 19 | description: Modrinth version name to use 20 | required: true 21 | changelog: 22 | type: string 23 | description: Modrinth changelog to use 24 | required: false 25 | version_type: 26 | type: choice 27 | description: Modrinth version type to use 28 | default: release 29 | options: 30 | - release 31 | - beta 32 | - alpha 33 | 34 | jobs: 35 | release: 36 | runs-on: ubuntu-latest 37 | steps: 38 | - uses: actions/checkout@v3 39 | - uses: actions/setup-java@v3 40 | with: 41 | distribution: adopt 42 | java-version: 17 43 | - uses: gradle/gradle-build-action@v2 44 | with: 45 | gradle-version: release-candidate 46 | arguments: ${{ inputs.project }}:modrinth 47 | cache-read-only: ${{ github.repository_owner != 'emmods' }} 48 | env: 49 | MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} 50 | VERSION_NAME: ${{ inputs.version_name }} 51 | CHANGELOG: ${{ inputs.changelog }} 52 | VERSION_TYPE: ${{ inputs.version_type }} 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Build tool ### 2 | run/ 3 | build/ 4 | 5 | ### Gradle ### 6 | .gradle 7 | !**/src/main/**/build/ 8 | !**/src/test/**/build/ 9 | 10 | ### Brachyura ### 11 | .brachyura/ 12 | 13 | ### IntelliJ IDEA ### 14 | .idea/ 15 | *.iws 16 | *.iml 17 | *.ipr 18 | out/ 19 | !**/src/main/**/out/ 20 | !**/src/test/**/out/ 21 | 22 | ### Eclipse ### 23 | .apt_generated 24 | .classpath 25 | .factorypath 26 | .project 27 | .settings 28 | .springBeans 29 | .sts4-cache 30 | bin/ 31 | !**/src/main/**/bin/ 32 | !**/src/test/**/bin/ 33 | 34 | ### NetBeans ### 35 | /nbproject/private/ 36 | /nbbuild/ 37 | /dist/ 38 | /nbdist/ 39 | /.nb-gradle/ 40 | 41 | ### VS Code ### 42 | .vscode/ 43 | 44 | ### Mac OS ### 45 | .DS_Store 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2022—2023 triphora 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 2. Altered source versions must be plainly marked as such, and must not be 16 | misrepresented as being the original software. 17 | 3. This notice may not be removed or altered from any source distribution. 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Our Quilt mods 2 | 3 | This repository includes most of our mods. These mods are all Quilt-exclusive and Modrinth-exclusive. 4 | 5 | | Mod name | Modrinth link | Directory link | License | 6 | |------------------|--------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------|-------------------| 7 | | Beelightful | [![beelightful](https://img.shields.io/modrinth/dt/beelightful?color=00AF5C&logo=modrinth)](https://modrinth.com/mod/beelightful) | [beelightful](./beelightful) | Zlib | 8 | | Clean Logs | [![clean-logs](https://img.shields.io/modrinth/dt/clean-logs?color=00AF5C&logo=modrinth)](https://modrinth.com/mod/clean-logs) | [clean_logs](./clean_logs) | LGPL-3.0-or-later | 9 | | Compass Commands | [![compass-commands](https://img.shields.io/modrinth/dt/compass-commands?color=00AF5C&logo=modrinth)](https://modrinth.com/mod/compass-commands) | [compass_commands](./compass_commands) | Zlib | 10 | | Emmod | N/A | [emmod](./emmod) | LGPL-3.0-only | 11 | | Only Pink Sheeps | [![only_pink_sheeps](https://img.shields.io/modrinth/dt/only_pink_sheeps?color=00AF5C&logo=modrinth)](https://modrinth.com/mod/only_pink_sheeps) | [only_pink_sheeps](./only_pink_sheeps) | Zlib | 12 | | Orientation | [![orientation](https://img.shields.io/modrinth/dt/orientation?color=00AF5C&logo=modrinth)](https://modrinth.com/mod/orientation) | [orientation](./orientation) | MIT | 13 | | Repeat No More | [![repeat-no-more](https://img.shields.io/modrinth/dt/repeat-no-more?color=00AF5C&logo=modrinth)](https://modrinth.com/mod/repeat-no-more) | [repeat_no_more](./repeat_no_more) | Zlib | 14 | | Wake Up Time | [![wake-up-time](https://img.shields.io/modrinth/dt/wake-up-time?color=00AF5C&logo=modrinth)](https://modrinth.com/mod/wake-up-time) | [wake_up_time](./wake_up_time) | Zlib | 15 | -------------------------------------------------------------------------------- /beelightful/README.md: -------------------------------------------------------------------------------- 1 | **Beelightful** intends to make bee stings more realistic. 2 | 3 | In vanilla Minecraft, when a bee stings you, you have the same effect - you lose two to three hearts depending on your difficulty and get the poison effect for a certain amount of time. 4 | 5 | With this mod, however, when a bee stings you, the effect changes based on your world's seed and your UUID. Therefore, you will always have the same effect in the same world with the same seed, but the effect will only change if you start a new save or if you change accounts. Just like in real life, your allergic effect to bee stings does not change. 6 | 7 | There's a chance that you will get any of the following effects: 8 | - Only hearts lost, no poison 9 | - Only poison, no hearts lost 10 | - Shorter poison length than usual 11 | - Normal effect 12 | - Longer poison length than usual 13 | - Longer poison length than usual plus double hearts lost 14 | - Allergy resulting in an instant fatality 15 | 16 | This mod is currently in alpha and I'm hoping to expand it more in the future. 17 | -------------------------------------------------------------------------------- /beelightful/build.gradle: -------------------------------------------------------------------------------- 1 | import dev.triphora.gradle.QuiltModJson.QuiltLoader 2 | 3 | version = '0.1.1' 4 | 5 | emmod { 6 | summary = 'Making bee stings more realistic since 2022.' 7 | depends.add new QuiltLoader.Dependency('minecraft', '>=1.17-pre1') 8 | } 9 | -------------------------------------------------------------------------------- /beelightful/src/main/java/dev/triphora/beelightful/mixin/BeeEntityMixin.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.beelightful.mixin; 2 | 3 | import net.minecraft.entity.Entity; 4 | import net.minecraft.entity.LivingEntity; 5 | import net.minecraft.entity.damage.DamageSource; 6 | import net.minecraft.entity.effect.StatusEffectInstance; 7 | import net.minecraft.entity.effect.StatusEffects; 8 | import net.minecraft.entity.passive.BeeEntity; 9 | import net.minecraft.server.world.ServerWorld; 10 | import net.minecraft.util.UuidUtil; 11 | import org.spongepowered.asm.mixin.Mixin; 12 | import org.spongepowered.asm.mixin.injection.At; 13 | import org.spongepowered.asm.mixin.injection.Redirect; 14 | 15 | @Mixin(BeeEntity.class) 16 | abstract class BeeEntityMixin { 17 | private static final String DESCRIPTOR = "Lnet/minecraft/entity/LivingEntity;addStatusEffect" + 18 | "(Lnet/minecraft/entity/effect/StatusEffectInstance;Lnet/minecraft/entity/Entity;)Z"; 19 | 20 | @Redirect(method = "tryAttack", at = @At(value = "INVOKE", target = DESCRIPTOR)) 21 | boolean beelightful$modifyBeeSting(LivingEntity target, StatusEffectInstance effect, Entity source) { 22 | int difficulty = effect.getDuration() / 20; 23 | boolean normalMode = difficulty == 10; 24 | boolean hardMode = difficulty == 18; 25 | int healthPoints = normalMode ? 2 : hardMode ? 3 : 0; 26 | @SuppressWarnings("ConstantConditions") var bee = (BeeEntity) (Object) this; 27 | 28 | switch (getBeeStingEffect(target)) { 29 | case 0, 1 -> {} // No poison! Congratulations. 30 | case 2 -> { // Shorter than default plus health gets returned (if you haven't yet died) 31 | effect.upgrade(new StatusEffectInstance(StatusEffects.POISON, difficulty * 10, 0)); 32 | target.addStatusEffect(effect, bee); 33 | target.addStatusEffect(new StatusEffectInstance(StatusEffects.INSTANT_HEALTH, healthPoints), bee); 34 | } 35 | case 3 -> { // Shorter than default 36 | effect.upgrade(new StatusEffectInstance(StatusEffects.POISON, difficulty * 10, 0)); 37 | target.addStatusEffect(effect, bee); 38 | } 39 | case 4, 5 -> target.addStatusEffect(effect, bee); // Same as default 40 | case 6 -> { // Longer than default 41 | effect.upgrade(new StatusEffectInstance(StatusEffects.POISON, difficulty * 100, 0)); 42 | target.addStatusEffect(effect, bee); 43 | } 44 | case 7 -> { // Longer than default plus double the damage 45 | effect.upgrade(new StatusEffectInstance(StatusEffects.POISON, difficulty * 200, 0)); 46 | target.addStatusEffect(effect, bee); 47 | target.addStatusEffect(new StatusEffectInstance(StatusEffects.INSTANT_DAMAGE, healthPoints), bee); 48 | } 49 | case 8, 9 -> target.damage(target.getWorld().getDamageSources().sting(bee), Float.MAX_VALUE); // Sorry. 50 | } 51 | return false; 52 | } 53 | 54 | private int getBeeStingEffect(LivingEntity target) { 55 | int chance = target.getWorld() instanceof ServerWorld serverWorld ? (int) (serverWorld.getSeed() % 10) : 0; 56 | for (var entry : UuidUtil.toIntArray(target.getUuid())) chance += entry; 57 | return Math.abs(chance % 10); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /beelightful/src/main/resources/assets/beelightful/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triphora/quilt_mods/09db38a5a29eefb7178a56d10347548beea74c8a/beelightful/src/main/resources/assets/beelightful/icon.png -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | import dev.triphora.gradle.ConfigurationExtension 2 | import dev.triphora.gradle.Constants 3 | import dev.triphora.gradle.MixinsJsonGenerator 4 | import dev.triphora.gradle.QuiltModJsonGenerator 5 | 6 | plugins { 7 | alias libs.plugins.quilt.loom apply false 8 | alias libs.plugins.minotaur apply false 9 | alias libs.plugins.machete apply false 10 | alias libs.plugins.outlet apply false 11 | } 12 | 13 | subprojects { 14 | apply plugin: 'java' 15 | //apply plugin: 'maven-publish' 16 | apply plugin: 'org.quiltmc.loom' 17 | apply plugin: 'com.modrinth.minotaur' 18 | apply plugin: 'io.github.p03w.machete' 19 | apply plugin: 'io.github.dexman545.outlet' 20 | 21 | group = Constants.GROUP 22 | archivesBaseName = project.name 23 | 24 | [ 25 | ['Modrinth', 'api.modrinth.com/maven', ['maven.modrinth']], 26 | ].forEach { var mavenInfo -> 27 | repositories { 28 | exclusiveContent { 29 | forRepository { 30 | maven { 31 | name = mavenInfo[0] 32 | url = 'https://' + mavenInfo[1] 33 | } 34 | } 35 | filter { 36 | mavenInfo[2].forEach { String group -> 37 | includeGroup group 38 | } 39 | } 40 | } 41 | } 42 | } 43 | 44 | loom { 45 | runtimeOnlyLog4j = project.name != 'clean_logs' 46 | runs { 47 | configureEach { 48 | vmArg '-Dmixin.debug.export=true' 49 | } 50 | } 51 | } 52 | 53 | java.withSourcesJar() 54 | 55 | dependencies { 56 | minecraft libs.minecraft 57 | mappings(variantOf(libs.quilt.mappings) { classifier 'intermediary-v2' }) 58 | modApi libs.quilt.loader 59 | 60 | modLocalRuntime(libs.bundles.runtime) { 61 | transitive = false 62 | } 63 | } 64 | 65 | extensions.create('emmod', ConfigurationExtension.class, project) 66 | task generateResources { 67 | doLast { 68 | new MixinsJsonGenerator().create(project) 69 | new QuiltModJsonGenerator().create(project) 70 | } 71 | outputs.dir('build/generated/resources') 72 | } 73 | 74 | sourcesJar.dependsOn generateResources 75 | remapJar.dependsOn generateResources 76 | 77 | sourceSets { 78 | main { 79 | resources { 80 | srcDir generateResources 81 | } 82 | } 83 | } 84 | 85 | if (emmod.qsl || emmod.midnightlib) { 86 | dependencies { 87 | modApi libs.quilted.fabric.api 88 | } 89 | } 90 | 91 | if (emmod.midnightlib) { 92 | dependencies { 93 | modApi libs.midnightlib 94 | include libs.midnightlib 95 | } 96 | } 97 | 98 | int javaVersion = emmod.javaVersion.orNull ?: 17 99 | 100 | tasks.withType(JavaCompile).configureEach { 101 | it.options.encoding = 'UTF-8' 102 | it.options.release = javaVersion 103 | it.sourceCompatibility = javaVersion 104 | } 105 | 106 | jar.from project.file('LICENSE').exists() ? project.file('LICENSE') : rootProject.file('LICENSE') 107 | 108 | def projectBody = project.file('README.md').text 109 | def devinsBadges = 'https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/cozy' 110 | 111 | if (emmod.qsl || emmod.midnightlib) { 112 | projectBody += "\n[![Requires Quilt Standard Libraries]($devinsBadges/requires/quilt-standard-libraries_64h.png)]" + 113 | '(https://modrinth.com/mod/qsl)' 114 | } 115 | 116 | projectBody += "\n---\n[![Support us through GitHub Sponsors]($devinsBadges/donate/ghsponsors-plural_64h.png)]" + 117 | "($Constants.DONATE_LINK)\\\n[![Chat with us on Discord]($devinsBadges/social/discord-plural_64h.png)]" + 118 | "($Constants.DISCORD_LINK)" 119 | 120 | modrinth { 121 | projectId = emmod.modrinthSlug.orElse project.name 122 | gameVersions = [libs.versions.minecraft.get()] 123 | versionName = System.getenv().VERSION_NAME ?: versionNumber 124 | changelog = System.getenv().CHANGELOG ?: DEFAULT_CHANGELOG 125 | versionType = System.getenv().VERSION_TYPE ?: DEFAULT_VERSION_TYPE 126 | uploadFile = remapJar 127 | additionalFiles = [sourcesJar] 128 | syncBodyFrom = projectBody 129 | } 130 | 131 | tasks.modrinth.doFirst { 132 | if (emmod.gameVersions) { 133 | modrinth.gameVersions = emmod.gameVersions 134 | } 135 | 136 | if (emmod.qsl || emmod.midnightlib) { 137 | modrinth { 138 | dependencies { 139 | required.project 'qsl' 140 | } 141 | } 142 | } 143 | 144 | if (emmod.midnightlib) { 145 | modrinth { 146 | dependencies { 147 | embedded.project 'midnightlib' 148 | optional.project 'modmenu' 149 | } 150 | } 151 | } 152 | } 153 | 154 | tasks.modrinth.dependsOn tasks.modrinthSyncBody 155 | tasks.modrinth.dependsOn { tasks.named('optimizeOutputsOfRemapJar') } 156 | 157 | //publishing { 158 | // publications { 159 | // mavenJava(MavenPublication) { 160 | // from components.java 161 | // } 162 | // } 163 | // repositories { 164 | // maven { 165 | // url = 's3://maven' 166 | // credentials(AwsCredentials) { 167 | // accessKey = findProperty('dev.triphora.maven.access') 168 | // secretKey = findProperty('dev.triphora.maven.secret') 169 | // } 170 | // } 171 | // } 172 | //} 173 | } 174 | -------------------------------------------------------------------------------- /buildSrc/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'idea' 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencies { 11 | implementation 'org.jetbrains:annotations:23.0.0' 12 | implementation 'org.apache.commons:commons-text:1.10.0' 13 | implementation 'com.google.code.gson:gson:2.10' 14 | implementation annotationProcessor('org.projectlombok:lombok:1.18.24') 15 | } 16 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/dev/triphora/gradle/ConfigurationExtension.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.gradle; 2 | 3 | import lombok.Getter; 4 | import org.gradle.api.Project; 5 | import org.gradle.api.provider.MapProperty; 6 | import org.gradle.api.provider.Property; 7 | import org.gradle.api.provider.SetProperty; 8 | 9 | public class ConfigurationExtension { 10 | @Getter private final Property midnightlib, qsl, mixin; 11 | @Getter private final Property summary, spdx, modrinthSlug, mixinPlugin; 12 | @Getter private final Property side; 13 | @Getter private final Property javaVersion; 14 | @Getter private final SetProperty gameVersions; 15 | @Getter private final SetProperty depends; 16 | @Getter private final MapProperty contributors, entrypoints, modMenuLinks; 17 | 18 | public ConfigurationExtension(Project project) { 19 | midnightlib = project.getObjects().property(Boolean.class).convention(false); 20 | qsl = project.getObjects().property(Boolean.class).convention(false); 21 | mixin = project.getObjects().property(Boolean.class).convention(true); 22 | summary = project.getObjects().property(String.class); 23 | spdx = project.getObjects().property(String.class).convention("Zlib"); 24 | modrinthSlug = project.getObjects().property(String.class).convention(project.getName()); 25 | mixinPlugin = project.getObjects().property(String.class).convention((String) null); 26 | side = project.getObjects().property(Side.class).convention(Side.ANY); 27 | javaVersion = project.getObjects().property(Integer.class).convention(17); 28 | gameVersions = project.getObjects().setProperty(String.class).empty(); 29 | depends = project.getObjects().setProperty(QuiltModJson.QuiltLoader.Dependency.class).empty(); 30 | contributors = project.getObjects().mapProperty(String.class, String.class).empty(); 31 | entrypoints = project.getObjects().mapProperty(String.class, String.class).empty(); 32 | modMenuLinks = project.getObjects().mapProperty(String.class, String.class).empty(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/dev/triphora/gradle/Constants.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.gradle; 2 | 3 | public class Constants { 4 | public static final String DONATE_LINK = "https://github.com/sponsors/triphora"; 5 | public static final String DISCORD_LINK = "https://discord.gg/buPbUvw5FD"; 6 | public static final String SOURCE_LINK = "https://github.com/emmods/quilt_mods"; 7 | public static final String ISSUES_LINK = "https://github.com/emmods/quilt_mods/issues"; 8 | public static final String EMAIL = "emma@modrinth.com"; 9 | public static final String GROUP = "dev.triphora"; 10 | public static final String INTERMEDIATE_MAPPINGS = "net.fabricmc:intermediary"; 11 | } 12 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/dev/triphora/gradle/Generator.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.gradle; 2 | 3 | import com.google.gson.Gson; 4 | import org.gradle.api.Project; 5 | 6 | import java.io.FileWriter; 7 | import java.io.IOException; 8 | import java.nio.file.Files; 9 | import java.nio.file.Path; 10 | 11 | interface Generator { 12 | void create(Project project) throws IOException; 13 | 14 | static void writeFinalResult(Project project, String filename, Object o) throws IOException { 15 | Path output = project.getBuildDir().toPath().resolve("generated").resolve("resources"); 16 | 17 | //noinspection ResultOfMethodCallIgnored 18 | output.toFile().mkdirs(); 19 | output = output.resolve(filename); 20 | if (Files.exists(output)) Files.delete(output); 21 | 22 | try (var writer = new FileWriter(output.toFile())) { 23 | new Gson().toJson(o, writer); 24 | } 25 | } 26 | 27 | static ConfigurationExtension getExtension(Project project) { 28 | return project.getExtensions().getByType(ConfigurationExtension.class); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/dev/triphora/gradle/MixinsJson.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.gradle; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.RequiredArgsConstructor; 5 | 6 | import javax.annotation.Nonnull; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | @RequiredArgsConstructor 11 | class MixinsJson { 12 | boolean required = true; 13 | String minVersion = "0.8"; 14 | String plugin; 15 | @Nonnull @SerializedName("package") String mixinPackage; 16 | String compatibilityLevel = "JAVA_17"; 17 | @Nonnull List mixins; 18 | @Nonnull List client; 19 | @Nonnull List server; 20 | Map injectors = Map.of("defaultRequire", 1); 21 | } 22 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/dev/triphora/gradle/MixinsJsonGenerator.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.gradle; 2 | 3 | import org.gradle.api.Project; 4 | 5 | import java.io.IOException; 6 | import java.nio.file.Files; 7 | import java.nio.file.Paths; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | public class MixinsJsonGenerator implements Generator { 12 | public void create(Project project) throws IOException { 13 | var extension = Generator.getExtension(project); 14 | 15 | if (!extension.getMixin().get()) return; 16 | 17 | final var mixinPackage = "dev.triphora." + project.getName() + ".mixin"; 18 | 19 | List mixins = new ArrayList<>(); 20 | List client = new ArrayList<>(); 21 | List server = new ArrayList<>(); 22 | 23 | var mixinFolder = Paths.get( 24 | project.getProjectDir() + "/src/main/java/" + mixinPackage.replaceAll("\\.", "/") 25 | ); 26 | try (var mixinPaths = Files.list(mixinFolder)) { 27 | mixinPaths.filter(Files::isRegularFile).forEach(path -> { 28 | var mixinName = path.getFileName().toString().replace(".java", ""); 29 | switch (extension.getSide().get()) { 30 | case CLIENT -> client.add(mixinName); 31 | case DEDICATED_SERVER -> server.add(mixinName); 32 | case ANY -> mixins.add(mixinName); 33 | } 34 | }); 35 | } 36 | try (var clientMixinPaths = Files.list(mixinFolder.resolve("client"))) { 37 | clientMixinPaths.filter(Files::isRegularFile).forEach(path -> 38 | client.add(path.getFileName().toString().replace(".java", ""))); 39 | } catch (Exception e) { 40 | // ignore 41 | } 42 | try (var serverMixinPaths = Files.list(mixinFolder.resolve("server"))) { 43 | serverMixinPaths.filter(Files::isRegularFile).forEach(path -> 44 | server.add(path.getFileName().toString().replace(".java", ""))); 45 | } catch (Exception e) { 46 | // ignore 47 | } 48 | 49 | var json = new MixinsJson(mixinPackage, mixins, client, server); 50 | var mixinPlugin = extension.getMixinPlugin().getOrNull(); 51 | if (mixinPlugin != null) json.plugin = mixinPlugin; 52 | 53 | Generator.writeFinalResult(project, project.getName() + ".mixins.json", json); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/dev/triphora/gradle/QuiltModJson.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.gradle; 2 | 3 | import lombok.AllArgsConstructor; 4 | import org.jetbrains.annotations.Nullable; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | @AllArgsConstructor 10 | public class QuiltModJson { 11 | int schema_version; 12 | QuiltLoader quilt_loader; 13 | Minecraft minecraft; 14 | ModMenu modmenu; 15 | String mixin; 16 | 17 | @AllArgsConstructor 18 | public static class QuiltLoader { 19 | String group; 20 | String id; 21 | String version; 22 | Metadata metadata; 23 | String intermediate_mappings; 24 | @Nullable Map entrypoints; 25 | List depends; 26 | 27 | @AllArgsConstructor 28 | static class Metadata { 29 | String name; 30 | @Nullable String description; 31 | Map contributors; 32 | Map contact; 33 | String license; 34 | String icon; 35 | } 36 | 37 | @AllArgsConstructor 38 | public static class Dependency { 39 | String id; 40 | String versions; 41 | @Nullable String reason; 42 | @Nullable String environment; 43 | boolean optional; 44 | 45 | public Dependency(String id) { 46 | this.id = id; 47 | } 48 | 49 | public Dependency(String id, String versions) { 50 | this.id = id; 51 | this.versions = versions; 52 | } 53 | 54 | public Dependency(String id, String versions, @Nullable String reason) { 55 | this.id = id; 56 | this.versions = versions; 57 | this.reason = reason; 58 | } 59 | } 60 | } 61 | 62 | @AllArgsConstructor 63 | static class Minecraft { 64 | String environment; 65 | } 66 | 67 | @AllArgsConstructor 68 | static class ModMenu { 69 | Map links; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/dev/triphora/gradle/QuiltModJsonGenerator.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.gradle; 2 | 3 | import org.apache.commons.text.WordUtils; 4 | import org.gradle.api.Project; 5 | 6 | import java.io.IOException; 7 | import java.util.ArrayList; 8 | import java.util.HashMap; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | import static dev.triphora.gradle.Constants.*; 13 | 14 | public class QuiltModJsonGenerator implements Generator { 15 | @Override 16 | public void create(Project project) throws IOException { 17 | var extension = Generator.getExtension(project); 18 | 19 | final var side = extension.getSide().get(); 20 | Map modMenuLinks = new HashMap<>(); 21 | modMenuLinks.put("modmenu.github_sponsors", DONATE_LINK); 22 | modMenuLinks.put("modmenu.discord", DISCORD_LINK); 23 | modMenuLinks.put("modmenu.modrinth", "https://modrinth.com/mod/" + extension.getModrinthSlug().get()); 24 | modMenuLinks.putAll(extension.getModMenuLinks().get()); 25 | 26 | var qmj = new QuiltModJson( 27 | 1, 28 | quiltLoader(extension, project), 29 | new QuiltModJson.Minecraft(side.toString()), 30 | new QuiltModJson.ModMenu(modMenuLinks), 31 | extension.getMixin().get() ? project.getName() + ".mixins.json" : null 32 | ); 33 | 34 | Generator.writeFinalResult(project, "quilt.mod.json", qmj); 35 | } 36 | 37 | private QuiltModJson.QuiltLoader quiltLoader(ConfigurationExtension extension, Project project) { 38 | var version = project.getVersion().toString(); 39 | if (version.equals("unspecified")) { 40 | throw new UnsupportedOperationException("Version for " + project.getName() + " is unspecified"); 41 | } 42 | 43 | return new QuiltModJson.QuiltLoader( 44 | GROUP, 45 | project.getName(), 46 | version, 47 | metadata(extension, project.getName()), 48 | INTERMEDIATE_MAPPINGS, 49 | extension.getEntrypoints().getOrNull(), 50 | depends(extension, project) 51 | ); 52 | } 53 | 54 | private QuiltModJson.QuiltLoader.Metadata metadata(ConfigurationExtension extension, String projectName) { 55 | Map contributors = new HashMap<>(); 56 | contributors.put("triphora", "Owner"); 57 | contributors.putAll(extension.getContributors().get()); 58 | 59 | Map contact = new HashMap<>(); 60 | contact.put("email", EMAIL); 61 | contact.put("homepage", "https://modrinth.com/mod/" + extension.getModrinthSlug().get()); 62 | contact.put("issues", ISSUES_LINK); 63 | contact.put("sources", SOURCE_LINK); 64 | contact.put("discord", DISCORD_LINK); 65 | contact.put("donate", DONATE_LINK); 66 | 67 | return new QuiltModJson.QuiltLoader.Metadata( 68 | WordUtils.capitalize(projectName.replaceAll("_", " ")), 69 | extension.getSummary().get(), 70 | contributors, 71 | contact, 72 | extension.getSpdx().get(), 73 | "assets/" + projectName + "/icon.png" 74 | ); 75 | } 76 | 77 | private List depends(ConfigurationExtension extension, Project project) { 78 | List list = new ArrayList<>(); 79 | if (extension.getMidnightlib().get()) { 80 | list.add(new QuiltModJson.QuiltLoader.Dependency( 81 | "midnightlib", 82 | ">=" + project.getConfigurations().getByName("include") 83 | .getResolvedConfiguration().getResolvedArtifacts().stream().filter( 84 | file -> file.getName().equals("midnightlib") 85 | ).iterator().next().getModuleVersion().getId().getVersion(), 86 | "Configuration library" 87 | )); 88 | list.add(new QuiltModJson.QuiltLoader.Dependency( 89 | "modmenu", 90 | ">=" + project.getConfigurations().getByName("modLocalRuntime") 91 | .getResolvedConfiguration().getResolvedArtifacts().stream().filter( 92 | file -> file.getName().equals("modmenu") 93 | ).iterator().next().getModuleVersion().getId().getVersion(), 94 | "To configure the mod", 95 | "client", 96 | true 97 | )); 98 | } 99 | list.add(new QuiltModJson.QuiltLoader.Dependency("java", ">=" + extension.getJavaVersion().get())); 100 | list.addAll(extension.getDepends().get()); 101 | return list; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/dev/triphora/gradle/Side.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.gradle; 2 | 3 | public enum Side { 4 | ANY("*"), 5 | CLIENT("client"), 6 | DEDICATED_SERVER("dedicated_server"); 7 | 8 | private final String string; 9 | 10 | Side(String string) { 11 | this.string = string; 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return string; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /clean_logs/LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /clean_logs/README.md: -------------------------------------------------------------------------------- 1 | **Clean Logs** will filter out logging based on user-defined options, either by a phrase method or a regex method. 2 | 3 | This code is based upon that of [Shut Up Console](https://curseforge.com/projects/396776). While the mod works on 1.17+, I wanted to add a new feature. Also, it had seemed to be abandoned, with the source URL being simply gone. Thus, here's Clean Logs! 4 | 5 | The central idea of Clean Logs is to be able to filter things out from your logs based on the config. You can edit the config at `config/clean-logs/config.toml`. Make sure your [TOML syntax is correct](https://www.toml-lint.com/) before saving - if it's not, it might get wiped! 6 | 7 | The added feature is the ability to turn off printing the lines in the log to filter out. This was my one complaint with Shut Up Console; it filters out the specified lines, but at the same time, it prints out the line to be filtered out. There's a new config option to disable this printing (it's still enabled by default, though). 8 | 9 | Want to add this to your development environment? Check out the [Modrinth Maven](https://docs.modrinth.com/docs/tutorials/maven/). 10 | -------------------------------------------------------------------------------- /clean_logs/build.gradle: -------------------------------------------------------------------------------- 1 | import dev.triphora.gradle.QuiltModJson 2 | 3 | version = '1.2.0' 4 | 5 | outlet { 6 | mcVersionRange = '>=1.18.2' 7 | allowSnapshotsForProject = false 8 | } 9 | 10 | emmod { 11 | mixin = false 12 | summary = 'Filters out messages in the console/log by user-defined filters.' 13 | spdx = 'LGPL-3.0-or-later' 14 | modrinthSlug = 'clean-logs' 15 | javaVersion = 15 16 | gameVersions = outlet.mcVersions() 17 | depends = [new QuiltModJson.QuiltLoader.Dependency( 18 | 'quilt_loader', '>=0.17.0', 'Quilt Config is in use by this project' 19 | )] 20 | contributors = ['Bravarly': 'Former Author'] 21 | entrypoints = [ 22 | "pre_launch": "dev.triphora.clean_logs.CleanLogs", 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /clean_logs/src/main/java/dev/triphora/clean_logs/CleanLogs.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.clean_logs; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | import org.apache.logging.log4j.core.LoggerContext; 6 | import org.quiltmc.loader.api.ModContainer; 7 | import org.quiltmc.loader.api.QuiltLoader; 8 | import org.quiltmc.loader.api.config.QuiltConfig; 9 | import org.quiltmc.loader.api.entrypoint.PreLaunchEntrypoint; 10 | 11 | import java.io.File; 12 | import java.io.IOException; 13 | import java.nio.file.Files; 14 | import java.nio.file.Paths; 15 | import java.util.ArrayList; 16 | 17 | public class CleanLogs implements PreLaunchEntrypoint { 18 | public static final Logger LOGGER = LogManager.getLogger("clean_logs"); 19 | public static final Config CONFIG = QuiltConfig.create("clean-logs", "config", Config.class); 20 | 21 | @Override 22 | public void onPreLaunch(ModContainer mod) { 23 | var newConfigLocation = new File(QuiltLoader.getConfigDir() + "/clean-logs/config.toml"); 24 | if (!newConfigLocation.exists()) migrate(newConfigLocation); 25 | 26 | if (ConfigHelper.PRINT_INIT_LINE) LOGGER.info("=== Clean Logs will filter from this point on. ==="); 27 | 28 | if (ConfigHelper.PRINT_ON_START && !CONFIG.phrases.isEmpty()) { 29 | LOGGER.info("=== Messages containing the following phrases will be filtered out: ==="); 30 | for (var entry : CONFIG.phrases) LOGGER.info(entry); 31 | } 32 | 33 | if (ConfigHelper.PRINT_ON_START && !CONFIG.regex.isEmpty()) { 34 | LOGGER.info("=== Messages matching the regex patterns will be filtered out: ==="); 35 | for (var entry : CONFIG.regex) LOGGER.info(entry); 36 | } 37 | 38 | final var filter = new JavaUtilLog4jFilter(); 39 | System.setOut(new SystemPrintFilter(System.out)); 40 | java.util.logging.Logger.getLogger("").setFilter(filter); 41 | ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).addFilter(filter); 42 | var foundOffshootLog4jLoggers = new ArrayList<>(); 43 | var logContext = (LoggerContext) LogManager.getContext(false); 44 | var map = logContext.getConfiguration().getLoggers(); 45 | 46 | for (var logger : map.values()) { 47 | if (!foundOffshootLog4jLoggers.contains(logger)) { 48 | logger.addFilter(filter); 49 | foundOffshootLog4jLoggers.add(logger); 50 | } 51 | } 52 | } 53 | 54 | public static boolean shouldFilterMessage(String message) { 55 | var stringIterator = CONFIG.phrases.iterator(); 56 | String phrase; 57 | 58 | var regexIterator = CONFIG.regex.iterator(); 59 | String regex; 60 | 61 | do { 62 | if (!stringIterator.hasNext()) { 63 | do { 64 | if (!regexIterator.hasNext()) return false; 65 | regex = regexIterator.next(); 66 | } while (!message.matches(regex)); 67 | return true; 68 | } 69 | phrase = stringIterator.next(); 70 | } while (!message.contains(phrase)); 71 | return true; 72 | } 73 | 74 | private static void migrate(File newConfigLocation) { 75 | var shutUpConsoleConfig = new File(QuiltLoader.getConfigDir() + "/shutupconsole.toml"); 76 | if (shutUpConsoleConfig.exists()) { 77 | LOGGER.warn("You still have an old Shut Up Console config!"); 78 | LOGGER.warn("Migrating it to a Clean Logs config..."); 79 | try { 80 | var path = Paths.get(shutUpConsoleConfig.getPath()); 81 | var content = Files.readString(path); 82 | content = content.replaceAll("Shut Up Console", "Clean Logs"); 83 | content = content.replaceAll("\\[shutupconsole]", """ 84 | # Print out all phrases and regex to be filtered out on startup 85 | # default: true 86 | printOnStart = true 87 | 88 | # Print a single line on start saying that Clean Logs will filter from this point forward 89 | # default: false 90 | printInitLineOnStart = false 91 | """); 92 | Files.writeString(path, content); 93 | //noinspection ResultOfMethodCallIgnored 94 | path.toFile().renameTo(newConfigLocation); 95 | LOGGER.info("Successfully migrated Shut Up Console config to Clean Logs config."); 96 | LOGGER.info("You may need to restart the game for it to take effect."); 97 | } catch (IOException e) { 98 | LOGGER.error("Migration of Shut Up Console config to Clean Logs config failed.", e); 99 | } 100 | } 101 | 102 | var oldCleanLogsConfig = new File(QuiltLoader.getConfigDir() + "/clean-logs.toml"); 103 | if (oldCleanLogsConfig.exists()) { 104 | try { 105 | LOGGER.warn("You still have an old Clean Logs (pre-1.2.0) config!"); 106 | LOGGER.warn("Migrating it to a new Clean Logs config..."); 107 | var path = Paths.get(oldCleanLogsConfig.getPath()); 108 | var content = Files.readString(path); 109 | content = content.replaceAll("\\[clean-logs]", ""); 110 | Files.writeString(path, content); 111 | //noinspection ResultOfMethodCallIgnored 112 | path.toFile().renameTo(newConfigLocation); 113 | LOGGER.info("Successfully migrated old Clean Logs config to new Clean Logs config."); 114 | LOGGER.info("You may need to restart the game for it to take effect."); 115 | } catch (IOException e) { 116 | LOGGER.error("Migration of old Clean Log config to new Clean Logs config failed.", e); 117 | } 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /clean_logs/src/main/java/dev/triphora/clean_logs/Config.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.clean_logs; 2 | 3 | import org.quiltmc.config.api.WrappedConfig; 4 | import org.quiltmc.config.api.annotations.Comment; 5 | import org.quiltmc.config.api.values.ValueList; 6 | 7 | @SuppressWarnings("unused") 8 | public final class Config extends WrappedConfig { 9 | @Comment("Print out all phrases and regex to be filtered out on startup") 10 | public final boolean printOnStart = true; 11 | @Comment("Print a single line on start saying that Clean Logs will filter from this point forward") 12 | public final boolean printInitLineOnStart = false; 13 | @Comment("If a log message has one of these phrases, it will be filtered out from logging") 14 | public final ValueList phrases = ValueList.create(""); 15 | @Comment("If a log message matches one of these regex patterns, it will be filtered out from logging") 16 | public final ValueList regex = ValueList.create(""); 17 | } 18 | -------------------------------------------------------------------------------- /clean_logs/src/main/java/dev/triphora/clean_logs/ConfigHelper.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.clean_logs; 2 | 3 | import org.quiltmc.config.api.values.TrackedValue; 4 | 5 | import java.util.List; 6 | 7 | // Util class for config shenanigans 8 | @SuppressWarnings("unchecked") 9 | final class ConfigHelper { 10 | static final boolean PRINT_ON_START = val("printOnStart"); 11 | static final boolean PRINT_INIT_LINE = val("printInitLineOnStart"); 12 | 13 | private static boolean val(String token) { 14 | return ((TrackedValue) CleanLogs.CONFIG.getValue(List.of(token))).value(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /clean_logs/src/main/java/dev/triphora/clean_logs/JavaUtilLog4jFilter.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.clean_logs; 2 | 3 | import org.apache.logging.log4j.core.LogEvent; 4 | import org.apache.logging.log4j.core.filter.AbstractFilter; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | import java.util.logging.Filter; 8 | import java.util.logging.LogRecord; 9 | 10 | public final class JavaUtilLog4jFilter extends AbstractFilter implements Filter { 11 | public boolean isLoggable(@NotNull LogRecord record) { 12 | return !CleanLogs.shouldFilterMessage(record.getMessage()); 13 | } 14 | 15 | public Result filter(@NotNull LogEvent event) { 16 | return CleanLogs.shouldFilterMessage("[" + event.getLoggerName() + "]: " + event.getMessage().getFormattedMessage()) ? Result.DENY : Result.NEUTRAL; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /clean_logs/src/main/java/dev/triphora/clean_logs/SystemPrintFilter.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.clean_logs; 2 | 3 | import java.io.PrintStream; 4 | 5 | public final class SystemPrintFilter extends PrintStream { 6 | public SystemPrintFilter(PrintStream stream) { 7 | super(stream); 8 | } 9 | 10 | @Override 11 | public void println(String x) { 12 | if (!CleanLogs.shouldFilterMessage(x)) super.println(x); 13 | } 14 | 15 | @Override 16 | public void print(String s) { 17 | if (!CleanLogs.shouldFilterMessage(s)) super.print(s); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /clean_logs/src/main/resources/assets/clean_logs/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triphora/quilt_mods/09db38a5a29eefb7178a56d10347548beea74c8a/clean_logs/src/main/resources/assets/clean_logs/icon.png -------------------------------------------------------------------------------- /compass_commands/README.md: -------------------------------------------------------------------------------- 1 | **Compass Commands** adds a few commands to set the compass target. This mod can be either on the server or the client; it works either way. 2 | - `/compass set x y z` - Sets the compass target to the coordinates. The `y` doesn't really matter, but it has to be there anyway. `~` can be used. 3 | - `/compass north|south|east|west|northwest|northeast|southwest|southeast` - Sets the compass target to the specified cardinal direction. 4 | - `/compass spawn` - Sets the compass target to the world spawn. 5 | - `/compass current` - Functionally equivalent to `/compass set ~ ~ ~`. 6 | -------------------------------------------------------------------------------- /compass_commands/build.gradle: -------------------------------------------------------------------------------- 1 | import dev.triphora.gradle.QuiltModJson 2 | 3 | version = '1.1.1' 4 | 5 | emmod { 6 | qsl = true 7 | mixin = false 8 | summary = 'Adds some commands for setting the compass target.' 9 | modrinthSlug = 'compass-commands' 10 | depends = [ 11 | new QuiltModJson.QuiltLoader.Dependency('quilt_base'), 12 | new QuiltModJson.QuiltLoader.Dependency('quilt_resource_loader'), 13 | new QuiltModJson.QuiltLoader.Dependency('quilt_command'), 14 | new QuiltModJson.QuiltLoader.Dependency('quilt_client_command', '*', 'Client-side-only commands', 'client', false), 15 | ] 16 | entrypoints = [ 17 | 'client_events': 'dev.triphora.compass_commands.CompassCommandsClient', 18 | 'server_events': 'dev.triphora.compass_commands.CompassCommandsServer', 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /compass_commands/src/main/java/dev/triphora/compass_commands/CompassCommandsClient.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.compass_commands; 2 | 3 | import com.mojang.brigadier.CommandDispatcher; 4 | import com.mojang.brigadier.builder.LiteralArgumentBuilder; 5 | import com.mojang.brigadier.tree.LiteralCommandNode; 6 | import net.minecraft.client.MinecraftClient; 7 | import net.minecraft.command.CommandBuildContext; 8 | import net.minecraft.command.argument.BlockPosArgumentType; 9 | import net.minecraft.command.argument.DefaultPosArgument; 10 | import net.minecraft.server.command.CommandManager; 11 | import net.minecraft.server.command.ServerCommandSource; 12 | import net.minecraft.text.Text; 13 | import net.minecraft.util.math.BlockPos; 14 | import net.minecraft.util.math.Vec3d; 15 | import org.quiltmc.qsl.command.api.client.ClientCommandManager; 16 | import org.quiltmc.qsl.command.api.client.ClientCommandRegistrationCallback; 17 | import org.quiltmc.qsl.command.api.client.QuiltClientCommandSource; 18 | 19 | import static org.quiltmc.qsl.command.api.client.ClientCommandManager.literal; 20 | 21 | public class CompassCommandsClient implements ClientCommandRegistrationCallback { 22 | private static final int LIMIT = 29999872; 23 | private static final MinecraftClient client = MinecraftClient.getInstance(); 24 | 25 | @Override 26 | public void registerCommands(CommandDispatcher dispatcher, CommandBuildContext buildContext, CommandManager.RegistrationEnvironment environment) { 27 | LiteralCommandNode compassCommand = dispatcher.register(literal("compass") 28 | .then(literal("set").then(ClientCommandManager.argument("pos", BlockPosArgumentType.blockPos()) 29 | .executes(c -> { 30 | ServerCommandSource fakeSource = new ServerCommandSource(null, client.player.getPos(), null, null, 0, null, null, null, null); 31 | return setTarget(c.getArgument("pos", DefaultPosArgument.class).toAbsolutePos(fakeSource)); 32 | }))) 33 | .then(fixedLocation("north", 0, -LIMIT)) 34 | .then(fixedLocation("south", 0, LIMIT)) 35 | .then(fixedLocation("east", LIMIT, 0)) 36 | .then(fixedLocation("west", -LIMIT, 0)) 37 | .then(fixedLocation("northwest", -LIMIT, -LIMIT)) 38 | .then(fixedLocation("northeast", LIMIT, -LIMIT)) 39 | .then(fixedLocation("southwest", -LIMIT, LIMIT)) 40 | .then(fixedLocation("southeast", LIMIT, LIMIT)) 41 | .then(literal("spawn").executes(c -> setTarget(c.getSource().getPlayer().clientWorld.getSpawnPos()))) 42 | .then(literal("current").executes(c -> setTarget(c.getSource().getPlayer().getPos()))) 43 | ); 44 | dispatcher.register(literal("comp").redirect(compassCommand)); 45 | } 46 | 47 | private static LiteralArgumentBuilder fixedLocation(String command, int x, int z) { 48 | return literal(command).executes(c -> setTarget(new BlockPos(x, 64, z))); 49 | } 50 | 51 | private static int setTarget(Vec3d vec) { 52 | return setTarget(BlockPos.fromPosition(vec)); 53 | } 54 | 55 | private static int setTarget(BlockPos pos) { 56 | client.world.setSpawnPos(pos, 0); 57 | client.player.sendMessage(Text.translatable("compass_commands.success", pos.getX(), pos.getY(), pos.getZ()), true); 58 | return 1; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /compass_commands/src/main/java/dev/triphora/compass_commands/CompassCommandsServer.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.compass_commands; 2 | 3 | import com.mojang.brigadier.CommandDispatcher; 4 | import com.mojang.brigadier.builder.LiteralArgumentBuilder; 5 | import com.mojang.brigadier.tree.LiteralCommandNode; 6 | import net.minecraft.command.CommandBuildContext; 7 | import net.minecraft.command.argument.BlockPosArgumentType; 8 | import net.minecraft.command.argument.DefaultPosArgument; 9 | import net.minecraft.network.packet.s2c.play.PlayerSpawnPositionUpdateS2CPacket; 10 | import net.minecraft.server.command.CommandManager; 11 | import net.minecraft.server.command.ServerCommandSource; 12 | import net.minecraft.server.network.ServerPlayerEntity; 13 | import net.minecraft.text.Text; 14 | import net.minecraft.util.math.BlockPos; 15 | import net.minecraft.util.math.Vec3d; 16 | import org.quiltmc.qsl.command.api.CommandRegistrationCallback; 17 | 18 | import static net.minecraft.server.command.CommandManager.literal; 19 | 20 | public class CompassCommandsServer implements CommandRegistrationCallback { 21 | private static final int LIMIT = 29999872; 22 | 23 | @Override 24 | public void registerCommands(CommandDispatcher dispatcher, CommandBuildContext buildContext, CommandManager.RegistrationEnvironment environment) { 25 | LiteralCommandNode compassCommand = dispatcher.register(literal("compass") 26 | .then(literal("set") 27 | .then(CommandManager.argument("pos", BlockPosArgumentType.blockPos()) 28 | .executes(c -> setTarget(c.getArgument("pos", DefaultPosArgument.class) 29 | .toAbsolutePos(c.getSource()), c.getSource().getPlayer())))) 30 | .then(fixedLocation("north", 0, -LIMIT)) 31 | .then(fixedLocation("south", 0, LIMIT)) 32 | .then(fixedLocation("east", LIMIT, 0)) 33 | .then(fixedLocation("west", -LIMIT, 0)) 34 | .then(fixedLocation("northwest", -LIMIT, -LIMIT)) 35 | .then(fixedLocation("northeast", LIMIT, -LIMIT)) 36 | .then(fixedLocation("southwest", -LIMIT, LIMIT)) 37 | .then(fixedLocation("southeast", LIMIT, LIMIT)) 38 | .then(literal("spawn").executes(c -> setTarget(c.getSource().getPlayer().getSpawnPointPosition(), c.getSource().getPlayer()))) 39 | .then(literal("current").executes(c -> setTarget(c.getSource().getPlayer().getPos(), c.getSource().getPlayer()))) 40 | ); 41 | dispatcher.register(literal("comp").redirect(compassCommand)); 42 | } 43 | 44 | private static LiteralArgumentBuilder fixedLocation(String command, int x, int z) { 45 | return literal(command).executes(c -> setTarget(new BlockPos(x, 64, z), c.getSource().getPlayer())); 46 | } 47 | 48 | private static int setTarget(Vec3d vec, ServerPlayerEntity player) { 49 | return setTarget(BlockPos.fromPosition(vec), player); 50 | } 51 | 52 | private static int setTarget(BlockPos pos, ServerPlayerEntity player) { 53 | player.networkHandler.sendPacket(new PlayerSpawnPositionUpdateS2CPacket(pos, 0)); 54 | player.sendMessage(Text.of("§bSet compass target to §f" + pos.getX() + ", " + pos.getY() + ", " + pos.getZ()), true); 55 | return 1; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /compass_commands/src/main/resources/assets/compass_commands/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triphora/quilt_mods/09db38a5a29eefb7178a56d10347548beea74c8a/compass_commands/src/main/resources/assets/compass_commands/icon.png -------------------------------------------------------------------------------- /compass_commands/src/main/resources/assets/compass_commands/lang/en_us.json: -------------------------------------------------------------------------------- 1 | { 2 | "compass_commands.success": "§bSet compass target to %s, %s, %s" 3 | } 4 | -------------------------------------------------------------------------------- /emmod/LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /emmod/README.md: -------------------------------------------------------------------------------- 1 | **Emmod** should not be used by anyone other than myself. 2 | -------------------------------------------------------------------------------- /emmod/build.gradle: -------------------------------------------------------------------------------- 1 | import dev.triphora.gradle.Side 2 | 3 | version = '1.0.0' 4 | 5 | emmod { 6 | summary = 'A mod which should only be used by Emma.' 7 | side = Side.CLIENT 8 | mixinPlugin = 'dev.triphora.emmod.NarratorOffTransformer' 9 | } 10 | 11 | dependencies { 12 | implementation(files 'unsafe-1.7.1.jar') 13 | include(files 'unsafe-1.7.1.jar') 14 | } 15 | 16 | tasks.modrinth.enabled = false 17 | tasks.modrinthSyncBody.enabled = false 18 | -------------------------------------------------------------------------------- /emmod/src/main/java/dev/triphora/emmod/NarratorOffTransformer.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.emmod; 2 | 3 | import java.io.IOException; 4 | import java.util.List; 5 | import java.util.Set; 6 | import net.gudenau.lib.unsafe.Unsafe; 7 | import org.objectweb.asm.ClassReader; 8 | import org.objectweb.asm.ClassWriter; 9 | import org.objectweb.asm.Opcodes; 10 | import org.objectweb.asm.tree.ClassNode; 11 | import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; 12 | import org.spongepowered.asm.mixin.extensibility.IMixinInfo; 13 | import org.spongepowered.asm.transformers.MixinClassWriter; 14 | 15 | // Code from auoeke's narrator-off, licensed LGPL-3.0 16 | public class NarratorOffTransformer implements IMixinConfigPlugin { 17 | public void onLoad(String mixinPackage) {} 18 | public String getRefMapperConfig() { return null; } 19 | public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { return true; } 20 | public void acceptTargets(Set myTargets, Set otherTargets) {} 21 | public List getMixins() { return null; } 22 | public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {} 23 | public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {} 24 | 25 | static { 26 | try { 27 | var node = new ClassNode(); 28 | //noinspection DataFlowIssue 29 | new ClassReader(NarratorOffTransformer.class.getResourceAsStream("/com/mojang/text2speech/Narrator.class")).accept(node, 0); 30 | 31 | for (var method : node.methods) { 32 | if (method.name.equals("getNarrator")) { 33 | method.instructions.clear(); 34 | method.tryCatchBlocks = null; 35 | 36 | method.visitTypeInsn(Opcodes.NEW, "com/mojang/text2speech/NarratorDummy"); 37 | method.visitInsn(Opcodes.DUP); 38 | method.visitMethodInsn(Opcodes.INVOKESPECIAL, "com/mojang/text2speech/NarratorDummy", "", "()V", false); 39 | method.visitInsn(Opcodes.ARETURN); 40 | 41 | break; 42 | } 43 | } 44 | 45 | var writer = new MixinClassWriter(ClassWriter.COMPUTE_FRAMES); 46 | node.accept(writer); 47 | var bytecode = writer.toByteArray(); 48 | Unsafe.defineClass("com.mojang.text2speech.Narrator", bytecode, 0, bytecode.length, ClassLoader.getSystemClassLoader(), null); 49 | } catch (IOException exception) { 50 | throw Unsafe.throwException(exception); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /emmod/src/main/java/dev/triphora/emmod/mixin/MinecraftClientMixin.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.emmod.mixin; 2 | 3 | import com.mojang.authlib.minecraft.UserApiService; 4 | import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; 5 | import net.minecraft.client.MinecraftClient; 6 | import net.minecraft.client.RunArgs; 7 | import org.quiltmc.loader.api.QuiltLoader; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Inject; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 12 | 13 | // Code from auoeke's noauth, licensed Unlicense 14 | @Mixin(MinecraftClient.class) 15 | abstract class MinecraftClientMixin { 16 | @Inject(method = "createUserApiService", at = @At("HEAD"), cancellable = true) 17 | void emmod$offlineUserInDevEnv(YggdrasilAuthenticationService authService, RunArgs runArgs, CallbackInfoReturnable cir) { 18 | if (QuiltLoader.isDevelopmentEnvironment()) cir.setReturnValue(UserApiService.OFFLINE); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /emmod/unsafe-1.7.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triphora/quilt_mods/09db38a5a29eefb7178a56d10347548beea74c8a/emmod/unsafe-1.7.1.jar -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # suppress inspection "UnusedProperty" for whole file 2 | org.gradle.jvmargs = -Xmx6G 3 | org.gradle.parallel = true 4 | -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | minecraft = '1.19.4' 3 | 4 | [libraries] 5 | # https://lambdaurora.dev/tools/import_quilt.html 6 | minecraft = { module = 'com.mojang:minecraft', version.ref = 'minecraft' } 7 | quilt_mappings = 'org.quiltmc:quilt-mappings:1.19.4+build.3' 8 | quilt_loader = 'org.quiltmc:quilt-loader:0.18.5' 9 | quilted_fabric_api = 'org.quiltmc.quilted-fabric-api:quilted-fabric-api:6.0.0-beta.2+0.76.0-1.19.4' 10 | 11 | mod_menu = 'maven.modrinth:modmenu:6.1.0-rc.1' 12 | midnightlib = 'maven.modrinth:midnightlib:1.2.1-fabric' 13 | 14 | sodium = 'maven.modrinth:sodium:mc1.19.4-0.4.10' 15 | lithium = 'maven.modrinth:lithium:mc1.19.4-0.11.1' 16 | starlight = 'maven.modrinth:starlight:1.1.1+1.19' 17 | ebe = 'maven.modrinth:ebe:0.7.1+1.19' 18 | arrp = 'maven.modrinth:arrp:0.6.4' 19 | dynamic_fps = 'maven.modrinth:dynamic-fps:v2.2.0' 20 | toml4j = 'com.moandjiezana.toml:toml4j:0.7.2' 21 | forget_me_chunk = 'maven.modrinth:forgetmechunk:1.0.4' 22 | 23 | [bundles] 24 | runtime = [ 25 | # TODO readd EBE, Memory Leak Fix, FerriteCore 26 | 'quilted_fabric_api', 'mod_menu', 27 | 'sodium', 'lithium', 'starlight', 'dynamic_fps', 'toml4j', 'forget_me_chunk', 28 | ] 29 | 30 | [plugins] 31 | quilt_loom = 'org.quiltmc.loom:1.1.+' 32 | minotaur = 'com.modrinth.minotaur:2.+' 33 | machete = 'io.github.p03w.machete:1.+' 34 | outlet = 'io.github.dexman545.outlet:1.5.+' 35 | -------------------------------------------------------------------------------- /only_pink_sheeps/README.md: -------------------------------------------------------------------------------- 1 | **Only Pink Sheep** is fairly self-explanatory: every sheep you encounter in the wild is going to be pink. 2 | 3 | Configuration options to customize the sheep colours is coming soon. 4 | -------------------------------------------------------------------------------- /only_pink_sheeps/build.gradle: -------------------------------------------------------------------------------- 1 | import dev.triphora.gradle.QuiltModJson 2 | import dev.triphora.gradle.Side 3 | 4 | version = '1.0.0' 5 | outlet.mcVersionRange = '>=1.19-alpha.22.14.a' 6 | 7 | emmod { 8 | summary = 'Never encounter any other sheep colour in nature, ever again.' 9 | side = Side.DEDICATED_SERVER 10 | gameVersions = outlet.mcVersions() 11 | depends = [ 12 | new QuiltModJson.QuiltLoader.Dependency('minecraft', '>=1.19-alpha.22.14.a'), 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /only_pink_sheeps/src/main/java/dev/triphora/only_pink_sheeps/mixin/SheepEntityMixin.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.only_pink_sheeps.mixin; 2 | 3 | import net.minecraft.entity.passive.SheepEntity; 4 | import net.minecraft.util.DyeColor; 5 | import net.minecraft.util.random.RandomGenerator; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.Overwrite; 8 | 9 | @Mixin(SheepEntity.class) 10 | abstract class SheepEntityMixin { 11 | /** 12 | * @author triphora 13 | * @reason Always make sheep pink! 14 | */ 15 | @Overwrite 16 | public static DyeColor generateDefaultColor(RandomGenerator random) { 17 | return DyeColor.PINK; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /only_pink_sheeps/src/main/resources/assets/only_pink_sheeps/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triphora/quilt_mods/09db38a5a29eefb7178a56d10347548beea74c8a/only_pink_sheeps/src/main/resources/assets/only_pink_sheeps/icon.png -------------------------------------------------------------------------------- /orientation/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Bert Shuler 2 | Copyright (c) 2021—2023 triphora 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | -------------------------------------------------------------------------------- /orientation/README.md: -------------------------------------------------------------------------------- 1 | **Orientation** is a fork of TheCritic's [Critical Orientation](https://github.com/bshuler/critical-orientation) mod with a few changes made to suit my needs, updated to modern Minecraft versions. 2 | 3 | Pressing backslash (`\`) will snap your camera angle to a multiple of 45 degrees. Change the keybind in settings if you so wish. There's also another key (`j`) which can snap to a configurable angle. 4 | 5 | The `/align` command also allows you to align to an arbitrary amount of degrees. 6 | -------------------------------------------------------------------------------- /orientation/build.gradle: -------------------------------------------------------------------------------- 1 | import dev.triphora.gradle.QuiltModJson 2 | import dev.triphora.gradle.Side 3 | 4 | version = '3.0.2' 5 | 6 | emmod { 7 | midnightlib = true 8 | mixin = false 9 | summary = 'Snaps the player direction to cardinal directions.' 10 | spdx = 'MIT' 11 | side = Side.CLIENT 12 | depends = [ 13 | new QuiltModJson.QuiltLoader.Dependency('quilt_base'), 14 | new QuiltModJson.QuiltLoader.Dependency('quilt_client_command'), 15 | new QuiltModJson.QuiltLoader.Dependency('quilt_lifecycle_events'), 16 | ] 17 | contributors = ['TheCritic': 'Former Author'] 18 | entrypoints = [ 19 | 'client_init': 'dev.triphora.orientation.Orientation', 20 | 'client_events': 'dev.triphora.orientation.Orientation' 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /orientation/src/main/java/dev/triphora/orientation/Orientation.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.orientation; 2 | 3 | import com.mojang.brigadier.CommandDispatcher; 4 | import com.mojang.brigadier.arguments.FloatArgumentType; 5 | import com.mojang.logging.LogUtils; 6 | import eu.midnightdust.lib.config.MidnightConfig; 7 | import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; 8 | import net.minecraft.client.MinecraftClient; 9 | import net.minecraft.client.option.KeyBind; 10 | import net.minecraft.command.CommandBuildContext; 11 | import net.minecraft.server.command.CommandManager; 12 | import net.minecraft.text.Text; 13 | import org.quiltmc.loader.api.ModContainer; 14 | import org.quiltmc.qsl.base.api.entrypoint.client.ClientModInitializer; 15 | import org.quiltmc.qsl.command.api.client.ClientCommandManager; 16 | import org.quiltmc.qsl.command.api.client.ClientCommandRegistrationCallback; 17 | import org.quiltmc.qsl.command.api.client.QuiltClientCommandSource; 18 | import org.quiltmc.qsl.lifecycle.api.client.event.ClientTickEvents; 19 | 20 | import static org.lwjgl.glfw.GLFW.GLFW_KEY_BACKSLASH; 21 | import static org.lwjgl.glfw.GLFW.GLFW_KEY_J; 22 | 23 | public class Orientation implements ClientModInitializer, ClientTickEvents.End, ClientCommandRegistrationCallback { 24 | private static final String CATEGORY = "orientation.category"; 25 | private static final MinecraftClient client = MinecraftClient.getInstance(); 26 | private static final KeyBind alignPlayer; 27 | private static final KeyBind alignPlayerConfigurable; 28 | 29 | static { 30 | alignPlayer = new KeyBind("key.orientation.align", GLFW_KEY_BACKSLASH, CATEGORY); 31 | alignPlayerConfigurable = new KeyBind("key.orientation.align-configurable", GLFW_KEY_J, CATEGORY); 32 | } 33 | 34 | @Override 35 | public void onInitializeClient(ModContainer mod) { 36 | MidnightConfig.init(mod.metadata().id(), Config.class); 37 | 38 | KeyBindingHelper.registerKeyBinding(alignPlayer); 39 | KeyBindingHelper.registerKeyBinding(alignPlayerConfigurable); 40 | } 41 | 42 | @Override 43 | public void endClientTick(MinecraftClient client) { 44 | if (alignPlayer.wasPressed()) align(); 45 | if (alignPlayerConfigurable.wasPressed()) setPlayerYaw(Config.customAlignment); 46 | } 47 | 48 | @Override 49 | public void registerCommands(CommandDispatcher dispatcher, CommandBuildContext buildContext, CommandManager.RegistrationEnvironment environment) { 50 | dispatcher.register(ClientCommandManager.literal("align") 51 | .then(ClientCommandManager.argument("yaw", FloatArgumentType.floatArg(-180, 180)).executes(c -> { 52 | setPlayerYaw(FloatArgumentType.getFloat(c, "yaw")); 53 | return 1; 54 | })) 55 | .executes(c -> { 56 | this.align(); 57 | return 1; 58 | }) 59 | ); 60 | } 61 | 62 | private static double roundYaw(double yaw) { 63 | yaw = yaw % 360; 64 | if (yaw > 180 || yaw < -180) { 65 | double mod = yaw % 180; 66 | if (mod > 0) yaw = -180 + mod; 67 | else if (mod < 0) yaw = 180 + mod; 68 | } 69 | 70 | if (yaw >= 0 && yaw < 22.5) yaw = 0; 71 | if (yaw >= 22.5 && yaw < 67.5) yaw = 45; 72 | if (yaw >= 67.5 && yaw < 112.5) yaw = 90; 73 | if (yaw >= 112.5 && yaw < 157.5) yaw = 135; 74 | if (yaw >= 157.5 && yaw <= 180) yaw = 180; 75 | if (yaw <= 0 && yaw > -22.5) yaw = 0; 76 | if (yaw <= -22.5 && yaw > -67.5) yaw = -45; 77 | if (yaw <= -67.5 && yaw > -112.5) yaw = -90; 78 | if (yaw <= -112.5 && yaw > -157.5) yaw = -135; 79 | if (yaw <= -157.5 && yaw >= -180) yaw = 180; 80 | 81 | return yaw; 82 | } 83 | 84 | private void align() { 85 | //noinspection ConstantConditions 86 | final double oldYaw = client.player.getHeadYaw(); 87 | final double newYaw = roundYaw(oldYaw); 88 | 89 | LogUtils.getLogger().debug("Yaw {} rounds to {}", oldYaw, newYaw); 90 | 91 | setPlayerYaw(newYaw); 92 | } 93 | 94 | private void setPlayerYaw(double yaw) { 95 | final var player = client.player; 96 | 97 | //noinspection ConstantConditions 98 | player.refreshPositionAndAngles(player.getX(), player.getY(), player.getZ(), (float) yaw, player.getPitch(0)); 99 | player.sendMessage(Text.translatable("orientation.success", yaw), true); 100 | } 101 | 102 | public static class Config extends MidnightConfig { 103 | @Comment public static Comment comment; 104 | @Entry(min = 0, max = 360) public static double customAlignment; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /orientation/src/main/resources/assets/orientation/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triphora/quilt_mods/09db38a5a29eefb7178a56d10347548beea74c8a/orientation/src/main/resources/assets/orientation/icon.png -------------------------------------------------------------------------------- /orientation/src/main/resources/assets/orientation/lang/en_us.json: -------------------------------------------------------------------------------- 1 | { 2 | "orientation.midnightconfig.title": "Orientation Config", 3 | "orientation.midnightconfig.comment": "To use negative values, take the absolute value and subtract that from 360. For example, -160 becomes 200.", 4 | "orientation.midnightconfig.customAlignment": "Configurable direction value", 5 | 6 | "orientation.category": "Orientation", 7 | "orientation.align": "Snap to direction", 8 | "orientation.align_configurable": "Snap to configurable direction", 9 | 10 | "orientation.success": "Aligned your direction to %s!" 11 | } 12 | -------------------------------------------------------------------------------- /repeat_no_more/README.md: -------------------------------------------------------------------------------- 1 | **Repeat No More** makes it so that you can't tick a repeater no mo' once it reaches full delay, made by request of my friend [unixbrain](https://u.emc.gs/unixbrain). 2 | 3 | Press shift to override it and tick it over anyway. It also has a config option accessible from [Mod Menu](https://modrinth.com/mod/mod-menu) if you want to disable the mod entirely. 4 | 5 | [Video demonstration](https://cdn.discordapp.com/attachments/734276873529458688/941894777312530462/2022-02-11_22.12.27.webm) 6 | -------------------------------------------------------------------------------- /repeat_no_more/build.gradle: -------------------------------------------------------------------------------- 1 | import dev.triphora.gradle.QuiltModJson 2 | import dev.triphora.gradle.Side 3 | 4 | version = '2.0.0' 5 | 6 | outlet { 7 | mcVersionRange = '>=1.19' 8 | allowSnapshotsForProject = false 9 | } 10 | 11 | emmod { 12 | midnightlib = true 13 | summary = "Make it so that you can't tick a repeater no mo' once it reaches full delay." 14 | modrinthSlug = 'repeat-no-more' 15 | side = Side.CLIENT 16 | gameVersions = outlet.mcVersions() 17 | depends = [ 18 | new QuiltModJson.QuiltLoader.Dependency('quilt_base'), 19 | new QuiltModJson.QuiltLoader.Dependency('quilt_resource_loader'), 20 | ] 21 | entrypoints = [ 22 | 'client_init': 'dev.triphora.repeat_no_more.RepeatNoMore', 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /repeat_no_more/src/main/java/dev/triphora/repeat_no_more/RepeatNoMore.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.repeat_no_more; 2 | 3 | import eu.midnightdust.lib.config.MidnightConfig; 4 | import org.quiltmc.loader.api.ModContainer; 5 | import org.quiltmc.qsl.base.api.entrypoint.client.ClientModInitializer; 6 | 7 | public class RepeatNoMore implements ClientModInitializer { 8 | @Override 9 | public void onInitializeClient(ModContainer mod) { 10 | MidnightConfig.init(mod.metadata().id(), Config.class); 11 | } 12 | 13 | public static class Config extends MidnightConfig { 14 | @Entry public static boolean enableMod = true; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /repeat_no_more/src/main/java/dev/triphora/repeat_no_more/mixin/RepeaterBlockMixin.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.repeat_no_more.mixin; 2 | 3 | import dev.triphora.repeat_no_more.RepeatNoMore; 4 | import net.minecraft.block.BlockState; 5 | import net.minecraft.block.RepeaterBlock; 6 | import net.minecraft.entity.player.PlayerEntity; 7 | import net.minecraft.state.property.IntProperty; 8 | import net.minecraft.text.Text; 9 | import net.minecraft.util.ActionResult; 10 | import net.minecraft.util.Hand; 11 | import net.minecraft.util.hit.BlockHitResult; 12 | import net.minecraft.util.math.BlockPos; 13 | import net.minecraft.world.World; 14 | import org.spongepowered.asm.mixin.Final; 15 | import org.spongepowered.asm.mixin.Mixin; 16 | import org.spongepowered.asm.mixin.Shadow; 17 | import org.spongepowered.asm.mixin.injection.At; 18 | import org.spongepowered.asm.mixin.injection.Inject; 19 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 20 | 21 | @Mixin(RepeaterBlock.class) 22 | abstract class RepeaterBlockMixin { 23 | @Shadow @Final public static IntProperty DELAY; 24 | 25 | @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) 26 | void repeat_no_more$onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { 27 | if (state.get(DELAY) == 4 && !player.isSneaking() && RepeatNoMore.Config.enableMod) { 28 | player.sendMessage(Text.translatable("repeat_no_more.prevented"), true); 29 | cir.setReturnValue(ActionResult.PASS); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /repeat_no_more/src/main/resources/assets/repeat_no_more/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triphora/quilt_mods/09db38a5a29eefb7178a56d10347548beea74c8a/repeat_no_more/src/main/resources/assets/repeat_no_more/icon.png -------------------------------------------------------------------------------- /repeat_no_more/src/main/resources/assets/repeat_no_more/lang/en_us.json: -------------------------------------------------------------------------------- 1 | { 2 | "repeat_no_more.midnightconfig.title": "Repeat No More Config", 3 | "repeat_no_more.midnightconfig.enableMod": "Enable/disable the mod", 4 | "repeat_no_more.prevented": "§a§lRepeat No More§r has prevented this action" 5 | } 6 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | exclusiveContent { 4 | forRepository { 5 | maven { 6 | name = 'Quilt' 7 | url = 'https://maven.quiltmc.org/repository/release' 8 | } 9 | } 10 | filter { 11 | includeGroupByRegex 'org.quiltmc(.*)?' 12 | } 13 | } 14 | exclusiveContent { 15 | forRepository { 16 | maven { 17 | name = 'Fabric' 18 | url = 'https://maven.fabricmc.net' 19 | } 20 | } 21 | filter { 22 | includeGroup 'net.fabricmc' 23 | } 24 | } 25 | gradlePluginPortal() 26 | } 27 | } 28 | 29 | include 'beelightful' 30 | include 'clean_logs' 31 | include 'compass_commands' 32 | include 'emmod' 33 | include 'only_pink_sheeps' 34 | include 'orientation' 35 | include 'repeat_no_more' 36 | include 'wake_up_time' 37 | -------------------------------------------------------------------------------- /wake_up_time/README.md: -------------------------------------------------------------------------------- 1 | **Wake Up Time**, made by request of my friend [unixbrain](https://u.emc.gs/unixbrain), lets you figure out what stage of the day (i.e. work cycle) your villagers are in. 2 | 3 | Press `V` (standing for Villager, configurable in key binds) for an action bar notification about what working stage your villagers are in and how long it'll take to get to working time. if it's currently working time, it'll say how much longer remains until working time is over. 4 | 5 | If you want to configure it to be persistent, you can do so via [Mod Menu](https://modrinth.com/mod/modmenu). 6 | 7 | This is named after Tom Petty's [Wake Up Time](https://youtu.be/nS2C8BmHP-c), a legendary song on his Wildflowers album. 8 | 9 | [Demonstration](https://streamable.com/4gzfb4) 10 | -------------------------------------------------------------------------------- /wake_up_time/build.gradle: -------------------------------------------------------------------------------- 1 | import dev.triphora.gradle.QuiltModJson 2 | import dev.triphora.gradle.Side 3 | 4 | version = '1.2.1' 5 | 6 | emmod { 7 | midnightlib = true 8 | mixin = false 9 | summary = 'Figure out what stage of the day your villagers are in.' 10 | modrinthSlug = 'wake-up-time' 11 | side = Side.CLIENT 12 | depends = [ 13 | new QuiltModJson.QuiltLoader.Dependency('quilt_base'), 14 | new QuiltModJson.QuiltLoader.Dependency('quilt_lifecycle_events'), 15 | new QuiltModJson.QuiltLoader.Dependency('quilt_resource_loader'), 16 | new QuiltModJson.QuiltLoader.Dependency('quilted_fabric_key_binding_api_v1'), 17 | ] 18 | entrypoints = [ 19 | 'client_init': 'dev.triphora.wake_up_time.WakeUpTime', 20 | 'client_events': 'dev.triphora.wake_up_time.WakeUpTime', 21 | ] 22 | modMenuLinks = ['wake_up_time.name_credits': 'https://youtu.be/nS2C8BmHP-c'] 23 | } 24 | -------------------------------------------------------------------------------- /wake_up_time/src/main/java/dev/triphora/wake_up_time/WakeUpTime.java: -------------------------------------------------------------------------------- 1 | package dev.triphora.wake_up_time; 2 | 3 | import eu.midnightdust.lib.config.MidnightConfig; 4 | import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; 5 | import net.minecraft.client.MinecraftClient; 6 | import net.minecraft.client.option.KeyBind; 7 | import net.minecraft.text.MutableText; 8 | import net.minecraft.text.Text; 9 | import org.quiltmc.loader.api.ModContainer; 10 | import org.quiltmc.qsl.base.api.entrypoint.client.ClientModInitializer; 11 | import org.quiltmc.qsl.lifecycle.api.client.event.ClientTickEvents; 12 | 13 | import static org.lwjgl.glfw.GLFW.GLFW_KEY_V; 14 | 15 | public class WakeUpTime implements ClientModInitializer, ClientTickEvents.End { 16 | private static final String CATEGORY = "wake_up_time.category"; 17 | private static final MinecraftClient client = MinecraftClient.getInstance(); 18 | private boolean pressed = false; 19 | private static final KeyBind sendStatusToActionBar; 20 | 21 | static { 22 | sendStatusToActionBar = new KeyBind("wake_up_time.send_status", GLFW_KEY_V, CATEGORY); 23 | } 24 | 25 | @Override 26 | public void onInitializeClient(ModContainer mod) { 27 | MidnightConfig.init(mod.metadata().id(), Config.class); 28 | KeyBindingHelper.registerKeyBinding(sendStatusToActionBar); 29 | } 30 | 31 | @Override 32 | public void endClientTick(MinecraftClient client) { 33 | if (sendStatusToActionBar.wasPressed()) { 34 | pressed = !pressed; 35 | sendStatusToActionBar(); 36 | } 37 | if (Config.persistent && pressed) sendStatusToActionBar(); 38 | } 39 | 40 | private void sendStatusToActionBar() { 41 | if (client.world == null || client.player == null) return; 42 | client.player.sendMessage(Text.translatable("wake_up_time.status", getStage()), true); 43 | } 44 | 45 | private MutableText getStage() { 46 | @SuppressWarnings("ConstantConditions") long time = client.world.getTimeOfDay(); 47 | while (time > 24000) time = time - 24000; 48 | 49 | if (time < 9000 && time >= 2000) { 50 | return Text.translatable("wake_up_time.working", null, "§a" + (9000 - time) / 20); 51 | } 52 | 53 | MutableText status = Text.translatable("wake_up_time.wandering"); 54 | if (time >= 12000 || time < 10) status = Text.translatable("wake_up_time.sleeping"); 55 | if (time >= 9000 && time < 11000) status = Text.translatable("wake_up_time.gathering"); 56 | 57 | final long timeUntilWork = time > 9000 ? 26000 - time : 2000 - time; 58 | 59 | return Text.translatable("wake_up_time.lazy_bums", null, "§a" + status.getString(), "§a" + timeUntilWork / 20); 60 | } 61 | 62 | public static class Config extends MidnightConfig { 63 | @Entry public static boolean persistent = false; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /wake_up_time/src/main/resources/assets/wake_up_time/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/triphora/quilt_mods/09db38a5a29eefb7178a56d10347548beea74c8a/wake_up_time/src/main/resources/assets/wake_up_time/icon.png -------------------------------------------------------------------------------- /wake_up_time/src/main/resources/assets/wake_up_time/lang/en_us.json: -------------------------------------------------------------------------------- 1 | { 2 | "wake_up_time.midnightconfig.title": "Wake Up Time Config", 3 | "wake_up_time.midnightconfig.persistent": "Persistent notification", 4 | 5 | "wake_up_time.category": "Wake Up Time", 6 | "wake_up_time.send_status": "Send villager clock status", 7 | 8 | "wake_up_time.status": "§bEmployed villagers are currently %s", 9 | "wake_up_time.lazy_bums": "%s§b; %s§a seconds§b until working time", 10 | "wake_up_time.working": "§aworking§b; %s§a seconds§b until workday ends", 11 | "wake_up_time.sleeping": "§asleeping", 12 | "wake_up_time.gathering": "§agathering", 13 | "wake_up_time.wandering": "§awandering", 14 | 15 | "wake_up_time.name_credits": "Name credits" 16 | } 17 | -------------------------------------------------------------------------------- /wake_up_time/src/main/resources/assets/wake_up_time/lang/ru_ru.json: -------------------------------------------------------------------------------- 1 | { 2 | "wake_up_time.midnightconfig.title": "Wake Up Time Config", 3 | 4 | "wake_up_time.category": "Wake Up Time", 5 | "wake_up_time.send_status": "Показать статус жителей", 6 | 7 | "wake_up_time.status": "§bСтатус жителей - %s", 8 | "wake_up_time.lazy_bums": "%s§b; %s§a секунды§b до рабочего времени", 9 | "wake_up_time.working": "§aработа§b; %s§a секунды§b до окончания рабочего дня", 10 | "wake_up_time.sleeping": "§aсон", 11 | "wake_up_time.gathering": "§aсбор", 12 | "wake_up_time.wandering": "§aсвободное время" 13 | } 14 | --------------------------------------------------------------------------------