mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-14 09:05:17 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79a0c5e559 | ||
|
|
1c5db211af | ||
|
|
1e0134a1ca | ||
|
|
8f7adced47 | ||
|
|
f45f18b1d7 | ||
|
|
96a7e14a45 | ||
|
|
7eb36a1481 | ||
|
|
bc420dcb0b | ||
|
|
50164db5c1 | ||
|
|
0cd5ef6bb7 | ||
|
|
8a240ec3c7 | ||
|
|
5d6dc5dce3 | ||
|
|
e152984538 | ||
|
|
06ab104c9a | ||
|
|
e06d7e47e0 | ||
|
|
17f537bf88 | ||
|
|
d95aff3774 | ||
|
|
2b1438dbf1 | ||
|
|
547e56bd7b | ||
|
|
f65f57d5d5 | ||
|
|
dff2204558 | ||
|
|
7219061b05 | ||
|
|
6f66d06743 | ||
|
|
1a99ec7db6 | ||
|
|
d4f44d6b2a | ||
|
|
480bf2c1d0 | ||
|
|
701d98eafa | ||
|
|
953f083978 | ||
|
|
e3ce211cc7 | ||
|
|
cd715efca1 | ||
|
|
585d3a91e1 | ||
|
|
1d41aa978d | ||
|
|
4512f8e5e3 | ||
|
|
3aba56440a | ||
|
|
3a687f48b9 | ||
|
|
f07bf5cb30 | ||
|
|
725d988e36 | ||
|
|
31d726abad | ||
|
|
a9aa468457 | ||
|
|
c828bb63c5 |
No files matched your search
+2
-2
@@ -29,8 +29,8 @@ repositories {
|
||||
}
|
||||
|
||||
minecraft {
|
||||
version = '1.7.9'
|
||||
mcpVersion = '9.04'
|
||||
version = '1.7.10'
|
||||
mcpVersion = '9.05'
|
||||
fmlDir = projectDir.getAbsolutePath();
|
||||
mainClass = 'cpw.mods.fml.relauncher.ServerLaunchWrapper'
|
||||
tweakClass = 'cpw.mods.fml.common.launcher.FMLTweaker'
|
||||
|
||||
+70
-832
File diff suppressed because it is too large.
Load diff
+578
-14413
File diff suppressed because it is too large.
Load diff
+18867
-19525
File diff suppressed because it is too large.
Load diff
+3
-3
@@ -38,8 +38,8 @@ DirNatives = %(DirJars)s/bin/natives
|
||||
Client = %(DirJars)s/bin/minecraft.jar
|
||||
Server = %(DirJars)s/minecraft_server.jar
|
||||
LWJGL = %(DirJars)s/bin/jinput.jar,%(DirJars)s/bin/lwjgl.jar,%(DirJars)s/bin/lwjgl_util.jar
|
||||
MD5Client = 7a304554fdea879a799efe6eaedd8c95
|
||||
MD5Server = c48168f463e935262ea65b702f175153
|
||||
MD5Client = 595007b790548806f66762507203b896
|
||||
MD5Server = a1de2db50b0d8bfac45be3e01e54bddf
|
||||
|
||||
[RETROGUARD]
|
||||
Location = %(DirRuntime)s/bin/retroguard.jar
|
||||
@@ -129,7 +129,7 @@ LogFile = %(DirLogs)s/mcp.log
|
||||
LogFileErr = %(DirLogs)s/mcperr.log
|
||||
UpdateUrl = http://mcp.ocean-labs.de/files/mcprolling_{version}/
|
||||
IgnoreUpdate = %(DirBin)s,%(DirLib)s,%(DirLogs)s,%(DirModSrc)s,%(DirReobf)s,%(DirSrc)s,%(DirTemp)s,%(DirEclipse)s/Client/bin,%(DirEclipse)s/Server/bin,%(DirJars)s/world,%(DirJars)s/saves,%(DirJars)s/resources
|
||||
RGIndex = 145000
|
||||
RGIndex = 154000
|
||||
ParamIndex = 45000
|
||||
|
||||
[ASTYLE]
|
||||
|
||||
-1570
File diff suppressed because it is too large.
Load diff
@@ -1,13 +0,0 @@
|
||||
diff -r -U 3 minecraft_server\net\minecraft\server\dedicated\DedicatedServer.java minecraft_server_patched\net\minecraft\server\dedicated\DedicatedServer.java
|
||||
--- minecraft_server\net\minecraft\server\dedicated\DedicatedServer.java
|
||||
+++ minecraft_server_patched\net\minecraft\server\dedicated\DedicatedServer.java
|
||||
@@ -261,7 +261,7 @@
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
- protected void func_71190_q() {
|
||||
+ public void func_71190_q() {
|
||||
super.func_71190_q();
|
||||
this.func_71333_ah();
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
diff -r -U 3 minecraft\net\minecraft\server\integrated\IntegratedServer.java minecraft_patched\net\minecraft\server\integrated\IntegratedServer.java
|
||||
--- minecraft\net\minecraft\server\integrated\IntegratedServer.java
|
||||
+++ minecraft_patched\net\minecraft\server\integrated\IntegratedServer.java
|
||||
@@ -95,7 +95,7 @@
|
||||
return true;
|
||||
}
|
||||
|
||||
- protected void func_71217_p() {
|
||||
+ public void func_71217_p() {
|
||||
boolean var1 = this.field_71348_o;
|
||||
this.field_71348_o = Minecraft.func_71410_x().func_147114_u() != null && Minecraft.func_71410_x().func_147113_T();
|
||||
if(!var1 && this.field_71348_o) {
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
[VERSION]
|
||||
MCPVersion = 9.04
|
||||
ClientVersion = 1.7.9
|
||||
ServerVersion = 1.7.9
|
||||
MCPVersion = 9.05
|
||||
ClientVersion = 1.7.10
|
||||
ServerVersion = 1.7.10
|
||||
@@ -7,7 +7,7 @@
|
||||
<listEntry value="1"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="net.minecraft.launchwrapper.Launch"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="--version 1.6 --tweakClass cpw.mods.fml.common.launcher.FMLTweaker --accessToken FML"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="--version 1.7 --tweakClass cpw.mods.fml.common.launcher.FMLTweaker --username=ForgeDevName --accessToken FML --userProperties={}"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="Minecraft"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xincgc -Xmx1024M -Xms1024M -Dfml.ignoreInvalidMinecraftCertificates=true"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/>
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
{
|
||||
"id": "@minecraft_version@-@project@@version@",
|
||||
"time": "@timestamp@",
|
||||
"releaseTime": "1960-01-01T00:00:00-0700",
|
||||
"type": "release",
|
||||
"minecraftArguments": "--version FML_DEV --tweakClass cpw.mods.fml.common.launcher.FMLTweaker",
|
||||
"minimumLauncherVersion": 13,
|
||||
"assets": "1.7.10",
|
||||
"libraries": [
|
||||
{
|
||||
"name": "net.minecraft:launchwrapper:1.9"
|
||||
},
|
||||
{
|
||||
"name": "org.ow2.asm:asm-debug-all:4.1",
|
||||
"children" : ["sources"],
|
||||
"url" : "http://repo.maven.apache.org/maven2"
|
||||
},
|
||||
{
|
||||
"name": "org.scala-lang:scala-library:2.10.2",
|
||||
"children" : ["sources"],
|
||||
"url" : "http://repo.maven.apache.org/maven2"
|
||||
},
|
||||
{
|
||||
"name": "org.scala-lang:scala-compiler:2.10.2",
|
||||
"children" : ["sources"],
|
||||
"url" : "http://repo.maven.apache.org/maven2"
|
||||
},
|
||||
{
|
||||
"name": "net.sf.jopt-simple:jopt-simple:4.5",
|
||||
"children" : ["sources"],
|
||||
"url" : "http://repo.maven.apache.org/maven2"
|
||||
},
|
||||
{
|
||||
"name": "lzma:lzma:0.0.1"
|
||||
},
|
||||
{
|
||||
"name": "com.mojang:realms:1.2.4"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.commons:commons-compress:1.8.1"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.httpcomponents:httpclient:4.3.3"
|
||||
},
|
||||
{
|
||||
"name": "commons-logging:commons-logging:1.1.3"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.httpcomponents:httpcore:4.3.2"
|
||||
},
|
||||
{
|
||||
"name": "java3d:vecmath:1.3.1"
|
||||
},
|
||||
{
|
||||
"name": "net.sf.trove4j:trove4j:3.0.3"
|
||||
},
|
||||
{
|
||||
"name": "com.ibm.icu:icu4j-core-mojang:51.2"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:codecjorbis:20101023"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:codecwav:20101023"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:libraryjavasound:20101123"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:librarylwjglopenal:20100824"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:soundsystem:20120107"
|
||||
},
|
||||
{
|
||||
"name": "io.netty:netty-all:4.0.10.Final"
|
||||
},
|
||||
{
|
||||
"name": "com.google.guava:guava:16.0"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.commons:commons-lang3:3.2.1"
|
||||
},
|
||||
{
|
||||
"name": "commons-io:commons-io:2.4"
|
||||
},
|
||||
{
|
||||
"name": "commons-codec:commons-codec:1.9"
|
||||
},
|
||||
{
|
||||
"name": "net.java.jinput:jinput:2.0.5"
|
||||
},
|
||||
{
|
||||
"name": "net.java.jutils:jutils:1.0.0"
|
||||
},
|
||||
{
|
||||
"name": "com.google.code.gson:gson:2.2.4"
|
||||
},
|
||||
{
|
||||
"name": "com.mojang:authlib:1.5.13"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.logging.log4j:log4j-api:2.0-beta9"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.logging.log4j:log4j-core:2.0-beta9"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl:2.9.1"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl_util:2.9.1"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.1",
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "net.java.jinput:jinput-platform:2.0.5",
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch:5.16"
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch-platform:5.16",
|
||||
"rules": [
|
||||
{
|
||||
"action": "allow"
|
||||
},
|
||||
{
|
||||
"action": "disallow",
|
||||
"os": {
|
||||
"name": "linux"
|
||||
}
|
||||
}
|
||||
],
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows-${arch}",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch-external-platform:4.5",
|
||||
"rules": [
|
||||
{
|
||||
"action": "allow",
|
||||
"os": {
|
||||
"name": "windows"
|
||||
}
|
||||
}
|
||||
],
|
||||
"natives": {
|
||||
"windows": "natives-windows-${arch}"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"mainClass": "net.minecraft.launchwrapper.Launch"
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
{
|
||||
"id": "@minecraft_version@-@project@@version@",
|
||||
"time": "@timestamp@",
|
||||
"releaseTime": "1960-01-01T00:00:00-0700",
|
||||
"type": "release",
|
||||
"minecraftArguments": "--version FML_DEV --tweakClass cpw.mods.fml.common.launcher.FMLTweaker",
|
||||
"libraries": [
|
||||
{
|
||||
"name": "net.minecraft:launchwrapper:1.9",
|
||||
"comment" : "Important for FML, we add this"
|
||||
},
|
||||
{
|
||||
"name": "org.ow2.asm:asm-debug-all:4.1",
|
||||
"children" : ["sources"],
|
||||
"url" : "http://repo.maven.apache.org/maven2",
|
||||
"comment" : "Important for FML, we add this"
|
||||
},
|
||||
{
|
||||
"name": "org.scala-lang:scala-library:2.10.2",
|
||||
"children" : ["sources"],
|
||||
"url" : "http://repo.maven.apache.org/maven2",
|
||||
"comment" : "Important for FML, we add this"
|
||||
},
|
||||
{
|
||||
"name": "org.scala-lang:scala-compiler:2.10.2",
|
||||
"children" : ["sources"],
|
||||
"url" : "http://repo.maven.apache.org/maven2",
|
||||
"comment" : "Important for FML, we add this"
|
||||
},
|
||||
{
|
||||
"name": "net.sf.jopt-simple:jopt-simple:4.5",
|
||||
"children" : ["sources"],
|
||||
"url" : "http://repo.maven.apache.org/maven2"
|
||||
},
|
||||
{
|
||||
"name": "lzma:lzma:0.0.1"
|
||||
},
|
||||
{
|
||||
"name": "com.mojang:realms:1.2"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.commons:commons-compress:1.8.1"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.httpcomponents:httpclient:4.3.3"
|
||||
},
|
||||
{
|
||||
"name": "commons-logging:commons-logging:1.1.3"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.httpcomponents:httpcore:4.3.2"
|
||||
},
|
||||
{
|
||||
"name": "java3d:vecmath:1.3.1"
|
||||
},
|
||||
{
|
||||
"name": "net.sf.trove4j:trove4j:3.0.3"
|
||||
},
|
||||
{
|
||||
"name": "com.ibm.icu:icu4j-core-mojang:51.2"
|
||||
},
|
||||
{
|
||||
"name": "net.sf.jopt-simple:jopt-simple:4.5"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:codecjorbis:20101023"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:codecwav:20101023"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:libraryjavasound:20101123"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:librarylwjglopenal:20100824"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:soundsystem:20120107"
|
||||
},
|
||||
{
|
||||
"name": "io.netty:netty-all:4.0.10.Final"
|
||||
},
|
||||
{
|
||||
"name": "com.google.guava:guava:15.0"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.commons:commons-lang3:3.1"
|
||||
},
|
||||
{
|
||||
"name": "commons-io:commons-io:2.4"
|
||||
},
|
||||
{
|
||||
"name": "commons-codec:commons-codec:1.9"
|
||||
},
|
||||
{
|
||||
"name": "net.java.jinput:jinput:2.0.5"
|
||||
},
|
||||
{
|
||||
"name": "net.java.jutils:jutils:1.0.0"
|
||||
},
|
||||
{
|
||||
"name": "com.google.code.gson:gson:2.2.4"
|
||||
},
|
||||
{
|
||||
"name": "com.mojang:authlib:1.5.13"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.logging.log4j:log4j-api:2.0-beta9"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.logging.log4j:log4j-core:2.0-beta9"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl:2.9.1"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl_util:2.9.1"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.1",
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "net.java.jinput:jinput-platform:2.0.5",
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch:5.16"
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch-platform:5.16",
|
||||
"rules": [
|
||||
{
|
||||
"action": "allow"
|
||||
},
|
||||
{
|
||||
"action": "disallow",
|
||||
"os": {
|
||||
"name": "linux"
|
||||
}
|
||||
}
|
||||
],
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows-${arch}",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch-external-platform:4.5",
|
||||
"rules": [
|
||||
{
|
||||
"action": "allow",
|
||||
"os": {
|
||||
"name": "windows"
|
||||
}
|
||||
}
|
||||
],
|
||||
"natives": {
|
||||
"windows": "natives-windows-${arch}"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"mainClass": "net.minecraft.launchwrapper.Launch",
|
||||
"minimumLauncherVersion": 13,
|
||||
"assets": "1.7.4"
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
{
|
||||
"id": "1.7.10-pre3",
|
||||
"time": "2014-05-14T17:29:23+02:00",
|
||||
"releaseTime": "2014-05-14T17:29:23+02:00",
|
||||
"type": "snapshot",
|
||||
"minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userProperties ${user_properties} --userType ${user_type}",
|
||||
"minimumLauncherVersion": 13,
|
||||
"assets": "1.7.4",
|
||||
"libraries": [
|
||||
{
|
||||
"name": "com.mojang:realms:1.2.1"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.commons:commons-compress:1.8.1"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.httpcomponents:httpclient:4.3.3"
|
||||
},
|
||||
{
|
||||
"name": "commons-logging:commons-logging:1.1.3"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.httpcomponents:httpcore:4.3.2"
|
||||
},
|
||||
{
|
||||
"name": "java3d:vecmath:1.3.1"
|
||||
},
|
||||
{
|
||||
"name": "net.sf.trove4j:trove4j:3.0.3"
|
||||
},
|
||||
{
|
||||
"name": "com.ibm.icu:icu4j-core-mojang:51.2"
|
||||
},
|
||||
{
|
||||
"name": "net.sf.jopt-simple:jopt-simple:4.5"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:codecjorbis:20101023"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:codecwav:20101023"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:libraryjavasound:20101123"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:librarylwjglopenal:20100824"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:soundsystem:20120107"
|
||||
},
|
||||
{
|
||||
"name": "io.netty:netty-all:4.0.10.Final"
|
||||
},
|
||||
{
|
||||
"name": "com.google.guava:guava:15.0"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.commons:commons-lang3:3.1"
|
||||
},
|
||||
{
|
||||
"name": "commons-io:commons-io:2.4"
|
||||
},
|
||||
{
|
||||
"name": "commons-codec:commons-codec:1.9"
|
||||
},
|
||||
{
|
||||
"name": "net.java.jinput:jinput:2.0.5"
|
||||
},
|
||||
{
|
||||
"name": "net.java.jutils:jutils:1.0.0"
|
||||
},
|
||||
{
|
||||
"name": "com.google.code.gson:gson:2.2.4"
|
||||
},
|
||||
{
|
||||
"name": "com.mojang:authlib:1.5.13"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.logging.log4j:log4j-api:2.0-beta9"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.logging.log4j:log4j-core:2.0-beta9"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl:2.9.1"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl_util:2.9.1"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.1",
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "net.java.jinput:jinput-platform:2.0.5",
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch:5.16"
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch-platform:5.16",
|
||||
"rules": [
|
||||
{
|
||||
"action": "allow"
|
||||
},
|
||||
{
|
||||
"action": "disallow",
|
||||
"os": {
|
||||
"name": "linux"
|
||||
}
|
||||
}
|
||||
],
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows-${arch}",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch-external-platform:4.5",
|
||||
"rules": [
|
||||
{
|
||||
"action": "allow",
|
||||
"os": {
|
||||
"name": "windows"
|
||||
}
|
||||
}
|
||||
],
|
||||
"natives": {
|
||||
"windows": "natives-windows-${arch}"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"mainClass": "net.minecraft.client.main.Main"
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
{
|
||||
"id": "@minecraft_version@-@project@@version@",
|
||||
"time": "@timestamp@",
|
||||
"releaseTime": "1960-01-01T00:00:00-0700",
|
||||
"type": "release",
|
||||
"minecraftArguments": "--version FML_DEV --tweakClass cpw.mods.fml.common.launcher.FMLTweaker",
|
||||
"minimumLauncherVersion": 13,
|
||||
"assets": "1.7.10",
|
||||
"libraries": [
|
||||
{
|
||||
"name": "net.minecraft:launchwrapper:1.9"
|
||||
},
|
||||
{
|
||||
"name": "org.ow2.asm:asm-debug-all:4.1",
|
||||
"children" : ["sources"],
|
||||
"url" : "http://repo.maven.apache.org/maven2"
|
||||
},
|
||||
{
|
||||
"name": "org.scala-lang:scala-library:2.10.2",
|
||||
"children" : ["sources"],
|
||||
"url" : "http://repo.maven.apache.org/maven2"
|
||||
},
|
||||
{
|
||||
"name": "org.scala-lang:scala-compiler:2.10.2",
|
||||
"children" : ["sources"],
|
||||
"url" : "http://repo.maven.apache.org/maven2"
|
||||
},
|
||||
{
|
||||
"name": "net.sf.jopt-simple:jopt-simple:4.5",
|
||||
"children" : ["sources"],
|
||||
"url" : "http://repo.maven.apache.org/maven2"
|
||||
},
|
||||
{
|
||||
"name": "lzma:lzma:0.0.1"
|
||||
},
|
||||
{
|
||||
"name": "com.mojang:realms:1.2.3"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.commons:commons-compress:1.8.1"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.httpcomponents:httpclient:4.3.3"
|
||||
},
|
||||
{
|
||||
"name": "commons-logging:commons-logging:1.1.3"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.httpcomponents:httpcore:4.3.2"
|
||||
},
|
||||
{
|
||||
"name": "java3d:vecmath:1.3.1"
|
||||
},
|
||||
{
|
||||
"name": "net.sf.trove4j:trove4j:3.0.3"
|
||||
},
|
||||
{
|
||||
"name": "com.ibm.icu:icu4j-core-mojang:51.2"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:codecjorbis:20101023"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:codecwav:20101023"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:libraryjavasound:20101123"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:librarylwjglopenal:20100824"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:soundsystem:20120107"
|
||||
},
|
||||
{
|
||||
"name": "io.netty:netty-all:4.0.10.Final"
|
||||
},
|
||||
{
|
||||
"name": "com.google.guava:guava:16.0"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.commons:commons-lang3:3.2.1"
|
||||
},
|
||||
{
|
||||
"name": "commons-io:commons-io:2.4"
|
||||
},
|
||||
{
|
||||
"name": "commons-codec:commons-codec:1.9"
|
||||
},
|
||||
{
|
||||
"name": "net.java.jinput:jinput:2.0.5"
|
||||
},
|
||||
{
|
||||
"name": "net.java.jutils:jutils:1.0.0"
|
||||
},
|
||||
{
|
||||
"name": "com.google.code.gson:gson:2.2.4"
|
||||
},
|
||||
{
|
||||
"name": "com.mojang:authlib:1.5.13"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.logging.log4j:log4j-api:2.0-beta9"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.logging.log4j:log4j-core:2.0-beta9"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl:2.9.1"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl_util:2.9.1"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.1",
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "net.java.jinput:jinput-platform:2.0.5",
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch:5.16"
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch-platform:5.16",
|
||||
"rules": [
|
||||
{
|
||||
"action": "allow"
|
||||
},
|
||||
{
|
||||
"action": "disallow",
|
||||
"os": {
|
||||
"name": "linux"
|
||||
}
|
||||
}
|
||||
],
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows-${arch}",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch-external-platform:4.5",
|
||||
"rules": [
|
||||
{
|
||||
"action": "allow",
|
||||
"os": {
|
||||
"name": "windows"
|
||||
}
|
||||
}
|
||||
],
|
||||
"natives": {
|
||||
"windows": "natives-windows-${arch}"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"mainClass": "net.minecraft.launchwrapper.Launch"
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
{
|
||||
"install": {
|
||||
"profileName": "@project@",
|
||||
"target":"@minecraft_version@-@project@@version@",
|
||||
"path":"@artifact@",
|
||||
"version":"@project@ @version@",
|
||||
"filePath":"@universal_jar@",
|
||||
"welcome":"Welcome to the simple @project@ installer.",
|
||||
"minecraft":"@minecraft_version@",
|
||||
"mirrorList" : "http://files.minecraftforge.net/mirror-brand.list",
|
||||
"logo":"/big_logo.png"
|
||||
},
|
||||
"versionInfo": {
|
||||
"id": "@minecraft_version@-@project@@version@",
|
||||
"time": "@timestamp@",
|
||||
"releaseTime": "1960-01-01T00:00:00-0700",
|
||||
"type": "release",
|
||||
"minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userProperties ${user_properties} --userType ${user_type} --tweakClass cpw.mods.fml.common.launcher.FMLTweaker",
|
||||
"minimumLauncherVersion": 13,
|
||||
"assets": "1.7.10",
|
||||
"libraries": [
|
||||
{
|
||||
"name": "@artifact@",
|
||||
"url": "http://files.minecraftforge.net/maven/"
|
||||
},
|
||||
{
|
||||
"name": "net.minecraft:launchwrapper:1.9",
|
||||
"serverreq":true
|
||||
},
|
||||
{
|
||||
"name": "org.ow2.asm:asm-all:4.1",
|
||||
"serverreq":true
|
||||
},
|
||||
{
|
||||
"name": "org.scala-lang:scala-library:2.10.2",
|
||||
"url" : "http://files.minecraftforge.net/maven/",
|
||||
"checksums" : [ "6ba65d12cd09d441083262d6f73d2257fec7c663", "65de4339eaed1c3675485fb03a3532fecfd8e8cd" ],
|
||||
"serverreq":true,
|
||||
"clientreq":true
|
||||
},
|
||||
{
|
||||
"name": "org.scala-lang:scala-compiler:2.10.2",
|
||||
"url" : "http://files.minecraftforge.net/maven/",
|
||||
"checksums" : [ "64c8b1380cc53d6850823d6e4e7ae984aa44ef9c", "99fd0ffb66f3088b0cd1071315fd5eb2b2b070ff" ],
|
||||
"serverreq":true,
|
||||
"clientreq":true
|
||||
},
|
||||
{
|
||||
"name": "net.sf.jopt-simple:jopt-simple:4.5",
|
||||
"serverreq":true
|
||||
},
|
||||
{
|
||||
"name": "lzma:lzma:0.0.1",
|
||||
"serverreq":true
|
||||
},
|
||||
{
|
||||
"name": "com.mojang:realms:1.2.4"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.commons:commons-compress:1.8.1"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.httpcomponents:httpclient:4.3.3"
|
||||
},
|
||||
{
|
||||
"name": "commons-logging:commons-logging:1.1.3"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.httpcomponents:httpcore:4.3.2"
|
||||
},
|
||||
{
|
||||
"name": "java3d:vecmath:1.3.1"
|
||||
},
|
||||
{
|
||||
"name": "net.sf.trove4j:trove4j:3.0.3"
|
||||
},
|
||||
{
|
||||
"name": "com.ibm.icu:icu4j-core-mojang:51.2"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:codecjorbis:20101023"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:codecwav:20101023"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:libraryjavasound:20101123"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:librarylwjglopenal:20100824"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:soundsystem:20120107"
|
||||
},
|
||||
{
|
||||
"name": "io.netty:netty-all:4.0.10.Final"
|
||||
},
|
||||
{
|
||||
"name": "com.google.guava:guava:16.0"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.commons:commons-lang3:3.2.1"
|
||||
},
|
||||
{
|
||||
"name": "commons-io:commons-io:2.4"
|
||||
},
|
||||
{
|
||||
"name": "commons-codec:commons-codec:1.9"
|
||||
},
|
||||
{
|
||||
"name": "net.java.jinput:jinput:2.0.5"
|
||||
},
|
||||
{
|
||||
"name": "net.java.jutils:jutils:1.0.0"
|
||||
},
|
||||
{
|
||||
"name": "com.google.code.gson:gson:2.2.4"
|
||||
},
|
||||
{
|
||||
"name": "com.mojang:authlib:1.5.13"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.logging.log4j:log4j-api:2.0-beta9"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.logging.log4j:log4j-core:2.0-beta9"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl:2.9.1"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl_util:2.9.1"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.1",
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "net.java.jinput:jinput-platform:2.0.5",
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch:5.16"
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch-platform:5.16",
|
||||
"rules": [
|
||||
{
|
||||
"action": "allow"
|
||||
},
|
||||
{
|
||||
"action": "disallow",
|
||||
"os": {
|
||||
"name": "linux"
|
||||
}
|
||||
}
|
||||
],
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows-${arch}",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch-external-platform:4.5",
|
||||
"rules": [
|
||||
{
|
||||
"action": "allow",
|
||||
"os": {
|
||||
"name": "windows"
|
||||
}
|
||||
}
|
||||
],
|
||||
"natives": {
|
||||
"windows": "natives-windows-${arch}"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"mainClass": "net.minecraft.launchwrapper.Launch"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
{
|
||||
"id": "1.7.10-pre4",
|
||||
"time": "2014-05-14T18:29:23+02:00",
|
||||
"releaseTime": "2014-05-14T18:29:23+02:00",
|
||||
"type": "snapshot",
|
||||
"minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userProperties ${user_properties} --userType ${user_type}",
|
||||
"minimumLauncherVersion": 13,
|
||||
"assets": "1.7.10",
|
||||
"libraries": [
|
||||
{
|
||||
"name": "com.mojang:realms:1.2.4"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.commons:commons-compress:1.8.1"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.httpcomponents:httpclient:4.3.3"
|
||||
},
|
||||
{
|
||||
"name": "commons-logging:commons-logging:1.1.3"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.httpcomponents:httpcore:4.3.2"
|
||||
},
|
||||
{
|
||||
"name": "java3d:vecmath:1.3.1"
|
||||
},
|
||||
{
|
||||
"name": "net.sf.trove4j:trove4j:3.0.3"
|
||||
},
|
||||
{
|
||||
"name": "com.ibm.icu:icu4j-core-mojang:51.2"
|
||||
},
|
||||
{
|
||||
"name": "net.sf.jopt-simple:jopt-simple:4.5"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:codecjorbis:20101023"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:codecwav:20101023"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:libraryjavasound:20101123"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:librarylwjglopenal:20100824"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:soundsystem:20120107"
|
||||
},
|
||||
{
|
||||
"name": "io.netty:netty-all:4.0.10.Final"
|
||||
},
|
||||
{
|
||||
"name": "com.google.guava:guava:15.0"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.commons:commons-lang3:3.1"
|
||||
},
|
||||
{
|
||||
"name": "commons-io:commons-io:2.4"
|
||||
},
|
||||
{
|
||||
"name": "commons-codec:commons-codec:1.9"
|
||||
},
|
||||
{
|
||||
"name": "net.java.jinput:jinput:2.0.5"
|
||||
},
|
||||
{
|
||||
"name": "net.java.jutils:jutils:1.0.0"
|
||||
},
|
||||
{
|
||||
"name": "com.google.code.gson:gson:2.2.4"
|
||||
},
|
||||
{
|
||||
"name": "com.mojang:authlib:1.5.13"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.logging.log4j:log4j-api:2.0-beta9"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.logging.log4j:log4j-core:2.0-beta9"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl:2.9.1"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl_util:2.9.1"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.1",
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "net.java.jinput:jinput-platform:2.0.5",
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch:5.16"
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch-platform:5.16",
|
||||
"rules": [
|
||||
{
|
||||
"action": "allow"
|
||||
},
|
||||
{
|
||||
"action": "disallow",
|
||||
"os": {
|
||||
"name": "linux"
|
||||
}
|
||||
}
|
||||
],
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows-${arch}",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch-external-platform:4.5",
|
||||
"rules": [
|
||||
{
|
||||
"action": "allow",
|
||||
"os": {
|
||||
"name": "windows"
|
||||
}
|
||||
}
|
||||
],
|
||||
"natives": {
|
||||
"windows": "natives-windows-${arch}"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"mainClass": "net.minecraft.client.main.Main"
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
{
|
||||
"install": {
|
||||
"profileName": "@project@",
|
||||
"target":"@minecraft_version@-@project@@version@",
|
||||
"path":"@artifact@",
|
||||
"version":"@project@ @version@",
|
||||
"filePath":"@universal_jar@",
|
||||
"welcome":"Welcome to the simple @project@ installer.",
|
||||
"minecraft":"@minecraft_version@",
|
||||
"mirrorList" : "http://files.minecraftforge.net/mirror-brand.list",
|
||||
"logo":"/big_logo.png"
|
||||
},
|
||||
"versionInfo": {
|
||||
"id": "@minecraft_version@-@project@@version@",
|
||||
"time": "@timestamp@",
|
||||
"releaseTime": "1960-01-01T00:00:00-0700",
|
||||
"type": "release",
|
||||
"minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userProperties ${user_properties} --userType ${user_type} --tweakClass cpw.mods.fml.common.launcher.FMLTweaker",
|
||||
"minimumLauncherVersion": 13,
|
||||
"assets": "1.7.10",
|
||||
"libraries": [
|
||||
{
|
||||
"name": "@artifact@",
|
||||
"url": "http://files.minecraftforge.net/maven/"
|
||||
},
|
||||
{
|
||||
"name": "net.minecraft:launchwrapper:1.9",
|
||||
"serverreq":true
|
||||
},
|
||||
{
|
||||
"name": "org.ow2.asm:asm-all:4.1",
|
||||
"serverreq":true
|
||||
},
|
||||
{
|
||||
"name": "org.scala-lang:scala-library:2.10.2",
|
||||
"url" : "http://files.minecraftforge.net/maven/",
|
||||
"checksums" : [ "6ba65d12cd09d441083262d6f73d2257fec7c663", "65de4339eaed1c3675485fb03a3532fecfd8e8cd" ],
|
||||
"serverreq":true,
|
||||
"clientreq":true
|
||||
},
|
||||
{
|
||||
"name": "org.scala-lang:scala-compiler:2.10.2",
|
||||
"url" : "http://files.minecraftforge.net/maven/",
|
||||
"checksums" : [ "64c8b1380cc53d6850823d6e4e7ae984aa44ef9c", "99fd0ffb66f3088b0cd1071315fd5eb2b2b070ff" ],
|
||||
"serverreq":true,
|
||||
"clientreq":true
|
||||
},
|
||||
{
|
||||
"name": "net.sf.jopt-simple:jopt-simple:4.5",
|
||||
"serverreq":true
|
||||
},
|
||||
{
|
||||
"name": "lzma:lzma:0.0.1",
|
||||
"serverreq":true
|
||||
},
|
||||
{
|
||||
"name": "com.mojang:realms:1.2.4"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.commons:commons-compress:1.8.1"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.httpcomponents:httpclient:4.3.3"
|
||||
},
|
||||
{
|
||||
"name": "commons-logging:commons-logging:1.1.3"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.httpcomponents:httpcore:4.3.2"
|
||||
},
|
||||
{
|
||||
"name": "java3d:vecmath:1.3.1"
|
||||
},
|
||||
{
|
||||
"name": "net.sf.trove4j:trove4j:3.0.3"
|
||||
},
|
||||
{
|
||||
"name": "com.ibm.icu:icu4j-core-mojang:51.2"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:codecjorbis:20101023"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:codecwav:20101023"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:libraryjavasound:20101123"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:librarylwjglopenal:20100824"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:soundsystem:20120107"
|
||||
},
|
||||
{
|
||||
"name": "io.netty:netty-all:4.0.10.Final"
|
||||
},
|
||||
{
|
||||
"name": "com.google.guava:guava:16.0"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.commons:commons-lang3:3.2.1"
|
||||
},
|
||||
{
|
||||
"name": "commons-io:commons-io:2.4"
|
||||
},
|
||||
{
|
||||
"name": "commons-codec:commons-codec:1.9"
|
||||
},
|
||||
{
|
||||
"name": "net.java.jinput:jinput:2.0.5"
|
||||
},
|
||||
{
|
||||
"name": "net.java.jutils:jutils:1.0.0"
|
||||
},
|
||||
{
|
||||
"name": "com.google.code.gson:gson:2.2.4"
|
||||
},
|
||||
{
|
||||
"name": "com.mojang:authlib:1.5.13"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.logging.log4j:log4j-api:2.0-beta9"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.logging.log4j:log4j-core:2.0-beta9"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl:2.9.1"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl_util:2.9.1"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.1",
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "net.java.jinput:jinput-platform:2.0.5",
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch:5.16"
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch-platform:5.16",
|
||||
"rules": [
|
||||
{
|
||||
"action": "allow"
|
||||
},
|
||||
{
|
||||
"action": "disallow",
|
||||
"os": {
|
||||
"name": "linux"
|
||||
}
|
||||
}
|
||||
],
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows-${arch}",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch-external-platform:4.5",
|
||||
"rules": [
|
||||
{
|
||||
"action": "allow",
|
||||
"os": {
|
||||
"name": "windows"
|
||||
}
|
||||
}
|
||||
],
|
||||
"natives": {
|
||||
"windows": "natives-windows-${arch}"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"mainClass": "net.minecraft.launchwrapper.Launch"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
{
|
||||
"id": "1.7.10",
|
||||
"time": "2014-05-14T19:29:23+02:00",
|
||||
"releaseTime": "2014-05-14T19:29:23+02:00",
|
||||
"type": "release",
|
||||
"minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userProperties ${user_properties} --userType ${user_type}",
|
||||
"minimumLauncherVersion": 13,
|
||||
"assets": "1.7.10",
|
||||
"libraries": [
|
||||
{
|
||||
"name": "com.mojang:realms:1.2.4"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.commons:commons-compress:1.8.1"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.httpcomponents:httpclient:4.3.3"
|
||||
},
|
||||
{
|
||||
"name": "commons-logging:commons-logging:1.1.3"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.httpcomponents:httpcore:4.3.2"
|
||||
},
|
||||
{
|
||||
"name": "java3d:vecmath:1.3.1"
|
||||
},
|
||||
{
|
||||
"name": "net.sf.trove4j:trove4j:3.0.3"
|
||||
},
|
||||
{
|
||||
"name": "com.ibm.icu:icu4j-core-mojang:51.2"
|
||||
},
|
||||
{
|
||||
"name": "net.sf.jopt-simple:jopt-simple:4.5"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:codecjorbis:20101023"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:codecwav:20101023"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:libraryjavasound:20101123"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:librarylwjglopenal:20100824"
|
||||
},
|
||||
{
|
||||
"name": "com.paulscode:soundsystem:20120107"
|
||||
},
|
||||
{
|
||||
"name": "io.netty:netty-all:4.0.10.Final"
|
||||
},
|
||||
{
|
||||
"name": "com.google.guava:guava:15.0"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.commons:commons-lang3:3.1"
|
||||
},
|
||||
{
|
||||
"name": "commons-io:commons-io:2.4"
|
||||
},
|
||||
{
|
||||
"name": "commons-codec:commons-codec:1.9"
|
||||
},
|
||||
{
|
||||
"name": "net.java.jinput:jinput:2.0.5"
|
||||
},
|
||||
{
|
||||
"name": "net.java.jutils:jutils:1.0.0"
|
||||
},
|
||||
{
|
||||
"name": "com.google.code.gson:gson:2.2.4"
|
||||
},
|
||||
{
|
||||
"name": "com.mojang:authlib:1.5.13"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.logging.log4j:log4j-api:2.0-beta9"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.logging.log4j:log4j-core:2.0-beta9"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl:2.9.1"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl_util:2.9.1"
|
||||
},
|
||||
{
|
||||
"name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.1",
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "net.java.jinput:jinput-platform:2.0.5",
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch:5.16"
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch-platform:5.16",
|
||||
"rules": [
|
||||
{
|
||||
"action": "allow"
|
||||
},
|
||||
{
|
||||
"action": "disallow",
|
||||
"os": {
|
||||
"name": "linux"
|
||||
}
|
||||
}
|
||||
],
|
||||
"natives": {
|
||||
"linux": "natives-linux",
|
||||
"windows": "natives-windows-${arch}",
|
||||
"osx": "natives-osx"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tv.twitch:twitch-external-platform:4.5",
|
||||
"rules": [
|
||||
{
|
||||
"action": "allow",
|
||||
"os": {
|
||||
"name": "windows"
|
||||
}
|
||||
}
|
||||
],
|
||||
"natives": {
|
||||
"windows": "natives-windows-${arch}"
|
||||
},
|
||||
"extract": {
|
||||
"exclude": [
|
||||
"META-INF/"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"mainClass": "net.minecraft.client.main.Main"
|
||||
}
|
||||
@@ -78,7 +78,7 @@
|
||||
try
|
||||
{
|
||||
Display.setVSyncEnabled(this.field_71474_y.field_74352_v);
|
||||
@@ -970,9 +979,11 @@
|
||||
@@ -971,9 +980,11 @@
|
||||
|
||||
if (!this.field_71454_w)
|
||||
{
|
||||
@@ -90,7 +90,7 @@
|
||||
}
|
||||
|
||||
GL11.glFlush();
|
||||
@@ -1554,6 +1565,8 @@
|
||||
@@ -1555,6 +1566,8 @@
|
||||
--this.field_71467_ac;
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
this.field_71424_I.func_76320_a("gui");
|
||||
|
||||
if (!this.field_71445_n)
|
||||
@@ -1698,6 +1711,7 @@
|
||||
@@ -1699,6 +1712,7 @@
|
||||
this.field_71462_r.func_146274_d();
|
||||
}
|
||||
}
|
||||
@@ -107,7 +107,7 @@
|
||||
}
|
||||
|
||||
if (this.field_71429_W > 0)
|
||||
@@ -1834,6 +1848,7 @@
|
||||
@@ -1835,6 +1849,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,7 +115,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2025,12 +2040,15 @@
|
||||
@@ -2026,12 +2041,15 @@
|
||||
this.field_71453_ak.func_74428_b();
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
this.func_71403_a((WorldClient)null);
|
||||
System.gc();
|
||||
ISaveHandler isavehandler = this.field_71469_aa.func_75804_a(p_71371_1_, false);
|
||||
@@ -2066,6 +2084,12 @@
|
||||
@@ -2067,6 +2085,12 @@
|
||||
|
||||
while (!this.field_71437_Z.func_71200_ad())
|
||||
{
|
||||
@@ -144,7 +144,7 @@
|
||||
String s2 = this.field_71437_Z.func_71195_b_();
|
||||
|
||||
if (s2 != null)
|
||||
@@ -2141,6 +2165,7 @@
|
||||
@@ -2142,6 +2166,7 @@
|
||||
this.field_110448_aq.func_148529_f();
|
||||
this.func_71351_a((ServerData)null);
|
||||
this.field_71455_al = false;
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
import java.util.Date;
|
||||
+import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import net.minecraft.client.Minecraft;
|
||||
@@ -35,6 +38,9 @@
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
@@ -29,6 +32,9 @@
|
||||
import org.lwjgl.opengl.GLContext;
|
||||
import org.lwjgl.util.glu.Project;
|
||||
|
||||
@@ -26,40 +26,22 @@
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class GuiMainMenu extends GuiScreen implements GuiYesNoCallback
|
||||
{
|
||||
@@ -67,6 +73,8 @@
|
||||
private GuiButton field_130023_H;
|
||||
private static final String __OBFID = "CL_00001154";
|
||||
|
||||
+ private GuiButton fmlModButton = null;
|
||||
+
|
||||
public GuiMainMenu()
|
||||
{
|
||||
this.field_146972_A = field_96138_a;
|
||||
@@ -267,13 +275,22 @@
|
||||
private void func_130022_h()
|
||||
{
|
||||
this.field_130023_H.field_146125_m = true;
|
||||
+ fmlModButton.field_146120_f = 98;
|
||||
+ fmlModButton.field_146128_h = this.field_146294_l / 2 + 2;
|
||||
}
|
||||
|
||||
private void func_73969_a(int p_73969_1_, int p_73969_2_)
|
||||
@@ -190,7 +196,13 @@
|
||||
{
|
||||
this.field_146292_n.add(new GuiButton(1, this.field_146294_l / 2 - 100, p_73969_1_, I18n.func_135052_a("menu.singleplayer", new Object[0])));
|
||||
this.field_146292_n.add(new GuiButton(2, this.field_146294_l / 2 - 100, p_73969_1_ + p_73969_2_ * 1, I18n.func_135052_a("menu.multiplayer", new Object[0])));
|
||||
- this.field_146292_n.add(this.field_130023_H = new GuiButton(14, this.field_146294_l / 2 - 100, p_73969_1_ + p_73969_2_ * 2, I18n.func_135052_a("menu.online", new Object[0])));
|
||||
+ //If Minecraft Realms is enabled, halve the size of both buttons and set them next to eachother.
|
||||
+ fmlModButton = new GuiButton(6, this.field_146294_l / 2 - 100, p_73969_1_ + p_73969_2_ * 2, "Mods");
|
||||
- this.field_146292_n.add(new GuiButton(14, this.field_146294_l / 2 - 100, p_73969_1_ + p_73969_2_ * 2, I18n.func_135052_a("menu.online", new Object[0])));
|
||||
+ GuiButton realmsButton = new GuiButton(14, this.field_146294_l / 2 - 100, p_73969_1_ + p_73969_2_ * 2, I18n.func_135052_a("menu.online", new Object[0]));
|
||||
+ GuiButton fmlModButton = new GuiButton(6, this.field_146294_l / 2 - 100, p_73969_1_ + p_73969_2_ * 2, "Mods");
|
||||
+ fmlModButton.field_146128_h = this.field_146294_l / 2 + 2;
|
||||
+ realmsButton.field_146120_f = 98;
|
||||
+ fmlModButton.field_146120_f = 98;
|
||||
+ this.field_146292_n.add(realmsButton);
|
||||
+ this.field_146292_n.add(fmlModButton);
|
||||
+
|
||||
+ field_130023_H = new GuiButton(14, this.field_146294_l / 2 - 100, p_73969_1_ + p_73969_2_ * 2, I18n.func_135052_a("menu.online"));
|
||||
+ field_130023_H.field_146120_f = 98;
|
||||
+ field_130023_H.field_146128_h = this.field_146294_l / 2 - 100;
|
||||
+ this.field_146292_n.add(field_130023_H);
|
||||
this.field_130023_H.field_146125_m = false;
|
||||
}
|
||||
|
||||
@@ -322,6 +339,11 @@
|
||||
private void func_73972_b(int p_73972_1_, int p_73972_2_)
|
||||
@@ -238,6 +250,11 @@
|
||||
this.field_146297_k.func_71400_g();
|
||||
}
|
||||
|
||||
@@ -71,7 +53,7 @@
|
||||
if (p_146284_1_.field_146127_k == 11)
|
||||
{
|
||||
this.field_146297_k.func_71371_a("Demo_World", "Demo_World", DemoWorldServer.field_73071_a);
|
||||
@@ -585,7 +607,15 @@
|
||||
@@ -481,7 +498,15 @@
|
||||
s = s + " Demo";
|
||||
}
|
||||
|
||||
|
||||
@@ -116,12 +116,3 @@
|
||||
}
|
||||
|
||||
public CrashReport func_71230_b(CrashReport p_71230_1_)
|
||||
@@ -1117,7 +1139,7 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
- public abstract String func_71206_a(WorldSettings.GameType var1, boolean var2);
|
||||
+ public abstract String func_71206_a(WorldSettings.GameType p_71206_1_, boolean p_71206_2_);
|
||||
|
||||
public int func_71259_af()
|
||||
{
|
||||
@@ -7,7 +7,7 @@
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import java.io.BufferedReader;
|
||||
@@ -46,6 +47,7 @@
|
||||
@@ -48,6 +49,7 @@
|
||||
private boolean field_71338_p;
|
||||
private WorldSettings.GameType field_71337_q;
|
||||
private boolean field_71335_s;
|
||||
@@ -15,7 +15,7 @@
|
||||
private static final String __OBFID = "CL_00001784";
|
||||
|
||||
public DedicatedServer(File p_i1508_1_)
|
||||
@@ -110,6 +112,8 @@
|
||||
@@ -112,6 +114,8 @@
|
||||
field_155771_h.warn("To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\"");
|
||||
}
|
||||
|
||||
@@ -23,30 +23,30 @@
|
||||
+
|
||||
field_155771_h.info("Loading properties");
|
||||
this.field_71340_o = new PropertyManager(new File("server.properties"));
|
||||
|
||||
@@ -192,6 +196,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
+ FMLCommonHandler.instance().onServerStarted();
|
||||
this.func_152361_a(new DedicatedPlayerList(this));
|
||||
long j = System.nanoTime();
|
||||
|
||||
@@ -237,6 +242,7 @@
|
||||
this.func_71191_d((this.func_71207_Z() + 8) / 16 * 16);
|
||||
this.func_71191_d(MathHelper.func_76125_a(this.func_71207_Z(), 64, 256));
|
||||
this.field_71340_o.func_73667_a("max-build-height", Integer.valueOf(this.func_71207_Z()));
|
||||
+ if (!FMLCommonHandler.instance().handleServerAboutToStart(this)) { return false; }
|
||||
field_155771_h.info("Preparing level \"" + this.func_71270_I() + "\"");
|
||||
this.func_71247_a(this.func_71270_I(), this.func_71270_I(), k, worldtype, s2);
|
||||
long i1 = System.nanoTime() - j;
|
||||
@@ -257,7 +263,8 @@
|
||||
this.field_71339_n.func_72602_a();
|
||||
this.field_154332_n = new ServerEula(new File("eula.txt"));
|
||||
@@ -203,6 +207,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
+ FMLCommonHandler.instance().onServerStarted();
|
||||
this.func_152361_a(new DedicatedPlayerList(this));
|
||||
long j = System.nanoTime();
|
||||
|
||||
- return true;
|
||||
+ allowPlayerLogins = true;
|
||||
+ return FMLCommonHandler.instance().handleServerStarting(this);
|
||||
@@ -248,6 +253,7 @@
|
||||
this.func_71191_d((this.func_71207_Z() + 8) / 16 * 16);
|
||||
this.func_71191_d(MathHelper.func_76125_a(this.func_71207_Z(), 64, 256));
|
||||
this.field_71340_o.func_73667_a("max-build-height", Integer.valueOf(this.func_71207_Z()));
|
||||
+ if (!FMLCommonHandler.instance().handleServerAboutToStart(this)) { return false; }
|
||||
field_155771_h.info("Preparing level \"" + this.func_71270_I() + "\"");
|
||||
this.func_71247_a(this.func_71270_I(), this.func_71270_I(), k, worldtype, s2);
|
||||
long i1 = System.nanoTime() - j;
|
||||
@@ -268,7 +274,8 @@
|
||||
this.field_71339_n.func_72602_a();
|
||||
}
|
||||
|
||||
- return true;
|
||||
+ allowPlayerLogins = true;
|
||||
+ return FMLCommonHandler.instance().handleServerStarting(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
--- ../src-base/minecraft/net/minecraft/util/ObjectIntIdentityMap.java
|
||||
+++ ../src-work/minecraft/net/minecraft/util/ObjectIntIdentityMap.java
|
||||
@@ -2,20 +2,21 @@
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Iterators;
|
||||
-import gnu.trove.map.hash.TIntIntHashMap;
|
||||
import java.util.ArrayList;
|
||||
+import java.util.IdentityHashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
+import java.util.Map;
|
||||
|
||||
public class ObjectIntIdentityMap implements IObjectIntIterable
|
||||
{
|
||||
- protected TIntIntHashMap field_148749_a = new TIntIntHashMap(256, 0.5F, -1, -1);
|
||||
+ protected Map<Object, Integer> field_148749_a = new IdentityHashMap<Object, Integer>(512);
|
||||
protected List field_148748_b = new ArrayList();
|
||||
private static final String __OBFID = "CL_00001203";
|
||||
|
||||
public void func_148746_a(Object p_148746_1_, int p_148746_2_)
|
||||
{
|
||||
- this.field_148749_a.put(System.identityHashCode(p_148746_1_), p_148746_2_);
|
||||
+ this.field_148749_a.put(p_148746_1_, p_148746_2_);
|
||||
|
||||
while (this.field_148748_b.size() <= p_148746_2_)
|
||||
{
|
||||
@@ -27,7 +28,8 @@
|
||||
|
||||
public int func_148747_b(Object p_148747_1_)
|
||||
{
|
||||
- return this.field_148749_a.get(System.identityHashCode(p_148747_1_));
|
||||
+ Integer ret = this.field_148749_a.get(p_148747_1_);
|
||||
+ return ret != null ? ret : -1;
|
||||
}
|
||||
|
||||
public Object func_148745_a(int p_148745_1_)
|
||||
@@ -1,6 +1,6 @@
|
||||
--- ../src-base/minecraft/net/minecraft/world/World.java
|
||||
+++ ../src-work/minecraft/net/minecraft/world/World.java
|
||||
@@ -1799,14 +1799,14 @@
|
||||
@@ -1800,14 +1800,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
this.field_72984_F.func_76318_c("pendingBlockEntities");
|
||||
|
||||
if (!this.field_147484_a.isEmpty())
|
||||
@@ -3597,7 +3597,7 @@
|
||||
@@ -3598,7 +3598,7 @@
|
||||
@SideOnly(Side.CLIENT)
|
||||
public double func_72919_O()
|
||||
{
|
||||
|
||||
@@ -716,7 +716,7 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
}
|
||||
|
||||
Map<String,String> modListMap = modListBldr.build();
|
||||
serverDataTag.put(data, new ExtendedServerListData(type, FMLNetworkHandler.checkModList(modListMap, Side.CLIENT) == null, modListMap, !moddedClientAllowed));
|
||||
serverDataTag.put(data, new ExtendedServerListData(type, FMLNetworkHandler.checkModList(modListMap, Side.SERVER) == null, modListMap, !moddedClientAllowed));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,50 +1,88 @@
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import cpw.mods.fml.client.config.ConfigGuiType;
|
||||
import cpw.mods.fml.client.config.DummyConfigElement;
|
||||
import cpw.mods.fml.client.config.GuiConfig;
|
||||
import cpw.mods.fml.client.config.IConfigElement;
|
||||
import cpw.mods.fml.client.config.DummyConfigElement.DummyCategoryElement;
|
||||
import cpw.mods.fml.client.config.DummyConfigElement.DummyListElement;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
|
||||
public class FMLConfigGuiFactory implements IModGuiFactory {
|
||||
public static class FMLConfigGuiScreen extends GuiScreen {
|
||||
private GuiScreen parent;
|
||||
public class FMLConfigGuiFactory implements IModGuiFactory
|
||||
{
|
||||
public static class FMLConfigGuiScreen extends GuiConfig
|
||||
{
|
||||
|
||||
public FMLConfigGuiScreen(GuiScreen parent)
|
||||
{
|
||||
this.parent = parent;
|
||||
super(parent, getConfigElements(), "FML", false, false, I18n.format("fml.config.sample.title"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void initGui()
|
||||
|
||||
private static List<IConfigElement> getConfigElements()
|
||||
{
|
||||
this.buttonList.add(new GuiButton(1, this.width / 2 - 75, this.height - 38, I18n.format("gui.done")));
|
||||
}
|
||||
List<IConfigElement> list = new ArrayList<IConfigElement>();
|
||||
List<IConfigElement> listsList = new ArrayList<IConfigElement>();
|
||||
List<IConfigElement> stringsList = new ArrayList<IConfigElement>();
|
||||
List<IConfigElement> numbersList = new ArrayList<IConfigElement>();
|
||||
Pattern commaDelimitedPattern = Pattern.compile("([A-Za-z]+((,){1}( )*|$))+?");
|
||||
|
||||
// Top Level Settings
|
||||
list.add(new DummyConfigElement<Boolean>("imABoolean", true, ConfigGuiType.BOOLEAN, "fml.config.sample.imABoolean").setRequiresMcRestart(true));
|
||||
list.add(new DummyConfigElement<Integer>("imAnInteger", 42, ConfigGuiType.INTEGER, "fml.config.sample.imAnInteger", -1, 256).setRequiresMcRestart(true));
|
||||
list.add(new DummyConfigElement<Double>("imADouble", 42.4242D, ConfigGuiType.DOUBLE, "fml.config.sample.imADouble", -1.0D, 256.256D).setRequiresMcRestart(true));
|
||||
list.add(new DummyConfigElement<String>("imAString", "http://www.montypython.net/scripts/string.php", ConfigGuiType.STRING, "fml.config.sample.imAString").setRequiresMcRestart(true));
|
||||
|
||||
// Lists category
|
||||
listsList.add(new DummyListElement<Boolean>("booleanList", new Boolean[] {true, false, true, false, true, false, true, false}, ConfigGuiType.BOOLEAN, "fml.config.sample.booleanList"));
|
||||
listsList.add(new DummyListElement<Boolean>("booleanListFixed", new Boolean[] {true, false, true, false, true, false, true, false}, ConfigGuiType.BOOLEAN, "fml.config.sample.booleanListFixed", true));
|
||||
listsList.add(new DummyListElement<Boolean>("booleanListMax", new Boolean[] {true, false, true, false, true, false, true, false}, ConfigGuiType.BOOLEAN, "fml.config.sample.booleanListMax", 10));
|
||||
listsList.add(new DummyListElement<Double>("doubleList", new Double[] {0.0D, 1.1D, 2.2D, 3.3D, 4.4D, 5.5D, 6.6D, 7.7D, 8.8D, 9.9D}, ConfigGuiType.DOUBLE, "fml.config.sample.doubleList"));
|
||||
listsList.add(new DummyListElement<Double>("doubleListFixed", new Double[] {0.0D, 1.1D, 2.2D, 3.3D, 4.4D, 5.5D, 6.6D, 7.7D, 8.8D, 9.9D}, ConfigGuiType.DOUBLE, "fml.config.sample.doubleListFixed", true));
|
||||
listsList.add(new DummyListElement<Double>("doubleListMax", new Double[] {0.0D, 1.1D, 2.2D, 3.3D, 4.4D, 5.5D, 6.6D, 7.7D, 8.8D, 9.9D}, ConfigGuiType.DOUBLE, "fml.config.sample.doubleListMax", 15));
|
||||
listsList.add(new DummyListElement<Double>("doubleListBounded", new Double[] {0.0D, 1.1D, 2.2D, 3.3D, 4.4D, 5.5D, 6.6D, 7.7D, 8.8D, 9.9D}, ConfigGuiType.DOUBLE, "fml.config.sample.doubleListBounded", -1.0D, 10.0D));
|
||||
listsList.add(new DummyListElement<Integer>("integerList", new Integer[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, ConfigGuiType.INTEGER, "fml.config.sample.integerList"));
|
||||
listsList.add(new DummyListElement<Integer>("integerListFixed", new Integer[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, ConfigGuiType.INTEGER, "fml.config.sample.integerListFixed", true));
|
||||
listsList.add(new DummyListElement<Integer>("integerListMax", new Integer[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, ConfigGuiType.INTEGER, "fml.config.sample.integerListMax", 15));
|
||||
listsList.add(new DummyListElement<Integer>("integerListBounded", new Integer[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, ConfigGuiType.INTEGER, "fml.config.sample.integerListBounded", -1, 10));
|
||||
listsList.add(new DummyListElement<String>("stringList", new String[] {"An", "array", "of", "string", "values"}, ConfigGuiType.STRING, "fml.config.sample.stringList"));
|
||||
listsList.add(new DummyListElement<String>("stringListFixed", new String[] {"A", "fixed", "length", "array", "of", "string", "values"}, ConfigGuiType.STRING, "fml.config.sample.stringListFixed", true));
|
||||
listsList.add(new DummyListElement<String>("stringListMax", new String[] {"An", "array", "of", "string", "values", "with", "a", "max", "length", "of", "15"}, ConfigGuiType.STRING, "fml.config.sample.stringListMax", 15));
|
||||
listsList.add(new DummyListElement<String>("stringListPattern", new String[] {"Valid", "Not Valid", "Is, Valid", "Comma, Separated, Value"}, ConfigGuiType.STRING, "fml.config.sample.stringListPattern", commaDelimitedPattern));
|
||||
|
||||
list.add(new DummyCategoryElement("lists", "fml.config.sample.ctgy.lists", listsList));
|
||||
|
||||
// Strings category
|
||||
stringsList.add(new DummyConfigElement<String>("basicString", "Just a regular String value, anything goes.", ConfigGuiType.STRING, "fml.config.sample.basicString"));
|
||||
stringsList.add(new DummyConfigElement<String>("cycleString", "this", ConfigGuiType.STRING, "fml.config.sample.cycleString", new String[] {"this", "property", "cycles", "through", "a", "list", "of", "valid", "choices"}));
|
||||
stringsList.add(new DummyConfigElement<String>("patternString", "only, comma, separated, words, can, be, entered, in, this, box", ConfigGuiType.STRING, "fml.config.sample.patternString", commaDelimitedPattern));
|
||||
stringsList.add(new DummyConfigElement<String>("chatColorPicker", "c", ConfigGuiType.COLOR, "fml.config.sample.chatColorPicker", new String[] {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}));
|
||||
stringsList.add(new DummyConfigElement<String>("modIDSelector", "FML", ConfigGuiType.MOD_ID, "fml.config.sample.modIDSelector"));
|
||||
|
||||
list.add(new DummyCategoryElement("strings", "fml.config.sample.ctgy.strings", stringsList));
|
||||
|
||||
// Numbers category
|
||||
numbersList.add((new DummyConfigElement<Integer>("basicInteger", 42, ConfigGuiType.INTEGER, "fml.config.sample.basicInteger")));
|
||||
numbersList.add((new DummyConfigElement<Integer>("boundedInteger", 42, ConfigGuiType.INTEGER, "fml.config.sample.boundedInteger", -1, 256)));
|
||||
numbersList.add(new DummyConfigElement<Double>("basicDouble", 42.4242D, ConfigGuiType.DOUBLE, "fml.config.sample.basicDouble"));
|
||||
numbersList.add(new DummyConfigElement<Double>("boundedDouble", 42.4242D, ConfigGuiType.DOUBLE, "fml.config.sample.boundedDouble", -1.0D, 256.256D));
|
||||
|
||||
@Override
|
||||
protected void actionPerformed(GuiButton p_73875_1_)
|
||||
{
|
||||
if (p_73875_1_.enabled && p_73875_1_.id == 1)
|
||||
{
|
||||
FMLClientHandler.instance().showGuiScreen(parent);
|
||||
}
|
||||
list.add(new DummyCategoryElement("numbers", "fml.config.sample.ctgy.numbers", numbersList));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawScreen(int p_73863_1_, int p_73863_2_, float p_73863_3_)
|
||||
{
|
||||
this.drawDefaultBackground();
|
||||
this.drawCenteredString(this.fontRendererObj, "Forge Mod Loader test config screen", this.width / 2, 40, 0xFFFFFF);
|
||||
super.drawScreen(p_73863_1_, p_73863_2_, p_73863_3_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private Minecraft minecraft;
|
||||
@Override
|
||||
public void initialize(Minecraft minecraftInstance)
|
||||
@@ -97,4 +135,4 @@ public class FMLConfigGuiFactory implements IModGuiFactory {
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Forge Mod Loader
|
||||
* Copyright (c) 2012-2014 cpw.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser Public License v2.1
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
* Contributors (this class):
|
||||
* bspkrs - implementation
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client.config;
|
||||
|
||||
public enum ConfigGuiType
|
||||
{
|
||||
STRING,
|
||||
INTEGER,
|
||||
BOOLEAN,
|
||||
DOUBLE,
|
||||
COLOR,
|
||||
MOD_ID,
|
||||
CONFIG_CATEGORY;
|
||||
}
|
||||
@@ -0,0 +1,418 @@
|
||||
/*
|
||||
* Forge Mod Loader
|
||||
* Copyright (c) 2012-2014 cpw.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser Public License v2.1
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
* Contributors (this class):
|
||||
* bspkrs - implementation
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import cpw.mods.fml.client.config.GuiConfigEntries.IConfigEntry;
|
||||
import cpw.mods.fml.client.config.GuiEditArrayEntries.IArrayEntry;
|
||||
|
||||
import net.minecraft.client.resources.I18n;
|
||||
|
||||
|
||||
/**
|
||||
* This class's main purpose is to provide the necessary objects for a sample Config GUI for FML, although
|
||||
* there may be practical uses for the objects defined here such as using the DummyCategoryElement object as a
|
||||
* wrapper for a custom IGuiConfigListEntry object that opens a special screen.
|
||||
*
|
||||
* @author bspkrs
|
||||
*/
|
||||
public class DummyConfigElement<T> implements IConfigElement<T>
|
||||
{
|
||||
protected boolean isProperty = true;
|
||||
protected boolean isList = false;
|
||||
protected ConfigGuiType type;
|
||||
protected String name;
|
||||
protected String langKey;
|
||||
protected Object value;
|
||||
protected Object defaultValue;
|
||||
protected T[] values;
|
||||
protected T[] defaultValues;
|
||||
protected String[] validValues;
|
||||
protected Pattern validStringPattern;
|
||||
protected T minValue;
|
||||
protected T maxValue;
|
||||
protected boolean requiresWorldRestart = false;
|
||||
protected boolean requiresMcRestart = false;
|
||||
protected boolean isListFixedLength = false;
|
||||
protected int maxListLength = -1;
|
||||
protected List<IConfigElement> childElements;
|
||||
protected Class<? extends IConfigEntry> configEntryClass;
|
||||
protected Class<? extends IArrayEntry> arrayEntryClass;
|
||||
|
||||
/**
|
||||
* This class provides a Dummy Category IConfigElement. It can be used to define a custom list of GUI entries that will
|
||||
* appear on the child screen or to specify a custom IGuiConfigListEntryfor a special category.
|
||||
*/
|
||||
public static class DummyCategoryElement<T> extends DummyConfigElement<T>
|
||||
{
|
||||
public DummyCategoryElement(String name, String langKey, List<IConfigElement> childElements)
|
||||
{
|
||||
this(name, langKey, childElements, (Class) null);
|
||||
}
|
||||
|
||||
public DummyCategoryElement(String name, String langKey, Class<? extends IConfigEntry> customListEntryClass)
|
||||
{
|
||||
this(name, langKey, new ArrayList<IConfigElement>(), customListEntryClass);
|
||||
}
|
||||
|
||||
public DummyCategoryElement(String name, String langKey, List<IConfigElement> childElements, Class<? extends IConfigEntry> customListEntryClass)
|
||||
{
|
||||
super(name, (T) null, ConfigGuiType.CONFIG_CATEGORY, langKey);
|
||||
this.childElements = childElements;
|
||||
this.configEntryClass = customListEntryClass;
|
||||
isProperty = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class provides a dummy array-type IConfigElement.
|
||||
*/
|
||||
public static class DummyListElement<T> extends DummyConfigElement<T>
|
||||
{
|
||||
public DummyListElement(String name, T[] defaultValues, ConfigGuiType type, String langKey, boolean isListFixedLength, int maxListLength, Pattern validStringPattern, T minValue, T maxValue)
|
||||
{
|
||||
super(name, (T) null, type, langKey, minValue, maxValue);
|
||||
this.defaultValues = defaultValues;
|
||||
this.values = defaultValues;
|
||||
this.isListFixedLength = isListFixedLength;
|
||||
this.maxListLength = maxListLength;
|
||||
this.validStringPattern = validStringPattern;
|
||||
isList = true;
|
||||
}
|
||||
|
||||
public DummyListElement(String name, T[] defaultValues, ConfigGuiType type, String langKey)
|
||||
{
|
||||
this(name, defaultValues, type, langKey, false, -1, (Pattern) null, (T) null, (T) null);
|
||||
}
|
||||
|
||||
public DummyListElement(String name, T[] defaultValues, ConfigGuiType type, String langKey, boolean isListFixedLength)
|
||||
{
|
||||
this(name, defaultValues, type, langKey, isListFixedLength, -1, (Pattern) null, (T) null, (T) null);
|
||||
}
|
||||
|
||||
public DummyListElement(String name, T[] defaultValues, ConfigGuiType type, String langKey, int maxListLength)
|
||||
{
|
||||
this(name, defaultValues, type, langKey, false, maxListLength, (Pattern) null, (T) null, (T) null);
|
||||
}
|
||||
|
||||
public DummyListElement(String name, T[] defaultValues, ConfigGuiType type, String langKey, T minValue, T maxValue)
|
||||
{
|
||||
this(name, defaultValues, type, langKey, false, -1, (Pattern) null, minValue, maxValue);
|
||||
}
|
||||
|
||||
public DummyListElement(String name, T[] defaultValues, ConfigGuiType type, String langKey, boolean isListFixedLength, T minValue, T maxValue)
|
||||
{
|
||||
this(name, defaultValues, type, langKey, isListFixedLength, -1, (Pattern) null, minValue, maxValue);
|
||||
}
|
||||
|
||||
public DummyListElement(String name, T[] defaultValues, ConfigGuiType type, String langKey, int maxListLength, T minValue, T maxValue)
|
||||
{
|
||||
this(name, defaultValues, type, langKey, false, maxListLength, (Pattern) null, minValue, maxValue);
|
||||
}
|
||||
|
||||
public DummyListElement(String name, T[] defaultValues, ConfigGuiType type, String langKey, boolean isListFixedLength, int maxListLength, T minValue, T maxValue)
|
||||
{
|
||||
this(name, defaultValues, type, langKey, isListFixedLength, maxListLength, (Pattern) null, minValue, maxValue);
|
||||
}
|
||||
|
||||
public DummyListElement(String name, T[] defaultValues, ConfigGuiType type, String langKey, Pattern validStringPattern)
|
||||
{
|
||||
this(name, defaultValues, type, langKey, false, -1, validStringPattern, (T) null, (T) null);
|
||||
}
|
||||
|
||||
public DummyListElement(String name, T[] defaultValues, ConfigGuiType type, String langKey, boolean isListFixedLength, Pattern validStringPattern)
|
||||
{
|
||||
this(name, defaultValues, type, langKey, isListFixedLength, -1, validStringPattern, (T) null, (T) null);
|
||||
}
|
||||
|
||||
public DummyListElement(String name, T[] defaultValues, ConfigGuiType type, String langKey, int maxListLength, Pattern validStringPattern)
|
||||
{
|
||||
this(name, defaultValues, type, langKey, false, maxListLength, validStringPattern, (T) null, (T) null);
|
||||
}
|
||||
|
||||
public DummyListElement setCustomEditListEntryClass(Class<? extends IArrayEntry> clazz)
|
||||
{
|
||||
this.arrayEntryClass = clazz;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDefault()
|
||||
{
|
||||
return Arrays.toString(this.defaultValues);
|
||||
}
|
||||
}
|
||||
|
||||
public DummyConfigElement(String name, T defaultValue, ConfigGuiType type, String langKey, String[] validValues, Pattern validStringPattern, T minValue, T maxValue)
|
||||
{
|
||||
this.name = name;
|
||||
this.defaultValue = defaultValue;
|
||||
this.value = defaultValue;
|
||||
this.type = type;
|
||||
this.langKey = langKey;
|
||||
this.validValues = validValues;
|
||||
this.validStringPattern = validStringPattern;
|
||||
if (minValue == null)
|
||||
{
|
||||
if (type == ConfigGuiType.INTEGER)
|
||||
this.minValue = (T) (Integer) Integer.MIN_VALUE;
|
||||
else if (type == ConfigGuiType.DOUBLE)
|
||||
this.minValue = (T) (Double) (-Double.MAX_VALUE);
|
||||
}
|
||||
else
|
||||
this.minValue = minValue;
|
||||
if (maxValue == null)
|
||||
{
|
||||
if (type == ConfigGuiType.INTEGER)
|
||||
this.maxValue = (T) (Integer) Integer.MAX_VALUE;
|
||||
else if (type == ConfigGuiType.DOUBLE)
|
||||
this.maxValue = (T) (Double) Double.MAX_VALUE;
|
||||
}
|
||||
else
|
||||
this.maxValue = maxValue;
|
||||
}
|
||||
|
||||
public DummyConfigElement(String name, T defaultValue, ConfigGuiType type, String langKey, Pattern validStringPattern)
|
||||
{
|
||||
this(name, defaultValue, type, langKey, (String[]) null, validStringPattern, (T) null, (T) null);
|
||||
}
|
||||
|
||||
public DummyConfigElement(String name, T defaultValue, ConfigGuiType type, String langKey, String[] validValues)
|
||||
{
|
||||
this(name, defaultValue, type, langKey, validValues, (Pattern) null, (T) null, (T) null);
|
||||
}
|
||||
|
||||
public DummyConfigElement(String name, T defaultValue, ConfigGuiType type, String langKey)
|
||||
{
|
||||
this(name, defaultValue, type, langKey, (String[]) null, (Pattern) null, (T) null, (T) null);
|
||||
}
|
||||
|
||||
public DummyConfigElement(String name, T defaultValue, ConfigGuiType type, String langKey, T minValue, T maxValue)
|
||||
{
|
||||
this(name, defaultValue, type, langKey, (String[]) null, (Pattern) null, minValue, maxValue);
|
||||
}
|
||||
|
||||
public DummyConfigElement setCustomListEntryClass(Class<? extends IConfigEntry> clazz)
|
||||
{
|
||||
this.configEntryClass = clazz;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProperty()
|
||||
{
|
||||
return isProperty;
|
||||
}
|
||||
|
||||
public IConfigElement setConfigEntryClass(Class<? extends IConfigEntry> clazz)
|
||||
{
|
||||
this.configEntryClass = clazz;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends IConfigEntry> getConfigEntryClass()
|
||||
{
|
||||
return configEntryClass;
|
||||
}
|
||||
|
||||
public IConfigElement setArrayEntryClass(Class<? extends IArrayEntry> clazz)
|
||||
{
|
||||
this.arrayEntryClass = clazz;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends IArrayEntry> getArrayEntryClass()
|
||||
{
|
||||
return arrayEntryClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQualifiedName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLanguageKey()
|
||||
{
|
||||
return langKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getComment()
|
||||
{
|
||||
return I18n.format(langKey + ".tooltip");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IConfigElement> getChildElements()
|
||||
{
|
||||
return childElements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigGuiType getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isList()
|
||||
{
|
||||
return isList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isListLengthFixed()
|
||||
{
|
||||
return this.isListFixedLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxListLength()
|
||||
{
|
||||
return this.maxListLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefault()
|
||||
{
|
||||
if (isProperty)
|
||||
{
|
||||
if (!isList)
|
||||
{
|
||||
if (value != null)
|
||||
return value.equals(defaultValue);
|
||||
else
|
||||
return defaultValue == null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Arrays.deepEquals(values, defaultValues);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDefault()
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T[] getDefaults()
|
||||
{
|
||||
return defaultValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setToDefault()
|
||||
{
|
||||
if (isList)
|
||||
this.values = Arrays.copyOf(this.defaultValues, this.defaultValues.length);
|
||||
else
|
||||
this.value = defaultValue;
|
||||
}
|
||||
|
||||
public IConfigElement<T> setRequiresWorldRestart(boolean requiresWorldRestart)
|
||||
{
|
||||
this.requiresWorldRestart = requiresWorldRestart;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresWorldRestart()
|
||||
{
|
||||
return requiresWorldRestart;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showInGui()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public IConfigElement<T> setRequiresMcRestart(boolean requiresMcRestart)
|
||||
{
|
||||
this.requiresMcRestart = this.requiresWorldRestart = requiresMcRestart;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresMcRestart()
|
||||
{
|
||||
return requiresMcRestart;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getValidValues()
|
||||
{
|
||||
return validValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pattern getValidationPattern()
|
||||
{
|
||||
return validStringPattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T[] getList()
|
||||
{
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(T value)
|
||||
{
|
||||
defaultValue = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(T[] aVal)
|
||||
{
|
||||
defaultValues = aVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getMinValue()
|
||||
{
|
||||
return minValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getMaxValue()
|
||||
{
|
||||
return maxValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Forge Mod Loader
|
||||
* Copyright (c) 2012-2014 cpw.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser Public License v2.1
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
* Contributors (this class):
|
||||
* bspkrs - implementation
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client.config;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
/**
|
||||
* This class provides a button that fixes several bugs present in the vanilla GuiButton drawing code.
|
||||
* The gist of it is that it allows buttons of any size without gaps in the graphics and with the
|
||||
* borders drawn properly. It also prevents button text from extending out of the sides of the button by
|
||||
* trimming the end of the string and adding an ellipsis.<br/><br/>
|
||||
*
|
||||
* The code that handles drawing the button is in GuiUtils.
|
||||
*
|
||||
* @author bspkrs
|
||||
*/
|
||||
public class GuiButtonExt extends GuiButton
|
||||
{
|
||||
public GuiButtonExt(int id, int xPos, int yPos, String displayString)
|
||||
{
|
||||
super(id, xPos, yPos, displayString);
|
||||
}
|
||||
|
||||
public GuiButtonExt(int id, int xPos, int yPos, int width, int height, String displayString)
|
||||
{
|
||||
super(id, xPos, yPos, width, height, displayString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws this button to the screen.
|
||||
*/
|
||||
@Override
|
||||
public void drawButton(Minecraft mc, int mouseX, int mouseY)
|
||||
{
|
||||
if (this.visible)
|
||||
{
|
||||
this.field_146123_n = mouseX >= this.xPosition && mouseY >= this.yPosition && mouseX < this.xPosition + this.width && mouseY < this.yPosition + this.height;
|
||||
int k = this.getHoverState(this.field_146123_n);
|
||||
GuiUtils.drawContinuousTexturedBox(buttonTextures, this.xPosition, this.yPosition, 0, 46 + k * 20, this.width, this.height, 200, 20, 2, 3, 2, 2, this.zLevel);
|
||||
this.mouseDragged(mc, mouseX, mouseY);
|
||||
int color = 14737632;
|
||||
|
||||
if (packedFGColour != 0)
|
||||
{
|
||||
color = packedFGColour;
|
||||
}
|
||||
else if (!this.enabled)
|
||||
{
|
||||
color = 10526880;
|
||||
}
|
||||
else if (this.field_146123_n)
|
||||
{
|
||||
color = 16777120;
|
||||
}
|
||||
|
||||
String buttonText = this.displayString;
|
||||
int strWidth = mc.fontRenderer.getStringWidth(buttonText);
|
||||
int ellipsisWidth = mc.fontRenderer.getStringWidth("...");
|
||||
|
||||
if (strWidth > width - 6 && strWidth > ellipsisWidth)
|
||||
buttonText = mc.fontRenderer.trimStringToWidth(buttonText, width - 6 - ellipsisWidth).trim() + "...";
|
||||
|
||||
this.drawCenteredString(mc.fontRenderer, buttonText, this.xPosition + this.width / 2, this.yPosition + (this.height - 8) / 2, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Forge Mod Loader
|
||||
* Copyright (c) 2012-2014 cpw.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser Public License v2.1
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
* Contributors (this class):
|
||||
* bspkrs - implementation
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client.config;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
|
||||
/**
|
||||
* This class provides a checkbox style control.
|
||||
*
|
||||
* @author bspkrs
|
||||
*/
|
||||
public class GuiCheckBox extends GuiButton
|
||||
{
|
||||
private boolean isChecked;
|
||||
private int boxWidth;
|
||||
|
||||
public GuiCheckBox(int id, int xPos, int yPos, String displayString, boolean isChecked)
|
||||
{
|
||||
super(id, xPos, yPos, displayString);
|
||||
this.isChecked = isChecked;
|
||||
this.boxWidth = 11;
|
||||
this.height = 11;
|
||||
this.width = this.boxWidth + 2 + Minecraft.getMinecraft().fontRenderer.getStringWidth(displayString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawButton(Minecraft mc, int mouseX, int mouseY)
|
||||
{
|
||||
if (this.visible)
|
||||
{
|
||||
this.field_146123_n = mouseX >= this.xPosition && mouseY >= this.yPosition && mouseX < this.xPosition + this.boxWidth && mouseY < this.yPosition + this.height;
|
||||
GuiUtils.drawContinuousTexturedBox(buttonTextures, this.xPosition, this.yPosition, 0, 46, this.boxWidth, this.height, 200, 20, 2, 3, 2, 2, this.zLevel);
|
||||
this.mouseDragged(mc, mouseX, mouseY);
|
||||
int color = 14737632;
|
||||
|
||||
if (packedFGColour != 0)
|
||||
{
|
||||
color = packedFGColour;
|
||||
}
|
||||
else if (!this.enabled)
|
||||
{
|
||||
color = 10526880;
|
||||
}
|
||||
|
||||
if (this.isChecked)
|
||||
this.drawCenteredString(mc.fontRenderer, "x", this.xPosition + this.boxWidth / 2 + 1, this.yPosition + 1, 14737632);
|
||||
|
||||
this.drawString(mc.fontRenderer, displayString, xPosition + this.boxWidth + 2, yPosition + 2, color);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mousePressed(Minecraft p_146116_1_, int p_146116_2_, int p_146116_3_)
|
||||
{
|
||||
if (this.enabled && this.visible && p_146116_2_ >= this.xPosition && p_146116_3_ >= this.yPosition && p_146116_2_ < this.xPosition + this.width && p_146116_3_ < this.yPosition + this.height)
|
||||
{
|
||||
this.isChecked = !this.isChecked;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isChecked()
|
||||
{
|
||||
return this.isChecked;
|
||||
}
|
||||
|
||||
public void setIsChecked(boolean isChecked)
|
||||
{
|
||||
this.isChecked = isChecked;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
/*
|
||||
* Forge Mod Loader
|
||||
* Copyright (c) 2012-2014 cpw.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser Public License v2.1
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
* Contributors (this class):
|
||||
* bspkrs - implementation
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client.config;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiMainMenu;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.gui.GuiYesNo;
|
||||
import net.minecraft.client.multiplayer.WorldClient;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.util.ChatComponentText;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
import static cpw.mods.fml.client.config.GuiUtils.RESET_CHAR;
|
||||
import static cpw.mods.fml.client.config.GuiUtils.UNDO_CHAR;
|
||||
|
||||
import cpw.mods.fml.client.config.GuiConfigEntries.IConfigEntry;
|
||||
import cpw.mods.fml.client.event.ConfigChangedEvent;
|
||||
import cpw.mods.fml.client.event.ConfigChangedEvent.OnConfigChangedEvent;
|
||||
import cpw.mods.fml.client.event.ConfigChangedEvent.PostConfigChangedEvent;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.eventhandler.Event.Result;
|
||||
|
||||
/**
|
||||
* This class is the base GuiScreen for all config GUI screens. It can be extended by mods to provide the top-level config screen
|
||||
* that will be called when the Config button is clicked from the Main Menu Mods list.
|
||||
*
|
||||
* @author bspkrs
|
||||
*/
|
||||
public class GuiConfig extends GuiScreen
|
||||
{
|
||||
/**
|
||||
* A reference to the screen object that created this. Used for navigating between screens.
|
||||
*/
|
||||
public final GuiScreen parentScreen;
|
||||
public String title = "Config GUI";
|
||||
public String titleLine2;
|
||||
public final List<IConfigElement> configElements;
|
||||
public final List<IConfigEntry> initEntries;
|
||||
public GuiConfigEntries entryList;
|
||||
private GuiButtonExt btnDefaultAll;
|
||||
private GuiButtonExt btnUndoAll;
|
||||
private GuiCheckBox chkApplyGlobally;
|
||||
public final String modID;
|
||||
/**
|
||||
* When set to a non-null value the OnConfigChanged and PostConfigChanged events will be posted when the Done button is pressed
|
||||
* if any configElements were changed (includes child screens). If not defined, the events will be posted if the parent gui is null
|
||||
* or if the parent gui is not an instance of GuiConfig.
|
||||
*/
|
||||
public final String configID;
|
||||
public final boolean isWorldRunning;
|
||||
public final boolean allRequireWorldRestart;
|
||||
public final boolean allRequireMcRestart;
|
||||
public boolean needsRefresh = true;
|
||||
private HoverChecker undoHoverChecker;
|
||||
private HoverChecker resetHoverChecker;
|
||||
private HoverChecker checkBoxHoverChecker;
|
||||
|
||||
/**
|
||||
* GuiConfig constructor that will use ConfigChangedEvent when editing is concluded. If a non-null value is passed for configID,
|
||||
* the OnConfigChanged and PostConfigChanged events will be posted when the Done button is pressed if any configElements were changed
|
||||
* (includes child screens). If configID is not defined, the events will be posted if the parent gui is null or if the parent gui
|
||||
* is not an instance of GuiConfig.
|
||||
*
|
||||
* @param parentScreen the parent GuiScreen object
|
||||
* @param configElements a List of IConfigProperty objects
|
||||
* @param areAllPropsHotLoadable send true if every property on this screen is able to be modified on the fly while a world is running
|
||||
* @param modID the mod ID for the mod whose config settings will be edited
|
||||
* @param configID an identifier that will be passed to the OnConfigChanged and PostConfigChanged events. Setting this value will force
|
||||
* the save action to be called when the Done button is pressed on this screen if any configElements were changed.
|
||||
* @param allRequireWorldRestart send true if all configElements on this screen require a world restart
|
||||
* @param title the desired title for this screen. For consistency it is recommended that you pass the path of the config file being
|
||||
* edited.
|
||||
*/
|
||||
public GuiConfig(GuiScreen parentScreen, List<IConfigElement> configElements, String modID, String configID,
|
||||
boolean allRequireWorldRestart, boolean allRequireMcRestart, String title)
|
||||
{
|
||||
this(parentScreen, configElements, modID, configID, allRequireWorldRestart, allRequireMcRestart, title, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* GuiConfig constructor that will use ConfigChangedEvent when editing is concluded. This constructor passes null for configID.
|
||||
* If configID is not defined, the events will be posted if the parent gui is null or if the parent gui is not an instance of GuiConfig.
|
||||
*
|
||||
* @param parentScreen the parent GuiScreen object
|
||||
* @param configElements a List of IConfigProperty objects
|
||||
* @param areAllPropsHotLoadable send true if every property on this screen is able to be modified on the fly while a world is running
|
||||
* @param modID the mod ID for the mod whose config settings will be edited
|
||||
* @param allRequireWorldRestart send true if all configElements on this screen require a world restart
|
||||
* @param title the desired title for this screen. For consistency it is recommended that you pass the path of the config file being
|
||||
* edited.
|
||||
*/
|
||||
public GuiConfig(GuiScreen parentScreen, List<IConfigElement> configElements, String modID,
|
||||
boolean allRequireWorldRestart, boolean allRequireMcRestart, String title)
|
||||
{
|
||||
this(parentScreen, configElements, modID, null, allRequireWorldRestart, allRequireMcRestart, title, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* GuiConfig constructor that will use ConfigChangedEvent when editing is concluded. This constructor passes null for configID.
|
||||
* If configID is not defined, the events will be posted if the parent gui is null or if the parent gui is not an instance of GuiConfig.
|
||||
*
|
||||
* @param parentScreen the parent GuiScreen object
|
||||
* @param configElements a List of IConfigProperty objects
|
||||
* @param modID the mod ID for the mod whose config settings will be edited
|
||||
* @param allRequireWorldRestart send true if all configElements on this screen require a world restart
|
||||
* @param title the desired title for this screen. For consistency it is recommended that you pass the path of the config file being
|
||||
* edited.
|
||||
* @param titleLine2 the desired title second line for this screen. Typically this is used to send the category name of the category
|
||||
* currently being edited.
|
||||
*/
|
||||
public GuiConfig(GuiScreen parentScreen, List<IConfigElement> configElements, String modID,
|
||||
boolean allRequireWorldRestart, boolean allRequireMcRestart, String title, String titleLine2)
|
||||
{
|
||||
this(parentScreen, configElements, modID, null, allRequireWorldRestart, allRequireMcRestart, title, titleLine2);
|
||||
}
|
||||
|
||||
/**
|
||||
* GuiConfig constructor that will use ConfigChangedEvent when editing is concluded. titleLine2 is specified in this constructor.
|
||||
* If a non-null value is passed for configID, the OnConfigChanged and PostConfigChanged events will be posted when the Done button is
|
||||
* pressed if any configElements were changed (includes child screens). If configID is not defined, the events will be posted if the parent
|
||||
* gui is null or if the parent gui is not an instance of GuiConfig.
|
||||
*
|
||||
* @param parentScreen the parent GuiScreen object
|
||||
* @param configElements a List of IConfigProperty objects
|
||||
* @param modID the mod ID for the mod whose config settings will be edited
|
||||
* @param configID an identifier that will be passed to the OnConfigChanged and PostConfigChanged events
|
||||
* @param allRequireWorldRestart send true if all configElements on this screen require a world restart
|
||||
* @param title the desired title for this screen. For consistency it is recommended that you pass the path of the config file being
|
||||
* edited.
|
||||
* @param titleLine2 the desired title second line for this screen. Typically this is used to send the category name of the category
|
||||
* currently being edited.
|
||||
*/
|
||||
public GuiConfig(GuiScreen parentScreen, List<IConfigElement> configElements, String modID, String configID,
|
||||
boolean allRequireWorldRestart, boolean allRequireMcRestart, String title, String titleLine2)
|
||||
{
|
||||
this.mc = Minecraft.getMinecraft();
|
||||
this.parentScreen = parentScreen;
|
||||
this.configElements = configElements;
|
||||
this.entryList = new GuiConfigEntries(this, mc);
|
||||
this.initEntries = new ArrayList<IConfigEntry>(entryList.listEntries);
|
||||
this.allRequireWorldRestart = allRequireWorldRestart;
|
||||
this.allRequireMcRestart = allRequireMcRestart;
|
||||
this.modID = modID;
|
||||
this.configID = configID;
|
||||
this.isWorldRunning = mc.theWorld != null;
|
||||
if (title != null)
|
||||
this.title = title;
|
||||
this.titleLine2 = titleLine2;
|
||||
if (this.titleLine2 != null && this.titleLine2.startsWith(" > "))
|
||||
this.titleLine2 = this.titleLine2.replaceFirst(" > ", "");
|
||||
}
|
||||
|
||||
public static String getAbridgedConfigPath(String path)
|
||||
{
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
if (mc.mcDataDir.getAbsolutePath().endsWith("."))
|
||||
return path.replace("\\", "/").replace(mc.mcDataDir.getAbsolutePath().replace("\\", "/").substring(0, mc.mcDataDir.getAbsolutePath().length() - 1), "/.minecraft/");
|
||||
else
|
||||
return path.replace("\\", "/").replace(mc.mcDataDir.getAbsolutePath().replace("\\", "/"), "/.minecraft");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui()
|
||||
{
|
||||
Keyboard.enableRepeatEvents(true);
|
||||
|
||||
if (this.entryList == null || this.needsRefresh)
|
||||
{
|
||||
this.entryList = new GuiConfigEntries(this, mc);
|
||||
this.needsRefresh = false;
|
||||
}
|
||||
|
||||
int undoGlyphWidth = mc.fontRenderer.getStringWidth(UNDO_CHAR) * 2;
|
||||
int resetGlyphWidth = mc.fontRenderer.getStringWidth(RESET_CHAR) * 2;
|
||||
int doneWidth = Math.max(mc.fontRenderer.getStringWidth(I18n.format("gui.done")) + 20, 100);
|
||||
int undoWidth = mc.fontRenderer.getStringWidth(" " + I18n.format("fml.configgui.tooltip.undoChanges")) + undoGlyphWidth + 20;
|
||||
int resetWidth = mc.fontRenderer.getStringWidth(" " + I18n.format("fml.configgui.tooltip.resetToDefault")) + resetGlyphWidth + 20;
|
||||
int checkWidth = mc.fontRenderer.getStringWidth(I18n.format("fml.configgui.applyGlobally")) + 13;
|
||||
int buttonWidthHalf = (doneWidth + 5 + undoWidth + 5 + resetWidth + 5 + checkWidth) / 2;
|
||||
this.buttonList.add(new GuiButtonExt(2000, this.width / 2 - buttonWidthHalf, this.height - 29, doneWidth, 20, I18n.format("gui.done")));
|
||||
this.buttonList.add(this.btnDefaultAll = new GuiUnicodeGlyphButton(2001, this.width / 2 - buttonWidthHalf + doneWidth + 5 + undoWidth + 5,
|
||||
this.height - 29, resetWidth, 20, " " + I18n.format("fml.configgui.tooltip.resetToDefault"), RESET_CHAR, 2.0F));
|
||||
this.buttonList.add(btnUndoAll = new GuiUnicodeGlyphButton(2002, this.width / 2 - buttonWidthHalf + doneWidth + 5,
|
||||
this.height - 29, undoWidth, 20, " " + I18n.format("fml.configgui.tooltip.undoChanges"), UNDO_CHAR, 2.0F));
|
||||
this.buttonList.add(chkApplyGlobally = new GuiCheckBox(2003, this.width / 2 - buttonWidthHalf + doneWidth + 5 + undoWidth + 5 + resetWidth + 5,
|
||||
this.height - 24, I18n.format("fml.configgui.applyGlobally"), false));
|
||||
|
||||
this.undoHoverChecker = new HoverChecker(this.btnUndoAll, 800);
|
||||
this.resetHoverChecker = new HoverChecker(this.btnDefaultAll, 800);
|
||||
this.checkBoxHoverChecker = new HoverChecker(chkApplyGlobally, 800);
|
||||
this.entryList.initGui();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuiClosed()
|
||||
{
|
||||
this.entryList.onGuiClosed();
|
||||
|
||||
if (this.configID != null && this.parentScreen instanceof GuiConfig)
|
||||
{
|
||||
GuiConfig parentGuiConfig = (GuiConfig) this.parentScreen;
|
||||
parentGuiConfig.needsRefresh = true;
|
||||
parentGuiConfig.initGui();
|
||||
}
|
||||
|
||||
if (!(this.parentScreen instanceof GuiConfig))
|
||||
Keyboard.enableRepeatEvents(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void actionPerformed(GuiButton button)
|
||||
{
|
||||
if (button.id == 2000)
|
||||
{
|
||||
boolean flag = true;
|
||||
try
|
||||
{
|
||||
if ((configID != null || this.parentScreen == null || !(this.parentScreen instanceof GuiConfig))
|
||||
&& (this.entryList.hasChangedEntry(true)))
|
||||
{
|
||||
boolean requiresMcRestart = this.entryList.saveConfigElements();
|
||||
|
||||
if (Loader.isModLoaded(modID))
|
||||
{
|
||||
ConfigChangedEvent event = new OnConfigChangedEvent(modID, configID, isWorldRunning, requiresMcRestart);
|
||||
FMLCommonHandler.instance().bus().post(event);
|
||||
if (!event.getResult().equals(Result.DENY))
|
||||
FMLCommonHandler.instance().bus().post(new PostConfigChangedEvent(modID, configID, isWorldRunning, requiresMcRestart));
|
||||
|
||||
if (requiresMcRestart)
|
||||
{
|
||||
flag = false;
|
||||
mc.displayGuiScreen(new GuiMessageDialog(parentScreen, "fml.configgui.gameRestartTitle",
|
||||
new ChatComponentText(I18n.format("fml.configgui.gameRestartRequired")), "fml.configgui.confirmRestartMessage"));
|
||||
}
|
||||
|
||||
if (this.parentScreen instanceof GuiConfig)
|
||||
((GuiConfig) this.parentScreen).needsRefresh = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (flag)
|
||||
this.mc.displayGuiScreen(this.parentScreen);
|
||||
}
|
||||
else if (button.id == 2001)
|
||||
{
|
||||
this.entryList.setAllToDefault(this.chkApplyGlobally.isChecked());
|
||||
}
|
||||
else if (button.id == 2002)
|
||||
{
|
||||
this.entryList.undoAllChanges(this.chkApplyGlobally.isChecked());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseClicked(int x, int y, int mouseEvent)
|
||||
{
|
||||
if (mouseEvent != 0 || !this.entryList.func_148179_a(x, y, mouseEvent))
|
||||
{
|
||||
this.entryList.mouseClicked(x, y, mouseEvent);
|
||||
super.mouseClicked(x, y, mouseEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseMovedOrUp(int x, int y, int mouseEvent)
|
||||
{
|
||||
if (mouseEvent != 0 || !this.entryList.func_148181_b(x, y, mouseEvent))
|
||||
{
|
||||
super.mouseMovedOrUp(x, y, mouseEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void keyTyped(char eventChar, int eventKey)
|
||||
{
|
||||
if (eventKey == Keyboard.KEY_ESCAPE)
|
||||
this.mc.displayGuiScreen(parentScreen);
|
||||
else
|
||||
this.entryList.keyTyped(eventChar, eventKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateScreen()
|
||||
{
|
||||
super.updateScreen();
|
||||
this.entryList.updateScreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawScreen(int mouseX, int mouseY, float partialTicks)
|
||||
{
|
||||
this.drawDefaultBackground();
|
||||
this.entryList.drawScreen(mouseX, mouseY, partialTicks);
|
||||
this.drawCenteredString(this.fontRendererObj, this.title, this.width / 2, 8, 16777215);
|
||||
String title2 = this.titleLine2;
|
||||
|
||||
if (title2 != null)
|
||||
{
|
||||
int strWidth = mc.fontRenderer.getStringWidth(title2);
|
||||
int elipsisWidth = mc.fontRenderer.getStringWidth("...");
|
||||
if (strWidth > width - 6 && strWidth > elipsisWidth)
|
||||
title2 = mc.fontRenderer.trimStringToWidth(title2, width - 6 - elipsisWidth).trim() + "...";
|
||||
this.drawCenteredString(this.fontRendererObj, title2, this.width / 2, 18, 16777215);
|
||||
}
|
||||
|
||||
this.btnUndoAll.enabled = this.entryList.areAnyEntriesEnabled(this.chkApplyGlobally.isChecked()) && this.entryList.hasChangedEntry(this.chkApplyGlobally.isChecked());
|
||||
this.btnDefaultAll.enabled = this.entryList.areAnyEntriesEnabled(this.chkApplyGlobally.isChecked()) && !this.entryList.areAllEntriesDefault(this.chkApplyGlobally.isChecked());
|
||||
super.drawScreen(mouseX, mouseY, partialTicks);
|
||||
this.entryList.drawScreenPost(mouseX, mouseY, partialTicks);
|
||||
if (this.undoHoverChecker.checkHover(mouseX, mouseY))
|
||||
this.drawToolTip(this.mc.fontRenderer.listFormattedStringToWidth(I18n.format("fml.configgui.tooltip.undoAll"), 300), mouseX, mouseY);
|
||||
if (this.resetHoverChecker.checkHover(mouseX, mouseY))
|
||||
this.drawToolTip(this.mc.fontRenderer.listFormattedStringToWidth(I18n.format("fml.configgui.tooltip.resetAll"), 300), mouseX, mouseY);
|
||||
if (this.checkBoxHoverChecker.checkHover(mouseX, mouseY))
|
||||
this.drawToolTip(this.mc.fontRenderer.listFormattedStringToWidth(I18n.format("fml.configgui.tooltip.applyGlobally"), 300), mouseX, mouseY);
|
||||
}
|
||||
|
||||
public void drawToolTip(List stringList, int x, int y)
|
||||
{
|
||||
this.func_146283_a(stringList, x, y);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Forge Mod Loader
|
||||
* Copyright (c) 2012-2014 cpw.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser Public License v2.1
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
* Contributors (this class):
|
||||
* bspkrs - implementation
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
|
||||
import static cpw.mods.fml.client.config.GuiUtils.RESET_CHAR;
|
||||
import static cpw.mods.fml.client.config.GuiUtils.UNDO_CHAR;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
/**
|
||||
* This class is the base screen used for editing an array-type property. It provides a list of array entries for the user to edit.
|
||||
* This screen is invoked from a GuiConfig screen by controls that use the EditListPropEntry IGuiConfigListEntry object.
|
||||
*
|
||||
* @author bspkrs
|
||||
*/
|
||||
public class GuiEditArray extends GuiScreen
|
||||
{
|
||||
protected GuiScreen parentScreen;
|
||||
protected IConfigElement configElement;
|
||||
private GuiEditArrayEntries entryList;
|
||||
private GuiButtonExt btnUndoChanges, btnDefault, btnDone;
|
||||
private String title;
|
||||
protected String titleLine2;
|
||||
protected String titleLine3;
|
||||
protected int slotIndex;
|
||||
private final Object[] beforeValues;
|
||||
private Object[] currentValues;
|
||||
private HoverChecker tooltipHoverChecker;
|
||||
private List toolTip;
|
||||
protected boolean enabled;
|
||||
|
||||
public GuiEditArray(GuiScreen parentScreen, IConfigElement configElement, int slotIndex, Object[] currentValues, boolean enabled)
|
||||
{
|
||||
this.mc = Minecraft.getMinecraft();
|
||||
this.parentScreen = parentScreen;
|
||||
this.configElement = configElement;
|
||||
this.slotIndex = slotIndex;
|
||||
this.beforeValues = currentValues;
|
||||
this.currentValues = currentValues;
|
||||
this.toolTip = new ArrayList();
|
||||
this.enabled = enabled;
|
||||
String propName = I18n.format(configElement.getLanguageKey());
|
||||
String comment;
|
||||
|
||||
comment = I18n.format(configElement.getLanguageKey() + ".tooltip",
|
||||
"\n" + EnumChatFormatting.AQUA, configElement.getDefault(), configElement.getMinValue(), configElement.getMaxValue());
|
||||
|
||||
if (!comment.equals(configElement.getLanguageKey() + ".tooltip"))
|
||||
toolTip = mc.fontRenderer.listFormattedStringToWidth(
|
||||
EnumChatFormatting.GREEN + propName + "\n" + EnumChatFormatting.YELLOW + comment, 300);
|
||||
else if (configElement.getComment() != null && !configElement.getComment().trim().isEmpty())
|
||||
toolTip = mc.fontRenderer.listFormattedStringToWidth(
|
||||
EnumChatFormatting.GREEN + propName + "\n" + EnumChatFormatting.YELLOW + configElement.getComment(), 300);
|
||||
else
|
||||
toolTip = mc.fontRenderer.listFormattedStringToWidth(
|
||||
EnumChatFormatting.GREEN + propName + "\n" + EnumChatFormatting.RED + "No tooltip defined.", 300);
|
||||
|
||||
if (parentScreen instanceof GuiConfig)
|
||||
{
|
||||
this.title = ((GuiConfig) parentScreen).title;
|
||||
if (((GuiConfig) parentScreen).titleLine2 != null)
|
||||
{
|
||||
this.titleLine2 = ((GuiConfig) parentScreen).titleLine2;
|
||||
this.titleLine3 = I18n.format(configElement.getLanguageKey());
|
||||
}
|
||||
else
|
||||
this.titleLine2 = I18n.format(configElement.getLanguageKey());
|
||||
this.tooltipHoverChecker = new HoverChecker(28, 37, 0, parentScreen.width, 800);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.title = I18n.format(configElement.getLanguageKey());
|
||||
this.tooltipHoverChecker = new HoverChecker(8, 17, 0, parentScreen.width, 800);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui()
|
||||
{
|
||||
this.entryList = new GuiEditArrayEntries(this, this.mc, this.configElement, this.beforeValues, this.currentValues);
|
||||
|
||||
int undoGlyphWidth = mc.fontRenderer.getStringWidth(UNDO_CHAR) * 2;
|
||||
int resetGlyphWidth = mc.fontRenderer.getStringWidth(RESET_CHAR) * 2;
|
||||
int doneWidth = Math.max(mc.fontRenderer.getStringWidth(I18n.format("gui.done")) + 20, 100);
|
||||
int undoWidth = mc.fontRenderer.getStringWidth(" " + I18n.format("fml.configgui.tooltip.undoChanges")) + undoGlyphWidth + 20;
|
||||
int resetWidth = mc.fontRenderer.getStringWidth(" " + I18n.format("fml.configgui.tooltip.resetToDefault")) + resetGlyphWidth + 20;
|
||||
int buttonWidthHalf = (doneWidth + 5 + undoWidth + 5 + resetWidth) / 2;
|
||||
this.buttonList.add(btnDone = new GuiButtonExt(2000, this.width / 2 - buttonWidthHalf, this.height - 29, doneWidth, 20, I18n.format("gui.done")));
|
||||
this.buttonList.add(btnDefault = new GuiUnicodeGlyphButton(2001, this.width / 2 - buttonWidthHalf + doneWidth + 5 + undoWidth + 5,
|
||||
this.height - 29, resetWidth, 20, " " + I18n.format("fml.configgui.tooltip.resetToDefault"), RESET_CHAR, 2.0F));
|
||||
this.buttonList.add(btnUndoChanges = new GuiUnicodeGlyphButton(2002, this.width / 2 - buttonWidthHalf + doneWidth + 5,
|
||||
this.height - 29, undoWidth, 20, " " + I18n.format("fml.configgui.tooltip.undoChanges"), UNDO_CHAR, 2.0F));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void actionPerformed(GuiButton button)
|
||||
{
|
||||
if (button.id == 2000)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.entryList.saveListChanges();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.mc.displayGuiScreen(this.parentScreen);
|
||||
}
|
||||
else if (button.id == 2001)
|
||||
{
|
||||
this.currentValues = (String[]) configElement.getDefaults();
|
||||
this.entryList = new GuiEditArrayEntries(this, this.mc, this.configElement, this.beforeValues, this.currentValues);
|
||||
}
|
||||
else if (button.id == 2002)
|
||||
{
|
||||
this.currentValues = Arrays.copyOf(beforeValues, beforeValues.length);
|
||||
this.entryList = new GuiEditArrayEntries(this, this.mc, this.configElement, this.beforeValues, this.currentValues);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseClicked(int x, int y, int mouseEvent)
|
||||
{
|
||||
if (mouseEvent != 0 || !this.entryList.func_148179_a(x, y, mouseEvent))
|
||||
{
|
||||
this.entryList.mouseClicked(x, y, mouseEvent);
|
||||
super.mouseClicked(x, y, mouseEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseMovedOrUp(int x, int y, int mouseEvent)
|
||||
{
|
||||
if (mouseEvent != 0 || !this.entryList.func_148181_b(x, y, mouseEvent))
|
||||
{
|
||||
super.mouseMovedOrUp(x, y, mouseEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void keyTyped(char eventChar, int eventKey)
|
||||
{
|
||||
if (eventKey == Keyboard.KEY_ESCAPE)
|
||||
this.mc.displayGuiScreen(parentScreen);
|
||||
else
|
||||
this.entryList.keyTyped(eventChar, eventKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateScreen()
|
||||
{
|
||||
super.updateScreen();
|
||||
this.entryList.updateScreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawScreen(int par1, int par2, float par3)
|
||||
{
|
||||
this.drawDefaultBackground();
|
||||
this.entryList.drawScreen(par1, par2, par3);
|
||||
this.drawCenteredString(this.fontRendererObj, this.title, this.width / 2, 8, 16777215);
|
||||
|
||||
if (this.titleLine2 != null)
|
||||
this.drawCenteredString(this.fontRendererObj, this.titleLine2, this.width / 2, 18, 16777215);
|
||||
|
||||
if (this.titleLine3 != null)
|
||||
this.drawCenteredString(this.fontRendererObj, this.titleLine3, this.width / 2, 28, 16777215);
|
||||
|
||||
this.btnDone.enabled = this.entryList.isListSavable();
|
||||
this.btnDefault.enabled = enabled && !this.entryList.isDefault();
|
||||
this.btnUndoChanges.enabled = enabled && this.entryList.isChanged();
|
||||
super.drawScreen(par1, par2, par3);
|
||||
this.entryList.drawScreenPost(par1, par2, par3);
|
||||
|
||||
if (this.tooltipHoverChecker != null && this.tooltipHoverChecker.checkHover(par1, par2))
|
||||
drawToolTip(this.toolTip, par1, par2);
|
||||
}
|
||||
|
||||
public void drawToolTip(List stringList, int x, int y)
|
||||
{
|
||||
this.func_146283_a(stringList, x, y);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,671 @@
|
||||
/*
|
||||
* Forge Mod Loader
|
||||
* Copyright (c) 2012-2014 cpw.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser Public License v2.1
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
* Contributors (this class):
|
||||
* bspkrs - implementation
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiListExtended;
|
||||
import net.minecraft.client.gui.GuiTextField;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
import static cpw.mods.fml.client.config.GuiUtils.INVALID;
|
||||
import static cpw.mods.fml.client.config.GuiUtils.VALID;
|
||||
|
||||
import cpw.mods.fml.client.config.GuiConfigEntries.ArrayEntry;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
|
||||
/**
|
||||
* This class implements the scrolling list functionality of the GuiEditList screen. It also provides all the default controls
|
||||
* for editing array-type properties.
|
||||
*
|
||||
* @author bspkrs
|
||||
*/
|
||||
public class GuiEditArrayEntries extends GuiListExtended
|
||||
{
|
||||
private GuiEditArray owningGui;
|
||||
public Minecraft mc;
|
||||
public IConfigElement configElement;
|
||||
public List<IArrayEntry> listEntries;
|
||||
public boolean isDefault;
|
||||
public boolean isChanged;
|
||||
public boolean canAddMoreEntries;
|
||||
public final int controlWidth;
|
||||
public final Object[] beforeValues;
|
||||
public Object[] currentValues;
|
||||
|
||||
public GuiEditArrayEntries(GuiEditArray parent, Minecraft mc, IConfigElement configElement, Object[] beforeValues, Object[] currentValues)
|
||||
{
|
||||
super(mc, parent.width, parent.height, parent.titleLine2 != null ? (parent.titleLine3 != null ? 43 : 33) : 23, parent.height - 32, 20);
|
||||
this.owningGui = parent;
|
||||
this.mc = mc;
|
||||
this.configElement = configElement;
|
||||
this.beforeValues = beforeValues;
|
||||
this.currentValues = currentValues;
|
||||
this.setShowSelectionBox(false);
|
||||
this.isChanged = !Arrays.deepEquals(beforeValues, currentValues);
|
||||
this.isDefault = Arrays.deepEquals(currentValues, configElement.getDefaults());
|
||||
this.canAddMoreEntries = !configElement.isListLengthFixed() && (configElement.getMaxListLength() == -1 || currentValues.length < configElement.getMaxListLength());
|
||||
|
||||
listEntries = new ArrayList<IArrayEntry>();
|
||||
|
||||
controlWidth = (parent.width / 2) - (configElement.isListLengthFixed() ? 0 : 48);
|
||||
|
||||
if (configElement.isList() && configElement.getArrayEntryClass() != null)
|
||||
{
|
||||
Class<? extends IArrayEntry> clazz = configElement.getArrayEntryClass();
|
||||
for (Object value : currentValues)
|
||||
{
|
||||
try
|
||||
{
|
||||
listEntries.add(clazz.getConstructor(GuiEditArray.class, GuiEditArrayEntries.class, IConfigElement.class, Object.class)
|
||||
.newInstance(this.owningGui, this, configElement, value.toString()));
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
FMLLog.severe("There was a critical error instantiating the custom IGuiEditListEntry for property %s.", configElement.getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (configElement.isList() && configElement.getType().equals(ConfigGuiType.BOOLEAN))
|
||||
for (Object value : currentValues)
|
||||
listEntries.add(new BooleanEntry(this.owningGui, this, configElement, Boolean.valueOf(value.toString())));
|
||||
else if (configElement.isList() && configElement.getType().equals(ConfigGuiType.INTEGER))
|
||||
for (Object value : currentValues)
|
||||
listEntries.add(new IntegerEntry(this.owningGui, this, configElement, Integer.parseInt(value.toString())));
|
||||
else if (configElement.isList() && configElement.getType().equals(ConfigGuiType.DOUBLE))
|
||||
for (Object value : currentValues)
|
||||
listEntries.add(new DoubleEntry(this.owningGui, this, configElement, Double.parseDouble(value.toString())));
|
||||
else if (configElement.isList())
|
||||
for (Object value : currentValues)
|
||||
listEntries.add(new StringEntry(this.owningGui, this, configElement, value.toString()));
|
||||
|
||||
if (!configElement.isListLengthFixed())
|
||||
listEntries.add(new BaseEntry(this.owningGui, this, configElement));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getScrollBarX()
|
||||
{
|
||||
return width - (width / 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the width of the list
|
||||
*/
|
||||
@Override
|
||||
public int getListWidth()
|
||||
{
|
||||
return owningGui.width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IArrayEntry getListEntry(int index)
|
||||
{
|
||||
return listEntries.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSize()
|
||||
{
|
||||
return listEntries.size();
|
||||
}
|
||||
|
||||
public void addNewEntry(int index)
|
||||
{
|
||||
if (configElement.isList() && configElement.getType() == ConfigGuiType.BOOLEAN)
|
||||
listEntries.add(index, new BooleanEntry(this.owningGui, this, this.configElement, Boolean.valueOf(true)));
|
||||
else if (configElement.isList() && configElement.getType() == ConfigGuiType.INTEGER)
|
||||
listEntries.add(index, new IntegerEntry(this.owningGui, this, this.configElement, 0));
|
||||
else if (configElement.isList() && configElement.getType() == ConfigGuiType.DOUBLE)
|
||||
listEntries.add(index, new DoubleEntry(this.owningGui, this, this.configElement, 0.0D));
|
||||
else if (configElement.isList())
|
||||
listEntries.add(index, new StringEntry(this.owningGui, this, this.configElement, ""));
|
||||
this.canAddMoreEntries = !configElement.isListLengthFixed()
|
||||
&& (configElement.getMaxListLength() == -1 || this.listEntries.size() - 1 < configElement.getMaxListLength());
|
||||
keyTyped((char) Keyboard.CHAR_NONE, Keyboard.KEY_END);
|
||||
}
|
||||
|
||||
public void removeEntry(int index)
|
||||
{
|
||||
this.listEntries.remove(index);
|
||||
this.canAddMoreEntries = !configElement.isListLengthFixed()
|
||||
&& (configElement.getMaxListLength() == -1 || this.listEntries.size() - 1 < configElement.getMaxListLength());
|
||||
keyTyped((char) Keyboard.CHAR_NONE, Keyboard.KEY_END);
|
||||
}
|
||||
|
||||
public boolean isChanged()
|
||||
{
|
||||
return isChanged;
|
||||
}
|
||||
|
||||
public boolean isDefault()
|
||||
{
|
||||
return isDefault;
|
||||
}
|
||||
|
||||
public void recalculateState()
|
||||
{
|
||||
isDefault = true;
|
||||
isChanged = false;
|
||||
|
||||
int listLength = configElement.isListLengthFixed() ? listEntries.size() : listEntries.size() - 1;
|
||||
|
||||
if (listLength != configElement.getDefaults().length)
|
||||
{
|
||||
isDefault = false;
|
||||
}
|
||||
|
||||
if (listLength != beforeValues.length)
|
||||
{
|
||||
isChanged = true;
|
||||
}
|
||||
|
||||
if (isDefault)
|
||||
for (int i = 0; i < listLength; i++)
|
||||
if (!configElement.getDefaults()[i].equals(listEntries.get(i).getValue()))
|
||||
isDefault = false;
|
||||
|
||||
if (!isChanged)
|
||||
for (int i = 0; i < listLength; i++)
|
||||
if (!beforeValues[i].equals(listEntries.get(i).getValue()))
|
||||
isChanged = true;
|
||||
}
|
||||
|
||||
protected void keyTyped(char eventChar, int eventKey)
|
||||
{
|
||||
for (IArrayEntry entry : this.listEntries)
|
||||
entry.keyTyped(eventChar, eventKey);
|
||||
|
||||
recalculateState();
|
||||
}
|
||||
|
||||
protected void updateScreen()
|
||||
{
|
||||
for (IArrayEntry entry : this.listEntries)
|
||||
entry.updateCursorCounter();
|
||||
}
|
||||
|
||||
protected void mouseClicked(int x, int y, int mouseEvent)
|
||||
{
|
||||
for (IArrayEntry entry : this.listEntries)
|
||||
entry.mouseClicked(x, y, mouseEvent);
|
||||
}
|
||||
|
||||
protected boolean isListSavable()
|
||||
{
|
||||
for (IArrayEntry entry : this.listEntries)
|
||||
if (!entry.isValueSavable())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void saveListChanges()
|
||||
{
|
||||
int listLength = configElement.isListLengthFixed() ? listEntries.size() : listEntries.size() - 1;
|
||||
|
||||
if (owningGui.slotIndex != -1 && owningGui.parentScreen != null
|
||||
&& owningGui.parentScreen instanceof GuiConfig
|
||||
&& ((GuiConfig) owningGui.parentScreen).entryList.getListEntry(owningGui.slotIndex) instanceof ArrayEntry)
|
||||
{
|
||||
ArrayEntry entry = (ArrayEntry) ((GuiConfig) owningGui.parentScreen).entryList.getListEntry(owningGui.slotIndex);
|
||||
|
||||
Object[] ao = new Object[listLength];
|
||||
for (int i = 0; i < listLength; i++)
|
||||
ao[i] = listEntries.get(i).getValue();
|
||||
|
||||
entry.setListFromChildScreen(ao);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (configElement.isList() && configElement.getType() == ConfigGuiType.BOOLEAN)
|
||||
{
|
||||
Boolean[] abol = new Boolean[listLength];
|
||||
for (int i = 0; i < listLength; i++)
|
||||
abol[i] = Boolean.valueOf(listEntries.get(i).getValue().toString());
|
||||
|
||||
configElement.set(abol);
|
||||
}
|
||||
else if (configElement.isList() && configElement.getType() == ConfigGuiType.INTEGER)
|
||||
{
|
||||
Integer[] ai = new Integer[listLength];
|
||||
for (int i = 0; i < listLength; i++)
|
||||
ai[i] = Integer.valueOf(listEntries.get(i).getValue().toString());
|
||||
|
||||
configElement.set(ai);
|
||||
}
|
||||
else if (configElement.isList() && configElement.getType() == ConfigGuiType.DOUBLE)
|
||||
{
|
||||
Double[] ad = new Double[listLength];
|
||||
for (int i = 0; i < listLength; i++)
|
||||
ad[i] = Double.valueOf(listEntries.get(i).getValue().toString());
|
||||
|
||||
configElement.set(ad);
|
||||
}
|
||||
else if (configElement.isList())
|
||||
{
|
||||
String[] as = new String[listLength];
|
||||
for (int i = 0; i < listLength; i++)
|
||||
as[i] = listEntries.get(i).getValue().toString();
|
||||
|
||||
configElement.set(as);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawScreenPost(int mouseX, int mouseY, float f)
|
||||
{
|
||||
for (IArrayEntry entry : this.listEntries)
|
||||
entry.drawToolTip(mouseX, mouseY);
|
||||
}
|
||||
|
||||
/**
|
||||
* IGuiListEntry Inner Classes
|
||||
*/
|
||||
|
||||
public static class DoubleEntry extends StringEntry
|
||||
{
|
||||
public DoubleEntry(GuiEditArray owningScreen, GuiEditArrayEntries owningEntryList, IConfigElement configElement, Double value)
|
||||
{
|
||||
super(owningScreen, owningEntryList, configElement, value);
|
||||
this.isValidated = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(char eventChar, int eventKey)
|
||||
{
|
||||
if (owningScreen.enabled || eventKey == Keyboard.KEY_LEFT || eventKey == Keyboard.KEY_RIGHT
|
||||
|| eventKey == Keyboard.KEY_HOME || eventKey == Keyboard.KEY_END)
|
||||
{
|
||||
String validChars = "0123456789";
|
||||
String before = this.textFieldValue.getText();
|
||||
if (validChars.contains(String.valueOf(eventChar)) ||
|
||||
(!before.startsWith("-") && this.textFieldValue.getCursorPosition() == 0 && eventChar == '-')
|
||||
|| (!before.contains(".") && eventChar == '.')
|
||||
|| eventKey == Keyboard.KEY_BACK || eventKey == Keyboard.KEY_DELETE || eventKey == Keyboard.KEY_LEFT || eventKey == Keyboard.KEY_RIGHT
|
||||
|| eventKey == Keyboard.KEY_HOME || eventKey == Keyboard.KEY_END)
|
||||
this.textFieldValue.textboxKeyTyped((owningScreen.enabled ? eventChar : Keyboard.CHAR_NONE), eventKey);
|
||||
|
||||
if (!textFieldValue.getText().trim().isEmpty() && !textFieldValue.getText().trim().equals("-"))
|
||||
{
|
||||
try
|
||||
{
|
||||
double value = Double.parseDouble(textFieldValue.getText().trim());
|
||||
if (value < Double.valueOf(configElement.getMinValue().toString()) || value > Double.valueOf(configElement.getMaxValue().toString()))
|
||||
this.isValidValue = false;
|
||||
else
|
||||
this.isValidValue = true;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
this.isValidValue = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
this.isValidValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getValue()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Double.valueOf(this.textFieldValue.getText().trim());
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
return Double.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class IntegerEntry extends StringEntry
|
||||
{
|
||||
public IntegerEntry(GuiEditArray owningScreen, GuiEditArrayEntries owningEntryList, IConfigElement configElement, Integer value)
|
||||
{
|
||||
super(owningScreen, owningEntryList, configElement, value);
|
||||
this.isValidated = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(char eventChar, int eventKey)
|
||||
{
|
||||
if (owningScreen.enabled || eventKey == Keyboard.KEY_LEFT || eventKey == Keyboard.KEY_RIGHT
|
||||
|| eventKey == Keyboard.KEY_HOME || eventKey == Keyboard.KEY_END)
|
||||
{
|
||||
String validChars = "0123456789";
|
||||
String before = this.textFieldValue.getText();
|
||||
if (validChars.contains(String.valueOf(eventChar))
|
||||
|| (!before.startsWith("-") && this.textFieldValue.getCursorPosition() == 0 && eventChar == '-')
|
||||
|| eventKey == Keyboard.KEY_BACK || eventKey == Keyboard.KEY_DELETE
|
||||
|| eventKey == Keyboard.KEY_LEFT || eventKey == Keyboard.KEY_RIGHT || eventKey == Keyboard.KEY_HOME || eventKey == Keyboard.KEY_END)
|
||||
this.textFieldValue.textboxKeyTyped((owningScreen.enabled ? eventChar : Keyboard.CHAR_NONE), eventKey);
|
||||
|
||||
if (!textFieldValue.getText().trim().isEmpty() && !textFieldValue.getText().trim().equals("-"))
|
||||
{
|
||||
try
|
||||
{
|
||||
long value = Long.parseLong(textFieldValue.getText().trim());
|
||||
if (value < Integer.valueOf(configElement.getMinValue().toString()) || value > Integer.valueOf(configElement.getMaxValue().toString()))
|
||||
this.isValidValue = false;
|
||||
else
|
||||
this.isValidValue = true;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
this.isValidValue = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
this.isValidValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getValue()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Integer.valueOf(this.textFieldValue.getText().trim());
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class StringEntry extends BaseEntry
|
||||
{
|
||||
protected final GuiTextField textFieldValue;
|
||||
|
||||
public StringEntry(GuiEditArray owningScreen, GuiEditArrayEntries owningEntryList, IConfigElement configElement, Object value)
|
||||
{
|
||||
super(owningScreen, owningEntryList, configElement);
|
||||
this.textFieldValue = new GuiTextField(owningEntryList.mc.fontRenderer, owningEntryList.width / 4 + 1, 0, owningEntryList.controlWidth - 3, 16);
|
||||
this.textFieldValue.setMaxStringLength(10000);
|
||||
this.textFieldValue.setText(value.toString());
|
||||
this.isValidated = configElement.getValidationPattern() != null;
|
||||
|
||||
if (configElement.getValidationPattern() != null)
|
||||
{
|
||||
if (configElement.getValidationPattern().matcher(this.textFieldValue.getText().trim()).matches())
|
||||
isValidValue = true;
|
||||
else
|
||||
isValidValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, Tessellator tessellator, int mouseX, int mouseY, boolean isSelected)
|
||||
{
|
||||
super.drawEntry(slotIndex, x, y, listWidth, slotHeight, tessellator, mouseX, mouseY, isSelected);
|
||||
if (configElement.isListLengthFixed() || slotIndex != owningEntryList.listEntries.size() - 1)
|
||||
{
|
||||
this.textFieldValue.setVisible(true);
|
||||
this.textFieldValue.yPosition = y + 1;
|
||||
this.textFieldValue.drawTextBox();
|
||||
}
|
||||
else
|
||||
this.textFieldValue.setVisible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(char eventChar, int eventKey)
|
||||
{
|
||||
if (owningScreen.enabled || eventKey == Keyboard.KEY_LEFT || eventKey == Keyboard.KEY_RIGHT
|
||||
|| eventKey == Keyboard.KEY_HOME || eventKey == Keyboard.KEY_END)
|
||||
{
|
||||
this.textFieldValue.textboxKeyTyped((owningScreen.enabled ? eventChar : Keyboard.CHAR_NONE), eventKey);
|
||||
|
||||
if (configElement.getValidationPattern() != null)
|
||||
{
|
||||
if (configElement.getValidationPattern().matcher(this.textFieldValue.getText().trim()).matches())
|
||||
isValidValue = true;
|
||||
else
|
||||
isValidValue = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCursorCounter()
|
||||
{
|
||||
this.textFieldValue.updateCursorCounter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(int x, int y, int mouseEvent)
|
||||
{
|
||||
this.textFieldValue.mouseClicked(x, y, mouseEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue()
|
||||
{
|
||||
return this.textFieldValue.getText().trim();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class BooleanEntry extends BaseEntry
|
||||
{
|
||||
protected final GuiButtonExt btnValue;
|
||||
private boolean value;
|
||||
|
||||
public BooleanEntry(GuiEditArray owningScreen, GuiEditArrayEntries owningEntryList, IConfigElement configElement, boolean value)
|
||||
{
|
||||
super(owningScreen, owningEntryList, configElement);
|
||||
this.value = value;
|
||||
this.btnValue = new GuiButtonExt(0, 0, 0, owningEntryList.controlWidth, 18, I18n.format(String.valueOf(value)));
|
||||
this.btnValue.enabled = owningScreen.enabled;
|
||||
this.isValidated = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, Tessellator tessellator, int mouseX, int mouseY, boolean isSelected)
|
||||
{
|
||||
super.drawEntry(slotIndex, x, y, listWidth, slotHeight, tessellator, mouseX, mouseY, isSelected);
|
||||
this.btnValue.xPosition = listWidth / 4;
|
||||
this.btnValue.yPosition = y;
|
||||
|
||||
String trans = I18n.format(String.valueOf(value));
|
||||
if (!trans.equals(String.valueOf(value)))
|
||||
this.btnValue.displayString = trans;
|
||||
else
|
||||
this.btnValue.displayString = String.valueOf(value);
|
||||
btnValue.packedFGColour = value ? GuiUtils.getColorCode('2', true) : GuiUtils.getColorCode('4', true);
|
||||
|
||||
this.btnValue.drawButton(owningEntryList.mc, mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mousePressed(int index, int x, int y, int mouseEvent, int relativeX, int relativeY)
|
||||
{
|
||||
if (this.btnValue.mousePressed(owningEntryList.mc, x, y))
|
||||
{
|
||||
btnValue.func_146113_a(owningEntryList.mc.getSoundHandler());
|
||||
value = !value;
|
||||
owningEntryList.recalculateState();
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.mousePressed(index, x, y, mouseEvent, relativeX, relativeY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(int index, int x, int y, int mouseEvent, int relativeX, int relativeY)
|
||||
{
|
||||
this.btnValue.mouseReleased(x, y);
|
||||
super.mouseReleased(index, x, y, mouseEvent, relativeX, relativeY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue()
|
||||
{
|
||||
return Boolean.valueOf(value);
|
||||
}
|
||||
}
|
||||
|
||||
public static class BaseEntry implements IArrayEntry
|
||||
{
|
||||
protected final GuiEditArray owningScreen;
|
||||
protected final GuiEditArrayEntries owningEntryList;
|
||||
protected final IConfigElement configElement;
|
||||
protected final GuiButtonExt btnAddNewEntryAbove;
|
||||
private final HoverChecker addNewEntryAboveHoverChecker;
|
||||
protected final GuiButtonExt btnRemoveEntry;
|
||||
private final HoverChecker removeEntryHoverChecker;
|
||||
private List addNewToolTip, removeToolTip;
|
||||
protected boolean isValidValue = true;
|
||||
protected boolean isValidated = false;
|
||||
|
||||
public BaseEntry(GuiEditArray owningScreen, GuiEditArrayEntries owningEntryList, IConfigElement configElement)
|
||||
{
|
||||
this.owningScreen = owningScreen;
|
||||
this.owningEntryList = owningEntryList;
|
||||
this.configElement = configElement;
|
||||
this.btnAddNewEntryAbove = new GuiButtonExt(0, 0, 0, 18, 18, "+");
|
||||
this.btnAddNewEntryAbove.packedFGColour = GuiUtils.getColorCode('2', true);
|
||||
this.btnAddNewEntryAbove.enabled = owningScreen.enabled;
|
||||
this.btnRemoveEntry = new GuiButtonExt(0, 0, 0, 18, 18, "x");
|
||||
this.btnRemoveEntry.packedFGColour = GuiUtils.getColorCode('c', true);
|
||||
this.btnRemoveEntry.enabled = owningScreen.enabled;
|
||||
this.addNewEntryAboveHoverChecker = new HoverChecker(this.btnAddNewEntryAbove, 800);
|
||||
this.removeEntryHoverChecker = new HoverChecker(this.btnRemoveEntry, 800);
|
||||
this.addNewToolTip = new ArrayList();
|
||||
this.removeToolTip = new ArrayList();
|
||||
addNewToolTip.add(I18n.format("fml.configgui.tooltip.addNewEntryAbove"));
|
||||
removeToolTip.add(I18n.format("fml.configgui.tooltip.removeEntry"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, Tessellator tessellator, int mouseX, int mouseY, boolean isSelected)
|
||||
{
|
||||
if (this.getValue() != null && this.isValidated)
|
||||
owningEntryList.mc.fontRenderer.drawString(
|
||||
isValidValue ? EnumChatFormatting.GREEN + VALID : EnumChatFormatting.RED + INVALID,
|
||||
listWidth / 4 - owningEntryList.mc.fontRenderer.getStringWidth(VALID) - 2,
|
||||
y + slotHeight / 2 - owningEntryList.mc.fontRenderer.FONT_HEIGHT / 2,
|
||||
16777215);
|
||||
|
||||
int half = listWidth / 2;
|
||||
if (owningEntryList.canAddMoreEntries)
|
||||
{
|
||||
this.btnAddNewEntryAbove.visible = true;
|
||||
this.btnAddNewEntryAbove.xPosition = half + ((half / 2) - 44);
|
||||
this.btnAddNewEntryAbove.yPosition = y;
|
||||
this.btnAddNewEntryAbove.drawButton(owningEntryList.mc, mouseX, mouseY);
|
||||
}
|
||||
else
|
||||
this.btnAddNewEntryAbove.visible = false;
|
||||
|
||||
if (!configElement.isListLengthFixed() && slotIndex != owningEntryList.listEntries.size() - 1)
|
||||
{
|
||||
this.btnRemoveEntry.visible = true;
|
||||
this.btnRemoveEntry.xPosition = half + ((half / 2) - 22);
|
||||
this.btnRemoveEntry.yPosition = y;
|
||||
this.btnRemoveEntry.drawButton(owningEntryList.mc, mouseX, mouseY);
|
||||
}
|
||||
else
|
||||
this.btnRemoveEntry.visible = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawToolTip(int mouseX, int mouseY)
|
||||
{
|
||||
boolean canHover = mouseY < owningEntryList.bottom && mouseY > owningEntryList.top;
|
||||
if (this.btnAddNewEntryAbove.visible && this.addNewEntryAboveHoverChecker.checkHover(mouseX, mouseY, canHover))
|
||||
owningScreen.drawToolTip(this.addNewToolTip, mouseX, mouseY);
|
||||
if (this.btnRemoveEntry.visible && this.removeEntryHoverChecker.checkHover(mouseX, mouseY, canHover))
|
||||
owningScreen.drawToolTip(this.removeToolTip, mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mousePressed(int index, int x, int y, int mouseEvent, int relativeX, int relativeY)
|
||||
{
|
||||
if (this.btnAddNewEntryAbove.mousePressed(owningEntryList.mc, x, y))
|
||||
{
|
||||
btnAddNewEntryAbove.func_146113_a(owningEntryList.mc.getSoundHandler());
|
||||
owningEntryList.addNewEntry(index);
|
||||
owningEntryList.recalculateState();
|
||||
return true;
|
||||
}
|
||||
else if (this.btnRemoveEntry.mousePressed(owningEntryList.mc, x, y))
|
||||
{
|
||||
btnRemoveEntry.func_146113_a(owningEntryList.mc.getSoundHandler());
|
||||
owningEntryList.removeEntry(index);
|
||||
owningEntryList.recalculateState();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(int index, int x, int y, int mouseEvent, int relativeX, int relativeY)
|
||||
{
|
||||
this.btnAddNewEntryAbove.mouseReleased(x, y);
|
||||
this.btnRemoveEntry.mouseReleased(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(char eventChar, int eventKey)
|
||||
{}
|
||||
|
||||
@Override
|
||||
public void updateCursorCounter()
|
||||
{}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(int x, int y, int mouseEvent)
|
||||
{}
|
||||
|
||||
@Override
|
||||
public boolean isValueSavable()
|
||||
{
|
||||
return isValidValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static interface IArrayEntry extends GuiListExtended.IGuiListEntry
|
||||
{
|
||||
public void keyTyped(char eventChar, int eventKey);
|
||||
|
||||
public void updateCursorCounter();
|
||||
|
||||
public void mouseClicked(int x, int y, int mouseEvent);
|
||||
|
||||
public void drawToolTip(int mouseX, int mouseY);
|
||||
|
||||
public boolean isValueSavable();
|
||||
|
||||
public Object getValue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package cpw.mods.fml.client.config;
|
||||
|
||||
import net.minecraft.client.gui.GuiDisconnected;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.util.IChatComponent;
|
||||
|
||||
public class GuiMessageDialog extends GuiDisconnected
|
||||
{
|
||||
private String buttonText;
|
||||
|
||||
public GuiMessageDialog(GuiScreen nextScreen, String title, IChatComponent message, String buttonText)
|
||||
{
|
||||
super(nextScreen, title, message);
|
||||
this.buttonText = buttonText;
|
||||
}
|
||||
|
||||
public void initGui()
|
||||
{
|
||||
super.initGui();
|
||||
((GuiButton) buttonList.get(0)).displayString = I18n.format(buttonText);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Forge Mod Loader
|
||||
* Copyright (c) 2012-2014 cpw.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser Public License v2.1
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
* Contributors (this class):
|
||||
* bspkrs - implementation
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
|
||||
import static cpw.mods.fml.client.config.GuiUtils.RESET_CHAR;
|
||||
import static cpw.mods.fml.client.config.GuiUtils.UNDO_CHAR;
|
||||
|
||||
/**
|
||||
* This class provides a screen that allows the user to select a value from a list.
|
||||
*
|
||||
* @author bspkrs
|
||||
*/
|
||||
public class GuiSelectString extends GuiScreen
|
||||
{
|
||||
protected GuiScreen parentScreen;
|
||||
protected IConfigElement configElement;
|
||||
private GuiSelectStringEntries entriesList;
|
||||
private GuiButtonExt btnUndoChanges, btnDefault, btnDone;
|
||||
private String title;
|
||||
protected String titleLine2;
|
||||
protected String titleLine3;
|
||||
protected int slotIndex;
|
||||
private final Map<Object, String> selectableValues;
|
||||
public final Object beforeValue;
|
||||
public Object currentValue;
|
||||
private HoverChecker tooltipHoverChecker;
|
||||
private List toolTip;
|
||||
protected boolean enabled;
|
||||
|
||||
public GuiSelectString(GuiScreen parentScreen, IConfigElement configElement, int slotIndex, Map<Object, String> selectableValues, Object currentValue, boolean enabled)
|
||||
{
|
||||
this.mc = Minecraft.getMinecraft();
|
||||
this.parentScreen = parentScreen;
|
||||
this.configElement = configElement;
|
||||
this.slotIndex = slotIndex;
|
||||
this.selectableValues = selectableValues;
|
||||
this.beforeValue = currentValue;
|
||||
this.currentValue = currentValue;
|
||||
this.toolTip = new ArrayList();
|
||||
this.enabled = enabled;
|
||||
String propName = I18n.format(configElement.getLanguageKey());
|
||||
String comment;
|
||||
|
||||
comment = I18n.format(configElement.getLanguageKey() + ".tooltip",
|
||||
"\n" + EnumChatFormatting.AQUA, configElement.getDefault(), configElement.getMinValue(), configElement.getMaxValue());
|
||||
|
||||
if (!comment.equals(configElement.getLanguageKey() + ".tooltip"))
|
||||
toolTip = mc.fontRenderer.listFormattedStringToWidth(
|
||||
EnumChatFormatting.GREEN + propName + "\n" + EnumChatFormatting.YELLOW + comment, 300);
|
||||
else if (configElement.getComment() != null && !configElement.getComment().trim().isEmpty())
|
||||
toolTip = mc.fontRenderer.listFormattedStringToWidth(
|
||||
EnumChatFormatting.GREEN + propName + "\n" + EnumChatFormatting.YELLOW + configElement.getComment(), 300);
|
||||
else
|
||||
toolTip = mc.fontRenderer.listFormattedStringToWidth(
|
||||
EnumChatFormatting.GREEN + propName + "\n" + EnumChatFormatting.RED + "No tooltip defined.", 300);
|
||||
|
||||
if (parentScreen instanceof GuiConfig)
|
||||
{
|
||||
this.title = ((GuiConfig) parentScreen).title;
|
||||
this.titleLine2 = ((GuiConfig) parentScreen).titleLine2;
|
||||
this.titleLine3 = I18n.format(configElement.getLanguageKey());
|
||||
this.tooltipHoverChecker = new HoverChecker(28, 37, 0, parentScreen.width, 800);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
this.title = I18n.format(configElement.getLanguageKey());
|
||||
this.tooltipHoverChecker = new HoverChecker(8, 17, 0, parentScreen.width, 800);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui()
|
||||
{
|
||||
this.entriesList = new GuiSelectStringEntries(this, this.mc, this.configElement, this.selectableValues);
|
||||
|
||||
int undoGlyphWidth = mc.fontRenderer.getStringWidth(UNDO_CHAR) * 2;
|
||||
int resetGlyphWidth = mc.fontRenderer.getStringWidth(RESET_CHAR) * 2;
|
||||
int doneWidth = Math.max(mc.fontRenderer.getStringWidth(I18n.format("gui.done")) + 20, 100);
|
||||
int undoWidth = mc.fontRenderer.getStringWidth(" " + I18n.format("fml.configgui.tooltip.undoChanges")) + undoGlyphWidth + 20;
|
||||
int resetWidth = mc.fontRenderer.getStringWidth(" " + I18n.format("fml.configgui.tooltip.resetToDefault")) + resetGlyphWidth + 20;
|
||||
int buttonWidthHalf = (doneWidth + 5 + undoWidth + 5 + resetWidth) / 2;
|
||||
this.buttonList.add(btnDone = new GuiButtonExt(2000, this.width / 2 - buttonWidthHalf, this.height - 29, doneWidth, 20, I18n.format("gui.done")));
|
||||
this.buttonList.add(btnDefault = new GuiUnicodeGlyphButton(2001, this.width / 2 - buttonWidthHalf + doneWidth + 5 + undoWidth + 5,
|
||||
this.height - 29, resetWidth, 20, " " + I18n.format("fml.configgui.tooltip.resetToDefault"), RESET_CHAR, 2.0F));
|
||||
this.buttonList.add(btnUndoChanges = new GuiUnicodeGlyphButton(2002, this.width / 2 - buttonWidthHalf + doneWidth + 5,
|
||||
this.height - 29, undoWidth, 20, " " + I18n.format("fml.configgui.tooltip.undoChanges"), UNDO_CHAR, 2.0F));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void actionPerformed(GuiButton button)
|
||||
{
|
||||
if (button.id == 2000)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.entriesList.saveChanges();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.mc.displayGuiScreen(this.parentScreen);
|
||||
}
|
||||
else if (button.id == 2001)
|
||||
{
|
||||
this.currentValue = configElement.getDefault();
|
||||
this.entriesList = new GuiSelectStringEntries(this, this.mc, this.configElement, this.selectableValues);
|
||||
}
|
||||
else if (button.id == 2002)
|
||||
{
|
||||
this.currentValue = beforeValue;
|
||||
this.entriesList = new GuiSelectStringEntries(this, this.mc, this.configElement, this.selectableValues);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseMovedOrUp(int x, int y, int mouseEvent)
|
||||
{
|
||||
if (mouseEvent != 0 || !this.entriesList.func_148181_b(x, y, mouseEvent))
|
||||
{
|
||||
super.mouseMovedOrUp(x, y, mouseEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawScreen(int par1, int par2, float par3)
|
||||
{
|
||||
this.drawDefaultBackground();
|
||||
this.entriesList.drawScreen(par1, par2, par3);
|
||||
this.drawCenteredString(this.fontRendererObj, this.title, this.width / 2, 8, 16777215);
|
||||
|
||||
if (this.titleLine2 != null)
|
||||
this.drawCenteredString(this.fontRendererObj, this.titleLine2, this.width / 2, 18, 16777215);
|
||||
|
||||
if (this.titleLine3 != null)
|
||||
this.drawCenteredString(this.fontRendererObj, this.titleLine3, this.width / 2, 28, 16777215);
|
||||
|
||||
this.btnDone.enabled = currentValue != null;
|
||||
this.btnDefault.enabled = enabled && !this.entriesList.isDefault();
|
||||
this.btnUndoChanges.enabled = enabled && this.entriesList.isChanged();
|
||||
super.drawScreen(par1, par2, par3);
|
||||
|
||||
if (this.tooltipHoverChecker != null && this.tooltipHoverChecker.checkHover(par1, par2))
|
||||
drawToolTip(this.toolTip, par1, par2);
|
||||
}
|
||||
|
||||
public void drawToolTip(List stringList, int x, int y)
|
||||
{
|
||||
this.func_146283_a(stringList, x, y);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Forge Mod Loader
|
||||
* Copyright (c) 2012-2014 cpw.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser Public License v2.1
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
* Contributors (this class):
|
||||
* bspkrs - implementation
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiListExtended;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import cpw.mods.fml.client.config.GuiConfigEntries.SelectValueEntry;
|
||||
|
||||
/**
|
||||
* This class implements the scrolling list functionality of the GuiSelectString screen.
|
||||
*
|
||||
* @author bspkrs
|
||||
*/
|
||||
public class GuiSelectStringEntries extends GuiListExtended
|
||||
{
|
||||
public GuiSelectString owningScreen;
|
||||
public Minecraft mc;
|
||||
public IConfigElement configElement;
|
||||
public List<IGuiSelectStringListEntry> listEntries;
|
||||
public final Map<Object, String> selectableValues;
|
||||
public int selectedIndex = -1;
|
||||
public int maxEntryWidth = 0;
|
||||
|
||||
public GuiSelectStringEntries(GuiSelectString owningScreen, Minecraft mc, IConfigElement configElement, Map<Object, String> selectableValues)
|
||||
{
|
||||
super(mc, owningScreen.width, owningScreen.height, owningScreen.titleLine2 != null ? (owningScreen.titleLine3 != null ? 43 : 33) : 23,
|
||||
owningScreen.height - 32, 11);
|
||||
this.owningScreen = owningScreen;
|
||||
this.mc = mc;
|
||||
this.configElement = configElement;
|
||||
this.selectableValues = selectableValues;
|
||||
this.setShowSelectionBox(true);
|
||||
|
||||
listEntries = new ArrayList<IGuiSelectStringListEntry>();
|
||||
|
||||
int index = 0;
|
||||
List<Entry<Object, String>> sortedList = new ArrayList<Entry<Object, String>>(selectableValues.entrySet());
|
||||
Collections.sort(sortedList, new EntryComparator());
|
||||
|
||||
for (Entry<Object, String> entry : sortedList)
|
||||
{
|
||||
listEntries.add(new ListEntry(this, entry));
|
||||
if (mc.fontRenderer.getStringWidth(entry.getValue()) > maxEntryWidth)
|
||||
maxEntryWidth = mc.fontRenderer.getStringWidth(entry.getValue());
|
||||
|
||||
if (owningScreen.currentValue.equals(entry.getKey()))
|
||||
{
|
||||
this.selectedIndex = index;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
public static class EntryComparator implements Comparator<Entry<Object, String>>
|
||||
{
|
||||
@Override
|
||||
public int compare(Entry<Object, String> o1, Entry<Object, String> o2)
|
||||
{
|
||||
int compare = o1.getValue().toLowerCase(Locale.US).compareTo(o2.getValue().toLowerCase(Locale.US));
|
||||
|
||||
if (compare == 0)
|
||||
compare = o1.getKey().toString().toLowerCase(Locale.US).compareTo(o2.getKey().toString().toLowerCase(Locale.US));
|
||||
|
||||
return compare;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The element in the slot that was clicked, boolean for whether it was double clicked or not
|
||||
*/
|
||||
@Override
|
||||
protected void elementClicked(int index, boolean doubleClick, int mouseX, int mouseY)
|
||||
{
|
||||
selectedIndex = index;
|
||||
owningScreen.currentValue = listEntries.get(index).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the element passed in is currently selected
|
||||
*/
|
||||
@Override
|
||||
protected boolean isSelected(int index)
|
||||
{
|
||||
return index == selectedIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getScrollBarX()
|
||||
{
|
||||
return width / 2 + this.maxEntryWidth / 2 + 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the width of the list
|
||||
*/
|
||||
@Override
|
||||
public int getListWidth()
|
||||
{
|
||||
return maxEntryWidth + 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IGuiSelectStringListEntry getListEntry(int index)
|
||||
{
|
||||
return listEntries.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSize()
|
||||
{
|
||||
return listEntries.size();
|
||||
}
|
||||
|
||||
public boolean isChanged()
|
||||
{
|
||||
return owningScreen.beforeValue != null ? !owningScreen.beforeValue.equals(owningScreen.currentValue) : owningScreen.currentValue != null;
|
||||
}
|
||||
|
||||
public boolean isDefault()
|
||||
{
|
||||
return owningScreen.currentValue != null ? owningScreen.currentValue.equals(configElement.getDefault()) : configElement.getDefault() == null;
|
||||
}
|
||||
|
||||
public void saveChanges()
|
||||
{
|
||||
if (owningScreen.slotIndex != -1 && owningScreen.parentScreen != null
|
||||
&& owningScreen.parentScreen instanceof GuiConfig
|
||||
&& ((GuiConfig) owningScreen.parentScreen).entryList.getListEntry(owningScreen.slotIndex) instanceof SelectValueEntry)
|
||||
{
|
||||
SelectValueEntry entry = (SelectValueEntry) ((GuiConfig) owningScreen.parentScreen).entryList.getListEntry(owningScreen.slotIndex);
|
||||
|
||||
entry.setValueFromChildScreen(owningScreen.currentValue);
|
||||
}
|
||||
else
|
||||
configElement.set(owningScreen.currentValue);
|
||||
}
|
||||
|
||||
public static class ListEntry implements IGuiSelectStringListEntry
|
||||
{
|
||||
protected final GuiSelectStringEntries owningList;
|
||||
protected final Entry<Object, String> value;
|
||||
|
||||
public ListEntry(GuiSelectStringEntries owningList, Entry<Object, String> value)
|
||||
{
|
||||
this.owningList = owningList;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, Tessellator tessellator, int mouseX, int mouseY, boolean isSelected)
|
||||
{
|
||||
owningList.mc.fontRenderer.drawString(value.getValue(), x + 1, y, slotIndex == owningList.selectedIndex ? 16777215 : 14737632);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mousePressed(int index, int x, int y, int mouseEvent, int relativeX, int relativeY)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(int index, int x, int y, int mouseEvent, int relativeX, int relativeY)
|
||||
{}
|
||||
|
||||
@Override
|
||||
public Object getValue()
|
||||
{
|
||||
return value.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
public static interface IGuiSelectStringListEntry extends GuiListExtended.IGuiListEntry
|
||||
{
|
||||
public Object getValue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Forge Mod Loader
|
||||
* Copyright (c) 2012-2014 cpw.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser Public License v2.1
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
* Contributors (this class):
|
||||
* bspkrs - implementation
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client.config;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
/**
|
||||
* This class provides a button that shows a string glyph at the beginning. The glyph can be scaled using the glyphScale parameter.
|
||||
*
|
||||
* @author bspkrs
|
||||
*/
|
||||
public class GuiUnicodeGlyphButton extends GuiButtonExt
|
||||
{
|
||||
public String glyph;
|
||||
public float glyphScale;
|
||||
|
||||
public GuiUnicodeGlyphButton(int id, int xPos, int yPos, int width, int height, String displayString, String glyph, float glyphScale)
|
||||
{
|
||||
super(id, xPos, yPos, width, height, displayString);
|
||||
this.glyph = glyph;
|
||||
this.glyphScale = glyphScale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawButton(Minecraft mc, int mouseX, int mouseY)
|
||||
{
|
||||
if (this.visible)
|
||||
{
|
||||
this.field_146123_n = mouseX >= this.xPosition && mouseY >= this.yPosition && mouseX < this.xPosition + this.width && mouseY < this.yPosition + this.height;
|
||||
int k = this.getHoverState(this.field_146123_n);
|
||||
GuiUtils.drawContinuousTexturedBox(buttonTextures, this.xPosition, this.yPosition, 0, 46 + k * 20, this.width, this.height, 200, 20, 2, 3, 2, 2, this.zLevel);
|
||||
this.mouseDragged(mc, mouseX, mouseY);
|
||||
int color = 14737632;
|
||||
|
||||
if (packedFGColour != 0)
|
||||
{
|
||||
color = packedFGColour;
|
||||
}
|
||||
else if (!this.enabled)
|
||||
{
|
||||
color = 10526880;
|
||||
}
|
||||
else if (this.field_146123_n)
|
||||
{
|
||||
color = 16777120;
|
||||
}
|
||||
|
||||
String buttonText = this.displayString;
|
||||
int glyphWidth = (int) (mc.fontRenderer.getStringWidth(glyph) * glyphScale);
|
||||
int strWidth = mc.fontRenderer.getStringWidth(buttonText);
|
||||
int elipsisWidth = mc.fontRenderer.getStringWidth("...");
|
||||
int totalWidth = strWidth + glyphWidth;
|
||||
|
||||
if (totalWidth > width - 6 && totalWidth > elipsisWidth)
|
||||
buttonText = mc.fontRenderer.trimStringToWidth(buttonText, width - 6 - elipsisWidth).trim() + "...";
|
||||
|
||||
strWidth = mc.fontRenderer.getStringWidth(buttonText);
|
||||
totalWidth = glyphWidth + strWidth;
|
||||
|
||||
GL11.glPushMatrix();
|
||||
GL11.glScalef(glyphScale, glyphScale, 1.0F);
|
||||
this.drawCenteredString(mc.fontRenderer, glyph,
|
||||
(int) (((this.xPosition + (this.width / 2) - (strWidth / 2)) / glyphScale) - (glyphWidth / (2 * glyphScale)) + 2),
|
||||
(int) (((this.yPosition + ((this.height - 8) / glyphScale) / 2) - 1) / glyphScale), color);
|
||||
GL11.glPopMatrix();
|
||||
|
||||
this.drawCenteredString(mc.fontRenderer, buttonText, (int) (this.xPosition + (this.width / 2) + (glyphWidth / glyphScale)),
|
||||
this.yPosition + (this.height - 8) / 2, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Forge Mod Loader
|
||||
* Copyright (c) 2012-2014 cpw.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser Public License v2.1
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
* Contributors (this class):
|
||||
* bspkrs - implementation
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client.config;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
/**
|
||||
* This class provides several methods and constants used by the Config GUI classes.
|
||||
*
|
||||
* @author bspkrs
|
||||
*/
|
||||
public class GuiUtils
|
||||
{
|
||||
public static final String UNDO_CHAR = "\u21B6";
|
||||
public static final String RESET_CHAR = "\u2604";
|
||||
public static final String VALID = "\u2714";
|
||||
public static final String INVALID = "\u2715";
|
||||
|
||||
private static int[] colorCodes = new int[] { 0, 170, 43520, 43690, 11141120, 11141290, 16755200, 11184810, 5592405, 5592575, 5635925, 5636095, 16733525, 16733695, 16777045, 16777215,
|
||||
0, 42, 10752, 10794, 2752512, 2752554, 2763264, 2763306, 1381653, 1381695, 1392405, 1392447, 4134165, 4134207, 4144917, 4144959 };
|
||||
|
||||
public static int getColorCode(char c, boolean isLighter)
|
||||
{
|
||||
return colorCodes[isLighter ? "0123456789abcdef".indexOf(c) : "0123456789abcdef".indexOf(c) + 16];
|
||||
}
|
||||
/**
|
||||
* Draws a textured box of any size (smallest size is borderSize * 2 square) based on a fixed size textured box with continuous borders
|
||||
* and filler. It is assumed that the desired texture ResourceLocation object has been bound using
|
||||
* Minecraft.getMinecraft().getTextureManager().bindTexture(resourceLocation).
|
||||
*
|
||||
* @param x x axis offset
|
||||
* @param y y axis offset
|
||||
* @param u bound resource location image x offset
|
||||
* @param v bound resource location image y offset
|
||||
* @param width the desired box width
|
||||
* @param height the desired box height
|
||||
* @param textureWidth the width of the box texture in the resource location image
|
||||
* @param textureHeight the height of the box texture in the resource location image
|
||||
* @param borderSize the size of the box's borders
|
||||
* @param zLevel the zLevel to draw at
|
||||
*/
|
||||
public static void drawContinuousTexturedBox(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight,
|
||||
int borderSize, float zLevel)
|
||||
{
|
||||
drawContinuousTexturedBox(x, y, u, v, width, height, textureWidth, textureHeight, borderSize, borderSize, borderSize, borderSize, zLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a textured box of any size (smallest size is borderSize * 2 square) based on a fixed size textured box with continuous borders
|
||||
* and filler. The provided ResourceLocation object will be bound using
|
||||
* Minecraft.getMinecraft().getTextureManager().bindTexture(resourceLocation).
|
||||
*
|
||||
* @param res the ResourceLocation object that contains the desired image
|
||||
* @param x x axis offset
|
||||
* @param y y axis offset
|
||||
* @param u bound resource location image x offset
|
||||
* @param v bound resource location image y offset
|
||||
* @param width the desired box width
|
||||
* @param height the desired box height
|
||||
* @param textureWidth the width of the box texture in the resource location image
|
||||
* @param textureHeight the height of the box texture in the resource location image
|
||||
* @param borderSize the size of the box's borders
|
||||
* @param zLevel the zLevel to draw at
|
||||
*/
|
||||
public static void drawContinuousTexturedBox(ResourceLocation res, int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight,
|
||||
int borderSize, float zLevel)
|
||||
{
|
||||
drawContinuousTexturedBox(res, x, y, u, v, width, height, textureWidth, textureHeight, borderSize, borderSize, borderSize, borderSize, zLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a textured box of any size (smallest size is borderSize * 2 square) based on a fixed size textured box with continuous borders
|
||||
* and filler. The provided ResourceLocation object will be bound using
|
||||
* Minecraft.getMinecraft().getTextureManager().bindTexture(resourceLocation).
|
||||
*
|
||||
* @param res the ResourceLocation object that contains the desired image
|
||||
* @param x x axis offset
|
||||
* @param y y axis offset
|
||||
* @param u bound resource location image x offset
|
||||
* @param v bound resource location image y offset
|
||||
* @param width the desired box width
|
||||
* @param height the desired box height
|
||||
* @param textureWidth the width of the box texture in the resource location image
|
||||
* @param textureHeight the height of the box texture in the resource location image
|
||||
* @param topBorder the size of the box's top border
|
||||
* @param bottomBorder the size of the box's bottom border
|
||||
* @param leftBorder the size of the box's left border
|
||||
* @param rightBorder the size of the box's right border
|
||||
* @param zLevel the zLevel to draw at
|
||||
*/
|
||||
public static void drawContinuousTexturedBox(ResourceLocation res, int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight,
|
||||
int topBorder, int bottomBorder, int leftBorder, int rightBorder, float zLevel)
|
||||
{
|
||||
Minecraft.getMinecraft().getTextureManager().bindTexture(res);
|
||||
drawContinuousTexturedBox(x, y, u, v, width, height, textureWidth, textureHeight, topBorder, bottomBorder, leftBorder, rightBorder, zLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a textured box of any size (smallest size is borderSize * 2 square) based on a fixed size textured box with continuous borders
|
||||
* and filler. It is assumed that the desired texture ResourceLocation object has been bound using
|
||||
* Minecraft.getMinecraft().getTextureManager().bindTexture(resourceLocation).
|
||||
*
|
||||
* @param x x axis offset
|
||||
* @param y y axis offset
|
||||
* @param u bound resource location image x offset
|
||||
* @param v bound resource location image y offset
|
||||
* @param width the desired box width
|
||||
* @param height the desired box height
|
||||
* @param textureWidth the width of the box texture in the resource location image
|
||||
* @param textureHeight the height of the box texture in the resource location image
|
||||
* @param topBorder the size of the box's top border
|
||||
* @param bottomBorder the size of the box's bottom border
|
||||
* @param leftBorder the size of the box's left border
|
||||
* @param rightBorder the size of the box's right border
|
||||
* @param zLevel the zLevel to draw at
|
||||
*/
|
||||
public static void drawContinuousTexturedBox(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight,
|
||||
int topBorder, int bottomBorder, int leftBorder, int rightBorder, float zLevel)
|
||||
{
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
OpenGlHelper.glBlendFunc(770, 771, 1, 0);
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
int fillerWidth = textureWidth - leftBorder - rightBorder;
|
||||
int fillerHeight = textureHeight - topBorder - bottomBorder;
|
||||
int canvasWidth = width - leftBorder - rightBorder;
|
||||
int canvasHeight = height - topBorder - bottomBorder;
|
||||
int xPasses = canvasWidth / fillerWidth;
|
||||
int remainderWidth = canvasWidth % fillerWidth;
|
||||
int yPasses = canvasHeight / fillerHeight;
|
||||
int remainderHeight = canvasHeight % fillerHeight;
|
||||
|
||||
// Draw Border
|
||||
// Top Left
|
||||
drawTexturedModalRect(x, y, u, v, leftBorder, topBorder, zLevel);
|
||||
// Top Right
|
||||
drawTexturedModalRect(x + leftBorder + canvasWidth, y, u + leftBorder + fillerWidth, v, rightBorder, topBorder, zLevel);
|
||||
// Bottom Left
|
||||
drawTexturedModalRect(x, y + topBorder + canvasHeight, u, v + topBorder + fillerHeight, leftBorder, bottomBorder, zLevel);
|
||||
// Bottom Right
|
||||
drawTexturedModalRect(x + leftBorder + canvasWidth, y + topBorder + canvasHeight, u + leftBorder + fillerWidth, v + topBorder + fillerHeight, rightBorder, bottomBorder, zLevel);
|
||||
|
||||
for (int i = 0; i < xPasses + (remainderWidth > 0 ? 1 : 0); i++)
|
||||
{
|
||||
// Top Border
|
||||
drawTexturedModalRect(x + leftBorder + (i * fillerWidth), y, u + leftBorder, v, (i == xPasses ? remainderWidth : fillerWidth), topBorder, zLevel);
|
||||
// Bottom Border
|
||||
drawTexturedModalRect(x + leftBorder + (i * fillerWidth), y + topBorder + canvasHeight, u + leftBorder, v + topBorder + fillerHeight, (i == xPasses ? remainderWidth : fillerWidth), bottomBorder, zLevel);
|
||||
|
||||
// Throw in some filler for good measure
|
||||
for (int j = 0; j < yPasses + (remainderHeight > 0 ? 1 : 0); j++)
|
||||
drawTexturedModalRect(x + leftBorder + (i * fillerWidth), y + topBorder + (j * fillerHeight), u + leftBorder, v + topBorder, (i == xPasses ? remainderWidth : fillerWidth), (j == yPasses ? remainderHeight : fillerHeight), zLevel);
|
||||
}
|
||||
|
||||
// Side Borders
|
||||
for (int j = 0; j < yPasses + (remainderHeight > 0 ? 1 : 0); j++)
|
||||
{
|
||||
// Left Border
|
||||
drawTexturedModalRect(x, y + topBorder + (j * fillerHeight), u, v + topBorder, leftBorder, (j == yPasses ? remainderHeight : fillerHeight), zLevel);
|
||||
// Right Border
|
||||
drawTexturedModalRect(x + leftBorder + canvasWidth, y + topBorder + (j * fillerHeight), u + leftBorder + fillerWidth, v + topBorder, rightBorder, (j == yPasses ? remainderHeight : fillerHeight), zLevel);
|
||||
}
|
||||
}
|
||||
|
||||
public static void drawTexturedModalRect(int x, int y, int u, int v, int width, int height, float zLevel)
|
||||
{
|
||||
float var7 = 0.00390625F;
|
||||
float var8 = 0.00390625F;
|
||||
Tessellator tessellator = Tessellator.instance;
|
||||
tessellator.startDrawingQuads();
|
||||
tessellator.addVertexWithUV((x + 0), (y + height), zLevel, ((u + 0) * var7), ((v + height) * var8));
|
||||
tessellator.addVertexWithUV((x + width), (y + height), zLevel, ((u + width) * var7), ((v + height) * var8));
|
||||
tessellator.addVertexWithUV((x + width), (y + 0), zLevel, ((u + width) * var7), ((v + 0) * var8));
|
||||
tessellator.addVertexWithUV((x + 0), (y + 0), zLevel, ((u + 0) * var7), ((v + 0) * var8));
|
||||
tessellator.draw();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Forge Mod Loader
|
||||
* Copyright (c) 2012-2014 cpw.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser Public License v2.1
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
* Contributors (this class):
|
||||
* bspkrs - implementation
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client.config;
|
||||
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
|
||||
/**
|
||||
* This class implements an easy way to check if the mouse has hovered within a certain region of the screen for a given
|
||||
* period of time. The region can be defined manually or by supplying a GuiButton object.
|
||||
*
|
||||
* @author bspkrs
|
||||
*/
|
||||
public class HoverChecker
|
||||
{
|
||||
private int top, bottom, left, right, threshold;
|
||||
private GuiButton button;
|
||||
private long hoverStart;
|
||||
|
||||
public HoverChecker(int top, int bottom, int left, int right, int threshold)
|
||||
{
|
||||
this.top = top;
|
||||
this.bottom = bottom;
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
this.threshold = threshold;
|
||||
this.hoverStart = -1;
|
||||
}
|
||||
|
||||
public HoverChecker(GuiButton button, int threshold)
|
||||
{
|
||||
this.button = button;
|
||||
this.threshold = threshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this method if the intended region has changed such as if the region must follow a scrolling list.
|
||||
* It is not necessary to call this method if a GuiButton defines the hover region.
|
||||
*/
|
||||
public void updateBounds(int top, int bottom, int left, int right)
|
||||
{
|
||||
this.top = top;
|
||||
this.bottom = bottom;
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the mouse is in the hover region. If the specified time period has elapsed the method returns true.
|
||||
* The hover timer is reset if the mouse is not within the region.
|
||||
*/
|
||||
public boolean checkHover(int mouseX, int mouseY)
|
||||
{
|
||||
return checkHover(mouseX, mouseY, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the mouse is in the hover region. If the specified time period has elapsed the method returns true.
|
||||
* The hover timer is reset if the mouse is not within the region.
|
||||
*/
|
||||
public boolean checkHover(int mouseX, int mouseY, boolean canHover)
|
||||
{
|
||||
if (this.button != null)
|
||||
{
|
||||
this.top = button.yPosition;
|
||||
this.bottom = button.yPosition + button.height;
|
||||
this.left = button.xPosition;
|
||||
this.right = button.xPosition + button.width;
|
||||
canHover = canHover && button.visible;
|
||||
}
|
||||
|
||||
if (canHover && hoverStart == -1 && mouseY >= top && mouseY <= bottom && mouseX >= left && mouseX <= right)
|
||||
hoverStart = System.currentTimeMillis();
|
||||
else if (!canHover || mouseY < top || mouseY > bottom || mouseX < left || mouseX > right)
|
||||
resetHoverTimer();
|
||||
|
||||
return canHover && hoverStart != -1 && System.currentTimeMillis() - hoverStart >= threshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually resets the hover timer.
|
||||
*/
|
||||
public void resetHoverTimer()
|
||||
{
|
||||
hoverStart = -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Forge Mod Loader
|
||||
* Copyright (c) 2012-2014 cpw.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser Public License v2.1
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
* Contributors (this class):
|
||||
* bspkrs - implementation
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client.config;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import cpw.mods.fml.client.config.GuiConfigEntries.IConfigEntry;
|
||||
import cpw.mods.fml.client.config.GuiEditArrayEntries.IArrayEntry;
|
||||
|
||||
/**
|
||||
* This interface provides the information needed by GuiConfig and GuiConfigEntries to display config elements for editing.
|
||||
*
|
||||
* @author bspkrs
|
||||
*/
|
||||
public interface IConfigElement<T>
|
||||
{
|
||||
/**
|
||||
* [Property, Category] Is this object a property object?
|
||||
*/
|
||||
public boolean isProperty();
|
||||
|
||||
/**
|
||||
* This method returns a class that implements {@code IConfigEntry} or null. This class MUST
|
||||
* provide a constructor with the following parameter types: {@code GuiConfig}, {@code GuiConfigEntries}, {@code IConfigElement}
|
||||
*/
|
||||
public Class<? extends IConfigEntry> getConfigEntryClass();
|
||||
|
||||
/**
|
||||
* This method returns a class that implements {@code IArrayEntry}. This class MUST provide a constructor with the
|
||||
* following parameter types: {@code GuiEditArray}, {@code GuiEditArrayEntries}, {@code IConfigElement}, {@code Object}
|
||||
*/
|
||||
public Class<? extends IArrayEntry> getArrayEntryClass();
|
||||
|
||||
/**
|
||||
* [Property, Category] Gets the name of this object.
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
/**
|
||||
* [Category] Gets the qualified name of this object. This is typically only used for category objects.
|
||||
*/
|
||||
public String getQualifiedName();
|
||||
|
||||
/**
|
||||
* [Property, Category] Gets a language key for localization of config GUI entry names. If the same key is specified with .tooltip
|
||||
* appended to the end, that key will return a localized tooltip when the mouse hovers over the property label/category button.
|
||||
*/
|
||||
public String getLanguageKey();
|
||||
|
||||
/**
|
||||
* [Property, Category] Gets the comment for this object. Used for the tooltip if getLanguageKey() + ".tooltip" is not defined in the
|
||||
* .lang file.
|
||||
*/
|
||||
public String getComment();
|
||||
|
||||
/**
|
||||
* [Category] Gets this category's child categories/properties.
|
||||
*/
|
||||
public List<IConfigElement> getChildElements();
|
||||
|
||||
/**
|
||||
* [Property, Category] Gets the ConfigGuiType value corresponding to the type of this property object, or CONFIG_CATEGORY if this is a
|
||||
* category object.
|
||||
*/
|
||||
public ConfigGuiType getType();
|
||||
|
||||
/**
|
||||
* [Property] Is this property object a list?
|
||||
*/
|
||||
public boolean isList();
|
||||
|
||||
/**
|
||||
* [Property] Does this list property have to remain a fixed length?
|
||||
*/
|
||||
public boolean isListLengthFixed();
|
||||
|
||||
/**
|
||||
* [Property] Gets the max length of this list property, or -1 if the length is unlimited.
|
||||
*/
|
||||
public int getMaxListLength();
|
||||
|
||||
/**
|
||||
* [Property] Is this property value equal to the default value?
|
||||
*/
|
||||
public boolean isDefault();
|
||||
|
||||
/**
|
||||
* [Property] Gets this property's default value. If this element is an array, this method should return a String
|
||||
* representation of that array using Arrays.toString()
|
||||
*/
|
||||
public Object getDefault();
|
||||
|
||||
/**
|
||||
* [Property] Gets this property's default values.
|
||||
*/
|
||||
public Object[] getDefaults();
|
||||
|
||||
/**
|
||||
* [Property] Sets this property's value to the default value.
|
||||
*/
|
||||
public void setToDefault();
|
||||
|
||||
/**
|
||||
* [Property, Category] Whether or not this element is safe to modify while a world is running. For Categories return false if ANY properties
|
||||
* in the category are modifiable while a world is running, true if all are not.
|
||||
*/
|
||||
public boolean requiresWorldRestart();
|
||||
|
||||
/**
|
||||
* [Property, Category] Whether or not this element should be allowed to show on config GUIs.
|
||||
*/
|
||||
public boolean showInGui();
|
||||
|
||||
/**
|
||||
* [Property, Category] Whether or not this element requires Minecraft to be restarted when changed.
|
||||
*/
|
||||
public boolean requiresMcRestart();
|
||||
|
||||
/**
|
||||
* [Property] Gets this property value.
|
||||
*/
|
||||
public Object get();
|
||||
|
||||
/**
|
||||
* [Property] Gets this property value as a list. Generally you should be sure of whether the property is a list before calling this.
|
||||
*/
|
||||
public Object[] getList();
|
||||
|
||||
/**
|
||||
* [Property] Sets this property's value.
|
||||
*/
|
||||
public void set(T value);
|
||||
|
||||
/**
|
||||
* [Property] Sets this property's value to the specified array.
|
||||
*/
|
||||
public void set(T[] aVal);
|
||||
|
||||
/**
|
||||
* [Property] Gets a String array of valid values for this property. This is generally used for String properties to allow the user to
|
||||
* select a value from a list of valid values.
|
||||
*/
|
||||
public String[] getValidValues();
|
||||
|
||||
/**
|
||||
* [Property] Gets this property's minimum value.
|
||||
*/
|
||||
public T getMinValue();
|
||||
|
||||
/**
|
||||
* [Property] Gets this property's maximum value.
|
||||
*/
|
||||
public T getMaxValue();
|
||||
|
||||
/**
|
||||
* [Property] Gets a Pattern object used in String property input validation.
|
||||
*/
|
||||
public Pattern getValidationPattern();
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Forge Mod Loader
|
||||
* Copyright (c) 2012-2014 cpw.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser Public License v2.1
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
* Contributors (this class):
|
||||
* bspkrs - implementation
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client.event;
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.Event;
|
||||
import cpw.mods.fml.common.eventhandler.Event.HasResult;
|
||||
|
||||
/**
|
||||
* These events are posted from the GuiConfig screen when the done button is pressed. The events are only posted
|
||||
* if the parent screen is not an instance of GuiConfig or if the configID field has been set for
|
||||
* the GuiConfig screen.
|
||||
*
|
||||
* Listeners for this event should use OnConfigChanged or PostConfigChanged and check for a specific mod ID.
|
||||
* For best results the listener should refresh any objects/fields that are set based on the mod's config
|
||||
* and should serialize the modified config.
|
||||
*
|
||||
* @author bspkrs
|
||||
*/
|
||||
@HasResult
|
||||
public class ConfigChangedEvent extends Event
|
||||
{
|
||||
/**
|
||||
* The Mod ID of the mod whose configuration just changed.
|
||||
*/
|
||||
public final String modID;
|
||||
/**
|
||||
* Whether or not a world is currently running.
|
||||
*/
|
||||
public final boolean isWorldRunning;
|
||||
/**
|
||||
* Will be set to true if any elements were changed that require a restart of Minecraft.
|
||||
*/
|
||||
public final boolean requiresMcRestart;
|
||||
/**
|
||||
* A String identifier for this ConfigChangedEvent.
|
||||
*/
|
||||
public final String configID;
|
||||
|
||||
public ConfigChangedEvent(String modID, String configID, boolean isWorldRunning, boolean requiresMcRestart)
|
||||
{
|
||||
this.modID = modID;
|
||||
this.configID = configID;
|
||||
this.isWorldRunning = isWorldRunning;
|
||||
this.requiresMcRestart = requiresMcRestart;
|
||||
}
|
||||
|
||||
/**
|
||||
* This event is intended to be consumed by the mod whose config has been changed. It fires when the Done button
|
||||
* has been clicked on a GuiConfig screen and the following conditions are met:<br/>
|
||||
* - at least one config element has been changed<br/>
|
||||
* - one of these 2 conditions are met:<br/>
|
||||
* 1) the parent screen is null or is not an instance of GuiConfig<br/>
|
||||
* 2) the configID field has been set to a non-null value for the GuiConfig screen<br/><br/>
|
||||
* Modders should check the modID field of the event to ensure they are only acting on their own config screen's event!
|
||||
*/
|
||||
public static class OnConfigChangedEvent extends ConfigChangedEvent
|
||||
{
|
||||
public OnConfigChangedEvent(String modID, String configID, boolean isWorldRunning, boolean requiresMcRestart)
|
||||
{
|
||||
super(modID, configID, isWorldRunning, requiresMcRestart);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This event is provided for mods to consume if they want to be able to check if other mods' configs have been changed.
|
||||
* This event only fires if the OnConfigChangedEvent result is not DENY.
|
||||
*/
|
||||
public static class PostConfigChangedEvent extends ConfigChangedEvent
|
||||
{
|
||||
public PostConfigChangedEvent(String modID, String configID, boolean isWorldRunning, boolean requiresMcRestart)
|
||||
{
|
||||
super(modID, configID, isWorldRunning, requiresMcRestart);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,7 @@ import cpw.mods.fml.common.functions.ArtifactVersionNameFunction;
|
||||
import cpw.mods.fml.common.functions.ModIdFunction;
|
||||
import cpw.mods.fml.common.registry.GameData;
|
||||
import cpw.mods.fml.common.registry.GameRegistry.Type;
|
||||
import cpw.mods.fml.common.registry.ObjectHolderRegistry;
|
||||
import cpw.mods.fml.common.toposort.ModSorter;
|
||||
import cpw.mods.fml.common.toposort.ModSortingException;
|
||||
import cpw.mods.fml.common.toposort.ModSortingException.SortingExceptionData;
|
||||
@@ -103,6 +104,7 @@ import cpw.mods.fml.relauncher.Side;
|
||||
*/
|
||||
public class Loader
|
||||
{
|
||||
public static final String MC_VERSION = "1.7.10";
|
||||
private static final Splitter DEPENDENCYPARTSPLITTER = Splitter.on(":").omitEmptyStrings().trimResults();
|
||||
private static final Splitter DEPENDENCYSPLITTER = Splitter.on(";").omitEmptyStrings().trimResults();
|
||||
/**
|
||||
@@ -176,14 +178,13 @@ public class Loader
|
||||
private Loader()
|
||||
{
|
||||
modClassLoader = new ModClassLoader(getClass().getClassLoader());
|
||||
String actualMCVersion = "1.7.9";
|
||||
if (!mccversion.equals(actualMCVersion))
|
||||
if (!mccversion.equals(MC_VERSION))
|
||||
{
|
||||
FMLLog.severe("This version of FML is built for Minecraft %s, we have detected Minecraft %s in your minecraft jar file", mccversion, actualMCVersion);
|
||||
FMLLog.severe("This version of FML is built for Minecraft %s, we have detected Minecraft %s in your minecraft jar file", mccversion, MC_VERSION);
|
||||
throw new LoaderException();
|
||||
}
|
||||
|
||||
minecraft = new MinecraftDummyContainer(actualMCVersion);
|
||||
minecraft = new MinecraftDummyContainer(MC_VERSION);
|
||||
mcp = new MCPDummyContainer(MetadataCollection.from(getClass().getResourceAsStream("/mcpmod.info"), "MCP").getMetadataForId("mcp", null));
|
||||
}
|
||||
|
||||
@@ -502,12 +503,14 @@ public class Loader
|
||||
|
||||
public void preinitializeMods()
|
||||
{
|
||||
ObjectHolderRegistry.INSTANCE.findObjectHolders(discoverer.getASMTable());
|
||||
if (!modController.isInState(LoaderState.PREINITIALIZATION))
|
||||
{
|
||||
FMLLog.warning("There were errors previously. Not beginning mod initialization phase");
|
||||
return;
|
||||
}
|
||||
modController.distributeStateMessage(LoaderState.PREINITIALIZATION, discoverer.getASMTable(), canonicalConfigDir);
|
||||
ObjectHolderRegistry.INSTANCE.applyObjectHolders();
|
||||
modController.transition(LoaderState.INITIALIZATION, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ import static org.objectweb.asm.Opcodes.ACC_FINAL;
|
||||
import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
|
||||
import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
|
||||
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
|
||||
import static org.objectweb.asm.Opcodes.INVOKESPECIAL;
|
||||
import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
@@ -25,9 +27,14 @@ import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
@@ -36,8 +43,10 @@ import net.minecraft.launchwrapper.IClassTransformer;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
import org.objectweb.asm.tree.MethodInsnNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
@@ -46,6 +55,8 @@ import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.io.ByteSource;
|
||||
import com.google.common.io.CharSource;
|
||||
import com.google.common.io.LineProcessor;
|
||||
import com.google.common.io.Resources;
|
||||
|
||||
@@ -54,7 +65,7 @@ import cpw.mods.fml.relauncher.FMLRelaunchLog;
|
||||
public class AccessTransformer implements IClassTransformer
|
||||
{
|
||||
private static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("fml.debugAccessTransformer", "false"));
|
||||
private class Modifier
|
||||
class Modifier
|
||||
{
|
||||
public String name = "";
|
||||
public String desc = "";
|
||||
@@ -95,7 +106,42 @@ public class AccessTransformer implements IClassTransformer
|
||||
readMapFile(rulesFile);
|
||||
}
|
||||
|
||||
private void readMapFile(String rulesFile) throws IOException
|
||||
AccessTransformer(JarFile jar) throws IOException
|
||||
{
|
||||
Manifest manifest = jar.getManifest();
|
||||
String atList = manifest.getMainAttributes().getValue("FMLAT");
|
||||
if (atList == null) return;
|
||||
for (String at : atList.split(" "))
|
||||
{
|
||||
JarEntry jarEntry = jar.getJarEntry("META-INF/"+at);
|
||||
if (jarEntry != null)
|
||||
{
|
||||
processATFile(new JarByteSource(jar,jarEntry).asCharSource(Charsets.UTF_8));
|
||||
}
|
||||
}
|
||||
FMLRelaunchLog.fine("Loaded %d rules from AccessTransformer mod jar file %s\n", modifiers.size(), jar.getName());
|
||||
}
|
||||
|
||||
AccessTransformer(Class<? extends AccessTransformer> dummyClazz)
|
||||
{
|
||||
// This is a noop
|
||||
}
|
||||
private class JarByteSource extends ByteSource {
|
||||
private JarFile jar;
|
||||
private JarEntry entry;
|
||||
public JarByteSource(JarFile jar, JarEntry entry)
|
||||
{
|
||||
this.jar = jar;
|
||||
this.entry = entry;
|
||||
}
|
||||
@Override
|
||||
public InputStream openStream() throws IOException
|
||||
{
|
||||
return jar.getInputStream(entry);
|
||||
}
|
||||
|
||||
}
|
||||
void readMapFile(String rulesFile) throws IOException
|
||||
{
|
||||
File file = new File(rulesFile);
|
||||
URL rulesResource;
|
||||
@@ -107,7 +153,12 @@ public class AccessTransformer implements IClassTransformer
|
||||
{
|
||||
rulesResource = Resources.getResource(rulesFile);
|
||||
}
|
||||
Resources.readLines(rulesResource, Charsets.UTF_8, new LineProcessor<Void>()
|
||||
processATFile(Resources.asCharSource(rulesResource, Charsets.UTF_8));
|
||||
FMLRelaunchLog.fine("Loaded %d rules from AccessTransformer config file %s\n", modifiers.size(), rulesFile);
|
||||
}
|
||||
private void processATFile(CharSource rulesResource) throws IOException
|
||||
{
|
||||
rulesResource.readLines(new LineProcessor<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void getResult()
|
||||
@@ -155,7 +206,6 @@ public class AccessTransformer implements IClassTransformer
|
||||
return true;
|
||||
}
|
||||
});
|
||||
FMLRelaunchLog.fine("Loaded %d rules from AccessTransformer config file %s\n", modifiers.size(), rulesFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -206,11 +256,28 @@ public class AccessTransformer implements IClassTransformer
|
||||
}
|
||||
else
|
||||
{
|
||||
List<MethodNode> nowOverridable = Lists.newArrayList();
|
||||
for (MethodNode n : classNode.methods)
|
||||
{
|
||||
if ((n.name.equals(m.name) && n.desc.equals(m.desc)) || m.name.equals("*"))
|
||||
{
|
||||
n.access = getFixedAccess(n.access, m);
|
||||
|
||||
// constructors always use INVOKESPECIAL
|
||||
if (!n.name.equals("<init>"))
|
||||
{
|
||||
// if we changed from private to something else we need to replace all INVOKESPECIAL calls to this method with INVOKEVIRTUAL
|
||||
// so that overridden methods will be called. Only need to scan this class, because obviously the method was private.
|
||||
boolean wasPrivate = (m.oldAccess & ACC_PRIVATE) == ACC_PRIVATE;
|
||||
boolean isNowPrivate = (m.newAccess & ACC_PRIVATE) == ACC_PRIVATE;
|
||||
|
||||
if (wasPrivate && !isNowPrivate)
|
||||
{
|
||||
nowOverridable.add(n);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println(String.format("Method: %s.%s%s %s -> %s", name, n.name, n.desc, toBinary(m.oldAccess), toBinary(m.newAccess)));
|
||||
@@ -222,6 +289,8 @@ public class AccessTransformer implements IClassTransformer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
replaceInvokeSpecial(classNode, nowOverridable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,6 +299,29 @@ public class AccessTransformer implements IClassTransformer
|
||||
return writer.toByteArray();
|
||||
}
|
||||
|
||||
private void replaceInvokeSpecial(ClassNode clazz, List<MethodNode> toReplace)
|
||||
{
|
||||
for (MethodNode method : clazz.methods)
|
||||
{
|
||||
for (Iterator<AbstractInsnNode> it = method.instructions.iterator(); it.hasNext();)
|
||||
{
|
||||
AbstractInsnNode insn = it.next();
|
||||
if (insn.getOpcode() == INVOKESPECIAL)
|
||||
{
|
||||
MethodInsnNode mInsn = (MethodInsnNode) insn;
|
||||
for (MethodNode n : toReplace)
|
||||
{
|
||||
if (n.name.equals(mInsn.name) && n.desc.equals(mInsn.desc))
|
||||
{
|
||||
mInsn.setOpcode(INVOKEVIRTUAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String toBinary(int num)
|
||||
{
|
||||
return String.format("%16s", Integer.toBinaryString(num)).replace(' ', '0');
|
||||
@@ -430,4 +522,12 @@ public class AccessTransformer implements IClassTransformer
|
||||
}
|
||||
}
|
||||
}
|
||||
Multimap<String, Modifier> getModifiers()
|
||||
{
|
||||
return modifiers;
|
||||
}
|
||||
boolean isEmpty()
|
||||
{
|
||||
return modifiers.isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package cpw.mods.fml.common.asm.transformers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.jar.JarFile;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
public class ModAccessTransformer extends AccessTransformer {
|
||||
private static List<AccessTransformer> embedded = Lists.newArrayList();
|
||||
public ModAccessTransformer() throws IOException
|
||||
{
|
||||
super(ModAccessTransformer.class);
|
||||
for (AccessTransformer at : embedded)
|
||||
{
|
||||
mergeModifiers(at.getModifiers());
|
||||
}
|
||||
}
|
||||
|
||||
private void mergeModifiers(Multimap<String, Modifier> modifiers)
|
||||
{
|
||||
getModifiers().putAll(modifiers);
|
||||
}
|
||||
|
||||
public static void addJar(JarFile jar) throws IOException
|
||||
{
|
||||
AccessTransformer at = new AccessTransformer(jar);
|
||||
if (!at.isEmpty())
|
||||
{
|
||||
embedded.add(at);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+35
-44
@@ -16,7 +16,6 @@ import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -43,8 +42,7 @@ import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.io.CharStreams;
|
||||
import com.google.common.io.InputSupplier;
|
||||
import com.google.common.io.CharSource;
|
||||
|
||||
import cpw.mods.fml.common.patcher.ClassPatchManager;
|
||||
import cpw.mods.fml.relauncher.FMLRelaunchLog;
|
||||
@@ -53,7 +51,6 @@ public class FMLDeobfuscatingRemapper extends Remapper {
|
||||
public static final FMLDeobfuscatingRemapper INSTANCE = new FMLDeobfuscatingRemapper();
|
||||
|
||||
private BiMap<String, String> classNameBiMap;
|
||||
private BiMap<String, String> mcpNameBiMap;
|
||||
|
||||
private Map<String,Map<String,String>> rawFieldMaps;
|
||||
private Map<String,Map<String,String>> rawMethodMaps;
|
||||
@@ -71,7 +68,6 @@ public class FMLDeobfuscatingRemapper extends Remapper {
|
||||
private FMLDeobfuscatingRemapper()
|
||||
{
|
||||
classNameBiMap=ImmutableBiMap.of();
|
||||
mcpNameBiMap=ImmutableBiMap.of();
|
||||
}
|
||||
|
||||
public void setupLoadOnly(String deobfFileName, boolean loadAll)
|
||||
@@ -80,12 +76,11 @@ public class FMLDeobfuscatingRemapper extends Remapper {
|
||||
{
|
||||
File mapData = new File(deobfFileName);
|
||||
LZMAInputSupplier zis = new LZMAInputSupplier(new FileInputStream(mapData));
|
||||
InputSupplier<InputStreamReader> srgSupplier = CharStreams.newReaderSupplier(zis,Charsets.UTF_8);
|
||||
List<String> srgList = CharStreams.readLines(srgSupplier);
|
||||
CharSource srgSource = zis.asCharSource(Charsets.UTF_8);
|
||||
List<String> srgList = srgSource.readLines();
|
||||
rawMethodMaps = Maps.newHashMap();
|
||||
rawFieldMaps = Maps.newHashMap();
|
||||
Builder<String, String> builder = ImmutableBiMap.<String,String>builder();
|
||||
Builder<String, String> mcpBuilder = ImmutableBiMap.<String,String>builder();
|
||||
Splitter splitter = Splitter.on(CharMatcher.anyOf(": ")).omitEmptyStrings().trimResults();
|
||||
for (String line : srgList)
|
||||
{
|
||||
@@ -94,7 +89,6 @@ public class FMLDeobfuscatingRemapper extends Remapper {
|
||||
if ("CL".equals(typ))
|
||||
{
|
||||
parseClass(builder, parts);
|
||||
parseMCPClass(mcpBuilder,parts);
|
||||
}
|
||||
else if ("MD".equals(typ) && loadAll)
|
||||
{
|
||||
@@ -106,7 +100,6 @@ public class FMLDeobfuscatingRemapper extends Remapper {
|
||||
}
|
||||
}
|
||||
classNameBiMap = builder.build();
|
||||
mcpNameBiMap = mcpBuilder.build();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
@@ -123,12 +116,11 @@ public class FMLDeobfuscatingRemapper extends Remapper {
|
||||
{
|
||||
InputStream classData = getClass().getResourceAsStream(deobfFileName);
|
||||
LZMAInputSupplier zis = new LZMAInputSupplier(classData);
|
||||
InputSupplier<InputStreamReader> srgSupplier = CharStreams.newReaderSupplier(zis,Charsets.UTF_8);
|
||||
List<String> srgList = CharStreams.readLines(srgSupplier);
|
||||
CharSource srgSource = zis.asCharSource(Charsets.UTF_8);
|
||||
List<String> srgList = srgSource.readLines();
|
||||
rawMethodMaps = Maps.newHashMap();
|
||||
rawFieldMaps = Maps.newHashMap();
|
||||
Builder<String, String> builder = ImmutableBiMap.<String,String>builder();
|
||||
Builder<String, String> mcpBuilder = ImmutableBiMap.<String,String>builder();
|
||||
Splitter splitter = Splitter.on(CharMatcher.anyOf(": ")).omitEmptyStrings().trimResults();
|
||||
for (String line : srgList)
|
||||
{
|
||||
@@ -137,7 +129,6 @@ public class FMLDeobfuscatingRemapper extends Remapper {
|
||||
if ("CL".equals(typ))
|
||||
{
|
||||
parseClass(builder, parts);
|
||||
parseMCPClass(mcpBuilder,parts);
|
||||
}
|
||||
else if ("MD".equals(typ))
|
||||
{
|
||||
@@ -149,13 +140,6 @@ public class FMLDeobfuscatingRemapper extends Remapper {
|
||||
}
|
||||
}
|
||||
classNameBiMap = builder.build();
|
||||
// Special case some mappings for modloader mods
|
||||
mcpBuilder.put("BaseMod","net/minecraft/src/BaseMod");
|
||||
mcpBuilder.put("ModLoader","net/minecraft/src/ModLoader");
|
||||
mcpBuilder.put("EntityRendererProxy","net/minecraft/src/EntityRendererProxy");
|
||||
mcpBuilder.put("MLProp","net/minecraft/src/MLProp");
|
||||
mcpBuilder.put("TradeEntry","net/minecraft/src/TradeEntry");
|
||||
mcpNameBiMap = mcpBuilder.build();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
@@ -167,8 +151,7 @@ public class FMLDeobfuscatingRemapper extends Remapper {
|
||||
|
||||
public boolean isRemappedClass(String className)
|
||||
{
|
||||
className = className.replace('.', '/');
|
||||
return classNameBiMap.containsKey(className) || mcpNameBiMap.containsKey(className) || (!classNameBiMap.isEmpty() && className.indexOf('/') == -1);
|
||||
return !map(className).equals(className);
|
||||
}
|
||||
|
||||
private void parseField(String[] parts)
|
||||
@@ -235,12 +218,6 @@ public class FMLDeobfuscatingRemapper extends Remapper {
|
||||
builder.put(parts[1],parts[2]);
|
||||
}
|
||||
|
||||
private void parseMCPClass(Builder<String, String> builder, String[] parts)
|
||||
{
|
||||
int clIdx = parts[2].lastIndexOf('/');
|
||||
builder.put("net/minecraft/src/"+parts[2].substring(clIdx+1),parts[2]);
|
||||
}
|
||||
|
||||
private void parseMethod(String[] parts)
|
||||
{
|
||||
String oldSrg = parts[1];
|
||||
@@ -280,13 +257,12 @@ public class FMLDeobfuscatingRemapper extends Remapper {
|
||||
{
|
||||
return classNameBiMap.get(typeName);
|
||||
}
|
||||
int dollarIdx = typeName.indexOf('$');
|
||||
String realType = dollarIdx > -1 ? typeName.substring(0, dollarIdx) : typeName;
|
||||
String subType = dollarIdx > -1 ? typeName.substring(dollarIdx+1) : "";
|
||||
|
||||
String result = classNameBiMap.containsKey(realType) ? classNameBiMap.get(realType) : mcpNameBiMap.containsKey(realType) ? mcpNameBiMap.get(realType) : realType;
|
||||
result = dollarIdx > -1 ? result+"$"+subType : result;
|
||||
return result;
|
||||
int dollarIdx = typeName.lastIndexOf('$');
|
||||
if (dollarIdx > -1)
|
||||
{
|
||||
return map(typeName.substring(0, dollarIdx)) + "$" + typeName.substring(dollarIdx + 1);
|
||||
}
|
||||
return typeName;
|
||||
}
|
||||
|
||||
public String unmap(String typeName)
|
||||
@@ -300,14 +276,12 @@ public class FMLDeobfuscatingRemapper extends Remapper {
|
||||
{
|
||||
return classNameBiMap.inverse().get(typeName);
|
||||
}
|
||||
int dollarIdx = typeName.indexOf('$');
|
||||
String realType = dollarIdx > -1 ? typeName.substring(0, dollarIdx) : typeName;
|
||||
String subType = dollarIdx > -1 ? typeName.substring(dollarIdx+1) : "";
|
||||
|
||||
|
||||
String result = classNameBiMap.containsValue(realType) ? classNameBiMap.inverse().get(realType) : mcpNameBiMap.containsValue(realType) ? mcpNameBiMap.inverse().get(realType) : realType;
|
||||
result = dollarIdx > -1 ? result+"$"+subType : result;
|
||||
return result;
|
||||
int dollarIdx = typeName.lastIndexOf('$');
|
||||
if (dollarIdx > -1)
|
||||
{
|
||||
return unmap(typeName.substring(0, dollarIdx)) + "$" + typeName.substring(dollarIdx + 1);
|
||||
}
|
||||
return typeName;
|
||||
}
|
||||
|
||||
|
||||
@@ -431,4 +405,21 @@ public class FMLDeobfuscatingRemapper extends Remapper {
|
||||
{
|
||||
return ImmutableSet.copyOf(classNameBiMap.keySet());
|
||||
}
|
||||
|
||||
public String getStaticFieldType(String oldType, String oldName, String newType, String newName)
|
||||
{
|
||||
String fType = getFieldType(oldType, oldName);
|
||||
if (oldType.equals(newType))
|
||||
{
|
||||
return fType;
|
||||
}
|
||||
Map<String,String> newClassMap = fieldDescriptions.get(newType);
|
||||
if (newClassMap == null)
|
||||
{
|
||||
newClassMap = Maps.newHashMap();
|
||||
fieldDescriptions.put(newType, newClassMap);
|
||||
}
|
||||
newClassMap.put(newName, fType);
|
||||
return fType;
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,11 @@
|
||||
package cpw.mods.fml.common.asm.transformers.deobf;
|
||||
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.commons.Remapper;
|
||||
import org.objectweb.asm.commons.RemappingClassAdapter;
|
||||
import org.objectweb.asm.commons.RemappingMethodAdapter;
|
||||
|
||||
public class FMLRemappingAdapter extends RemappingClassAdapter {
|
||||
public FMLRemappingAdapter(ClassVisitor cv)
|
||||
@@ -31,4 +35,41 @@ public class FMLRemappingAdapter extends RemappingClassAdapter {
|
||||
FMLDeobfuscatingRemapper.INSTANCE.mergeSuperMaps(name, superName, interfaces);
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MethodVisitor createRemappingMethodAdapter(int access, String newDesc, MethodVisitor mv)
|
||||
{
|
||||
return new StaticFixingMethodVisitor(access, newDesc, mv, remapper);
|
||||
}
|
||||
|
||||
private static class StaticFixingMethodVisitor extends RemappingMethodAdapter
|
||||
{
|
||||
|
||||
public StaticFixingMethodVisitor(int access, String desc, MethodVisitor mv, Remapper remapper)
|
||||
{
|
||||
super(access, desc, mv, remapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFieldInsn(int opcode, String originalType, String originalName, String desc)
|
||||
{
|
||||
// This method solves the problem of a static field reference changing type. In all probability it is a
|
||||
// compatible change, however we need to fix up the desc to point at the new type
|
||||
String type = remapper.mapType(originalType);
|
||||
String fieldName = remapper.mapFieldName(originalType, originalName, desc);
|
||||
String newDesc = remapper.mapDesc(desc);
|
||||
if (opcode == Opcodes.GETSTATIC && type.startsWith("net/minecraft/") && newDesc.startsWith("Lnet/minecraft/"))
|
||||
{
|
||||
String replDesc = FMLDeobfuscatingRemapper.INSTANCE.getStaticFieldType(originalType, originalName, type, fieldName);
|
||||
if (replDesc != null)
|
||||
{
|
||||
newDesc = remapper.mapDesc(replDesc);
|
||||
}
|
||||
}
|
||||
// super.super
|
||||
if (mv != null) {
|
||||
mv.visitFieldInsn(opcode, type, fieldName, newDesc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,9 @@ import java.io.InputStream;
|
||||
|
||||
import LZMA.LzmaInputStream;
|
||||
|
||||
import com.google.common.io.InputSupplier;
|
||||
import com.google.common.io.ByteSource;
|
||||
|
||||
public class LZMAInputSupplier implements InputSupplier<InputStream> {
|
||||
public class LZMAInputSupplier extends ByteSource {
|
||||
private InputStream compressedData;
|
||||
|
||||
public LZMAInputSupplier(InputStream compressedData)
|
||||
@@ -28,7 +28,7 @@ public class LZMAInputSupplier implements InputSupplier<InputStream> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInput() throws IOException
|
||||
public InputStream openStream() throws IOException
|
||||
{
|
||||
return new LzmaInputStream(this.compressedData);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ public class FMLDeobfTweaker implements ITweaker {
|
||||
{
|
||||
classLoader.registerTransformer(transformer);
|
||||
}
|
||||
classLoader.registerTransformer("cpw.mods.fml.common.asm.transformers.ModAccessTransformer");
|
||||
try
|
||||
{
|
||||
FMLRelaunchLog.fine("Validating minecraft");
|
||||
|
||||
@@ -13,7 +13,9 @@ public class FMLServerTweaker extends FMLTweaker {
|
||||
@Override
|
||||
public void injectIntoClassLoader(LaunchClassLoader classLoader)
|
||||
{
|
||||
classLoader.addClassLoaderExclusion("com.mojang.util.");
|
||||
// The mojang packages are excluded so the log4j2 queue is correctly visible from
|
||||
// the obfuscated and deobfuscated parts of the code. Without, the UI won't show anything
|
||||
classLoader.addClassLoaderExclusion("com.mojang.");
|
||||
classLoader.addTransformerExclusion("cpw.mods.fml.repackage.");
|
||||
classLoader.addTransformerExclusion("cpw.mods.fml.relauncher.");
|
||||
classLoader.addTransformerExclusion("cpw.mods.fml.common.asm.transformers.");
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import cpw.mods.fml.relauncher.FMLLaunchHandler;
|
||||
import cpw.mods.fml.relauncher.FMLSecurityManager;
|
||||
|
||||
public class FMLTweaker implements ITweaker {
|
||||
private File gameDir;
|
||||
@@ -26,6 +27,17 @@ public class FMLTweaker implements ITweaker {
|
||||
private List<String> standaloneArgs;
|
||||
private static URI jarLocation;
|
||||
|
||||
public FMLTweaker()
|
||||
{
|
||||
try
|
||||
{
|
||||
System.setSecurityManager(new FMLSecurityManager());
|
||||
}
|
||||
catch (SecurityException se)
|
||||
{
|
||||
throw new RuntimeException("FML was unable to install the security manager. The game will not start", se);
|
||||
}
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile)
|
||||
@@ -105,6 +117,7 @@ public class FMLTweaker implements ITweaker {
|
||||
public void injectIntoClassLoader(LaunchClassLoader classLoader)
|
||||
{
|
||||
classLoader.addClassLoaderExclusion("org.apache.");
|
||||
classLoader.addClassLoaderExclusion("com.google.common.");
|
||||
classLoader.addTransformerExclusion("cpw.mods.fml.repackage.");
|
||||
classLoader.addTransformerExclusion("cpw.mods.fml.relauncher.");
|
||||
classLoader.addTransformerExclusion("cpw.mods.fml.common.asm.transformers.");
|
||||
|
||||
@@ -106,8 +106,8 @@ public class FMLOutboundHandler extends ChannelOutboundHandlerAdapter {
|
||||
public List<NetworkDispatcher> selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet)
|
||||
{
|
||||
EntityPlayerMP player = (EntityPlayerMP) args;
|
||||
NetworkDispatcher dispatcher = player.playerNetServerHandler.netManager.channel().attr(NetworkDispatcher.FML_DISPATCHER).get();
|
||||
return ImmutableList.of(dispatcher);
|
||||
NetworkDispatcher dispatcher = player == null ? null : player.playerNetServerHandler.netManager.channel().attr(NetworkDispatcher.FML_DISPATCHER).get();
|
||||
return dispatcher == null ? ImmutableList.<NetworkDispatcher>of() : ImmutableList.of(dispatcher);
|
||||
}
|
||||
},
|
||||
/**
|
||||
@@ -223,7 +223,7 @@ public class FMLOutboundHandler extends ChannelOutboundHandlerAdapter {
|
||||
public List<NetworkDispatcher> selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet)
|
||||
{
|
||||
NetworkManager clientConnection = FMLCommonHandler.instance().getClientToServerNetworkManager();
|
||||
return clientConnection == null ? ImmutableList.<NetworkDispatcher>of() : ImmutableList.of(clientConnection.channel().attr(NetworkDispatcher.FML_DISPATCHER).get());
|
||||
return clientConnection == null || clientConnection.channel().attr(NetworkDispatcher.FML_DISPATCHER).get() == null ? ImmutableList.<NetworkDispatcher>of() : ImmutableList.of(clientConnection.channel().attr(NetworkDispatcher.FML_DISPATCHER).get());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -11,6 +11,11 @@ import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.network.play.client.C17PacketCustomPayload;
|
||||
import net.minecraft.network.play.server.S3FPacketCustomPayload;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.logging.log4j.core.helpers.Integers;
|
||||
import com.google.common.collect.ConcurrentHashMultiset;
|
||||
import com.google.common.collect.Multiset;
|
||||
import com.google.common.collect.Multiset.Entry;
|
||||
import com.google.common.collect.Multisets;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.network.FMLNetworkException;
|
||||
import cpw.mods.fml.common.network.NetworkRegistry;
|
||||
@@ -23,7 +28,8 @@ public class FMLProxyPacket extends Packet {
|
||||
private final ByteBuf payload;
|
||||
private INetHandler netHandler;
|
||||
private NetworkDispatcher dispatcher;
|
||||
|
||||
private static Multiset<String> badPackets = ConcurrentHashMultiset.create();
|
||||
private static int packetCountWarning = Integers.parseInt(System.getProperty("fml.badPacketCounter", "100"), 100);
|
||||
private FMLProxyPacket(byte[] payload, String channel)
|
||||
{
|
||||
this(Unpooled.wrappedBuffer(payload), channel);
|
||||
@@ -68,7 +74,21 @@ public class FMLProxyPacket extends Packet {
|
||||
internalChannel.attr(NetworkRegistry.NET_HANDLER).set(this.netHandler);
|
||||
try
|
||||
{
|
||||
internalChannel.writeInbound(this);
|
||||
if (internalChannel.writeInbound(this))
|
||||
{
|
||||
badPackets.add(this.channel);
|
||||
if (badPackets.size() % packetCountWarning == 0)
|
||||
{
|
||||
FMLLog.severe("Detected ongoing potential memory leak. %d packets have leaked. Top offenders", badPackets.size());
|
||||
int i = 0;
|
||||
for (Entry<String> s : Multisets.copyHighestCountFirst(badPackets).entrySet())
|
||||
{
|
||||
if (i++ > 10) break;
|
||||
FMLLog.severe("\t %s : %d", s.getElement(), s.getCount());
|
||||
}
|
||||
}
|
||||
}
|
||||
internalChannel.inboundMessages().clear();
|
||||
}
|
||||
catch (FMLNetworkException ne)
|
||||
{
|
||||
|
||||
+3
-1
@@ -4,6 +4,7 @@ import org.apache.logging.log4j.Level;
|
||||
import net.minecraft.network.INetHandler;
|
||||
import com.google.common.base.Throwables;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.network.FMLOutboundHandler;
|
||||
import cpw.mods.fml.common.network.NetworkRegistry;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
@@ -28,11 +29,12 @@ public class SimpleChannelHandlerWrapper<REQ extends IMessage, REPLY extends IMe
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, REQ msg) throws Exception
|
||||
{
|
||||
INetHandler iNetHandler = ctx.attr(NetworkRegistry.NET_HANDLER).get();
|
||||
INetHandler iNetHandler = ctx.channel().attr(NetworkRegistry.NET_HANDLER).get();
|
||||
MessageContext context = new MessageContext(iNetHandler, side);
|
||||
REPLY result = messageHandler.onMessage(msg, context);
|
||||
if (result != null)
|
||||
{
|
||||
ctx.channel().attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.REPLY);
|
||||
ctx.writeAndFlush(result).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,7 +330,7 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
|
||||
if (name.isEmpty()) throw new IllegalArgumentException(String.format("Can't use an empty name for the registry, object %s.", thing));
|
||||
if (name.indexOf(':') == -1) throw new IllegalArgumentException(String.format("Can't add the name (%s) without a prefix, object %s", name, thing));
|
||||
if (thing == null) throw new NullPointerException(String.format("Can't add null-object to the registry, name %s.", name));
|
||||
if (name.equals(optionalDefaultName))
|
||||
if (name.equals(optionalDefaultName) && this.optionalDefaultObject == null)
|
||||
{
|
||||
this.optionalDefaultObject = thing;
|
||||
}
|
||||
@@ -420,4 +420,9 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
|
||||
underlyingIntegerMap.func_148746_a(thing, id); // obj <-> id
|
||||
super.putObject(name, thing); // name <-> obj
|
||||
}
|
||||
|
||||
public I getDefaultValue()
|
||||
{
|
||||
return optionalDefaultObject;
|
||||
}
|
||||
}
|
||||
@@ -530,6 +530,8 @@ public class GameData {
|
||||
getMain().iBlockRegistry.dump();
|
||||
getMain().iItemRegistry.dump();
|
||||
Loader.instance().fireRemapEvent(remaps);
|
||||
// The id map changed, ensure we apply object holders
|
||||
ObjectHolderRegistry.INSTANCE.applyObjectHolders();
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
@@ -664,6 +666,8 @@ public class GameData {
|
||||
|
||||
getMain().set(frozen);
|
||||
}
|
||||
// the id mapping has reverted, ensure we sync up the object holders
|
||||
ObjectHolderRegistry.INSTANCE.applyObjectHolders();
|
||||
}
|
||||
|
||||
protected static boolean isFrozen(FMLControlledNamespacedRegistry<?> registry)
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
|
||||
package cpw.mods.fml.common.registry;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -424,4 +428,24 @@ public class GameRegistry
|
||||
return GameData.getUniqueName(item);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This will cause runtime injection of public static final fields to occur at various points
|
||||
* where mod blocks and items <em>could</em> be subject to change. This allows for dynamic
|
||||
* substitution to occur.
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE, ElementType.FIELD})
|
||||
public @interface ObjectHolder {
|
||||
/**
|
||||
* If used on a class, this represents a modid only.
|
||||
* If used on a field, it represents a name, which can be abbreviated or complete.
|
||||
* Abbreviated names derive their modid from an enclosing ObjectHolder at the class level.
|
||||
*
|
||||
* @return either a modid or a name based on the rules above
|
||||
*/
|
||||
String value();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package cpw.mods.fml.common.registry;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import com.google.common.base.Throwables;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.registry.GameRegistry.ObjectHolder;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.Item;
|
||||
|
||||
|
||||
/**
|
||||
* Internal class used in tracking {@link ObjectHolder} references
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
class ObjectHolderRef {
|
||||
private Field field;
|
||||
private String injectedObject;
|
||||
private boolean isBlock;
|
||||
private boolean isItem;
|
||||
|
||||
|
||||
ObjectHolderRef(Field field, String injectedObject, boolean extractFromExistingValues)
|
||||
{
|
||||
this.field = field;
|
||||
this.isBlock = Block.class.isAssignableFrom(field.getType());
|
||||
this.isItem = Item.class.isAssignableFrom(field.getType());
|
||||
if (extractFromExistingValues)
|
||||
{
|
||||
try
|
||||
{
|
||||
Object existing = field.get(null);
|
||||
// nothing is ever allowed to replace AIR
|
||||
if (existing == null || existing == GameData.getBlockRegistry().getDefaultValue())
|
||||
{
|
||||
this.injectedObject = null;
|
||||
this.field = null;
|
||||
this.isBlock = false;
|
||||
this.isItem = false;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.injectedObject = isBlock ? GameData.getBlockRegistry().getNameForObject(existing) :
|
||||
isItem ? GameData.getItemRegistry().getNameForObject(existing) : null;
|
||||
}
|
||||
} catch (Exception e)
|
||||
{
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.injectedObject = injectedObject;
|
||||
}
|
||||
|
||||
if (this.injectedObject == null || !isValid())
|
||||
{
|
||||
throw new IllegalStateException("The ObjectHolder annotation cannot apply to a field that is not an Item or Block");
|
||||
}
|
||||
makeWritable(field);
|
||||
}
|
||||
|
||||
private static Field modifiersField;
|
||||
private static Object reflectionFactory;
|
||||
private static Method newFieldAccessor;
|
||||
private static Method fieldAccessorSet;
|
||||
private static void makeWritable(Field f)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (modifiersField == null)
|
||||
{
|
||||
Method getReflectionFactory = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("getReflectionFactory");
|
||||
reflectionFactory = getReflectionFactory.invoke(null);
|
||||
newFieldAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newFieldAccessor", Field.class, boolean.class);
|
||||
fieldAccessorSet = Class.forName("sun.reflect.FieldAccessor").getDeclaredMethod("set", Object.class, Object.class);
|
||||
modifiersField = Field.class.getDeclaredField("modifiers");
|
||||
modifiersField.setAccessible(true);
|
||||
}
|
||||
modifiersField.setInt(f, f.getModifiers() & ~Modifier.FINAL);
|
||||
} catch (Exception e)
|
||||
{
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isValid()
|
||||
{
|
||||
return isBlock || isItem;
|
||||
}
|
||||
public void apply()
|
||||
{
|
||||
Object thing;
|
||||
if (isBlock)
|
||||
{
|
||||
thing = GameData.getBlockRegistry().getObject(injectedObject);
|
||||
if (thing == Blocks.air)
|
||||
{
|
||||
thing = null;
|
||||
}
|
||||
}
|
||||
else if (isItem)
|
||||
{
|
||||
thing = GameData.getItemRegistry().getObject(injectedObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
thing = null;
|
||||
}
|
||||
|
||||
if (thing == null)
|
||||
{
|
||||
FMLLog.warning("Unable to lookup %s for %s. Is there something wrong with the registry?", injectedObject, field);
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
Object fieldAccessor = newFieldAccessor.invoke(reflectionFactory, field, false);
|
||||
fieldAccessorSet.invoke(fieldAccessor, null, thing);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLLog.log(Level.WARN, e, "Unable to set %s with value %s (%s)", this.field, thing, this.injectedObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package cpw.mods.fml.common.registry;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
|
||||
import cpw.mods.fml.common.registry.GameRegistry.ObjectHolder;
|
||||
|
||||
/**
|
||||
* Internal registry for tracking {@link ObjectHolder} references
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public enum ObjectHolderRegistry {
|
||||
INSTANCE;
|
||||
private List<ObjectHolderRef> objectHolders = Lists.newArrayList();
|
||||
|
||||
public void findObjectHolders(ASMDataTable table)
|
||||
{
|
||||
FMLLog.info("Processing ObjectHolder annotations");
|
||||
Set<ASMData> allObjectHolders = table.getAll(GameRegistry.ObjectHolder.class.getName());
|
||||
Map<String, String> classModIds = Maps.newHashMap();
|
||||
Map<String, Class<?>> classCache = Maps.newHashMap();
|
||||
for (ASMData data : allObjectHolders)
|
||||
{
|
||||
String className = data.getClassName();
|
||||
String annotationTarget = data.getObjectName();
|
||||
String value = (String) data.getAnnotationInfo().get("value");
|
||||
boolean isClass = className.equals(annotationTarget);
|
||||
if (isClass)
|
||||
{
|
||||
scanTarget(classModIds, classCache, className, annotationTarget, value, isClass, false);
|
||||
}
|
||||
}
|
||||
// double pass - get all the class level annotations first, then the field level annotations
|
||||
for (ASMData data : allObjectHolders)
|
||||
{
|
||||
String className = data.getClassName();
|
||||
String annotationTarget = data.getObjectName();
|
||||
String value = (String) data.getAnnotationInfo().get("value");
|
||||
boolean isClass = className.equals(annotationTarget);
|
||||
if (!isClass)
|
||||
{
|
||||
scanTarget(classModIds, classCache, className, annotationTarget, value, isClass, false);
|
||||
}
|
||||
}
|
||||
scanTarget(classModIds, classCache, "net.minecraft.init.Blocks", null, "minecraft", true, true);
|
||||
scanTarget(classModIds, classCache, "net.minecraft.init.Items", null, "minecraft", true, true);
|
||||
FMLLog.info("Found %d ObjectHolder annotations", objectHolders.size());
|
||||
}
|
||||
|
||||
private void scanTarget(Map<String, String> classModIds, Map<String, Class<?>> classCache, String className, String annotationTarget, String value, boolean isClass, boolean extractFromValue)
|
||||
{
|
||||
Class<?> clazz;
|
||||
if (classCache.containsKey(className))
|
||||
{
|
||||
clazz = classCache.get(className);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
clazz = Class.forName(className, true, getClass().getClassLoader());
|
||||
classCache.put(className, clazz);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// unpossible?
|
||||
throw Throwables.propagate(ex);
|
||||
}
|
||||
}
|
||||
if (isClass)
|
||||
{
|
||||
scanClassForFields(classModIds, className, value, clazz, extractFromValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value.indexOf(':') == -1)
|
||||
{
|
||||
String prefix = classModIds.get(className);
|
||||
if (prefix == null)
|
||||
{
|
||||
FMLLog.warning("Found an unqualified ObjectHolder annotation (%s) without a modid context at %s.%s, ignoring", value, className, annotationTarget);
|
||||
throw new IllegalStateException("Unqualified reference to ObjectHolder");
|
||||
}
|
||||
value = prefix + ":" + value;
|
||||
}
|
||||
try
|
||||
{
|
||||
Field f = clazz.getField(annotationTarget);
|
||||
addHolderReference(new ObjectHolderRef(f, value, extractFromValue));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// unpossible?
|
||||
throw Throwables.propagate(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void scanClassForFields(Map<String, String> classModIds, String className, String value, Class<?> clazz, boolean extractFromExistingValues)
|
||||
{
|
||||
classModIds.put(className, value);
|
||||
for (Field f : clazz.getFields())
|
||||
{
|
||||
int mods = f.getModifiers();
|
||||
boolean isMatch = Modifier.isPublic(mods) && Modifier.isStatic(mods) && Modifier.isFinal(mods);
|
||||
if (!isMatch || f.isAnnotationPresent(ObjectHolder.class))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
addHolderReference(new ObjectHolderRef(f, value + ":"+ f.getName(), extractFromExistingValues));
|
||||
}
|
||||
}
|
||||
|
||||
private void addHolderReference(ObjectHolderRef ref)
|
||||
{
|
||||
if (ref.isValid())
|
||||
{
|
||||
objectHolders.add(ref);
|
||||
}
|
||||
}
|
||||
|
||||
public void applyObjectHolders()
|
||||
{
|
||||
FMLLog.info("Applying holder lookups");
|
||||
for (ObjectHolderRef ohr : objectHolders)
|
||||
{
|
||||
ohr.apply();
|
||||
}
|
||||
FMLLog.info("Holder lookups applied");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,21 +28,18 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import org.apache.logging.log4j.Level;
|
||||
|
||||
import net.minecraft.launchwrapper.ITweaker;
|
||||
import net.minecraft.launchwrapper.Launch;
|
||||
import net.minecraft.launchwrapper.LaunchClassLoader;
|
||||
|
||||
import org.apache.logging.log4j.Level;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.ObjectArrays;
|
||||
import com.google.common.primitives.Ints;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.asm.transformers.ModAccessTransformer;
|
||||
import cpw.mods.fml.common.launcher.FMLInjectionAndSortingTweaker;
|
||||
import cpw.mods.fml.common.launcher.FMLTweaker;
|
||||
import cpw.mods.fml.common.toposort.TopologicalSort;
|
||||
@@ -246,9 +243,10 @@ public class CoreModManager {
|
||||
jar = new JarFile(coreMod);
|
||||
if (jar.getManifest() == null)
|
||||
{
|
||||
// Not a coremod
|
||||
// Not a coremod and no access transformer list
|
||||
continue;
|
||||
}
|
||||
ModAccessTransformer.addJar(jar);
|
||||
mfAttributes = jar.getManifest().getMainAttributes();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package cpw.mods.fml.relauncher;
|
||||
|
||||
import java.security.Permission;
|
||||
|
||||
/**
|
||||
* A custom security manager stopping certain events from happening
|
||||
* unexpectedly.
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class FMLSecurityManager extends SecurityManager {
|
||||
@Override
|
||||
public void checkPermission(Permission perm)
|
||||
{
|
||||
String permName = perm.getName() != null ? perm.getName() : "missing";
|
||||
if (permName.startsWith("exitVM"))
|
||||
{
|
||||
Class<?>[] classContexts = getClassContext();
|
||||
String callingClass = classContexts.length > 3 ? classContexts[4].getName() : "none";
|
||||
String callingParent = classContexts.length > 4 ? classContexts[5].getName() : "none";
|
||||
// FML is allowed to call system exit and the Minecraft applet (from the quit button)
|
||||
if (!(callingClass.startsWith("cpw.mods.fml.") || ( "net.minecraft.client.Minecraft".equals(callingClass) && "net.minecraft.client.Minecraft".equals(callingParent)) || ("net.minecraft.server.dedicated.DedicatedServer".equals(callingClass) && "net.minecraft.server.MinecraftServer".equals(callingParent))))
|
||||
{
|
||||
throw new ExitTrappedException();
|
||||
}
|
||||
}
|
||||
else if ("setSecurityManager".equals(permName))
|
||||
{
|
||||
throw new SecurityException("Cannot replace the FML security manager");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public static class ExitTrappedException extends SecurityException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
fml.config.sample.basicDouble.tooltip=A double property with no defined bounds.
|
||||
fml.config.sample.basicDouble=Unbounded Double
|
||||
fml.config.sample.basicInteger.tooltip=An integer property with no defined bounds.
|
||||
fml.config.sample.basicInteger=Unbounded Integer
|
||||
fml.config.sample.basicString.tooltip=A basic string property. The user can enter anything in this textbox.
|
||||
fml.config.sample.basicString=Basic String
|
||||
fml.config.sample.booleanList.tooltip=A boolean list with no max length and can be lengthened or shortened.
|
||||
fml.config.sample.booleanList=Basic Boolean List
|
||||
fml.config.sample.booleanListFixed.tooltip=A boolean list that has a fixed length of 8.
|
||||
fml.config.sample.booleanListFixed=Fixed Length Boolean List
|
||||
fml.config.sample.booleanListMax.tooltip=A boolean list that has a max length of 10.
|
||||
fml.config.sample.booleanListMax=Max Length Boolean List
|
||||
fml.config.sample.boundedDouble.tooltip=A double property with defined bounds.
|
||||
fml.config.sample.boundedDouble=Bounded Double
|
||||
fml.config.sample.boundedInteger.tooltip=An integer property with defined bounds.
|
||||
fml.config.sample.boundedInteger=Bounded Integer
|
||||
fml.config.sample.chatColorPicker.tooltip=A special property that allows the user to select a font color code.
|
||||
fml.config.sample.chatColorPicker=Chat Color Picker
|
||||
fml.config.sample.ctgy.lists.tooltip=Provides a variety of array-property controls to play with.
|
||||
fml.config.sample.ctgy.lists=Sample Array Controls
|
||||
fml.config.sample.ctgy.numbers.tooltip=Provides a listing of the numeric controls for toying with.
|
||||
fml.config.sample.ctgy.numbers=Sample Numeric Controls
|
||||
fml.config.sample.ctgy.strings.tooltip=Provides a listing of the different String-type controls to play with.
|
||||
fml.config.sample.ctgy.strings=Sample String Controls
|
||||
fml.config.sample.cycleString.tooltip=A string property that has a defined list of valid values that can be cycled through.
|
||||
fml.config.sample.cycleString=Cycle Value String
|
||||
fml.config.sample.doubleList.tooltip=A double list with no max length and can be lengthened or shortened.
|
||||
fml.config.sample.doubleList=Basic Double List
|
||||
fml.config.sample.doubleListBounded.tooltip=A double list with specific value bounds.
|
||||
fml.config.sample.doubleListBounded=Double List with Value Bounds
|
||||
fml.config.sample.doubleListFixed.tooltip=A double list that has a fixed length of 10.
|
||||
fml.config.sample.doubleListFixed=Fixed Length Double List
|
||||
fml.config.sample.doubleListMax.tooltip=A double list that has a max length of 15.
|
||||
fml.config.sample.doubleListMax=Max Length Double List
|
||||
fml.config.sample.imABoolean.tooltip=Yep, that's pretty much it... I'm a Boolean control.
|
||||
fml.config.sample.imABoolean=I'm a Boolean
|
||||
fml.config.sample.imADouble.tooltip=There are two of me. Or maybe I work for both the CIA and the KGB. Not sure.
|
||||
fml.config.sample.imADouble=I'm a Double
|
||||
fml.config.sample.imAString.tooltip=Aah. Now, I understand you want us to advertise your washing powder. <*String.*> String, washing powder, what's the difference? We can sell anything. <*Good. Well I have this large quantity of string, 122,000 miles of it to be exact, which I inherited, and I thought if I advertised it...*> Of course! A national campaign. Useful stuff, string, no trouble there. <*Ah, but there's a snag, you see. Due to bad planning, the 122,000 miles is in three inch lengths. So it's not very useful.*> Well, that's our selling point! SIMPSON'S INDIVIDUAL STRINGETTES! THE NOW STRING! READY CUT, EASY TO HANDLE, SIMPSON'S INDIVIDUAL EMPEROR STRINGETTES - JUST THE RIGHT LENGTH!
|
||||
fml.config.sample.imAString=I'm a String
|
||||
fml.config.sample.imAnInteger.tooltip=Did I say that I'm an Integer? Oh, I see.
|
||||
fml.config.sample.imAnInteger=I'm an Integer
|
||||
fml.config.sample.integerList.tooltip=An integer list with no max length and can be lengthened or shortened.
|
||||
fml.config.sample.integerList=Basic Integer List
|
||||
fml.config.sample.integerListBounded.tooltip=An integer list with specific value bounds.
|
||||
fml.config.sample.integerListBounded=Integer List with Value Bounds
|
||||
fml.config.sample.integerListFixed.tooltip=An integer list that has a fixed length of 10.
|
||||
fml.config.sample.integerListFixed=Fixed Length Integer List
|
||||
fml.config.sample.integerListMax.tooltip=An integer list that has a max length of 15.
|
||||
fml.config.sample.integerListMax=Max Length Integer List
|
||||
fml.config.sample.modIDSelector.tooltip=A special property that allows the user to select a mod ID from a list of all installed mods. There are many possibilities for how this could be used with a little custom code: selecting biomes, selecting entities, selecting items, selecting blocks, etc.
|
||||
fml.config.sample.modIDSelector=Mod ID Selector
|
||||
fml.config.sample.patternString.tooltip=A string property that is validated using a Pattern object.
|
||||
fml.config.sample.patternString=Pattern Validated String
|
||||
fml.config.sample.stringList.tooltip=A basic string list with no validation.
|
||||
fml.config.sample.stringList=Basic String List
|
||||
fml.config.sample.stringListFixed.tooltip=A string list that has a fixed length of 7.
|
||||
fml.config.sample.stringListFixed=Fixed Length String List
|
||||
fml.config.sample.stringListMax.tooltip=A string list that has a max length of 15.
|
||||
fml.config.sample.stringListMax=Max Length String List
|
||||
fml.config.sample.stringListPattern.tooltip=A string list that validates each value using a Pattern object.
|
||||
fml.config.sample.stringListPattern=Pattern Validated String List
|
||||
fml.config.sample.title=This is for playing with the Config GUI behavior. Changes are not saved.
|
||||
|
||||
fml.configgui.applyGlobally=Apply globally
|
||||
fml.configgui.confirmRestartMessage=I Understand
|
||||
fml.configgui.gameRestartRequired=One or more changed settings requires that Minecraft be restarted before taking effect.
|
||||
fml.configgui.gameRestartTitle=Minecraft Restart Required
|
||||
fml.configgui.sampletext=Sample Text
|
||||
fml.configgui.tooltip.addNewEntryAbove=Add New Entry Above
|
||||
fml.configgui.tooltip.applyGlobally=Apply Undo Changes or Reset to Default globally.
|
||||
fml.configgui.tooltip.removeEntry=Remove Entry
|
||||
fml.configgui.tooltip.resetAll=Reset All to Default. If the Apply globally checkbox is checked values on child screens will also be reset.
|
||||
fml.configgui.tooltip.resetToDefault=Reset to Default
|
||||
fml.configgui.tooltip.undoAll=Undo All Changes. If the Apply globally checkbox is checked changes to child screens will also be undone.
|
||||
fml.configgui.tooltip.undoChanges=Undo Changes
|
||||
fml.configgui.tooltip.default=[default: %s]
|
||||
fml.configgui.tooltip.defaultNumeric=[range: %s ~ %s, default: %s]
|
||||
@@ -85,3 +85,21 @@ protected net.minecraft.util.ObjectIntIdentityMap field_148749_a # internal map
|
||||
protected net.minecraft.util.ObjectIntIdentityMap field_148748_b # internal index list
|
||||
protected-f net.minecraft.util.RegistryNamespaced field_148759_a # identitymap
|
||||
protected net.minecraft.util.RegistryNamespaced func_148755_c(Ljava/lang/String;)Ljava/lang/String; # prefix if necessary
|
||||
|
||||
# GuiButton
|
||||
public net.minecraft.client.gui.GuiButton field_146120_f # width - needed for config GUI stuff
|
||||
public net.minecraft.client.gui.GuiButton field_146121_g # height - needed for config GUI stuff
|
||||
# GuiTextField
|
||||
public-f net.minecraft.client.gui.GuiTextField field_146209_f # xPosition - needed for config GUI stuff
|
||||
public-f net.minecraft.client.gui.GuiTextField field_146210_g # yPosition - needed for config GUI stuff
|
||||
public-f net.minecraft.client.gui.GuiTextField field_146218_h # width - needed for config GUI stuff
|
||||
public-f net.minecraft.client.gui.GuiTextField field_146219_i # height - needed for config GUI stuff
|
||||
# GuiSlot
|
||||
public net.minecraft.client.gui.GuiSlot field_148149_f # slotHeight - needed for config GUI stuff
|
||||
public net.minecraft.client.gui.GuiSlot field_148151_d # right - needed for config GUI stuff
|
||||
public net.minecraft.client.gui.GuiSlot field_148152_e # left - needed for config GUI stuff
|
||||
public net.minecraft.client.gui.GuiSlot field_148153_b # top - needed for config GUI stuff
|
||||
public net.minecraft.client.gui.GuiSlot field_148154_c # bottom - needed for config GUI stuff
|
||||
public net.minecraft.client.gui.GuiSlot field_148155_a # width - needed for config GUI stuff
|
||||
public net.minecraft.client.gui.GuiSlot field_148158_l # height - needed for config GUI stuff
|
||||
public net.minecraft.client.gui.GuiSlot field_148160_j # headerPadding - needed for config GUI stuff
|
||||
@@ -3,8 +3,8 @@
|
||||
"modid": "mcp",
|
||||
"name": "Minecraft Coder Pack",
|
||||
"description": "Modding toolkit to decompile and deobfuscate the Minecraft client and server files.",
|
||||
"version": "9.03",
|
||||
"mcversion": "1.7.2",
|
||||
"version": "9.05",
|
||||
"mcversion": "1.7.10",
|
||||
"logoFile": "/mcplogo.png",
|
||||
"url": "http://mcp.ocean-labs.de/",
|
||||
"updateUrl": "",
|
||||
|
||||
Reference in new issue
Block a user