6.0.0 - 部分插件及工具版本更新
This commit is contained in:
@@ -1,19 +1,23 @@
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
|
||||
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_16
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.compilerArgs << '-Xlint:deprecation' << '-Xlint:unchecked'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion versions.compile
|
||||
buildToolsVersion versions.buildTool
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion versions.mini
|
||||
targetSdkVersion versions.target
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
@@ -21,11 +25,9 @@ android {
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
sourceCompatibility JavaVersion.VERSION_16
|
||||
targetCompatibility JavaVersion.VERSION_16
|
||||
}
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
@@ -33,45 +35,51 @@ android {
|
||||
}
|
||||
|
||||
repositories {
|
||||
flatDir {
|
||||
dirs 'libs'
|
||||
}
|
||||
google()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
androidTestImplementation('androidx.test.espresso:espresso-core:3.1.1-alpha01', {
|
||||
exclude group: 'com.android.support', module: 'support-annotations'
|
||||
})
|
||||
testImplementation 'junit:junit:4.12'
|
||||
api fileTree(dir: 'libs', include: ['*.jar'])
|
||||
api 'org.greenrobot:eventbus:3.0.0'
|
||||
api 'net.lingala.zip4j:zip4j:1.3.2'
|
||||
api('com.afollestad.material-dialogs:core:0.9.2.3', {
|
||||
exclude group: 'com.android.support'
|
||||
})
|
||||
api 'com.google.android.material:material:1.1.0-alpha01'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
|
||||
api 'org.greenrobot:eventbus:3.2.0'
|
||||
|
||||
api 'net.lingala.zip4j:zip4j:2.9.1'
|
||||
|
||||
api('com.afollestad.material-dialogs:core:0.9.6.0')
|
||||
api 'com.google.android.material:material:1.5.0-beta01'
|
||||
|
||||
api 'com.github.hyb1996:EnhancedFloaty:0.31'
|
||||
|
||||
api 'com.makeramen:roundedimageview:2.3.0'
|
||||
// OpenCv
|
||||
api(name: 'opencv-3.4.3', ext: 'aar')
|
||||
|
||||
// OkHttp
|
||||
api 'com.squareup.okhttp3:okhttp:3.10.0'
|
||||
api 'com.squareup.okhttp3:okhttp:5.0.0-alpha.3'
|
||||
|
||||
// JDeferred
|
||||
api 'org.jdeferred:jdeferred-android-aar:1.2.6'
|
||||
//RootShell
|
||||
|
||||
// RootShell
|
||||
api 'com.github.Stericson:RootShell:1.6'
|
||||
|
||||
// Gson
|
||||
api 'com.google.code.gson:gson:2.8.2'
|
||||
// log4j
|
||||
api 'com.google.code.gson:gson:2.8.9'
|
||||
|
||||
// Log4j
|
||||
api group: 'de.mindpipe.android', name: 'android-logging-log4j', version: '1.0.3'
|
||||
api group: 'log4j', name: 'log4j', version: '1.2.17'
|
||||
// Terminal emulator
|
||||
api(name: 'libtermexec-release', ext: 'aar')
|
||||
api(name: 'emulatorview-release', ext: 'aar')
|
||||
api(name: 'term-debug', ext: 'aar')
|
||||
api files('libs/rhino-1.7.7.2.jar')
|
||||
api project(path: ':common')
|
||||
api project(path: ':automator')
|
||||
}
|
||||
|
||||
// Preference
|
||||
api 'androidx.preference:preference-ktx:1.1.1'
|
||||
|
||||
// Terminal emulator
|
||||
api project(":libs:jackpal.androidterm.libtermexec-1.0")
|
||||
api project(":libs:jackpal.androidterm.emulatorview-1.0.42")
|
||||
api project(":libs:jackpal.androidterm-1.0.70")
|
||||
|
||||
api project(":libs:com.android.dx-1.7.0")
|
||||
api project(":libs:org.mozilla.rhino-1.7.14")
|
||||
api project(':libs:org.opencv-4.5.4')
|
||||
|
||||
api project(':common')
|
||||
api project(':automator')
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,46 +1,49 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.stardust.autojs">
|
||||
|
||||
package="com.stardust.autojs"
|
||||
>
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_SETTINGS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_SECURE_SETTINGS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
|
||||
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
|
||||
|
||||
<application
|
||||
>
|
||||
<application>
|
||||
<activity
|
||||
android:name=".execution.ScriptExecuteActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:theme="@style/ScriptTheme"/>
|
||||
android:name=".execution.ScriptExecuteActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:theme="@style/ScriptTheme" />
|
||||
|
||||
|
||||
<activity
|
||||
android:name="com.stardust.autojs.core.permission.PermissionRequestActivity"
|
||||
android:excludeFromRecents="true"
|
||||
android:taskAffinity="com.stardust.autojs.runtime.api.image.ScreenCaptureRequestActivity"
|
||||
android:theme="@style/ScriptTheme.Transparent"/>
|
||||
android:name="com.stardust.autojs.core.permission.PermissionRequestActivity"
|
||||
android:excludeFromRecents="true"
|
||||
android:taskAffinity="com.stardust.autojs.runtime.api.image.ScreenCaptureRequestActivity"
|
||||
android:theme="@style/ScriptTheme.Transparent" />
|
||||
|
||||
<activity
|
||||
android:name="com.stardust.autojs.core.image.capture.ScreenCaptureRequestActivity"
|
||||
android:excludeFromRecents="true"
|
||||
android:taskAffinity="com.stardust.autojs.runtime.api.image.ScreenCaptureRequestActivity"
|
||||
android:theme="@style/ScriptTheme.Transparent"/>
|
||||
android:name="com.stardust.autojs.core.image.capture.ScreenCaptureRequestActivity"
|
||||
android:excludeFromRecents="true"
|
||||
android:taskAffinity="com.stardust.autojs.runtime.api.image.ScreenCaptureRequestActivity"
|
||||
android:theme="@style/ScriptTheme.Transparent" />
|
||||
|
||||
<service
|
||||
android:name="com.stardust.autojs.core.accessibility.AccessibilityService"
|
||||
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
|
||||
android:name="com.stardust.autojs.core.accessibility.AccessibilityService"
|
||||
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.accessibilityservice.AccessibilityService"/>
|
||||
<action android:name="android.accessibilityservice.AccessibilityService" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.accessibilityservice"
|
||||
android:resource="@xml/accessibility_service_config"/>
|
||||
android:name="android.accessibilityservice"
|
||||
android:resource="@xml/accessibility_service_config" />
|
||||
</service>
|
||||
|
||||
</application>
|
||||
|
||||
@@ -52,7 +52,7 @@ runtime.init();
|
||||
global.timers = require('__timers__.js')(runtime, global);
|
||||
|
||||
//初始化不依赖环境的模块
|
||||
global.JSON = require('__json2__.js');
|
||||
global.JSON = require('json2.js');
|
||||
global.util = require('__util__.js');
|
||||
global.device = runtime.device;
|
||||
global.Promise = require('promise.js');
|
||||
|
||||
@@ -1,510 +0,0 @@
|
||||
// json2.js
|
||||
// 2016-10-28
|
||||
// Public Domain.
|
||||
// NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
// See http://www.JSON.org/js.html
|
||||
// This code should be minified before deployment.
|
||||
// See http://javascript.crockford.com/jsmin.html
|
||||
|
||||
// USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
|
||||
// NOT CONTROL.
|
||||
|
||||
// This file creates a global JSON object containing two methods: stringify
|
||||
// and parse. This file provides the ES5 JSON capability to ES3 systems.
|
||||
// If a project might run on IE8 or earlier, then this file should be included.
|
||||
// This file does nothing on ES5 systems.
|
||||
|
||||
// JSON.stringify(value, replacer, space)
|
||||
// value any JavaScript value, usually an object or array.
|
||||
// replacer an optional parameter that determines how object
|
||||
// values are stringified for objects. It can be a
|
||||
// function or an array of strings.
|
||||
// space an optional parameter that specifies the indentation
|
||||
// of nested structures. If it is omitted, the text will
|
||||
// be packed without extra whitespace. If it is a number,
|
||||
// it will specify the number of spaces to indent at each
|
||||
// level. If it is a string (such as "\t" or " "),
|
||||
// it contains the characters used to indent at each level.
|
||||
// This method produces a JSON text from a JavaScript value.
|
||||
// When an object value is found, if the object contains a toJSON
|
||||
// method, its toJSON method will be called and the result will be
|
||||
// stringified. A toJSON method does not serialize: it returns the
|
||||
// value represented by the name/value pair that should be serialized,
|
||||
// or undefined if nothing should be serialized. The toJSON method
|
||||
// will be passed the key associated with the value, and this will be
|
||||
// bound to the value.
|
||||
|
||||
// For example, this would serialize Dates as ISO strings.
|
||||
|
||||
// Date.prototype.toJSON = function (key) {
|
||||
// function f(n) {
|
||||
// // Format integers to have at least two digits.
|
||||
// return (n < 10)
|
||||
// ? "0" + n
|
||||
// : n;
|
||||
// }
|
||||
// return this.getUTCFullYear() + "-" +
|
||||
// f(this.getUTCMonth() + 1) + "-" +
|
||||
// f(this.getUTCDate()) + "T" +
|
||||
// f(this.getUTCHours()) + ":" +
|
||||
// f(this.getUTCMinutes()) + ":" +
|
||||
// f(this.getUTCSeconds()) + "Z";
|
||||
// };
|
||||
|
||||
// You can provide an optional replacer method. It will be passed the
|
||||
// key and value of each member, with this bound to the containing
|
||||
// object. The value that is returned from your method will be
|
||||
// serialized. If your method returns undefined, then the member will
|
||||
// be excluded from the serialization.
|
||||
|
||||
// If the replacer parameter is an array of strings, then it will be
|
||||
// used to select the members to be serialized. It filters the results
|
||||
// such that only members with keys listed in the replacer array are
|
||||
// stringified.
|
||||
|
||||
// Values that do not have JSON representations, such as undefined or
|
||||
// functions, will not be serialized. Such values in objects will be
|
||||
// dropped; in arrays they will be replaced with null. You can use
|
||||
// a replacer function to replace those with JSON values.
|
||||
|
||||
// JSON.stringify(undefined) returns undefined.
|
||||
|
||||
// The optional space parameter produces a stringification of the
|
||||
// value that is filled with line breaks and indentation to make it
|
||||
// easier to read.
|
||||
|
||||
// If the space parameter is a non-empty string, then that string will
|
||||
// be used for indentation. If the space parameter is a number, then
|
||||
// the indentation will be that many spaces.
|
||||
|
||||
// Example:
|
||||
|
||||
// text = JSON.stringify(["e", {pluribus: "unum"}]);
|
||||
// // text is '["e",{"pluribus":"unum"}]'
|
||||
|
||||
// text = JSON.stringify(["e", {pluribus: "unum"}], null, "\t");
|
||||
// // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
|
||||
|
||||
// text = JSON.stringify([new Date()], function (key, value) {
|
||||
// return this[key] instanceof Date
|
||||
// ? "Date(" + this[key] + ")"
|
||||
// : value;
|
||||
// });
|
||||
// // text is '["Date(---current time---)"]'
|
||||
|
||||
// JSON.parse(text, reviver)
|
||||
// This method parses a JSON text to produce an object or array.
|
||||
// It can throw a SyntaxError exception.
|
||||
|
||||
// The optional reviver parameter is a function that can filter and
|
||||
// transform the results. It receives each of the keys and values,
|
||||
// and its return value is used instead of the original value.
|
||||
// If it returns what it received, then the structure is not modified.
|
||||
// If it returns undefined then the member is deleted.
|
||||
|
||||
// Example:
|
||||
|
||||
// // Parse the text. Values that look like ISO date strings will
|
||||
// // be converted to Date objects.
|
||||
|
||||
// myData = JSON.parse(text, function (key, value) {
|
||||
// var a;
|
||||
// if (typeof value === "string") {
|
||||
// a =
|
||||
// /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
|
||||
// if (a) {
|
||||
// return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
|
||||
// +a[5], +a[6]));
|
||||
// }
|
||||
// }
|
||||
// return value;
|
||||
// });
|
||||
|
||||
// myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
|
||||
// var d;
|
||||
// if (typeof value === "string" &&
|
||||
// value.slice(0, 5) === "Date(" &&
|
||||
// value.slice(-1) === ")") {
|
||||
// d = new Date(value.slice(5, -1));
|
||||
// if (d) {
|
||||
// return d;
|
||||
// }
|
||||
// }
|
||||
// return value;
|
||||
// });
|
||||
|
||||
// This is a reference implementation. You are free to copy, modify, or
|
||||
// redistribute.
|
||||
|
||||
/*jslint
|
||||
eval, for, this
|
||||
*/
|
||||
|
||||
/*property
|
||||
JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
|
||||
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
|
||||
lastIndex, length, parse, prototype, push, replace, slice, stringify,
|
||||
test, toJSON, toString, valueOf
|
||||
*/
|
||||
|
||||
|
||||
// Create a JSON object only if one does not already exist. We create the
|
||||
// methods in a closure to avoid creating global variables.
|
||||
var gson = new com.google.gson.Gson();
|
||||
JSON = {};
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var rx_one = /^[\],:{}\s]*$/;
|
||||
var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
|
||||
var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
|
||||
var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
|
||||
var rx_escapable = /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
|
||||
var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
|
||||
|
||||
function f(n) {
|
||||
// Format integers to have at least two digits.
|
||||
return n < 10
|
||||
? "0" + n
|
||||
: n;
|
||||
}
|
||||
|
||||
function this_value() {
|
||||
return this.valueOf();
|
||||
}
|
||||
|
||||
if (typeof Date.prototype.toJSON !== "function") {
|
||||
|
||||
Date.prototype.toJSON = function () {
|
||||
|
||||
return isFinite(this.valueOf())
|
||||
? this.getUTCFullYear() + "-" +
|
||||
f(this.getUTCMonth() + 1) + "-" +
|
||||
f(this.getUTCDate()) + "T" +
|
||||
f(this.getUTCHours()) + ":" +
|
||||
f(this.getUTCMinutes()) + ":" +
|
||||
f(this.getUTCSeconds()) + "Z"
|
||||
: null;
|
||||
};
|
||||
|
||||
Boolean.prototype.toJSON = this_value;
|
||||
Number.prototype.toJSON = this_value;
|
||||
String.prototype.toJSON = this_value;
|
||||
}
|
||||
|
||||
var gap;
|
||||
var indent;
|
||||
var meta;
|
||||
var rep;
|
||||
|
||||
|
||||
function quote(string) {
|
||||
|
||||
// If the string contains no control characters, no quote characters, and no
|
||||
// backslash characters, then we can safely slap some quotes around it.
|
||||
// Otherwise we must also replace the offending characters with safe escape
|
||||
// sequences.
|
||||
|
||||
rx_escapable.lastIndex = 0;
|
||||
return rx_escapable.test(string)
|
||||
? "\"" + string.replace(rx_escapable, function (a) {
|
||||
var c = meta[a];
|
||||
return typeof c === "string"
|
||||
? c
|
||||
: "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
|
||||
}) + "\""
|
||||
: "\"" + string + "\"";
|
||||
}
|
||||
|
||||
|
||||
function str(key, holder) {
|
||||
|
||||
// Produce a string from holder[key].
|
||||
|
||||
var i; // The loop counter.
|
||||
var k; // The member key.
|
||||
var v; // The member value.
|
||||
var length;
|
||||
var mind = gap;
|
||||
var partial;
|
||||
var value = holder[key];
|
||||
|
||||
if(value && value.getClass){
|
||||
return gson.toJson(value);
|
||||
}
|
||||
|
||||
// If the value has a toJSON method, call it to obtain a replacement value.
|
||||
|
||||
if (value && typeof value === "object" &&
|
||||
typeof value.toJSON === "function") {
|
||||
value = value.toJSON(key);
|
||||
}
|
||||
|
||||
// If we were called with a replacer function, then call the replacer to
|
||||
// obtain a replacement value.
|
||||
|
||||
if (typeof rep === "function") {
|
||||
value = rep.call(holder, key, value);
|
||||
}
|
||||
|
||||
// What happens next depends on the value's type.
|
||||
|
||||
switch (typeof value) {
|
||||
case "string":
|
||||
return quote(value);
|
||||
|
||||
case "number":
|
||||
|
||||
// JSON numbers must be finite. Encode non-finite numbers as null.
|
||||
|
||||
return isFinite(value)
|
||||
? String(value)
|
||||
: "null";
|
||||
|
||||
case "boolean":
|
||||
case "null":
|
||||
|
||||
// If the value is a boolean or null, convert it to a string. Note:
|
||||
// typeof null does not produce "null". The case is included here in
|
||||
// the remote chance that this gets fixed someday.
|
||||
|
||||
return String(value);
|
||||
|
||||
// If the type is "object", we might be dealing with an object or an array or
|
||||
// null.
|
||||
|
||||
case "object":
|
||||
|
||||
// Due to a specification blunder in ECMAScript, typeof null is "object",
|
||||
// so watch out for that case.
|
||||
|
||||
if (!value) {
|
||||
return "null";
|
||||
}
|
||||
|
||||
// Make an array to hold the partial results of stringifying this object value.
|
||||
|
||||
gap += indent;
|
||||
partial = [];
|
||||
|
||||
// Is the value an array?
|
||||
|
||||
if (Object.prototype.toString.apply(value) === "[object Array]") {
|
||||
|
||||
// The value is an array. Stringify every element. Use null as a placeholder
|
||||
// for non-JSON values.
|
||||
|
||||
length = value.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
partial[i] = str(i, value) || "null";
|
||||
}
|
||||
|
||||
// Join all of the elements together, separated with commas, and wrap them in
|
||||
// brackets.
|
||||
|
||||
v = partial.length === 0
|
||||
? "[]"
|
||||
: gap
|
||||
? "[\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "]"
|
||||
: "[" + partial.join(",") + "]";
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
|
||||
// If the replacer is an array, use it to select the members to be stringified.
|
||||
|
||||
if (rep && typeof rep === "object") {
|
||||
length = rep.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
if (typeof rep[i] === "string") {
|
||||
k = rep[i];
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (
|
||||
gap
|
||||
? ": "
|
||||
: ":"
|
||||
) + v);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// Otherwise, iterate through all of the keys in the object.
|
||||
|
||||
for (k in value) {
|
||||
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (
|
||||
gap
|
||||
? ": "
|
||||
: ":"
|
||||
) + v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Join all of the member texts together, separated with commas,
|
||||
// and wrap them in braces.
|
||||
|
||||
v = partial.length === 0
|
||||
? "{}"
|
||||
: gap
|
||||
? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}"
|
||||
: "{" + partial.join(",") + "}";
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
// If the JSON object does not yet have a stringify method, give it one.
|
||||
|
||||
if (typeof JSON.stringify !== "function") {
|
||||
meta = { // table of character substitutions
|
||||
"\b": "\\b",
|
||||
"\t": "\\t",
|
||||
"\n": "\\n",
|
||||
"\f": "\\f",
|
||||
"\r": "\\r",
|
||||
"\"": "\\\"",
|
||||
"\\": "\\\\"
|
||||
};
|
||||
JSON.stringify = function (value, replacer, space) {
|
||||
|
||||
// The stringify method takes a value and an optional replacer, and an optional
|
||||
// space parameter, and returns a JSON text. The replacer can be a function
|
||||
// that can replace values, or an array of strings that will select the keys.
|
||||
// A default replacer method can be provided. Use of the space parameter can
|
||||
// produce text that is more easily readable.
|
||||
|
||||
var i;
|
||||
gap = "";
|
||||
indent = "";
|
||||
|
||||
// If the space parameter is a number, make an indent string containing that
|
||||
// many spaces.
|
||||
|
||||
if (typeof space === "number") {
|
||||
for (i = 0; i < space; i += 1) {
|
||||
indent += " ";
|
||||
}
|
||||
|
||||
// If the space parameter is a string, it will be used as the indent string.
|
||||
|
||||
} else if (typeof space === "string") {
|
||||
indent = space;
|
||||
}
|
||||
|
||||
// If there is a replacer, it must be a function or an array.
|
||||
// Otherwise, throw an error.
|
||||
|
||||
rep = replacer;
|
||||
if (replacer && typeof replacer !== "function" &&
|
||||
(typeof replacer !== "object" ||
|
||||
typeof replacer.length !== "number")) {
|
||||
throw new Error("JSON.stringify");
|
||||
}
|
||||
|
||||
// Make a fake root object containing our value under the key of "".
|
||||
// Return the result of stringifying the value.
|
||||
|
||||
return str("", {"": value});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// If the JSON object does not yet have a parse method, give it one.
|
||||
|
||||
if (typeof JSON.parse !== "function") {
|
||||
JSON.parse = function (text, reviver) {
|
||||
|
||||
// The parse method takes a text and an optional reviver function, and returns
|
||||
// a JavaScript value if the text is a valid JSON text.
|
||||
|
||||
var j;
|
||||
|
||||
function walk(holder, key) {
|
||||
|
||||
// The walk method is used to recursively walk the resulting structure so
|
||||
// that modifications can be made.
|
||||
|
||||
var k;
|
||||
var v;
|
||||
var value = holder[key];
|
||||
if (value && typeof value === "object") {
|
||||
for (k in value) {
|
||||
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
||||
v = walk(value, k);
|
||||
if (v !== undefined) {
|
||||
value[k] = v;
|
||||
} else {
|
||||
delete value[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return reviver.call(holder, key, value);
|
||||
}
|
||||
|
||||
|
||||
// Parsing happens in four stages. In the first stage, we replace certain
|
||||
// Unicode characters with escape sequences. JavaScript handles many characters
|
||||
// incorrectly, either silently deleting them, or treating them as line endings.
|
||||
|
||||
text = String(text);
|
||||
rx_dangerous.lastIndex = 0;
|
||||
if (rx_dangerous.test(text)) {
|
||||
text = text.replace(rx_dangerous, function (a) {
|
||||
return "\\u" +
|
||||
("0000" + a.charCodeAt(0).toString(16)).slice(-4);
|
||||
});
|
||||
}
|
||||
|
||||
// In the second stage, we run the text against regular expressions that look
|
||||
// for non-JSON patterns. We are especially concerned with "()" and "new"
|
||||
// because they can cause invocation, and "=" because it can cause mutation.
|
||||
// But just to be safe, we want to reject all unexpected forms.
|
||||
|
||||
// We split the second stage into 4 regexp operations in order to work around
|
||||
// crippling inefficiencies in IE's and Safari's regexp engines. First we
|
||||
// replace the JSON backslash pairs with "@" (a non-JSON character). Second, we
|
||||
// replace all simple value tokens with "]" characters. Third, we delete all
|
||||
// open brackets that follow a colon or comma or that begin the text. Finally,
|
||||
// we look to see that the remaining characters are only whitespace or "]" or
|
||||
// "," or ":" or "{" or "}". If that is so, then the text is safe for eval.
|
||||
|
||||
if (
|
||||
rx_one.test(
|
||||
text
|
||||
.replace(rx_two, "@")
|
||||
.replace(rx_three, "]")
|
||||
.replace(rx_four, "")
|
||||
)
|
||||
) {
|
||||
|
||||
// In the third stage we use the eval function to compile the text into a
|
||||
// JavaScript structure. The "{" operator is subject to a syntactic ambiguity
|
||||
// in JavaScript: it can begin a block or an object literal. We wrap the text
|
||||
// in parens to eliminate the ambiguity.
|
||||
|
||||
j = eval("(" + text + ")");
|
||||
|
||||
// In the optional fourth stage, we recursively walk the new structure, passing
|
||||
// each name/value pair to a reviver function for possible transformation.
|
||||
|
||||
return (typeof reviver === "function")
|
||||
? walk({"": j}, "")
|
||||
: j;
|
||||
}
|
||||
|
||||
// If the text is not JSON parseable, then a SyntaxError is thrown.
|
||||
|
||||
throw new SyntaxError("JSON.parse");
|
||||
};
|
||||
}
|
||||
}());
|
||||
|
||||
module.exports = JSON;
|
||||
765
autojs/src/main/assets/modules/json2.js
Normal file
765
autojs/src/main/assets/modules/json2.js
Normal file
@@ -0,0 +1,765 @@
|
||||
// noinspection ES6ConvertVarToLetConst
|
||||
|
||||
// json2.js
|
||||
// 2017-06-12
|
||||
// Public Domain.
|
||||
// NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
|
||||
// USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
|
||||
// NOT CONTROL.
|
||||
|
||||
// This file creates a global JSON object containing two methods: stringify
|
||||
// and parse. This file provides the ES5 JSON capability to ES3 systems.
|
||||
// If a project might run on IE8 or earlier, then this file should be included.
|
||||
// This file does nothing on ES5 systems.
|
||||
|
||||
// JSON.stringify(value, replacer, space)
|
||||
// value any JavaScript value, usually an object or array.
|
||||
// replacer an optional parameter that determines how object
|
||||
// values are stringified for objects. It can be a
|
||||
// function or an array of strings.
|
||||
// space an optional parameter that specifies the indentation
|
||||
// of nested structures. If it is omitted, the text will
|
||||
// be packed without extra whitespace. If it is a number,
|
||||
// it will specify the number of spaces to indent at each
|
||||
// level. If it is a string (such as "\t" or " "),
|
||||
// it contains the characters used to indent at each level.
|
||||
// This method produces a JSON text from a JavaScript value.
|
||||
// When an object value is found, if the object contains a toJSON
|
||||
// method, its toJSON method will be called and the result will be
|
||||
// stringified. A toJSON method does not serialize: it returns the
|
||||
// value represented by the name/value pair that should be serialized,
|
||||
// or undefined if nothing should be serialized. The toJSON method
|
||||
// will be passed the key associated with the value, and this will be
|
||||
// bound to the value.
|
||||
|
||||
// For example, this would serialize Dates as ISO strings.
|
||||
|
||||
// Date.prototype.toJSON = function (key) {
|
||||
// function f(n) {
|
||||
// // Format integers to have at least two digits.
|
||||
// return (n < 10)
|
||||
// ? "0" + n
|
||||
// : n;
|
||||
// }
|
||||
// return this.getUTCFullYear() + "-" +
|
||||
// f(this.getUTCMonth() + 1) + "-" +
|
||||
// f(this.getUTCDate()) + "T" +
|
||||
// f(this.getUTCHours()) + ":" +
|
||||
// f(this.getUTCMinutes()) + ":" +
|
||||
// f(this.getUTCSeconds()) + "Z";
|
||||
// };
|
||||
|
||||
// You can provide an optional replacer method. It will be passed the
|
||||
// key and value of each member, with this bound to the containing
|
||||
// object. The value that is returned from your method will be
|
||||
// serialized. If your method returns undefined, then the member will
|
||||
// be excluded from the serialization.
|
||||
|
||||
// If the replacer parameter is an array of strings, then it will be
|
||||
// used to select the members to be serialized. It filters the results
|
||||
// such that only members with keys listed in the replacer array are
|
||||
// stringified.
|
||||
|
||||
// Values that do not have JSON representations, such as undefined or
|
||||
// functions, will not be serialized. Such values in objects will be
|
||||
// dropped; in arrays they will be replaced with null. You can use
|
||||
// a replacer function to replace those with JSON values.
|
||||
|
||||
// JSON.stringify(undefined) returns undefined.
|
||||
|
||||
// The optional space parameter produces a stringification of the
|
||||
// value that is filled with line breaks and indentation to make it
|
||||
// easier to read.
|
||||
|
||||
// If the space parameter is a non-empty string, then that string will
|
||||
// be used for indentation. If the space parameter is a number, then
|
||||
// the indentation will be that many spaces.
|
||||
|
||||
// Example:
|
||||
|
||||
// text = JSON.stringify(["e", {pluribus: "unum"}]);
|
||||
// // text is '["e",{"pluribus":"unum"}]'
|
||||
|
||||
// text = JSON.stringify(["e", {pluribus: "unum"}], null, "\t");
|
||||
// // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
|
||||
|
||||
// text = JSON.stringify([new Date()], function (key, value) {
|
||||
// return this[key] instanceof Date
|
||||
// ? "Date(" + this[key] + ")"
|
||||
// : value;
|
||||
// });
|
||||
// // text is '["Date(---current time---)"]'
|
||||
|
||||
// JSON.parse(text, reviver)
|
||||
// This method parses a JSON text to produce an object or array.
|
||||
// It can throw a SyntaxError exception.
|
||||
|
||||
// The optional reviver parameter is a function that can filter and
|
||||
// transform the results. It receives each of the keys and values,
|
||||
// and its return value is used instead of the original value.
|
||||
// If it returns what it received, then the structure is not modified.
|
||||
// If it returns undefined then the member is deleted.
|
||||
|
||||
// Example:
|
||||
|
||||
// // Parse the text. Values that look like ISO date strings will
|
||||
// // be converted to Date objects.
|
||||
|
||||
// myData = JSON.parse(text, function (key, value) {
|
||||
// var a;
|
||||
// if (typeof value === "string") {
|
||||
// a =
|
||||
// /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
|
||||
// if (a) {
|
||||
// return new Date(Date.UTC(
|
||||
// +a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6]
|
||||
// ));
|
||||
// }
|
||||
// return value;
|
||||
// }
|
||||
// });
|
||||
|
||||
// myData = JSON.parse(
|
||||
// "[\"Date(09/09/2001)\"]",
|
||||
// function (key, value) {
|
||||
// var d;
|
||||
// if (
|
||||
// typeof value === "string"
|
||||
// && value.slice(0, 5) === "Date("
|
||||
// && value.slice(-1) === ")"
|
||||
// ) {
|
||||
// d = new Date(value.slice(5, -1));
|
||||
// if (d) {
|
||||
// return d;
|
||||
// }
|
||||
// }
|
||||
// return value;
|
||||
// }
|
||||
// );
|
||||
|
||||
// This is a reference implementation. You are free to copy, modify, or
|
||||
// redistribute.
|
||||
|
||||
/*jslint
|
||||
eval, for, this
|
||||
*/
|
||||
|
||||
/*property
|
||||
JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
|
||||
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
|
||||
lastIndex, length, parse, prototype, push, replace, slice, stringify,
|
||||
test, toJSON, toString, valueOf
|
||||
*/
|
||||
|
||||
|
||||
// Create a JSON object only if one does not already exist. We create the
|
||||
// methods in a closure to avoid creating global variables.
|
||||
|
||||
if (typeof JSON !== 'object') {
|
||||
// noinspection JSValidateTypes
|
||||
JSON = {};
|
||||
}
|
||||
|
||||
(function basic() {
|
||||
'use strict';
|
||||
|
||||
var rx_one = /^[\],:{}\s]*$/;
|
||||
var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
|
||||
var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
|
||||
var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
|
||||
var rx_escapable = /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
|
||||
var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
|
||||
|
||||
function f(n) {
|
||||
// Format integers to have at least two digits.
|
||||
return (n < 10)
|
||||
? '0' + n
|
||||
: n;
|
||||
}
|
||||
|
||||
function this_value() {
|
||||
return this.valueOf();
|
||||
}
|
||||
|
||||
if (typeof Date.prototype.toJSON !== 'function') {
|
||||
|
||||
Date.prototype.toJSON = function () {
|
||||
|
||||
return isFinite(this.valueOf())
|
||||
? (
|
||||
this.getUTCFullYear()
|
||||
+ '-'
|
||||
+ f(this.getUTCMonth() + 1)
|
||||
+ '-'
|
||||
+ f(this.getUTCDate())
|
||||
+ 'T'
|
||||
+ f(this.getUTCHours())
|
||||
+ ':'
|
||||
+ f(this.getUTCMinutes())
|
||||
+ ':'
|
||||
+ f(this.getUTCSeconds())
|
||||
+ 'Z'
|
||||
)
|
||||
: null;
|
||||
};
|
||||
|
||||
Boolean.prototype.toJSON = this_value;
|
||||
Number.prototype.toJSON = this_value;
|
||||
String.prototype.toJSON = this_value;
|
||||
}
|
||||
|
||||
var gap;
|
||||
var indent;
|
||||
var meta;
|
||||
var rep;
|
||||
|
||||
function quote(string) {
|
||||
|
||||
// If the string contains no control characters, no quote characters, and no
|
||||
// backslash characters, then we can safely slap some quotes around it.
|
||||
// Otherwise we must also replace the offending characters with safe escape
|
||||
// sequences.
|
||||
|
||||
rx_escapable.lastIndex = 0;
|
||||
return rx_escapable.test(string)
|
||||
? '"' + string.replace(rx_escapable, function (a) {
|
||||
var c = meta[a];
|
||||
return typeof c === 'string'
|
||||
? c
|
||||
: '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||||
}) + '"'
|
||||
: '"' + string + '"';
|
||||
}
|
||||
|
||||
function str(key, holder) {
|
||||
|
||||
// Produce a string from holder[key].
|
||||
|
||||
var i; // The loop counter.
|
||||
var k; // The member key.
|
||||
var v; // The member value.
|
||||
var length;
|
||||
var mind = gap;
|
||||
var partial;
|
||||
var value = holder[key];
|
||||
|
||||
// If the value has a toJSON method, call it to obtain a replacement value.
|
||||
|
||||
if (
|
||||
value
|
||||
&& typeof value === 'object'
|
||||
&& typeof value.toJSON === 'function'
|
||||
) {
|
||||
value = value.toJSON(key);
|
||||
}
|
||||
|
||||
// If we were called with a replacer function, then call the replacer to
|
||||
// obtain a replacement value.
|
||||
|
||||
if (typeof rep === 'function') {
|
||||
value = rep.call(holder, key, value);
|
||||
}
|
||||
|
||||
// What happens next depends on the value's type.
|
||||
|
||||
switch (typeof value) {
|
||||
case 'string':
|
||||
return quote(value);
|
||||
|
||||
case 'number':
|
||||
|
||||
// JSON numbers must be finite. Encode non-finite numbers as null.
|
||||
|
||||
return (isFinite(value))
|
||||
? String(value)
|
||||
: 'null';
|
||||
|
||||
case 'boolean':
|
||||
|
||||
// If the value is a boolean or null, convert it to a string. Note:
|
||||
// typeof null does not produce "null". The case is included here in
|
||||
// the remote chance that this gets fixed someday.
|
||||
|
||||
return String(value);
|
||||
|
||||
// If the type is "object", we might be dealing with an object or an array or
|
||||
// null.
|
||||
|
||||
case 'object':
|
||||
|
||||
// Due to a specification blunder in ECMAScript, typeof null is "object",
|
||||
// so watch out for that case.
|
||||
|
||||
if (!value) {
|
||||
return 'null';
|
||||
}
|
||||
|
||||
// Make an array to hold the partial results of stringifying this object value.
|
||||
|
||||
gap += indent;
|
||||
partial = [];
|
||||
|
||||
// Is the value an array?
|
||||
|
||||
if (Object.prototype.toString.apply(value) === '[object Array]') {
|
||||
|
||||
// The value is an array. Stringify every element. Use null as a placeholder
|
||||
// for non-JSON values.
|
||||
|
||||
length = value.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
partial[i] = str(i, value) || 'null';
|
||||
}
|
||||
|
||||
// Join all of the elements together, separated with commas, and wrap them in
|
||||
// brackets.
|
||||
|
||||
v = partial.length === 0
|
||||
? '[]'
|
||||
: gap
|
||||
? (
|
||||
'[\n'
|
||||
+ gap
|
||||
+ partial.join(',\n' + gap)
|
||||
+ '\n'
|
||||
+ mind
|
||||
+ ']'
|
||||
)
|
||||
: '[' + partial.join(',') + ']';
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
|
||||
// If the replacer is an array, use it to select the members to be stringified.
|
||||
|
||||
if (rep && typeof rep === 'object') {
|
||||
length = rep.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
if (typeof rep[i] === 'string') {
|
||||
k = rep[i];
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (
|
||||
(gap)
|
||||
? ': '
|
||||
: ':'
|
||||
) + v);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// Otherwise, iterate through all of the keys in the object.
|
||||
|
||||
for (k in value) {
|
||||
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (
|
||||
(gap)
|
||||
? ': '
|
||||
: ':'
|
||||
) + v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Join all of the member texts together, separated with commas,
|
||||
// and wrap them in braces.
|
||||
|
||||
v = partial.length === 0
|
||||
? '{}'
|
||||
: gap
|
||||
? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
|
||||
: '{' + partial.join(',') + '}';
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
// If the JSON object does not yet have a stringify method, give it one.
|
||||
|
||||
if (typeof JSON.stringify !== 'function') {
|
||||
meta = { // table of character substitutions
|
||||
'\b': '\\b',
|
||||
'\t': '\\t',
|
||||
'\n': '\\n',
|
||||
'\f': '\\f',
|
||||
'\r': '\\r',
|
||||
'"': '\\"',
|
||||
'\\': '\\\\',
|
||||
};
|
||||
|
||||
/**
|
||||
* The JSON.stringify() method converts a JavaScript object or value to a JSON string,
|
||||
* optionally replacing values if a replacer function is specified or optionally
|
||||
* including only the specified properties if a replacer array is specified.
|
||||
* @param {any} value -
|
||||
* The value to convert to a JSON string.
|
||||
* @param {(this: any, key: string, value: any) => any} [replacer] -
|
||||
* A function that alters the behavior of the stringification process,
|
||||
* or an array of String and Number that serve as an allowlist
|
||||
* for selecting/filtering the properties of the value object to be included in the JSON string.
|
||||
* If this value is null or not provided,
|
||||
* all properties of the object are included in the resulting JSON string.
|
||||
* @param {string | number} [space] -
|
||||
* A String or Number object that's used to insert white space
|
||||
* into the output JSON string for readability purposes.
|
||||
* If this is a Number, it indicates the number of space characters
|
||||
* to use as white space for indenting purposes; this number is capped
|
||||
* at 10 (if it is greater, the value is just 10).
|
||||
* Values less than 1 indicate that no space should be used.
|
||||
* If this is a String, the string (or the first 10 characters of the string,
|
||||
* if it's longer than that) is used as white space.
|
||||
* If this parameter is not provided (or is null), no white space is used.
|
||||
* @return {string} -
|
||||
* A JSON string representing the given value, or undefined.
|
||||
*/
|
||||
JSON.stringify = function (value, replacer, space) {
|
||||
|
||||
// The stringify method takes a value and an optional replacer, and an optional
|
||||
// space parameter, and returns a JSON text. The replacer can be a function
|
||||
// that can replace values, or an array of strings that will select the keys.
|
||||
// A default replacer method can be provided. Use of the space parameter can
|
||||
// produce text that is more easily readable.
|
||||
|
||||
var i;
|
||||
gap = '';
|
||||
indent = '';
|
||||
|
||||
// If the space parameter is a number, make an indent string containing that
|
||||
// many spaces.
|
||||
|
||||
if (typeof space === 'number') {
|
||||
for (i = 0; i < space; i += 1) {
|
||||
indent += ' ';
|
||||
}
|
||||
|
||||
// If the space parameter is a string, it will be used as the indent string.
|
||||
|
||||
} else if (typeof space === 'string') {
|
||||
indent = space;
|
||||
}
|
||||
|
||||
// If there is a replacer, it must be a function or an array.
|
||||
// Otherwise, throw an error.
|
||||
|
||||
rep = replacer;
|
||||
if (replacer && typeof replacer !== 'function' && (
|
||||
typeof replacer !== 'object'
|
||||
|| typeof replacer.length !== 'number'
|
||||
)) {
|
||||
throw new Error('JSON.stringify');
|
||||
}
|
||||
|
||||
// Make a fake root object containing our value under the key of "".
|
||||
// Return the result of stringifying the value.
|
||||
|
||||
return str('', {'': value});
|
||||
};
|
||||
}
|
||||
|
||||
// If the JSON object does not yet have a parse method, give it one.
|
||||
|
||||
if (typeof JSON.parse !== 'function') {
|
||||
/**
|
||||
* The JSON.parse() method parses a JSON string,
|
||||
* constructing the JavaScript value or object described by the string.
|
||||
* An optional reviver function can be provided to perform
|
||||
* a transformation on the resulting object before it is returned.
|
||||
* @param {string} text -
|
||||
* The string to parse as JSON. See the JSON object for a description of JSON syntax.
|
||||
* @param {(this: any, key: string, value: any) => any} reviver -
|
||||
* If a function, this prescribes how the value
|
||||
* originally produced by parsing is transformed, before being returned.
|
||||
* @return {any} -
|
||||
* The Object, Array, string, number, boolean, or null value corresponding to the given JSON text.
|
||||
*/
|
||||
JSON.parse = function (text, reviver) {
|
||||
|
||||
// The parse method takes a text and an optional reviver function, and returns
|
||||
// a JavaScript value if the text is a valid JSON text.
|
||||
|
||||
var j;
|
||||
|
||||
function walk(holder, key) {
|
||||
|
||||
// The walk method is used to recursively walk the resulting structure so
|
||||
// that modifications can be made.
|
||||
|
||||
var k;
|
||||
var v;
|
||||
var value = holder[key];
|
||||
if (value && typeof value === 'object') {
|
||||
for (k in value) {
|
||||
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
||||
v = walk(value, k);
|
||||
if (v !== undefined) {
|
||||
value[k] = v;
|
||||
} else {
|
||||
delete value[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return reviver.call(holder, key, value);
|
||||
}
|
||||
|
||||
// Parsing happens in four stages. In the first stage, we replace certain
|
||||
// Unicode characters with escape sequences. JavaScript handles many characters
|
||||
// incorrectly, either silently deleting them, or treating them as line endings.
|
||||
|
||||
text = String(text);
|
||||
rx_dangerous.lastIndex = 0;
|
||||
if (rx_dangerous.test(text)) {
|
||||
text = text.replace(rx_dangerous, function (a) {
|
||||
return (
|
||||
'\\u'
|
||||
+ ('0000' + a.charCodeAt(0).toString(16)).slice(-4)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// In the second stage, we run the text against regular expressions that look
|
||||
// for non-JSON patterns. We are especially concerned with "()" and "new"
|
||||
// because they can cause invocation, and "=" because it can cause mutation.
|
||||
// But just to be safe, we want to reject all unexpected forms.
|
||||
|
||||
// We split the second stage into 4 regexp operations in order to work around
|
||||
// crippling inefficiencies in IE's and Safari's regexp engines. First we
|
||||
// replace the JSON backslash pairs with "@" (a non-JSON character). Second, we
|
||||
// replace all simple value tokens with "]" characters. Third, we delete all
|
||||
// open brackets that follow a colon or comma or that begin the text. Finally,
|
||||
// we look to see that the remaining characters are only whitespace or "]" or
|
||||
// "," or ":" or "{" or "}". If that is so, then the text is safe for eval.
|
||||
|
||||
if (
|
||||
rx_one.test(
|
||||
text
|
||||
.replace(rx_two, '@')
|
||||
.replace(rx_three, ']')
|
||||
.replace(rx_four, ''),
|
||||
)
|
||||
) {
|
||||
|
||||
// In the third stage we use the eval function to compile the text into a
|
||||
// JavaScript structure. The "{" operator is subject to a syntactic ambiguity
|
||||
// in JavaScript: it can begin a block or an object literal. We wrap the text
|
||||
// in parens to eliminate the ambiguity.
|
||||
|
||||
j = eval('(' + text + ')');
|
||||
|
||||
// In the optional fourth stage, we recursively walk the new structure, passing
|
||||
// each name/value pair to a reviver function for possible transformation.
|
||||
|
||||
return (typeof reviver === 'function')
|
||||
? walk({'': j}, '')
|
||||
: j;
|
||||
}
|
||||
|
||||
// If the text is not JSON parseable, then a SyntaxError is thrown.
|
||||
|
||||
throw new SyntaxError('JSON.parse');
|
||||
};
|
||||
}
|
||||
}());
|
||||
|
||||
(function cycle() {
|
||||
/*
|
||||
cycle.js
|
||||
2021-05-31
|
||||
|
||||
Public Domain.
|
||||
|
||||
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
|
||||
This code should be minified before deployment.
|
||||
See https://www.crockford.com/jsmin.html
|
||||
|
||||
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
|
||||
NOT CONTROL.
|
||||
*/
|
||||
|
||||
// The file uses the WeakMap feature of ES6.
|
||||
|
||||
/*jslint eval */
|
||||
|
||||
/*property
|
||||
$ref, decycle, forEach, get, indexOf, isArray, keys, length, push,
|
||||
retrocycle, set, stringify, test
|
||||
*/
|
||||
|
||||
if (typeof JSON.decycle !== 'function') {
|
||||
/**
|
||||
* Make a deep copy of an object or array, assuring that there is at most one instance
|
||||
* of each object or array in the resulting structure.
|
||||
* The duplicate references (which might be forming cycles) are replaced
|
||||
* with an object of the form {"$ref": PATH} where the PATH is
|
||||
* a JSONPath string that locates the first occurance.
|
||||
*
|
||||
* If a replacer function is provided, then it will be called for each value.
|
||||
* A replacer function receives a value and returns a replacement value.
|
||||
*
|
||||
* JSONPath is used to locate the unique object.
|
||||
* $ indicates the top level of the object or array.
|
||||
* [NUMBER] or [STRING] indicates a child element or property.
|
||||
* @example
|
||||
* var a = [];
|
||||
* a[0] = a;
|
||||
* // produces the string '[{"$ref":"$"}]'.
|
||||
* return JSON.stringify(JSON.decycle(a));
|
||||
* @example
|
||||
* let o = {};
|
||||
* o.a = o;
|
||||
*
|
||||
* let p = (JSON.retrocycle(JSON.parse(JSON.stringify(JSON.decycle(o)))));
|
||||
* console.log(p.a.a.a === p.a); // true
|
||||
*/
|
||||
JSON.decycle = function decycle(object, replacer) {
|
||||
'use strict';
|
||||
|
||||
var objects = new WeakMap(); // object to path mappings
|
||||
|
||||
return (function derez(value, path) {
|
||||
|
||||
// The derez function recurses through the object, producing the deep copy.
|
||||
|
||||
var old_path; // The path of an earlier occurance of value
|
||||
var nu; // The new object or array
|
||||
|
||||
// If a replacer function was provided, then call it to get a replacement value.
|
||||
|
||||
if (replacer !== undefined) {
|
||||
value = replacer(value);
|
||||
}
|
||||
|
||||
// typeof null === "object", so go on if this value is really an object but not
|
||||
// one of the weird builtin objects.
|
||||
|
||||
if (
|
||||
typeof value === 'object'
|
||||
&& value !== null
|
||||
&& !(value instanceof Boolean)
|
||||
&& !(value instanceof Date)
|
||||
&& !(value instanceof Number)
|
||||
&& !(value instanceof RegExp)
|
||||
&& !(value instanceof String)
|
||||
) {
|
||||
|
||||
// If the value is an object or array, look to see if we have already
|
||||
// encountered it. If so, return a {"$ref":PATH} object. This uses an
|
||||
// ES6 WeakMap.
|
||||
|
||||
old_path = objects.get(value);
|
||||
if (old_path !== undefined) {
|
||||
return {$ref: old_path};
|
||||
}
|
||||
|
||||
// Otherwise, accumulate the unique value and its path.
|
||||
|
||||
objects.set(value, path);
|
||||
|
||||
// If it is an array, replicate the array.
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
nu = [];
|
||||
value.forEach(function (element, i) {
|
||||
nu[i] = derez(element, path + '[' + i + ']');
|
||||
});
|
||||
} else {
|
||||
|
||||
// If it is an object, replicate the object.
|
||||
|
||||
nu = {};
|
||||
Object.keys(value).forEach(function (name) {
|
||||
nu[name] = derez(
|
||||
value[name],
|
||||
path + '[' + JSON.stringify(name) + ']',
|
||||
);
|
||||
});
|
||||
}
|
||||
return nu;
|
||||
}
|
||||
return value;
|
||||
}(object, '$'));
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof JSON.retrocycle !== 'function') {
|
||||
/**
|
||||
* Restore an object that was reduced by decycle.
|
||||
* Members whose values are objects of the form {$ref: PATH} are replaced with references to the value found by the PATH.
|
||||
* This will restore cycles.
|
||||
* The object will be mutated.
|
||||
*
|
||||
* The eval function is used to locate the values described by a PATH.
|
||||
* The root object is kept in a $ variable.
|
||||
* A regular expression is used to assure that the PATH is extremely well formed.
|
||||
* The regexp contains nested quantifiers.
|
||||
* That has been known to have extremely bad performance problems on some browsers for very long strings.
|
||||
* A PATH is expected to be reasonably short.
|
||||
* A PATH is allowed to belong to a very restricted subset of Goessner's JSONPath.
|
||||
* @example
|
||||
* var s = '[{"$ref":"$"}]';
|
||||
* // produces an array containing a single element which is the array itself.
|
||||
* return JSON.retrocycle(JSON.parse(s));
|
||||
* @example
|
||||
* let o = {};
|
||||
* o.a = o;
|
||||
*
|
||||
* let p = (JSON.retrocycle(JSON.parse(JSON.stringify(JSON.decycle(o)))));
|
||||
* console.log(p.a.a.a === p.a); // true
|
||||
*/
|
||||
JSON.retrocycle = function retrocycle($) {
|
||||
'use strict';
|
||||
|
||||
var px = /^\$(?:\[(?:\d+|"(?:[^\\"\u0000-\u001f]|\\(?:[\\"\/bfnrt]|u[0-9a-zA-Z]{4}))*")])*$/;
|
||||
|
||||
(function rez(value) {
|
||||
|
||||
// The rez function walks recursively through the object looking for $ref
|
||||
// properties. When it finds one that has a value that is a path, then it
|
||||
// replaces the $ref object with a reference to the value that is found by
|
||||
// the path.
|
||||
|
||||
if (value && typeof value === 'object') {
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach(function (element, i) {
|
||||
if (typeof element === 'object' && element !== null) {
|
||||
var path = element['$ref'];
|
||||
if (typeof path === 'string' && px.test(path)) {
|
||||
value[i] = eval(path);
|
||||
} else {
|
||||
rez(element);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Object.keys(value).forEach(function (name) {
|
||||
var item = value[name];
|
||||
if (typeof item === 'object' && item !== null) {
|
||||
var path = item['$ref'];
|
||||
if (typeof path === 'string' && px.test(path)) {
|
||||
value[name] = eval(path);
|
||||
} else {
|
||||
rez(item);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}($));
|
||||
|
||||
return $;
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
||||
module.exports = {
|
||||
stringify: JSON.stringify,
|
||||
parse: JSON.parse,
|
||||
decycle: JSON.decycle,
|
||||
retrocycle: JSON.retrocycle,
|
||||
};
|
||||
@@ -25,5 +25,5 @@ return G(2,n)},o.pick=$n,o.slice=function(n,t,r){var e=null==n?0:n.length;return
|
||||
return t(n),n},o.thru=function(n,t){return t(n)},o.toArray=function(n){return M(n)?n.length?A(n):[]:W(n)},o.values=W,o.extend=Bn,Y(o,o),o.clone=function(n){return V(n)?Nn(n)?A(n):k(n,_n(n)):n},o.escape=function(n){return(n=Q(n))&&rn.test(n)?n.replace(tn,fn):n},o.every=function(n,t,r){return t=r?Z:t,f(n,g(t))},o.find=An,o.forEach=z,o.has=function(n,t){return null!=n&&pn.call(n,t)},o.head=q,o.identity=X,o.indexOf=P,o.isArguments=n,o.isArray=Nn,o.isBoolean=function(n){return true===n||false===n||H(n)&&"[object Boolean]"==hn.call(n);
|
||||
},o.isDate=function(n){return H(n)&&"[object Date]"==hn.call(n)},o.isEmpty=function(t){return M(t)&&(Nn(t)||L(t)||U(t.splice)||n(t))?!t.length:!_n(t).length},o.isEqual=function(n,t){return b(n,t)},o.isFinite=function(n){return typeof n=="number"&&gn(n)},o.isFunction=U,o.isNaN=function(n){return K(n)&&n!=+n},o.isNull=function(n){return null===n},o.isNumber=K,o.isObject=V,o.isRegExp=function(n){return H(n)&&"[object RegExp]"==hn.call(n)},o.isString=L,o.isUndefined=function(n){return n===Z},o.last=function(n){
|
||||
var t=null==n?0:n.length;return t?n[t-1]:Z},o.max=function(n){return n&&n.length?a(n,X,v):Z},o.min=function(n){return n&&n.length?a(n,X,_):Z},o.noConflict=function(){return on._===this&&(on._=vn),this},o.noop=function(){},o.reduce=C,o.result=function(n,t,r){return t=null==n?Z:n[t],t===Z&&(t=r),U(t)?t.call(n):t},o.size=function(n){return null==n?0:(n=M(n)?n:_n(n),n.length)},o.some=function(n,t,r){return t=r?Z:t,E(n,g(t))},o.uniqueId=function(n){var t=++sn;return Q(n)+t},o.each=z,o.first=q,Y(o,function(){
|
||||
var n={};return s(o,function(t,r){pn.call(o.prototype,r)||(n[r]=t)}),n}(),{chain:false}),o.VERSION="4.17.5",mn("pop join replace reverse split push shift sort splice unshift".split(" "),function(n){var t=(/^(?:replace|split)$/.test(n)?String.prototype:an)[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|join|replace|shift)$/.test(n);o.prototype[n]=function(){var n=arguments;if(e&&!this.__chain__){var u=this.value();return t.apply(Nn(u)?u:[],n)}return this[r](function(r){return t.apply(Nn(r)?r:[],n);
|
||||
var n={};return s(o,function(t,r){pn.call(o.prototype,r)||(n[r]=t)}),n}(),{chain:false}),o.VERSION="4.17.15",mn("pop join replace reverse split push shift sort splice unshift".split(" "),function(n){var t=(/^(?:replace|split)$/.test(n)?String.prototype:an)[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|join|replace|shift)$/.test(n);o.prototype[n]=function(){var n=arguments;if(e&&!this.__chain__){var u=this.value();return t.apply(Nn(u)?u:[],n)}return this[r](function(r){return t.apply(Nn(r)?r:[],n);
|
||||
})}}),o.prototype.toJSON=o.prototype.valueOf=o.prototype.value=function(){return w(this.__wrapped__,this.__actions__)},typeof define=="function"&&typeof define.amd=="object"&&define.amd?(on._=o, define(function(){return o})):cn?((cn.exports=o)._=o,un._=o):on._=o}).call(this);
|
||||
@@ -6,6 +6,7 @@ import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
@@ -233,6 +234,7 @@ public abstract class AutoJs {
|
||||
return mActivityInfoProvider;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public AccessibilityNotificationObserver getNotificationObserver() {
|
||||
return mNotificationObserver;
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.stardust.autojs;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/12/8.
|
||||
@@ -11,7 +11,7 @@ import android.preference.PreferenceManager;
|
||||
public class Config {
|
||||
|
||||
private static Config sInstance;
|
||||
private SharedPreferences mSharedPreferences;
|
||||
private final SharedPreferences mSharedPreferences;
|
||||
private final Context mContext;
|
||||
|
||||
public Config(Context context) {
|
||||
|
||||
@@ -133,8 +133,8 @@ public abstract class AccessibilityBridge {
|
||||
|
||||
public void setFlags(int flags) {
|
||||
mFlags = flags;
|
||||
if ((mFlags & FLAG_USE_USAGE_STATS) != 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
if (!AppOpsKt.isOpPermissionGranted(mContext, AppOpsManager.OPSTR_GET_USAGE_STATS)) {
|
||||
if ((mFlags & FLAG_USE_USAGE_STATS) != 0) {
|
||||
if (!AppOpsKt.isUsageStatsPermissionGranted(mContext)) {
|
||||
IntentUtil.requestAppUsagePermission(mContext);
|
||||
throw new SecurityException("没有\"查看使用情况\"权限");
|
||||
}
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
package com.stardust.autojs.core.activity
|
||||
|
||||
import android.accessibilityservice.AccessibilityService
|
||||
import android.app.AppOpsManager
|
||||
import android.app.usage.UsageStatsManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import android.os.SystemClock
|
||||
import android.util.Log
|
||||
import android.view.accessibility.AccessibilityEvent
|
||||
import android.view.accessibility.AccessibilityWindowInfo
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.stardust.app.isOpPermissionGranted
|
||||
import com.stardust.app.isUsageStatsPermissionGranted
|
||||
import com.stardust.autojs.core.util.Shell
|
||||
import com.stardust.view.accessibility.AccessibilityDelegate
|
||||
import java.util.regex.Pattern
|
||||
@@ -27,6 +25,7 @@ class ActivityInfoProvider(private val context: Context) : AccessibilityDelegate
|
||||
|
||||
@Volatile
|
||||
private var mLatestPackage: String = ""
|
||||
|
||||
@Volatile
|
||||
private var mLatestActivity: String = ""
|
||||
private var mLatestComponentFromShell: ComponentName? = null
|
||||
@@ -40,7 +39,7 @@ class ActivityInfoProvider(private val context: Context) : AccessibilityDelegate
|
||||
if (useShell && compFromShell != null) {
|
||||
return compFromShell.packageName
|
||||
}
|
||||
if (useUsageStats && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
|
||||
if (useUsageStats) {
|
||||
mLatestPackage = getLatestPackageByUsageStats()
|
||||
}
|
||||
return mLatestPackage
|
||||
@@ -78,19 +77,17 @@ class ActivityInfoProvider(private val context: Context) : AccessibilityDelegate
|
||||
|
||||
override fun onAccessibilityEvent(service: AccessibilityService, event: AccessibilityEvent): Boolean {
|
||||
if (event.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
val window = service.getWindow(event.windowId)
|
||||
if (window?.isFocused != false) {
|
||||
setLatestComponent(event.packageName, event.className)
|
||||
return false
|
||||
}
|
||||
val window = service.getWindow(event.windowId)
|
||||
if (window?.isFocused != false) {
|
||||
setLatestComponent(event.packageName, event.className)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun getLatestPackageByUsageStatsIfGranted(): String {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1 && context.isOpPermissionGranted(AppOpsManager.OPSTR_GET_USAGE_STATS)) {
|
||||
if (context.isUsageStatsPermissionGranted()) {
|
||||
return getLatestPackageByUsageStats()
|
||||
}
|
||||
return mLatestPackage
|
||||
@@ -103,7 +100,7 @@ class ActivityInfoProvider(private val context: Context) : AccessibilityDelegate
|
||||
return
|
||||
}
|
||||
val latestPackage = matcher.group(1)
|
||||
if (latestPackage.contains(":")) {
|
||||
if (latestPackage != null && latestPackage.contains(":")) {
|
||||
return
|
||||
}
|
||||
val latestActivity = if (matcher.groupCount() >= 2) {
|
||||
@@ -112,10 +109,12 @@ class ActivityInfoProvider(private val context: Context) : AccessibilityDelegate
|
||||
""
|
||||
}
|
||||
Log.d(LOG_TAG, "setLatestComponent: output = $output, comp = $latestPackage/$latestActivity")
|
||||
mLatestComponentFromShell = ComponentName(latestPackage, latestActivity)
|
||||
if (latestPackage != null) {
|
||||
mLatestComponentFromShell = ComponentName(latestPackage, latestActivity)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createShell(dumpInterval: Int): Shell {
|
||||
private fun createShell(@Suppress("SameParameterValue") dumpInterval: Int): Shell {
|
||||
val shell = Shell(true)
|
||||
shell.setCallback(object : Shell.Callback {
|
||||
override fun onOutput(str: String) {
|
||||
|
||||
@@ -57,8 +57,10 @@ class ScriptCanvasView(context: Context, private val mScriptRuntime: ScriptRunti
|
||||
canvas = lockCanvas()
|
||||
scriptCanvas.setCanvas(canvas)
|
||||
emit("draw", scriptCanvas, this@ScriptCanvasView)
|
||||
unlockCanvasAndPost(canvas)
|
||||
canvas = null
|
||||
if (canvas != null) {
|
||||
unlockCanvasAndPost(canvas)
|
||||
canvas = null
|
||||
}
|
||||
val dt = mTimePerDraw - (SystemClock.uptimeMillis() - time)
|
||||
if (dt > 0) {
|
||||
sleep(dt)
|
||||
|
||||
@@ -37,12 +37,10 @@ public class TemplateMatching {
|
||||
this.similarity = similarity;
|
||||
}
|
||||
|
||||
@SuppressWarnings("NullableProblems")
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Match{" +
|
||||
"point=" + point +
|
||||
", similarity=" + similarity +
|
||||
'}';
|
||||
return String.format("Match{point=%s, similarity=%s}", point, similarity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +66,6 @@ public class TemplateMatching {
|
||||
* @param weakThreshold 弱阈值。该值用于在每一轮模板匹配中检验是否继续匹配。如果相似度小于该值,则不再继续匹配。
|
||||
* @param strictThreshold 强阈值。该值用于检验最终匹配结果,以及在每一轮匹配中如果相似度大于该值则直接返回匹配结果。
|
||||
* @param maxLevel 图像金字塔的层数
|
||||
* @return
|
||||
*/
|
||||
public static List<Match> fastTemplateMatching(Mat img, Mat template, int matchMethod, float weakThreshold, float strictThreshold, int maxLevel, int limit) {
|
||||
TimingLogger logger = new TimingLogger(LOG_TAG, "fast_tm");
|
||||
@@ -90,6 +87,8 @@ public class TemplateMatching {
|
||||
if (previousMatchResult.isEmpty()) {
|
||||
// 如果不是第一次匹配,并且不满足shouldContinueMatching的条件,则直接退出匹配
|
||||
if (!isFirstMatching && !shouldContinueMatching(level, maxLevel)) {
|
||||
releaseIfNeeded(src, img);
|
||||
releaseIfNeeded(currentTemplate, template);
|
||||
break;
|
||||
}
|
||||
Mat matchResult = matchTemplate(src, currentTemplate, matchMethod);
|
||||
@@ -107,10 +106,8 @@ public class TemplateMatching {
|
||||
}
|
||||
}
|
||||
|
||||
if (src != img)
|
||||
OpenCVHelper.release(src);
|
||||
if (currentTemplate != template)
|
||||
OpenCVHelper.release(currentTemplate);
|
||||
releaseIfNeeded(src, img);
|
||||
releaseIfNeeded(currentTemplate, template);
|
||||
|
||||
logger.addSplit("level:" + level + ", result:" + previousMatchResult);
|
||||
|
||||
@@ -138,6 +135,11 @@ public class TemplateMatching {
|
||||
return finalMatchResult;
|
||||
}
|
||||
|
||||
private static void releaseIfNeeded(Mat src, Mat ref) {
|
||||
if (src != ref) {
|
||||
OpenCVHelper.release(src);
|
||||
}
|
||||
}
|
||||
|
||||
private static Mat getPyramidDownAtLevel(Mat m, int level) {
|
||||
if (level == 0) {
|
||||
@@ -190,7 +192,7 @@ public class TemplateMatching {
|
||||
private static int selectPyramidLevel(Mat img, Mat template) {
|
||||
int minDim = Nath.min(img.rows(), img.cols(), template.rows(), template.cols());
|
||||
//这里选取16为图像缩小后的最小宽高,从而用log(2, minDim / 16)得到最多可以经过几次缩小。
|
||||
int maxLevel = (int) (Math.log(minDim / 16) / Math.log(2));
|
||||
int maxLevel = (int) (Math.log(minDim >> 4) / Math.log(2));
|
||||
if (maxLevel < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -7,11 +7,6 @@ import androidx.annotation.Nullable;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.stardust.app.DialogUtils;
|
||||
|
||||
import org.opencv.android.InstallCallbackInterface;
|
||||
import org.opencv.android.LoaderCallbackInterface;
|
||||
import org.opencv.android.OpenCVLoader;
|
||||
|
||||
|
||||
@@ -25,7 +20,7 @@ public class OpenCVHelper {
|
||||
void onInitFinish();
|
||||
}
|
||||
|
||||
private static final String LOG_TAG = "OpenCVHelper";
|
||||
private static final String TAG = "OpenCVHelper";
|
||||
private static boolean sInitialized = false;
|
||||
|
||||
public static MatOfPoint newMatOfPoint(Mat mat) {
|
||||
@@ -49,19 +44,20 @@ public class OpenCVHelper {
|
||||
}
|
||||
|
||||
public synchronized static void initIfNeeded(Context context, InitializeCallback callback) {
|
||||
if (sInitialized) {
|
||||
callback.onInitFinish();
|
||||
return;
|
||||
}
|
||||
sInitialized = true;
|
||||
if (Looper.getMainLooper() == Looper.myLooper()) {
|
||||
new Thread(() -> {
|
||||
OpenCVLoader.initDebug();
|
||||
callback.onInitFinish();
|
||||
}).start();
|
||||
if (!sInitialized) {
|
||||
sInitialized = true;
|
||||
if (Looper.getMainLooper() == Looper.myLooper()) {
|
||||
new Thread(() -> init(callback)).start();
|
||||
} else {
|
||||
init(callback);
|
||||
}
|
||||
} else {
|
||||
OpenCVLoader.initDebug();
|
||||
callback.onInitFinish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void init(InitializeCallback callback) {
|
||||
OpenCVLoader.initDebug();
|
||||
callback.onInitFinish();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.stardust.autojs.core.pref
|
||||
|
||||
import android.preference.PreferenceManager
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.stardust.app.GlobalAppContext
|
||||
|
||||
object Pref {
|
||||
|
||||
@@ -284,11 +284,6 @@ public class JsDialog {
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setMessage(CharSequence message) {
|
||||
mDialog.setMessage(message);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ArrayList<CharSequence> getItems() {
|
||||
return mDialog.getItems();
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.stardust.autojs.core.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.stardust.autojs.engine;
|
||||
|
||||
import android.content.Context;
|
||||
import android.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.stardust.autojs.core.util.ProcessShell;
|
||||
|
||||
@@ -13,17 +13,16 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
/**
|
||||
* Created by Stardust on 2017/4/2.
|
||||
* <p>
|
||||
* <p>
|
||||
* A ScriptEngine is created by {@link ScriptEngineManager#createEngine(String, int)} ()}, and then can be
|
||||
* used to execute script with {@link ScriptEngine#execute(ScriptSource)} in the **same** thread.
|
||||
* used to execute script with {@link ScriptEngine#execute(ScriptSource)} in the <strong>same</strong> thread.
|
||||
* When the execution finish successfully, the engine should be destroy in the thread that created it.
|
||||
* <p>
|
||||
* <br>
|
||||
* If you want to stop the engine in other threads, you should call {@link ScriptEngine#forceStop()}.
|
||||
* </p>
|
||||
*/
|
||||
|
||||
public interface ScriptEngine<S extends ScriptSource> {
|
||||
|
||||
|
||||
String TAG_ENV_PATH = "env_path";
|
||||
String TAG_SOURCE = "source";
|
||||
String TAG_WORKING_DIRECTORY = "execute_path";
|
||||
|
||||
@@ -8,13 +8,15 @@ import java.util.*
|
||||
/**
|
||||
* Created by Stardust on 2017/2/1.
|
||||
*/
|
||||
data class ExecutionConfig(var workingDirectory: String = "",
|
||||
var path: Array<out String> = emptyArray(),
|
||||
var intentFlags: Int = 0,
|
||||
var delay: Long = 0,
|
||||
var interval: Long = 0,
|
||||
var loopTimes: Int = 1,
|
||||
var scriptConfig: ScriptConfig = ScriptConfig()) : Parcelable {
|
||||
data class ExecutionConfig(
|
||||
var workingDirectory: String = "",
|
||||
var path: Array<out String> = emptyArray(),
|
||||
var intentFlags: Int = 0,
|
||||
var delay: Long = 0,
|
||||
var interval: Long = 0,
|
||||
var loopTimes: Int = 1,
|
||||
var scriptConfig: ScriptConfig = ScriptConfig()
|
||||
) : Parcelable {
|
||||
|
||||
|
||||
private val mArguments = HashMap<String, Any>()
|
||||
@@ -23,12 +25,13 @@ data class ExecutionConfig(var workingDirectory: String = "",
|
||||
get() = mArguments
|
||||
|
||||
constructor(parcel: Parcel) : this(
|
||||
parcel.readString().orEmpty(),
|
||||
parcel.createStringArray().orEmpty(),
|
||||
parcel.readInt(),
|
||||
parcel.readLong(),
|
||||
parcel.readLong(),
|
||||
parcel.readInt())
|
||||
parcel.readString().orEmpty(),
|
||||
parcel.createStringArray().orEmpty(),
|
||||
parcel.readInt(),
|
||||
parcel.readLong(),
|
||||
parcel.readLong(),
|
||||
parcel.readInt()
|
||||
)
|
||||
|
||||
fun setArgument(key: String, `object`: Any) {
|
||||
mArguments[key] = `object`
|
||||
@@ -38,6 +41,10 @@ data class ExecutionConfig(var workingDirectory: String = "",
|
||||
return mArguments[key]
|
||||
}
|
||||
|
||||
fun getArguments(): Any {
|
||||
return mArguments
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
@@ -6,7 +6,7 @@ import com.android.dx.command.dexer.Main;
|
||||
import com.stardust.pio.PFiles;
|
||||
import com.stardust.util.MD5;
|
||||
|
||||
import net.lingala.zip4j.core.ZipFile;
|
||||
import net.lingala.zip4j.ZipFile;
|
||||
import net.lingala.zip4j.exception.ZipException;
|
||||
import net.lingala.zip4j.model.FileHeader;
|
||||
import net.lingala.zip4j.model.ZipParameters;
|
||||
@@ -17,7 +17,6 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -29,14 +28,13 @@ import dalvik.system.DexClassLoader;
|
||||
|
||||
public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoader {
|
||||
|
||||
|
||||
private static final String LOG_TAG = "AndroidClassLoader";
|
||||
private final ClassLoader parent;
|
||||
private final List<DexClassLoader> mDexClassLoaders = new ArrayList<>();
|
||||
private final File mCacheDir;
|
||||
|
||||
/**
|
||||
* Create a new instance with the given parent classloader and cache dierctory
|
||||
* Create a new instance with the given parent classloader and cache directory
|
||||
*
|
||||
* @param parent the parent
|
||||
* @param dir the cache directory
|
||||
@@ -47,7 +45,9 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
|
||||
if (dir.exists()) {
|
||||
PFiles.deleteFilesOfDir(dir);
|
||||
} else {
|
||||
dir.mkdirs();
|
||||
if (!dir.mkdirs()) {
|
||||
Log.e(LOG_TAG, "dir.mkdirs() failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,14 +63,15 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
|
||||
final ZipFile zipFile = new ZipFile(classFile);
|
||||
final ZipParameters parameters = new ZipParameters();
|
||||
parameters.setFileNameInZip(name.replace('.', '/') + ".class");
|
||||
parameters.setSourceExternalStream(true);
|
||||
zipFile.addStream(new ByteArrayInputStream(data), parameters);
|
||||
return dexJar(classFile, null).loadClass(name);
|
||||
} catch (IOException | ZipException | ClassNotFoundException e) {
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
throw new FatalLoadingException(e);
|
||||
} finally {
|
||||
if (classFile != null) {
|
||||
classFile.delete();
|
||||
if (!classFile.delete()) {
|
||||
Log.e(LOG_TAG, "classFile.delete() failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,10 +80,14 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
|
||||
File file = new File(mCacheDir, name.hashCode() + System.currentTimeMillis() + ".jar");
|
||||
if (create) {
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
if (!file.createNewFile()) {
|
||||
Log.e(LOG_TAG, "file.createNewFile() failed");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
file.delete();
|
||||
if (!file.delete()) {
|
||||
Log.e(LOG_TAG, "file.delete() failed");
|
||||
}
|
||||
}
|
||||
return file;
|
||||
}
|
||||
@@ -101,17 +106,17 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
|
||||
final File classFile = generateTempFile(jar.getPath(), false);
|
||||
final ZipFile zipFile = new ZipFile(classFile);
|
||||
final ZipFile jarFile = new ZipFile(jar);
|
||||
//noinspection unchecked
|
||||
for (FileHeader header : (List<FileHeader>) jarFile.getFileHeaders()) {
|
||||
for (FileHeader header : jarFile.getFileHeaders()) {
|
||||
if (!header.isDirectory()) {
|
||||
final ZipParameters parameters = new ZipParameters();
|
||||
parameters.setFileNameInZip(header.getFileName());
|
||||
parameters.setSourceExternalStream(true);
|
||||
zipFile.addStream(jarFile.getInputStream(header), parameters);
|
||||
}
|
||||
}
|
||||
dexJar(classFile, dexFile);
|
||||
classFile.delete();
|
||||
if (!classFile.delete()) {
|
||||
Log.e(LOG_TAG, "classFile.delete() failed");
|
||||
}
|
||||
} catch (ZipException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
@@ -144,7 +149,9 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
|
||||
Main.run(arguments);
|
||||
DexClassLoader loader = loadDex(dexFile);
|
||||
if (isTmpDex) {
|
||||
dexFile.delete();
|
||||
if (!dexFile.delete()) {
|
||||
Log.e(LOG_TAG, "dexFile.delete() failed");
|
||||
}
|
||||
}
|
||||
return loader;
|
||||
}
|
||||
|
||||
@@ -215,9 +215,7 @@ public class ScriptRuntime {
|
||||
this.automator = new SimpleActionAutomator(accessibilityBridge, this);
|
||||
automator.setScreenMetrics(mScreenMetrics);
|
||||
this.info = accessibilityBridge.getInfoProvider();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
images = new Images(context, this, builder.mScreenCaptureRequester);
|
||||
}
|
||||
images = new Images(context, this, builder.mScreenCaptureRequester);
|
||||
engines = new Engines(builder.mEngineService, this);
|
||||
dialogs = new Dialogs(this);
|
||||
device = new Device(context);
|
||||
|
||||
@@ -4,7 +4,6 @@ import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.widget.CompoundButton;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.afollestad.materialdialogs.Theme;
|
||||
@@ -13,10 +12,8 @@ import com.stardust.autojs.annotation.ScriptInterface;
|
||||
import com.stardust.autojs.annotation.ScriptVariable;
|
||||
import com.stardust.autojs.core.ui.dialog.BlockedMaterialDialog;
|
||||
import com.stardust.autojs.core.ui.dialog.JsDialogBuilder;
|
||||
import com.stardust.autojs.runtime.ScriptBridges;
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
import com.stardust.util.ArrayUtils;
|
||||
import com.stardust.util.UiHandler;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/8.
|
||||
|
||||
@@ -15,6 +15,7 @@ import android.os.Looper;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
|
||||
import com.stardust.autojs.annotation.ScriptVariable;
|
||||
@@ -44,8 +45,6 @@ import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -54,6 +53,8 @@ import java.util.List;
|
||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||
public class Images {
|
||||
|
||||
private static final String TAG = Images.class.getSimpleName();
|
||||
|
||||
private ScriptRuntime mScriptRuntime;
|
||||
private ScreenCaptureRequester mScreenCaptureRequester;
|
||||
private ScreenCapturer mScreenCapturer;
|
||||
@@ -348,21 +349,22 @@ public class Images {
|
||||
}
|
||||
Activity currentActivity = mScriptRuntime.app.getCurrentActivity();
|
||||
Context context = currentActivity == null ? mContext : currentActivity;
|
||||
mScriptRuntime.console.info("opencv initializing");
|
||||
Log.i(TAG, "opencv: initializing");
|
||||
if (Looper.myLooper() == Looper.getMainLooper()) {
|
||||
OpenCVHelper.initIfNeeded(context, () -> {
|
||||
mOpenCvInitialized = true;
|
||||
mScriptRuntime.console.info("opencv initialized");
|
||||
});
|
||||
OpenCVHelper.initIfNeeded(context, this::initSuccessfully);
|
||||
} else {
|
||||
VolatileDispose<Boolean> result = new VolatileDispose<>();
|
||||
OpenCVHelper.initIfNeeded(context, () -> {
|
||||
mOpenCvInitialized = true;
|
||||
initSuccessfully();
|
||||
result.setAndNotify(true);
|
||||
mScriptRuntime.console.info("opencv initialized");
|
||||
});
|
||||
result.blockedGet();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void initSuccessfully() {
|
||||
mOpenCvInitialized = true;
|
||||
Log.i(TAG, "opencv: initialized");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,14 +5,14 @@ import android.util.Log;
|
||||
|
||||
import com.stardust.autojs.engine.RhinoJavaScriptEngine;
|
||||
|
||||
import org.mozilla.javascript.jdk15.VMBridge_jdk15;
|
||||
import org.mozilla.javascript.jdk18.VMBridge_jdk18;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class VMBridge_custom extends VMBridge_jdk15 {
|
||||
public class VMBridge_custom extends VMBridge_jdk18 {
|
||||
|
||||
private static final String LOG_TAG = "VMBridge_custom";
|
||||
|
||||
@@ -73,9 +73,9 @@ public class VMBridge_custom extends VMBridge_jdk15 {
|
||||
} catch (InvocationTargetException var10) {
|
||||
throw Context.throwAsScriptRuntimeEx(var10);
|
||||
} catch (IllegalAccessException var11) {
|
||||
throw Kit.initCause(new IllegalStateException(), var11);
|
||||
throw new IllegalStateException(var11);
|
||||
} catch (InstantiationException var12) {
|
||||
throw Kit.initCause(new IllegalStateException(), var12);
|
||||
throw new IllegalStateException(var12);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user