Update LiteLoader

This commit is contained in:
Matthew Messinger 2016-01-15 02:49:17 -05:00
parent b4148959f7
commit c8ce4aa3ed
340 changed files with 44115 additions and 25 deletions

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "LiteLoader"]
path = LiteLoader
url = ./LiteLoader

View file

@ -1,9 +1,23 @@
plugins { buildscript {
id 'net.minecraftforge.gradle.tweaker-client' version '2.0.2' repositories {
jcenter()
maven {
name 'forge'
url 'http://files.minecraftforge.net/maven'
} }
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.0-SNAPSHOT'
}
}
plugins {
}
ext.voxellib = project ':voxellib' ext.voxellib = project ':voxellib'
ext.revision = 186 ext.revision = 186
apply plugin: 'net.minecraftforge.gradle.tweaker-client'
archivesBaseName = "MineLittlePony" archivesBaseName = "MineLittlePony"
group = 'com.brohoof.minelp' group = 'com.brohoof.minelp'
version = '1.8' version = '1.8'
@ -31,6 +45,7 @@ sourceSets {
} }
project('forge') { project('forge') {
apply plugin: 'net.minecraftforge.gradle.forge' apply plugin: 'net.minecraftforge.gradle.forge'
version = '0'
minecraft { minecraft {
version = '1.8-11.14.3.1543' version = '1.8-11.14.3.1543'
mappings = rootProject.minecraft.mappings mappings = rootProject.minecraft.mappings
@ -41,7 +56,10 @@ project('forge') {
provided rootProject provided rootProject
} }
} }
project('LiteLoader'){
apply plugin: 'mnm.gradle.ap-ide'
mcMappings = rootProject.minecraft.mappings
}
processResources { processResources {
def props = [ def props = [
version: version, version: version,
@ -57,12 +75,16 @@ processResources {
exclude 'litemod.json' exclude 'litemod.json'
} }
} }
repositories.flatDir { allprojects {repositories{
dir 'liteloader' maven {
name 'sponge'
url 'http://repo.spongepowered.org/maven'
} }
}}
dependencies { dependencies {
deobfProvided 'com.mumfrey:liteloader:1.8-SNAPSHOT:srgnames' provided project('LiteLoader')
provided voxellib provided voxellib
compile sourceSets.common.output compile sourceSets.common.output
compile sourceSets.hdskins.output compile sourceSets.hdskins.output
hdskinsCompile sourceSets.common.output hdskinsCompile sourceSets.common.output

View file

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip

3
liteloader/.factorypath Normal file
View file

@ -0,0 +1,3 @@
<factorypath>
<factorypathentry kind='EXTJAR' id='C:\Users\Matthew\.gradle\caches\modules-2\files-2.1\org.spongepowered\mixin\0.4.11-SNAPSHOT\505a52d43cdcd61c2ce6e08a271e5a18cd12b834\mixin-0.4.11-SNAPSHOT.jar' enabled='true' runInBatchMode='false' />
</factorypath>

78
liteloader/.gitignore vendored Normal file
View file

@ -0,0 +1,78 @@
# Build #
#########
MANIFEST.MF
dependency-reduced-pom.xml
# Compiled #
############
bin
build
dist
lib
out
run
target
*.com
*.class
*.dll
*.exe
*.o
*.so
# Databases #
#############
*.db
*.sql
*.sqlite
# Packages #
############
*.7z
*.dmg
*.gz
*.iso
*.rar
*.tar
*.zip
# Repository #
##############
.git
# Logging #
###########
/logs
*.log
# Misc #
########
*.bak
# System #
##########
.DS_Store
ehthumbs.db
Thumbs.db
*.bat
*.sh
# Project #
###########
.checkstyle
.classpath
.externalToolBuilders
.gradle
.nb-gradle
.idea
.project
.settings
eclipse
nbproject
atlassian-ide-plugin.xml
build.xml
nb-configuration.xml
*.iml
*.ipr
*.iws
*.launch

290
liteloader/build.gradle Normal file
View file

@ -0,0 +1,290 @@
buildscript {
repositories {
jcenter()
mavenLocal()
mavenCentral()
maven {
name = "forge"
url = "http://files.minecraftforge.net/maven"
}
maven {
name = "sonatype"
url = "https://oss.sonatype.org/content/repositories/snapshots/"
}
maven {
name = 'sponge'
url = 'http://repo.spongepowered.org/maven'
}
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.0-SNAPSHOT'
classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.0'
classpath 'org.spongepowered:mixingradle:0.1-SNAPSHOT'
}
}
apply plugin: 'net.minecraftforge.gradle.tweaker-client'
apply plugin: 'checkstyle'
apply plugin: 'maven'
apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'org.spongepowered.mixin'
// Default tasks
defaultTasks 'build'
ext {
// Artefact details
buildNumber = project.hasProperty("buildNumber") ? buildNumber : '0'
buildVersion = project.hasProperty("buildVersion") ? buildVersion : '0.0'
ciSystem = project.hasProperty("ciSystem") ? ciSystem : 'unknown'
commit = project.hasProperty("commit") ? commit : 'unknown'
classifier = project.hasProperty("buildType") ? buildType : 'SNAPSHOT'
isReleaseBuild = "RELEASE".equals(project.classifier.toUpperCase())
mavenRepo = project.isReleaseBuild ? "mavenUrl" : "mavenSnapshotUrl"
// Extended project information
projectName = 'LiteLoader'
inceptionYear = '2012'
packaging = 'jar'
startClass = 'com.mumfrey.liteloader.debug.Start'
tweakClass = 'com.mumfrey.liteloader.launch.LiteLoaderTweaker'
}
// Basic project information
group = "com.mumfrey"
archivesBaseName = "liteloader"
version = buildVersion + (project.isReleaseBuild ? '' : '-' + project.classifier)
// Minimum version of Java required
sourceCompatibility = '1.6'
targetCompatibility = '1.6'
repositories {
maven {
name = 'sponge'
url = 'https://repo.spongepowered.org/maven/'
}
}
dependencies {
compile 'org.spongepowered:mixin:0.4.11-SNAPSHOT'
compile 'com.google.guava:guava:17.0'
compile 'com.google.code.gson:gson:2.2.4'
}
minecraft {
version = project.mcVersion
mappings = project.mcMappings
runDir = "run"
tweakClass = project.tweakClass
}
sourceSets {
main {
refMap = "mixins.liteloader.core.refmap.json"
}
client {
compileClasspath += main.compileClasspath + main.output
//refMap = "mixins.liteloader.client.refmap.json"
}
debug {
compileClasspath += client.compileClasspath + client.output
}
}
mixin {
defaultObfuscationEnv notch
}
checkstyle {
configProperties = [
"name" : project.name,
"organization": project.organization,
"url" : project.url,
"year" : project.inceptionYear
]
configFile = file("checkstyle.xml")
toolVersion = '6.13'
}
javadoc {
source sourceSets.client.allJava
source sourceSets.debug.allJava
}
afterEvaluate {
logger.lifecycle '================================================='
logger.lifecycle ' LiteLoader'
logger.lifecycle ' Copyright (C) 2011-2016 Adam Mummery-Smith'
logger.lifecycle ' Running in {} mode', (project.isReleaseBuild ? "RELEASE" : "SNAPSHOT")
logger.lifecycle '================================================='
makeEclipseCleanRunClient {
arguments = ""
jvmArguments = "-Dliteloader.debug=true -Dmixin.debug.verbose=true -Dmixin.debug.verify=true"
}
// hacks for run configs
def mc = plugins.getPlugin 'net.minecraftforge.gradle.tweaker-client'
mc.replacer.putReplacement '{RUN_CLIENT_MAIN}', project.startClass
mc.replacer.putReplacement '{RUN_CLIENT_TWEAKER}', minecraft.tweakClass
}
// manifest entries for all jars
def jarManifest = {
mainAttributes (
'Built-By': System.properties['user.name'],
'Created-By': System.properties['java.vm.version'] + " (" + System.properties['java.vm.vendor'] + ")",
'Implementation-Title': name,
'Implementation-Version': version + "+" + ciSystem + "-b" + buildNumber + ".git-" + commit,
'Implementation-Vendor': url
)
}
jar {
doFirst {
// Seriously forge?
ant.replace(
file: sourceSets.main.refMapFile,
token: "func_72355_a(Lnet/minecraft/network/NetworkManager;Lnet/minecraft/entity/player/EntityPlayerMP;)V",
value: "initializeConnectionToPlayer(Lnet/minecraft/network/NetworkManager;Lnet/minecraft/entity/player/EntityPlayerMP;Lnet/minecraft/network/NetHandlerPlayServer;)V"
)
}
from sourceSets.client.output
from sourceSets.debug.output
manifest jarManifest
}
task releaseJar(type: Jar) {
from sourceSets.main.output
from sourceSets.client.output
manifest jarManifest
classifier = 'staging'
}
shadowJar {
manifest jarManifest
dependsOn 'reobfReleaseJar'
from sourceSets.main.output
from sourceSets.client.output
exclude 'META-INF/*.DSA'
exclude 'META-INF/*.RSA'
exclude 'dummyThing'
exclude 'LICENSE.txt'
dependencies {
include(dependency('org.spongepowered:mixin'))
}
classifier = 'release'
}
sourceJar {
dependsOn retromapReplacedDebug
dependsOn retromapReplacedClient
from zipTree(tasks.retromapReplacedDebug.out)
from zipTree(tasks.retromapReplacedClient.out)
}
task javadocJar(type: Jar, dependsOn: javadoc) {
from javadoc.destinationDir
classifier = 'javadoc'
}
// Hey @AbrarSyed why can't we just turn this off >:(
task runClient(type: JavaExec, overwrite: true) {
doFirst {
println "Do not use runClient, it is not compatible with Mixin"
System.exit(-1)
}
}
tasks.withType(JavaCompile) {
options.compilerArgs += [
'-Xlint:all',
'-Xlint:-path',
'-Xlint:-rawtypes',
'-Xlint:-processing'
]
options.deprecation = true
options.encoding = 'utf8'
}
if (JavaVersion.current().isJava8Compatible()) {
tasks.withType(Javadoc) {
// disable the crazy super-strict doclint tool in Java 8
options.addStringOption('Xdoclint:none', '-quiet')
}
}
reobf {
jar {
mappingType = 'SEARGE'
}
releaseJar {
mappingType = 'NOTCH'
classpath = sourceSets.main.compileClasspath
}
shadowJar {
mappingType = 'NOTCH'
classpath = sourceSets.main.compileClasspath
}
}
build.dependsOn {[
'reobfReleaseJar',
'reobfShadowJar'
]}
artifacts {
if (project.isReleaseBuild) {
archives jar
}
archives shadowJar
archives sourceJar
archives javadocJar
}
task deploy(type: Copy, dependsOn: build) {
def libraryDir = new File(new File(System.env.APPDATA), ".minecraft/libraries")
from shadowJar.outputs.files[0]
into new File(libraryDir, sprintf('%1$s%4$s%2$s%4$s%3$s', project.group.replace('.', File.separator), archivesBaseName, buildVersion, File.separatorChar))
rename shadowJar.outputs.files[0].name, sprintf("%s-%s.jar", archivesBaseName, buildVersion)
}
uploadArchives {
repositories {
mavenDeployer {
if (project.hasProperty(project.mavenRepo)) {
repository(url: project.getProperty(project.mavenRepo)) {
authentication(userName: project.mavenUsername, password: project.mavenPassword)
}
}
pom {
groupId = project.group
version = project.version
artifactId = project.archivesBaseName
project {
name project.archivesBaseName
packaging 'jar'
description 'LiteLoader'
url 'http://www.liteloader.com/'
scm {
url 'http://develop.liteloader.com/liteloader/LiteLoader'
connection 'scm:git:http://develop.liteloader.com/liteloader/LiteLoader.git'
developerConnection 'scm:git:http://develop.liteloader.com/liteloader/LiteLoader.git'
}
issueManagement {
system 'GitLab Issues'
url 'http://develop.liteloader.com/liteloader/LiteLoader/issues'
}
}
}
}
}
}

109
liteloader/checkstyle.xml Normal file
View file

@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<!--
This configuration file was written by the eclipse-cs plugin configuration editor
-->
<!--
Checkstyle-Configuration: LiteLoader Style
Description: none
-->
<module name="Checker">
<property name="severity" value="warning"/>
<property name="charset" value="UTF-8"/>
<module name="TreeWalker">
<module name="FileContentsHolder"/>
<module name="OuterTypeFilename"/>
<module name="IllegalTokenText">
<property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
<property name="format" value="\\u00(08|09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
<property name="message" value="Avoid using corresponding octal or Unicode escape."/>
</module>
<module name="EmptyBlock">
<property name="option" value="TEXT"/>
<property name="tokens" value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/>
</module>
<module name="ArrayTypeStyle"/>
<module name="MissingSwitchDefault"/>
<module name="FallThrough"/>
<module name="UpperEll"/>
<module name="ModifierOrder"/>
<module name="PackageName">
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
<message key="name.invalidPattern" value="Package name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="TypeName">
<message key="name.invalidPattern" value="Type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="MemberName">
<property name="format" value="^[a-z]([a-zA-Z0-9]*)?$"/>
<message key="name.invalidPattern" value="Member name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="ParameterName">
<property name="format" value="^[a-z]([a-zA-Z0-9]*)?$"/>
<message key="name.invalidPattern" value="Parameter name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="LocalVariableName">
<property name="format" value="^[a-z]([a-zA-Z0-9]*)?$"/>
<property name="tokens" value="VARIABLE_DEF"/>
<message key="name.invalidPattern" value="Local variable name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="ClassTypeParameterName">
<property name="format" value="(^[A-Z][0-9]?)$|(T[A-Z][a-zA-Z0-9]*$)"/>
<message key="name.invalidPattern" value="Class type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="MethodTypeParameterName">
<property name="format" value="(^[A-Z][0-9]?)$|(T[A-Z][a-zA-Z0-9]*$)"/>
<message key="name.invalidPattern" value="Method type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="NoFinalizer"/>
<module name="OperatorWrap">
<property name="option" value="NL"/>
<property name="tokens" value="BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR, LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR "/>
</module>
<module name="RequireThis"/>
<module name="EqualsHashCode"/>
<module name="LeftCurly">
<property name="option" value="nl"/>
</module>
<module name="MethodParamPad">
<property name="allowLineBreaks" value="true"/>
<property name="tokens" value="CTOR_DEF,METHOD_CALL,METHOD_DEF,SUPER_CTOR_CALL"/>
</module>
<module name="LineLength">
<metadata name="net.sf.eclipsecs.core.comment" value="Code line length"/>
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
<property name="max" value="150"/>
<message key="maxLineLen" value="Code line is longer than {0,number,integer} characters (found {1,number,integer})."/>
</module>
<module name="LineLength">
<metadata name="net.sf.eclipsecs.core.comment" value="Comment line length"/>
<property name="ignorePattern" value="^[ ]*([a-zA-Z0-9\{\}\+\|\&amp;\&quot;@\(\)\?\:\.=]|//)"/>
<message key="maxLineLen" value="Comment line is longer than {0,number,integer} characters (found {1,number,integer})."/>
</module>
<module name="NeedBraces">
<property name="allowSingleLineStatement" value="true"/>
<message key="needBraces" value="''{0}'' must use '''{}'''s."/>
</module>
<module name="RightCurly">
<property name="option" value="alone"/>
<property name="tokens" value="LITERAL_TRY,LITERAL_CATCH,LITERAL_FINALLY,LITERAL_IF,LITERAL_ELSE,CLASS_DEF,METHOD_DEF,CTOR_DEF,LITERAL_FOR,LITERAL_WHILE,LITERAL_DO,STATIC_INIT,INSTANCE_INIT"/>
<property name="shouldStartLine" value="false"/>
</module>
<module name="MissingOverride">
<property name="severity" value="error"/>
</module>
<module name="MissingDeprecated">
<property name="severity" value="warning"/>
</module>
<module name="TypecastParenPad">
<property name="tokens" value="RPAREN,TYPECAST"/>
</module>
<module name="DefaultComesLast"/>
<module name="EmptyStatement"/>
<module name="EqualsAvoidNull"/>
<module name="StringLiteralEquality"/>
<module name="FinalClass"/>
</module>
<module name="SuppressionCommentFilter"/>
</module>

View file

@ -0,0 +1,295 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="12">
<profile kind="CodeFormatterProfile" name="LiteLoader" version="12">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.compiler.source" value="1.8"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.8"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.8"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="150"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
</profile>
</profiles>

View file

@ -0,0 +1,7 @@
#Organize Import Order
#Wed Dec 02 11:57:04 GMT 2015
4=com
3=org
2=javax
1=java
0=\#

View file

@ -0,0 +1,10 @@
name=LiteLoader
inceptionYear=2012
packaging=jar
description=LiteLoader
url=http://www.liteloader.com
organization=LiteLoader
buildType=SNAPSHOT
buildVersion=1.8
mcVersion=1.8
mcMappings=snapshot_20151124

View file

@ -0,0 +1,27 @@
package com.mumfrey.liteloader;
import com.mumfrey.liteloader.core.LiteLoaderEventBroker.ReturnValue;
import net.minecraft.util.IChatComponent;
/**
* Interface for mods which can filter inbound chat
*
* @author Adam Mummery-Smith
*/
public interface ChatFilter extends LiteMod
{
/**
* Chat filter function, return false to filter this packet, true to pass
* the packet.
*
* @param chat ChatMessageComponent parsed from the chat packet
* @param message Chat message parsed from the chat message component
* @param newMessage If you wish to mutate the message, set the value using
* newMessage.set()
*
* @return True to keep the packet, false to discard
*/
public abstract boolean onChat(IChatComponent chat, String message, ReturnValue<IChatComponent> newMessage);
}

View file

@ -0,0 +1,20 @@
package com.mumfrey.liteloader;
import net.minecraft.util.IChatComponent;
/**
* Interface for mods which receive inbound chat
*
* @author Adam Mummery-Smith
*/
public interface ChatListener extends LiteMod
{
/**
* Handle an inbound message
*
* @param chat IChatComponent parsed from the chat packet
* @param message Chat message parsed from the chat message component
*/
public abstract void onChat(IChatComponent chat, String message);
}

View file

@ -0,0 +1,15 @@
package com.mumfrey.liteloader;
import net.minecraft.client.gui.GuiNewChat;
/**
* Interface for mods which want to alter the chat display
*
* @author Adam Mummery-Smith
*/
public interface ChatRenderListener extends LiteMod
{
public abstract void onPreRenderChat(int screenWidth, int screenHeight, GuiNewChat chat);
public abstract void onPostRenderChat(int screenWidth, int screenHeight, GuiNewChat chat);
}

View file

@ -0,0 +1,39 @@
package com.mumfrey.liteloader;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.entity.Entity;
/**
* Interface for mods which want to receive callbacks when entities are rendered
* into the world.
*
* @author Adam Mummery-Smith
*/
public interface EntityRenderListener extends LiteMod
{
/**
* Called immediately prior to an entity being rendered
*
* @param render
* @param entity
* @param xPos
* @param yPos
* @param zPos
* @param yaw
* @param partialTicks
*/
public abstract void onRenderEntity(Render render, Entity entity, double xPos, double yPos, double zPos, float yaw, float partialTicks);
/**
* Called immediately following an entity being rendered
*
* @param render
* @param entity
* @param xPos
* @param yPos
* @param zPos
* @param yaw
* @param partialTicks
*/
public abstract void onPostRenderEntity(Render render, Entity entity, double xPos, double yPos, double zPos, float yaw, float partialTicks);
}

View file

@ -0,0 +1,34 @@
package com.mumfrey.liteloader;
import net.minecraft.client.shader.Framebuffer;
/**
* Interface for mods which want to interact with Minecraft's main Frame Buffer
* Object.
*
* @author Adam Mummery-Smith
*/
public interface FrameBufferListener extends LiteMod
{
/**
* Called before the FBO is rendered. Useful if you want to interact with
* the FBO before it is drawn to the screen.
*/
public abstract void preRenderFBO(Framebuffer fbo);
/**
* Called immediately before the FBO is rendered to the screen, after the
* appropriate IGL modes and matrix transforms have been set but before the
* FBO is actually rendered into the main output buffer.
*
* @param fbo FBO instance
* @param width FBO width
* @param height FBO height
*/
public abstract void onRenderFBO(Framebuffer fbo, int width, int height);
/**
* Called after the FBO is rendered whilst still inside the FBO transform
*/
public abstract void postRenderFBO(Framebuffer fbo);
}

View file

@ -0,0 +1,18 @@
package com.mumfrey.liteloader;
import net.minecraft.client.Minecraft;
/**
* Interface for mods which want a frame notification every single game loop
*
* @author Adam Mummery-Smith
*/
public interface GameLoopListener extends LiteMod
{
/**
* Called every frame, before the world is ticked
*
* @param minecraft
*/
public abstract void onRunGameLoop(Minecraft minecraft);
}

View file

@ -0,0 +1,13 @@
package com.mumfrey.liteloader;
/**
* Interface for mods which want callbacks when the HUD is rendered
*
* @author Adam Mummery-Smith
*/
public interface HUDRenderListener extends LiteMod
{
public abstract void onPreRenderHUD(int screenWidth, int screenHeight);
public abstract void onPostRenderHUD(int screenWidth, int screenHeight);
}

View file

@ -0,0 +1,24 @@
package com.mumfrey.liteloader;
import net.minecraft.client.Minecraft;
import com.mumfrey.liteloader.core.LiteLoader;
/**
* Interface for mods which need to initialise stuff once the game
* initialisation is completed, for example mods which need to register new
* renderers.
*
* @author Adam Mummery-Smith
*/
public interface InitCompleteListener extends Tickable
{
/**
* Called as soon as the game is initialised and the main game loop is
* running.
*
* @param minecraft Minecraft instance
* @param loader LiteLoader instance
*/
public abstract void onInitCompleted(Minecraft minecraft, LiteLoader loader);
}

View file

@ -0,0 +1,29 @@
package com.mumfrey.liteloader;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.network.INetHandler;
import net.minecraft.network.play.server.S01PacketJoinGame;
import com.mojang.realmsclient.dto.RealmsServer;
/**
* Interface for mods which wish to be notified when the player connects to a
* server (or local game).
*
* @author Adam Mummery-Smith
*/
public interface JoinGameListener extends LiteMod
{
/**
* Called on join game
*
* @param netHandler Net handler
* @param joinGamePacket Join game packet
* @param serverData ServerData object representing the server being
* connected to
* @param realmsServer If connecting to a realm, a reference to the
* RealmsServer object
*/
public abstract void onJoinGame(INetHandler netHandler, S01PacketJoinGame joinGamePacket, ServerData serverData, RealmsServer realmsServer);
}

View file

@ -0,0 +1,17 @@
package com.mumfrey.liteloader;
/**
* Interface for mods which want to filter outbound chat
*
* @author Adam Mummery-Smith
*/
public interface OutboundChatFilter extends LiteMod
{
/**
* Raised when a chat message is being sent, return false to filter this
* message or true to allow it to be sent.
*
* @param message
*/
public abstract boolean onSendChatMessage(String message);
}

View file

@ -0,0 +1,20 @@
package com.mumfrey.liteloader;
import net.minecraft.network.play.client.C01PacketChatMessage;
/**
* Interface for mods which want to monitor outbound chat
*
* @author Adam Mummery-Smith
*/
public interface OutboundChatListener extends LiteMod
{
/**
* Raised when a new chat packet is created (not necessarily transmitted,
* something could be trolling us).
*
* @param packet
* @param message
*/
public abstract void onSendChatMessage(C01PacketChatMessage packet, String message);
}

View file

@ -0,0 +1,21 @@
package com.mumfrey.liteloader;
import net.minecraft.network.login.INetHandlerLoginClient;
import net.minecraft.network.login.server.S02PacketLoginSuccess;
/**
*
* @author Adam Mummery-Smith
*/
public interface PostLoginListener extends LiteMod
{
/**
* Called immediately after login, before the player has properly joined the
* game. Note that this event is raised <b>in the network thread</b> and is
* not marshalled to the main thread as other packet-generated events are.
*
* @param netHandler
* @param packet
*/
public abstract void onPostLogin(INetHandlerLoginClient netHandler, S02PacketLoginSuccess packet);
}

View file

@ -0,0 +1,23 @@
package com.mumfrey.liteloader;
/**
* Render callback that gets called AFTER entities are rendered
*
* @author Adam Mummery-Smith
*/
public interface PostRenderListener extends LiteMod
{
/**
* Called after entities are rendered but before particles
*
* @param partialTicks
*/
public abstract void onPostRenderEntities(float partialTicks);
/**
* Called after all world rendering is completed
*
* @param partialTicks
*/
public abstract void onPostRender(float partialTicks);
}

View file

@ -0,0 +1,57 @@
package com.mumfrey.liteloader;
import net.minecraft.client.renderer.RenderGlobal;
/**
* Render callbacks that get called before certain render events
*
* @author Adam Mummery-Smith
*/
public interface PreRenderListener extends LiteMod
{
/**
* Called immediately before rendering of the world (including the sky) is
* started.
*
* @param partialTicks
*/
public abstract void onRenderWorld(float partialTicks);
/**
* Called <b>after</b> the world camera transform is initialised, may be
* called more than once per frame if anaglyph is enabled.
*
* @param partialTicks
* @param pass
* @param timeSlice
*/
public abstract void onSetupCameraTransform(float partialTicks, int pass, long timeSlice);
/**
* Called when the sky is rendered, may be called more than once per frame
* if anaglyph is enabled.
*
* @param partialTicks
* @param pass
*/
public abstract void onRenderSky(float partialTicks, int pass);
/**
* Called immediately before the clouds are rendered, may be called more
* than once per frame if anaglyph is enabled.
*
* @param renderGlobal
* @param partialTicks
* @param pass
*/
public abstract void onRenderClouds(float partialTicks, int pass, RenderGlobal renderGlobal);
/**
* Called before the terrain is rendered, may be called more than once per
* frame if anaglyph is enabled.
*
* @param partialTicks
* @param pass
*/
public abstract void onRenderTerrain(float partialTicks, int pass);
}

View file

@ -0,0 +1,36 @@
package com.mumfrey.liteloader;
import net.minecraft.client.gui.GuiScreen;
/**
* Interface for objects which want a pre-render callback
*
* @author Adam Mummery-Smith
*/
public interface RenderListener extends LiteMod
{
/**
* Callback when a frame is rendered
*/
public abstract void onRender();
/**
* Called immediately before the current GUI is rendered
*
* @param currentScreen Current screen (if any)
*/
public abstract void onRenderGui(GuiScreen currentScreen);
/**
* Called when the world is rendered
*
* @deprecated Use PreRenderListener::onRenderWorld(F)V instead
*/
@Deprecated
public abstract void onRenderWorld();
/**
* Called immediately after the world/camera transform is initialised
*/
public abstract void onSetupCameraTransform();
}

View file

@ -0,0 +1,28 @@
package com.mumfrey.liteloader;
import net.minecraft.client.shader.Framebuffer;
import net.minecraft.util.IChatComponent;
import com.mumfrey.liteloader.core.LiteLoaderEventBroker.ReturnValue;
/**
* Interface for mods which want to handle or inhibit the saving of screenshots
*
* @author Adam Mummery-Smith
*/
public interface ScreenshotListener extends LiteMod
{
/**
* Called when a screenshot is taken, mods should return FALSE to suspend
* further processing, or TRUE to allow processing to continue normally
*
* @param screenshotName
* @param width
* @param height
* @param fbo
* @param message Message to return if the event is cancelled
* @return FALSE to suspend further processing, or TRUE to allow processing
* to continue normally
*/
public boolean onSaveScreenshot(String screenshotName, int width, int height, Framebuffer fbo, ReturnValue<IChatComponent> message);
}

View file

@ -0,0 +1,22 @@
package com.mumfrey.liteloader;
import net.minecraft.client.Minecraft;
/**
* Interface for mods which want tick events
*
* @author Adam Mummery-Smith
*/
public interface Tickable extends LiteMod
{
/**
* Called every frame
*
* @param minecraft Minecraft instance
* @param partialTicks Partial tick value
* @param inGame True if in-game, false if in the menu
* @param clock True if this is a new tick, otherwise false if it's a
* regular frame
*/
public abstract void onTick(Minecraft minecraft, float partialTicks, boolean inGame, boolean clock);
}

View file

@ -0,0 +1,10 @@
package com.mumfrey.liteloader;
import net.minecraft.client.gui.ScaledResolution;
public interface ViewportListener extends LiteMod
{
public abstract void onViewportResized(ScaledResolution resolution, int displayWidth, int displayHeight);
public abstract void onFullScreenToggled(boolean fullScreen);
}

View file

@ -0,0 +1,121 @@
package com.mumfrey.liteloader.client;
import com.mumfrey.liteloader.client.ducks.IClientNetLoginHandler;
import com.mumfrey.liteloader.core.ClientPluginChannels;
import com.mumfrey.liteloader.core.exceptions.UnregisteredChannelException;
import net.minecraft.client.Minecraft;
import net.minecraft.network.INetHandler;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.PacketBuffer;
import net.minecraft.network.login.INetHandlerLoginClient;
import net.minecraft.network.login.server.S02PacketLoginSuccess;
import net.minecraft.network.play.INetHandlerPlayClient;
import net.minecraft.network.play.client.C17PacketCustomPayload;
import net.minecraft.network.play.server.S01PacketJoinGame;
import net.minecraft.network.play.server.S3FPacketCustomPayload;
/**
* Handler for client plugin channels
*
* @author Adam Mummery-Smith
*/
public class ClientPluginChannelsClient extends ClientPluginChannels
{
/**
* @param netHandler
* @param loginPacket
*/
void onPostLogin(INetHandlerLoginClient netHandler, S02PacketLoginSuccess loginPacket)
{
this.clearPluginChannels(netHandler);
}
/**
* @param netHandler
* @param loginPacket
*/
void onJoinGame(INetHandler netHandler, S01PacketJoinGame loginPacket)
{
this.sendRegisteredPluginChannels(netHandler);
}
/**
* Callback for the plugin channel hook
*
* @param customPayload
*/
@Override
public void onPluginChannelMessage(S3FPacketCustomPayload customPayload)
{
if (customPayload != null && customPayload.getChannelName() != null)
{
String channel = customPayload.getChannelName();
PacketBuffer data = customPayload.getBufferData();
this.onPluginChannelMessage(channel, data);
}
}
/**
* @param netHandler
* @param registrationData
*/
@Override
protected void sendRegistrationData(INetHandler netHandler, PacketBuffer registrationData)
{
if (netHandler instanceof INetHandlerLoginClient)
{
NetworkManager networkManager = ((IClientNetLoginHandler)netHandler).getNetMgr();
networkManager.sendPacket(new C17PacketCustomPayload(CHANNEL_REGISTER, registrationData));
}
else if (netHandler instanceof INetHandlerPlayClient)
{
ClientPluginChannelsClient.dispatch(new C17PacketCustomPayload(CHANNEL_REGISTER, registrationData));
}
}
/**
* Send a message to the server on a plugin channel
*
* @param channel Channel to send, must not be a reserved channel name
* @param data
*/
@Override
protected boolean send(String channel, PacketBuffer data, ChannelPolicy policy)
{
if (channel == null || channel.length() > 16 || CHANNEL_REGISTER.equals(channel) || CHANNEL_UNREGISTER.equals(channel))
{
throw new RuntimeException("Invalid channel name specified");
}
if (!policy.allows(this, channel))
{
if (policy.isSilent()) return false;
throw new UnregisteredChannelException(channel);
}
C17PacketCustomPayload payload = new C17PacketCustomPayload(channel, data);
return ClientPluginChannelsClient.dispatch(payload);
}
/**
* @param payload
*/
static boolean dispatch(C17PacketCustomPayload payload)
{
try
{
Minecraft minecraft = Minecraft.getMinecraft();
if (minecraft.thePlayer != null && minecraft.thePlayer.sendQueue != null)
{
minecraft.thePlayer.sendQueue.addToSendQueue(payload);
return true;
}
}
catch (Exception ex) {}
return false;
}
}

View file

@ -0,0 +1,183 @@
package com.mumfrey.liteloader.client;
import java.io.File;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.mumfrey.liteloader.client.ducks.IFramebuffer;
import com.mumfrey.liteloader.core.Proxy;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiNewChat;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.shader.Framebuffer;
import net.minecraft.entity.Entity;
import net.minecraft.server.integrated.IntegratedServer;
import net.minecraft.util.IChatComponent;
import net.minecraft.world.WorldSettings;
/**
* Proxy class which handles the redirected calls from the injected callbacks
* and routes them to the relevant liteloader handler classes. We do this rather
* than patching a bunch of bytecode into the packet classes themselves because
* this is easier to maintain.
*
* @author Adam Mummery-Smith
*/
public abstract class ClientProxy extends Proxy
{
private static LiteLoaderEventBrokerClient broker;
private ClientProxy() {}
public static void onStartupComplete()
{
Proxy.onStartupComplete();
ClientProxy.broker = LiteLoaderEventBrokerClient.getInstance();
if (ClientProxy.broker == null)
{
throw new RuntimeException("LiteLoader failed to start up properly."
+ " The game is in an unstable state and must shut down now. Check the developer log for startup errors");
}
ClientProxy.broker.onStartupComplete();
}
public static void onTimerUpdate()
{
ClientProxy.broker.onTimerUpdate();
}
public static void newTick()
{
}
public static void onTick()
{
ClientProxy.broker.onTick();
}
public static void onRender()
{
ClientProxy.broker.onRender();
}
public static void preRenderGUI(float partialTicks)
{
ClientProxy.broker.preRenderGUI(partialTicks);
}
public static void onSetupCameraTransform(int pass, float partialTicks, long timeSlice)
{
ClientProxy.broker.onSetupCameraTransform(pass, partialTicks, timeSlice);
}
public static void postRenderEntities(int pass, float partialTicks, long timeSlice)
{
ClientProxy.broker.postRenderEntities(partialTicks, timeSlice);
}
public static void postRender(float partialTicks, long timeSlice)
{
ClientProxy.broker.postRender(partialTicks, timeSlice);
}
public static void onRenderHUD(float partialTicks)
{
ClientProxy.broker.onRenderHUD(partialTicks);
}
public static void onRenderChat(GuiNewChat chatGui, float partialTicks)
{
ClientProxy.broker.onRenderChat(chatGui, partialTicks);
}
public static void postRenderChat(GuiNewChat chatGui, float partialTicks)
{
ClientProxy.broker.postRenderChat(chatGui, partialTicks);
}
public static void postRenderHUD(float partialTicks)
{
ClientProxy.broker.postRenderHUD(partialTicks);
}
public static void onCreateIntegratedServer(IntegratedServer server, String folderName, String worldName, WorldSettings worldSettings)
{
ClientProxy.broker.onStartServer(server, folderName, worldName, worldSettings);
}
public static void onOutboundChat(CallbackInfo e, String message)
{
ClientProxy.broker.onSendChatMessage(e, message);
}
public static void onResize(Minecraft mc)
{
if (ClientProxy.broker == null) return;
ClientProxy.broker.onResize(mc);
}
public static void preRenderFBO(Framebuffer frameBufferMc)
{
if (ClientProxy.broker == null) return;
if (frameBufferMc instanceof IFramebuffer)
{
((IFramebuffer)frameBufferMc).setDispatchRenderEvent(true);
}
ClientProxy.broker.preRenderFBO(frameBufferMc);
}
public static void postRenderFBO(Framebuffer frameBufferMc)
{
if (ClientProxy.broker == null) return;
ClientProxy.broker.postRenderFBO(frameBufferMc);
}
public static void renderFBO(Framebuffer frameBufferMc, int width, int height, boolean flag)
{
if (ClientProxy.broker == null) return;
ClientProxy.broker.onRenderFBO(frameBufferMc, width, height);
}
public static void onRenderWorld(float partialTicks, long timeSlice)
{
ClientProxy.broker.onRenderWorld(partialTicks, timeSlice);
}
public static void onRenderSky(int pass, float partialTicks, long timeSlice)
{
ClientProxy.broker.onRenderSky(partialTicks, pass, timeSlice);
}
public static void onRenderClouds(RenderGlobal renderGlobalIn, float partialTicks, int pass)
{
ClientProxy.broker.onRenderClouds(partialTicks, pass, renderGlobalIn);
}
public static void onRenderTerrain(int pass, float partialTicks, long timeSlice)
{
ClientProxy.broker.onRenderTerrain(partialTicks, pass, timeSlice);
}
public static void onSaveScreenshot(CallbackInfoReturnable<IChatComponent> ci, File gameDir, String name, int width, int height,
Framebuffer fbo)
{
ClientProxy.broker.onScreenshot(ci, name, width, height, fbo);
}
public static void onRenderEntity(RenderManager source, Render render, Entity entity, double x, double y, double z, float yaw, float pTicks)
{
ClientProxy.broker.onRenderEntity(source, entity, x, y, z, yaw, pTicks, render);
}
public static void onPostRenderEntity(RenderManager source, Render render, Entity entity, double x, double y, double z, float yaw, float pTicks)
{
ClientProxy.broker.onPostRenderEntity(source, entity, x, y, z, yaw, pTicks, render);
}
}

View file

@ -0,0 +1,159 @@
package com.mumfrey.liteloader.client;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.SoundHandler;
import net.minecraft.client.gui.GuiNewChat;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.profiler.Profiler;
import net.minecraft.server.integrated.IntegratedServer;
import com.mumfrey.liteloader.client.overlays.IMinecraft;
import com.mumfrey.liteloader.common.GameEngine;
import com.mumfrey.liteloader.common.Resources;
/**
*
* @author Adam Mummery-Smith
*/
public class GameEngineClient implements GameEngine<Minecraft, IntegratedServer>
{
private final Minecraft engine = Minecraft.getMinecraft();
private final Resources<?, ?> resources = new ResourcesClient();
/* (non-Javadoc)
* @see com.mumfrey.liteloader.common.GameEngine#getProfiler()
*/
@Override
public Profiler getProfiler()
{
return this.engine.mcProfiler;
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.common.GameEngine#isClient()
*/
@Override
public boolean isClient()
{
return true;
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.common.GameEngine#isServer()
*/
@Override
public boolean isServer()
{
return this.isSinglePlayer();
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.common.GameEngine#isInGame()
*/
@Override
public boolean isInGame()
{
return this.engine.thePlayer != null && this.engine.theWorld != null && this.engine.theWorld.isRemote;
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.common.GameEngine#isRunning()
*/
@Override
public boolean isRunning()
{
return ((IMinecraft)this.engine).isRunning();
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.common.GameEngine#isSingleplayer()
*/
@Override
public boolean isSinglePlayer()
{
return this.engine.isSingleplayer();
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.common.GameEngine#getClient()
*/
@Override
public Minecraft getClient()
{
return this.engine;
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.common.GameEngine#getServer()
*/
@Override
public IntegratedServer getServer()
{
return this.engine.getIntegratedServer();
}
@Override
public Resources<?, ?> getResources()
{
return this.resources;
}
public GameSettings getGameSettings()
{
return this.engine.gameSettings;
}
public ScaledResolution getScaledResolution()
{
return new ScaledResolution(this.engine, this.engine.displayWidth, this.engine.displayHeight);
}
public GuiNewChat getChatGUI()
{
return this.engine.ingameGUI.getChatGUI();
}
public GuiScreen getCurrentScreen()
{
return this.engine.currentScreen;
}
public boolean hideGUI()
{
return this.engine.gameSettings.hideGUI;
}
public SoundHandler getSoundHandler()
{
return this.engine.getSoundHandler();
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.common.GameEngine#getKeyBindings()
*/
@Override
public List<KeyBinding> getKeyBindings()
{
LinkedList<KeyBinding> keyBindings = new LinkedList<KeyBinding>();
keyBindings.addAll(Arrays.asList(this.engine.gameSettings.keyBindings));
return keyBindings;
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.common.GameEngine
* #setKeyBindings(java.util.List)
*/
@Override
public void setKeyBindings(List<KeyBinding> keyBindings)
{
this.engine.gameSettings.keyBindings = keyBindings.toArray(new KeyBinding[0]);
}
}

View file

@ -0,0 +1,111 @@
package com.mumfrey.liteloader.client;
import net.minecraft.client.audio.SoundHandler;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.IResourcePack;
import net.minecraft.client.resources.SimpleReloadableResourceManager;
import net.minecraft.network.INetHandler;
import net.minecraft.network.play.server.S01PacketJoinGame;
import net.minecraft.world.World;
import com.mumfrey.liteloader.api.CoreProvider;
import com.mumfrey.liteloader.common.GameEngine;
import com.mumfrey.liteloader.common.Resources;
import com.mumfrey.liteloader.core.LiteLoader;
import com.mumfrey.liteloader.core.LiteLoaderMods;
import com.mumfrey.liteloader.launch.LoaderProperties;
import com.mumfrey.liteloader.resources.InternalResourcePack;
/**
* CoreProvider which fixes SoundManager derping up at startup
*
* @author Adam Mummery-Smith
*/
public class LiteLoaderCoreProviderClient implements CoreProvider
{
/**
* Loader Properties adapter
*/
private final LoaderProperties properties;
/**
* Read from the properties file, if true we will inhibit the sound manager
* reload during startup to avoid getting in trouble with OpenAL.
*/
private boolean inhibitSoundManagerReload = true;
/**
* If inhibit is enabled, this object is used to reflectively inhibit the
* sound manager's reload process during startup by removing it from the
* reloadables list.
*/
private SoundHandlerReloadInhibitor soundHandlerReloadInhibitor;
public LiteLoaderCoreProviderClient(LoaderProperties properties)
{
this.properties = properties;
}
@Override
public void onInit()
{
this.inhibitSoundManagerReload = this.properties.getAndStoreBooleanProperty(LoaderProperties.OPTION_SOUND_MANAGER_FIX, true);
}
@SuppressWarnings("unchecked")
@Override
public void onPostInit(GameEngine<?, ?> engine)
{
SimpleReloadableResourceManager resourceManager = (SimpleReloadableResourceManager)engine.getResources().getResourceManager();
SoundHandler soundHandler = ((GameEngineClient)engine).getSoundHandler();
this.soundHandlerReloadInhibitor = new SoundHandlerReloadInhibitor(resourceManager, soundHandler);
if (this.inhibitSoundManagerReload)
{
this.soundHandlerReloadInhibitor.inhibit();
}
// Add self as a resource pack for texture/lang resources
Resources<IResourceManager, IResourcePack> resources = (Resources<IResourceManager, IResourcePack>)LiteLoader.getGameEngine().getResources();
resources.registerResourcePack(new InternalResourcePack("LiteLoader", LiteLoader.class, "liteloader"));
}
@Override
public void onPostInitComplete(LiteLoaderMods mods)
{
}
@Override
public void onStartupComplete()
{
if (this.soundHandlerReloadInhibitor != null && this.soundHandlerReloadInhibitor.isInhibited())
{
this.soundHandlerReloadInhibitor.unInhibit(true);
}
}
@Override
public void onJoinGame(INetHandler netHandler, S01PacketJoinGame loginPacket)
{
}
@Override
public void onPostRender(int mouseX, int mouseY, float partialTicks)
{
}
@Override
public void onTick(boolean clock, float partialTicks, boolean inGame)
{
}
@Override
public void onWorldChanged(World world)
{
}
@Override
public void onShutDown()
{
}
}

View file

@ -0,0 +1,567 @@
package com.mumfrey.liteloader.client;
import org.lwjgl.input.Mouse;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.mumfrey.liteloader.*;
import com.mumfrey.liteloader.client.overlays.IEntityRenderer;
import com.mumfrey.liteloader.client.overlays.IMinecraft;
import com.mumfrey.liteloader.common.LoadingProgress;
import com.mumfrey.liteloader.core.InterfaceRegistrationDelegate;
import com.mumfrey.liteloader.core.LiteLoader;
import com.mumfrey.liteloader.core.LiteLoaderEventBroker;
import com.mumfrey.liteloader.core.event.HandlerList;
import com.mumfrey.liteloader.core.event.HandlerList.ReturnLogicOp;
import com.mumfrey.liteloader.core.event.ProfilingHandlerList;
import com.mumfrey.liteloader.interfaces.FastIterableDeque;
import com.mumfrey.liteloader.launch.LoaderProperties;
import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiNewChat;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.IResourceManagerReloadListener;
import net.minecraft.client.shader.Framebuffer;
import net.minecraft.entity.Entity;
import net.minecraft.network.play.client.C01PacketChatMessage;
import net.minecraft.server.integrated.IntegratedServer;
import net.minecraft.util.IChatComponent;
import net.minecraft.util.Timer;
public class LiteLoaderEventBrokerClient extends LiteLoaderEventBroker<Minecraft, IntegratedServer> implements IResourceManagerReloadListener
{
/**
* Singleton
*/
private static LiteLoaderEventBrokerClient instance;
/**
* Reference to the game
*/
protected final GameEngineClient engineClient;
/**
* Current screen width
*/
private int screenWidth = 854;
/**
* Current screen height
*/
private int screenHeight = 480;
/**
*
*/
private boolean wasFullScreen = false;
/**
* Hash code of the current world. We don't store the world reference
* here because we don't want to mess with world GC by mistake.
*/
private int worldHashCode = 0;
private FastIterableDeque<Tickable> tickListeners;
private FastIterableDeque<GameLoopListener> loopListeners = new HandlerList<GameLoopListener>(GameLoopListener.class);
private FastIterableDeque<RenderListener> renderListeners = new HandlerList<RenderListener>(RenderListener.class);
private FastIterableDeque<PreRenderListener> preRenderListeners = new HandlerList<PreRenderListener>(PreRenderListener.class);
private FastIterableDeque<PostRenderListener> postRenderListeners = new HandlerList<PostRenderListener>(PostRenderListener.class);
private FastIterableDeque<HUDRenderListener> hudRenderListeners = new HandlerList<HUDRenderListener>(HUDRenderListener.class);
private FastIterableDeque<ChatRenderListener> chatRenderListeners = new HandlerList<ChatRenderListener>(ChatRenderListener.class);
private FastIterableDeque<OutboundChatListener> outboundChatListeners = new HandlerList<OutboundChatListener>(OutboundChatListener.class);
private FastIterableDeque<ViewportListener> viewportListeners = new HandlerList<ViewportListener>(ViewportListener.class);
private FastIterableDeque<FrameBufferListener> frameBufferListeners = new HandlerList<FrameBufferListener>(FrameBufferListener.class);
private FastIterableDeque<InitCompleteListener> initListeners = new HandlerList<InitCompleteListener>(InitCompleteListener.class);
private FastIterableDeque<OutboundChatFilter> outboundChatFilters = new HandlerList<OutboundChatFilter>(OutboundChatFilter.class,
ReturnLogicOp.AND);
private FastIterableDeque<ScreenshotListener> screenshotListeners = new HandlerList<ScreenshotListener>(ScreenshotListener.class,
ReturnLogicOp.AND_BREAK_ON_FALSE);
private FastIterableDeque<EntityRenderListener> entityRenderListeners = new HandlerList<EntityRenderListener>(EntityRenderListener.class);
@SuppressWarnings("cast")
public LiteLoaderEventBrokerClient(LiteLoader loader, GameEngineClient engine, LoaderProperties properties)
{
super(loader, engine, properties);
LiteLoaderEventBrokerClient.instance = this;
this.engineClient = (GameEngineClient)engine;
this.tickListeners = new ProfilingHandlerList<Tickable>(Tickable.class, this.engineClient.getProfiler());
}
public static LiteLoaderEventBrokerClient getInstance()
{
return LiteLoaderEventBrokerClient.instance;
}
@Override
public void onResourceManagerReload(IResourceManager resourceManager)
{
LoadingProgress.setMessage("Reloading Resources...");
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.InterfaceProvider#registerInterfaces(
* com.mumfrey.liteloader.core.InterfaceRegistrationDelegate)
*/
@Override
public void registerInterfaces(InterfaceRegistrationDelegate delegate)
{
super.registerInterfaces(delegate);
delegate.registerInterface(Tickable.class);
delegate.registerInterface(GameLoopListener.class);
delegate.registerInterface(RenderListener.class);
delegate.registerInterface(PreRenderListener.class);
delegate.registerInterface(PostRenderListener.class);
delegate.registerInterface(HUDRenderListener.class);
delegate.registerInterface(ChatRenderListener.class);
delegate.registerInterface(OutboundChatListener.class);
delegate.registerInterface(ViewportListener.class);
delegate.registerInterface(FrameBufferListener.class);
delegate.registerInterface(InitCompleteListener.class);
delegate.registerInterface(OutboundChatFilter.class);
delegate.registerInterface(ScreenshotListener.class);
delegate.registerInterface(EntityRenderListener.class);
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.InterfaceProvider#initProvider()
*/
@Override
public void initProvider()
{
}
/**
* @param tickable
*/
public void addTickListener(Tickable tickable)
{
this.tickListeners.add(tickable);
}
/**
* @param loopListener
*/
public void addLoopListener(GameLoopListener loopListener)
{
this.loopListeners.add(loopListener);
}
/**
* @param initCompleteListener
*/
public void addInitListener(InitCompleteListener initCompleteListener)
{
this.initListeners.add(initCompleteListener);
}
/**
* @param renderListener
*/
public void addRenderListener(RenderListener renderListener)
{
this.renderListeners.add(renderListener);
}
/**
* @param preRenderListener
*/
public void addPreRenderListener(PreRenderListener preRenderListener)
{
this.preRenderListeners.add(preRenderListener);
}
/**
* @param postRenderListener
*/
public void addPostRenderListener(PostRenderListener postRenderListener)
{
this.postRenderListeners.add(postRenderListener);
}
/**
* @param chatRenderListener
*/
public void addChatRenderListener(ChatRenderListener chatRenderListener)
{
this.chatRenderListeners.add(chatRenderListener);
}
/**
* @param hudRenderListener
*/
public void addHUDRenderListener(HUDRenderListener hudRenderListener)
{
this.hudRenderListeners.add(hudRenderListener);
}
/**
* @param outboundChatListener
*/
public void addOutboundChatListener(OutboundChatListener outboundChatListener)
{
this.outboundChatListeners.add(outboundChatListener);
}
/**
* @param outboundChatFilter
*/
public void addOutboundChatFiler(OutboundChatFilter outboundChatFilter)
{
this.outboundChatFilters.add(outboundChatFilter);
}
/**
* @param viewportListener
*/
public void addViewportListener(ViewportListener viewportListener)
{
this.viewportListeners.add(viewportListener);
}
/**
* @param frameBufferListener
*/
public void addFrameBufferListener(FrameBufferListener frameBufferListener)
{
this.frameBufferListeners.add(frameBufferListener);
}
/**
* @param screenshotListener
*/
public void addScreenshotListener(ScreenshotListener screenshotListener)
{
this.screenshotListeners.add(screenshotListener);
}
/**
* @param entityRenderListener
*/
public void addEntityRenderListener(EntityRenderListener entityRenderListener)
{
this.entityRenderListeners.add(entityRenderListener);
}
/**
* Late initialisation callback
*/
@Override
protected void onStartupComplete()
{
this.engine.getResources().refreshResources(false);
for (InitCompleteListener initMod : this.initListeners)
{
try
{
LoadingProgress.setMessage("Calling late init for mod %s...", initMod.getName());
LiteLoaderLogger.info("Calling late init for mod %s", initMod.getName());
initMod.onInitCompleted(this.engine.getClient(), this.loader);
}
catch (Throwable th)
{
this.mods.onLateInitFailed(initMod, th);
LiteLoaderLogger.warning(th, "Error calling late init for mod %s", initMod.getName());
}
}
this.onResize(this.engineClient.getClient());
super.onStartupComplete();
}
public void onResize(Minecraft minecraft)
{
ScaledResolution currentResolution = this.engineClient.getScaledResolution();
this.screenWidth = currentResolution.getScaledWidth();
this.screenHeight = currentResolution.getScaledHeight();
if (this.wasFullScreen != minecraft.isFullScreen())
{
this.viewportListeners.all().onFullScreenToggled(minecraft.isFullScreen());
}
this.wasFullScreen = minecraft.isFullScreen();
this.viewportListeners.all().onViewportResized(currentResolution, minecraft.displayWidth, minecraft.displayHeight);
}
/**
* Callback from the tick hook, pre render
*/
void onRender()
{
this.renderListeners.all().onRender();
}
/**
* Callback from the tick hook, post render entities
*
* @param partialTicks
* @param timeSlice
*/
void postRenderEntities(float partialTicks, long timeSlice)
{
this.postRenderListeners.all().onPostRenderEntities(partialTicks);
}
/**
* Callback from the tick hook, post render
*
* @param partialTicks
* @param timeSlice
*/
void postRender(float partialTicks, long timeSlice)
{
((IEntityRenderer)this.engineClient.getClient().entityRenderer).setupCamera(partialTicks, 0);
this.postRenderListeners.all().onPostRender(partialTicks);
}
/**
* Called immediately before the current GUI is rendered
*/
void preRenderGUI(float partialTicks)
{
this.renderListeners.all().onRenderGui(this.engineClient.getCurrentScreen());
}
/**
* Called immediately after the world/camera transform is initialised
*
* @param pass
* @param timeSlice
* @param partialTicks
*/
void onSetupCameraTransform(int pass, float partialTicks, long timeSlice)
{
this.renderListeners.all().onSetupCameraTransform();
this.preRenderListeners.all().onSetupCameraTransform(partialTicks, pass, timeSlice);
}
/**
* Called immediately before the chat log is rendered
*
* @param chatGui
* @param partialTicks
*/
void onRenderChat(GuiNewChat chatGui, float partialTicks)
{
this.chatRenderListeners.all().onPreRenderChat(this.screenWidth, this.screenHeight, chatGui);
}
/**
* Called immediately after the chat log is rendered
*
* @param chatGui
* @param partialTicks
*/
void postRenderChat(GuiNewChat chatGui, float partialTicks)
{
this.chatRenderListeners.all().onPostRenderChat(this.screenWidth, this.screenHeight, chatGui);
}
/**
* Callback when about to render the HUD
*/
void onRenderHUD(float partialTicks)
{
this.hudRenderListeners.all().onPreRenderHUD(this.screenWidth, this.screenHeight);
}
/**
* Callback when the HUD has just been rendered
*/
void postRenderHUD(float partialTicks)
{
this.hudRenderListeners.all().onPostRenderHUD(this.screenWidth, this.screenHeight);
}
/**
* Callback from the tick hook, called every frame when the timer is updated
*/
void onTimerUpdate()
{
Minecraft minecraft = this.engine.getClient();
this.loopListeners.all().onRunGameLoop(minecraft);
}
/**
* Callback from the tick hook, ticks all tickable mods
*/
void onTick()
{
this.profiler.endStartSection("litemods");
Timer minecraftTimer = ((IMinecraft)this.engine.getClient()).getTimer();
float partialTicks = minecraftTimer.renderPartialTicks;
boolean clock = minecraftTimer.elapsedTicks > 0;
Minecraft minecraft = this.engine.getClient();
// Flag indicates whether we are in game at the moment
Entity renderViewEntity = minecraft.getRenderViewEntity(); // TODO OBF MCPTEST func_175606_aa - getRenderViewEntity
boolean inGame = renderViewEntity != null && renderViewEntity.worldObj != null;
this.profiler.startSection("loader");
super.onTick(clock, partialTicks, inGame);
int mouseX = Mouse.getX() * this.screenWidth / minecraft.displayWidth;
int mouseY = this.screenHeight - Mouse.getY() * this.screenHeight / minecraft.displayHeight - 1;
this.profiler.endStartSection("postrender");
super.onPostRender(mouseX, mouseY, partialTicks);
this.profiler.endSection();
// Iterate tickable mods
this.tickListeners.all().onTick(minecraft, partialTicks, inGame, clock);
// Detected world change
int worldHashCode = (minecraft.theWorld != null) ? minecraft.theWorld.hashCode() : 0;
if (worldHashCode != this.worldHashCode)
{
this.worldHashCode = worldHashCode;
super.onWorldChanged(minecraft.theWorld);
}
}
/**
* @param packet
* @param message
*/
void onSendChatMessage(C01PacketChatMessage packet, String message)
{
this.outboundChatListeners.all().onSendChatMessage(packet, message);
}
/**
* @param message
*/
void onSendChatMessage(CallbackInfo e, String message)
{
if (!this.outboundChatFilters.all().onSendChatMessage(message))
{
e.cancel();
}
}
/**
* @param framebuffer
*/
void preRenderFBO(Framebuffer framebuffer)
{
this.frameBufferListeners.all().preRenderFBO(framebuffer);
}
/**
* @param framebuffer
* @param width
* @param height
*/
void onRenderFBO(Framebuffer framebuffer, int width, int height)
{
this.frameBufferListeners.all().onRenderFBO(framebuffer, width, height);
}
/**
* @param framebuffer
*/
void postRenderFBO(Framebuffer framebuffer)
{
this.frameBufferListeners.all().postRenderFBO(framebuffer);
}
/**
* @param partialTicks
* @param timeSlice
*/
void onRenderWorld(float partialTicks, long timeSlice)
{
this.preRenderListeners.all().onRenderWorld(partialTicks);
this.renderListeners.all().onRenderWorld();
}
/**
* @param partialTicks
* @param pass
* @param timeSlice
*/
void onRenderSky(float partialTicks, int pass, long timeSlice)
{
this.preRenderListeners.all().onRenderSky(partialTicks, pass);
}
/**
* @param partialTicks
* @param pass
* @param renderGlobal
*/
void onRenderClouds(float partialTicks, int pass, RenderGlobal renderGlobal)
{
this.preRenderListeners.all().onRenderClouds(partialTicks, pass, renderGlobal);
}
/**
* @param partialTicks
* @param pass
* @param timeSlice
*/
void onRenderTerrain(float partialTicks, int pass, long timeSlice)
{
this.preRenderListeners.all().onRenderTerrain(partialTicks, pass);
}
/**
* @param e
* @param name
* @param width
* @param height
* @param fbo
*/
void onScreenshot(CallbackInfoReturnable<IChatComponent> ci, String name, int width, int height, Framebuffer fbo)
{
ReturnValue<IChatComponent> ret = new ReturnValue<IChatComponent>(ci.getReturnValue());
if (!this.screenshotListeners.all().onSaveScreenshot(name, width, height, fbo, ret))
{
ci.setReturnValue(ret.get());
}
}
/**
* @param source
* @param entity
* @param xPos
* @param yPos
* @param zPos
* @param yaw
* @param partialTicks
* @param render
*/
public void onRenderEntity(RenderManager source, Entity entity, double xPos, double yPos, double zPos, float yaw, float partialTicks,
Render render)
{
this.entityRenderListeners.all().onRenderEntity(render, entity, xPos, yPos, zPos, yaw, partialTicks);
}
/**
* @param source
* @param entity
* @param xPos
* @param yPos
* @param zPos
* @param yaw
* @param partialTicks
* @param render
*/
public void onPostRenderEntity(RenderManager source, Entity entity, double xPos, double yPos, double zPos, float yaw, float partialTicks,
Render render)
{
this.entityRenderListeners.all().onPostRenderEntity(render, entity, xPos, yPos, zPos, yaw, partialTicks);
}
}

View file

@ -0,0 +1,294 @@
package com.mumfrey.liteloader.client;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiIngameMenu;
import net.minecraft.client.gui.GuiMainMenu;
import net.minecraft.client.gui.GuiOptions;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.resources.I18n;
import org.lwjgl.input.Keyboard;
import com.mumfrey.liteloader.client.gui.GuiLiteLoaderPanel;
import com.mumfrey.liteloader.common.GameEngine;
import com.mumfrey.liteloader.core.LiteLoaderMods;
import com.mumfrey.liteloader.core.LiteLoaderUpdateSite;
import com.mumfrey.liteloader.core.LiteLoaderVersion;
import com.mumfrey.liteloader.interfaces.PanelManager;
import com.mumfrey.liteloader.launch.LoaderEnvironment;
import com.mumfrey.liteloader.launch.LoaderProperties;
import com.mumfrey.liteloader.modconfig.ConfigManager;
import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
/**
* Observer which handles the display of the mod panel
*
* @author Adam Mummery-Smith
*/
public class LiteLoaderPanelManager implements PanelManager<GuiScreen>
{
private final LoaderEnvironment environment;
/**
* Loader Properties adapter
*/
private final LoaderProperties properties;
private LiteLoaderMods mods;
private ConfigManager configManager;
private Minecraft minecraft;
/**
* Setting which determines whether we show the "mod info" screen tab in the
* main menu.
*/
private boolean displayModInfoScreenTab = true;
/**
* Don't hide t
*/
private boolean tabAlwaysExpanded = false;
/**
* Override for the "mod info" tab setting, so that mods which want to
* handle the mod info themselves can temporarily disable the function
* without having to change the underlying property.
*/
private boolean hideModInfoScreenTab = false;
private boolean checkForUpdate = false;
private String notification;
/**
* Active "mod info" screen, drawn as an overlay when in the main menu and
* made the active screen if the user clicks the tab.
*/
private GuiLiteLoaderPanel panelHost;
/**
* @param environment
* @param properties
*/
@SuppressWarnings("unchecked")
public LiteLoaderPanelManager(GameEngine<?, ?> engine, LoaderEnvironment environment, LoaderProperties properties)
{
this.environment = environment;
this.properties = properties;
this.minecraft = ((GameEngine<Minecraft, ?>)engine).getClient();
this.displayModInfoScreenTab = this.properties.getAndStoreBooleanProperty(LoaderProperties.OPTION_MOD_INFO_SCREEN, true);
this.tabAlwaysExpanded = this.properties.getAndStoreBooleanProperty(LoaderProperties.OPTION_NO_HIDE_TAB, false);
if (this.properties.getAndStoreBooleanProperty(LoaderProperties.OPTION_FORCE_UPDATE, false))
{
int updateCheckInterval = this.properties.getIntegerProperty(LoaderProperties.OPTION_UPDATE_CHECK_INTR) + 1;
LiteLoaderLogger.debug("Force update is TRUE, updateCheckInterval = %d", updateCheckInterval);
if (updateCheckInterval > 10)
{
LiteLoaderLogger.debug("Forcing update check!");
this.checkForUpdate = true;
updateCheckInterval = 0;
}
this.properties.setIntegerProperty(LoaderProperties.OPTION_UPDATE_CHECK_INTR, updateCheckInterval);
this.properties.writeProperties();
}
}
@Override
public void init(LiteLoaderMods mods, ConfigManager configManager)
{
this.mods = mods;
this.configManager = configManager;
}
@Override
public void onStartupComplete()
{
if (this.checkForUpdate)
{
LiteLoaderVersion.getUpdateSite().beginUpdateCheck();
}
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.TickObserver
* #onTick(boolean, float, boolean)
*/
@Override
public void onTick(boolean clock, float partialTicks, boolean inGame)
{
if (clock && this.panelHost != null && this.minecraft.currentScreen != this.panelHost)
{
this.panelHost.updateScreen();
}
if (clock && this.checkForUpdate)
{
LiteLoaderUpdateSite updateSite = LiteLoaderVersion.getUpdateSite();
if (!updateSite.isCheckInProgress() && updateSite.isCheckComplete())
{
LiteLoaderLogger.debug("Scheduled update check completed, success=%s", updateSite.isCheckSucceess());
this.checkForUpdate = false;
if (updateSite.isCheckSucceess() && updateSite.isUpdateAvailable())
{
this.setNotification(I18n.format("gui.notifications.updateavailable"));
}
}
}
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.PostRenderObserver
* #onPostRender(int, int, float)
*/
@Override
public void onPostRender(int mouseX, int mouseY, float partialTicks)
{
if (this.mods == null) return;
boolean tabHidden = this.isTabHidden() && this.minecraft.currentScreen instanceof GuiMainMenu;
if (this.isPanelSupportedOnScreen(this.minecraft.currentScreen)
&& ((this.displayModInfoScreenTab && !tabHidden) || (this.panelHost != null && this.panelHost.isOpen())))
{
// If we're at the main menu, prepare the overlay
if (this.panelHost == null || this.panelHost.getScreen() != this.minecraft.currentScreen)
{
this.panelHost = new GuiLiteLoaderPanel(this.minecraft, this.minecraft.currentScreen, this.mods, this.environment, this.properties,
this.configManager, !tabHidden);
if (this.notification != null)
{
this.panelHost.setNotification(this.notification);
}
}
this.minecraft.entityRenderer.setupOverlayRendering();
this.panelHost.drawScreen(mouseX, mouseY, partialTicks, this.tabAlwaysExpanded);
}
else if (this.minecraft.currentScreen != this.panelHost && this.panelHost != null)
{
// If we're in any other screen, kill the overlay
this.panelHost.release();
this.panelHost = null;
}
else if (this.isPanelSupportedOnScreen(this.minecraft.currentScreen)
&& Keyboard.isKeyDown(Keyboard.KEY_LCONTROL)
&& Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)
&& Keyboard.isKeyDown(Keyboard.KEY_TAB))
{
this.displayLiteLoaderPanel(this.minecraft.currentScreen);
}
}
/**
* Set the "mod info" screen tab to hidden, regardless of the property
* setting.
*/
@Override
public void hideTab()
{
this.hideModInfoScreenTab = true;
}
private boolean isTabHidden()
{
return this.hideModInfoScreenTab && this.getStartupErrorCount() == 0 && this.notification == null;
}
/**
* Set whether the "mod info" screen tab should be shown in the main menu
*/
@Override
public void setTabVisible(boolean show)
{
this.displayModInfoScreenTab = show;
this.properties.setBooleanProperty(LoaderProperties.OPTION_MOD_INFO_SCREEN, show);
this.properties.writeProperties();
}
/**
* Get whether the "mod info" screen tab is shown in the main menu
*/
@Override
public boolean isTabVisible()
{
return this.displayModInfoScreenTab;
}
@Override
public void setTabAlwaysExpanded(boolean expand)
{
this.tabAlwaysExpanded = expand;
this.properties.setBooleanProperty(LoaderProperties.OPTION_NO_HIDE_TAB, expand);
this.properties.writeProperties();
}
@Override
public boolean isTabAlwaysExpanded()
{
return this.tabAlwaysExpanded;
}
@Override
public void setForceUpdateEnabled(boolean forceUpdate)
{
this.properties.setBooleanProperty(LoaderProperties.OPTION_FORCE_UPDATE, forceUpdate);
this.properties.writeProperties();
}
@Override
public boolean isForceUpdateEnabled()
{
return this.properties.getBooleanProperty(LoaderProperties.OPTION_FORCE_UPDATE);
}
/**
* Display the liteloader panel over the specified GUI
*
* @param parentScreen
*/
@Override
public void displayLiteLoaderPanel(GuiScreen parentScreen)
{
if (this.isPanelSupportedOnScreen(parentScreen))
{
this.panelHost = new GuiLiteLoaderPanel(this.minecraft, parentScreen, this.mods, this.environment, this.properties,
this.configManager, !this.isTabHidden());
this.minecraft.displayGuiScreen(this.panelHost);
}
}
@Override
public int getStartupErrorCount()
{
return this.mods.getStartupErrorCount();
}
@Override
public int getCriticalErrorCount()
{
return this.mods.getCriticalErrorCount();
}
@Override
public void setNotification(String notification)
{
LiteLoaderLogger.debug("Setting notification: " + notification);
this.notification = notification;
if (this.panelHost != null)
{
this.panelHost.setNotification(notification);
}
}
private boolean isPanelSupportedOnScreen(GuiScreen guiScreen)
{
return (guiScreen instanceof GuiMainMenu || guiScreen instanceof GuiIngameMenu || guiScreen instanceof GuiOptions);
}
}

View file

@ -0,0 +1,262 @@
package com.mumfrey.liteloader.client;
import com.mojang.realmsclient.dto.RealmsServer;
import com.mumfrey.liteloader.*;
import com.mumfrey.liteloader.common.ducks.IChatPacket;
import com.mumfrey.liteloader.common.transformers.PacketEventInfo;
import com.mumfrey.liteloader.core.ClientPluginChannels;
import com.mumfrey.liteloader.core.InterfaceRegistrationDelegate;
import com.mumfrey.liteloader.core.LiteLoader;
import com.mumfrey.liteloader.core.LiteLoaderEventBroker.ReturnValue;
import com.mumfrey.liteloader.core.PacketEvents;
import com.mumfrey.liteloader.core.event.EventCancellationException;
import com.mumfrey.liteloader.core.event.HandlerList;
import com.mumfrey.liteloader.core.event.HandlerList.ReturnLogicOp;
import com.mumfrey.liteloader.core.runtime.Packets;
import com.mumfrey.liteloader.interfaces.FastIterableDeque;
import com.mumfrey.liteloader.util.ChatUtilities;
import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
import net.minecraft.client.Minecraft;
import net.minecraft.network.INetHandler;
import net.minecraft.network.Packet;
import net.minecraft.network.login.INetHandlerLoginClient;
import net.minecraft.network.login.server.S02PacketLoginSuccess;
import net.minecraft.network.play.INetHandlerPlayClient;
import net.minecraft.network.play.server.S01PacketJoinGame;
import net.minecraft.network.play.server.S02PacketChat;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.IChatComponent;
import net.minecraft.util.IThreadListener;
/**
* Client-side packet event handlers
*
* @author Adam Mummery-Smith
*/
public class PacketEventsClient extends PacketEvents
{
private static RealmsServer joiningRealm;
private FastIterableDeque<JoinGameListener> joinGameListeners = new HandlerList<JoinGameListener>(JoinGameListener.class);
private FastIterableDeque<ChatListener> chatListeners = new HandlerList<ChatListener>(ChatListener.class);
private FastIterableDeque<ChatFilter> chatFilters = new HandlerList<ChatFilter>(ChatFilter.class,
ReturnLogicOp.AND_BREAK_ON_FALSE);
private FastIterableDeque<PreJoinGameListener> preJoinGameListeners = new HandlerList<PreJoinGameListener>(PreJoinGameListener.class,
ReturnLogicOp.AND_BREAK_ON_FALSE);
private FastIterableDeque<PostLoginListener> postLoginListeners = new HandlerList<PostLoginListener>(PostLoginListener.class);
@Override
public void registerInterfaces(InterfaceRegistrationDelegate delegate)
{
super.registerInterfaces(delegate);
delegate.registerInterface(JoinGameListener.class);
delegate.registerInterface(ChatListener.class);
delegate.registerInterface(ChatFilter.class);
delegate.registerInterface(PreJoinGameListener.class);
delegate.registerInterface(PostLoginListener.class);
}
/**
* @param joinGameListener
*/
public void registerJoinGameListener(JoinGameListener joinGameListener)
{
this.joinGameListeners.add(joinGameListener);
}
/**
* @param chatFilter
*/
public void registerChatFilter(ChatFilter chatFilter)
{
this.chatFilters.add(chatFilter);
}
/**
* @param chatListener
*/
public void registerChatListener(ChatListener chatListener)
{
if (chatListener instanceof ChatFilter)
{
LiteLoaderLogger.warning("Interface error initialising mod '%1s'. A mod implementing ChatFilter and ChatListener is not supported! "
+ "Remove one of these interfaces", chatListener.getName());
}
else
{
this.chatListeners.add(chatListener);
}
}
/**
* @param joinGameListener
*/
public void registerPreJoinGameListener(PreJoinGameListener joinGameListener)
{
this.preJoinGameListeners.add(joinGameListener);
}
/**
* @param postLoginListener
*/
public void registerPostLoginListener(PostLoginListener postLoginListener)
{
this.postLoginListeners.add(postLoginListener);
}
public static void onJoinRealm(long serverId, RealmsServer server)
{
PacketEventsClient.joiningRealm = server;
}
@Override
protected IThreadListener getPacketContextListener(Packets.Context context)
{
if (context == Packets.Context.SERVER)
{
return MinecraftServer.getServer();
}
return Minecraft.getMinecraft();
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.core.PacketEvents#handlePacket(
* com.mumfrey.liteloader.common.transformers.PacketEventInfo,
* net.minecraft.network.INetHandler,
* net.minecraft.network.play.server.S01PacketJoinGame)
*/
@Override
protected void handlePacket(PacketEventInfo<Packet> e, INetHandler netHandler, S01PacketJoinGame packet)
{
if (this.preJoinGame(e, netHandler, packet))
{
return;
}
((INetHandlerPlayClient)netHandler).handleJoinGame(packet);
super.handlePacket(e, netHandler, packet);
this.postJoinGame(e, netHandler, packet);
}
/**
* @param e
* @param netHandler
* @param packet
* @throws EventCancellationException
*/
private boolean preJoinGame(PacketEventInfo<Packet> e, INetHandler netHandler, S01PacketJoinGame packet) throws EventCancellationException
{
if (!(netHandler instanceof INetHandlerPlayClient))
{
return true;
}
e.cancel();
return !this.preJoinGameListeners.all().onPreJoinGame(netHandler, packet);
}
/**
* @param e
* @param netHandler
* @param packet
*/
private void postJoinGame(PacketEventInfo<Packet> e, INetHandler netHandler, S01PacketJoinGame packet)
{
this.joinGameListeners.all().onJoinGame(netHandler, packet, Minecraft.getMinecraft().getCurrentServerData(), PacketEventsClient.joiningRealm);
PacketEventsClient.joiningRealm = null;
ClientPluginChannels clientPluginChannels = LiteLoader.getClientPluginChannels();
if (clientPluginChannels instanceof ClientPluginChannelsClient)
{
((ClientPluginChannelsClient)clientPluginChannels).onJoinGame(netHandler, packet);
}
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.core.PacketEvents#handlePacket(
* com.mumfrey.liteloader.common.transformers.PacketEventInfo,
* net.minecraft.network.INetHandler,
* net.minecraft.network.login.server.S02PacketLoginSuccess)
*/
@Override
protected void handlePacket(PacketEventInfo<Packet> e, INetHandler netHandler, S02PacketLoginSuccess packet)
{
if (netHandler instanceof INetHandlerLoginClient)
{
INetHandlerLoginClient netHandlerLoginClient = (INetHandlerLoginClient)netHandler;
ClientPluginChannels clientPluginChannels = LiteLoader.getClientPluginChannels();
if (clientPluginChannels instanceof ClientPluginChannelsClient)
{
((ClientPluginChannelsClient)clientPluginChannels).onPostLogin(netHandlerLoginClient, packet);
}
this.postLoginListeners.all().onPostLogin(netHandlerLoginClient, packet);
}
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.core.PacketEvents#handlePacket(
* com.mumfrey.liteloader.common.transformers.PacketEventInfo,
* net.minecraft.network.INetHandler,
* net.minecraft.network.play.server.S02PacketChat)
*/
@Override
protected void handlePacket(PacketEventInfo<Packet> e, INetHandler netHandler, S02PacketChat packet)
{
if (packet.getChatComponent() == null)
{
return;
}
IChatComponent originalChat = packet.getChatComponent();
IChatComponent chat = originalChat;
String message = chat.getFormattedText();
// Chat filters get a stab at the chat first, if any filter returns false the chat is discarded
for (ChatFilter chatFilter : this.chatFilters)
{
ReturnValue<IChatComponent> ret = new ReturnValue<IChatComponent>();
if (chatFilter.onChat(chat, message, ret))
{
if (ret.isSet())
{
chat = ret.get();
if (chat == null)
{
chat = new ChatComponentText("");
}
message = chat.getFormattedText();
}
}
else
{
e.cancel();
return;
}
}
if (chat != originalChat)
{
try
{
chat = ChatUtilities.convertLegacyCodes(chat);
((IChatPacket)packet).setChatComponent(chat);
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
// Chat listeners get the chat if no filter removed it
this.chatListeners.all().onChat(chat, message);
}
}

View file

@ -0,0 +1,117 @@
package com.mumfrey.liteloader.client;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.IResourcePack;
import com.mumfrey.liteloader.LiteMod;
import com.mumfrey.liteloader.api.ModLoadObserver;
import com.mumfrey.liteloader.common.Resources;
import com.mumfrey.liteloader.core.LiteLoader;
import com.mumfrey.liteloader.core.ModInfo;
import com.mumfrey.liteloader.interfaces.LoadableMod;
import com.mumfrey.liteloader.resources.ModResourcePack;
import com.mumfrey.liteloader.resources.ModResourcePackDir;
import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
/**
* Observer which handles registering mods on the client as resource packs
*
* @author Adam Mummery-Smith
*/
public class ResourceObserver implements ModLoadObserver
{
private final Map<String, IResourcePack> resourcePacks = new HashMap<String, IResourcePack>();
public ResourceObserver()
{
}
@Override
public void onModLoaded(LiteMod mod)
{
}
@SuppressWarnings("unchecked")
@Override
public void onPostModLoaded(ModInfo<LoadableMod<?>> handle)
{
if (!handle.hasContainer()) return;
LoadableMod<?> container = handle.getContainer();
String modName = handle.getMod().getName();
if (modName == null) return;
if (container.hasResources())
{
LiteLoaderLogger.info("Adding \"%s\" to active resource pack set", container.getLocation());
IResourcePack resourcePack = this.initResourcePack(container, modName);
Resources<IResourceManager, IResourcePack> resources
= (Resources<IResourceManager, IResourcePack>)LiteLoader.getGameEngine().getResources();
if (resources.registerResourcePack(resourcePack))
{
LiteLoaderLogger.info("Successfully added \"%s\" to active resource pack set", container.getLocation());
}
}
}
public IResourcePack initResourcePack(LoadableMod<?> container, String name)
{
IResourcePack resourcePack = this.getResourcePack(container);
if (resourcePack == null)
{
if (container.isDirectory())
{
LiteLoaderLogger.info("Setting up \"%s/%s\" as mod resource pack with identifier \"%s\"",
container.toFile().getParentFile().getName(), container.getName(), name);
resourcePack = new ModResourcePackDir(name, container.toFile());
}
else
{
LiteLoaderLogger.info("Setting up \"%s\" as mod resource pack with identifier \"%s\"", container.getName(), name);
resourcePack = new ModResourcePack(name, container.toFile());
}
this.setResourcePack(container, resourcePack);
}
return resourcePack;
}
private IResourcePack getResourcePack(LoadableMod<?> container)
{
String path = container.getLocation();
return this.resourcePacks.get(path);
}
private void setResourcePack(LoadableMod<?> container, IResourcePack resourcePack)
{
String path = container.getLocation();
this.resourcePacks.put(path, resourcePack);
}
@Override
public void onModLoadFailed(LoadableMod<?> container, String identifier, String reason, Throwable th)
{
}
@Override
public void onPreInitMod(LiteMod mod)
{
}
@Override
public void onPostInitMod(LiteMod mod)
{
}
@Override
public void onMigrateModConfig(LiteMod mod, File newConfigPath, File oldConfigPath)
{
}
}

View file

@ -0,0 +1,95 @@
package com.mumfrey.liteloader.client;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.IResourcePack;
import com.mumfrey.liteloader.client.overlays.IMinecraft;
import com.mumfrey.liteloader.common.LoadingProgress;
import com.mumfrey.liteloader.common.Resources;
public class ResourcesClient implements Resources<IResourceManager, IResourcePack>
{
private final Minecraft engine = Minecraft.getMinecraft();
/**
* Registered resource packs
*/
private final Map<String, IResourcePack> registeredResourcePacks = new HashMap<String, IResourcePack>();
/**
* True while initialising mods if we need to do a resource manager reload
* once the process is completed.
*/
private boolean pendingResourceReload;
/* (non-Javadoc)
* @see com.mumfrey.liteloader.common.GameEngine#refreshResources(boolean)
*/
@Override
public void refreshResources(boolean force)
{
if (this.pendingResourceReload || force)
{
LoadingProgress.setMessage("Reloading Resources...");
this.pendingResourceReload = false;
this.engine.refreshResources();
}
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.common.GameEngine#getResourceManager()
*/
@Override
public IResourceManager getResourceManager()
{
return this.engine.getResourceManager();
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.common.GameEngine#registerResourcePack(
* net.minecraft.client.resources.IResourcePack)
*/
@Override
public boolean registerResourcePack(IResourcePack resourcePack)
{
if (!this.registeredResourcePacks.containsKey(resourcePack.getPackName()))
{
this.pendingResourceReload = true;
List<IResourcePack> defaultResourcePacks = ((IMinecraft)this.engine).getDefaultResourcePacks();
if (!defaultResourcePacks.contains(resourcePack))
{
defaultResourcePacks.add(resourcePack);
this.registeredResourcePacks.put(resourcePack.getPackName(), resourcePack);
return true;
}
}
return false;
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.common.GameEngine#unRegisterResourcePack(
* net.minecraft.client.resources.IResourcePack)
*/
@Override
public boolean unRegisterResourcePack(IResourcePack resourcePack)
{
if (this.registeredResourcePacks.containsValue(resourcePack))
{
this.pendingResourceReload = true;
List<IResourcePack> defaultResourcePacks = ((IMinecraft)this.engine).getDefaultResourcePacks();
this.registeredResourcePacks.remove(resourcePack.getPackName());
defaultResourcePacks.remove(resourcePack);
return true;
}
return false;
}
}

View file

@ -0,0 +1,129 @@
package com.mumfrey.liteloader.client;
import java.util.List;
import com.mumfrey.liteloader.client.ducks.IReloadable;
import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
import net.minecraft.client.audio.SoundHandler;
import net.minecraft.client.resources.IResourceManagerReloadListener;
import net.minecraft.client.resources.SimpleReloadableResourceManager;
/**
* Manager object which handles inhibiting the sound handler's reload
* notification at startup.
*
* @author Adam Mummery-Smith
*/
public class SoundHandlerReloadInhibitor
{
/**
* Resource Manager
*/
private SimpleReloadableResourceManager resourceManager;
/**
* Sound manager
*/
private SoundHandler soundHandler;
/**
* True if inhibition is currently active
*/
private boolean inhibited;
/**
* So that we can re-insert the sound manager at the same index, we store
* the index we remove it from.
*/
private int storedIndex;
SoundHandlerReloadInhibitor(SimpleReloadableResourceManager resourceManager, SoundHandler soundHandler)
{
this.resourceManager = resourceManager;
this.soundHandler = soundHandler;
}
/**
* Inhibit the sound manager reload notification
*
* @return true if inhibit was applied
*/
public boolean inhibit()
{
try
{
if (!this.inhibited)
{
List<IResourceManagerReloadListener> reloadListeners = ((IReloadable)this.resourceManager).getReloadListeners();
if (reloadListeners != null)
{
this.storedIndex = reloadListeners.indexOf(this.soundHandler);
if (this.storedIndex > -1)
{
LiteLoaderLogger.info("Inhibiting sound handler reload");
reloadListeners.remove(this.soundHandler);
this.inhibited = true;
return true;
}
}
}
}
catch (Exception ex)
{
LiteLoaderLogger.warning("Error inhibiting sound handler reload");
}
return false;
}
/**
* Remove the sound manager reload inhibit
*
* @param reload True to reload the sound manager now
* @return true if the sound manager was successfully restored
*/
public boolean unInhibit(boolean reload)
{
try
{
if (this.inhibited)
{
List<IResourceManagerReloadListener> reloadListeners = ((IReloadable)this.resourceManager).getReloadListeners();
if (reloadListeners != null)
{
if (this.storedIndex > -1)
{
reloadListeners.add(this.storedIndex, this.soundHandler);
}
else
{
reloadListeners.add(this.soundHandler);
}
LiteLoaderLogger.info("Sound handler reload inhibit removed");
if (reload)
{
LiteLoaderLogger.info("Reloading sound handler");
this.soundHandler.onResourceManagerReload(this.resourceManager);
}
this.inhibited = false;
return true;
}
}
}
catch (Exception ex)
{
LiteLoaderLogger.warning("Error removing sound handler reload inhibit");
}
return false;
}
public boolean isInhibited()
{
return this.inhibited;
}
}

View file

@ -0,0 +1,30 @@
package com.mumfrey.liteloader.client;
import net.minecraft.client.resources.I18n;
import com.mumfrey.liteloader.api.TranslationProvider;
public class Translator implements TranslationProvider
{
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.TranslationProvider#translate(
* java.lang.String, java.lang.Object[])
*/
@Override
public String translate(String key, Object... args)
{
// TODO doesn't currently honour the contract of TranslationProvider::translate, should return null if translation is missing
return I18n.format(key, args);
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.TranslationProvider#translate(
* java.lang.String, java.lang.String, java.lang.Object[])
*/
@Override
public String translate(String locale, String key, Object... args)
{
// TODO doesn't currently honour the contract of TranslationProvider::translate, should return null if translation is missing
return I18n.format(key, args);
}
}

View file

@ -0,0 +1,141 @@
package com.mumfrey.liteloader.client.api;
import java.net.URI;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.ResourceLocation;
import com.mumfrey.liteloader.api.BrandingProvider;
import com.mumfrey.liteloader.client.util.render.IconAbsolute;
import com.mumfrey.liteloader.core.LiteLoader;
import com.mumfrey.liteloader.util.render.Icon;
/**
* LiteLoader's branding provider
*
* @author Adam Mummery-Smith
*/
public class LiteLoaderBrandingProvider implements BrandingProvider
{
public static final int BRANDING_COLOUR = 0xFF4785D1;
public static final ResourceLocation ABOUT_TEXTURE = new ResourceLocation("liteloader", "textures/gui/about.png");
public static final IconAbsolute LOGO_COORDS = new IconAbsolute(LiteLoaderBrandingProvider.ABOUT_TEXTURE,
"logo", 128, 40, 0, 0, 256, 80);
public static final IconAbsolute ICON_COORDS = new IconAbsolute(LiteLoaderBrandingProvider.ABOUT_TEXTURE,
"chicken", 32, 45, 0, 80, 64, 170);
public static final IconAbsolute TWITTER_AVATAR_COORDS = new IconAbsolute(LiteLoaderBrandingProvider.ABOUT_TEXTURE,
"twitter_avatar",32, 32, 192, 80, 256, 144);
public static final URI LITELOADER_URI = URI.create("http://www.liteloader.com/");
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.BrandingProvider#getPriority()
*/
@Override
public int getPriority()
{
return -1000;
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.BrandingProvider#getDisplayName()
*/
@Override
public String getDisplayName()
{
return "LiteLoader " + I18n.format("gui.about.versiontext", LiteLoader.getVersion());
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.BrandingProvider#getCopyrightText()
*/
@Override
public String getCopyrightText()
{
return "Copyright (c) 2012-2016 Adam Mummery-Smith";
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.BrandingProvider#getHomepage()
*/
@Override
public URI getHomepage()
{
return LiteLoaderBrandingProvider.LITELOADER_URI;
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.BrandingProvider#getBrandingColour()
*/
@Override
public int getBrandingColour()
{
return LiteLoaderBrandingProvider.BRANDING_COLOUR;
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.BrandingProvider#getLogoResource()
*/
@Override
public ResourceLocation getLogoResource()
{
return LiteLoaderBrandingProvider.ABOUT_TEXTURE;
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.BrandingProvider#getLogoCoords()
*/
@Override
public Icon getLogoCoords()
{
return LiteLoaderBrandingProvider.LOGO_COORDS;
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.BrandingProvider#getIconResource()
*/
@Override
public ResourceLocation getIconResource()
{
return LiteLoaderBrandingProvider.ABOUT_TEXTURE;
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.BrandingProvider#getIconCoords()
*/
@Override
public Icon getIconCoords()
{
return LiteLoaderBrandingProvider.ICON_COORDS;
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.BrandingProvider#getTwitterUserName()
*/
@Override
public String getTwitterUserName()
{
return "therealeq2";
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.BrandingProvider
* #getTwitterAvatarResource()
*/
@Override
public ResourceLocation getTwitterAvatarResource()
{
return LiteLoaderBrandingProvider.ABOUT_TEXTURE;
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.BrandingProvider#getTwitterAvatarCoords()
*/
@Override
public Icon getTwitterAvatarCoords()
{
return LiteLoaderBrandingProvider.TWITTER_AVATAR_COORDS;
}
}

View file

@ -0,0 +1,161 @@
package com.mumfrey.liteloader.client.api;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.server.integrated.IntegratedServer;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ObjectArrays;
import com.mumfrey.liteloader.api.CoreProvider;
import com.mumfrey.liteloader.api.CustomisationProvider;
import com.mumfrey.liteloader.api.InterfaceProvider;
import com.mumfrey.liteloader.api.Observer;
import com.mumfrey.liteloader.client.LiteLoaderCoreProviderClient;
import com.mumfrey.liteloader.client.ResourceObserver;
import com.mumfrey.liteloader.client.Translator;
import com.mumfrey.liteloader.core.LiteLoader;
import com.mumfrey.liteloader.core.api.LiteLoaderCoreAPI;
import com.mumfrey.liteloader.interfaces.ObjectFactory;
import com.mumfrey.liteloader.messaging.MessageBus;
import com.mumfrey.liteloader.transformers.event.json.ModEvents;
/**
* Client side of the core API
*
* @author Adam Mummery-Smith
*/
public class LiteLoaderCoreAPIClient extends LiteLoaderCoreAPI
{
private static final String PKG_LITELOADER_CLIENT = LiteLoaderCoreAPI.PKG_LITELOADER + ".client";
private static final String[] requiredTransformers = {
LiteLoaderCoreAPI.PKG_LITELOADER + ".transformers.event.EventProxyTransformer",
LiteLoaderCoreAPI.PKG_LITELOADER + ".launch.LiteLoaderTransformer",
LiteLoaderCoreAPIClient.PKG_LITELOADER_CLIENT + ".transformers.CrashReportTransformer"
};
private static final String[] requiredDownstreamTransformers = {
LiteLoaderCoreAPI.PKG_LITELOADER_COMMON + ".transformers.LiteLoaderPacketTransformer",
LiteLoaderCoreAPIClient.PKG_LITELOADER_CLIENT + ".transformers.MinecraftTransformer",
LiteLoaderCoreAPI.PKG_LITELOADER + ".transformers.event.json.ModEventInjectionTransformer"
};
private ObjectFactory<Minecraft, IntegratedServer> objectFactory;
@Override
public String[] getMixinConfigs()
{
String[] commonConfigs = super.getMixinConfigs();
return ObjectArrays.concat(commonConfigs, new String[] {
"mixins.liteloader.client.json"
}, String.class);
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.LiteAPI#getRequiredTransformers()
*/
@Override
public String[] getRequiredTransformers()
{
return LiteLoaderCoreAPIClient.requiredTransformers;
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.LiteAPI
* #getRequiredDownstreamTransformers()
*/
@Override
public String[] getRequiredDownstreamTransformers()
{
return LiteLoaderCoreAPIClient.requiredDownstreamTransformers;
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.LiteAPI#getCustomisationProviders()
*/
@Override
public List<CustomisationProvider> getCustomisationProviders()
{
return ImmutableList.<CustomisationProvider>of
(
new LiteLoaderBrandingProvider(),
new LiteLoaderModInfoDecorator(),
new Translator()
);
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.LiteAPI#getCoreProviders()
*/
@Override
public List<CoreProvider> getCoreProviders()
{
return ImmutableList.<CoreProvider>of
(
new LiteLoaderCoreProviderClient(this.properties),
LiteLoader.getInput()
);
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.LiteAPI#getInterfaceProviders()
*/
@Override
public List<InterfaceProvider> getInterfaceProviders()
{
ObjectFactory<?, ?> objectFactory = this.getObjectFactory();
return ImmutableList.<InterfaceProvider>of
(
objectFactory.getEventBroker(),
objectFactory.getPacketEventBroker(),
objectFactory.getClientPluginChannels(),
objectFactory.getServerPluginChannels(),
MessageBus.getInstance()
);
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.LiteAPI#getPreInitObservers()
*/
@Override
public List<Observer> getPreInitObservers()
{
return ImmutableList.<Observer>of
(
new ModEvents()
);
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.LiteAPI#getObservers()
*/
@Override
public List<Observer> getObservers()
{
ObjectFactory<?, ?> objectFactory = this.getObjectFactory();
return ImmutableList.<Observer>of
(
new ResourceObserver(),
objectFactory.getPanelManager(),
objectFactory.getEventBroker()
);
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.core.api.LiteLoaderCoreAPI#getObjectFactory()
*/
@Override
public ObjectFactory<?, ?> getObjectFactory()
{
if (this.objectFactory == null)
{
this.objectFactory = new ObjectFactoryClient(this.environment, this.properties);
}
return this.objectFactory;
}
}

View file

@ -0,0 +1,138 @@
package com.mumfrey.liteloader.client.api;
import java.util.List;
import net.minecraft.client.resources.I18n;
import com.mumfrey.liteloader.api.ModInfoDecorator;
import com.mumfrey.liteloader.client.gui.GuiLiteLoaderPanel;
import com.mumfrey.liteloader.client.gui.modlist.GuiModListPanel;
import com.mumfrey.liteloader.client.util.render.IconAbsolute;
import com.mumfrey.liteloader.client.util.render.IconAbsoluteClickable;
import com.mumfrey.liteloader.core.ModInfo;
import com.mumfrey.liteloader.util.render.IconTextured;
/**
* ModInfo decorator
*
* @author Adam Mummery-Smith
*/
public class LiteLoaderModInfoDecorator implements ModInfoDecorator
{
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.ModInfoDecorator
* #addIcons(com.mumfrey.liteloader.core.ModInfo, java.util.List)
*/
@Override
public void addIcons(final ModInfo<?> mod, List<IconTextured> icons)
{
if (mod.hasTweakClass())
{
icons.add(new IconAbsoluteClickable(LiteLoaderBrandingProvider.ABOUT_TEXTURE,
I18n.format("gui.mod.providestweak"), 12, 12, 158, 80, 170, 92)
{
@Override
public void onClicked(Object source, Object container)
{
if (container instanceof GuiModListPanel)
{
((GuiModListPanel)container).displayModHelpMessage(mod, "gui.mod.providestweak", "gui.mod.help.tweak");
}
}
});
}
if (mod.hasEventTransformers())
{
icons.add(new IconAbsoluteClickable(LiteLoaderBrandingProvider.ABOUT_TEXTURE,
I18n.format("gui.mod.providesevents"), 12, 12, 170, 92, 182, 104)
{
@Override
public void onClicked(Object source, Object container)
{
if (container instanceof GuiModListPanel)
{
((GuiModListPanel)container).displayModHelpMessage(mod, "gui.mod.providesevents", "gui.mod.help.events");
}
}
});
}
if (mod.hasClassTransformers())
{
icons.add(new IconAbsoluteClickable(LiteLoaderBrandingProvider.ABOUT_TEXTURE,
I18n.format("gui.mod.providestransformer"), 12, 12, 170, 80, 182, 92)
{
@Override
public void onClicked(Object source, Object container)
{
if (container instanceof GuiModListPanel)
{
((GuiModListPanel)container).displayModHelpMessage(mod, "gui.mod.providestransformer", "gui.mod.help.transformer");
}
}
});
}
if (mod.hasMixins())
{
icons.add(new IconAbsoluteClickable(LiteLoaderBrandingProvider.ABOUT_TEXTURE,
I18n.format("gui.mod.providesmixins"), 12, 12, 122, 104, 134, 116)
{
@Override
public void onClicked(Object source, Object container)
{
if (container instanceof GuiModListPanel)
{
((GuiModListPanel)container).displayModHelpMessage(mod, "gui.mod.providesmixins", "gui.mod.help.mixins");
}
}
});
}
if (mod.usesAPI())
{
icons.add(new IconAbsolute(LiteLoaderBrandingProvider.ABOUT_TEXTURE,
I18n.format("gui.mod.usingapi"), 12, 12, 122, 92, 134, 104));
}
List<Throwable> startupErrors = mod.getStartupErrors();
if (startupErrors != null && startupErrors.size() > 0)
{
icons.add(new IconAbsoluteClickable(LiteLoaderBrandingProvider.ABOUT_TEXTURE,
I18n.format("gui.mod.startuperror", startupErrors.size()), 12, 12, 134, 92, 146, 104)
{
@Override
public void onClicked(Object source, Object container)
{
if (source instanceof GuiLiteLoaderPanel)
{
((GuiLiteLoaderPanel)source).showErrorPanel(mod);
}
}
});
}
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.ModInfoDecorator
* #modifyStatusText(com.mumfrey.liteloader.core.ModInfo,
* java.lang.String)
*/
@Override
public String modifyStatusText(ModInfo<?> mod, String statusText)
{
return null;
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.api.ModInfoDecorator
* #onDrawListEntry(int, int, float, int, int, int, int, boolean,
* com.mumfrey.liteloader.core.ModInfo, int, int, int)
*/
@Override
public void onDrawListEntry(int mouseX, int mouseY, float partialTicks, int xPosition, int yPosition, int width, int height, boolean selected,
ModInfo<?> mod, int gradientColour, int titleColour, int statusColour)
{
}
}

View file

@ -0,0 +1,164 @@
package com.mumfrey.liteloader.client.api;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.launchwrapper.Launch;
import net.minecraft.server.integrated.IntegratedServer;
import com.mumfrey.liteloader.client.LiteLoaderEventBrokerClient;
import com.mumfrey.liteloader.client.ClientPluginChannelsClient;
import com.mumfrey.liteloader.client.GameEngineClient;
import com.mumfrey.liteloader.client.LiteLoaderPanelManager;
import com.mumfrey.liteloader.client.PacketEventsClient;
import com.mumfrey.liteloader.client.gui.startup.LoadingBar;
import com.mumfrey.liteloader.common.GameEngine;
import com.mumfrey.liteloader.core.ClientPluginChannels;
import com.mumfrey.liteloader.core.LiteLoaderEventBroker;
import com.mumfrey.liteloader.core.LiteLoader;
import com.mumfrey.liteloader.core.PacketEvents;
import com.mumfrey.liteloader.core.ServerPluginChannels;
import com.mumfrey.liteloader.interfaces.PanelManager;
import com.mumfrey.liteloader.interfaces.ObjectFactory;
import com.mumfrey.liteloader.launch.LoaderEnvironment;
import com.mumfrey.liteloader.launch.LoaderProperties;
import com.mumfrey.liteloader.permissions.PermissionsManagerClient;
import com.mumfrey.liteloader.permissions.PermissionsManagerServer;
import com.mumfrey.liteloader.util.Input;
import com.mumfrey.liteloader.util.InputManager;
/**
* Factory for lifetime loader objects for the client side
*
* @author Adam Mummery-Smith
*/
class ObjectFactoryClient implements ObjectFactory<Minecraft, IntegratedServer>
{
private LoaderEnvironment environment;
private LoaderProperties properties;
private Input input;
private LiteLoaderEventBrokerClient clientEvents;
private PacketEventsClient clientPacketEvents;
private GameEngineClient engine;
private PanelManager<GuiScreen> modPanelManager;
private ClientPluginChannelsClient clientPluginChannels;
private ServerPluginChannels serverPluginChannels;
ObjectFactoryClient(LoaderEnvironment environment, LoaderProperties properties)
{
this.environment = environment;
this.properties = properties;
}
@Override
public Input getInput()
{
if (this.input == null)
{
this.input = new InputManager(this.environment, this.properties);
}
return this.input;
}
@Override
public LiteLoaderEventBroker<Minecraft, IntegratedServer> getEventBroker()
{
if (this.clientEvents == null)
{
this.clientEvents = new LiteLoaderEventBrokerClient(LiteLoader.getInstance(), (GameEngineClient)this.getGameEngine(), this.properties);
}
return this.clientEvents;
}
@Override
public PacketEvents getPacketEventBroker()
{
if (this.clientPacketEvents == null)
{
this.clientPacketEvents = new PacketEventsClient();
}
return this.clientPacketEvents;
}
@Override
public GameEngine<Minecraft, IntegratedServer> getGameEngine()
{
if (this.engine == null)
{
this.engine = new GameEngineClient();
}
return this.engine;
}
@Override
public PanelManager<GuiScreen> getPanelManager()
{
if (this.modPanelManager == null)
{
this.modPanelManager = new LiteLoaderPanelManager(this.getGameEngine(), this.environment, this.properties);
}
return this.modPanelManager;
}
@Override
public ClientPluginChannels getClientPluginChannels()
{
if (this.clientPluginChannels == null)
{
this.clientPluginChannels = new ClientPluginChannelsClient();
}
return this.clientPluginChannels;
}
@Override
public ServerPluginChannels getServerPluginChannels()
{
if (this.serverPluginChannels == null)
{
this.serverPluginChannels = new ServerPluginChannels();
}
return this.serverPluginChannels;
}
@Override
public PermissionsManagerClient getClientPermissionManager()
{
return PermissionsManagerClient.getInstance();
}
@Override
public PermissionsManagerServer getServerPermissionManager()
{
return null;
}
@SuppressWarnings("unused")
@Override
public void preBeginGame()
{
try
{
Class<?> progressManagerClass = Class.forName("net.minecraftforge.fml.common.ProgressManager", false, Launch.classLoader);
return; // Disable my loading bar if Forge's is present
}
catch (ClassNotFoundException ex)
{
}
new LoadingBar();
}
}

View file

@ -0,0 +1,8 @@
package com.mumfrey.liteloader.client.ducks;
import net.minecraft.network.NetworkManager;
public interface IClientNetLoginHandler
{
public abstract NetworkManager getNetMgr();
}

View file

@ -0,0 +1,8 @@
package com.mumfrey.liteloader.client.ducks;
public interface IFramebuffer
{
public abstract IFramebuffer setDispatchRenderEvent(boolean dispatchRenderEvent);
public abstract boolean isDispatchRenderEvent();
}

View file

@ -0,0 +1,6 @@
package com.mumfrey.liteloader.client.ducks;
public interface INamespacedRegistry
{
public abstract IObjectIntIdentityMap getUnderlyingMap();
}

View file

@ -0,0 +1,11 @@
package com.mumfrey.liteloader.client.ducks;
import java.util.IdentityHashMap;
import java.util.List;
public interface IObjectIntIdentityMap
{
public abstract <V> IdentityHashMap<V, Integer> getIdentityMap();
public abstract <V> List<V> getObjectList();
}

View file

@ -0,0 +1,8 @@
package com.mumfrey.liteloader.client.ducks;
import java.util.Map;
public interface IRegistrySimple
{
public abstract <K, V> Map<K, V> getRegistryObjects();
}

View file

@ -0,0 +1,10 @@
package com.mumfrey.liteloader.client.ducks;
import java.util.List;
import net.minecraft.client.resources.IResourceManagerReloadListener;
public interface IReloadable
{
public abstract List<IResourceManagerReloadListener> getReloadListeners();
}

View file

@ -0,0 +1,11 @@
package com.mumfrey.liteloader.client.ducks;
import java.util.Map;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.entity.Entity;
public interface IRenderManager
{
public abstract Map<Class<? extends Entity>, Render> getRenderMap();
}

View file

@ -0,0 +1,11 @@
package com.mumfrey.liteloader.client.ducks;
import java.util.Map;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.tileentity.TileEntity;
public interface ITileEntityRendererDispatcher
{
public abstract Map<Class<? extends TileEntity>, TileEntitySpecialRenderer> getSpecialRenderMap();
}

View file

@ -0,0 +1,51 @@
package com.mumfrey.liteloader.client.gui;
import static com.mumfrey.liteloader.gl.GL.*;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import com.mumfrey.liteloader.client.api.LiteLoaderBrandingProvider;
/**
* Super-simple implementation of a checkbox control
*
* @author Adam Mummery-Smith
*/
public class GuiCheckbox extends GuiButton
{
public boolean checked;
public GuiCheckbox(int controlId, int xPosition, int yPosition, String displayString)
{
super(controlId, xPosition, yPosition, Minecraft.getMinecraft().fontRendererObj.getStringWidth(displayString) + 16, 12, displayString);
}
@Override
public void drawButton(Minecraft minecraft, int mouseX, int mouseY)
{
if (this.visible)
{
minecraft.getTextureManager().bindTexture(LiteLoaderBrandingProvider.ABOUT_TEXTURE);
glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
this.hovered = mouseX >= this.xPosition
&& mouseY >= this.yPosition
&& mouseX < this.xPosition + this.width
&& mouseY < this.yPosition + this.height;
this.drawTexturedModalRect(this.xPosition, this.yPosition, this.checked ? 134 : 122, 80, 12, 12);
this.mouseDragged(minecraft, mouseX, mouseY);
int colour = 0xE0E0E0;
if (!this.enabled)
{
colour = 0xA0A0A0;
}
else if (this.hovered)
{
colour = 0xFFFFA0;
}
this.drawString(minecraft.fontRendererObj, this.displayString, this.xPosition + 16, this.yPosition + 2, colour);
}
}
}

View file

@ -0,0 +1,55 @@
package com.mumfrey.liteloader.client.gui;
import com.mumfrey.liteloader.client.api.LiteLoaderBrandingProvider;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
public class GuiHoverLabel extends GuiButton
{
private FontRenderer fontRenderer;
private int colour;
private int hoverColour;
public GuiHoverLabel(int id, int xPosition, int yPosition, FontRenderer fontRenderer, String displayText)
{
this(id, xPosition, yPosition, fontRenderer, displayText, LiteLoaderBrandingProvider.BRANDING_COLOUR);
}
public GuiHoverLabel(int id, int xPosition, int yPosition, FontRenderer fontRenderer, String displayText, int colour)
{
this(id, xPosition, yPosition, fontRenderer, displayText, colour, 0xFFFFFFAA);
}
public GuiHoverLabel(int id, int xPosition, int yPosition, FontRenderer fontRenderer, String displayText, int colour, int hoverColour)
{
super(id, xPosition, yPosition, GuiHoverLabel.getStringWidth(fontRenderer, displayText), 8, displayText);
this.fontRenderer = fontRenderer;
this.colour = colour;
this.hoverColour = hoverColour;
}
@Override
public void drawButton(Minecraft minecraft, int mouseX, int mouseY)
{
if (this.visible)
{
this.hovered = mouseX >= this.xPosition
&& mouseY >= this.yPosition
&& mouseX < this.xPosition + this.width
&& mouseY < this.yPosition + this.height;
this.fontRenderer.drawString(this.displayString, this.xPosition, this.yPosition, this.hovered ? this.hoverColour : this.colour);
}
else
{
this.hovered = false;
}
}
private static int getStringWidth(FontRenderer fontRenderer, String text)
{
return fontRenderer.getStringWidth(text);
}
}

View file

@ -0,0 +1,815 @@
package com.mumfrey.liteloader.client.gui;
import static com.mumfrey.liteloader.gl.GL.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiMainMenu;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import com.mumfrey.liteloader.LiteMod;
import com.mumfrey.liteloader.api.BrandingProvider;
import com.mumfrey.liteloader.api.LiteAPI;
import com.mumfrey.liteloader.api.ModInfoDecorator;
import com.mumfrey.liteloader.client.api.LiteLoaderBrandingProvider;
import com.mumfrey.liteloader.core.LiteLoader;
import com.mumfrey.liteloader.core.LiteLoaderMods;
import com.mumfrey.liteloader.core.LiteLoaderVersion;
import com.mumfrey.liteloader.core.ModInfo;
import com.mumfrey.liteloader.core.api.LiteLoaderCoreAPI;
import com.mumfrey.liteloader.launch.LoaderEnvironment;
import com.mumfrey.liteloader.launch.LoaderProperties;
import com.mumfrey.liteloader.modconfig.ConfigManager;
import com.mumfrey.liteloader.modconfig.ConfigPanel;
import com.mumfrey.liteloader.util.render.Icon;
/**
* GUI screen which displays info about loaded mods and also allows them to be
* enabled and disabled. An instance of this class is created every time the
* main menu is displayed and is drawn as an overlay until the tab is clicked,
* at which point it becomes the active GUI screen and draws the parent main
* menu screen as its background to give the appearance of being overlaid on the
* main menu.
*
* @author Adam Mummery-Smith
*/
public class GuiLiteLoaderPanel extends GuiScreen
{
static final int WHITE = 0xFFFFFFFF;
static final int OPAQUE = 0xFF000000;
static final int NOTIFICATION_TOOLTIP_FOREGROUND = 0xFFFFFF;
static final int NOTIFICATION_TOOLTIP_BACKGROUND = 0xB0000099;
static final int ERROR_TOOLTIP_FOREGROUND = 0xFF5555;
static final int ERROR_TOOLTIP_BACKGROUND = 0xB0330000;
static final int HEADER_HR_COLOUR = 0xFF999999;
static final int HEADER_TEXT_COLOUR = GuiLiteLoaderPanel.WHITE;
static final int HEADER_TEXT_COLOUR_SUB = 0xFFAAAAAA;
static final int TOOLTIP_FOREGROUND = 0xFFFFFF;
static final int TOOLTIP_FOREGROUND_SUB = 0xCCCCCC;
static final int TOOLTIP_BACKGROUND = 0xB0000000;
static final int LEFT_EDGE = 80;
static final int MARGIN = 12;
static final int TAB_WIDTH = 20;
static final int TAB_HEIGHT = 40;
static final int TAB_TOP = 20;
static final int PANEL_TOP = 83;
static final int PANEL_BOTTOM = 26;
private static final double TWEEN_RATE = 0.08;
private static boolean displayErrorToolTip = true;
/**
* Reference to the main menu which this screen is either overlaying or
* using as its background.
*/
private GuiScreen parentScreen;
@SuppressWarnings("unused")
private final LoaderEnvironment environment;
private final LoaderProperties properties;
/**
* Tick number (update counter) used for tweening
*/
private long tickNumber;
/**
* Last tick number, for tweening
*/
private double lastTick;
/**
* Current tween percentage (0.0 -> 1.0)
*/
private double tweenAmount = 0.0;
/**
* Since we don't get real mouse events we have to simulate them by tracking
* the mouse state.
*/
private boolean mouseDown, toggled, toggleable;
/**
* Hover opacity for the tab
*/
private float tabOpacity = 0.0F;
private boolean showTab = true;
/**
* Text to display under the header
*/
private String activeModText, versionText;
/**
* Configuration panel
*/
private GuiPanel currentPanel;
private final GuiPanelMods modsPanel;
private final GuiPanelSettings settingsPanel;
private int brandColour = LiteLoaderBrandingProvider.BRANDING_COLOUR;
private ResourceLocation logoResource = LiteLoaderBrandingProvider.ABOUT_TEXTURE;
private Icon logoCoords = LiteLoaderBrandingProvider.LOGO_COORDS;
private ResourceLocation iconResource = LiteLoaderBrandingProvider.ABOUT_TEXTURE;
private Icon iconCoords = LiteLoaderBrandingProvider.ICON_COORDS;
private List<ModInfoDecorator> modInfoDecorators = new ArrayList<ModInfoDecorator>();
private boolean mouseOverLogo = false;
private int startupErrorCount = 0, criticalErrorCount = 0;
private String notification;
private boolean isSnapshot;
/**
* @param minecraft
* @param parentScreen
* @param mods
*/
public GuiLiteLoaderPanel(Minecraft minecraft, GuiScreen parentScreen, LiteLoaderMods mods, LoaderEnvironment environment,
LoaderProperties properties, ConfigManager configManager, boolean showTab)
{
this.mc = minecraft;
this.fontRendererObj = minecraft.fontRendererObj;
this.parentScreen = parentScreen;
this.showTab = showTab;
this.environment = environment;
this.properties = properties;
this.toggleable = true;
this.versionText = I18n.format("gui.about.versiontext", LiteLoader.getVersion());
this.activeModText = I18n.format("gui.about.modsloaded", mods.getLoadedMods().size());
this.initBranding();
this.currentPanel = this.modsPanel = new GuiPanelMods(this, minecraft, mods, environment, configManager,
this.brandColour, this.modInfoDecorators);
this.settingsPanel = new GuiPanelSettings(this, minecraft);
this.startupErrorCount = mods.getStartupErrorCount();
this.criticalErrorCount = mods.getCriticalErrorCount();
String branding = LiteLoader.getBranding();
if (branding != null && branding.contains("SNAPSHOT"))
{
this.isSnapshot = true;
this.versionText = "\247c" + branding;
}
}
/**
*
*/
private void initBranding()
{
LiteAPI logoProvider = null;
int brandingColourProviderPriority = Integer.MIN_VALUE;
int logoProviderPriority = Integer.MIN_VALUE;
int iconProviderPriority = Integer.MIN_VALUE;
for (LiteAPI api : LiteLoader.getAPIs())
{
BrandingProvider brandingProvider = LiteLoader.getCustomisationProvider(api, BrandingProvider.class);
if (brandingProvider != null)
{
if (brandingProvider.getBrandingColour() != 0 && brandingProvider.getPriority() > brandingColourProviderPriority)
{
brandingColourProviderPriority = brandingProvider.getPriority();
this.brandColour = GuiLiteLoaderPanel.OPAQUE | brandingProvider.getBrandingColour();
}
ResourceLocation logoResource = brandingProvider.getLogoResource();
Icon logoCoords = brandingProvider.getLogoCoords();
if (logoResource != null && logoCoords != null && brandingProvider.getPriority() > logoProviderPriority)
{
logoProvider = api;
logoProviderPriority = brandingProvider.getPriority();
this.logoResource = logoResource;
this.logoCoords = logoCoords;
}
ResourceLocation iconResource = brandingProvider.getIconResource();
Icon iconCoords = brandingProvider.getIconCoords();
if (iconResource != null && iconCoords != null && brandingProvider.getPriority() > iconProviderPriority)
{
iconProviderPriority = brandingProvider.getPriority();
this.iconResource = iconResource;
this.iconCoords = iconCoords;
}
}
ModInfoDecorator modInfoDecorator = LiteLoader.getCustomisationProvider(api, ModInfoDecorator.class);
if (modInfoDecorator != null)
{
this.modInfoDecorators.add(modInfoDecorator);
}
}
if (logoProvider != null && !LiteLoaderCoreAPI.class.isAssignableFrom(logoProvider.getClass()))
{
this.versionText = I18n.format("gui.about.poweredbyversion", logoProvider.getVersion(), LiteLoader.getVersion());
}
}
/**
* Get the computed branding colour
*/
public int getBrandColour()
{
return this.brandColour;
}
/**
* Release references prior to being disposed
*/
public void release()
{
this.parentScreen = null;
}
/**
* Get the parent menu
*/
public GuiScreen getScreen()
{
return this.parentScreen;
}
/**
* Return true if the panel is not fully closed (tweening or open)
*/
public boolean isOpen()
{
return this.tweenAmount > 0.0;
}
public void setToggleable(boolean toggleable)
{
this.toggleable = toggleable;
}
public void setNotification(String notification)
{
this.notification = notification;
}
/* (non-Javadoc)
* @see net.minecraft.client.gui.GuiScreen#initGui()
*/
@SuppressWarnings("unchecked")
@Override
public void initGui()
{
// Hide the tooltip once the user opens the panel
GuiLiteLoaderPanel.displayErrorToolTip = false;
this.currentPanel.setSize(this.width - LEFT_EDGE, this.height);
this.buttonList.add(new GuiHoverLabel(2, LEFT_EDGE + MARGIN, this.height - PANEL_BOTTOM + 9, this.fontRendererObj,
I18n.format("gui.about.taboptions"), this.brandColour));
if (LiteLoaderVersion.getUpdateSite().canCheckForUpdate() && this.mc.theWorld == null && !this.isSnapshot)
{
this.buttonList.add(new GuiHoverLabel(3, LEFT_EDGE + MARGIN + 38 + this.fontRendererObj.getStringWidth(this.versionText) + 6, 50,
this.fontRendererObj, I18n.format("gui.about.checkupdates"), this.brandColour));
}
Keyboard.enableRepeatEvents(true);
}
@Override
public void onGuiClosed()
{
Keyboard.enableRepeatEvents(false);
}
/* (non-Javadoc)
* @see net.minecraft.client.gui.GuiScreen
* #setWorldAndResolution(net.minecraft.client.Minecraft, int, int)
*/
@Override
public void setWorldAndResolution(Minecraft minecraft, int width, int height)
{
if (this.mc.currentScreen == this)
{
// Set res in parent screen if we are the active GUI
this.parentScreen.setWorldAndResolution(minecraft, width, height);
}
super.setWorldAndResolution(minecraft, width, height);
}
/* (non-Javadoc)
* @see net.minecraft.client.gui.GuiScreen#updateScreen()
*/
@Override
public void updateScreen()
{
this.currentPanel.onTick();
this.tickNumber++;
if (this.mc.currentScreen == this)
{
this.mc.currentScreen = this.parentScreen;
this.parentScreen.updateScreen();
this.mc.currentScreen = this;
}
if (this.toggled && this.toggleable)
{
this.onToggled();
}
}
/* (non-Javadoc)
* @see net.minecraft.client.gui.GuiScreen#drawScreen(int, int, float)
*/
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks)
{
this.drawScreen(mouseX, mouseY, partialTicks, false);
}
/**
* @param mouseX
* @param mouseY
* @param partialTicks
* @param alwaysExpandTab
*/
public void drawScreen(int mouseX, int mouseY, float partialTicks, boolean alwaysExpandTab)
{
boolean active = this.mc.currentScreen == this;
if (active)
{
// Draw the parent screen as our background if we are the active screen
glClear(GL_DEPTH_BUFFER_BIT);
this.parentScreen.drawScreen(-10, -10, partialTicks);
glClear(GL_DEPTH_BUFFER_BIT);
}
else
{
// If this is not the active screen, copy the width and height from the parent GUI
this.width = this.parentScreen.width;
this.height = this.parentScreen.height;
}
// Calculate the current tween position
float xOffset = (this.width - LEFT_EDGE) * this.calcTween(partialTicks, active) + 16.0F + (this.tabOpacity * -32.0F);
int offsetMouseX = mouseX - (int)xOffset;
// Handle mouse stuff here since we won't get mouse events when not the active GUI
boolean mouseOverTab = this.showTab && (offsetMouseX > LEFT_EDGE - TAB_WIDTH
&& offsetMouseX < LEFT_EDGE
&& mouseY > TAB_TOP
&& mouseY < TAB_TOP + TAB_HEIGHT);
this.handleMouseClick(offsetMouseX, mouseY, partialTicks, active, mouseOverTab);
// Calculate the tab opacity, not framerate adjusted because we don't really care
this.tabOpacity = mouseOverTab || alwaysExpandTab || this.startupErrorCount > 0 || this.notification != null
|| this.isOpen() ? 0.5F : Math.max(0.0F, this.tabOpacity - partialTicks * 0.1F);
// Draw the panel contents
this.drawPanel(offsetMouseX, mouseY, partialTicks, active, xOffset);
this.drawTooltips(mouseX, mouseY, partialTicks, active, xOffset, mouseOverTab);
}
/**
* @param mouseX
* @param mouseY
* @param partialTicks
* @param active
* @param xOffset
*/
private void drawPanel(int mouseX, int mouseY, float partialTicks, boolean active, float xOffset)
{
this.mouseOverLogo = false;
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
glPushMatrix();
glTranslatef(xOffset, 0.0F, 0.0F);
// Draw the background and left edge
drawRect(LEFT_EDGE, 0, this.width, this.height, GuiLiteLoaderPanel.TOOLTIP_BACKGROUND);
if (this.showTab)
{
drawRect(LEFT_EDGE, 0, LEFT_EDGE + 1, TAB_TOP, GuiLiteLoaderPanel.WHITE);
drawRect(LEFT_EDGE, TAB_TOP + TAB_HEIGHT, LEFT_EDGE + 1, this.height, GuiLiteLoaderPanel.WHITE);
this.mc.getTextureManager().bindTexture(LiteLoaderBrandingProvider.ABOUT_TEXTURE);
glDrawTexturedRect(LEFT_EDGE - TAB_WIDTH, TAB_TOP, TAB_WIDTH + 1, TAB_HEIGHT, 80, 80, 122, 160, 0.5F + this.tabOpacity);
if (this.startupErrorCount > 0)
{
glDrawTexturedRect(LEFT_EDGE - TAB_WIDTH + 7, TAB_TOP + 2, 12, 12, 134, 92, 134 + 12, 92 + 12, 0.5F + this.tabOpacity);
}
else if (this.notification != null)
{
glDrawTexturedRect(LEFT_EDGE - TAB_WIDTH + 7, TAB_TOP + 2, 12, 12, 134 + 12, 92, 134 + 24, 92 + 12, 0.5F + this.tabOpacity);
}
}
else
{
drawRect(LEFT_EDGE, 0, LEFT_EDGE + 1, this.height, GuiLiteLoaderPanel.WHITE);
}
// Only draw the panel contents if we are actually open
if (this.isOpen())
{
if (this.currentPanel.isCloseRequested())
{
this.closeCurrentPanel();
}
this.drawCurrentPanel(mouseX, mouseY, partialTicks);
if (!this.currentPanel.stealFocus())
{
// Draw other controls inside the transform so that they slide properly
super.drawScreen(mouseX, mouseY, partialTicks);
}
}
else
{
this.closeCurrentPanel();
}
glPopMatrix();
}
/**
* @param mouseX
* @param mouseY
* @param partialTicks
*/
private void drawCurrentPanel(int mouseX, int mouseY, float partialTicks)
{
glPushMatrix();
glTranslatef(LEFT_EDGE, 0, 0);
this.currentPanel.draw(mouseX - LEFT_EDGE, mouseY, partialTicks);
glPopMatrix();
}
/**
* @param mouseX
* @param mouseY
* @param partialTicks
*/
protected boolean drawInfoPanel(int mouseX, int mouseY, float partialTicks, int left, int bottom)
{
int right = this.width - MARGIN - LEFT_EDGE + left;
left += MARGIN;
// Draw the header pieces
this.mc.getTextureManager().bindTexture(this.logoResource);
glDrawTexturedRect(left, MARGIN, this.logoCoords, 1.0F);
this.mc.getTextureManager().bindTexture(this.iconResource);
glDrawTexturedRect(right - this.iconCoords.getIconWidth(), MARGIN, this.iconCoords, 1.0F);
// Draw header text
this.fontRendererObj.drawString(this.versionText, left + 38, 50, GuiLiteLoaderPanel.HEADER_TEXT_COLOUR);
this.fontRendererObj.drawString(this.activeModText, left + 38, 60, GuiLiteLoaderPanel.HEADER_TEXT_COLOUR_SUB);
// Draw top and bottom horizontal rules
drawRect(left, 80, right, 81, GuiLiteLoaderPanel.HEADER_HR_COLOUR);
drawRect(left, this.height - bottom + 2, right, this.height - bottom + 3, GuiLiteLoaderPanel.HEADER_HR_COLOUR);
this.mouseOverLogo = (mouseY > MARGIN && mouseY < MARGIN + this.logoCoords.getIconHeight()
&& mouseX > left && mouseX < left + this.logoCoords.getIconWidth());
return this.mouseOverLogo;
}
private void drawTooltips(int mouseX, int mouseY, float partialTicks, boolean active, float xOffset, boolean mouseOverTab)
{
boolean annoyingTip = this.startupErrorCount > 0 || this.notification != null;
if (mouseOverTab && this.tweenAmount < 0.01)
{
GuiLiteLoaderPanel.drawTooltip(this.fontRendererObj, LiteLoader.getVersionDisplayString(), mouseX, mouseY, this.width, this.height,
GuiLiteLoaderPanel.TOOLTIP_FOREGROUND, GuiLiteLoaderPanel.TOOLTIP_BACKGROUND);
GuiLiteLoaderPanel.drawTooltip(this.fontRendererObj, this.activeModText, mouseX, mouseY + 13, this.width, this.height,
GuiLiteLoaderPanel.TOOLTIP_FOREGROUND_SUB, GuiLiteLoaderPanel.TOOLTIP_BACKGROUND);
if (annoyingTip)
{
this.drawNotificationTooltip(mouseX, mouseY - 13);
}
}
else if (GuiLiteLoaderPanel.displayErrorToolTip && annoyingTip && !active && this.parentScreen instanceof GuiMainMenu)
{
this.drawNotificationTooltip((int)xOffset + LEFT_EDGE - 12, TAB_TOP + 2);
}
}
private void drawNotificationTooltip(int left, int top)
{
if (this.startupErrorCount > 0)
{
GuiLiteLoaderPanel.drawTooltip(this.fontRendererObj, I18n.format("gui.error.tooltip", this.startupErrorCount, this.criticalErrorCount),
left, top, this.width, this.height, GuiLiteLoaderPanel.ERROR_TOOLTIP_FOREGROUND, GuiLiteLoaderPanel.ERROR_TOOLTIP_BACKGROUND);
}
else if (this.notification != null)
{
GuiLiteLoaderPanel.drawTooltip(this.fontRendererObj, this.notification, left, top, this.width, this.height,
GuiLiteLoaderPanel.NOTIFICATION_TOOLTIP_FOREGROUND, GuiLiteLoaderPanel.NOTIFICATION_TOOLTIP_BACKGROUND);
}
}
/* (non-Javadoc)
* @see net.minecraft.client.gui.GuiScreen
* #actionPerformed(net.minecraft.client.gui.GuiButton)
*/
@Override
protected void actionPerformed(GuiButton button)
{
if (button.id == 2)
{
this.setCurrentPanel(this.settingsPanel);
}
if (button.id == 3)
{
this.setCurrentPanel(new GuiPanelUpdateCheck(this, this.mc, LiteLoaderVersion.getUpdateSite(), "LiteLoader", this.properties));
}
}
/* (non-Javadoc)
* @see net.minecraft.client.gui.GuiScreen#keyTyped(char, int)
*/
@Override
protected void keyTyped(char keyChar, int keyCode)
{
this.currentPanel.keyPressed(keyChar, keyCode);
}
/**
*
*/
void showLogPanel()
{
this.setCurrentPanel(new GuiPanelLiteLoaderLog(this.mc, this));
}
/**
*
*/
void showAboutPanel()
{
this.setCurrentPanel(new GuiPanelAbout(this.mc, this));
}
public void showErrorPanel(ModInfo<?> mod)
{
this.setCurrentPanel(new GuiPanelError(this.mc, this, mod));
}
/* (non-Javadoc)
* @see net.minecraft.client.gui.GuiScreen#mouseClicked(int, int, int)
*/
@Override
protected void mouseClicked(int mouseX, int mouseY, int button) throws IOException
{
this.currentPanel.mousePressed(mouseX - LEFT_EDGE, mouseY, button);
if (button == 0 && this.mouseOverLogo && !this.currentPanel.stealFocus())
{
this.showAboutPanel();
}
if (!this.currentPanel.stealFocus())
{
super.mouseClicked(mouseX, mouseY, button);
}
}
/* (non-Javadoc)
* @see net.minecraft.client.gui.GuiScreen#mouseReleased(int, int, int)
*/
@Override
protected void mouseReleased(int mouseX, int mouseY, int button)
{
if (button == -1)
{
this.currentPanel.mouseMoved(mouseX - LEFT_EDGE, mouseY);
}
else
{
this.currentPanel.mouseReleased(mouseX - LEFT_EDGE, mouseY, button);
}
if (!this.currentPanel.stealFocus())
{
super.mouseReleased(mouseX, mouseY, button);
}
}
/* (non-Javadoc)
* @see net.minecraft.client.gui.GuiScreen#handleMouseInput()
*/
@Override
public void handleMouseInput() throws IOException
{
int mouseWheelDelta = Mouse.getEventDWheel();
if (mouseWheelDelta != 0)
{
this.currentPanel.mouseWheelScrolled(mouseWheelDelta);
}
super.handleMouseInput();
}
/**
* @param mouseX
* @param active
* @param mouseOverTab
*/
public void handleMouseClick(int mouseX, int mouseY, float partialTicks, boolean active, boolean mouseOverTab)
{
boolean mouseDown = Mouse.isButtonDown(0);
if (((active && mouseX < LEFT_EDGE && this.tweenAmount > 0.75) || mouseOverTab) && !this.mouseDown && mouseDown)
{
this.mouseDown = true;
this.toggled = true;
}
else if (this.mouseDown && !mouseDown)
{
this.mouseDown = false;
}
}
/**
* @param partialTicks
* @param active
*/
private float calcTween(float partialTicks, boolean active)
{
double tickValue = this.tickNumber + partialTicks;
if (active && this.tweenAmount < 1.0)
{
this.tweenAmount = Math.min(1.0, this.tweenAmount + ((tickValue - this.lastTick) * TWEEN_RATE));
}
else if (!active && this.isOpen())
{
this.tweenAmount = Math.max(0.0, this.tweenAmount - ((tickValue - this.lastTick) * TWEEN_RATE));
}
this.lastTick = tickValue;
return 1.0F - (float)Math.sin(this.tweenAmount * 0.5 * Math.PI);
}
/**
* Called when the tab is clicked
*/
void onToggled()
{
this.toggled = false;
this.mc.displayGuiScreen(this.mc.currentScreen == this ? this.parentScreen : this);
}
/**
* Callback for the "config" button, display the config panel for the
* currently selected mod.
*/
void openConfigPanel(ConfigPanel panel, LiteMod mod)
{
if (panel != null)
{
this.setCurrentPanel(new GuiPanelConfigContainer(this.mc, panel, mod));
}
}
/**
* @param newPanel
*/
private void setCurrentPanel(GuiPanel newPanel)
{
this.closeCurrentPanel();
this.currentPanel = newPanel;
this.currentPanel.setSize(this.width - LEFT_EDGE, this.height);
this.currentPanel.onShown();
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.modconfig.ConfigPanelHost#close()
*/
private void closeCurrentPanel()
{
this.currentPanel.onHidden();
this.currentPanel = this.modsPanel;
this.modsPanel.setSize(this.width - LEFT_EDGE, this.height);
}
/**
* Draw a tooltip at the specified location and clip to screenWidth and
* screenHeight
*
* @param fontRenderer
* @param tooltipText
* @param mouseX
* @param mouseY
* @param screenWidth
* @param screenHeight
* @param colour
* @param backgroundColour
*/
public static void drawTooltip(FontRenderer fontRenderer, String tooltipText, int mouseX, int mouseY, int screenWidth, int screenHeight,
int colour, int backgroundColour)
{
int textSize = fontRenderer.getStringWidth(tooltipText);
mouseX = Math.max(0, Math.min(screenWidth - 4, mouseX - 4));
mouseY = Math.max(0, Math.min(screenHeight - 16, mouseY));
drawRect(mouseX - textSize - 2, mouseY, mouseX + 2, mouseY + 12, backgroundColour);
fontRenderer.drawStringWithShadow(tooltipText, mouseX - textSize, mouseY + 2, colour);
}
/**
* @param x
* @param y
* @param width
* @param height
* @param u
* @param v
* @param u2
* @param v2
* @param alpha
*/
static void glDrawTexturedRect(int x, int y, int width, int height, int u, int v, int u2, int v2, float alpha)
{
float texMapScale = 0.00390625F; // 256px
glDrawTexturedRect(x, y, width, height, u * texMapScale, v * texMapScale, u2 * texMapScale, v2 * texMapScale, alpha);
}
/**
* @param x
* @param y
* @param width
* @param height
* @param u
* @param v
* @param u2
* @param v2
* @param alpha
*/
static void glDrawTexturedRect(int x, int y, int width, int height, float u, float v, float u2, float v2, float alpha)
{
glDisableLighting();
glEnableBlend();
glAlphaFunc(GL_GREATER, 0.0F);
glEnableTexture2D();
glColor4f(1.0F, 1.0F, 1.0F, alpha);
Tessellator tessellator = Tessellator.getInstance();
WorldRenderer worldRenderer = tessellator.getWorldRenderer();
worldRenderer.startDrawingQuads();
worldRenderer.addVertexWithUV(x + 0, y + height, 0, u , v2);
worldRenderer.addVertexWithUV(x + width, y + height, 0, u2, v2);
worldRenderer.addVertexWithUV(x + width, y + 0, 0, u2, v );
worldRenderer.addVertexWithUV(x + 0, y + 0, 0, u , v );
tessellator.draw();
glDisableBlend();
glAlphaFunc(GL_GREATER, 0.01F);
}
/**
* @param x
* @param y
* @param icon
* @param alpha
*/
static void glDrawTexturedRect(int x, int y, Icon icon, float alpha)
{
glDrawTexturedRect(x, y, icon.getIconWidth(), icon.getIconHeight(), icon.getMinU(), icon.getMinV(), icon.getMaxU(), icon.getMaxV(), alpha);
}
}

View file

@ -0,0 +1,209 @@
package com.mumfrey.liteloader.client.gui;
import static com.mumfrey.liteloader.gl.GL.*;
import java.util.LinkedList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiButton;
import com.mumfrey.liteloader.client.api.LiteLoaderBrandingProvider;
/**
* Base class for panels
*
* @author Adam Mummery-Smith
*/
public abstract class GuiPanel extends Gui
{
protected static final int TOP = 26;
protected static final int BOTTOM = 40;
protected static final int MARGIN = 12;
/**
* Minecraft
*/
protected Minecraft mc;
/**
* Buttons
*/
protected List<GuiButton> controls = new LinkedList<GuiButton>();
/**
* Current available width
*/
protected int width = 0;
/**
* Current available height
*/
protected int height = 0;
/**
* Current inner pane width (width - margins)
*/
protected int innerWidth = 0;
/**
* Current inner pane visible height (height - chrome)
*/
protected int innerHeight = 0;
/**
* Panel Y position (for scroll)
*/
protected int innerTop = TOP;
/**
* True if the client wants to close the panel
*/
private boolean closeRequested;
/**
* @param minecraft
*/
public GuiPanel(Minecraft minecraft)
{
this.mc = minecraft;
}
boolean stealFocus()
{
return true;
}
/**
* Called by the containing screen to set the panel size
*
* @param width
* @param height
*/
void setSize(int width, int height)
{
this.controls.clear();
this.width = width;
this.height = height;
this.innerHeight = this.height - TOP - BOTTOM;
this.innerWidth = this.width - (MARGIN * 2) - 6;
}
/**
* @param mouseX
* @param mouseY
* @param partialTicks
*/
void draw(int mouseX, int mouseY, float partialTicks)
{
for (GuiButton control : this.controls)
control.drawButton(this.mc, mouseX, mouseY);
}
/**
*
*/
public void close()
{
this.closeRequested = true;
}
/**
* Get whether the client wants to close the panel
*/
boolean isCloseRequested()
{
return this.closeRequested;
}
/**
* @param mouseX
* @param mouseY
* @param mouseButton
*/
void mousePressed(int mouseX, int mouseY, int mouseButton)
{
if (mouseButton == 0)
{
for (GuiButton control : this.controls)
{
if (control.mousePressed(this.mc, mouseX, mouseY))
{
control.playPressSound(this.mc.getSoundHandler());
this.actionPerformed(control);
}
}
}
}
/**
* @param mouseX
* @param mouseY
*/
boolean mouseOverPanel(int mouseX, int mouseY)
{
return mouseX > MARGIN && mouseX <= this.width - MARGIN && mouseY > TOP && mouseY <= this.height - BOTTOM;
}
/**
* Called every tick
*/
abstract void onTick();
/**
* Called after the screen is hidden
*/
abstract void onHidden();
/**
* Called when the panel is shown
*/
abstract void onShown();
/**
* @param keyChar
* @param keyCode
*/
abstract void keyPressed(char keyChar, int keyCode);
/**
* @param mouseX
* @param mouseY
*/
abstract void mouseMoved(int mouseX, int mouseY);
/**
* @param mouseX
* @param mouseY
* @param mouseButton
*/
abstract void mouseReleased(int mouseX, int mouseY, int mouseButton);
/**
* @param mouseWheelDelta
*/
abstract void mouseWheelScrolled(int mouseWheelDelta);
/**
* @param control
*/
abstract void actionPerformed(GuiButton control);
/**
* @param x
* @param y
* @param frame
*/
protected void drawThrobber(int x, int y, int frame)
{
glEnableBlend();
glAlphaFunc(GL_GREATER, 0.0F);
this.mc.getTextureManager().bindTexture(LiteLoaderBrandingProvider.ABOUT_TEXTURE);
this.drawTexturedModalRect(x, y, (frame % 4) * 16, 171 + (((frame / 4) % 3) * 16), 16, 16);
glAlphaFunc(GL_GREATER, 0.1F);
glDisableBlend();
}
}

View file

@ -0,0 +1,251 @@
package com.mumfrey.liteloader.client.gui;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.input.Keyboard;
import com.mumfrey.liteloader.api.BrandingProvider;
import com.mumfrey.liteloader.api.LiteAPI;
import com.mumfrey.liteloader.client.api.LiteLoaderBrandingProvider;
import com.mumfrey.liteloader.client.util.render.IconAbsolute;
import com.mumfrey.liteloader.core.LiteLoader;
import com.mumfrey.liteloader.util.SortableValue;
import com.mumfrey.liteloader.util.render.Icon;
/**
* "About LiteLoader" panel which docks in the mod info screen and lists
* information about the installed APIs.
*
* @author Adam Mummery-Smith
*/
class GuiPanelAbout extends GuiPanel implements ScrollPanelContent
{
public static final IconAbsolute apiIconCoords = new IconAbsolute(LiteLoaderBrandingProvider.ABOUT_TEXTURE, "api_icon",
32, 32, 192, 144, 256, 208);
private static final int ROW_HEIGHT = 40;
private static final URI MCP_URI = URI.create("http://mcp.ocean-labs.de/");
private GuiLiteLoaderPanel parent;
private GuiScrollPanel scrollPane;
private List<BrandingProvider> brandings = new ArrayList<BrandingProvider>();
private boolean mouseOverLogo;
public GuiPanelAbout(Minecraft minecraft, GuiLiteLoaderPanel parent)
{
super(minecraft);
this.parent = parent;
this.scrollPane = new GuiScrollPanel(minecraft, this, MARGIN, 90, 100, 100);
this.sortBrandingProviders();
this.scrollPane.addControl(new GuiHoverLabel(-2, 38, 22 + this.brandings.size() * GuiPanelAbout.ROW_HEIGHT, this.mc.fontRendererObj,
"\247n" + MCP_URI.toString(), this.parent.getBrandColour()));
}
/**
*
*/
private void sortBrandingProviders()
{
Set<SortableValue<BrandingProvider>> sortedBrandingProviders = new TreeSet<SortableValue<BrandingProvider>>();
for (LiteAPI api : LiteLoader.getAPIs())
{
BrandingProvider brandingProvider = LiteLoader.getCustomisationProvider(api, BrandingProvider.class);
if (brandingProvider != null)
{
sortedBrandingProviders.add(new SortableValue<BrandingProvider>(Integer.MAX_VALUE - brandingProvider.getPriority(), 0,
brandingProvider));
}
}
int brandingIndex = 0;
for (SortableValue<BrandingProvider> sortedBrandingProvider : sortedBrandingProviders)
{
BrandingProvider brandingProvider = sortedBrandingProvider.getValue();
this.brandings.add(brandingProvider);
URI homepage = brandingProvider.getHomepage();
if (homepage != null)
{
this.scrollPane.addControl(new GuiHoverLabel(brandingIndex, 38, 22 + brandingIndex * GuiPanelAbout.ROW_HEIGHT,
this.mc.fontRendererObj, "\247n" + homepage, this.parent.getBrandColour()));
}
brandingIndex++;
}
}
@Override
void setSize(int width, int height)
{
super.setSize(width, height);
this.scrollPane.setSizeAndPosition(MARGIN, 86, this.width - MARGIN * 2, this.height - 126);
this.controls.add(new GuiButton(-1, this.width - 99 - MARGIN, this.height - BOTTOM + 9, 100, 20, I18n.format("gui.done")));
this.controls.add(new GuiButton(-3, MARGIN, this.height - BOTTOM + 9, 100, 20, I18n.format("gui.log.button")));
}
@Override
void draw(int mouseX, int mouseY, float partialTicks)
{
this.mouseOverLogo = this.parent.drawInfoPanel(mouseX, mouseY, partialTicks, 0, 38);
this.scrollPane.draw(mouseX, mouseY, partialTicks);
super.draw(mouseX, mouseY, partialTicks);
}
@Override
public int getScrollPanelContentHeight(GuiScrollPanel source)
{
return 64 + this.brandings.size() * GuiPanelAbout.ROW_HEIGHT;
}
@Override
public void drawScrollPanelContent(GuiScrollPanel source, int mouseX, int mouseY, float partialTicks, int scrollAmount, int visibleHeight)
{
FontRenderer fontRenderer = this.mc.fontRendererObj;
int textColour = 0xFFAAAAAA;
int yPos = 0;
for (BrandingProvider branding : this.brandings)
{
ResourceLocation twitterAvatarResource = branding.getTwitterAvatarResource();
Icon twitterAvatarCoords = branding.getTwitterAvatarCoords();
this.mc.getTextureManager().bindTexture(twitterAvatarResource != null ? twitterAvatarResource : LiteLoaderBrandingProvider.ABOUT_TEXTURE);
GuiLiteLoaderPanel.glDrawTexturedRect(0, yPos, twitterAvatarCoords != null ? twitterAvatarCoords : GuiPanelAbout.apiIconCoords, 1.0F);
fontRenderer.drawString(branding.getDisplayName(), 38, yPos, 0xFFFFFFFF);
fontRenderer.drawString(branding.getCopyrightText(), 38, yPos + 11, textColour);
yPos += GuiPanelAbout.ROW_HEIGHT;
}
fontRenderer.drawString("Created using Mod Coder Pack", 38, yPos, 0xFFFFFFFF);
fontRenderer.drawString("MCP is (c) Copyright by the MCP Team", 38, yPos + 11, textColour);
yPos += GuiPanelAbout.ROW_HEIGHT;
fontRenderer.drawString("Minecraft is Copyright (c) Mojang AB", 38, yPos, textColour);
fontRenderer.drawString("All rights reserved.", 38, yPos + 11, textColour);
}
@Override
public void scrollPanelMousePressed(GuiScrollPanel source, int mouseX, int mouseY, int mouseButton)
{
int index = mouseY / GuiPanelAbout.ROW_HEIGHT;
int yOffset = mouseY - (GuiPanelAbout.ROW_HEIGHT * index);
if (mouseButton == 0 && mouseX < 33 && index >= 0 && index < this.brandings.size() && yOffset < 33)
{
String twitterUserName = this.brandings.get(index).getTwitterUserName();
if (twitterUserName != null)
{
URI twitterURI = URI.create("https://www.twitter.com/" + twitterUserName);
this.openURI(twitterURI);
}
}
}
/**
* @param control
*/
@Override
void actionPerformed(GuiButton control)
{
if (control.id == -1) this.close();
if (control.id == -2) this.openURI(MCP_URI);
if (control.id == -3) this.parent.showLogPanel();
}
@Override
public void scrollPanelActionPerformed(GuiScrollPanel source, GuiButton control)
{
if (control.id >= 0 && control.id < this.brandings.size())
{
URI homepage = this.brandings.get(control.id).getHomepage();
if (homepage != null) this.openURI(homepage);
}
}
private void openURI(URI uri)
{
try
{
Class<?> desktop = Class.forName("java.awt.Desktop");
Object instance = desktop.getMethod("getDesktop").invoke(null);
desktop.getMethod("browse", URI.class).invoke(instance, uri);
}
catch (Throwable th) {}
}
@Override
void onTick()
{
}
@Override
void onHidden()
{
}
@Override
void onShown()
{
}
@Override
void keyPressed(char keyChar, int keyCode)
{
if (keyCode == Keyboard.KEY_ESCAPE) this.close();
}
@Override
void mousePressed(int mouseX, int mouseY, int mouseButton)
{
this.scrollPane.mousePressed(mouseX, mouseY, mouseButton);
if (mouseButton == 0 && this.mouseOverLogo)
{
this.close();
}
super.mousePressed(mouseX, mouseY, mouseButton);
}
@Override
void mouseMoved(int mouseX, int mouseY)
{
}
@Override
void mouseReleased(int mouseX, int mouseY, int mouseButton)
{
this.scrollPane.mouseReleased(mouseX, mouseY, mouseButton);
}
@Override
void mouseWheelScrolled(int mouseWheelDelta)
{
this.scrollPane.mouseWheelScrolled(mouseWheelDelta);
}
}

View file

@ -0,0 +1,274 @@
package com.mumfrey.liteloader.client.gui;
import static com.mumfrey.liteloader.gl.GL.*;
import static com.mumfrey.liteloader.gl.GLClippingPlanes.*;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.resources.I18n;
import com.mumfrey.liteloader.LiteMod;
import com.mumfrey.liteloader.modconfig.ConfigPanel;
import com.mumfrey.liteloader.modconfig.ConfigPanelHost;
/**
* Config panel container, this handles drawing the configuration panel chrome
* and also hosts the configuration panels themselves to support scrolling and
* stuff.
*
* @author Adam Mummery-Smith
*/
class GuiPanelConfigContainer extends GuiPanel implements ConfigPanelHost
{
/**
* Panel we are hosting
*/
private ConfigPanel panel;
/**
* Mod being configured, the panel may want a reference to it
*/
private LiteMod mod;
/**
* Scroll bar for the panel
*/
GuiSimpleScrollBar scrollBar = new GuiSimpleScrollBar();
/**
* Panel's internal height (for scrolling)
*/
private int totalHeight = -1;
/**
* @param minecraft
* @param panel
* @param mod
*/
GuiPanelConfigContainer(Minecraft minecraft, ConfigPanel panel, LiteMod mod)
{
super(minecraft);
this.panel = panel;
this.mod = mod;
}
/**
*
*/
String getPanelTitle()
{
String panelTitle = this.panel.getPanelTitle();
return panelTitle != null ? panelTitle : I18n.format("gui.settings.title", this.mod.getName());
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.modconfig.ConfigPanelHost#getMod()
*/
@SuppressWarnings("unchecked")
@Override
public <TModClass extends LiteMod> TModClass getMod()
{
return (TModClass)this.mod;
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.modconfig.ConfigPanelHost#getWidth()
*/
@Override
public int getWidth()
{
return this.innerWidth;
}
/* (non-Javadoc)
* @see com.mumfrey.liteloader.modconfig.ConfigPanelHost#getHeight()
*/
@Override
public int getHeight()
{
return this.innerHeight;
}
/**
* Callback from parent screen when window is resized
*
* @param width
* @param height
*/
@Override
void setSize(int width, int height)
{
super.setSize(width, height);
this.panel.onPanelResize(this);
this.controls.add(new GuiButton(0, this.width - 99 - MARGIN, this.height - BOTTOM + 9, 100, 20, I18n.format("gui.saveandclose")));
}
/**
* Callback from parent screen when panel is displayed
*/
@Override
void onShown()
{
try
{
this.panel.onPanelShown(this);
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
/**
* Callback from parent screen when panel is hidden
*/
@Override
void onHidden()
{
try
{
this.panel.onPanelHidden();
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
/**
* Callback from parent screen every tick
*/
@Override
void onTick()
{
this.panel.onTick(this);
}
/**
* Draw the panel and chrome
*
* @param mouseX
* @param mouseY
* @param partialTicks
*/
@Override
void draw(int mouseX, int mouseY, float partialTicks)
{
// Scroll position
this.innerTop = TOP - this.scrollBar.getValue();
// Draw panel title
this.mc.fontRendererObj.drawString(this.getPanelTitle(), MARGIN, TOP - 14, 0xFFFFFFFF);
// Draw top and bottom horizontal bars
drawRect(MARGIN, TOP - 4, this.width - MARGIN, TOP - 3, 0xFF999999);
drawRect(MARGIN, this.height - BOTTOM + 2, this.width - MARGIN, this.height - BOTTOM + 3, 0xFF999999);
// Clip rect
glEnableClipping(MARGIN, this.width - MARGIN - 6, TOP, this.height - BOTTOM);
// Offset by scroll
glPushMatrix();
glTranslatef(MARGIN, this.innerTop, 0.0F);
// Draw panel contents
this.panel.drawPanel(this, mouseX - MARGIN - (this.mouseOverPanel(mouseX, mouseY) ? 0 : 99999), mouseY - this.innerTop, partialTicks);
glClear(GL_DEPTH_BUFFER_BIT);
// Disable clip rect
glDisableClipping();
// Restore transform
glPopMatrix();
// Get total scroll height from panel
this.totalHeight = Math.max(-1, this.panel.getContentHeight());
// Update and draw scroll bar
this.scrollBar.setMaxValue(this.totalHeight - this.innerHeight);
this.scrollBar.drawScrollBar(mouseX, mouseY, partialTicks, this.width - MARGIN - 5, TOP, 5, this.innerHeight,
Math.max(this.innerHeight, this.totalHeight));
// Draw other buttons
super.draw(mouseX, mouseY, partialTicks);
}
/**
* @param control
*/
@Override
void actionPerformed(GuiButton control)
{
if (control.id == 0) this.close();
}
/**
* @param mouseWheelDelta
*/
@Override
void mouseWheelScrolled(int mouseWheelDelta)
{
this.scrollBar.offsetValue(-mouseWheelDelta / 8);
}
/**
* @param mouseX
* @param mouseY
* @param mouseButton
*/
@Override
void mousePressed(int mouseX, int mouseY, int mouseButton)
{
if (mouseButton == 0)
{
if (this.scrollBar.wasMouseOver())
{
this.scrollBar.setDragging(true);
}
}
super.mousePressed(mouseX, mouseY, mouseButton);
if (this.mouseOverPanel(mouseX, mouseY))
{
this.panel.mousePressed(this, mouseX - MARGIN, mouseY - this.innerTop, mouseButton);
}
}
/**
* @param mouseX
* @param mouseY
* @param mouseButton
*/
@Override
void mouseReleased(int mouseX, int mouseY, int mouseButton)
{
if (mouseButton == 0)
{
this.scrollBar.setDragging(false);
}
this.panel.mouseReleased(this, mouseX - MARGIN, mouseY - this.innerTop, mouseButton);
}
/**
* @param mouseX
* @param mouseY
*/
@Override
void mouseMoved(int mouseX, int mouseY)
{
this.panel.mouseMoved(this, mouseX - MARGIN, mouseY - this.innerTop);
}
/**
* @param keyChar
* @param keyCode
*/
@Override
void keyPressed(char keyChar, int keyCode)
{
this.panel.keyPressed(this, keyChar, keyCode);
}
}

View file

@ -0,0 +1,161 @@
package com.mumfrey.liteloader.client.gui;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import org.lwjgl.input.Keyboard;
import com.mumfrey.liteloader.core.ModInfo;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.resources.I18n;
public class GuiPanelError extends GuiPanel implements ScrollPanelContent
{
private final ModInfo<?> mod;
private GuiScrollPanel scrollPane;
private List<String> scrollPaneContent = new ArrayList<String>();
public GuiPanelError(Minecraft minecraft, GuiLiteLoaderPanel parent, ModInfo<?> mod)
{
super(minecraft);
this.mod = mod;
this.scrollPane = new GuiScrollPanel(minecraft, this, MARGIN, TOP, this.width - (MARGIN * 2), this.height - TOP - BOTTOM);
this.populateScrollPaneContent();
}
private void populateScrollPaneContent()
{
for (Throwable th : this.mod.getStartupErrors())
{
StringWriter sw = new StringWriter();
th.printStackTrace(new PrintWriter(sw, true));
for (String line : sw.toString().split("\\r?\\n"))
{
this.scrollPaneContent.add(line.replace("\t", " "));
}
this.scrollPaneContent.add("!");
}
this.scrollPaneContent.remove(this.scrollPaneContent.size() - 1);
}
@Override
public int getScrollPanelContentHeight(GuiScrollPanel source)
{
return this.scrollPaneContent.size() * 10;
}
@Override
public void drawScrollPanelContent(GuiScrollPanel source, int mouseX, int mouseY, float partialTicks, int scrollAmount, int visibleHeight)
{
int yPos = -10;
for (String line : this.scrollPaneContent)
{
if ("!".equals(line))
{
yPos += 10;
drawRect(0, yPos + 4, this.width, yPos + 5, 0xFF555555);
}
else
{
boolean indented = line.startsWith(" ");
line = line.replaceAll("\\((.+?\\.java:[0-9]+)\\)", "(\247f$1\247r)");
line = line.replaceAll("at ([^\\(]+)\\(", "at \2476$1\247r(");
this.mc.fontRendererObj.drawString(line, 2, yPos += 10, indented ? 0xFF999999 : 0xFFFF5555);
}
}
}
@Override
public void scrollPanelActionPerformed(GuiScrollPanel source, GuiButton control)
{
}
@Override
public void scrollPanelMousePressed(GuiScrollPanel source, int mouseX, int mouseY, int mouseButton)
{
}
@Override
void setSize(int width, int height)
{
super.setSize(width, height);
this.scrollPane.setSizeAndPosition(MARGIN, TOP, this.width - (MARGIN * 2), this.height - TOP - BOTTOM);
this.controls.add(new GuiButton(0, this.width - 59 - MARGIN, this.height - BOTTOM + 9, 60, 20, I18n.format("gui.done")));
}
@Override
void draw(int mouseX, int mouseY, float partialTicks)
{
this.mc.fontRendererObj.drawString(I18n.format("gui.error.title", this.mod.getDisplayName()), MARGIN, TOP - 14, 0xFFFFFFFF);
drawRect(MARGIN, TOP - 4, this.width - MARGIN, TOP - 3, 0xFF999999);
drawRect(MARGIN, this.height - BOTTOM + 2, this.width - MARGIN, this.height - BOTTOM + 3, 0xFF999999);
this.scrollPane.draw(mouseX, mouseY, partialTicks);
super.draw(mouseX, mouseY, partialTicks);
}
@Override
void onTick()
{
}
@Override
void onHidden()
{
}
@Override
void onShown()
{
}
@Override
void keyPressed(char keyChar, int keyCode)
{
if (keyCode == Keyboard.KEY_ESCAPE) this.close();
}
@Override
void mousePressed(int mouseX, int mouseY, int mouseButton)
{
this.scrollPane.mousePressed(mouseX, mouseY, mouseButton);
super.mousePressed(mouseX, mouseY, mouseButton);
}
@Override
void mouseMoved(int mouseX, int mouseY)
{
}
@Override
void mouseReleased(int mouseX, int mouseY, int mouseButton)
{
this.scrollPane.mouseReleased(mouseX, mouseY, mouseButton);
}
@Override
void mouseWheelScrolled(int mouseWheelDelta)
{
this.scrollPane.mouseWheelScrolled(mouseWheelDelta);
}
@Override
void actionPerformed(GuiButton control)
{
if (control.id == 0) this.close();
}
}

View file

@ -0,0 +1,406 @@
package com.mumfrey.liteloader.client.gui;
import static com.mumfrey.liteloader.gl.GL.*;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.Session;
import org.lwjgl.input.Keyboard;
import com.mumfrey.liteloader.core.LiteLoader;
import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
import com.mumfrey.liteloader.util.net.LiteLoaderLogUpload;
/**
*
* @author Adam Mummery-Smith
*/
class GuiPanelLiteLoaderLog extends GuiPanel implements ScrollPanelContent
{
private static boolean useNativeRes = true;
/**
* Scroll pane
*/
private GuiScrollPanel scrollPane;
private List<String> logEntries = new ArrayList<String>();
private long logIndex = -1;
private GuiCheckbox chkScale;
private float guiScale;
private GuiButton btnUpload;
private LiteLoaderLogUpload logUpload;
private String logURL;
private int throb;
private boolean closeDialog;
private GuiLiteLoaderPanel parent;
private int debugInfoTimer = 0;
/**
* @param minecraft
* @param parent
*/
GuiPanelLiteLoaderLog(Minecraft minecraft, GuiLiteLoaderPanel parent)
{
super(minecraft);
this.parent = parent;
this.scrollPane = new GuiScrollPanel(minecraft, this, MARGIN, TOP, this.width - (MARGIN * 2), this.height - TOP - BOTTOM);
}
private void updateLog()
{
this.logEntries = LiteLoaderLogger.getLogTail();
this.logIndex = LiteLoaderLogger.getLogIndex();
this.scrollPane.updateHeight();
this.scrollPane.scrollToBottom();
}
@Override
public int getScrollPanelContentHeight(GuiScrollPanel source)
{
return (int)(this.logEntries.size() * 10 / (this.chkScale.checked ? this.guiScale : 1.0F));
}
/**
* Callback from parent screen when window is resized
*
* @param width
* @param height
*/
@Override
void setSize(int width, int height)
{
super.setSize(width, height);
this.controls.add(new GuiButton(0, this.width - 59 - MARGIN, this.height - BOTTOM + 9, 60, 20,
I18n.format("gui.done")));
this.controls.add(this.btnUpload = new GuiButton(1, this.width - 145 - MARGIN, this.height - BOTTOM + 9, 80, 20,
I18n.format("gui.log.postlog")));
this.controls.add(this.chkScale = new GuiCheckbox(2, MARGIN, this.height - BOTTOM + 15,
I18n.format("gui.log.scalecheckbox")));
this.chkScale.checked = GuiPanelLiteLoaderLog.useNativeRes;
ScaledResolution res = new ScaledResolution(this.mc, this.mc.displayWidth, this.mc.displayHeight);
this.guiScale = res.getScaleFactor();
this.scrollPane.setSizeAndPosition(MARGIN, TOP, this.width - (MARGIN * 2), this.height - TOP - BOTTOM);
this.updateLog();
}
/**
* Callback from parent screen when panel is displayed
*/
@Override
void onShown()
{
}
/**
* Callback from parent screen when panel is hidden
*/
@Override
void onHidden()
{
}
/**
* Callback from parent screen every tick
*/
@Override
void onTick()
{
this.throb++;
if (LiteLoaderLogger.getLogIndex() > this.logIndex)
{
this.updateLog();
}
if (this.logUpload != null && this.logUpload.isCompleted())
{
this.logURL = this.logUpload.getLogUrl().trim();
this.logUpload = null;
int xMid = this.width / 2;
if (this.logURL.startsWith("http:"))
{
LiteLoaderLogger.info("Log file upload succeeded, url is %s", this.logURL);
int urlWidth = this.mc.fontRendererObj.getStringWidth(this.logURL);
this.controls.add(new GuiHoverLabel(3, xMid - (urlWidth / 2), this.height / 2, this.mc.fontRendererObj, "\247n" + this.logURL,
this.parent.getBrandColour()));
}
else
{
LiteLoaderLogger.info("Log file upload failed, reason is %s", this.logURL);
}
this.controls.add(new GuiButton(4, xMid - 40, this.height - BOTTOM - MARGIN - 24, 80, 20, I18n.format("gui.log.closedialog")));
}
if (this.closeDialog)
{
this.closeDialog = false;
this.logURL = null;
this.setSize(this.width, this.height);
}
if (Keyboard.isKeyDown(Keyboard.KEY_F3))
{
this.debugInfoTimer++;
if (this.debugInfoTimer == 60)
{
LiteLoader.dumpDebugInfo();
}
}
else
{
this.debugInfoTimer = 0;
}
}
/**
* Draw the panel and chrome
*
* @param mouseX
* @param mouseY
* @param partialTicks
*/
@Override
void draw(int mouseX, int mouseY, float partialTicks)
{
// Draw panel title
this.mc.fontRendererObj.drawString(I18n.format("gui.log.title"), MARGIN, TOP - 14, 0xFFFFFFFF);
// Draw top and bottom horizontal bars
drawRect(MARGIN, TOP - 4, this.width - MARGIN, TOP - 3, 0xFF999999);
drawRect(MARGIN, this.height - BOTTOM + 2, this.width - MARGIN, this.height - BOTTOM + 3, 0xFF999999);
this.scrollPane.draw(mouseX, mouseY, partialTicks);
int xMid = this.width / 2;
int yMid = this.height / 2;
if (this.logUpload != null || this.logURL != null)
{
drawRect(MARGIN + MARGIN, TOP + MARGIN, this.width - MARGIN - MARGIN, this.height - BOTTOM - MARGIN, 0xC0000000);
if (this.logUpload != null)
{
this.drawCenteredString(this.mc.fontRendererObj, I18n.format("gui.log.uploading"), xMid, yMid - 10, 0xFFFFFFFF);
this.drawThrobber(xMid - 90, yMid - 14, this.throb);
}
else
{
if (this.logURL.startsWith("http:"))
{
this.drawCenteredString(this.mc.fontRendererObj, I18n.format("gui.log.uploadsuccess"), xMid, yMid - 14, 0xFF55FF55);
}
else
{
this.drawCenteredString(this.mc.fontRendererObj, I18n.format("gui.log.uploadfailed"), xMid, yMid - 10, 0xFFFF5555);
}
}
}
// Draw other buttons
super.draw(mouseX, mouseY, partialTicks);
}
@Override
public void drawScrollPanelContent(GuiScrollPanel source, int mouseX, int mouseY, float partialTicks, int scrollAmount, int visibleHeight)
{
int yPos = 0;
int height = this.innerHeight;
if (this.chkScale.checked)
{
float scale = 1.0F / this.guiScale;
glScalef(scale, scale, scale);
height = (int)(height * this.guiScale);
scrollAmount = (int)(scrollAmount * this.guiScale);
}
for (String logLine : this.logEntries)
{
if (yPos > scrollAmount - 10 && yPos <= scrollAmount + height)
{
this.mc.fontRendererObj.drawString(logLine, 0, yPos, this.getMessageColour(logLine.toLowerCase().substring(11)));
}
yPos += 10;
}
}
@Override
public void scrollPanelMousePressed(GuiScrollPanel source, int mouseX, int mouseY, int mouseButton)
{
}
private int getMessageColour(String logLine)
{
if (logLine.startsWith("liteloader")) return 0xFFFFFF;
if (logLine.startsWith("active pack:")) return 0xFFFF55;
if (logLine.startsWith("success")) return 0x55FF55;
if (logLine.startsWith("discovering")) return 0xFFFF55;
if (logLine.startsWith("searching")) return 0x00AA00;
if (logLine.startsWith("considering")) return 0xFFAA00;
if (logLine.startsWith("not adding")) return 0xFF5555;
if (logLine.startsWith("mod in")) return 0xAA0000;
if (logLine.startsWith("error")) return 0xAA0000;
if (logLine.startsWith("adding newest")) return 0x5555FF;
if (logLine.startsWith("found")) return 0xFFFF55;
if (logLine.startsWith("discovered")) return 0xFFFF55;
if (logLine.startsWith("setting up")) return 0xAA00AA;
if (logLine.startsWith("adding \"")) return 0xAA00AA;
if (logLine.startsWith("injecting")) return 0xFF55FF;
if (logLine.startsWith("loading")) return 0x5555FF;
if (logLine.startsWith("initialising")) return 0x55FFFF;
if (logLine.startsWith("calling late")) return 0x00AAAA;
if (logLine.startsWith("dependency check")) return 0xFFAA00;
if (logLine.startsWith("dependency")) return 0xFF5500;
if (logLine.startsWith("mod name collision")) return 0xAA0000;
if (logLine.startsWith("registering discovery module")) return 0x55FF55;
if (logLine.startsWith("registering interface provider")) return 0xFFAA00;
if (logLine.startsWith("mod file '")) return 0xFFAA00;
if (logLine.startsWith("classtransformer '")) return 0x5555FF;
if (logLine.startsWith("tweakClass '")) return 0x5555FF;
if (logLine.startsWith("baking listener list")) return 0x00AAAA;
if (logLine.startsWith("generating new event handler")) return 0xFFFF55;
return 0xCCCCCC;
}
/**
* @param control
*/
@Override
public void actionPerformed(GuiButton control)
{
if (control.id == 0) this.close();
if (control.id == 1) this.postLog();
if (control.id == 2 && this.chkScale != null)
{
this.chkScale.checked = !this.chkScale.checked;
GuiPanelLiteLoaderLog.useNativeRes = this.chkScale.checked;
this.updateLog();
}
if (control.id == 3 && this.logURL != null)
{
this.openURI(URI.create(this.logURL));
}
if (control.id == 4)
{
this.closeDialog = true;
}
}
@Override
public void scrollPanelActionPerformed(GuiScrollPanel source, GuiButton control)
{
}
/**
* @param mouseWheelDelta
*/
@Override
void mouseWheelScrolled(int mouseWheelDelta)
{
this.scrollPane.mouseWheelScrolled(mouseWheelDelta);
}
/**
* @param mouseX
* @param mouseY
* @param mouseButton
*/
@Override
void mousePressed(int mouseX, int mouseY, int mouseButton)
{
this.scrollPane.mousePressed(mouseX, mouseY, mouseButton);
super.mousePressed(mouseX, mouseY, mouseButton);
}
/**
* @param mouseX
* @param mouseY
* @param mouseButton
*/
@Override
void mouseReleased(int mouseX, int mouseY, int mouseButton)
{
this.scrollPane.mouseReleased(mouseX, mouseY, mouseButton);
}
/**
* @param mouseX
* @param mouseY
*/
@Override
void mouseMoved(int mouseX, int mouseY)
{
}
/**
* @param keyChar
* @param keyCode
*/
@Override
void keyPressed(char keyChar, int keyCode)
{
if (keyCode == Keyboard.KEY_ESCAPE) this.close();
if (keyCode == Keyboard.KEY_SPACE) this.actionPerformed(this.chkScale);
this.scrollPane.keyPressed(keyChar, keyCode);
}
private void postLog()
{
this.btnUpload.enabled = false;
StringBuilder completeLog = new StringBuilder();
for (String logLine : this.logEntries)
{
completeLog.append(logLine).append("\r\n");
}
LiteLoaderLogger.info("Uploading log file to liteloader...");
Session session = this.mc.getSession();
this.logUpload = new LiteLoaderLogUpload(session.getUsername(), session.getPlayerID(), completeLog.toString());
this.logUpload.start();
}
private void openURI(URI uri)
{
try
{
Class<?> desktop = Class.forName("java.awt.Desktop");
Object instance = desktop.getMethod("getDesktop").invoke(null);
desktop.getMethod("browse", URI.class).invoke(instance, uri);
}
catch (Throwable th) {}
}
}

View file

@ -0,0 +1,295 @@
package com.mumfrey.liteloader.client.gui;
import static com.mumfrey.liteloader.gl.GL.*;
import static com.mumfrey.liteloader.gl.GLClippingPlanes.*;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.resources.I18n;
import org.lwjgl.input.Keyboard;
import com.mumfrey.liteloader.LiteMod;
import com.mumfrey.liteloader.api.ModInfoDecorator;
import com.mumfrey.liteloader.client.gui.modlist.ModList;
import com.mumfrey.liteloader.client.gui.modlist.ModListContainer;
import com.mumfrey.liteloader.core.LiteLoaderMods;
import com.mumfrey.liteloader.launch.LoaderEnvironment;
import com.mumfrey.liteloader.modconfig.ConfigManager;
import com.mumfrey.liteloader.modconfig.ConfigPanel;
/**
* Mods panel
*
* @author Adam Mummery-Smith
*/
public class GuiPanelMods extends GuiPanel implements ModListContainer
{
private static final int SCROLLBAR_WIDTH = 5;
private final GuiLiteLoaderPanel parentScreen;
private final ConfigManager configManager;
/**
* List of enumerated mods
*/
private ModList modList;
/**
* Enable / disable button
*/
private GuiButton btnToggle;
/**
* Config button
*/
private GuiButton btnConfig;
/**
* Height of all the items in the list
*/
private int listHeight = 100;
/**
* Scroll bar control for the mods list
*/
private GuiSimpleScrollBar scrollBar = new GuiSimpleScrollBar();
public GuiPanelMods(GuiLiteLoaderPanel parentScreen, Minecraft minecraft, LiteLoaderMods mods, LoaderEnvironment environment,
ConfigManager configManager, int brandColour, List<ModInfoDecorator> decorators)
{
super(minecraft);
this.parentScreen = parentScreen;
this.configManager = configManager;
this.modList = new ModList(this, minecraft, mods, environment, configManager, brandColour, decorators);
}
@Override
public GuiLiteLoaderPanel getParentScreen()
{
return this.parentScreen;
}
@Override
public void setConfigButtonVisible(boolean visible)
{
this.btnConfig.visible = visible;
}
@Override
public void setEnableButtonVisible(boolean visible)
{
this.btnToggle.visible = visible;
}
@Override
public void setEnableButtonText(String displayString)
{
this.btnToggle.displayString = displayString;
}
@Override
boolean stealFocus()
{
return false;
}
@Override
void setSize(int width, int height)
{
super.setSize(width, height);
int rightPanelLeftEdge = MARGIN + 4 + (this.width - MARGIN - MARGIN - 4) / 2;
this.controls.clear();
this.controls.add(this.btnToggle = new GuiButton(0, rightPanelLeftEdge, this.height - GuiLiteLoaderPanel.PANEL_BOTTOM - 24, 90, 20,
I18n.format("gui.enablemod")));
this.controls.add(this.btnConfig = new GuiButton(1, rightPanelLeftEdge + 92, this.height - GuiLiteLoaderPanel.PANEL_BOTTOM - 24, 69, 20,
I18n.format("gui.modsettings")));
this.modList.setSize(width, height);
}
@Override
void onTick()
{
this.modList.onTick();
}
@Override
void onHidden()
{
}
@Override
void onShown()
{
}
@Override
void mousePressed(int mouseX, int mouseY, int mouseButton)
{
if (mouseButton == 0)
{
if (this.scrollBar.wasMouseOver())
{
this.scrollBar.setDragging(true);
}
if (mouseY > GuiLiteLoaderPanel.PANEL_TOP && mouseY < this.height - GuiLiteLoaderPanel.PANEL_BOTTOM)
{
this.modList.mousePressed(mouseX, mouseY, mouseButton);
}
}
super.mousePressed(mouseX, mouseY, mouseButton);
}
@Override
void keyPressed(char keyChar, int keyCode)
{
if (keyCode == Keyboard.KEY_ESCAPE)
{
this.parentScreen.onToggled();
return;
}
else if (this.modList.keyPressed(keyChar, keyCode))
{
// Suppress further handling
}
else if (keyCode == Keyboard.KEY_F3)
{
this.parentScreen.showLogPanel();
}
else if (keyCode == Keyboard.KEY_F1)
{
this.parentScreen.showAboutPanel();
}
}
@Override
void mouseMoved(int mouseX, int mouseY)
{
}
@Override
void mouseReleased(int mouseX, int mouseY, int mouseButton)
{
if (mouseButton == 0)
{
this.scrollBar.setDragging(false);
this.modList.mouseReleased(mouseX, mouseY, mouseButton);
}
}
@Override
void mouseWheelScrolled(int mouseWheelDelta)
{
if (!this.modList.mouseWheelScrolled(mouseWheelDelta))
{
this.scrollBar.offsetValue(-mouseWheelDelta / 8);
}
}
@Override
public void showConfig()
{
this.actionPerformed(this.btnConfig);
}
@Override
void actionPerformed(GuiButton control)
{
if (control.id == 0)
{
this.modList.toggleSelectedMod();
}
if (control.id == 1)
{
Class<? extends LiteMod> modClass = this.modList.getSelectedModClass();
if (modClass != null)
{
ConfigPanel panel = this.configManager.getPanel(modClass);
LiteMod mod = this.modList.getSelectedModInstance();
this.parentScreen.openConfigPanel(panel, mod);
}
}
}
@Override
void draw(int mouseX, int mouseY, float partialTicks)
{
this.parentScreen.drawInfoPanel(mouseX, mouseY, partialTicks, 0, GuiLiteLoaderPanel.PANEL_BOTTOM);
int innerWidth = this.width - MARGIN - MARGIN - 4;
int panelWidth = innerWidth / 2;
int panelHeight = this.height - GuiLiteLoaderPanel.PANEL_BOTTOM - GuiLiteLoaderPanel.PANEL_TOP;
this.drawModsList(mouseX, mouseY, partialTicks, panelWidth, panelHeight);
int left = MARGIN + panelWidth;
int top = GuiLiteLoaderPanel.PANEL_TOP;
int spaceForButtons = (this.btnConfig.visible || this.btnToggle.visible ? 28 : 0);
int bottom = this.height - GuiLiteLoaderPanel.PANEL_BOTTOM - spaceForButtons;
glEnableClipping(left, this.width - MARGIN, top, bottom);
this.modList.drawModPanel(mouseX, mouseY, partialTicks, left, top, this.width - MARGIN - left, panelHeight - spaceForButtons);
glDisableClipping();
super.draw(mouseX, mouseY, partialTicks);
}
/**
* @param mouseX
* @param mouseY
* @param partialTicks
* @param width
* @param height
*/
private void drawModsList(int mouseX, int mouseY, float partialTicks, int width, int height)
{
this.scrollBar.drawScrollBar(mouseX, mouseY, partialTicks, MARGIN + width - SCROLLBAR_WIDTH, GuiLiteLoaderPanel.PANEL_TOP, SCROLLBAR_WIDTH,
height, this.listHeight);
// clip outside of scroll area
glEnableClipping(MARGIN, MARGIN + width - SCROLLBAR_WIDTH - 1, GuiLiteLoaderPanel.PANEL_TOP, this.height - GuiLiteLoaderPanel.PANEL_BOTTOM);
// handle scrolling
glPushMatrix();
glTranslatef(0.0F, GuiLiteLoaderPanel.PANEL_TOP - this.scrollBar.getValue(), 0.0F);
mouseY -= (GuiLiteLoaderPanel.PANEL_TOP - this.scrollBar.getValue());
this.listHeight = this.modList.drawModList(mouseX, mouseY, partialTicks, MARGIN, 0, width - SCROLLBAR_WIDTH - 1, height);
this.scrollBar.setMaxValue(this.listHeight - height);
glPopMatrix();
glDisableClipping();
}
@Override
public void scrollTo(int yPosTop, int yPosBottom)
{
// Mod is above the top of the visible window
if (yPosTop < this.scrollBar.getValue())
{
this.scrollBar.setValue(yPosTop);
return;
}
int panelHeight = this.height - GuiLiteLoaderPanel.PANEL_BOTTOM - GuiLiteLoaderPanel.PANEL_TOP;
// Mod is below the bottom of the visible window
if (yPosBottom - this.scrollBar.getValue() > panelHeight)
{
this.scrollBar.setValue(yPosBottom - panelHeight);
}
}
}

View file

@ -0,0 +1,152 @@
package com.mumfrey.liteloader.client.gui;
import org.lwjgl.input.Keyboard;
import com.mumfrey.liteloader.core.LiteLoader;
import com.mumfrey.liteloader.interfaces.PanelManager;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.resources.I18n;
class GuiPanelSettings extends GuiPanel
{
private GuiLiteLoaderPanel parentScreen;
private GuiCheckbox chkShowTab, chkNoHide, chkForceUpdate;
private boolean hide;
private String[] helpText = new String[5];
GuiPanelSettings(GuiLiteLoaderPanel parentScreen, Minecraft minecraft)
{
super(minecraft);
this.parentScreen = parentScreen;
this.helpText[0] = I18n.format("gui.settings.showtab.help1");
this.helpText[1] = I18n.format("gui.settings.showtab.help2");
this.helpText[2] = I18n.format("gui.settings.notabhide.help1");
this.helpText[3] = I18n.format("gui.settings.forceupdate.help1");
this.helpText[4] = I18n.format("gui.settings.forceupdate.help2");
}
@Override
public void close()
{
this.hide = true;
}
@Override
boolean isCloseRequested()
{
boolean hide = this.hide;
this.hide = false;
return hide;
}
@Override
void setSize(int width, int height)
{
super.setSize(width, height);
this.controls.add(new GuiButton(-1, this.width - 99 - MARGIN, this.height - BOTTOM + 9, 100, 20, I18n.format("gui.done")));
this.controls.add(this.chkShowTab = new GuiCheckbox(0, 34, 90, I18n.format("gui.settings.showtab.label")));
this.controls.add(this.chkNoHide = new GuiCheckbox(1, 34, 128, I18n.format("gui.settings.notabhide.label")));
this.controls.add(this.chkForceUpdate = new GuiCheckbox(2, 34, 158, I18n.format("gui.settings.forceupdate.label")));
this.updateCheckBoxes();
}
private void updateCheckBoxes()
{
PanelManager<?> panelManager = LiteLoader.getModPanelManager();
this.chkShowTab.checked = panelManager.isTabVisible();
this.chkNoHide.checked = panelManager.isTabAlwaysExpanded();
this.chkForceUpdate.checked = panelManager.isForceUpdateEnabled();
}
private void updateSettings()
{
PanelManager<?> panelManager = LiteLoader.getModPanelManager();
panelManager.setTabVisible(this.chkShowTab.checked);
panelManager.setTabAlwaysExpanded(this.chkNoHide.checked);
panelManager.setForceUpdateEnabled(this.chkForceUpdate.checked);
}
@Override
void draw(int mouseX, int mouseY, float partialTicks)
{
this.parentScreen.drawInfoPanel(mouseX, mouseY, partialTicks, 0, 38);
FontRenderer fontRenderer = this.mc.fontRendererObj;
int brandColour = this.parentScreen.getBrandColour();
fontRenderer.drawString(this.helpText[0], 50, 104, brandColour);
fontRenderer.drawString(this.helpText[1], 50, 114, brandColour);
fontRenderer.drawString(this.helpText[2], 50, 142, brandColour);
fontRenderer.drawString(this.helpText[3], 50, 172, brandColour);
fontRenderer.drawString(this.helpText[4], 50, 182, brandColour);
super.draw(mouseX, mouseY, partialTicks);
}
@Override
void actionPerformed(GuiButton control)
{
if (control.id == -1)
{
this.close();
return;
}
if (control instanceof GuiCheckbox)
{
((GuiCheckbox)control).checked = !((GuiCheckbox)control).checked;
this.updateSettings();
}
}
@Override
void keyPressed(char keyChar, int keyCode)
{
if (keyCode == Keyboard.KEY_ESCAPE)
{
this.close();
}
}
@Override
void onTick()
{
}
@Override
void onHidden()
{
}
@Override
void onShown()
{
}
@Override
void mouseMoved(int mouseX, int mouseY)
{
}
@Override
void mouseReleased(int mouseX, int mouseY, int mouseButton)
{
}
@Override
void mouseWheelScrolled(int mouseWheelDelta)
{
}
}

View file

@ -0,0 +1,232 @@
package com.mumfrey.liteloader.client.gui;
import java.net.URI;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.resources.I18n;
import org.lwjgl.input.Keyboard;
import com.mumfrey.liteloader.core.LiteLoaderUpdateSite;
import com.mumfrey.liteloader.launch.ClassPathUtilities;
import com.mumfrey.liteloader.launch.LoaderProperties;
import com.mumfrey.liteloader.update.UpdateSite;
/**
* "Check for updates" panel which docks in the mod info screen
*
* @author Adam Mummery-Smith
*/
class GuiPanelUpdateCheck extends GuiPanel
{
private static final int WHITE = 0xFFFFFFFF;
/**
* URI to open if a new version is available
*/
private static final URI DOWNLOAD_URI = URI.create("http://dl.liteloader.com");
private final GuiLiteLoaderPanel parentScreen;
/**
* Update site to contact
*/
private final UpdateSite updateSite;
/**
* Panel title
*/
private final String panelTitle;
/**
* Buttons
*/
private GuiButton btnCheck, btnDownload;
/**
* Throbber frame
*/
private int throb;
private boolean canForceUpdate, updateForced;
public GuiPanelUpdateCheck(GuiLiteLoaderPanel parentScreen, Minecraft minecraft, UpdateSite updateSite, String updateName,
LoaderProperties properties)
{
super(minecraft);
this.parentScreen = parentScreen;
this.updateSite = updateSite;
this.panelTitle = I18n.format("gui.updates.title", updateName);
this.canForceUpdate = (updateSite instanceof LiteLoaderUpdateSite && ((LiteLoaderUpdateSite)updateSite).canForceUpdate(properties));
}
@Override
void setSize(int width, int height)
{
super.setSize(width, height);
this.controls.add(new GuiButton(0, this.width - 99 - MARGIN, this.height - BOTTOM + 9, 100, 20,
this.updateForced ? I18n.format("gui.exitgame") : I18n.format("gui.done")));
this.controls.add(this.btnCheck = new GuiButton(1, MARGIN + 16, TOP + 16, 100, 20,
I18n.format("gui.checknow")));
this.controls.add(this.btnDownload = new GuiButton(2, MARGIN + 16, TOP + 118, 100, 20,
this.canForceUpdate ? I18n.format("gui.forceupdate") : I18n.format("gui.downloadupdate")));
}
@Override
void draw(int mouseX, int mouseY, float partialTicks)
{
FontRenderer fontRenderer = this.mc.fontRendererObj;
// Draw panel title
fontRenderer.drawString(this.panelTitle, MARGIN, TOP - 14, GuiPanelUpdateCheck.WHITE);
// Draw top and bottom horizontal bars
drawRect(MARGIN, TOP - 4, this.width - MARGIN, TOP - 3, 0xFF999999);
drawRect(MARGIN, this.height - BOTTOM + 2, this.width - MARGIN, this.height - BOTTOM + 3, 0xFF999999);
this.btnCheck.enabled = !this.updateForced && !this.updateSite.isCheckInProgress();
this.btnDownload.visible = false;
if (this.updateSite.isCheckInProgress())
{
this.drawThrobber(MARGIN, TOP + 40, this.throb);
fontRenderer.drawString(I18n.format("gui.updates.status.checking", ""), MARGIN + 18, TOP + 44, GuiPanelUpdateCheck.WHITE);
}
else if (this.updateSite.isCheckComplete())
{
boolean success = this.updateSite.isCheckSucceess();
String status = success ? I18n.format("gui.updates.status.success") : I18n.format("gui.updates.status.failed");
fontRenderer.drawString(I18n.format("gui.updates.status.checking", status), MARGIN + 18, TOP + 44, GuiPanelUpdateCheck.WHITE);
if (success)
{
fontRenderer.drawString(I18n.format("gui.updates.available.title"), MARGIN + 18, TOP + 70, GuiPanelUpdateCheck.WHITE);
if (this.updateSite.isUpdateAvailable())
{
this.btnDownload.visible = !this.updateForced;
fontRenderer.drawString(I18n.format("gui.updates.available.newversion"), MARGIN + 18, TOP + 84, GuiPanelUpdateCheck.WHITE);
fontRenderer.drawString(I18n.format("gui.updates.available.version", this.updateSite.getAvailableVersion()),
MARGIN + 18, TOP + 94, GuiPanelUpdateCheck.WHITE);
fontRenderer.drawString(I18n.format("gui.updates.available.date", this.updateSite.getAvailableVersionDate()),
MARGIN + 18, TOP + 104, GuiPanelUpdateCheck.WHITE);
if (this.updateForced)
{
fontRenderer.drawString(I18n.format("gui.updates.forced"), MARGIN + 18, TOP + 144, 0xFFFFAA00);
}
}
else
{
fontRenderer.drawString(I18n.format("gui.updates.available.nonewversion"), MARGIN + 18, TOP + 84, GuiPanelUpdateCheck.WHITE);
}
}
}
else
{
fontRenderer.drawString(I18n.format("gui.updates.status.idle"), MARGIN + 18, TOP + 44, GuiPanelUpdateCheck.WHITE);
}
super.draw(mouseX, mouseY, partialTicks);
}
@Override
public void close()
{
if (this.updateForced)
{
return;
}
super.close();
}
/**
* @param control
*/
@Override
void actionPerformed(GuiButton control)
{
if (control.id == 0)
{
if (this.updateForced)
{
ClassPathUtilities.terminateRuntime(0);
return;
}
this.close();
}
if (control.id == 1) this.updateSite.beginUpdateCheck();
if (control.id == 2)
{
if (this.canForceUpdate && ((LiteLoaderUpdateSite)this.updateSite).forceUpdate())
{
this.updateForced = true;
this.parentScreen.setToggleable(false);
ScaledResolution sr = new ScaledResolution(this.mc, this.mc.displayWidth, this.mc.displayHeight);
this.parentScreen.setWorldAndResolution(this.mc, sr.getScaledWidth(), sr.getScaledHeight());
}
else
{
this.openURI(GuiPanelUpdateCheck.DOWNLOAD_URI);
}
this.btnDownload.enabled = false;
}
}
private void openURI(URI uri)
{
try
{
Class<?> desktop = Class.forName("java.awt.Desktop");
Object instance = desktop.getMethod("getDesktop").invoke(null);
desktop.getMethod("browse", URI.class).invoke(instance, uri);
}
catch (Throwable th) {}
}
@Override
void onTick()
{
this.throb++;
}
@Override
void onHidden()
{
}
@Override
void onShown()
{
}
@Override
void keyPressed(char keyChar, int keyCode)
{
if (keyCode == Keyboard.KEY_ESCAPE) this.close();
}
@Override
void mouseMoved(int mouseX, int mouseY)
{
}
@Override
void mouseReleased(int mouseX, int mouseY, int mouseButton)
{
}
@Override
void mouseWheelScrolled(int mouseWheelDelta)
{
}
}

View file

@ -0,0 +1,208 @@
package com.mumfrey.liteloader.client.gui;
import static com.mumfrey.liteloader.gl.GL.*;
import static com.mumfrey.liteloader.gl.GLClippingPlanes.*;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import org.lwjgl.input.Keyboard;
/**
* Basic non-interactive scrollable panel using OpenGL clipping planes
*
* TODO handle interaction
*
* @author Adam Mummery-Smith
*/
class GuiScrollPanel extends GuiPanel
{
private ScrollPanelContent content;
/**
* Scroll bar for the panel
*/
private GuiSimpleScrollBar scrollBar = new GuiSimpleScrollBar();
/**
* Left edge coord - specified
*/
private int left;
/**
* Top edge coord - specified
*/
private int top;
/**
*
*/
private int contentHeight;
public GuiScrollPanel(Minecraft minecraft, ScrollPanelContent content, int left, int top, int width, int height)
{
super(minecraft);
this.setContent(content);
}
public void setContent(ScrollPanelContent content)
{
if (content == null)
{
throw new IllegalArgumentException("Scroll pane content can not be null");
}
this.content = content;
}
@Override
void setSize(int width, int height)
{
this.width = width;
this.height = height;
this.updateHeight();
}
public void setSizeAndPosition(int left, int top, int width, int height)
{
this.left = left;
this.top = top;
this.setSize(width, height);
}
public void updateHeight()
{
this.contentHeight = this.content.getScrollPanelContentHeight(this);
this.scrollBar.setMaxValue(this.contentHeight - this.height);
}
public void scrollToBottom()
{
this.scrollBar.setValue(this.contentHeight);
}
public void scrollToTop()
{
this.scrollBar.setValue(0);
}
public void scrollBy(int amount)
{
this.scrollBar.offsetValue(amount);
}
public GuiButton addControl(GuiButton control)
{
this.controls.add(control);
return control;
}
/**
* Draw the panel and chrome
*
* @param mouseX
* @param mouseY
* @param partialTicks
*/
@Override
public void draw(int mouseX, int mouseY, float partialTicks)
{
int scrollPosition = this.scrollBar.getValue();
// Clip rect
glEnableClipping(this.left, this.left + this.width - 6, this.top, this.top + this.height);
// Offset by scroll
glPushMatrix();
glTranslatef(this.left, this.top - scrollPosition, 0.0F);
this.content.drawScrollPanelContent(this, mouseX, mouseY, partialTicks, scrollPosition, this.height);
super.draw(mouseX - this.left, mouseY + scrollPosition - this.top, partialTicks);
// Disable clip rect
glDisableClipping();
// Restore transform
glPopMatrix();
// Update and draw scroll bar
this.scrollBar.drawScrollBar(mouseX, mouseY, partialTicks, this.left + this.width - 5, this.top, 5, this.height,
Math.max(this.height, this.contentHeight));
}
@Override
public void mouseWheelScrolled(int mouseWheelDelta)
{
this.scrollBy(-mouseWheelDelta / 8);
}
@Override
public void mousePressed(int mouseX, int mouseY, int mouseButton)
{
mouseY += this.scrollBar.getValue() - this.top;
mouseX -= this.left;
super.mousePressed(mouseX, mouseY, mouseButton);
if (mouseX > 0 && mouseX < this.width && mouseY > 0 && mouseY < this.contentHeight)
{
this.content.scrollPanelMousePressed(this, mouseX, mouseY, mouseButton);
}
if (mouseButton == 0)
{
if (this.scrollBar.wasMouseOver())
{
this.scrollBar.setDragging(true);
}
}
}
@Override
public void mouseReleased(int mouseX, int mouseY, int mouseButton)
{
if (mouseButton == 0)
{
this.scrollBar.setDragging(false);
}
}
@Override
public void keyPressed(char keyChar, int keyCode)
{
if (keyCode == Keyboard.KEY_UP) this.scrollBar.offsetValue(-10);
if (keyCode == Keyboard.KEY_DOWN) this.scrollBar.offsetValue(10);
if (keyCode == Keyboard.KEY_PRIOR) this.scrollBar.offsetValue(-this.height + 10);
if (keyCode == Keyboard.KEY_NEXT) this.scrollBar.offsetValue(this.height - 10);
if (keyCode == Keyboard.KEY_HOME) this.scrollBar.setValue(0);
if (keyCode == Keyboard.KEY_END) this.scrollBar.setValue(this.contentHeight);
}
@Override
void onTick()
{
}
@Override
void onHidden()
{
}
@Override
void onShown()
{
}
@Override
void mouseMoved(int mouseX, int mouseY)
{
}
@Override
void actionPerformed(GuiButton control)
{
this.content.scrollPanelActionPerformed(this, control);
}
}

View file

@ -0,0 +1,153 @@
package com.mumfrey.liteloader.client.gui;
import net.minecraft.client.gui.Gui;
/**
* Extremely simple scrollbar implementation
*
* @author Adam Mummery-Smith
*/
public class GuiSimpleScrollBar extends Gui
{
/**
* Current value
*/
private int value = 0;
/**
* Current maximum value
*/
private int maxValue = 100;
private int backColour = 0x44FFFFFF;
private int foreColour = 0xFFFFFFFF;
/**
* True if mouse was over the drag bar when last drawn
*/
private boolean mouseOver = false;
/**
* True if currently dragging the scroll bar
*/
private boolean dragging = false;
/**
* Value prior to starting to drag
*/
private int mouseDownValue = 0;
/**
* mouse Y coordinate prior to starting to drag
*/
private int mouseDownY = 0;
/**
* Get the current scroll value
*/
public int getValue()
{
return this.value;
}
/**
* Set the scroll value, the value is clamped between 0 and the current max
* value.
*/
public void setValue(int value)
{
this.value = Math.min(Math.max(value, 0), this.maxValue);
}
/**
* Offset the scroll value by the specified amount, the value is clamped
* between 0 and the current max value.
*/
public void offsetValue(int offset)
{
this.setValue(this.value + offset);
}
/**
* Get the current max value
*/
public int getMaxValue()
{
return this.maxValue;
}
/**
* Sets the current max value
*/
public void setMaxValue(int maxValue)
{
this.maxValue = Math.max(0, maxValue);
this.value = Math.min(this.value, this.maxValue);
}
/**
* Returns true if the mouse was over the drag bar on the last render
*/
public boolean wasMouseOver()
{
return this.mouseOver;
}
/**
* Set the current dragging state
*/
public void setDragging(boolean dragging)
{
this.dragging = dragging;
}
/**
* Draw the scroll bar
*
* @param mouseX
* @param mouseY
* @param partialTicks
* @param xPosition
* @param yPosition
* @param width
* @param height
* @param totalHeight
*/
public void drawScrollBar(int mouseX, int mouseY, float partialTicks, int xPosition, int yPosition, int width, int height, int totalHeight)
{
drawRect(xPosition, yPosition, xPosition + width, yPosition + height, this.backColour);
if (totalHeight > 0)
{
int slideHeight = height - 2;
float pct = Math.min(1.0F, (float)slideHeight / (float)totalHeight);
int barHeight = (int)(pct * slideHeight);
int barTravel = slideHeight - barHeight;
int barPosition = yPosition + 1 + (this.maxValue > 0 ? (int)((this.value / (float)this.maxValue) * barTravel) : 0);
drawRect(xPosition + 1, barPosition, xPosition + width - 1, barPosition + barHeight, this.foreColour);
this.mouseOver = mouseX > xPosition && mouseX < xPosition + width && mouseY > barPosition && mouseY < barPosition + barHeight;
this.handleDrag(mouseY, barTravel);
}
}
/**
* @param mouseY
* @param barTravel
*/
public void handleDrag(int mouseY, int barTravel)
{
if (this.dragging)
{
// Convert pixel delta to value delta
float valuePerPixel = (float)this.maxValue / barTravel;
this.setValue((int)(this.mouseDownValue + ((mouseY - this.mouseDownY) * valuePerPixel)));
}
else
{
this.mouseDownY = mouseY;
this.mouseDownValue = this.value;
}
}
}

View file

@ -0,0 +1,14 @@
package com.mumfrey.liteloader.client.gui;
import net.minecraft.client.gui.GuiButton;
public interface ScrollPanelContent
{
public abstract int getScrollPanelContentHeight(GuiScrollPanel source);
public abstract void drawScrollPanelContent(GuiScrollPanel source, int mouseX, int mouseY, float partialTicks, int scrollAmt, int visibleHeight);
public abstract void scrollPanelActionPerformed(GuiScrollPanel source, GuiButton control);
public abstract void scrollPanelMousePressed(GuiScrollPanel source, int mouseX, int mouseY, int mouseButton);
}

View file

@ -0,0 +1,155 @@
package com.mumfrey.liteloader.client.gui.modlist;
import static com.mumfrey.liteloader.gl.GL.*;
import static com.mumfrey.liteloader.gl.GLClippingPlanes.*;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.resources.I18n;
import com.google.common.base.Strings;
import com.mumfrey.liteloader.client.api.LiteLoaderBrandingProvider;
import com.mumfrey.liteloader.client.gui.GuiSimpleScrollBar;
import com.mumfrey.liteloader.client.util.render.IconAbsolute;
import com.mumfrey.liteloader.core.ModInfo;
import com.mumfrey.liteloader.util.render.IconTextured;
public class GuiModInfoPanel extends Gui
{
private static final int TITLE_COLOUR = GuiModListPanel.WHITE;
private static final int AUTHORS_COLOUR = GuiModListPanel.WHITE;
private static final int DIVIDER_COLOUR = GuiModListPanel.GREY;
private static final int DESCRIPTION_COLOUR = GuiModListPanel.WHITE;
private static final IconAbsolute infoIcon = new IconAbsolute(LiteLoaderBrandingProvider.ABOUT_TEXTURE, "Info", 12, 12, 146, 92, 158, 104);
private final ModListEntry owner;
private final FontRenderer fontRenderer;
private final int brandColour;
private final ModInfo<?> modInfo;
private GuiSimpleScrollBar scrollBar = new GuiSimpleScrollBar();
private boolean mouseOverPanel, mouseOverScrollBar;
private boolean showHelp;
private String helpTitle, helpText;
public GuiModInfoPanel(ModListEntry owner, FontRenderer fontRenderer, int brandColour, ModInfo<?> modInfo)
{
this.owner = owner;
this.fontRenderer = fontRenderer;
this.brandColour = brandColour;
this.modInfo = modInfo;
}
public void draw(int mouseX, int mouseY, float partialTicks, int xPosition, int yPosition, int width, int height)
{
int bottom = height + yPosition;
int yPos = yPosition + 2;
this.mouseOverPanel = this.isMouseOver(mouseX, mouseY, xPosition, yPos, width, height);
this.fontRenderer.drawString(this.owner.getTitleText(), xPosition + 5, yPos, GuiModInfoPanel.TITLE_COLOUR); yPos += 10;
this.fontRenderer.drawString(this.owner.getVersionText(), xPosition + 5, yPos, GuiModListPanel.VERSION_TEXT_COLOUR); yPos += 10;
drawRect(xPosition + 5, yPos, xPosition + width, yPos + 1, GuiModInfoPanel.DIVIDER_COLOUR); yPos += 4; // divider
this.fontRenderer.drawString(I18n.format("gui.about.authors") + ": \2477" + this.modInfo.getAuthor(), xPosition + 5, yPos,
GuiModInfoPanel.AUTHORS_COLOUR); yPos += 10;
if (!Strings.isNullOrEmpty(this.modInfo.getURL()))
{
this.fontRenderer.drawString(this.modInfo.getURL(), xPosition + 5, yPos, GuiModListPanel.BLEND_2THRDS & this.brandColour); yPos += 10;
}
drawRect(xPosition + 5, yPos, xPosition + width, yPos + 1, GuiModInfoPanel.DIVIDER_COLOUR); yPos += 4; // divider
drawRect(xPosition + 5, bottom - 1, xPosition + width, bottom, GuiModInfoPanel.DIVIDER_COLOUR); // divider
glEnableClipping(-1, -1, yPos, bottom - 3);
int scrollHeight = bottom - yPos - 3;
int contentHeight = this.drawContent(xPosition, width, yPos);
this.scrollBar.setMaxValue(contentHeight - scrollHeight);
this.scrollBar.drawScrollBar(mouseX, mouseY, partialTicks, xPosition + width - 5, yPos, 5, scrollHeight, contentHeight);
this.mouseOverScrollBar = this.isMouseOver(mouseX, mouseY, xPosition + width - 5, yPos, 5, scrollHeight);
}
private int drawContent(int xPosition, int width, int yPos)
{
yPos -= this.scrollBar.getValue();
if (this.showHelp)
{
this.drawIcon(xPosition + 3, yPos, GuiModInfoPanel.infoIcon); yPos += 2;
this.fontRenderer.drawString(this.helpTitle, xPosition + 17, yPos, this.brandColour); yPos += 12;
return this.drawText(xPosition + 17, width - 24, yPos, this.helpText, GuiModInfoPanel.DESCRIPTION_COLOUR) + 15;
}
return this.drawText(xPosition + 5, width - 11, yPos, this.modInfo.getDescription(), GuiModInfoPanel.DESCRIPTION_COLOUR);
}
protected void drawIcon(int xPosition, int yPosition, IconTextured icon)
{
glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
Minecraft.getMinecraft().getTextureManager().bindTexture(icon.getTextureResource());
glEnableBlend();
this.drawTexturedModalRect(xPosition, yPosition, icon.getUPos(), icon.getVPos(), icon.getIconWidth(), icon.getIconHeight());
glDisableBlend();
}
private int drawText(int xPosition, int width, int yPos, String text, int colour)
{
int totalHeight = this.fontRenderer.splitStringWidth(text, width);
this.fontRenderer.drawSplitString(text, xPosition, yPos, width, colour);
return totalHeight;
}
private boolean isMouseOver(int mouseX, int mouseY, int x, int y, int width, int height)
{
return mouseX > x && mouseX < x + width && mouseY > y && mouseY < y + height;
}
public void mousePressed()
{
if (this.mouseOverScrollBar)
{
this.scrollBar.setDragging(true);
}
}
public void mouseReleased()
{
this.scrollBar.setDragging(false);
}
public boolean mouseWheelScrolled(int mouseWheelDelta)
{
if (this.mouseOverPanel)
{
this.scrollBar.offsetValue(-mouseWheelDelta / 8);
return true;
}
return false;
}
public void displayHelpMessage(String title, String text)
{
this.showHelp = true;
this.helpTitle = I18n.format(title);
this.helpText = I18n.format(text);
this.scrollBar.setValue(0);
}
public void clearHelpMessage()
{
this.showHelp = false;
}
}

View file

@ -0,0 +1,271 @@
package com.mumfrey.liteloader.client.gui.modlist;
import static com.mumfrey.liteloader.gl.GL.*;
import static com.mumfrey.liteloader.gl.GLClippingPlanes.*;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.Gui;
import com.mumfrey.liteloader.api.ModInfoDecorator;
import com.mumfrey.liteloader.client.gui.GuiLiteLoaderPanel;
import com.mumfrey.liteloader.core.ModInfo;
import com.mumfrey.liteloader.util.render.IconClickable;
import com.mumfrey.liteloader.util.render.IconTextured;
public class GuiModListPanel extends Gui
{
static final int BLACK = 0xFF000000;
static final int DARK_GREY = 0xB0333333;
static final int GREY = 0xFF999999;
static final int WHITE = 0xFFFFFFFF;
static final int BLEND_2THRDS = 0xB0FFFFFF;
static final int BLEND_HALF = 0x80FFFFFF;
static final int API_COLOUR = 0xFFAA00AA;
static final int EXTERNAL_ENTRY_COLOUR = 0xFF47D1AA;
static final int MISSING_DEPENDENCY_COLOUR = 0xFFFFAA00;
static final int ERROR_COLOUR = 0xFFFF5555;
static final int ERROR_GRADIENT_COLOUR = 0xFFAA0000;
static final int ERROR_GRADIENT_COLOUR2 = 0xFF550000;
static final int VERSION_TEXT_COLOUR = GuiModListPanel.GREY;
static final int GRADIENT_COLOUR2 = GuiModListPanel.BLEND_2THRDS & GuiModListPanel.DARK_GREY;
static final int HANGER_COLOUR = GuiModListPanel.GREY;
static final int HANGER_COLOUR_MOUSEOVER = GuiModListPanel.WHITE;
static final int PANEL_HEIGHT = 32;
static final int PANEL_SPACING = 3;
protected ModListEntry owner;
/**
* For text display
*/
protected final FontRenderer fontRenderer;
protected final int brandColour;
protected final List<ModInfoDecorator> decorators;
protected final ModInfo<?> modInfo;
/**
* True if the mouse was over this mod on the last render
*/
private boolean mouseOver;
private IconClickable mouseOverIcon = null;
private List<IconTextured> modIcons = new ArrayList<IconTextured>();
public GuiModListPanel(ModListEntry owner, FontRenderer fontRenderer, int brandColour, ModInfo<?> modInfo, List<ModInfoDecorator> decorators)
{
this.owner = owner;
this.fontRenderer = fontRenderer;
this.brandColour = brandColour;
this.modInfo = modInfo;
this.decorators = decorators;
for (ModInfoDecorator decorator : this.decorators)
{
decorator.addIcons(modInfo, this.modIcons);
}
}
public void draw(int mouseX, int mouseY, float partialTicks, int xPosition, int yPosition, int width, boolean selected, int pass)
{
if (pass == 0)
{
this.render(mouseX, mouseY, partialTicks, xPosition, yPosition, width, selected);
}
else if (pass == 1)
{
this.postRender(mouseX, mouseY, partialTicks, xPosition, yPosition, width, selected);
}
}
/**
* Draw this list entry as a list item
*
* @param mouseX
* @param mouseY
* @param partialTicks
* @param xPosition
* @param yPosition
* @param width
* @param selected
*/
protected void render(int mouseX, int mouseY, float partialTicks, int xPosition, int yPosition, int width, boolean selected)
{
int gradientColour = this.getGradientColour(selected);
int titleColour = this.getTitleColour(selected);
int statusColour = this.getStatusColour(selected);
this.drawGradientRect(xPosition, yPosition, xPosition + width, yPosition + GuiModListPanel.PANEL_HEIGHT, gradientColour,
GuiModListPanel.GRADIENT_COLOUR2);
String titleText = this.owner.getTitleText();
String versionText = this.owner.getVersionText();
String statusText = this.owner.getStatusText();
for (ModInfoDecorator decorator : this.decorators)
{
String newStatusText = decorator.modifyStatusText(this.modInfo, statusText);
if (newStatusText != null) statusText = newStatusText;
}
this.fontRenderer.drawString(titleText, xPosition + 5, yPosition + 2, titleColour);
this.fontRenderer.drawString(versionText, xPosition + 5, yPosition + 12, GuiModListPanel.VERSION_TEXT_COLOUR);
this.fontRenderer.drawString(statusText, xPosition + 5, yPosition + 22, statusColour);
this.updateMouseOver(mouseX, mouseY, xPosition, yPosition, width);
int hangerColour = this.mouseOver ? GuiModListPanel.HANGER_COLOUR_MOUSEOVER : GuiModListPanel.HANGER_COLOUR;
drawRect(xPosition, yPosition, xPosition + 1, yPosition + PANEL_HEIGHT, hangerColour);
for (ModInfoDecorator decorator : this.decorators)
{
decorator.onDrawListEntry(mouseX, mouseY, partialTicks, xPosition, yPosition, width, GuiModListPanel.PANEL_HEIGHT, selected,
this.modInfo, gradientColour, titleColour, statusColour);
}
}
/**
* @param mouseX
* @param mouseY
* @param xPosition
* @param yPosition
* @param width
*/
protected void updateMouseOver(int mouseX, int mouseY, int xPosition, int yPosition, int width)
{
this.mouseOver = this.isMouseOver(mouseX, mouseY, xPosition, yPosition, width, PANEL_HEIGHT);
}
protected void postRender(int mouseX, int mouseY, float partialTicks, int xPosition, int yPosition, int width, boolean selected)
{
xPosition += (width - 14);
yPosition += (GuiModListPanel.PANEL_HEIGHT - 14);
this.mouseOverIcon = null;
for (IconTextured icon : this.modIcons)
{
xPosition = this.drawPropertyIcon(xPosition, yPosition, icon, mouseX, mouseY);
}
}
protected int drawPropertyIcon(int xPosition, int yPosition, IconTextured icon, int mouseX, int mouseY)
{
glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
Minecraft.getMinecraft().getTextureManager().bindTexture(icon.getTextureResource());
glEnableBlend();
this.drawTexturedModalRect(xPosition, yPosition, icon.getUPos(), icon.getVPos(), icon.getIconWidth(), icon.getIconHeight());
glDisableBlend();
if (mouseX >= xPosition && mouseX <= xPosition + 12 && mouseY >= yPosition && mouseY <= yPosition + 12)
{
String tooltipText = icon.getDisplayText();
if (tooltipText != null)
{
glDisableClipping();
GuiLiteLoaderPanel.drawTooltip(this.fontRenderer, tooltipText, mouseX, mouseY, 4096, 4096, GuiModListPanel.WHITE,
GuiModListPanel.BLEND_HALF & GuiModListPanel.BLACK);
glEnableClipping();
}
if (icon instanceof IconClickable) this.mouseOverIcon = (IconClickable)icon;
}
return xPosition - 14;
}
/**
* @param selected
*/
protected int getGradientColour(boolean selected)
{
return GuiModListPanel.BLEND_2THRDS
& (this.owner.isErrored()
? (selected ? GuiModListPanel.ERROR_GRADIENT_COLOUR : GuiModListPanel.ERROR_GRADIENT_COLOUR2)
: (selected ? (this.owner.isExternal() ? GuiModListPanel.EXTERNAL_ENTRY_COLOUR : this.brandColour) : GuiModListPanel.BLACK));
}
/**
* @param selected
*/
protected int getTitleColour(boolean selected)
{
if (this.owner.isMissingDependencies()) return GuiModListPanel.MISSING_DEPENDENCY_COLOUR;
if (this.owner.isMissingAPIs()) return GuiModListPanel.API_COLOUR;
if (this.owner.isErrored()) return GuiModListPanel.ERROR_COLOUR;
if (!this.owner.isActive()) return GuiModListPanel.GREY;
return this.owner.isExternal() ? GuiModListPanel.EXTERNAL_ENTRY_COLOUR : GuiModListPanel.WHITE;
}
/**
* @param selected
*/
protected int getStatusColour(boolean selected)
{
return this.owner.isExternal() ? GuiModListPanel.EXTERNAL_ENTRY_COLOUR : this.brandColour;
}
public boolean isVisible()
{
return true;
}
public int getSpacing()
{
return GuiModListPanel.PANEL_SPACING;
}
public int getHeight()
{
return GuiModListPanel.PANEL_HEIGHT;
}
public int getTotalHeight()
{
return GuiModListPanel.PANEL_HEIGHT + GuiModListPanel.PANEL_SPACING;
}
protected boolean isMouseOver(int mouseX, int mouseY, int x, int y, int width, int height)
{
return mouseX > x && mouseX < x + width && mouseY > y && mouseY < y + height;
}
public boolean isMouseOverIcon()
{
return this.mouseOver && this.mouseOverIcon != null;
}
public boolean isMouseOver()
{
return this.mouseOver;
}
public void iconClick(Object source)
{
if (this.mouseOverIcon != null)
{
this.mouseOverIcon.onClicked(source, this);
}
}
public void mousePressed(int mouseX, int mouseY, int mouseButton)
{
this.owner.clearHelpMessage();
}
public void displayModHelpMessage(ModInfo<?> mod, String title, String text)
{
this.owner.displayHelpMessage(title, text);
}
}

View file

@ -0,0 +1,53 @@
package com.mumfrey.liteloader.client.gui.modlist;
import java.util.List;
import net.minecraft.client.gui.FontRenderer;
import com.mumfrey.liteloader.api.ModInfoDecorator;
import com.mumfrey.liteloader.core.ModInfo;
public class GuiModListPanelInvalid extends GuiModListPanel
{
private static final int BAD_PANEL_HEIGHT = 22;
public GuiModListPanelInvalid(ModListEntry owner, FontRenderer fontRenderer, int brandColour, ModInfo<?> modInfo,
List<ModInfoDecorator> decorators)
{
super(owner, fontRenderer, brandColour, modInfo, decorators);
}
@Override
protected void render(int mouseX, int mouseY, float partialTicks, int xPosition, int yPosition, int width, boolean selected)
{
int gradientColour = selected ? ERROR_GRADIENT_COLOUR : ERROR_GRADIENT_COLOUR2;
this.drawGradientRect(xPosition, yPosition, xPosition + width, yPosition + 22, gradientColour, GuiModListPanel.GRADIENT_COLOUR2);
String titleText = this.owner.getTitleText();
String reasonText = this.modInfo.getDescription();
this.fontRenderer.drawString(titleText, xPosition + 5, yPosition + 2, 0xFF8888);
this.fontRenderer.drawString(reasonText, xPosition + 5, yPosition + 12, GuiModListPanel.ERROR_GRADIENT_COLOUR);
this.updateMouseOver(mouseX, mouseY, xPosition, yPosition, width);
drawRect(xPosition, yPosition, xPosition + 1, yPosition + 22, ERROR_COLOUR);
}
@Override
protected void postRender(int mouseX, int mouseY, float partialTicks, int xPosition, int yPosition, int width, boolean selected)
{
}
@Override
public int getHeight()
{
return GuiModListPanelInvalid.BAD_PANEL_HEIGHT;
}
@Override
public int getTotalHeight()
{
return GuiModListPanelInvalid.BAD_PANEL_HEIGHT + GuiModListPanel.PANEL_SPACING;
}
}

View file

@ -0,0 +1,273 @@
package com.mumfrey.liteloader.client.gui.modlist;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.I18n;
import org.lwjgl.input.Keyboard;
import com.mumfrey.liteloader.LiteMod;
import com.mumfrey.liteloader.api.ModInfoDecorator;
import com.mumfrey.liteloader.client.gui.GuiLiteLoaderPanel;
import com.mumfrey.liteloader.core.LiteLoaderMods;
import com.mumfrey.liteloader.core.ModInfo;
import com.mumfrey.liteloader.interfaces.Loadable;
import com.mumfrey.liteloader.interfaces.LoadableMod;
import com.mumfrey.liteloader.launch.LoaderEnvironment;
import com.mumfrey.liteloader.modconfig.ConfigManager;
public class ModList
{
private final ModListContainer container;
private final ConfigManager configManager;
/**
* List of enumerated mods
*/
private final List<ModListEntry> mods = new ArrayList<ModListEntry>();
/**
* Currently selected mod
*/
private ModListEntry selectedMod = null;
private boolean hasConfig = false;
public ModList(ModListContainer container, Minecraft minecraft, LiteLoaderMods mods, LoaderEnvironment environment, ConfigManager configManager,
int brandColour, List<ModInfoDecorator> decorators)
{
this.container = container;
this.configManager = configManager;
this.populate(minecraft, mods, environment, brandColour, decorators);
}
/**
* @param minecraft
* @param mods
* @param environment
* @param brandColour
* @param decorators
*/
protected void populate(Minecraft minecraft, LiteLoaderMods mods, LoaderEnvironment environment, int brandColour,
List<ModInfoDecorator> decorators)
{
// Add mods to this treeset first, in order to sort them
Map<String, ModListEntry> sortedMods = new TreeMap<String, ModListEntry>();
// Active mods
for (ModInfo<LoadableMod<?>> mod : mods.getLoadedMods())
{
ModListEntry modListEntry = new ModListEntry(this, mods, environment, minecraft.fontRendererObj, brandColour, decorators, mod);
sortedMods.put(modListEntry.getKey(), modListEntry);
}
// Disabled mods
for (ModInfo<?> disabledMod : mods.getDisabledMods())
{
ModListEntry modListEntry = new ModListEntry(this, mods, environment, minecraft.fontRendererObj, brandColour, decorators, disabledMod);
sortedMods.put(modListEntry.getKey(), modListEntry);
}
// Show bad containers if no other containers are found, should help users realise they have the wrong mod version!
if (sortedMods.size() == 0)
{
for (ModInfo<?> badMod : mods.getBadContainers())
{
ModListEntry modListEntry = new ModListEntry(this, mods, environment, minecraft.fontRendererObj, brandColour, decorators, badMod);
sortedMods.put(modListEntry.getKey(), modListEntry);
}
}
// Injected tweaks
for (ModInfo<Loadable<?>> injectedTweak : mods.getInjectedTweaks())
{
ModListEntry modListEntry = new ModListEntry(this, mods, environment, minecraft.fontRendererObj, brandColour, decorators, injectedTweak);
sortedMods.put(modListEntry.getKey(), modListEntry);
}
// Add the sorted mods to the mods list
this.mods.addAll(sortedMods.values());
// Select the first mod in the list
if (this.mods.size() > 0)
{
this.selectedMod = this.mods.get(0);
}
}
public GuiLiteLoaderPanel getParentScreen()
{
return this.container.getParentScreen();
}
public LiteMod getSelectedModInstance()
{
return this.selectedMod != null ? this.selectedMod.getModInstance() : null;
}
public Class<? extends LiteMod> getSelectedModClass()
{
return this.selectedMod != null ? this.selectedMod.getModClass() : null;
}
public void setSize(int width, int height)
{
this.selectMod(this.selectedMod);
}
public void onTick()
{
for (ModListEntry mod : this.mods)
{
mod.onTick();
}
}
public void mousePressed(int mouseX, int mouseY, int mouseButton)
{
ModListEntry lastSelectedMod = this.selectedMod;
for (ModListEntry mod : this.mods)
{
mod.mousePressed(mouseX, mouseY, mouseButton);
}
if (this.selectedMod != null && this.selectedMod == lastSelectedMod)
{
this.selectedMod.getInfoPanel().mousePressed();
}
}
public boolean keyPressed(char keyChar, int keyCode)
{
if (keyCode == Keyboard.KEY_UP)
{
int selectedIndex = this.mods.indexOf(this.selectedMod) - 1;
if (selectedIndex > -1) this.selectMod(this.mods.get(selectedIndex));
this.scrollSelectedModIntoView();
return true;
}
else if (keyCode == Keyboard.KEY_DOWN)
{
int selectedIndex = this.mods.indexOf(this.selectedMod);
if (selectedIndex > -1 && selectedIndex < this.mods.size() - 1) this.selectMod(this.mods.get(selectedIndex + 1));
this.scrollSelectedModIntoView();
return true;
}
else if (keyCode == Keyboard.KEY_SPACE
|| keyCode == Keyboard.KEY_RETURN
|| keyCode == Keyboard.KEY_NUMPADENTER
|| keyCode == Keyboard.KEY_RIGHT)
{
this.toggleSelectedMod();
return true;
}
return false;
}
public void mouseReleased(int mouseX, int mouseY, int mouseButton)
{
if (this.selectedMod != null)
{
this.selectedMod.getInfoPanel().mouseReleased();
}
}
public boolean mouseWheelScrolled(int mouseWheelDelta)
{
return this.selectedMod != null && this.selectedMod.getInfoPanel().mouseWheelScrolled(mouseWheelDelta);
}
public int drawModList(int mouseX, int mouseY, float partialTicks, int left, int top, int width, int height)
{
this.drawModListPass(mouseX, mouseY, partialTicks, left, top, width, 0);
return this.drawModListPass(mouseX, mouseY, partialTicks, left, top, width, 1);
}
protected int drawModListPass(int mouseX, int mouseY, float partialTicks, int left, int top, int width, int pass)
{
int yPos = top;
for (ModListEntry mod : this.mods)
{
GuiModListPanel panel = mod.getListPanel();
if (panel.isVisible())
{
if (yPos > 0) yPos += panel.getSpacing();
panel.draw(mouseX, mouseY, partialTicks, left, yPos, width, mod == this.selectedMod, pass);
yPos += panel.getHeight();
}
}
return yPos;
}
public void drawModPanel(int mouseX, int mouseY, float partialTicks, int left, int top, int width, int height)
{
if (this.selectedMod != null)
{
this.selectedMod.getInfoPanel().draw(mouseX, mouseY, partialTicks, left, top, width, height);
}
}
/**
* @param mod Mod list entry to select
*/
void selectMod(ModListEntry mod)
{
if (this.selectedMod != null)
{
this.selectedMod.getInfoPanel().mouseReleased();
}
this.selectedMod = mod;
this.hasConfig = false;
this.container.setEnableButtonVisible(false);
this.container.setConfigButtonVisible(false);
if (this.selectedMod != null && this.selectedMod.canBeToggled())
{
this.container.setEnableButtonVisible(true);
this.container.setEnableButtonText(this.selectedMod.willBeEnabled() ? I18n.format("gui.disablemod") : I18n.format("gui.enablemod"));
this.hasConfig = this.configManager.hasPanel(this.selectedMod.getModClass());
this.container.setConfigButtonVisible(this.hasConfig);
}
}
/**
* Toggle the selected mod's enabled status
*/
public void toggleSelectedMod()
{
if (this.selectedMod != null)
{
this.selectedMod.toggleEnabled();
this.selectMod(this.selectedMod);
}
}
private void scrollSelectedModIntoView()
{
if (this.selectedMod == null) return;
int yPos = 0;
for (ModListEntry mod : this.mods)
{
if (mod == this.selectedMod) break;
yPos += mod.getListPanel().getTotalHeight();
}
int modHeight = this.selectedMod.getListPanel().getTotalHeight();
this.container.scrollTo(yPos, yPos + modHeight);
}
public void showConfig(ModListEntry modListEntry)
{
this.container.showConfig();
}
}

View file

@ -0,0 +1,18 @@
package com.mumfrey.liteloader.client.gui.modlist;
import com.mumfrey.liteloader.client.gui.GuiLiteLoaderPanel;
public interface ModListContainer
{
public abstract GuiLiteLoaderPanel getParentScreen();
public abstract void setEnableButtonVisible(boolean visible);
public abstract void setConfigButtonVisible(boolean visible);
public abstract void setEnableButtonText(String displayString);
public abstract void showConfig();
public abstract void scrollTo(int yPos, int modHeight);
}

View file

@ -0,0 +1,334 @@
package com.mumfrey.liteloader.client.gui.modlist;
import java.util.List;
import java.util.Set;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.resources.I18n;
import com.mumfrey.liteloader.LiteMod;
import com.mumfrey.liteloader.api.ModInfoDecorator;
import com.mumfrey.liteloader.core.LiteLoaderMods;
import com.mumfrey.liteloader.core.ModInfo;
import com.mumfrey.liteloader.interfaces.Loadable;
import com.mumfrey.liteloader.interfaces.LoadableMod;
import com.mumfrey.liteloader.launch.LoaderEnvironment;
/**
* Represents a mod in the mod info screen, keeps track of mod information and
* provides methods for displaying the mod in the mod list and drawing the
* selected mod info.
*
* @author Adam Mummery-Smith
*/
public class ModListEntry
{
private final ModList modList;
private final LiteLoaderMods mods;
private final ModInfo<?> modInfo;
private GuiModListPanel listPanel;
private GuiModInfoPanel infoPanel;
/**
* Whether the mod is currently active
*/
private boolean isActive;
private boolean isValid;
private boolean isMissingDependencies;
private boolean isMissingAPIs;
private boolean isErrored;
/**
* True if the mod is missing a dependency which has caused it not to load
*/
private Set<String> missingDependencies;
/**
* True if the mod is missing an API which has caused it not to load
*/
private Set<String> missingAPIs;
/**
* Whether the mod can be toggled, not all mods support this, eg. internal
* mods
*/
private boolean canBeToggled;
/**
* Whether the mod WILL be enabled on the next startup, if the mod is active
* and has been disabled this will be false, and if it's currently disabled
* by has been toggled then it will be true.
*/
private boolean willBeEnabled;
/**
* True if this is not a mod but an external jar
*/
private boolean isExternal;
/**
* Timer used to handle double-clicking on a mod
*/
private int doubleClickTime = 0;
/**
* @param modList
* @param mods
* @param environment
* @param fontRenderer
* @param brandColour
* @param decorators
* @param modInfo
*/
ModListEntry(ModList modList, LiteLoaderMods mods, LoaderEnvironment environment, FontRenderer fontRenderer, int brandColour,
List<ModInfoDecorator> decorators, ModInfo<?> modInfo)
{
this.modList = modList;
this.mods = mods;
this.modInfo = modInfo;
this.isActive = modInfo.isActive();
this.isValid = modInfo.isValid();
this.canBeToggled = modInfo.isToggleable() && mods.getEnabledModsList().saveAllowed();
this.willBeEnabled = mods.isModEnabled(this.modInfo.getIdentifier());
this.isExternal = modInfo.getContainer().isExternalJar();
this.isErrored = modInfo.getStartupErrors() != null && modInfo.getStartupErrors().size() > 0;
if (!modInfo.isActive() && this.isValid)
{
this.isActive = modInfo.getContainer().isEnabled(environment);
Loadable<?> modContainer = modInfo.getContainer();
if (modContainer instanceof LoadableMod<?>)
{
LoadableMod<?> loadableMod = (LoadableMod<?>)modContainer;
this.missingDependencies = loadableMod.getMissingDependencies();
this.missingAPIs = loadableMod.getMissingAPIs();
this.isMissingDependencies = this.missingDependencies.size() > 0;
this.isMissingAPIs = this.missingAPIs.size() > 0;
}
}
this.initPanels(fontRenderer, brandColour, decorators, modInfo);
}
/**
* @param fontRenderer
* @param brandColour
* @param decorators
* @param modInfo
*/
protected void initPanels(FontRenderer fontRenderer, int brandColour, List<ModInfoDecorator> decorators, ModInfo<?> modInfo)
{
this.infoPanel = new GuiModInfoPanel(this, fontRenderer, brandColour, modInfo);
if (this.isValid)
{
this.listPanel = new GuiModListPanel(this, fontRenderer, brandColour, modInfo, decorators);
}
else
{
this.listPanel = new GuiModListPanelInvalid(this, fontRenderer, brandColour, modInfo, decorators);
}
}
public void onTick()
{
if (this.doubleClickTime > 0)
{
this.doubleClickTime--;
}
}
public void mousePressed(int mouseX, int mouseY, int mouseButton)
{
if (this.getListPanel().isMouseOver())
{
this.modList.selectMod(this);
if (this.getListPanel().isMouseOver())
{
this.getListPanel().mousePressed(mouseX, mouseY, mouseButton);
}
if (this.getListPanel().isMouseOverIcon())
{
this.getListPanel().iconClick(this.modList.getParentScreen());
}
else
{
// handle double-click
if (this.doubleClickTime > 0)
{
this.onDoubleClicked();
}
}
this.doubleClickTime = 5;
}
}
protected void onDoubleClicked()
{
this.modList.showConfig(this);
}
protected String getTitleText()
{
return this.modInfo.getDisplayName();
}
protected String getVersionText()
{
return I18n.format("gui.about.versiontext", this.modInfo.getVersion());
}
protected String getStatusText()
{
String statusText = this.isExternal ? I18n.format("gui.status.loaded") : I18n.format("gui.status.active");
if (this.isMissingAPIs)
{
statusText = "\2475" + I18n.format("gui.status.missingapis");
if (this.canBeToggled && !this.willBeEnabled) statusText = "\247c" + I18n.format("gui.status.pending.disabled");
}
else if (this.isMissingDependencies)
{
statusText = "\247e" + I18n.format("gui.status.missingdeps");
if (this.canBeToggled && !this.willBeEnabled) statusText = "\247c" + I18n.format("gui.status.pending.disabled");
}
else if (this.isErrored)
{
statusText = "\247c" + I18n.format("gui.status.startuperror");
}
else if (this.canBeToggled)
{
if (!this.isActive && !this.willBeEnabled) statusText = "\2477" + I18n.format("gui.status.disabled");
if (!this.isActive && this.willBeEnabled) statusText = "\247a" + I18n.format("gui.status.pending.enabled");
if ( this.isActive && !this.willBeEnabled) statusText = "\247c" + I18n.format("gui.status.pending.disabled");
}
return statusText;
}
/**
* Toggle the enablement status of this mod, if supported
*/
public void toggleEnabled()
{
if (this.canBeToggled)
{
this.willBeEnabled = !this.willBeEnabled;
this.mods.setModEnabled(this.modInfo.getIdentifier(), this.willBeEnabled);
}
}
protected void displayHelpMessage(String title, String text)
{
this.infoPanel.displayHelpMessage(title, text);
}
public void clearHelpMessage()
{
this.infoPanel.clearHelpMessage();
}
public String getKey()
{
return (this.isErrored ? "0000" : "") + this.modInfo.getIdentifier() + Integer.toHexString(this.hashCode());
}
public ModInfo<?> getModInfo()
{
return this.modInfo;
}
public LiteMod getModInstance()
{
return this.modInfo.getMod();
}
public Class<? extends LiteMod> getModClass()
{
return this.modInfo.getModClass();
}
public String getName()
{
return this.modInfo.getDisplayName();
}
public String getVersion()
{
return this.modInfo.getVersion();
}
public String getAuthor()
{
return this.modInfo.getAuthor();
}
public String getDescription()
{
return this.modInfo.getDescription();
}
public boolean isEnabled()
{
return this.isActive;
}
public boolean canBeToggled()
{
return this.canBeToggled;
}
public boolean willBeEnabled()
{
return this.willBeEnabled;
}
public boolean isActive()
{
return this.isActive;
}
public boolean isErrored()
{
return this.isErrored;
}
public boolean isExternal()
{
return this.isExternal;
}
public boolean isMissingAPIs()
{
return this.isMissingAPIs;
}
public boolean isMissingDependencies()
{
return this.isMissingDependencies;
}
public GuiModListPanel getListPanel()
{
return this.listPanel;
}
public GuiModInfoPanel getInfoPanel()
{
return this.infoPanel;
}
}

View file

@ -0,0 +1,440 @@
package com.mumfrey.liteloader.client.gui.startup;
import static com.mumfrey.liteloader.gl.GL.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.client.renderer.texture.ITextureObject;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.resources.IResource;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.shader.Framebuffer;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.Display;
import com.mumfrey.liteloader.common.LoadingProgress;
import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
/**
* Crappy implementation of a "Mojang Screen" loading bar
*
* @author Adam Mummery-Smith
*/
public class LoadingBar extends LoadingProgress
{
private static LoadingBar instance;
private static final String LOADING_MESSAGE_1 = "Starting Game...";
private static final String LOADING_MESSAGE_2 = "Initialising...";
private int minecraftProgress = 0;
private int totalMinecraftProgress = 606;
private int liteLoaderProgressScale = 3;
private int liteLoaderProgress = 0;
private int totalLiteLoaderProgress = 0;
private ResourceLocation textureLocation = new ResourceLocation("textures/gui/title/mojang.png");
private String minecraftMessage = LoadingBar.LOADING_MESSAGE_1;
private String message = "";
private Minecraft minecraft;
private TextureManager textureManager;
private FontRenderer fontRenderer;
private Framebuffer fbo;
private boolean enabled = true;
private boolean errored;
private boolean calculatedColour = false;
private int barLuma = 0, r2 = 246, g2 = 136, b2 = 62;
private int logIndex = 0;
private List<String> logTail = new ArrayList<String>();
public LoadingBar()
{
LoadingBar.instance = this;
}
@Override
protected void _setEnabled(boolean enabled)
{
this.enabled = enabled;
}
@Override
protected void _dispose()
{
this.minecraft = null;
this.textureManager = null;
this.fontRenderer = null;
this.disposeFbo();
}
private void disposeFbo()
{
if (this.fbo != null)
{
this.fbo.deleteFramebuffer();
this.fbo = null;
}
}
public static void incrementProgress()
{
if (LoadingBar.instance != null) LoadingBar.instance._incrementProgress();
}
protected void _incrementProgress()
{
this.message = this.minecraftMessage;
this.minecraftProgress++;
this.render();
}
public static void initTextures()
{
if (LoadingBar.instance != null) LoadingBar.instance._initTextures();
}
protected void _initTextures()
{
this.minecraftMessage = LoadingBar.LOADING_MESSAGE_2;
}
@Override
protected void _incLiteLoaderProgress()
{
this.liteLoaderProgress += this.liteLoaderProgressScale;
this.render();
}
@Override
protected void _setMessage(String message)
{
this.message = message;
this.render();
}
@Override
protected void _incLiteLoaderProgress(String message)
{
this.message = message;
this.liteLoaderProgress += this.liteLoaderProgressScale ;
this.render();
}
@Override
protected void _incTotalLiteLoaderProgress(int by)
{
this.totalLiteLoaderProgress += (by * this.liteLoaderProgressScale);
this.render();
}
/**
*
*/
private void render()
{
if (!this.enabled || this.errored) return;
try
{
if (this.minecraft == null) this.minecraft = Minecraft.getMinecraft();
if (this.textureManager == null) this.textureManager = this.minecraft.getTextureManager();
if (Display.isCreated() && this.textureManager != null)
{
if (this.fontRenderer == null)
{
this.fontRenderer = new FontRenderer(this.minecraft.gameSettings, new ResourceLocation("textures/font/ascii.png"),
this.textureManager, false);
this.fontRenderer.onResourceManagerReload(this.minecraft.getResourceManager());
}
double totalProgress = this.totalMinecraftProgress + this.totalLiteLoaderProgress;
double progress = (this.minecraftProgress + this.liteLoaderProgress) / totalProgress;
// if (progress >= 1.0) LoadingBar.message = "Preparing...";
this.render(progress);
}
}
catch (Exception ex)
{
// Disable the loading bar if ANY errors occur
this.errored = true;
}
}
/**
* @param progress
*/
private void render(double progress)
{
if (this.totalMinecraftProgress == -1)
{
this.totalMinecraftProgress = 606 - this.minecraftProgress;
this.minecraftProgress = 0;
}
// Calculate the bar colour if we haven't already done that
if (!this.calculatedColour)
{
this.calculatedColour = true;
ITextureObject texture = this.textureManager.getTexture(this.textureLocation);
if (texture == null)
{
try
{
DynamicTexture textureData = this.loadTexture(this.minecraft.getResourceManager(), this.textureLocation);
this.textureLocation = this.minecraft.getTextureManager().getDynamicTextureLocation("loadingScreen", textureData);
this.findMostCommonColour(textureData.getTextureData());
textureData.updateDynamicTexture();
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
}
ScaledResolution scaledResolution = new ScaledResolution(this.minecraft, this.minecraft.displayWidth, this.minecraft.displayHeight);
int scaleFactor = scaledResolution.getScaleFactor();
int scaledWidth = scaledResolution.getScaledWidth();
int scaledHeight = scaledResolution.getScaledHeight();
int fboWidth = scaledWidth * scaleFactor;
int fboHeight = scaledHeight * scaleFactor;
if (this.fbo == null)
{
this.fbo = new Framebuffer(fboWidth, fboHeight, true);
}
else if (this.fbo.framebufferWidth != fboWidth || this.fbo.framebufferHeight != fboHeight)
{
this.fbo.createBindFramebuffer(fboWidth, fboHeight);
}
this.fbo.bindFramebuffer(false);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0D, scaledWidth, scaledHeight, 0.0D, 1000.0D, 3000.0D);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0F, 0.0F, -2000.0F);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisableLighting();
glDisableFog();
glDisableDepthTest();
glEnableTexture2D();
this.textureManager.bindTexture(this.textureLocation);
Tessellator tessellator = Tessellator.getInstance();
WorldRenderer worldRenderer = tessellator.getWorldRenderer();
worldRenderer.startDrawingQuads();
worldRenderer.setColorOpaque_I(0xFFFFFFFF); // TODO OBF MCPTEST func_178991_c - setColorOpaque_I
worldRenderer.addVertexWithUV(0.0D, scaledHeight, 0.0D, 0.0D, 0.0D);
worldRenderer.addVertexWithUV(scaledWidth, scaledHeight, 0.0D, 0.0D, 0.0D);
worldRenderer.addVertexWithUV(scaledWidth, 0.0D, 0.0D, 0.0D, 0.0D);
worldRenderer.addVertexWithUV(0.0D, 0.0D, 0.0D, 0.0D, 0.0D);
tessellator.draw();
glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
int left = (scaledWidth - 256) / 2;
int top = (scaledHeight - 256) / 2;
int u1 = 0;
int v1 = 0;
int u2 = 256;
int v2 = 256;
float texMapScale = 0.00390625F;
worldRenderer.startDrawingQuads();
worldRenderer.setColorOpaque_I(0xFFFFFFFF); // TODO OBF MCPTEST func_178991_c - setColorOpaque_I
worldRenderer.addVertexWithUV(left + 0, top + v2, 0.0D, (u1 + 0) * texMapScale, (v1 + v2) * texMapScale);
worldRenderer.addVertexWithUV(left + u2, top + v2, 0.0D, (u1 + u2) * texMapScale, (v1 + v2) * texMapScale);
worldRenderer.addVertexWithUV(left + u2, top + 0, 0.0D, (u1 + u2) * texMapScale, (v1 + 0) * texMapScale);
worldRenderer.addVertexWithUV(left + 0, top + 0, 0.0D, (u1 + 0) * texMapScale, (v1 + 0) * texMapScale);
tessellator.draw();
glEnableTexture2D();
glEnableColorLogic();
glLogicOp(GL_OR_REVERSE);
this.fontRenderer.drawString(this.message, 1, scaledHeight - 19, 0xFF000000);
if (LiteLoaderLogger.DEBUG)
{
int logBottom = this.minecraft.displayHeight - (20 * scaleFactor) - 2;
glPushMatrix();
glScalef(1.0F / scaleFactor, 1.0F / scaleFactor, 1.0F);
this.renderLogTail(logBottom);
glPopMatrix();
}
glDisableColorLogic();
glEnableTexture2D();
double barHeight = 10.0D;
double barWidth = scaledResolution.getScaledWidth_double() - 2.0D;
glDisableTexture2D();
glEnableBlend();
glEnableAlphaTest();
glAlphaFunc(GL_GREATER, 0.0F);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// tessellator.startDrawingQuads();
// tessellator.setColorRGBA(0, 0, 0, 32);
// tessellator.addVertex(0.0D, scaledHeight, 0.0D);
// tessellator.setColorRGBA(0, 0, 0, 180);
// tessellator.addVertex(0.0D + scaledWidth, scaledHeight, 0.0D);
// tessellator.setColorRGBA(0, 0, 0, 0);
// tessellator.addVertex(0.0D + scaledWidth, (scaledHeight / 10), 0.0D);
// tessellator.addVertex(0.0D, scaledHeight - (scaledHeight / 3), 0.0D);
// tessellator.draw();
worldRenderer.startDrawingQuads();
worldRenderer.setColorRGBA(this.barLuma, this.barLuma, this.barLuma, 128); // TODO OBF MCPTEST func_178961_b - setColorRGBA
worldRenderer.addVertex(0.0D, scaledHeight, 0.0D);
worldRenderer.addVertex(0.0D + scaledWidth, scaledHeight, 0.0D);
worldRenderer.addVertex(0.0D + scaledWidth, scaledHeight - barHeight, 0.0D);
worldRenderer.addVertex(0.0D, scaledHeight - barHeight, 0.0D);
tessellator.draw();
barHeight -= 1;
worldRenderer.startDrawingQuads();
worldRenderer.setColorRGBA(this.r2, this.g2, this.b2, 255); // TODO OBF MCPTEST func_178961_b - setColorRGBA
worldRenderer.addVertex(1.0D + barWidth * progress, scaledHeight - 1, 1.0D);
worldRenderer.addVertex(1.0D + barWidth * progress, scaledHeight - barHeight, 1.0D);
worldRenderer.setColorRGBA(0, 0, 0, 255); // TODO OBF MCPTEST func_178961_b - setColorRGBA
worldRenderer.addVertex(1.0D, scaledHeight - barHeight, 1.0D);
worldRenderer.addVertex(1.0D, scaledHeight - 1, 1.0D);
tessellator.draw();
glAlphaFunc(GL_GREATER, 0.1F);
glDisableLighting();
glDisableFog();
this.fbo.unbindFramebuffer();
this.fbo.framebufferRender(fboWidth, fboHeight);
glEnableAlphaTest();
glAlphaFunc(GL_GREATER, 0.1F);
// glFlush();
this.minecraft.updateDisplay(); // TODO OBF MCPTEST updateDisplay - func_175601_h
}
private void renderLogTail(int yPos)
{
if (this.logIndex != LiteLoaderLogger.getLogIndex())
{
this.logTail = LiteLoaderLogger.getLogTail();
}
for (int logIndex = this.logTail.size() - 1; yPos > 10 && logIndex >= 0; logIndex--)
{
this.fontRenderer.drawString(this.logTail.get(logIndex), 10, yPos -= 10, 0xFF000000);
}
}
/**
* Find the most common (approx) colour in the image and assign it to the
* bar, reduces the palette to 9-bit by stripping the the 5 LSB from each
* byte to create a 9-bit palette index in the form RRRGGGBBB
*
* @param textureData
*/
private void findMostCommonColour(int[] textureData)
{
// Array of frequency values, indexed by palette index
int[] freq = new int[512];
for (int pos = 0; pos < textureData.length; pos++)
{
int paletteIndex = ((textureData[pos] >> 21 & 0x7) << 6) + ((textureData[pos] >> 13 & 0x7) << 3) + (textureData[pos] >> 5 & 0x7);
freq[paletteIndex]++;
}
int peak = 0;
// Black, white and 0x200000 excluded on purpose
for (int paletteIndex = 2; paletteIndex < 511; paletteIndex++)
{
if (freq[paletteIndex] > peak)
{
peak = freq[paletteIndex];
this.setBarColour(paletteIndex);
}
}
}
/**
* @param paletteIndex
*/
private void setBarColour(int paletteIndex)
{
this.r2 = this.padComponent((paletteIndex & 0x1C0) >> 1);
this.g2 = this.padComponent((paletteIndex & 0x38) << 2);
this.b2 = this.padComponent((paletteIndex & 0x7) << 5);
this.barLuma = (Math.max(this.r2, Math.max(this.g2, this.b2)) < 64) ? 255 : 0;
}
/**
* Pad LSB with 1's if any MSB are 1 (effectively a bitwise ceil() function)
*
* @param component
*/
private int padComponent(int component)
{
return (component > 0x1F) ? component | 0x1F : component;
}
private DynamicTexture loadTexture(IResourceManager resourceManager, ResourceLocation textureLocation) throws IOException
{
InputStream inputStream = null;
try
{
IResource resource = resourceManager.getResource(textureLocation);
inputStream = resource.getInputStream();
BufferedImage image = ImageIO.read(inputStream);
return new DynamicTexture(image);
}
finally
{
if (inputStream != null)
{
inputStream.close();
}
}
}
}

View file

@ -0,0 +1,26 @@
package com.mumfrey.liteloader.client.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.mumfrey.liteloader.client.ClientProxy;
import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.client.entity.EntityPlayerSP;
@Mixin(EntityPlayerSP.class)
public abstract class MixinEntityPlayerSP extends AbstractClientPlayer
{
public MixinEntityPlayerSP()
{
super(null, null);
}
@Inject(method = "sendChatMessage(Ljava/lang/String;)V", at = { @At("HEAD") }, cancellable = true)
public void onSendChatMessage(String message, CallbackInfo ci)
{
ClientProxy.onOutboundChat(ci, message);
}
}

View file

@ -0,0 +1,115 @@
package com.mumfrey.liteloader.client.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.At.Shift;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.mumfrey.liteloader.client.ClientProxy;
import net.minecraft.client.renderer.EntityRenderer;
import net.minecraft.client.renderer.RenderGlobal;
@Mixin(EntityRenderer.class)
public abstract class MixinEntityRenderer
{
@Inject(method = "updateCameraAndRender(F)V", at = @At(
value = "INVOKE",
shift = Shift.AFTER,
target = "Lnet/minecraft/client/renderer/GlStateManager;clear(I)V"
))
private void onPreRenderGUI(float partialTicks, CallbackInfo ci)
{
ClientProxy.preRenderGUI(partialTicks);
}
@Inject(method = "updateCameraAndRender(F)V", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/gui/GuiIngame;renderGameOverlay(F)V"
))
private void onRenderHUD(float partialTicks, CallbackInfo ci)
{
ClientProxy.onRenderHUD(partialTicks);
}
@Inject(method = "updateCameraAndRender(F)V", at = @At(
value = "INVOKE",
shift = Shift.AFTER,
target = "Lnet/minecraft/client/gui/GuiIngame;renderGameOverlay(F)V"
))
private void onPostRenderHUD(float partialTicks, CallbackInfo ci)
{
ClientProxy.postRenderHUD(partialTicks);
}
@Inject(method = "renderWorld(FJ)V", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/profiler/Profiler;startSection(Ljava/lang/String;)V",
ordinal = 0
))
private void onRenderWorld(float partialTicks, long timeSlice, CallbackInfo ci)
{
ClientProxy.onRenderWorld(partialTicks, timeSlice);
}
@Inject(method = "renderWorld(FJ)V", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/profiler/Profiler;endSection()V",
ordinal = 0
))
private void onPostRender(float partialTicks, long timeSlice, CallbackInfo ci)
{
ClientProxy.postRender(partialTicks, timeSlice);
}
@Inject(method = "renderWorldPass(IFJ)V", at = @At(
value = "INVOKE_STRING",
target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V",
args = "ldc=frustum"
))
private void onSetupCameraTransform(int pass, float partialTicks, long timeSlice, CallbackInfo ci)
{
ClientProxy.onSetupCameraTransform(pass, partialTicks, timeSlice);
}
@Inject(method = "renderWorldPass(IFJ)V", at = @At(
value = "INVOKE_STRING",
target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V",
args = "ldc=sky"
))
private void onRenderSky(int pass, float partialTicks, long timeSlice, CallbackInfo ci)
{
ClientProxy.onRenderSky(pass, partialTicks, timeSlice);
}
@Inject(method = "renderWorldPass(IFJ)V", at = @At(
value = "INVOKE_STRING",
target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V",
args = "ldc=terrain"
))
private void onRenderTerrain(int pass, float partialTicks, long timeSlice, CallbackInfo ci)
{
ClientProxy.onRenderTerrain(pass, partialTicks, timeSlice);
}
@Inject(method = "renderWorldPass(IFJ)V", at = @At(
value = "INVOKE_STRING",
target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V",
args = "ldc=litParticles"
))
private void onPostRenderEntities(int pass, float partialTicks, long timeSlice, CallbackInfo ci)
{
ClientProxy.postRenderEntities(pass, partialTicks, timeSlice);
}
@Inject(method = "renderCloudsCheck(Lnet/minecraft/client/renderer/RenderGlobal;FI)V", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V"
))
private void onRenderClouds(RenderGlobal renderGlobalIn, float partialTicks, int pass, CallbackInfo ci)
{
ClientProxy.onRenderClouds(renderGlobalIn, partialTicks, pass);
}
}

View file

@ -0,0 +1,43 @@
package com.mumfrey.liteloader.client.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.mumfrey.liteloader.client.ClientProxy;
import com.mumfrey.liteloader.client.ducks.IFramebuffer;
import net.minecraft.client.shader.Framebuffer;
@Mixin(Framebuffer.class)
public abstract class MixinFramebuffer implements IFramebuffer
{
private boolean dispatchRenderEvent;
@Override
public IFramebuffer setDispatchRenderEvent(boolean dispatchRenderEvent)
{
this.dispatchRenderEvent = dispatchRenderEvent;
return this;
}
@Override
public boolean isDispatchRenderEvent()
{
return this.dispatchRenderEvent;
}
@Inject(method = "framebufferRenderExt(IIZ)V", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/shader/Framebuffer;bindFramebufferTexture()V"
))
private void onRenderFBO(int width, int height, boolean flag, CallbackInfo ci)
{
if (this.dispatchRenderEvent)
{
ClientProxy.renderFBO((Framebuffer)(Object)this, width, height, flag);
this.dispatchRenderEvent = false;
}
}
}

View file

@ -0,0 +1,39 @@
package com.mumfrey.liteloader.client.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.At.Shift;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.mumfrey.liteloader.client.ClientProxy;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiIngame;
import net.minecraft.client.gui.GuiNewChat;
@Mixin(GuiIngame.class)
public abstract class MixinGuiIngame extends Gui
{
@Shadow private GuiNewChat persistantChatGUI;
@Inject(method = "renderGameOverlay(F)V", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/gui/GuiNewChat;drawChat(I)V"
))
private void onRenderChat(float partialTicks, CallbackInfo ci)
{
ClientProxy.onRenderChat(this.persistantChatGUI, partialTicks);
}
@Inject(method = "renderGameOverlay(F)V", at = @At(
value = "INVOKE",
shift = Shift.AFTER,
target = "Lnet/minecraft/client/gui/GuiNewChat;drawChat(I)V"
))
private void postRenderChat(float partialTicks, CallbackInfo ci)
{
ClientProxy.postRenderChat(this.persistantChatGUI, partialTicks);
}
}

View file

@ -0,0 +1,39 @@
package com.mumfrey.liteloader.client.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Surrogate;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.mumfrey.liteloader.client.ClientProxy;
import net.minecraft.client.Minecraft;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.integrated.IntegratedServer;
import net.minecraft.world.WorldSettings;
@Mixin(IntegratedServer.class)
public abstract class MixinIntegratedServer extends MinecraftServer
{
public MixinIntegratedServer()
{
super(null, null);
}
@Inject(
method = "<init>*", //(Lnet/minecraft/client/Minecraft;Ljava/lang/String;Ljava/lang/String;Lnet/minecraft/world/WorldSettings;)V",
at = @At("RETURN"),
remap = false
)
private void onConstructed(Minecraft mcIn, String folderName, String worldName, WorldSettings settings, CallbackInfo ci)
{
ClientProxy.onCreateIntegratedServer((IntegratedServer)(Object)this, folderName, worldName, settings);
}
@Surrogate
private void onConstructed(Minecraft mcIn, CallbackInfo ci)
{
// ClientProxy.onCreateIntegratedServer((IntegratedServer)(Object)this, folderName, worldName, settings);
}
}

View file

@ -0,0 +1,85 @@
package com.mumfrey.liteloader.client.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.At.Shift;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.mumfrey.liteloader.client.ClientProxy;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.shader.Framebuffer;
@Mixin(Minecraft.class)
public abstract class MixinMinecraft
{
@Inject(method = "startGame()V", at = @At("RETURN"))
private void onStartupComplete(CallbackInfo ci)
{
ClientProxy.onStartupComplete();
}
@Inject(method = "updateFramebufferSize()V", at = @At("HEAD"))
private void onResize(CallbackInfo ci)
{
ClientProxy.onResize((Minecraft)(Object)this);
}
@Inject(method = "runTick()V", at = @At("HEAD"))
private void newTick(CallbackInfo ci)
{
ClientProxy.newTick();
}
@Inject(method = "runGameLoop()V", at = @At(
value = "INVOKE",
shift = Shift.AFTER,
target = "Lnet/minecraft/client/renderer/EntityRenderer;updateCameraAndRender(F)V"
))
private void onTick(CallbackInfo ci)
{
ClientProxy.onTick();
}
@Redirect(method = "runGameLoop()V", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/shader/Framebuffer;framebufferRender(II)V"
))
private void renderFBO(Framebuffer framebufferMc, int width, int height)
{
boolean fboEnabled = OpenGlHelper.isFramebufferEnabled();
if (fboEnabled)
{
ClientProxy.preRenderFBO(framebufferMc);
framebufferMc.framebufferRender(width, height);
ClientProxy.preRenderFBO(framebufferMc);
}
else
{
framebufferMc.framebufferRender(width, height);
}
}
@Inject(method = "runGameLoop()V", at = @At(
value = "INVOKE_STRING",
target = "Lnet/minecraft/profiler/Profiler;startSection(Ljava/lang/String;)V",
args = "ldc=tick"
))
private void onTimerUpdate(CallbackInfo ci)
{
ClientProxy.onTimerUpdate();
}
@Inject (method = "runGameLoop()V", at = @At(
value = "INVOKE_STRING",
target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V",
args = "ldc=gameRenderer"
))
private void onRender(CallbackInfo ci)
{
ClientProxy.onRender();
}
}

View file

@ -0,0 +1,21 @@
package com.mumfrey.liteloader.client.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import com.mumfrey.liteloader.client.ducks.IClientNetLoginHandler;
import net.minecraft.client.network.NetHandlerLoginClient;
import net.minecraft.network.NetworkManager;
@Mixin(NetHandlerLoginClient.class)
public abstract class MixinNetHandlerLoginClient implements IClientNetLoginHandler
{
@Shadow private NetworkManager networkManager;
@Override
public NetworkManager getNetMgr()
{
return this.networkManager;
}
}

View file

@ -0,0 +1,32 @@
package com.mumfrey.liteloader.client.mixin;
import java.util.IdentityHashMap;
import java.util.List;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import com.mumfrey.liteloader.client.ducks.IObjectIntIdentityMap;
import net.minecraft.util.ObjectIntIdentityMap;
@Mixin(ObjectIntIdentityMap.class)
public abstract class MixinObjectIntIdentityMap implements IObjectIntIdentityMap
{
@Shadow private IdentityHashMap<?, Integer> identityMap;
@Shadow private List<?> objectList;
@SuppressWarnings("unchecked")
@Override
public <V> IdentityHashMap<V, Integer> getIdentityMap()
{
return (IdentityHashMap<V, Integer>)this.identityMap;
}
@SuppressWarnings("unchecked")
@Override
public <V> List<V> getObjectList()
{
return (List<V>)this.objectList;
}
}

View file

@ -0,0 +1,26 @@
package com.mumfrey.liteloader.client.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import com.mojang.realmsclient.RealmsMainScreen;
import com.mojang.realmsclient.dto.RealmsServer;
import com.mumfrey.liteloader.client.PacketEventsClient;
import net.minecraft.realms.RealmsScreen;
@Mixin(value = RealmsMainScreen.class, remap = false)
public abstract class MixinRealmsMainScreen extends RealmsScreen
{
@Inject(method = "play(J)V", locals = LocalCapture.CAPTURE_FAILSOFT, at = @At(
value = "INVOKE",
target = "Lcom/mojang/realmsclient/RealmsMainScreen;stopRealmsFetcherAndPinger()V"
))
private void onJoinRealm(long serverId, CallbackInfo ci, RealmsServer server)
{
PacketEventsClient.onJoinRealm(serverId, server);
}
}

View file

@ -0,0 +1,23 @@
package com.mumfrey.liteloader.client.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import com.mumfrey.liteloader.client.ducks.INamespacedRegistry;
import com.mumfrey.liteloader.client.ducks.IObjectIntIdentityMap;
import net.minecraft.util.ObjectIntIdentityMap;
import net.minecraft.util.RegistryNamespaced;
import net.minecraft.util.RegistrySimple;
@Mixin(RegistryNamespaced.class)
public abstract class MixinRegistryNamespaced extends RegistrySimple implements INamespacedRegistry
{
@Shadow protected ObjectIntIdentityMap underlyingIntegerMap;
@Override
public IObjectIntIdentityMap getUnderlyingMap()
{
return (IObjectIntIdentityMap)this.underlyingIntegerMap;
}
}

View file

@ -0,0 +1,23 @@
package com.mumfrey.liteloader.client.mixin;
import java.util.Map;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import com.mumfrey.liteloader.client.ducks.IRegistrySimple;
import net.minecraft.util.RegistrySimple;
@Mixin(RegistrySimple.class)
public abstract class MixinRegistrySimple implements IRegistrySimple
{
@Shadow protected Map<?, ?> registryObjects;
@SuppressWarnings("unchecked")
@Override
public <K, V> Map<K, V> getRegistryObjects()
{
return (Map<K, V>)this.registryObjects;
}
}

View file

@ -0,0 +1,39 @@
package com.mumfrey.liteloader.client.mixin;
import java.util.Map;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import com.mumfrey.liteloader.client.ClientProxy;
import com.mumfrey.liteloader.client.ducks.IRenderManager;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.entity.Entity;
@Mixin(RenderManager.class)
public abstract class MixinRenderManager implements IRenderManager
{
@Shadow private Map<Class<? extends Entity>, Render> entityRenderMap;
@Override
public Map<Class<? extends Entity>, Render> getRenderMap()
{
return this.entityRenderMap;
}
@Redirect(method = "doRenderEntity(Lnet/minecraft/entity/Entity;DDDFFZ)Z", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/entity/Render;doRender(Lnet/minecraft/entity/Entity;DDDFF)V"
))
private void onRenderEntity(Render render, Entity entity, double x, double y, double z, float entityYaw, float partialTicks)
{
RenderManager source = (RenderManager)(Object)this;
ClientProxy.onRenderEntity(source, render, entity, x, y, z, entityYaw, partialTicks);
render.doRender(entity, x, y, z, entityYaw, partialTicks);
ClientProxy.onPostRenderEntity(source, render, entity, x, y, z, entityYaw, partialTicks);
}
}

View file

@ -0,0 +1,32 @@
package com.mumfrey.liteloader.client.mixin;
import java.io.File;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.mumfrey.liteloader.client.ClientProxy;
import net.minecraft.client.shader.Framebuffer;
import net.minecraft.util.IChatComponent;
import net.minecraft.util.ScreenShotHelper;
@Mixin(ScreenShotHelper.class)
public abstract class MixinScreenShotHelper
{
@Inject(
method = "saveScreenshot(Ljava/io/File;Ljava/lang/String;IILnet/minecraft/client/shader/Framebuffer;)Lnet/minecraft/util/IChatComponent;",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/OpenGlHelper;isFramebufferEnabled()Z",
ordinal = 0
),
cancellable = true
)
private static void onSaveScreenshot(File gameDir, String name, int width, int height, Framebuffer fbo, CallbackInfoReturnable<IChatComponent> ci)
{
ClientProxy.onSaveScreenshot(ci, gameDir, name, width, height, fbo);
}
}

View file

@ -0,0 +1,31 @@
package com.mumfrey.liteloader.client.mixin;
import java.util.UUID;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.mojang.authlib.GameProfile;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.Session;
@Mixin(Session.class)
public abstract class MixinSession
{
@Shadow public abstract String getUsername();
@Inject(method = "getProfile()Lcom/mojang/authlib/GameProfile;", cancellable = true, at = @At(
value = "NEW",
args = "class=com/mojang/authlib/GameProfile",
ordinal = 1
))
private void generateGameProfile(CallbackInfoReturnable<GameProfile> ci)
{
UUID uuid = EntityPlayer.getUUID(new GameProfile((UUID)null, this.getUsername()));
ci.setReturnValue(new GameProfile(uuid, this.getUsername()));
}
}

View file

@ -0,0 +1,23 @@
package com.mumfrey.liteloader.client.mixin;
import java.util.List;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import com.mumfrey.liteloader.client.ducks.IReloadable;
import net.minecraft.client.resources.IResourceManagerReloadListener;
import net.minecraft.client.resources.SimpleReloadableResourceManager;
@Mixin(SimpleReloadableResourceManager.class)
public abstract class MixinSimpleReloadableResourceManager implements IReloadable
{
@Shadow private List<IResourceManagerReloadListener> reloadListeners;
@Override
public List<IResourceManagerReloadListener> getReloadListeners()
{
return this.reloadListeners;
}
}

View file

@ -0,0 +1,24 @@
package com.mumfrey.liteloader.client.mixin;
import java.util.Map;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import com.mumfrey.liteloader.client.ducks.ITileEntityRendererDispatcher;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.tileentity.TileEntity;
@Mixin(TileEntityRendererDispatcher.class)
public abstract class MixinTileEntityRendererDispatcher implements ITileEntityRendererDispatcher
{
@Shadow private Map<Class<? extends TileEntity>, TileEntitySpecialRenderer> mapSpecialRenderers;
@Override
public Map<Class<? extends TileEntity>, TileEntitySpecialRenderer> getSpecialRenderMap()
{
return this.mapSpecialRenderers;
}
}

View file

@ -0,0 +1,29 @@
package com.mumfrey.liteloader.client.overlays;
import net.minecraft.util.ResourceLocation;
import com.mumfrey.liteloader.transformers.access.Accessor;
import com.mumfrey.liteloader.transformers.access.Invoker;
/**
* Adapter for EntityRenderer to expose some private functionality
*
* @author Adam Mummery-Smith
*/
@Accessor("EntityRenderer")
public interface IEntityRenderer
{
@Accessor("useShader") public abstract boolean getUseShader();
@Accessor("useShader") public abstract void setUseShader(boolean useShader);
@Accessor("shaderResourceLocations") public abstract ResourceLocation[] getShaders();
@Accessor("shaderIndex") public abstract int getShaderIndex();
@Accessor("shaderIndex") public abstract void setShaderIndex(int shaderIndex);
@Invoker("loadShader") public abstract void selectShader(ResourceLocation shader);
@Invoker("getFOVModifier") public abstract float getFOV(float partialTicks, boolean armFOV);
@Invoker("setupCameraTransform") public abstract void setupCamera(float partialTicks, int pass);
}

View file

@ -0,0 +1,36 @@
package com.mumfrey.liteloader.client.overlays;
import com.mumfrey.liteloader.transformers.access.Accessor;
/**
* Adapter for GuiTextField to expose internal properties, mainly to allow
* sensible subclassing.
*
* @author Adam Mummery-Smith
*/
@Accessor("GuiTextField")
public interface IGuiTextField
{
@Accessor("#2") public abstract int getXPosition();
@Accessor("#2") public abstract void setXPosition(int xPosition);
@Accessor("#3") public abstract int getYPosition();
@Accessor("#3") public abstract void setYPosition(int yPosition);
@Accessor("#4") public abstract int getInternalWidth();
@Accessor("#4") public abstract void setInternalWidth(int width);
@Accessor("#5") public abstract int getHeight();
@Accessor("#5") public abstract void setHeight(int height);
@Accessor("#12") public abstract boolean isEnabled();
// @Accessor("#12") public abstract void setEnabled(boolean enabled); // built in
@Accessor("#13") public abstract int getLineScrollOffset();
@Accessor("#16") public abstract int getTextColor();
// @Accessor("#16") public abstract void setTextColor(int color); // built in
@Accessor("#17") public abstract int getDisabledTextColour();
// @Accessor("#17") public abstract void setDisabledTextColour(int color); // built in
}

View file

@ -0,0 +1,60 @@
package com.mumfrey.liteloader.client.overlays;
import java.util.List;
import net.minecraft.client.resources.IResourcePack;
import net.minecraft.util.Timer;
import com.mumfrey.liteloader.core.runtime.Obf;
import com.mumfrey.liteloader.transformers.access.Accessor;
import com.mumfrey.liteloader.transformers.access.Invoker;
import com.mumfrey.liteloader.transformers.access.ObfTableClass;
/**
* Interface containing injected accessors for Minecraft
*
* @author Adam Mummery-Smith
*/
@ObfTableClass(Obf.class)
@Accessor("Minecraft")
public interface IMinecraft
{
/**
* Get the timer instance
*/
@Accessor("timer")
public abstract Timer getTimer();
/**
* Get the "running" flag
*/
@Accessor("running")
public abstract boolean isRunning();
/**
* Get the default resource packs set
*/
@Accessor("defaultResourcePacks")
public abstract List<IResourcePack> getDefaultResourcePacks();
/**
* Get the current server address (from connection)
*/
@Accessor("serverName")
public abstract String getServerName();
/**
* Get the current server port (from connection)
*/
@Accessor("serverPort")
public abstract int getServerPort();
/**
* Notify the client that the window was resized
*
* @param width
* @param height
*/
@Invoker("resize")
public abstract void onResizeWindow(int width, int height);
}

View file

@ -0,0 +1,14 @@
package com.mumfrey.liteloader.client.overlays;
import net.minecraft.client.audio.SoundList;
import net.minecraft.util.ResourceLocation;
import com.mumfrey.liteloader.transformers.access.Accessor;
import com.mumfrey.liteloader.transformers.access.Invoker;
@Accessor("SoundHandler")
public interface ISoundHandler
{
@Invoker("loadSoundResource")
public abstract void addSound(ResourceLocation sound, SoundList soundList);
}

View file

@ -0,0 +1,75 @@
package com.mumfrey.liteloader.client.transformers;
import java.util.ListIterator;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.VarInsnNode;
import com.mumfrey.liteloader.core.runtime.Obf;
import com.mumfrey.liteloader.transformers.ClassTransformer;
public class CrashReportTransformer extends ClassTransformer
{
@Override
public byte[] transform(String name, String transformedName, byte[] basicClass)
{
if (basicClass != null && (Obf.CrashReport$6.name.equals(name) || Obf.CrashReport$6.obf.equals(name)))
{
try
{
return this.transformCallableJVMFlags(basicClass);
}
catch (Exception ex) {}
}
return basicClass;
}
/**
* Inject the additional callback for populating the crash report into the
* CallableJVMFlags class.
*
* @param basicClass basic class
* @return transformed class
*/
private byte[] transformCallableJVMFlags(byte[] basicClass)
{
ClassNode classNode = this.readClass(basicClass, true);
for (MethodNode method : classNode.methods)
{
if ("<init>".equals(method.name))
{
this.transformCallableJVMFlagsConstructor(method);
}
}
return this.writeClass(classNode);
}
/**
* @param ctor
*/
public void transformCallableJVMFlagsConstructor(MethodNode ctor)
{
InsnList code = new InsnList();
code.add(new VarInsnNode(Opcodes.ALOAD, 1));
code.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "com/mumfrey/liteloader/core/LiteLoader", "populateCrashReport",
"(Ljava/lang/Object;)V", false));
ListIterator<AbstractInsnNode> insns = ctor.instructions.iterator();
while (insns.hasNext())
{
AbstractInsnNode insnNode = insns.next();
if (insnNode.getOpcode() == Opcodes.RETURN)
{
ctor.instructions.insertBefore(insnNode, code);
}
}
}
}

View file

@ -0,0 +1,91 @@
package com.mumfrey.liteloader.client.transformers;
import java.util.Iterator;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TypeInsnNode;
import com.mumfrey.liteloader.core.runtime.Obf;
import com.mumfrey.liteloader.launch.LiteLoaderTweaker;
import com.mumfrey.liteloader.transformers.access.AccessorTransformer;
import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
public class MinecraftTransformer extends AccessorTransformer
{
private static final String TWEAKCLASS = LiteLoaderTweaker.class.getName().replace('.', '/');
@Override
protected void addAccessors()
{
this.addAccessor(Obf.IMinecraft.name);
this.addAccessor(Obf.IGuiTextField.name);
this.addAccessor(Obf.IEntityRenderer.name);
this.addAccessor(Obf.ISoundHandler.name);
}
@Override
protected void postTransform(String name, String transformedName, ClassNode classNode)
{
if ((Obf.Minecraft.name.equals(transformedName) || Obf.Minecraft.obf.equals(transformedName)))
{
for (MethodNode method : classNode.methods)
{
if (Obf.startGame.obf.equals(method.name) || Obf.startGame.srg.equals(method.name) || Obf.startGame.name.equals(method.name))
{
this.transformStartGame(method);
}
}
}
}
private void transformStartGame(MethodNode method)
{
InsnList insns = new InsnList();
boolean found = false;
Iterator<AbstractInsnNode> iter = method.instructions.iterator();
while (iter.hasNext())
{
AbstractInsnNode insn = iter.next();
insns.add(insn);
if (insn instanceof TypeInsnNode && insn.getOpcode() == Opcodes.NEW && insns.getLast() != null)
{
TypeInsnNode typeNode = (TypeInsnNode)insn;
if (!found && (Obf.EntityRenderer.obf.equals(typeNode.desc) || Obf.EntityRenderer.ref.equals(typeNode.desc)))
{
LiteLoaderLogger.info("MinecraftTransformer found INIT injection point, this is good.");
found = true;
insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, MinecraftTransformer.TWEAKCLASS, Obf.init.name, "()V", false));
insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, MinecraftTransformer.TWEAKCLASS, Obf.postInit.name, "()V", false));
}
}
if (LiteLoaderTweaker.loadingBarEnabled())
{
if (insn instanceof LdcInsnNode)
{
LdcInsnNode ldcInsn = (LdcInsnNode)insn;
if ("textures/blocks".equals(ldcInsn.cst))
{
insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, Obf.LoadingBar.ref, "initTextures", "()V", false));
}
}
insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, Obf.LoadingBar.ref, "incrementProgress", "()V", false));
}
}
method.instructions = insns;
if (!found) LiteLoaderLogger.severe("MinecraftTransformer failed to find INIT injection point, the game will probably crash pretty soon.");
}
}

View file

@ -0,0 +1,22 @@
package com.mumfrey.liteloader.client.util;
import java.util.Map;
import com.mumfrey.liteloader.core.runtime.Obf;
import com.mumfrey.liteloader.util.PrivateFields;
import net.minecraft.tileentity.TileEntity;
@SuppressWarnings("rawtypes")
public final class PrivateFieldsClient<P, T> extends PrivateFields<P, T>
{
private PrivateFieldsClient(Class<P> owner, Obf obf)
{
super(owner, obf);
}
// CHECKSTYLE:OFF
public static final PrivateFieldsClient<TileEntity, Map> tileEntityNameToClassMap = new PrivateFieldsClient<TileEntity, Map>(TileEntity.class, Obf.tileEntityNameToClassMap);
public static final PrivateFieldsClient<TileEntity, Map> tileEntityClassToNameMap = new PrivateFieldsClient<TileEntity, Map>(TileEntity.class, Obf.tileEntityClassToNameMap);
}

View file

@ -0,0 +1,128 @@
package com.mumfrey.liteloader.client.util.render;
import com.mumfrey.liteloader.util.render.IconTextured;
import net.minecraft.util.ResourceLocation;
public class IconAbsolute implements IconTextured
{
private ResourceLocation textureResource;
private String displayText;
private int texMapSize = 256;
private int width;
private int height;
private int uPos, vPos;
private float uCoord;
private float uCoord2;
private float vCoord;
private float vCoord2;
public IconAbsolute(ResourceLocation textureResource, String displayText, int width, int height, float uCoord, float vCoord, float uCoord2,
float vCoord2)
{
this(textureResource, displayText, width, height, uCoord, vCoord, uCoord2, vCoord2, 256);
}
public IconAbsolute(ResourceLocation textureResource, String displayText, int width, int height, float uCoord, float vCoord, float uCoord2,
float vCoord2, int texMapSize)
{
this.textureResource = textureResource;
this.displayText = displayText;
this.width = width;
this.height = height;
this.uPos = (int)uCoord;
this.vPos = (int)vCoord;
this.texMapSize = texMapSize;
this.uCoord = uCoord / this.texMapSize;
this.uCoord2 = uCoord2 / this.texMapSize;
this.vCoord = vCoord / this.texMapSize;
this.vCoord2 = vCoord2 / this.texMapSize;
}
@Override
public String getDisplayText()
{
return this.displayText;
}
@Override
public ResourceLocation getTextureResource()
{
return this.textureResource;
}
@Override
public int getIconWidth()
{
return this.width;
}
@Override
public int getIconHeight()
{
return this.height;
}
@Override
public int getUPos()
{
return this.uPos;
}
@Override
public int getVPos()
{
return this.vPos;
}
@Override
public float getMinU()
{
return this.uCoord;
}
@Override
public float getMaxU()
{
return this.uCoord2 - Float.MIN_VALUE;
}
@Override
public float getInterpolatedU(double slice)
{
float uSize = this.uCoord2 - this.uCoord;
return this.uCoord + uSize * ((float)slice / 16.0F) - Float.MIN_VALUE;
}
@Override
public float getMinV()
{
return this.vCoord;
}
@Override
public float getMaxV()
{
return this.vCoord2 - Float.MIN_VALUE;
}
@Override
public float getInterpolatedV(double slice)
{
float vSize = this.vCoord2 - this.vCoord;
return this.vCoord + vSize * ((float)slice / 16.0F) - Float.MIN_VALUE;
}
@Override
public String getIconName()
{
return this.displayText;
}
}

View file

@ -0,0 +1,20 @@
package com.mumfrey.liteloader.client.util.render;
import net.minecraft.util.ResourceLocation;
import com.mumfrey.liteloader.util.render.IconClickable;
public abstract class IconAbsoluteClickable extends IconAbsolute implements IconClickable
{
public IconAbsoluteClickable(ResourceLocation textureResource, String displayText, int width, int height, float uCoord, float vCoord,
float uCoord2, float vCoord2)
{
super(textureResource, displayText, width, height, uCoord, vCoord, uCoord2, vCoord2);
}
public IconAbsoluteClickable(ResourceLocation textureResource, String displayText, int width, int height, float uCoord, float vCoord,
float uCoord2, float vCoord2, int texMapSize)
{
super(textureResource, displayText, width, height, uCoord, vCoord, uCoord2, vCoord2, texMapSize);
}
}

View file

@ -0,0 +1,140 @@
package com.mumfrey.liteloader.client.util.render;
import com.mumfrey.liteloader.util.render.Icon;
import net.minecraft.util.ResourceLocation;
public class IconTiled implements Icon
{
private ResourceLocation textureResource;
protected int iconID;
protected int iconU;
protected int iconV;
private int width;
private int height;
private float uCoord;
private float uCoord2;
private float vCoord;
private float vCoord2;
private int textureWidth, textureHeight;
public IconTiled(ResourceLocation textureResource, int id)
{
this(textureResource, id, 16);
}
public IconTiled(ResourceLocation textureResource, int id, int iconSize)
{
this(textureResource, id, iconSize, 0);
}
public IconTiled(ResourceLocation textureResource, int id, int iconSize, int yOffset)
{
this(textureResource, id, iconSize, (id % (256 / iconSize)) * iconSize, (id / (256 / iconSize)) * iconSize + yOffset);
}
public IconTiled(ResourceLocation textureResource, int id, int iconSize, int iconU, int iconV)
{
this(textureResource, id, iconU, iconV, iconSize, iconSize, 256, 256);
}
public IconTiled(ResourceLocation textureResource, int id, int iconU, int iconV, int width, int height, int textureWidth, int textureHeight)
{
this.iconID = id;
this.textureResource = textureResource;
this.textureWidth = textureWidth;
this.textureHeight = textureHeight;
this.width = width;
this.height = height;
this.init(iconU, iconV);
}
protected void init(int iconU, int iconV)
{
this.iconU = iconU;
this.iconV = iconV;
this.uCoord = (float)iconU / (float)this.textureWidth;
this.uCoord2 = (float)(iconU + this.width) / (float)this.textureWidth;
this.vCoord = (float)iconV / (float)this.textureHeight;
this.vCoord2 = (float)(iconV + this.height) / (float)this.textureHeight;
}
public ResourceLocation getTextureResource()
{
return this.textureResource;
}
public int getIconID()
{
return this.iconID;
}
public void setIconID(int id)
{
this.iconID = id;
this.init((id % 16) * 16, (id / 16) * 16);
}
@Override
public int getIconWidth()
{
return this.width;
}
@Override
public int getIconHeight()
{
return this.height;
}
@Override
public float getMinU()
{
return this.uCoord;
}
@Override
public float getMaxU()
{
return this.uCoord2 - Float.MIN_VALUE;
}
@Override
public float getInterpolatedU(double slice)
{
float uSize = this.uCoord2 - this.uCoord;
return this.uCoord + uSize * ((float)slice / 16.0F) - Float.MIN_VALUE;
}
@Override
public float getMinV()
{
return this.vCoord;
}
@Override
public float getMaxV()
{
return this.vCoord2 - Float.MIN_VALUE;
}
@Override
public float getInterpolatedV(double slice)
{
float vSize = this.vCoord2 - this.vCoord;
return this.vCoord + vSize * ((float)slice / 16.0F) - Float.MIN_VALUE;
}
@Override
public String getIconName()
{
return this.textureResource + "_" + this.iconID;
}
}

Some files were not shown because too many files have changed in this diff Show more