mirror of
				https://github.com/chylex/Minecraft-Window-Title.git
				synced 2025-10-30 18:17:20 +01:00 
			
		
		
		
	Compare commits
	
		
			17 Commits
		
	
	
		
			1.12/older
			...
			6c4892dcd0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 6c4892dcd0 | |||
| e0b48e1c53 | |||
| d070b4b22f | |||
| 2c12af5fa8 | |||
| 04f1714ec5 | |||
| 466de670f3 | |||
| 639f96dbed | |||
| 4aceac18c2 | |||
| bb0abf7e5e | |||
| 7d33aa8531 | |||
| 744969ef0c | |||
| ecec2c9087 | |||
| c5085bc460 | |||
| 834a3dd4e5 | |||
| 5ebdf1f9bc | |||
| 31352987b5 | |||
| 136bd2baf0 | 
							
								
								
									
										1
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| * text=auto eol=lf | ||||
							
								
								
									
										3
									
								
								.github/FUNDING.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.github/FUNDING.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| github: chylex | ||||
| patreon: chylex | ||||
| ko_fi: chylex | ||||
							
								
								
									
										
											BIN
										
									
								
								.github/README/screenshot.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								.github/README/screenshot.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 245 KiB | 
							
								
								
									
										30
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1 +1,29 @@ | ||||
| Build/ | ||||
| bin/ | ||||
| [Bb]uild/ | ||||
| eclipse/ | ||||
| run/ | ||||
| out/ | ||||
| .gradle/ | ||||
| .idea/$CACHE_FILE$ | ||||
| .idea/codeStyles/ | ||||
| .idea/compiler.xml | ||||
| .idea/dictionaries | ||||
| .idea/inspectionProfiles/ | ||||
| .idea/jarRepositories.xml | ||||
| .idea/libraries/ | ||||
| .idea/misc.xml | ||||
| .idea/modules/ | ||||
| .idea/modules.xml | ||||
| .idea/runConfigurations/ | ||||
| .idea/shelf/ | ||||
| .idea/uiDesigner.xml | ||||
| .idea/workspace.xml | ||||
| .settings/ | ||||
| .updateclasses/ | ||||
| .classpath | ||||
| .project | ||||
| .DS_Store | ||||
| *.launch | ||||
| *.ipr | ||||
| *.iws | ||||
| Thumbs.db | ||||
|   | ||||
							
								
								
									
										6
									
								
								.idea/encodings.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.idea/encodings.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project version="4"> | ||||
|   <component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8"> | ||||
|     <file url="PROJECT" charset="UTF-8" /> | ||||
|   </component> | ||||
| </project> | ||||
							
								
								
									
										21
									
								
								.idea/gradle.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								.idea/gradle.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project version="4"> | ||||
|   <component name="GradleMigrationSettings" migrationVersion="1" /> | ||||
|   <component name="GradleSettings"> | ||||
|     <option name="linkedExternalProjectsSettings"> | ||||
|       <GradleProjectSettings> | ||||
|         <option name="delegatedBuild" value="true" /> | ||||
|         <option name="testRunner" value="GRADLE" /> | ||||
|         <option name="distributionType" value="DEFAULT_WRAPPED" /> | ||||
|         <option name="externalProjectPath" value="$PROJECT_DIR$" /> | ||||
|         <option name="modules"> | ||||
|           <set> | ||||
|             <option value="$PROJECT_DIR$" /> | ||||
|             <option value="$PROJECT_DIR$/Fabric" /> | ||||
|             <option value="$PROJECT_DIR$/Forge" /> | ||||
|           </set> | ||||
|         </option> | ||||
|       </GradleProjectSettings> | ||||
|     </option> | ||||
|   </component> | ||||
| </project> | ||||
							
								
								
									
										11
									
								
								.idea/vcs.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								.idea/vcs.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project version="4"> | ||||
|   <component name="GitSharedSettings"> | ||||
|     <option name="FORCE_PUSH_PROHIBITED_PATTERNS"> | ||||
|       <list /> | ||||
|     </option> | ||||
|   </component> | ||||
|   <component name="VcsDirectoryMappings"> | ||||
|     <mapping directory="" vcs="Git" /> | ||||
|   </component> | ||||
| </project> | ||||
							
								
								
									
										30
									
								
								CURSEFORGE.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								CURSEFORGE.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| <h2>Installation</h2> | ||||
| <p>The mod supports <a href="https://files.minecraftforge.net/">Forge</a> and <a href="https://fabricmc.net/">Fabric</a> (*) mod loaders. Follow either mod loader's installation guide, then <a href="https://www.curseforge.com/minecraft/mc-mods/custom-window-title/files">download the mod file</a> for your Minecraft version and mod loader, and install it into the <strong>.minecraft/mods</strong> folder.</p> | ||||
| <p>(*) Fabric API is <strong>not</strong> required.</p> | ||||
| <h2>Configuration</h2> | ||||
| <p>Run the game once to create the configuration file. By default, the window title will be set to <strong>Minecraft <em><version></em></strong>. Unlike in vanilla 1.15.2 onwards, the title will not change when you enter a world/server.</p> | ||||
| <p>To change the title or icon, navigate to the <strong>.minecraft/config</strong> folder, and open <strong>customwindowtitle-client.toml</strong> in a text editor. You will see the following entries:</p> | ||||
| <p><span style="font-family: courier new,courier,monospace;">title = '<span style="color: #808000;">Minecraft {mcversion}</span>'</span><br /> <span style="font-family: courier new,courier,monospace;">icon16 = ''</span><br /> <span style="font-family: courier new,courier,monospace;">icon32 = ''</span></p> | ||||
| <p>Only edit text inside quotes or apostrophes.</p> | ||||
| <h3>Changing the Title</h3> | ||||
| <p>You can use the following special tokens in the <em>title</em> configuration entry:</p> | ||||
| <ul> | ||||
|   <li><strong>{mcversion}</strong> - current Minecraft version</li> | ||||
|   <li><strong>{modversion:<span style="text-decoration: underline;">modid</span>}</strong> - version of installed mod with the identifier <em>modid</em></li> | ||||
| </ul> | ||||
| <p>If any of the tokens aren't working, search the game log for <strong>CustomWindowTitle</strong> and you should see the reason, otherwise please file an issue on the <a href="https://github.com/chylex/Minecraft-Window-Title/issues">issue tracker</a> with as many details as possible.</p> | ||||
| <h3>Changing the Icon</h3> | ||||
| <p>You must create two PNG images with sizes 16x16 and 32x32 pixels. The images <strong>must be saved with transparency</strong> even if they don't use it, <strong>otherwise the icons will appear corrupted</strong>. In Krita for example, you must check <em>Store alpha channel (transparency)</em> when saving the image.</p> | ||||
| <p>The <em>icon16</em> and <em>icon32</em> configuration entries point to the PNG files relative to the <strong>.minecraft/config</strong> folder. For example, if you place the two icons in a folder named <em>customwindowtitle</em> as follows:</p> | ||||
| <ul> | ||||
|   <li><span style="font-family: courier new, courier, monospace;">.minecraft/config/<span style="color: #008080;">customwindowtitle-client.toml</span></span></li> | ||||
|   <li><span style="font-family: courier new, courier, monospace;">.minecraft/config/<span style="color: #808000;">customwindowtitle/icon16.png</span></span></li> | ||||
|   <li><span style="font-family: courier new, courier, monospace;">.minecraft/config/<span style="color: #808000;">customwindowtitle/icon32.png</span></span></li> | ||||
| </ul> | ||||
| <p>Then, the two icon entries should look like this:</p> | ||||
| <p><span style="font-family: courier new,courier,monospace;">icon16 = '<span style="color: #808000;">customwindowtitle/icon16.png</span>'</span><br /> <span style="font-family: courier new,courier,monospace;">icon32 = '<span style="color: #808000;">customwindowtitle/icon32.png</span>'</span></p> | ||||
| <p><strong>Custom icons require Custom Window Title 1.1.0 or newer.</strong></p> | ||||
| <h2>Screenshots</h2> | ||||
| <p>These screenshots were taken using the following example configuration:</p> | ||||
| <p><span style="font-family: courier new,courier,monospace;">title = "<span style="color: #808000;">Minecraft {mcversion} - Custom Window Title {modversion:customwindowtitle}</span>"</span></p> | ||||
| <p><img src="https://media.forgecdn.net/attachments/277/212/customwindowtitlefabric.png" width="417" height="284" /><img src="https://media.forgecdn.net/attachments/277/213/customwindowtitleforge.png" alt="" width="417" height="284" /></p> | ||||
							
								
								
									
										39
									
								
								Fabric/build.gradle.kts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								Fabric/build.gradle.kts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| val modId: String by project | ||||
