diff --git a/app/libs/ecj-compiler-3.12.1.jar.bak b/app/libs/ecj-compiler-3.12.1.jar.bak new file mode 100644 index 0000000..da02ac5 Binary files /dev/null and b/app/libs/ecj-compiler-3.12.1.jar.bak differ diff --git a/app/libs/horizon-extension-1.2.jar b/app/libs/horizon-extension-1.2.jar index ba707e2..2c62447 100644 Binary files a/app/libs/horizon-extension-1.2.jar and b/app/libs/horizon-extension-1.2.jar differ diff --git a/app/libs/rhino-innercore-1.7.14.dex b/app/libs/rhino-innercore-1.7.14.dex deleted file mode 100644 index c05e025..0000000 Binary files a/app/libs/rhino-innercore-1.7.14.dex and /dev/null differ diff --git a/app/libs/rhino-innercore-1.7.14.jar b/app/libs/rhino-innercore-1.7.14.jar deleted file mode 100644 index 82ad85c..0000000 Binary files a/app/libs/rhino-innercore-1.7.14.jar and /dev/null differ diff --git a/app/libs/rhino-innercore-1.7.14.jar.bak b/app/libs/rhino-innercore-1.7.14.jar.bak new file mode 100644 index 0000000..e6421b8 Binary files /dev/null and b/app/libs/rhino-innercore-1.7.14.jar.bak differ diff --git a/app/src/main/assets/rhino/Messages.properties b/app/src/main/assets/rhino/Messages.properties new file mode 100644 index 0000000..5290a4a --- /dev/null +++ b/app/src/main/assets/rhino/Messages.properties @@ -0,0 +1,845 @@ +# +# Default JavaScript messages file. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# This is replaced during jar assembly from property string +# and should not be translated +implementation.version = 1.7.7 + +# +# To add JavaScript error messages for a particular locale, create a +# new Messages_[locale].properties file, where [locale] is the Java +# string abbreviation for that locale. For example, JavaScript +# messages for the Polish locale should be located in +# Messages_pl.properties, and messages for the Italian Swiss locale +# should be located in Messages_it_CH.properties. Message properties +# files should be accessible through the classpath under +# org.mozilla.javascript.resources +# +# See: +# java.util.ResourceBundle +# java.text.MessageFormat +# + +# SomeJavaClassWhereUsed + +# Codegen +msg.dup.parms =\ + Duplicate parameter name "{0}". + +msg.too.big.jump =\ + Program too complex: too big jump offset. + +msg.too.big.index =\ + Program too complex: internal index exceeds 64K limit. + +msg.while.compiling.fn =\ + Encountered code generation error while compiling function "{0}": {1} + +msg.while.compiling.script =\ + Encountered code generation error while compiling script: {0} + +# Context +msg.ctor.not.found =\ + Constructor for "{0}" not found. + +msg.not.ctor =\ + "{0}" is not a constructor. + +# FunctionObject +msg.varargs.ctor =\ + Method or constructor "{0}" must be static with the signature \ + "(Context cx, Object[] args, Function ctorObj, boolean inNewExpr)" \ + to define a variable arguments constructor. + +msg.varargs.fun =\ + Method "{0}" must be static with the signature \ + "(Context cx, Scriptable thisObj, Object[] args, Function funObj)" \ + to define a variable arguments function. + +msg.incompat.call =\ + Method "{0}" called on incompatible object. + +msg.bad.parms =\ + Unsupported parameter type "{0}" in method "{1}". + +msg.bad.method.return =\ + Unsupported return type "{0}" in method "{1}". + +msg.bad.ctor.return =\ + Construction of objects of type "{0}" is not supported. + +msg.no.overload =\ + Method "{0}" occurs multiple times in class "{1}". + +msg.method.not.found =\ + Method "{0}" not found in "{1}". + +# IRFactory + +msg.bad.for.in.lhs =\ + Invalid left-hand side of for..in loop. + +msg.mult.index =\ + Only one variable allowed in for..in loop. + +msg.bad.for.in.destruct =\ + Left hand side of for..in loop must be an array of length 2 to accept \ + key/value pair. + +msg.cant.convert =\ + Can''t convert to type "{0}". + +msg.bad.assign.left =\ + Invalid assignment left-hand side. + +msg.bad.decr =\ + Invalid decrement operand. + +msg.bad.incr =\ + Invalid increment operand. + +msg.bad.yield =\ + yield must be in a function. + +msg.yield.parenthesized =\ + yield expression must be parenthesized. + +# NativeGlobal +msg.cant.call.indirect =\ + Function "{0}" must be called directly, and not by way of a \ + function of another name. + +msg.eval.nonstring =\ + Calling eval() with anything other than a primitive string value will \ + simply return the value. Is this what you intended? + +msg.eval.nonstring.strict =\ + Calling eval() with anything other than a primitive string value is not \ + allowed in strict mode. + +msg.bad.destruct.op =\ + Invalid destructuring assignment operator + +# NativeCall +msg.only.from.new =\ + "{0}" may only be invoked from a "new" expression. + +msg.deprec.ctor =\ + The "{0}" constructor is deprecated. + +# NativeFunction +msg.no.function.ref.found =\ + no source found to decompile function reference {0} + +msg.arg.isnt.array =\ + second argument to Function.prototype.apply must be an array + +# NativeGlobal +msg.bad.esc.mask =\ + invalid string escape mask + +# NativeJavaClass +msg.cant.instantiate =\ + error instantiating ({0}): class {1} is interface or abstract + +msg.bad.ctor.sig =\ + Found constructor with wrong signature: \ + {0} calling {1} with signature {2} + +msg.not.java.obj =\ + Expected argument to getClass() to be a Java object. + +msg.no.java.ctor =\ + Java constructor for "{0}" with arguments "{1}" not found. + +# NativeJavaMethod +msg.method.ambiguous =\ + The choice of Java method {0}.{1} matching JavaScript argument types ({2}) is ambiguous; \ + candidate methods are: {3} + +msg.constructor.ambiguous =\ + The choice of Java constructor {0} matching JavaScript argument types ({1}) is ambiguous; \ + candidate constructors are: {2} + +# NativeJavaObject +msg.conversion.not.allowed =\ + Cannot convert {0} to {1} + +msg.no.empty.interface.conversion =\ + Cannot convert function to interface {0} with no methods + +msg.no.function.interface.conversion =\ + Cannot convert function to interface {0} since it contains methods with \ + different names + +msg.undefined.function.interface =\ + Property "{0}" is not defined in interface adapter + +msg.not.function.interface =\ + Property "{0}" is not a function in interface adapter + +# NativeJavaPackage +msg.not.classloader =\ + Constructor for "Packages" expects argument of type java.lang.Classloader + +# NativeRegExp +msg.bad.quant =\ + Invalid quantifier {0} + +msg.overlarge.backref =\ + Overly large back reference {0} + +msg.overlarge.min =\ + Overly large minimum {0} + +msg.overlarge.max =\ + Overly large maximum {0} + +msg.zero.quant =\ + Zero quantifier {0} + +msg.max.lt.min =\ + Maximum {0} less than minimum + +msg.unterm.quant =\ + Unterminated quantifier {0} + +msg.unterm.paren =\ + Unterminated parenthetical {0} + +msg.unterm.class =\ + Unterminated character class {0} + +msg.bad.range =\ + Invalid range in character class. + +msg.trail.backslash =\ + Trailing \\ in regular expression. + +msg.re.unmatched.right.paren =\ + unmatched ) in regular expression. + +msg.no.regexp =\ + Regular expressions are not available. + +msg.bad.backref =\ + back-reference exceeds number of capturing parentheses. + +msg.bad.regexp.compile =\ + Only one argument may be specified if the first argument to \ + RegExp.prototype.compile is a RegExp object. + +msg.arg.not.object =\ + Expected argument of type object, but instead had type {0} + +# NativeDate +msg.invalid.date =\ + Date is invalid. + +msg.toisostring.must.return.primitive =\ + toISOString must return a primitive value, but instead returned "{0}" + +# Parser +msg.got.syntax.errors = \ + Compilation produced {0} syntax errors. + +msg.var.redecl =\ + TypeError: redeclaration of var {0}. + +msg.const.redecl =\ + TypeError: redeclaration of const {0}. + +msg.let.redecl =\ + TypeError: redeclaration of variable {0}. + +msg.parm.redecl =\ + TypeError: redeclaration of formal parameter {0}. + +msg.fn.redecl =\ + TypeError: redeclaration of function {0}. + +msg.let.decl.not.in.block =\ + SyntaxError: let declaration not directly within block + +msg.bad.object.init =\ + SyntaxError: invalid object initializer + +# NodeTransformer +msg.dup.label =\ + duplicated label + +msg.undef.label =\ + undefined label + +msg.bad.break =\ + unlabelled break must be inside loop or switch + +msg.continue.outside =\ + continue must be inside loop + +msg.continue.nonloop =\ + continue can only use labeles of iteration statements + +msg.bad.throw.eol =\ + Line terminator is not allowed between the throw keyword and throw \ + expression. + +msg.no.paren.parms =\ + missing ( before function parameters. + +msg.no.parm =\ + missing formal parameter + +msg.no.paren.after.parms =\ + missing ) after formal parameters + +msg.no.brace.body =\ + missing '{' before function body + +msg.no.brace.after.body =\ + missing } after function body + +msg.no.paren.cond =\ + missing ( before condition + +msg.no.paren.after.cond =\ + missing ) after condition + +msg.no.semi.stmt =\ + missing ; before statement + +msg.missing.semi =\ + missing ; after statement + +msg.no.name.after.dot =\ + missing name after . operator + +msg.no.name.after.coloncolon =\ + missing name after :: operator + +msg.no.name.after.dotdot =\ + missing name after .. operator + +msg.no.name.after.xmlAttr =\ + missing name after .@ + +msg.no.bracket.index =\ + missing ] in index expression + +msg.no.paren.switch =\ + missing ( before switch expression + +msg.no.paren.after.switch =\ + missing ) after switch expression + +msg.no.brace.switch =\ + missing '{' before switch body + +msg.bad.switch =\ + invalid switch statement + +msg.no.colon.case =\ + missing : after case expression + +msg.double.switch.default =\ + double default label in the switch statement + +msg.no.while.do =\ + missing while after do-loop body + +msg.no.paren.for =\ + missing ( after for + +msg.no.semi.for =\ + missing ; after for-loop initializer + +msg.no.semi.for.cond =\ + missing ; after for-loop condition + +msg.in.after.for.name =\ + missing in after for + +msg.no.paren.for.ctrl =\ + missing ) after for-loop control + +msg.no.paren.with =\ + missing ( before with-statement object + +msg.no.paren.after.with =\ + missing ) after with-statement object + +msg.no.with.strict =\ + with statements not allowed in strict mode + +msg.no.paren.after.let =\ + missing ( after let + +msg.no.paren.let =\ + missing ) after variable list + +msg.no.curly.let =\ + missing } after let statement + +msg.bad.return =\ + invalid return + +msg.no.brace.block =\ + missing } in compound statement + +msg.bad.label =\ + invalid label + +msg.bad.var =\ + missing variable name + +msg.bad.var.init =\ + invalid variable initialization + +msg.no.colon.cond =\ + missing : in conditional expression + +msg.no.paren.arg =\ + missing ) after argument list + +msg.no.bracket.arg =\ + missing ] after element list + +msg.bad.prop =\ + invalid property id + +msg.no.colon.prop =\ + missing : after property id + +msg.no.brace.prop =\ + missing } after property list + +msg.no.paren =\ + missing ) in parenthetical + +msg.reserved.id =\ + identifier is a reserved word + +msg.no.paren.catch =\ + missing ( before catch-block condition + +msg.bad.catchcond =\ + invalid catch block condition + +msg.catch.unreachable =\ + any catch clauses following an unqualified catch are unreachable + +msg.no.brace.try =\ + missing '{' before try block + +msg.no.brace.catchblock =\ + missing '{' before catch-block body + +msg.try.no.catchfinally =\ + ''try'' without ''catch'' or ''finally'' + +msg.no.return.value =\ + function {0} does not always return a value + +msg.anon.no.return.value =\ + anonymous function does not always return a value + +msg.return.inconsistent =\ + return statement is inconsistent with previous usage + +msg.generator.returns =\ + TypeError: generator function {0} returns a value + +msg.anon.generator.returns =\ + TypeError: anonymous generator function returns a value + +msg.syntax =\ + syntax error + +msg.unexpected.eof =\ + Unexpected end of file + +msg.XML.bad.form =\ + illegally formed XML syntax + +msg.XML.not.available =\ + XML runtime not available + +msg.too.deep.parser.recursion =\ + Too deep recursion while parsing + +msg.too.many.constructor.args =\ + Too many constructor arguments + +msg.too.many.function.args =\ + Too many function arguments + +msg.no.side.effects =\ + Code has no side effects + +msg.extra.trailing.semi =\ + Extraneous trailing semicolon + +msg.extra.trailing.comma =\ + Trailing comma is not legal in an ECMA-262 object initializer + +msg.trailing.array.comma =\ + Trailing comma in array literal has different cross-browser behavior + +msg.equal.as.assign =\ + Test for equality (==) mistyped as assignment (=)? + +msg.var.hides.arg =\ + Variable {0} hides argument + +msg.destruct.assign.no.init =\ + Missing = in destructuring declaration + +msg.no.octal.strict =\ + Octal numbers prohibited in strict mode. + +msg.dup.obj.lit.prop.strict =\ + Property "{0}" already defined in this object literal. + +msg.dup.param.strict =\ + Parameter "{0}" already declared in this function. + +msg.bad.id.strict =\ + "{0}" is not a valid identifier for this use in strict mode. + +# ScriptRuntime + +# is there a better message for this? +# it's currently only used as a poison pill for caller, caller and arguments properties +msg.op.not.allowed =\ + This operation is not allowed. + +msg.no.properties =\ + {0} has no properties. + +msg.invalid.iterator =\ + Invalid iterator value + +msg.iterator.primitive =\ + __iterator__ returned a primitive value + +msg.assn.create.strict =\ + Assignment to undeclared variable {0} + +msg.ref.undefined.prop =\ + Reference to undefined property "{0}" + +msg.prop.not.found =\ + Property {0} not found. + +msg.set.prop.no.setter =\ + Cannot set property {0} that has only a getter. + +msg.invalid.type =\ + Invalid JavaScript value of type {0} + +msg.primitive.expected =\ + Primitive type expected (had {0} instead) + +msg.namespace.expected =\ + Namespace object expected to left of :: (found {0} instead) + +msg.null.to.object =\ + Cannot convert null to an object. + +msg.undef.to.object =\ + Cannot convert undefined to an object. + +msg.cyclic.value =\ + Cyclic {0} value not allowed. + +msg.is.not.defined =\ + "{0}" is not defined. + +msg.undef.prop.read =\ + Cannot read property "{1}" from {0} + +msg.undef.prop.write =\ + Cannot set property "{1}" of {0} to "{2}" + +msg.undef.prop.delete =\ + Cannot delete property "{1}" of {0} + +msg.undef.method.call =\ + Cannot call method "{1}" of {0} + +msg.undef.with =\ + Cannot apply "with" to {0} + +msg.isnt.function =\ + {0} is not a function, it is {1}. + +msg.isnt.function.in =\ + Cannot call property {0} in object {1}. It is not a function, it is "{2}". + +msg.function.not.found =\ + Cannot find function {0}. + +msg.function.not.found.in =\ + Cannot find function {0} in object {1}. + +msg.isnt.xml.object =\ + {0} is not an xml object. + +msg.no.ref.to.get =\ + {0} is not a reference to read reference value. + +msg.no.ref.to.set =\ + {0} is not a reference to set reference value to {1}. + +msg.no.ref.from.function =\ + Function {0} can not be used as the left-hand side of assignment \ + or as an operand of ++ or -- operator. + +msg.bad.default.value =\ + Object''s getDefaultValue() method returned an object. + +msg.instanceof.not.object = \ + Can''t use ''instanceof'' on a non-object. + +msg.instanceof.bad.prototype = \ + ''prototype'' property of {0} is not an object. + +msg.in.not.object = \ + Can''t use ''in'' on a non-object. + +msg.bad.radix = \ + illegal radix {0}. + +# ScriptableObject +msg.default.value =\ + Cannot find default value for object. + +msg.zero.arg.ctor =\ + Cannot load class "{0}" which has no zero-parameter constructor. + +duplicate.defineClass.name =\ + Invalid method "{0}": name "{1}" is already in use. + +msg.ctor.multiple.parms =\ + Can''t define constructor or class {0} since more than one \ + constructor has multiple parameters. + +msg.extend.scriptable =\ + {0} must extend ScriptableObject in order to define property {1}. + +msg.bad.getter.parms =\ + In order to define a property, getter {0} must have zero parameters \ + or a single ScriptableObject parameter. + +msg.obj.getter.parms =\ + Expected static or delegated getter {0} to take a ScriptableObject parameter. + +msg.getter.static =\ + Getter and setter must both be static or neither be static. + +msg.setter.return =\ + Setter must have void return type: {0} + +msg.setter2.parms =\ + Two-parameter setter must take a ScriptableObject as its first parameter. + +msg.setter1.parms =\ + Expected single parameter setter for {0} + +msg.setter2.expected =\ + Expected static or delegated setter {0} to take two parameters. + +msg.setter.parms =\ + Expected either one or two parameters for setter. + +msg.setter.bad.type =\ + Unsupported parameter type "{0}" in setter "{1}". + +msg.add.sealed =\ + Cannot add a property to a sealed object: {0}. + +msg.remove.sealed =\ + Cannot remove a property from a sealed object: {0}. + +msg.modify.sealed =\ + Cannot modify a property of a sealed object: {0}. + +msg.modify.readonly =\ + Cannot modify readonly property: {0}. + +msg.both.data.and.accessor.desc =\ + Cannot be both a data and an accessor descriptor. + +msg.change.configurable.false.to.true =\ + Cannot change the configurable attribute of "{0}" from false to true. + +msg.change.enumerable.with.configurable.false =\ + Cannot change the enumerable attribute of "{0}" because configurable is false. + +msg.change.writable.false.to.true.with.configurable.false =\ + Cannot change the writable attribute of "{0}" from false to true because configurable is false. + +msg.change.value.with.writable.false =\ + Cannot change the value of attribute "{0}" because writable is false. + +msg.change.getter.with.configurable.false =\ + Cannot change the get attribute of "{0}" because configurable is false. + +msg.change.setter.with.configurable.false =\ + Cannot change the set attribute of "{0}" because configurable is false. + +msg.change.property.data.to.accessor.with.configurable.false =\ + Cannot change "{0}" from a data property to an accessor property because configurable is false. + +msg.change.property.accessor.to.data.with.configurable.false =\ + Cannot change "{0}" from an accessor property to a data property because configurable is false. + +msg.not.extensible =\ + Cannot add properties to this object because extensible is false. + +# TokenStream +msg.missing.exponent =\ + missing exponent + +msg.caught.nfe =\ + number format error + +msg.unterminated.string.lit =\ + unterminated string literal + +msg.unterminated.comment =\ + unterminated comment + +msg.unterminated.re.lit =\ + unterminated regular expression literal + +msg.invalid.re.flag =\ + invalid flag after regular expression + +msg.no.re.input.for =\ + no input for {0} + +msg.illegal.character =\ + illegal character + +msg.invalid.escape =\ + invalid Unicode escape sequence + +msg.bad.namespace =\ + not a valid default namespace statement. \ + Syntax is: default xml namespace = EXPRESSION; + +# TokensStream warnings +msg.bad.octal.literal =\ + illegal octal literal digit {0}; interpreting it as a decimal digit + +msg.reserved.keyword =\ + illegal usage of future reserved keyword {0}; interpreting it as ordinary identifier + +# LiveConnect errors +msg.java.internal.field.type =\ + Internal error: type conversion of {0} to assign to {1} on {2} failed. + +msg.java.conversion.implicit_method =\ + Can''t find converter method "{0}" on class {1}. + +msg.java.method.assign =\ + Java method "{0}" cannot be assigned to. + +msg.java.internal.private =\ + Internal error: attempt to access private/protected field "{0}". + +msg.java.no_such_method =\ + Can''t find method {0}. + +msg.script.is.not.constructor =\ + Script objects are not constructors. + +msg.nonjava.method =\ + Java method "{0}" was invoked with {1} as "this" value that can not be converted to Java type {2}. + +msg.java.member.not.found =\ + Java class "{0}" has no public instance field or method named "{1}". + +msg.java.array.index.out.of.bounds =\ + Array index {0} is out of bounds [0..{1}]. + +msg.java.array.member.not.found =\ + Java arrays have no public instance fields or methods named "{0}". + +msg.pkg.int =\ + Java package names may not be numbers. + +msg.access.prohibited =\ + Access to Java class "{0}" is prohibited. + +# ImporterTopLevel +msg.ambig.import =\ + Ambiguous import: "{0}" and and "{1}". + +msg.not.pkg =\ + Function importPackage must be called with a package; had "{0}" instead. + +msg.not.class =\ + Function importClass must be called with a class; had "{0}" instead. + +msg.not.class.not.pkg =\ + "{0}" is neither a class nor a package. + +msg.prop.defined =\ + Cannot import "{0}" since a property by that name is already defined. + +#JavaAdapter +msg.adapter.zero.args =\ + JavaAdapter requires at least one argument. + +msg.not.java.class.arg = \ +Argument {0} is not Java class: {1}. + +#JavaAdapter +msg.only.one.super = \ +Only one class may be extended by a JavaAdapter. Had {0} and {1}. + + +# Arrays +msg.arraylength.bad =\ + Inappropriate array length. + +# Arrays +msg.arraylength.too.big =\ + Array length {0} exceeds supported capacity limit. + +msg.empty.array.reduce =\ + Reduce of empty array with no initial value + +# URI +msg.bad.uri =\ + Malformed URI sequence. + +# Number +msg.bad.precision =\ + Precision {0} out of range. + +# NativeGenerator +msg.send.newborn =\ + Attempt to send value to newborn generator + +msg.already.exec.gen =\ + Already executing generator + +msg.StopIteration.invalid =\ + StopIteration may not be changed to an arbitrary object. + +# Interpreter +msg.yield.closing =\ + Yield from closing generator + +msg.called.null.or.undefined=\ + {0}.prototype.{1} method called on null or undefined + +msg.first.arg.not.regexp=\ + First argument to {0}.prototype.{1} must not be a regular expression \ No newline at end of file diff --git a/app/src/main/java/com/zhekasmirnov/horizon/modloader/java/JavaCompilerHolder.java b/app/src/main/java/com/zhekasmirnov/horizon/modloader/java/JavaCompilerHolder.java new file mode 100644 index 0000000..237425d --- /dev/null +++ b/app/src/main/java/com/zhekasmirnov/horizon/modloader/java/JavaCompilerHolder.java @@ -0,0 +1,266 @@ +package com.zhekasmirnov.horizon.modloader.java; + +import android.content.Context; +import android.content.res.AssetManager; +import com.zhekasmirnov.horizon.compiler.packages.Environment; +import com.zhekasmirnov.horizon.modloader.ModContext; +import com.zhekasmirnov.horizon.runtime.logger.EventLogger; +import com.zhekasmirnov.horizon.runtime.logger.Logger; +import com.zhekasmirnov.horizon.runtime.task.Task; +import com.zhekasmirnov.horizon.runtime.task.TaskManager; +import com.zhekasmirnov.horizon.util.FileUtils; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import org.eclipse.jdt.core.compiler.CompilationProgress; +import org.eclipse.jdt.internal.compiler.batch.Main; +import org.eclipse.jdt.internal.compiler.util.SuffixConstants; + +public class JavaCompilerHolder { + private static final String COMPONENT_PATH = "sdk/java/"; + private static final HashMap instances = new HashMap<>(); + private final Component[] COMPONENTS = { new JarComponent(COMPONENT_PATH, "android.jar"), + new JarComponent(COMPONENT_PATH, "android-support-multidex.jar"), + new JarComponent(COMPONENT_PATH, "android-support-v4.jar"), new JarComponent(COMPONENT_PATH, "dx.jar"), + new JarComponent(COMPONENT_PATH, "support-annotations-25.3.1.jar"), + new JarComponent(COMPONENT_PATH, "gson-2.6.2.jar"), + new JarComponent(COMPONENT_PATH, "horizon-classes.jar") }; + private final String COMPONENT_VERSION_UUID = "34b14f6e-d8d1-48af-86a7-8adcb41396ce"; + private boolean configured = false; + private final ModContext context; + private final File installationDir; + private boolean isInitialized = false; + private boolean isInitializing = false; + private boolean isInstalled = false; + private final Object main; + + private interface Component { + List getBootFiles(); + boolean install(); + boolean isInstalled(); + } + + private class JarComponent implements Component { + private final String assetName; + private final String assetPath; + + private JarComponent(String str, String str2) { + this.assetPath = str; + this.assetName = str2; + } + + private File getJarFile() { + return new File(Environment.getJavacDir(JavaCompilerHolder.this.context.context), this.assetName); + } + + private String getLockFile() { + try { + String javacDir = Environment.getJavacDir(JavaCompilerHolder.this.context.context); + return FileUtils.readFileText(new File(javacDir, this.assetName + ".uuid")).trim(); + } catch (IOException | NullPointerException unused) { + return null; + } + } + + private void setLockFile() { + try { + String javacDir = Environment.getJavacDir(JavaCompilerHolder.this.context.context); + FileUtils.writeFileText(new File(javacDir, this.assetName + ".uuid"), + "34b14f6e-d8d1-48af-86a7-8adcb41396ce"); + } catch (IOException unused) { + throw new RuntimeException("failed to write UUID lock for jar component: " + this.assetName); + } + } + + public boolean isInstalled() { + return getJarFile().exists() && "34b14f6e-d8d1-48af-86a7-8adcb41396ce".equals(getLockFile()); + } + + public boolean install() { + try { + AssetManager assets = JavaCompilerHolder.this.context.context.getAssets(); + File jarFile = getJarFile(); + FileUtils.unpackAssetOrDirectory(assets, jarFile, this.assetPath + this.assetName); + setLockFile(); + return true; + } catch (IOException e) { + Logger.debug("JavaCompiler", "skipped installing non-exiting " + assetName + " component"); + return false; + } catch (Exception e) { + throw new RuntimeException("failed to install jar component " + this.assetName, e); + } + } + + public List getBootFiles() { + ArrayList arrayList = new ArrayList<>(); + if (isInstalled()) { + arrayList.add(getJarFile()); + } + return arrayList; + } + + public String toString() { + return "[jar component " + this.assetName + "]"; + } + } + + public static JavaCompilerHolder getInstance(Context context2) { + JavaCompilerHolder javaCompilerHolder; + synchronized (instances) { + javaCompilerHolder = instances.get(context2); + } + return javaCompilerHolder; + } + + public static void initializeForContext(ModContext modContext, TaskManager taskManager) { + if (getInstance(modContext.context) == null) { + synchronized (instances) { + JavaCompilerHolder javaCompilerHolder = new JavaCompilerHolder(modContext); + instances.put(modContext.context, javaCompilerHolder); + taskManager.addTask(javaCompilerHolder.getInitializationTask()); + } + } + } + + public JavaCompilerHolder(ModContext modContext) { + this.context = modContext; + File file = new File(Environment.getJavacDir(modContext.context)); + this.installationDir = file; + if (!file.exists()) { + this.installationDir.mkdirs(); + } + try { + Class.forName("org.eclipse.jdt.internal.compiler.batch.Main"); + } catch (ClassNotFoundException e) { + Logger.debug("JavaCompiler", "skipped java ecj initialization because it not found"); + this.main = null; + return; + } + if (this.installationDir.isDirectory()) { + this.main = new Main( + new PrintWriter(modContext.getEventLogger().getStream(EventLogger.MessageType.INFO, "BUILD")), + new PrintWriter(modContext.getEventLogger().getStream(EventLogger.MessageType.FAULT, "BUILD")), + false, (Map) null, (CompilationProgress) null); + return; + } + throw new RuntimeException("failed to allocate installation directory " + this.installationDir); + } + + private void initialize() { + this.isInstalled = true; + for (Component component : this.COMPONENTS) { + if (!component.isInstalled()) { + Logger.debug("JavaCompiler", "installing or re-installing java component: " + component); + if (!component.install()) { + this.isInstalled = false; + } + } + } + } + + public Task getInitializationTask() { + return new Task() { + public String getDescription() { + return "initializing javac"; + } + + public Object getLock() { + return "initialize_javac"; + } + + public void run() { + if (!JavaCompilerHolder.this.isInitializing) { + boolean unused = JavaCompilerHolder.this.isInitializing = true; + if (!JavaCompilerHolder.this.isInitialized) { + JavaCompilerHolder.this.initialize(); + JavaCompilerHolder.this.isInitialized = true; + } + JavaCompilerHolder.this.isInitializing = false; + } + } + }; + } + + private void awaitInitialization() { + while (!this.isInitialized) { + Thread.yield(); + } + } + + public boolean compile(JavaCompilerArguments javaCompilerArguments) { + if (this.main == null) { + return false; + } + if (!this.configured) { + ((Main) (this.main)).configure(javaCompilerArguments.toArray()); + this.configured = true; + } + awaitInitialization(); + return ((Main) (this.main)).compile(new String[0]); + } + + public List getBootFiles() { + ArrayList arrayList = new ArrayList<>(); + for (Component bootFiles : this.COMPONENTS) { + arrayList.addAll(bootFiles.getBootFiles()); + } + return arrayList; + } + + void installLibraries(List list, File file) { + for (File next : list) { + String name = next.getName(); + if (name.endsWith(".jar") || name.endsWith("zip")) { + installJarLibrary(next, file); + } else if (name.endsWith(".dex")) { + File file2 = new File(next.getAbsolutePath().replace(".dex", ".jar")); + installJarLibrary(file2, file); + file2.delete(); + } else { + throw new RuntimeException("Unsupported file format: " + next.getName()); + } + } + } + + private void installJarLibrary(File file, File file2) { + try { + JarFile jarFile = new JarFile(file); + Enumeration entries = jarFile.entries(); + file2.mkdirs(); + while (entries.hasMoreElements()) { + JarEntry nextElement = entries.nextElement(); + if (nextElement.getName().endsWith(SuffixConstants.SUFFIX_STRING_class)) { + File file3 = new File(file2 + File.separator + nextElement.getName()); + if (nextElement.isDirectory()) { + file3.mkdir(); + } else if (!file3.exists()) { + file3.getParentFile().mkdirs(); + InputStream inputStream = jarFile.getInputStream(nextElement); + FileOutputStream fileOutputStream = new FileOutputStream(file3); + byte[] bArr = new byte[8192]; + while (true) { + int read = inputStream.read(bArr); + if (read <= 0) { + break; + } + fileOutputStream.write(bArr, 0, read); + } + fileOutputStream.close(); + inputStream.close(); + } + } + } + } catch (IOException e) { + throw new RuntimeException("failed to install jar library " + file.getName(), e); + } + } +} diff --git a/app/src/main/java/io/nernar/instant/environment/LauncherActivity.java b/app/src/main/java/io/nernar/instant/environment/LauncherActivity.java index a2072a4..a00f96f 100644 --- a/app/src/main/java/io/nernar/instant/environment/LauncherActivity.java +++ b/app/src/main/java/io/nernar/instant/environment/LauncherActivity.java @@ -45,17 +45,15 @@ public class LauncherActivity extends Activity { private static final String[] REQUIRED_PERMISSIONS = { "android.permission.WRITE_EXTERNAL_STORAGE" }; private final HashMap permissionResults = new HashMap<>(); - + private enum PermissionResult { - GRANTED, - DENIED, - REJECTED - } - + GRANTED, DENIED, REJECTED + } + private class DecisionResult { String result; } - + private final Runnable LAUNCH_RUNNABLE = new Runnable() { public void run() { requestPermissionsIfNeeded(); @@ -91,76 +89,80 @@ public void run() { @Override public void run() { View view = LauncherActivity.this.findViewById(R.id.logTextView); - if (view != null) initiateDesiredAnimation(view); + if (view != null) + initiateDesiredAnimation(view); } }); } }; - -private void initPermissionResults() { - synchronized (this.permissionResults) { - for (String str : REQUIRED_PERMISSIONS) { - this.permissionResults.put(str, ContextCompat.checkSelfPermission(this, str) == 0 ? PermissionResult.GRANTED : PermissionResult.DENIED); + + private void initPermissionResults() { + synchronized (this.permissionResults) { + for (String str : REQUIRED_PERMISSIONS) { + this.permissionResults.put(str, + ContextCompat.checkSelfPermission(this, str) == 0 ? PermissionResult.GRANTED + : PermissionResult.DENIED); + } } } -} -private PermissionResult getAllPermissionsResult() { - synchronized (this.permissionResults) { - for (PermissionResult next : this.permissionResults.values()) { - if (next == PermissionResult.REJECTED) { - return next; - } - if (next == PermissionResult.DENIED) { - return next; + private PermissionResult getAllPermissionsResult() { + synchronized (this.permissionResults) { + for (PermissionResult next : this.permissionResults.values()) { + if (next == PermissionResult.REJECTED) { + return next; + } + if (next == PermissionResult.DENIED) { + return next; + } } + return PermissionResult.GRANTED; } - return PermissionResult.GRANTED; } -} -private void requestDeniedPermissions() { - ArrayList arrayList = new ArrayList<>(); - synchronized (this.permissionResults) { - for (String next : this.permissionResults.keySet()) { - if (this.permissionResults.get(next) != PermissionResult.GRANTED) { - arrayList.add(next); + private void requestDeniedPermissions() { + ArrayList arrayList = new ArrayList<>(); + synchronized (this.permissionResults) { + for (String next : this.permissionResults.keySet()) { + if (this.permissionResults.get(next) != PermissionResult.GRANTED) { + arrayList.add(next); + } + } + for (String put : arrayList) { + this.permissionResults.put(put, PermissionResult.DENIED); } } - for (String put : arrayList) { - this.permissionResults.put(put, PermissionResult.DENIED); - } + ActivityCompat.requestPermissions(this, arrayList.toArray(new String[arrayList.size()]), 0); } - ActivityCompat.requestPermissions(this, arrayList.toArray(new String[arrayList.size()]), 0); -} -private void requestPermissionsIfNeeded() { - initPermissionResults(); - if (getAllPermissionsResult() != PermissionResult.GRANTED) { - requestDeniedPermissions(); - while (true) { - PermissionResult allPermissionsResult = getAllPermissionsResult(); - if (allPermissionsResult != PermissionResult.GRANTED) { - if (allPermissionsResult == PermissionResult.REJECTED) { - requestDeniedPermissions(); + private void requestPermissionsIfNeeded() { + initPermissionResults(); + if (getAllPermissionsResult() != PermissionResult.GRANTED) { + requestDeniedPermissions(); + while (true) { + PermissionResult allPermissionsResult = getAllPermissionsResult(); + if (allPermissionsResult != PermissionResult.GRANTED) { + if (allPermissionsResult == PermissionResult.REJECTED) { + requestDeniedPermissions(); + } + Thread.yield(); + } else { + return; } - Thread.yield(); - } else { - return; } } } -} -public void onRequestPermissionsResult(int i, String[] strArr, int[] iArr) { - super.onRequestPermissionsResult(i, strArr, iArr); - synchronized (this.permissionResults) { - for (int i2 = 0; i2 < strArr.length; i2++) { - this.permissionResults.put(strArr[i2], iArr[i2] == 0 ? PermissionResult.GRANTED : PermissionResult.REJECTED); + public void onRequestPermissionsResult(int i, String[] strArr, int[] iArr) { + super.onRequestPermissionsResult(i, strArr, iArr); + synchronized (this.permissionResults) { + for (int i2 = 0; i2 < strArr.length; i2++) { + this.permissionResults.put(strArr[i2], + iArr[i2] == 0 ? PermissionResult.GRANTED : PermissionResult.REJECTED); + } } } -} - + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -170,21 +172,31 @@ protected void onCreate(Bundle savedInstanceState) { System.setOut(new DebuggerStream(logView, logScroll)); new Thread(LAUNCH_RUNNABLE).start(); } - + @Override - protected void onStop() { - super.onStop(); + protected void onDestroy() { + super.onDestroy(); Runtime.getRuntime().exit(0); } - + private void printlnCopyright() { - System.out.println("Copyright, 2022 Mozilla Foundation (Mozilla Rhino 1.7.14)"); + try { + Class.forName("org.eclipse.jdt.internal.compiler.batch.Main"); + System.out.println("Copyright, 2015 IBM Corp (Eclipse Compiler for Java(TM) 3.12.1)"); + } catch (ClassNotFoundException e) { + } + try { + Class.forName("org.mozilla.javascript.Context"); + System.out.println("Copyright, 2022 Mozilla Foundation (Mozilla Rhino 1.7.14)"); + } catch (ClassNotFoundException e) { + System.out.println("Copyright, 2015 Mozilla Foundation (Mozilla Rhino 1.7.7)"); + } System.out.println("Copyright, 2022 Horizon Team (Horizon 1.2, Inner Core)"); System.out.println("Copyright, 2022 Nernar (Instant Referrer " + InstantReferrer.getVersionName() + ")"); System.out.println("Project uses platform licensed libraries. All rights reserved."); System.out.println(); } - + private void initiateDesiredAnimation(View view) { AlphaAnimation animation = new AlphaAnimation(1f, 0.4f); animation.setInterpolator(new AccelerateDecelerateInterpolator()); @@ -193,12 +205,13 @@ private void initiateDesiredAnimation(View view) { public void onAnimationEnd(Animation who) { view.setAlpha(0.4f); } + public void onAnimationStart(Animation who) {} public void onAnimationRepeat(Animation who) {} }); view.startAnimation(animation); } - + private String requestPackByUserSelection(List packs) { DecisionResult selection = new DecisionResult(); runOnUiThread(new Runnable() { @@ -227,7 +240,7 @@ public void onDismiss(DialogInterface di) { } return selection.result; } - + private Pack getValidSelectedPack(ContextHolder holder) { String selectedFolder = getSharedPreferences("selected", 0).getString("pack_folder", null); File packsFolder = new File(Environment.getExternalStorageDirectory(), "games/horizon/packs"); @@ -246,7 +259,8 @@ private Pack getValidSelectedPack(ContextHolder holder) { System.out.println(StringUtils.getStackTrace(any)); try { Thread.sleep(3000); - } catch (InterruptedException e) {} + } catch (InterruptedException e) { + } } } ArrayList availabledPacks = new ArrayList<>(); diff --git a/app/src/main/java/io/nernar/instant/prebuilt/InstantTranslation.java b/app/src/main/java/io/nernar/instant/prebuilt/InstantTranslation.java index 5a0cd48..f83ed7e 100644 --- a/app/src/main/java/io/nernar/instant/prebuilt/InstantTranslation.java +++ b/app/src/main/java/io/nernar/instant/prebuilt/InstantTranslation.java @@ -73,6 +73,7 @@ public static InstantTranslation toSingleton() { { put(new ENGLISH()); put(new RUSSIAN()); + put(new UKRAINIAN()); } public final class ENGLISH extends AbstractResource { @@ -164,4 +165,49 @@ public String getId() { return InstantTranslation.this.getId() + ":ru"; } } + + public final class UKRAINIAN extends AbstractResource { + { + put("instant_referrer", "Середовище раннього запуску"); + put("exit", "Вийти"); + put("proceed", "Продовжити"); + put("yes", "Так"); + put("no", "Ні"); + put("abort", "Відміна"); + put("restart", "Рестарт"); + put("hold_to_abort", "Утримуйте клавішу для відміни запуску"); + put("abort_not_supported", "Відміна запуску не підтримується"); + put("instant_not_supported", "Середовище раннього запуску поки що не підтримується"); + put("fail_launch", "Не вдалось провести запуск"); + put("another_instance_running", "Інший пак Inner Core вже був завантажений, тому середовище раннього запуску не може бути використано."); + put("restart_to_launch", "Ви бажаєте перезавантажити програму, щоб відновити його?"); + put("instant_wait", "ШУКАЄМО СЕРЕДОВИЩЕ"); + put("instant_build", "ПІДГОТУВАННЯ"); + put("instant_run", "ЗБІРКА"); + put("fail_remove_launch_button", "Не вдалося видалити клавішу запуску"); + put("fail_setup_informative_progress", "Не вдалося встановити інформаційний прогрес"); + put("fail_make_immersive", "Не вдалося перейти в безрамковий режим"); + put("fail_restyle_padding_recycler", "Не вдалося додати відступи в меню"); + put("fail_change_recycler_gravity", "Не вдалося змінити гравітаційне притяжіння меню"); + put("fail_measure_recycler_layout", "Не вдалося розтягнути макет меню"); + put("fail_add_auto_launch_button", "Не вдалося додати прапорець автозапуску"); + put("fail_patch_abort_ability", "Не вдалося зазначити можливіть відміни"); + put("fail_remove_recycler_decoration", "Не вдалося видалити розмежування пунктів меню"); + put("fail_measure_and_clip_background", "Не вдалося розтягнути й обрізати фон"); + put("fail_remove_distribution_nodes", "Не вдалося видалити нотатки для розповсюдження"); + put("fail_close_advertisement_requests", "Не вдалося закрити рекламні запити"); + put("fail_cleanup_exiting_containers", "Не вдалося очистити існуючі контейнери"); + put("continue_decision", "Ви все одно бажаєте продовжити?"); + put("instant_startup_interrupted", "Старт середовища ранього запуску був перерваний або щось відбулось під час завантаження модулів."); + put("resource_override_invocation", "Перезапис розміщення ресурсів зазнав краху"); + put("flipbook_descriptor_invocation", "Створення описів анімованих текстур зазнало краху"); + put("material_processor_invocation", "Створення обробника матеріалів зазнало краху"); + put("content_manager_invocation", "Створення основного обробника ресурсів зазнало краху"); + } + + @Override + public String getId() { + return InstantTranslation.this.getId() + ":uk"; + } + } } diff --git a/app/src/main/java/io/nernar/instant/storage/TranslationResource.java b/app/src/main/java/io/nernar/instant/storage/TranslationResource.java index 4ab2c60..ce6c0cb 100644 --- a/app/src/main/java/io/nernar/instant/storage/TranslationResource.java +++ b/app/src/main/java/io/nernar/instant/storage/TranslationResource.java @@ -12,9 +12,10 @@ public TranslationResource(String id, String english) { put("en", english); } - public TranslationResource(String id, String english, String russian) { + public TranslationResource(String id, String english, String russian, String ukrainian) { this(id, english); put("ru", russian); + put("uk", ukrainian); } public TranslationResource(String id, String... keysAndSource) { diff --git a/app/src/main/java/io/nernar/instant/storage/external/InstantConfigInformation.java b/app/src/main/java/io/nernar/instant/storage/external/InstantConfigInformation.java index c7cafef..1908257 100644 --- a/app/src/main/java/io/nernar/instant/storage/external/InstantConfigInformation.java +++ b/app/src/main/java/io/nernar/instant/storage/external/InstantConfigInformation.java @@ -7,7 +7,8 @@ public class InstantConfigInformation extends AbstractResource { { put(new TranslationResource("description", "Miscellaneous Instant Referrer options and several internal visual interface patches.", - "Основные настройки среды раннего запуска и некоторых частей встроенных патчей интерфейса.")); + "Основные настройки среды раннего запуска и некоторых частей встроенных патчей интерфейса.", + "Основні налаштування середовища раннього запуску і деяких частин вбудованих патчів інтерфейсу.")); put(new Properties()); } @@ -48,7 +49,8 @@ protected class Environment extends AbstractResource { { put(new TranslationResource("name", "Environment", - "Среда")); + "Среда", + "Середовище")); put("collapsible", false); put("index", 0); } @@ -63,8 +65,12 @@ protected class EnvironmentInformativeProgress extends AbstractResource { { put(new TranslationResource("name", "Informative progress", - "Информативный прогресс")); - put("description", "Показывать больше информации в выполняемых задачах, в том числе их количество и затраченное время."); + "Информативный прогресс", + "Інформативний прогрес")); + put(new TranslationResource("description", + "Show more information in performed tasks, including their count and spent time.", + "Показывать больше информации в выполняемых задачах, в том числе их количество и затраченное время.", + "Показувати більше інформації у виконуваних задачах, в тому числі їх кількість і витрачений час.")); put("index", 1); } @@ -78,8 +84,12 @@ protected class EnvironmentImmersiveMode extends AbstractResource { { put(new TranslationResource("name", "Immersive mode", - "Безграничный режим")); - put("description", "Расширять содержимое окна, делая системные панели навигации прозрачными."); + "Безграничный режим", + "Безрамковий режим")); + put(new TranslationResource("description", + "Expand window contents, making system navigation panels transparent.", + "Расширять содержимое окна, делая системные панели навигации прозрачными.", + "Розширювати вміст вікна, роблячи системні панелі навігації прозорими.")); put("index", 2); } @@ -104,8 +114,12 @@ protected class EnvironmentAutoLaunchOverride extends AbstractResource { { put(new TranslationResource("name", "Auto-launch Override", - "Перезапись авто-запуска")); - put("description", "Игнорировать входящий системный флаг авто-запуска, заменяя его встроенным флажком."); + "Перезапись авто-запуска", + "Перезапис авто-запуску")); + put(new TranslationResource("description", + "Ignore incoming auto-start system flag, replacing it with a built-in flag.", + "Игнорировать входящий системный флаг авто-запуска, заменяя его встроенным флажком.", + "Ігнорувати вхідний системний прапорець авто-запуску, замінюючи його вбудованим прапорцем.")); put("index", 3); } @@ -119,8 +133,12 @@ protected class EnvironmentAbortAbility extends AbstractResource { { put(new TranslationResource("name", "Abort Ability", - "Возможность отмены")); - put("description", "Добавить возможность отменить запуск пака, не перезапуская приложение."); + "Возможность отмены", + "Можливість відмінии")); + put(new TranslationResource("description", + "Add ability to cancel pack launch without restarting application.", + "Добавить возможность отменить запуск пака, не перезапуская приложение.", + "Додати можливість відмінювати запуск паку не перезавантажуючи програму.")); put("index", 4); } @@ -134,7 +152,8 @@ protected class Background extends AbstractResource { { put(new TranslationResource("name", "Background", - "Компоновка")); + "Компоновка", + "Фон")); put("collapsible", false); put("index", 5); } @@ -149,8 +168,12 @@ protected class BackgroundShuffleArt extends AbstractResource { { put(new TranslationResource("name", "Shuffle Art", - "Перемешать арты")); - put("description", "Случайно изменять порядок фоновых артов после каждого запуска."); + "Перемешать арты", + "Змішати арти")); + put(new TranslationResource("description", + "Randomly change order of background art after each launch.", + "Случайно изменять порядок фоновых артов после каждого запуска.", + "Випадково змінювати порядок фонових артів після кожного запуску.")); put("index", 6); } @@ -186,8 +209,12 @@ protected class BackgroundForceFullscreen extends AbstractResource { { put(new TranslationResource("name", "Force Fullscreen", - "Полноэкранный режим")); - put("description", "Растянуть изображение компоновки на весь экран."); + "Полноэкранный режим", + "Повноекранний режим")); + put(new TranslationResource("description", + "Stretch content layout image to full screen.", + "Растянуть изображение компоновки на весь экран.", + "Растянуть изображение компоновки на весь экран.")); put("index", 7); } @@ -223,7 +250,8 @@ protected class Distribution extends AbstractResource { { put(new TranslationResource("name", "Distribution", - "Распространение")); + "Распространение", + "Розповсюдження")); put("collapsible", false); put("index", 8); } @@ -238,8 +266,12 @@ protected class DistributionHadMinecraft extends AbstractResource { { put(new TranslationResource("name", "Had Minecraft", - "Наличие Майнкрафта")); - put("description", "Игнорировать наличие установленной игре на устройстве, обозначая прочую собственную покупку."); + "Наличие Майнкрафта", + "Наявність Майнкрафту")); + put(new TranslationResource("description", + "Ignore presence of device installed game, indicating other own purchase.", + "Игнорировать наличие установленной игре на устройстве, обозначая прочую собственную покупку.", + "Ігнорувати наявність уставновленої гри на пристрої, позначаючи іншу особисту покупку.")); put("index", 9); } @@ -253,8 +285,12 @@ protected class DistributionDismissWarning extends AbstractResource { { put(new TranslationResource("name", "Dismiss Warning", - "Скрытие предупреждения")); - put("description", "Скрывать предупреждение об отсуствии игры, следуя условиям лицензирования."); + "Скрытие предупреждения", + "Приховані попередження")); + put(new TranslationResource("description", + "Hide warning about game absense, following licensing conditions.", + "Скрывать предупреждение об отсуствии игры, следуя условиям лицензирования.", + "Приховувати попередження про відсутність гри, слідуючи умовам ліцензування.")); put("index", 10); } @@ -268,7 +304,8 @@ protected class Advertisement extends AbstractResource { { put(new TranslationResource("name", "Advertisement", - "Объявления")); + "Объявления", + "Оголошення")); put("collapsible", false); put("index", 11); } @@ -283,8 +320,12 @@ protected class AdvertisementSupportModification extends AbstractResource { { put(new TranslationResource("name", "Support Modification", - "Поддержка модификаций")); - put("description", "Поддерживать разработчиков модификаций и создателей Inner Core, добавляя рекламные карточки."); + "Поддержка модификаций", + "Підтримка модифікацій")); + put(new TranslationResource("description", + "Support modification developers and Inner Core creators by adding promotional cards.", + "Поддерживать разработчиков модификаций и создателей Inner Core, добавляя рекламные карточки.", + "Підтримувати розробників модифікацій і творців Inner Core, додаючи рекламні картки.")); put("index", 12); } @@ -298,8 +339,12 @@ protected class AdvertisementBlockEverything extends AbstractResource { { put(new TranslationResource("name", "Block Everything", - "Блокировка всего")); - put("description", "Запретить добавление любых рекламных объявлений, отказываясь от поддержки создателей Horizon."); + "Блокировка всего", + "Блокування всього")); + put(new TranslationResource("description", + "Prohibit addition of any advertisements, refusing to support creators of Horizon.", + "Запретить добавление любых рекламных объявлений, отказываясь от поддержки создателей Horizon.", + "Заборонити додавання будь-яких рекламних оголошень, відмовляючись від підтримки творців Horizon.")); put("index", 13); } diff --git a/app/src/main/java/io/nernar/instant/visual/InstantActivityFactory.java b/app/src/main/java/io/nernar/instant/visual/InstantActivityFactory.java index e8c7d27..f91b1dd 100644 --- a/app/src/main/java/io/nernar/instant/visual/InstantActivityFactory.java +++ b/app/src/main/java/io/nernar/instant/visual/InstantActivityFactory.java @@ -1,19 +1,23 @@ package io.nernar.instant.visual; import android.app.Activity; +import android.content.Context; import android.graphics.Bitmap; import android.graphics.Color; import android.widget.RelativeLayout; import com.zhekasmirnov.horizon.launcher.pack.Pack; import io.nernar.instant.referrer.InstantConfig; import io.nernar.instant.storage.external.InstantConfigInformation; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import org.json.JSONObject; import org.mineprogramming.horizon.innercore.view.config.ConfigPage; import org.mineprogramming.horizon.innercore.view.page.PagesManager; import java.util.ArrayList; import java.util.Collection; public class InstantActivityFactory extends Pack.MenuActivityFactory { - private PagesManager pagesManager; + private Object pagesManager = null; @Override public String getMenuTitle() { @@ -46,17 +50,30 @@ public String getIconGraphics() { @Override public void onCreateLayout(Activity activity, RelativeLayout content) { - // TODO: ConfigView already deprecated and located in org.mineprogramming.horizon.innercore.view.config + // ConfigView already deprecated and located in org.mineprogramming.horizon.innercore.view.config // without any backport/backsupport implementation, what are you doing, Igor? - // ConfigView config = new ConfigView(activity, "Instant Referrer", InstantConfig.getFile().getAbsolutePath()); - pagesManager = new PagesManager(content); - ConfigPage config = new ConfigPage(pagesManager, "Instant Referrer", InstantConfig.getFile().getAbsolutePath()); - config.loadInfo(new InstantConfigInformation()); - pagesManager.reset(config); + try { + pagesManager = new PagesManager(content); + ConfigPage config = new ConfigPage((PagesManager) pagesManager, "Instant Referrer", InstantConfig.getFile().getAbsolutePath()); + config.loadInfo(new InstantConfigInformation()); + ((PagesManager) pagesManager).reset(config); + } catch (NoClassDefFoundError any) { + try { + Class clazz = Class.forName("org.mineprogramming.horizon.innercore.view.config.ConfigView"); + Constructor constructor = clazz.getConstructor(Context.class, String.class, String.class); + Object object = constructor.newInstance(activity, "Instant Referrer", InstantConfig.getFile().getAbsolutePath()); + object.getClass().getMethod("loadInfo", JSONObject.class).invoke(object, new InstantConfigInformation()); + } catch (ClassNotFoundException | InstantiationException | InvocationTargetException | NoSuchMethodException | IllegalAccessException e) { + throw new UnsupportedOperationException(e); + } + } } @Override public boolean onBackPressed() { - return pagesManager.navigateBack(); + if (pagesManager == null) { + return false; + } + return ((PagesManager) pagesManager).navigateBack(); } }