| val minecraftVersion: String by project | ||||
| val fabricVersion: String by project | ||||
|  | ||||
| plugins { | ||||
| 	idea | ||||
| 	id("fabric-loom") | ||||
| } | ||||
|  | ||||
| dependencies { | ||||
| 	minecraft("com.mojang:minecraft:$minecraftVersion") | ||||
| 	modImplementation("net.fabricmc:fabric-loader:$fabricVersion") | ||||
| 	mappings(loom.officialMojangMappings()) | ||||
| } | ||||
|  | ||||
| loom { | ||||
| 	runs { | ||||
| 		named("client") { | ||||
| 			configName = "Fabric Client" | ||||
| 			client() | ||||
| 			runDir("../run") | ||||
| 			ideConfigGenerated(true) | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	mixin { | ||||
| 		add(sourceSets.main.get(), "$modId.refmap.json") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| tasks.processResources { | ||||
| 	filesMatching("fabric.mod.json") { | ||||
| 		expand(inputs.properties) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| tasks.remapJar { | ||||
| 	archiveVersion.set(tasks.jar.get().archiveVersion) | ||||
| } | ||||
| @@ -0,0 +1,31 @@ | ||||
| package chylex.customwindowtitle.fabric; | ||||
| import chylex.customwindowtitle.TitleConfig; | ||||
| import chylex.customwindowtitle.TitleParser; | ||||
| import chylex.customwindowtitle.data.CommonTokenData; | ||||
| import com.mojang.blaze3d.platform.Window; | ||||
| import net.fabricmc.api.ClientModInitializer; | ||||
| import net.fabricmc.loader.api.FabricLoader; | ||||
| import net.minecraft.client.Minecraft; | ||||
|  | ||||
| public class CustomWindowTitle implements ClientModInitializer { | ||||
| 	private final TitleConfig config; | ||||
| 	 | ||||
| 	public CustomWindowTitle() { | ||||
| 		config = TitleConfig.read(FabricLoader.getInstance().getConfigDirectory().getAbsolutePath()); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public void onInitializeClient() { | ||||
| 		CommonTokenData.register(new TokenProvider()); | ||||
| 		Minecraft.getInstance().execute(this::updateTitle); | ||||
| 	} | ||||
| 	 | ||||
| 	private void updateTitle() { | ||||
| 		final Window window = Minecraft.getInstance().getWindow(); | ||||
| 		window.setTitle(TitleParser.parse(config.getTitle())); | ||||
| 		 | ||||
| 		if (config.hasIcon()) { | ||||
| 			window.setIcon(config.readIcon16(), config.readIcon32()); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,16 @@ | ||||
| package chylex.customwindowtitle.fabric; | ||||
| import chylex.customwindowtitle.TokenException; | ||||
| import chylex.customwindowtitle.data.CommonTokenProvider; | ||||
| import net.fabricmc.loader.api.FabricLoader; | ||||
|  | ||||
| final class TokenProvider implements CommonTokenProvider { | ||||
| 	@Override | ||||
| 	public String getModVersion(final String modId) { | ||||
| 		return FabricLoader.getInstance() | ||||
| 			.getModContainer(modId) | ||||
| 			.orElseThrow(() -> new TokenException("mod info for '" + modId + "' not found")) | ||||
| 			.getMetadata() | ||||
| 			.getVersion() | ||||
| 			.getFriendlyString(); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										34
									
								
								Fabric/src/main/resources/fabric.mod.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								Fabric/src/main/resources/fabric.mod.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| { | ||||
|   "schemaVersion": 1, | ||||
|   "id": "${id}", | ||||
|   "name": "${name}", | ||||
|   "description": "${description}", | ||||
|   "version": "${version}", | ||||
|   "license": "${license}", | ||||
|    | ||||
|   "authors": [ | ||||
|     "${author}" | ||||
|   ], | ||||
|    | ||||
|   "contact": { | ||||
|     "homepage": "https://chylex.com", | ||||
|     "issues": "${issuesURL}", | ||||
|     "sources": "${sourcesURL}" | ||||
|   }, | ||||
|    | ||||
|   "environment": "client", | ||||
|   "entrypoints": { | ||||
|     "client": [ | ||||
|       "chylex.customwindowtitle.fabric.CustomWindowTitle" | ||||
|     ] | ||||
|   }, | ||||
|    | ||||
|   "mixins": [{ | ||||
|     "config": "${id}.mixins.json" | ||||
|   }], | ||||
|    | ||||
|   "depends": { | ||||
|     "fabricloader": ">=${minimumFabricVersion}", | ||||
|     "minecraft": ">=${minimumMinecraftVersion}" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										25
									
								
								Forge/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								Forge/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,25 +0,0 @@ | ||||
| # eclipse | ||||
| bin | ||||
| *.launch | ||||
| .settings | ||||
| .metadata | ||||
| .classpath | ||||
| .project | ||||
|  | ||||
| # idea | ||||
| out | ||||
| *.ipr | ||||
| *.iws | ||||
| *.iml | ||||
| .idea | ||||
|  | ||||
| # gradle | ||||
| build | ||||
| .gradle | ||||
|  | ||||
| # other | ||||
| eclipse | ||||
| run | ||||
|  | ||||
| # Files from Forge MDK | ||||
| forge*changelog.txt | ||||
| @@ -1,39 +0,0 @@ | ||||
| buildscript{ | ||||
|     repositories{ | ||||
|         maven{ url = 'https://files.minecraftforge.net/maven' } | ||||
|         jcenter() | ||||
|     } | ||||
|  | ||||
|     dependencies{ | ||||
|         classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT' | ||||
|     } | ||||
| } | ||||
|  | ||||
| apply plugin: 'net.minecraftforge.gradle.forge' | ||||
|  | ||||
| def mcversion = "1.12.2" | ||||
| def forgeversion = "14.23.5.2847" | ||||
|  | ||||
| def metaName = "Custom Window Title" | ||||
| def metaVersion = "1.0.0" | ||||
|  | ||||
| group = 'chylex.customwindowtitle.forge' | ||||
| version = metaVersion | ||||
| archivesBaseName = metaName.replaceAll('\\s', '') | ||||
|  | ||||
| sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' | ||||
|  | ||||
| minecraft{ | ||||
|     version = mcversion + '-' + forgeversion | ||||
|     runDir = "run" | ||||
|     mappings = "snapshot_20180814" | ||||
|     makeObfSourceJar = false | ||||
| } | ||||
|  | ||||
| jar{ | ||||
|     archiveName = archivesBaseName + '-Legacy-v' + version + '.jar' | ||||
|  | ||||
|     from('../'){ | ||||
|         include 'LICENSE' | ||||
|     } | ||||
| } | ||||
							
								
								
									
										78
									
								
								Forge/build.gradle.kts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								Forge/build.gradle.kts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | ||||
| import net.minecraftforge.gradle.userdev.UserDevExtension | ||||
| import org.gradle.api.file.DuplicatesStrategy.INCLUDE | ||||
| import org.spongepowered.asm.gradle.plugins.MixinExtension | ||||
|  | ||||
| val modId: String by project | ||||
| val minecraftVersion: String by project | ||||
| val forgeVersion: String by project | ||||
| val mixinVersion: String by project | ||||
|  | ||||
| buildscript { | ||||
| 	repositories { | ||||
| 		maven("https://maven.minecraftforge.net") | ||||
| 		maven("https://repo.spongepowered.org/maven") | ||||
| 		mavenCentral() | ||||
| 	} | ||||
| 	 | ||||
| 	dependencies { | ||||
| 		classpath(group = "net.minecraftforge.gradle", name = "ForgeGradle", version = "5.1.+") { isChanging = true } | ||||
| 		classpath(group = "org.spongepowered", name = "mixingradle", version = "0.7-SNAPSHOT") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| plugins { | ||||
| 	java | ||||
| 	eclipse | ||||
| } | ||||
|  | ||||
| apply { | ||||
| 	plugin("net.minecraftforge.gradle") | ||||
| 	plugin("org.spongepowered.mixin") | ||||
| } | ||||
|  | ||||
| dependencies { | ||||
| 	"minecraft"("net.minecraftforge:forge:$minecraftVersion-$forgeVersion") | ||||
| 	 | ||||
| 	if (System.getProperty("idea.sync.active") != "true") { | ||||
| 		annotationProcessor("org.spongepowered:mixin:$mixinVersion:processor") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| configure<UserDevExtension> { | ||||
| 	mappings("official", minecraftVersion) | ||||
| 	 | ||||
| 	runs { | ||||
| 		create("client") { | ||||
| 			taskName = "Client" | ||||
| 			workingDirectory(rootProject.file("run")) | ||||
| 			ideaModule("${rootProject.name}.${project.name}.main") | ||||
| 			 | ||||
| 			property("mixin.env.remapRefMap", "true") | ||||
| 			property("mixin.env.refMapRemappingFile", "$projectDir/build/createSrgToMcp/output.srg") | ||||
| 			arg("-mixin.config=$modId.mixins.json") | ||||
| 			 | ||||
| 			mods { | ||||
| 				create(modId) { | ||||
| 					source(sourceSets.main.get()) | ||||
| 					source(rootProject.sourceSets.main.get()) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| configure<MixinExtension> { | ||||
| 	add(sourceSets.main.get(), "$modId.refmap.json") | ||||
| } | ||||
|  | ||||
| tasks.processResources { | ||||
| 	from(sourceSets.main.get().resources.srcDirs) { | ||||
| 		include("META-INF/mods.toml") | ||||
| 		expand(inputs.properties) | ||||
| 		duplicatesStrategy = INCLUDE | ||||
| 	} | ||||
| } | ||||
|  | ||||
| tasks.jar { | ||||
| 	finalizedBy("reobfJar") | ||||
| } | ||||
| @@ -1,4 +0,0 @@ | ||||
| # Sets default memory used for gradle commands. Can be overridden by user or command line properties. | ||||
| # This is required to provide enough memory for the Minecraft decompilation process. | ||||
| org.gradle.jvmargs=-Xmx3G | ||||
| org.gradle.daemon=false | ||||
							
								
								
									
										
											BIN
										
									
								
								Forge/gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Forge/gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -1,7 +0,0 @@ | ||||
| package chylex.customwindowtitle; | ||||
|  | ||||
| public class TokenException extends RuntimeException{ | ||||
| 	public TokenException(String message){ | ||||
| 		super(message); | ||||
| 	} | ||||
| } | ||||
| @@ -1,51 +1,40 @@ | ||||
| package chylex.customwindowtitle.forge; | ||||
| import chylex.customwindowtitle.TitleConfig; | ||||
| import chylex.customwindowtitle.TitleParser; | ||||
| import chylex.customwindowtitle.data.CommonTokenData; | ||||
| import com.mojang.blaze3d.platform.Window; | ||||
| import net.minecraft.client.Minecraft; | ||||
| import net.minecraftforge.eventbus.api.SubscribeEvent; | ||||
| import net.minecraftforge.fml.IExtensionPoint.DisplayTest; | ||||
| import net.minecraftforge.fml.ModLoadingContext; | ||||
| import net.minecraftforge.fml.common.Mod; | ||||
| import net.minecraftforge.fml.common.Mod.EventHandler; | ||||
| import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
| import org.lwjgl.opengl.Display; | ||||
| import java.io.IOException; | ||||
| import java.nio.charset.StandardCharsets; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.Paths; | ||||
| import java.util.Collections; | ||||
| import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; | ||||
| import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; | ||||
| import net.minecraftforge.fml.loading.FMLPaths; | ||||
| import net.minecraftforge.fmllegacy.network.FMLNetworkConstants; | ||||
|  | ||||
| @Mod(modid = "customwindowtitle", useMetadata = true, clientSideOnly = true, acceptedMinecraftVersions = "*", acceptableRemoteVersions = "*") | ||||
| public class CustomWindowTitle{ | ||||
| 	private static final String defaultTitle = "Minecraft {mcversion}"; | ||||
| 	private String configTitle; | ||||
| @Mod("customwindowtitle") | ||||
| public class CustomWindowTitle { | ||||
| 	private final TitleConfig config; | ||||
| 	 | ||||
| 	@EventHandler | ||||
| 	public void onPreInit(FMLPreInitializationEvent e){ | ||||
| 		Path configFile = Paths.get(e.getModConfigurationDirectory().getAbsolutePath(), "customwindowtitle-client.toml"); | ||||
| 		 | ||||
| 		try{ | ||||
| 			String prefix = "title = "; | ||||
| 			 | ||||
| 			if (!Files.exists(configFile)){ | ||||
| 				Files.write(configFile, Collections.singletonList(prefix + '"' + defaultTitle + '"'), StandardCharsets.UTF_8); | ||||
| 				configTitle = defaultTitle; | ||||
| 			} | ||||
| 			else{ | ||||
| 				configTitle = Files | ||||
| 					.readAllLines(configFile, StandardCharsets.UTF_8) | ||||
| 					.stream() | ||||
| 					.filter(line -> line.startsWith(prefix)) | ||||
| 					.map(line -> StringUtils.strip(StringUtils.removeStart(line, prefix).trim(), "\"")) | ||||
| 					.findFirst() | ||||
| 					.orElse(defaultTitle); | ||||
| 			} | ||||
| 		}catch(IOException ex){ | ||||
| 			throw new RuntimeException("CustomWindowTitle configuration error", ex); | ||||
| 		} | ||||
| 		 | ||||
| 		TokenData.register(); | ||||
| 		updateTitle(); | ||||
| 	public CustomWindowTitle() { | ||||
| 		config = TitleConfig.read(FMLPaths.CONFIGDIR.get().toString()); | ||||
| 		ModLoadingContext.get().registerExtensionPoint(DisplayTest.class, () -> new DisplayTest(() -> FMLNetworkConstants.IGNORESERVERONLY, (a, b) -> true)); | ||||
| 		FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onClientSetup); | ||||
| 		CommonTokenData.register(new TokenProvider()); | ||||
| 	} | ||||
| 	 | ||||
| 	private void updateTitle(){ | ||||
| 		Display.setTitle(TitleParser.parse(configTitle)); | ||||
| 	@SubscribeEvent | ||||
| 	public void onClientSetup(final FMLClientSetupEvent e) { | ||||
| 		e.enqueueWork(this::updateTitle); | ||||
| 	} | ||||
| 	 | ||||
| 	private void updateTitle() { | ||||
| 		final Window window = Minecraft.getInstance().getWindow(); | ||||
| 		window.setTitle(TitleParser.parse(config.getTitle())); | ||||
| 		 | ||||
| 		if (config.hasIcon()) { | ||||
| 			window.setIcon(config.readIcon16(), config.readIcon32()); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -1,29 +0,0 @@ | ||||
| package chylex.customwindowtitle.forge; | ||||
| import chylex.customwindowtitle.TokenException; | ||||
| import net.minecraft.realms.RealmsSharedConstants; | ||||
| import net.minecraftforge.fml.common.Loader; | ||||
| import net.minecraftforge.fml.common.ModContainer; | ||||
| import static chylex.customwindowtitle.TitleTokens.noArgs; | ||||
| import static chylex.customwindowtitle.TitleTokens.oneArg; | ||||
| import static chylex.customwindowtitle.TitleTokens.registerToken; | ||||
|  | ||||
| final class TokenData{ | ||||
| 	static void register(){ | ||||
| 		registerToken("mcversion", noArgs(TokenData::getMinecraftVersion)); | ||||
| 		registerToken("modversion", oneArg(TokenData::getModVersion)); | ||||
| 	} | ||||
| 	 | ||||
| 	static String getMinecraftVersion(){ | ||||
| 		return RealmsSharedConstants.VERSION_STRING; | ||||
| 	} | ||||
| 	 | ||||
| 	static String getModVersion(String modId){ | ||||
| 		ModContainer mod = Loader.instance().getIndexedModList().get(modId); | ||||
| 		 | ||||
| 		if (mod == null){ | ||||
| 			throw new TokenException("mod info for '" + modId + "' not found"); | ||||
| 		} | ||||
| 		 | ||||
| 		return mod.getMetadata().version; | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,25 @@ | ||||
| package chylex.customwindowtitle.forge; | ||||
| import chylex.customwindowtitle.TokenException; | ||||
| import chylex.customwindowtitle.data.CommonTokenProvider; | ||||
| import net.minecraftforge.fml.ModList; | ||||
| import net.minecraftforge.forgespi.language.IModFileInfo; | ||||
| import net.minecraftforge.forgespi.language.IModInfo; | ||||
|  | ||||
| final class TokenProvider implements CommonTokenProvider { | ||||
| 	@Override | ||||
| 	public String getModVersion(final String modId) { | ||||
| 		final IModFileInfo file = ModList.get().getModFileById(modId); | ||||
| 		 | ||||
| 		if (file == null) { | ||||
| 			throw new TokenException("mod file for '" + modId + "' not found"); | ||||
| 		} | ||||
| 		 | ||||
| 		for (final IModInfo info : file.getMods()) { | ||||
| 			if (info.getModId().equals(modId)) { | ||||
| 				return info.getVersion().toString(); | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		throw new TokenException("mod info for '" + modId + "' not found"); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										27
									
								
								Forge/src/main/resources/META-INF/mods.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								Forge/src/main/resources/META-INF/mods.toml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| modLoader = "javafml" | ||||
| loaderVersion = "[0,)" | ||||
|  | ||||
| authors = "${author}" | ||||
| license = "${license}" | ||||
| issueTrackerURL = "${issuesURL}" | ||||
|  | ||||
| [[mods]] | ||||
| modId = "${id}" | ||||
| version = "${version}" | ||||
| displayName = "${name}" | ||||
| description = "${description}" | ||||
| displayURL = "${sourcesURL}" | ||||
|  | ||||
| [[dependencies.${id}]] | ||||
| modId = "minecraft" | ||||
| mandatory = true | ||||
| versionRange = "[${minimumMinecraftVersion},)" | ||||
| ordering = "NONE" | ||||
| side = "CLIENT" | ||||
|  | ||||
| [[dependencies.${id}]] | ||||
| modId = "forge" | ||||
| mandatory = true | ||||
| versionRange = "[${minimumForgeVersion},)" | ||||
| ordering = "NONE" | ||||
| side = "CLIENT" | ||||
| @@ -1,10 +0,0 @@ | ||||
| [ | ||||
| { | ||||
|   "modid": "customwindowtitle", | ||||
|   "name": "Custom Window Title", | ||||
|   "description": "", | ||||
|   "version": "1.0.0", | ||||
|   "url": "https://github.com/chylex/Minecraft-Window-Title", | ||||
|   "authorList": ["chylex"] | ||||
| } | ||||
| ] | ||||
| @@ -1,7 +0,0 @@ | ||||
| { | ||||
|     "pack": { | ||||
|         "description": "Custom Window Title", | ||||
|         "pack_format": 3, | ||||
|         "_comment": "" | ||||
|     } | ||||
| } | ||||
							
								
								
									
										44
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								README.md
									
									
									
									
									
								
							| @@ -4,25 +4,48 @@ | ||||
|  | ||||
| The mod supports [Forge](https://files.minecraftforge.net/) and [Fabric](https://fabricmc.net/) (*) mod loaders, **the same mod file will work in both**. Follow either mod loader's installation guide, then [download the mod file](https://www.curseforge.com/minecraft/mc-mods/custom-window-title/files) for your Minecraft version, and install it into the **.minecraft/mods** folder. | ||||
|  | ||||
| (*) Fabric API is not required. | ||||
| (*) Fabric API is **not** required. | ||||
|  | ||||
| ## Configuration | ||||
|  | ||||
| Run the game once to create the configuration file. By default, the window title will be set to **Minecraft _<version>_**. Unlike in vanilla 1.15.2 onwards, the title will not change when you enter a world/server. | ||||
|  | ||||
| To change the title, navigate to the **.minecraft/config** folder, and open **customwindowtitle-client.toml** in a text editor. You will see the following line: | ||||
| To change the title or icon, navigate to the **.minecraft/config** folder, and open **customwindowtitle-client.toml** in a text editor. You will see the following entries: | ||||
|  | ||||
| ```toml | ||||
| title = "Minecraft {mcversion}" | ||||
| title = 'Minecraft {mcversion}'   | ||||
| icon16 = ''   | ||||
| icon32 = '' | ||||
| ``` | ||||
|  | ||||
| Change only text inside the quotes. You can use the following special tokens: | ||||
| Only edit text inside quotes or apostrophes. | ||||
|  | ||||
| ### Changing the Title | ||||
|  | ||||
| You can use the following special tokens in the _title_ configuration entry: | ||||
|  | ||||
| * **{mcversion}** - current Minecraft version | ||||
| * **{modversion:<span style="text-decoration: underline;">modid</span>}** - version of installed mod with the identifier _modid_ | ||||
|  | ||||
| If any of the tokens aren't working, search the game log for **CustomWindowTitle** and you should see the reason, otherwise please file an issue on the [issue tracker](https://github.com/chylex/Minecraft-Window-Title/issues) with as many details as possible. | ||||
|  | ||||
| ### Changing the Icon | ||||
|  | ||||
| You must create two PNG images with sizes 16x16 and 32x32 pixels. The images **must be saved with transparency** even if they don't use it, **otherwise the icons will appear corrupted**. In Krita for example, you must check _Store alpha channel (transparency)_ when saving the image. | ||||
|  | ||||
| The _icon16_ and _icon32_ configuration entries point to the PNG files relative to the **.minecraft/config** folder. For example, if you place the two icons in a folder named _customwindowtitle_ as follows: | ||||
|  | ||||
| * `.minecraft/config/customwindowtitle-client.toml` | ||||
| * `.minecraft/config/customwindowtitle/icon16.png` | ||||
| * `.minecraft/config/customwindowtitle/icon32.png` | ||||
|  | ||||
| Then, the two icon entries should look like this: | ||||
|  | ||||
| ```toml | ||||
| icon16 = 'customwindowtitle/icon16.png'   | ||||
| icon32 = 'customwindowtitle/icon32.png' | ||||
| ``` | ||||
|  | ||||
| ## Screenshots | ||||
|  | ||||
| These screenshots were taken using the following example configuration: | ||||
| @@ -31,10 +54,17 @@ These screenshots were taken using the following example configuration: | ||||
| title = "Minecraft {mcversion} - Custom Window Title {modversion:customwindowtitle}" | ||||
| ``` | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| # For Developers | ||||
|  | ||||
| Currently the common source files (package `chylex.customwindowtitle`) are just duplicated in the Forge and Fabric folders, and the jar files are combined with a horrible python script. If anyone has the time and patience to clean it up, I'd appreciate a Pull Request :P | ||||
| The mod sources are organized into 3 projects: | ||||
| - `src/` contains common source files and mixins | ||||
| - `Fabric/src/` contains source files specific for Fabric | ||||
| - `Forge/src/` contains source files specific for Forge | ||||
|  | ||||
| For now, you can build either separate Forge and Fabric projects using `gradlew build` in either folder, or run `python BuildMerge.py` to automatically build both and combine them into a single `.jar` file. | ||||
| The Gradle project provides the following tasks: | ||||
| - `setupIdea` generates Minecraft sources and run configurations for IntelliJ IDEA | ||||
| - `assemble` creates 2 `.jar` files in the `build/dist` folder - one for Forge, one for Fabric | ||||
|  | ||||
| When building against a Minecraft version that is only supported by one mod loader, open `gradle.properties` and comment or remove either `forgeVersion` or `fabricVersion` to disable them. | ||||
|   | ||||
							
								
								
									
										179
									
								
								build.gradle.kts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								build.gradle.kts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,179 @@ | ||||
| import org.gradle.api.file.DuplicatesStrategy.EXCLUDE | ||||
| import java.text.SimpleDateFormat | ||||
| import java.util.Date | ||||
|  | ||||
| val modId: String by project | ||||
| val modName: String by project | ||||
| val modDescription: String by project | ||||
| val modAuthor: String by project | ||||
| val modVersion: String by project | ||||
| val modLicense: String by project | ||||
| val modSourcesURL: String by project | ||||
| val modIssuesURL: String by project | ||||
|  | ||||
| val minecraftVersion: String by project | ||||
| val mixinVersion: String by project | ||||
|  | ||||
| val minimumMinecraftVersion: String by project | ||||
| val minimumForgeVersion: String by project | ||||
| val minimumFabricVersion: String by project | ||||
|  | ||||
| val modNameStripped = modName.replace(" ", "") | ||||
| val jarVersion = "$minecraftVersion+v$modVersion" | ||||
|  | ||||
| buildscript { | ||||
| 	repositories { | ||||
| 		maven("https://repo.spongepowered.org/maven") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| plugins { | ||||
| 	`java-library` | ||||
| 	idea | ||||
| 	id("org.spongepowered.gradle.vanilla") version "0.2.1-SNAPSHOT" | ||||
| } | ||||
|  | ||||
| idea { | ||||
| 	module { | ||||
| 		excludeDirs.add(file("gradle")) | ||||
| 		excludeDirs.add(file("run")) | ||||
| 		 | ||||
| 		if (findProject(":Forge") == null) { | ||||
| 			excludeDirs.add(file("Forge")) | ||||
| 		} | ||||
| 		 | ||||
| 		if (findProject(":Fabric") == null) { | ||||
| 			excludeDirs.add(file("Fabric")) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| repositories { | ||||
| 	maven("https://repo.spongepowered.org/maven") | ||||
| 	mavenCentral() | ||||
| } | ||||
|  | ||||
| dependencies { | ||||
| 	implementation("org.spongepowered:mixin:$mixinVersion") | ||||
| 	api("com.google.code.findbugs:jsr305:3.0.2") | ||||
| } | ||||
|  | ||||
| base { | ||||
| 	archivesName.set("$modNameStripped-Common") | ||||
| } | ||||
|  | ||||
| minecraft { | ||||
| 	version(minecraftVersion) | ||||
| 	runs.clear() | ||||
| } | ||||
|  | ||||
| allprojects { | ||||
| 	group = "com.$modAuthor.$modId" | ||||
| 	version = modVersion | ||||
| 	 | ||||
| 	apply(plugin = "java") | ||||
| 	 | ||||
| 	dependencies { | ||||
| 		implementation("org.jetbrains:annotations:22.0.0") | ||||
| 	} | ||||
| 	 | ||||
| 	extensions.getByType<JavaPluginExtension>().apply { | ||||
| 		toolchain.languageVersion.set(JavaLanguageVersion.of(16)) | ||||
| 	} | ||||
| 	 | ||||
| 	tasks.withType<JavaCompile> { | ||||
| 		options.encoding = "UTF-8" | ||||
| 		options.release.set(16) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| subprojects { | ||||
| 	repositories { | ||||
| 		maven("https://repo.spongepowered.org/maven") | ||||
| 	} | ||||
| 	 | ||||
| 	dependencies { | ||||
| 		implementation(rootProject) | ||||
| 	} | ||||
| 	 | ||||
| 	base { | ||||
| 		archivesName.set("$modNameStripped-${project.name}") | ||||
| 	} | ||||
| 	 | ||||
| 	tasks.withType<JavaCompile> { | ||||
| 		source({ rootProject.sourceSets.main.get().allSource }) | ||||
| 	} | ||||
| 	 | ||||
| 	tasks.processResources { | ||||
| 		inputs.property("id", modId) | ||||
| 		inputs.property("name", modName) | ||||
| 		inputs.property("description", modDescription) | ||||
| 		inputs.property("version", modVersion) | ||||
| 		inputs.property("author", modAuthor) | ||||
| 		inputs.property("license", modLicense) | ||||
| 		inputs.property("sourcesURL", modSourcesURL) | ||||
| 		inputs.property("issuesURL", modIssuesURL) | ||||
| 		inputs.property("minimumMinecraftVersion", minimumMinecraftVersion) | ||||
| 		inputs.property("minimumForgeVersion", minimumForgeVersion) | ||||
| 		inputs.property("minimumFabricVersion", minimumFabricVersion) | ||||
| 		 | ||||
| 		from(rootProject.sourceSets.main.get().resources) { | ||||
| 			expand(inputs.properties) | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	tasks.jar { | ||||
| 		archiveVersion.set(jarVersion) | ||||
| 		 | ||||
| 		from(rootProject.file("LICENSE")) | ||||
| 		 | ||||
| 		manifest { | ||||
| 			attributes( | ||||
| 				"Specification-Title" to modId, | ||||
| 				"Specification-Vendor" to modAuthor, | ||||
| 				"Specification-Version" to "1", | ||||
| 				"Implementation-Title" to "$modNameStripped-${project.name}", | ||||
| 				"Implementation-Vendor" to modAuthor, | ||||
| 				"Implementation-Version" to modVersion, | ||||
| 				"Implementation-Timestamp" to SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").format(Date()), | ||||
| 				"MixinConfigs" to "$modId.mixins.json" | ||||
| 			) | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	tasks.test { | ||||
| 		onlyIf { false } | ||||
| 	} | ||||
| } | ||||
|  | ||||
| tasks.register("setupIdea") { | ||||
| 	group = "mod" | ||||
| 	 | ||||
| 	dependsOn(tasks.findByName("decompile")) | ||||
| 	 | ||||
| 	val forge = findProject(":Forge") | ||||
| 	if (forge != null) { | ||||
| 		dependsOn(forge.tasks.getByName("genIntellijRuns")) | ||||
| 	} | ||||
| 	 | ||||
| 	val fabric = findProject(":Fabric") | ||||
| 	if (fabric != null) { | ||||
| 		dependsOn(fabric.tasks.getByName("genSources")) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| val copyJars = tasks.register<Copy>("copyJars") { | ||||
| 	group = "build" | ||||
| 	duplicatesStrategy = EXCLUDE | ||||
| 	 | ||||
| 	for (subproject in subprojects) { | ||||
| 		dependsOn(subproject.tasks.assemble) | ||||
| 		from(subproject.base.libsDirectory.file("${subproject.base.archivesName.get()}-$jarVersion.jar")) | ||||
| 	} | ||||
| 	 | ||||
| 	into(file("${project.buildDir}/dist")) | ||||
| } | ||||
|  | ||||
| tasks.assemble { | ||||
| 	finalizedBy(copyJars) | ||||
| } | ||||
							
								
								
									
										25
									
								
								gradle.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								gradle.properties
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| # Mod | ||||
| modId=customwindowtitle | ||||
| modName=Custom Window Title | ||||
| modDescription=Customize window title and icon. | ||||
| modAuthor=chylex | ||||
| modVersion=1.1.1 | ||||
| modLicense=Unlicense | ||||
| modSourcesURL=https://github.com/chylex/Minecraft-Window-Title | ||||
| modIssuesURL=https://github.com/chylex/Minecraft-Window-Title/issues | ||||
|  | ||||
| # Dependencies | ||||
| minecraftVersion=1.17.1 | ||||
| forgeVersion=37.0.75 | ||||
| fabricVersion=0.11.7 | ||||
| loomVersion=0.12 | ||||
| mixinVersion=0.8.4 | ||||
|  | ||||
| # Constraints | ||||
| minimumMinecraftVersion=1.17 | ||||
| minimumForgeVersion=31.2.45 | ||||
| minimumFabricVersion=0.7.2 | ||||
|  | ||||
| # Gradle | ||||
| org.gradle.jvmargs=-Xmx3G | ||||
| org.gradle.daemon=false | ||||
							
								
								
									
										
											BIN
										
									
								
								gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -1,5 +1,5 @@ | ||||
| distributionBase=GRADLE_USER_HOME | ||||
| distributionPath=wrapper/dists | ||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip | ||||
| zipStoreBase=GRADLE_USER_HOME | ||||
| zipStorePath=wrapper/dists | ||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip | ||||
							
								
								
									
										71
									
								
								Forge/gradlew → gradlew
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										71
									
								
								Forge/gradlew → gradlew
									
									
									
									
										vendored
									
									
								
							| @@ -1,4 +1,20 @@ | ||||
| #!/usr/bin/env sh | ||||
| #!/usr/bin/env bash | ||||
| 
 | ||||
| # | ||||
| # Copyright 2015 the original author or authors. | ||||
| # | ||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| # you may not use this file except in compliance with the License. | ||||
| # You may obtain a copy of the License at | ||||
| # | ||||
| #      https://www.apache.org/licenses/LICENSE-2.0 | ||||
| # | ||||
| # Unless required by applicable law or agreed to in writing, software | ||||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| # See the License for the specific language governing permissions and | ||||
| # limitations under the License. | ||||
| # | ||||
| 
 | ||||
| ############################################################################## | ||||
| ## | ||||
| @@ -28,7 +44,7 @@ APP_NAME="Gradle" | ||||
| APP_BASE_NAME=`basename "$0"` | ||||
| 
 | ||||
| # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||||
| DEFAULT_JVM_OPTS="" | ||||
| DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' | ||||
| 
 | ||||
| # Use the maximum available, or set MAX_FD != -1 to use that value. | ||||
| MAX_FD="maximum" | ||||
| @@ -56,7 +72,7 @@ case "`uname`" in | ||||
|   Darwin* ) | ||||
|     darwin=true | ||||
|     ;; | ||||
|   MINGW* ) | ||||
|   MSYS* | MINGW* ) | ||||
|     msys=true | ||||
|     ;; | ||||
|   NONSTOP* ) | ||||
| @@ -66,6 +82,7 @@ esac | ||||
| 
 | ||||
| CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | ||||
| 
 | ||||
| 
 | ||||
| # Determine the Java command to use to start the JVM. | ||||
| if [ -n "$JAVA_HOME" ] ; then | ||||
|     if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | ||||
| @@ -109,10 +126,11 @@ if $darwin; then | ||||
|     GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" | ||||
| fi | ||||
| 
 | ||||
| # For Cygwin, switch paths to Windows format before running java | ||||
| if $cygwin ; then | ||||
| # For Cygwin or MSYS, switch paths to Windows format before running java | ||||
| if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then | ||||
|     APP_HOME=`cygpath --path --mixed "$APP_HOME"` | ||||
|     CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` | ||||
| 
 | ||||
|     JAVACMD=`cygpath --unix "$JAVACMD"` | ||||
| 
 | ||||
|     # We build the pattern for arguments to be converted via cygpath | ||||
| @@ -138,35 +156,28 @@ if $cygwin ; then | ||||
|         else | ||||
|             eval `echo args$i`="\"$arg\"" | ||||
|         fi | ||||
|         i=$((i+1)) | ||||
|         i=`expr $i + 1` | ||||
|     done | ||||
|     case $i in | ||||
|         (0) set -- ;; | ||||
|         (1) set -- "$args0" ;; | ||||
|         (2) set -- "$args0" "$args1" ;; | ||||
|         (3) set -- "$args0" "$args1" "$args2" ;; | ||||
|         (4) set -- "$args0" "$args1" "$args2" "$args3" ;; | ||||
|         (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; | ||||
|         (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; | ||||
|         (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; | ||||
|         (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; | ||||
|         (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; | ||||
|         0) set -- ;; | ||||
|         1) set -- "$args0" ;; | ||||
|         2) set -- "$args0" "$args1" ;; | ||||
|         3) set -- "$args0" "$args1" "$args2" ;; | ||||
|         4) set -- "$args0" "$args1" "$args2" "$args3" ;; | ||||
|         5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; | ||||
|         6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; | ||||
|         7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; | ||||
|         8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; | ||||
|         9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; | ||||
|     esac | ||||
| fi | ||||
| 
 | ||||
| # Escape application args | ||||
| save () { | ||||
|     for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done | ||||
|     echo " " | ||||
| } | ||||
| APP_ARGS=$(save "$@") | ||||
| ARGV=("$@") | ||||
| eval set -- $DEFAULT_JVM_OPTS | ||||
| 
 | ||||
| # Collect all arguments for the java command, following the shell quoting and substitution rules | ||||
| eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" | ||||
| IFS=$' | ||||
| ' read -rd '' -a JAVA_OPTS_ARR <<< "$(echo $JAVA_OPTS | xargs -n1)" | ||||
| IFS=$' | ||||
| ' read -rd '' -a GRADLE_OPTS_ARR <<< "$(echo $GRADLE_OPTS | xargs -n1)" | ||||
| 
 | ||||
| # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong | ||||
| if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then | ||||
|   cd "$(dirname "$0")" | ||||
| fi | ||||
| 
 | ||||
| exec "$JAVACMD" "$@" | ||||
| exec "$JAVACMD" "$@" "${JAVA_OPTS_ARR[@]}" "${GRADLE_OPTS_ARR[@]}" "-Dorg.gradle.appname=$APP_BASE_NAME" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "${ARGV[@]}" | ||||
							
								
								
									
										43
									
								
								Forge/gradlew.bat → gradlew.bat
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								Forge/gradlew.bat → gradlew.bat
									
									
									
									
										vendored
									
									
								
							| @@ -1,3 +1,19 @@ | ||||
| @rem | ||||
| @rem Copyright 2015 the original author or authors. | ||||
| @rem | ||||
| @rem Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| @rem you may not use this file except in compliance with the License. | ||||
| @rem You may obtain a copy of the License at | ||||
| @rem | ||||
| @rem      https://www.apache.org/licenses/LICENSE-2.0 | ||||
| @rem | ||||
| @rem Unless required by applicable law or agreed to in writing, software | ||||
| @rem distributed under the License is distributed on an "AS IS" BASIS, | ||||
| @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| @rem See the License for the specific language governing permissions and | ||||
| @rem limitations under the License. | ||||
| @rem | ||||
| 
 | ||||
| @if "%DEBUG%" == "" @echo off | ||||
| @rem ########################################################################## | ||||
| @rem | ||||
| @@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=. | ||||
| set APP_BASE_NAME=%~n0 | ||||
| set APP_HOME=%DIRNAME% | ||||
| 
 | ||||
| @rem Resolve any "." and ".." in APP_HOME to make it shorter. | ||||
| for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi | ||||
| 
 | ||||
| @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||||
| set DEFAULT_JVM_OPTS= | ||||
| set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" | ||||
| 
 | ||||
| @rem Find java.exe | ||||
| if defined JAVA_HOME goto findJavaFromJavaHome | ||||
| 
 | ||||
| set JAVA_EXE=java.exe | ||||
| %JAVA_EXE% -version >NUL 2>&1 | ||||
| if "%ERRORLEVEL%" == "0" goto init | ||||
| if "%ERRORLEVEL%" == "0" goto execute | ||||
| 
 | ||||
| echo. | ||||
| echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||||
| @@ -35,7 +54,7 @@ goto fail | ||||
| set JAVA_HOME=%JAVA_HOME:"=% | ||||
| set JAVA_EXE=%JAVA_HOME%/bin/java.exe | ||||
| 
 | ||||
| if exist "%JAVA_EXE%" goto init | ||||
| if exist "%JAVA_EXE%" goto execute | ||||
| 
 | ||||
| echo. | ||||
| echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | ||||
| @@ -45,28 +64,14 @@ echo location of your Java installation. | ||||
| 
 | ||||
| goto fail | ||||
| 
 | ||||
| :init | ||||
| @rem Get command-line arguments, handling Windows variants | ||||
| 
 | ||||
| if not "%OS%" == "Windows_NT" goto win9xME_args | ||||
| 
 | ||||
| :win9xME_args | ||||
| @rem Slurp the command line arguments. | ||||
| set CMD_LINE_ARGS= | ||||
| set _SKIP=2 | ||||
| 
 | ||||
| :win9xME_args_slurp | ||||
| if "x%~1" == "x" goto execute | ||||
| 
 | ||||
| set CMD_LINE_ARGS=%* | ||||
| 
 | ||||
| :execute | ||||
| @rem Setup the command line | ||||
| 
 | ||||
| set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar | ||||
| 
 | ||||
| 
 | ||||
| @rem Execute Gradle | ||||
| "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% | ||||
| "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* | ||||
| 
 | ||||
| :end | ||||
| @rem End local scope for the variables with windows NT shell | ||||
							
								
								
									
										23
									
								
								settings.gradle.kts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								settings.gradle.kts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| rootProject.name = "Minecraft-Window-Title" | ||||
|  | ||||
| pluginManagement { | ||||
| 	repositories { | ||||
| 		gradlePluginPortal() | ||||
| 		maven(url = "https://maven.fabricmc.net/") { name = "Fabric" } | ||||
| 		maven(url = "https://repo.spongepowered.org/repository/maven-public/") { name = "Sponge Snapshots" } | ||||
| 	} | ||||
| 	 | ||||
| 	plugins { | ||||
| 		if (settings.extra.has("loomVersion")) { | ||||
| 			id("fabric-loom") version "${settings.extra["loomVersion"]}-SNAPSHOT" | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| if (settings.extra.has("forgeVersion")) { | ||||
| 	include("Forge") | ||||
| } | ||||
|  | ||||
| if (settings.extra.has("fabricVersion")) { | ||||
| 	include("Fabric") | ||||
| } | ||||
							
								
								
									
										131
									
								
								src/main/java/chylex/customwindowtitle/TitleConfig.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								src/main/java/chylex/customwindowtitle/TitleConfig.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,131 @@ | ||||
| package chylex.customwindowtitle; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.nio.charset.StandardCharsets; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.Paths; | ||||
| import java.nio.file.StandardOpenOption; | ||||
| import java.util.Collections; | ||||
| import java.util.LinkedHashMap; | ||||
| import java.util.Map; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
| public final class TitleConfig { | ||||
| 	private static final Map<String, String> DEFAULTS; | ||||
| 	 | ||||
| 	static { | ||||
| 		final Map<String, String> defaults = new LinkedHashMap<>(); | ||||
| 		 | ||||
| 		defaults.put("title", "Minecraft {mcversion}"); | ||||
| 		defaults.put("icon16", ""); | ||||
| 		defaults.put("icon32", ""); | ||||
| 		 | ||||
| 		DEFAULTS = Collections.unmodifiableMap(defaults); | ||||
| 	} | ||||
| 	 | ||||
| 	public static TitleConfig read(final String folder) { | ||||
| 		final Path configFile = Paths.get(folder, "customwindowtitle-client.toml"); | ||||
| 		final Map<String, String> config = new LinkedHashMap<>(DEFAULTS); | ||||
| 		 | ||||
| 		try { | ||||
| 			if (!Files.exists(configFile)) { | ||||
| 				Files.write(configFile, config.entrySet().stream().map(entry -> String.format("%s = '%s'", entry.getKey(), entry.getValue())).collect(Collectors.toList()), StandardCharsets.UTF_8); | ||||
| 			} | ||||
| 			else { | ||||
| 				Files.readAllLines(configFile, StandardCharsets.UTF_8).stream().map(String::trim).filter(line -> !line.isEmpty()).forEach(line -> { | ||||
| 					final String[] split = line.split("=", 2); | ||||
| 					 | ||||
| 					if (split.length != 2) { | ||||
| 						throw new RuntimeException("CustomWindowTitle configuration has an invalid line: " + line); | ||||
| 					} | ||||
| 					 | ||||
| 					final String key = split[0].trim(); | ||||
| 					final String value = parseTrimmedValue(split[1].trim()); | ||||
| 					 | ||||
| 					if (config.containsKey(key)) { | ||||
| 						config.put(key, value); | ||||
| 					} | ||||
| 					else { | ||||
| 						throw new RuntimeException("CustomWindowTitle configuration has an invalid key: " + key); | ||||
| 					} | ||||
| 				}); | ||||
| 			} | ||||
| 		} catch (final IOException e) { | ||||
| 			throw new RuntimeException("CustomWindowTitle configuration error", e); | ||||
| 		} | ||||
| 		 | ||||
| 		final String icon16 = config.get("icon16"); | ||||
| 		final String icon32 = config.get("icon32"); | ||||
| 		 | ||||
| 		final Path pathIcon16 = icon16.isEmpty() ? null : Paths.get(folder, icon16); | ||||
| 		final Path pathIcon32 = icon32.isEmpty() ? null : Paths.get(folder, icon32); | ||||
| 		 | ||||
| 		if ((pathIcon16 == null) != (pathIcon32 == null)) { | ||||
| 			throw new RuntimeException("CustomWindowTitle configuration specifies only one icon, both 'icon16' and 'icon32' must be set."); | ||||
| 		} | ||||
| 		 | ||||
| 		if (pathIcon16 != null && Files.notExists(pathIcon16)) { | ||||
| 			throw new RuntimeException("CustomWindowTitle 16x16 icon not found: " + pathIcon16); | ||||
| 		} | ||||
| 		 | ||||
| 		if (pathIcon32 != null && Files.notExists(pathIcon32)) { | ||||
| 			throw new RuntimeException("CustomWindowTitle 32x32 icon not found: " + pathIcon32); | ||||
| 		} | ||||
| 		 | ||||
| 		return new TitleConfig(config.get("title"), pathIcon16, pathIcon32); | ||||
| 	} | ||||
| 	 | ||||
| 	private static String parseTrimmedValue(String value) { | ||||
| 		if (value.isEmpty()) { | ||||
| 			return value; | ||||
| 		} | ||||
| 		 | ||||
| 		final char surrounding = value.charAt(0); | ||||
| 		final int length = value.length(); | ||||
| 		 | ||||
| 		if (value.charAt(length - 1) == surrounding) { | ||||
| 			value = value.substring(1, length - 1); | ||||
| 			 | ||||
| 			if (surrounding == '"') { | ||||
| 				value = value.replace("\\\"", "\"").replace("\\\\", "\\"); | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		return value; | ||||
| 	} | ||||
| 	 | ||||
| 	private final String title; | ||||
| 	private final Path icon16; | ||||
| 	private final Path icon32; | ||||
| 	 | ||||
| 	private TitleConfig(final String title, final Path icon16, final Path icon32) { | ||||
| 		this.title = title; | ||||
| 		this.icon16 = icon16; | ||||
| 		this.icon32 = icon32; | ||||
| 	} | ||||
| 	 | ||||
| 	public String getTitle() { | ||||
| 		return title; | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean hasIcon() { | ||||
| 		return icon16 != null && icon32 != null; | ||||
| 	} | ||||
| 	 | ||||
| 	public InputStream readIcon16() { | ||||
| 		try { | ||||
| 			return Files.newInputStream(icon16, StandardOpenOption.READ); | ||||
| 		} catch (final IOException e) { | ||||
| 			throw new RuntimeException("CustomWindowTitle could not open the specified 16x16 icon: " + icon16, e); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public InputStream readIcon32() { | ||||
| 		try { | ||||
| 			return Files.newInputStream(icon32, StandardOpenOption.READ); | ||||
| 		} catch (final IOException e) { | ||||
| 			throw new RuntimeException("CustomWindowTitle could not open the specified 32x32 icon: " + icon16, e); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -6,32 +6,32 @@ import org.apache.logging.log4j.Logger; | ||||
| import java.util.regex.Matcher; | ||||
| import java.util.regex.Pattern; | ||||
| 
 | ||||
| public final class TitleParser{ | ||||
| public final class TitleParser { | ||||
| 	private static final Pattern tokenRegex = Pattern.compile("\\{([a-z]+)(?::([^}]+))?}"); | ||||
| 	private static final Logger logger = LogManager.getLogger("CustomWindowTitle"); | ||||
| 	 | ||||
| 	public static String parse(String input){ | ||||
| 		StringBuffer buffer = new StringBuffer(); | ||||
| 		Matcher matcher = tokenRegex.matcher(input); | ||||
| 	public static String parse(final String input) { | ||||
| 		final StringBuffer buffer = new StringBuffer(); | ||||
| 		final Matcher matcher = tokenRegex.matcher(input); | ||||
| 		 | ||||
| 		while(matcher.find()){ | ||||
| 			String token = matcher.group(1); | ||||
| 			String[] args = StringUtils.split(matcher.group(2), ','); | ||||
| 		while (matcher.find()) { | ||||
| 			final String token = matcher.group(1); | ||||
| 			final String[] args = StringUtils.split(matcher.group(2), ','); | ||||
| 			 | ||||
| 			String result = null; | ||||
| 			 | ||||
| 			try{ | ||||
| 			try { | ||||
| 				result = TitleTokens.getTokenFunction(token).apply(args == null ? ArrayUtils.EMPTY_STRING_ARRAY : args); | ||||
| 			}catch(TokenException e){ | ||||
| 			} catch (final TokenException e) { | ||||
| 				logger.warn("Error processing token '" + token + "': " + e.getMessage()); | ||||
| 			}catch(Throwable t){ | ||||
| 			} catch (final Throwable t) { | ||||
| 				logger.warn("Error processing token '" + token + "': " + t.getMessage(), t); | ||||
| 			} | ||||
| 			 | ||||
| 			if (result == null){ | ||||
| 			if (result == null) { | ||||
| 				matcher.appendReplacement(buffer, input.substring(matcher.start(), matcher.end())); | ||||
| 			} | ||||
| 			else{ | ||||
| 			else { | ||||
| 				matcher.appendReplacement(buffer, result); | ||||
| 			} | ||||
| 		} | ||||
| @@ -42,5 +42,5 @@ public final class TitleParser{ | ||||
| 	 | ||||
| 	// Static class | ||||
| 	 | ||||
| 	private TitleParser(){} | ||||
| 	private TitleParser() {} | ||||
| } | ||||
| @@ -5,39 +5,39 @@ import java.util.function.Function; | ||||
| import java.util.function.Supplier; | ||||
| import java.util.function.UnaryOperator; | ||||
| 
 | ||||
| public final class TitleTokens{ | ||||
| public final class TitleTokens { | ||||
| 	 | ||||
| 	// Registry | ||||
| 	 | ||||
| 	private static final Map<String, Function<String[], String>> tokenMap = new HashMap<>(); | ||||
| 	 | ||||
| 	public static void registerToken(String token, Function<String[], String> processor){ | ||||
| 	public static void registerToken(final String token, final Function<String[], String> processor) { | ||||
| 		tokenMap.putIfAbsent(token, processor); | ||||
| 	} | ||||
| 	 | ||||
| 	public static Function<String[], String> getTokenFunction(String token){ | ||||
| 	public static Function<String[], String> getTokenFunction(final String token) { | ||||
| 		return tokenMap.getOrDefault(token, args -> null); | ||||
| 	} | ||||
| 	 | ||||
| 	// Arguments | ||||
| 	 | ||||
| 	public static Function<String[], String> noArgs(Supplier<String> func){ | ||||
| 	public static Function<String[], String> noArgs(final Supplier<String> func) { | ||||
| 		return args -> args.length > 0 ? fail("expected no arguments, got " + args.length) : func.get(); | ||||
| 	} | ||||
| 	 | ||||
| 	public static Function<String[], String> oneArg(UnaryOperator<String> func){ | ||||
| 	public static Function<String[], String> oneArg(final UnaryOperator<String> func) { | ||||
| 		return args -> args.length != 1 ? fail("expected 1 argument, got " + args.length) : func.apply(args[0]); | ||||
| 	} | ||||
| 	 | ||||
| 	public static Function<String[], String> rangeArgs(int min, int max, Function<String[], String> func){ | ||||
| 	public static Function<String[], String> rangeArgs(final int min, final int max, final Function<String[], String> func) { | ||||
| 		return args -> args.length < min || args.length > max ? fail("expected between " + min + " and " + max + " arguments, got " + args.length) : func.apply(args); | ||||
| 	} | ||||
| 	 | ||||
| 	private static String fail(String message){ | ||||
| 	private static String fail(final String message) { | ||||
| 		throw new TokenException(message); | ||||
| 	} | ||||
| 	 | ||||
| 	// Static class | ||||
| 	 | ||||
| 	private TitleTokens(){} | ||||
| 	private TitleTokens() {} | ||||
| } | ||||
| @@ -0,0 +1,7 @@ | ||||
| package chylex.customwindowtitle; | ||||
|  | ||||
| public class TokenException extends RuntimeException { | ||||
| 	public TokenException(final String message) { | ||||
| 		super(message); | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,14 @@ | ||||
| package chylex.customwindowtitle.data; | ||||
|  | ||||
| import static chylex.customwindowtitle.TitleTokens.noArgs; | ||||
| import static chylex.customwindowtitle.TitleTokens.oneArg; | ||||
| import static chylex.customwindowtitle.TitleTokens.registerToken; | ||||
|  | ||||
| public final class CommonTokenData { | ||||
| 	public static void register(final CommonTokenProvider provider) { | ||||
| 		registerToken("mcversion", noArgs(provider::getMinecraftVersion)); | ||||
| 		registerToken("modversion", oneArg(provider::getModVersion)); | ||||
| 	} | ||||
| 	 | ||||
| 	private CommonTokenData() {} | ||||
| } | ||||
| @@ -0,0 +1,10 @@ | ||||
| package chylex.customwindowtitle.data; | ||||
| import net.minecraft.client.Minecraft; | ||||
|  | ||||
| public interface CommonTokenProvider { | ||||
| 	default String getMinecraftVersion() { | ||||
| 		return Minecraft.getInstance().getGame().getVersion().getName(); | ||||
| 	} | ||||
| 	 | ||||
| 	String getModVersion(final String modId); | ||||
| } | ||||
| @@ -0,0 +1,14 @@ | ||||
| package chylex.customwindowtitle.mixin; | ||||
| import net.minecraft.client.Minecraft; | ||||
| import org.spongepowered.asm.mixin.Mixin; | ||||
| import org.spongepowered.asm.mixin.injection.At; | ||||
| import org.spongepowered.asm.mixin.injection.Inject; | ||||
| import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | ||||
|  | ||||
| @Mixin(Minecraft.class) | ||||
| public final class DisableVanillaTitle { | ||||
| 	@Inject(method = "updateTitle()V", at = @At("HEAD"), cancellable = true) | ||||
| 	private void updateTitle(final CallbackInfo info) { | ||||
| 		info.cancel(); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										13
									
								
								src/main/resources/customwindowtitle.mixins.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/main/resources/customwindowtitle.mixins.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| { | ||||
|   "required": true, | ||||
|   "minVersion": "0.8", | ||||
|   "package": "chylex.customwindowtitle.mixin", | ||||
|   "refmap": "customwindowtitle.refmap.json", | ||||
|   "compatibilityLevel": "JAVA_16", | ||||
|   "client": [ | ||||
|     "DisableVanillaTitle" | ||||
|   ], | ||||
|   "injectors": { | ||||
|     "defaultRequire": 1 | ||||
|   } | ||||
| } | ||||
							
								
								
									
										7
									
								
								src/main/resources/pack.mcmeta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/main/resources/pack.mcmeta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| { | ||||
|     "pack": { | ||||
|         "description": "${name}", | ||||
|         "pack_format": 5, | ||||
|         "_comment": "" | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user