├── .gitignore
├── DrawGGDoc.md
├── README.md
├── app
├── .gitignore
├── build.gradle
├── libs
│ └── gg96.jar
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ ├── Thousand_Dust
│ │ ├── DevInfo.java
│ │ ├── DrawView.java
│ │ ├── MyAccessibilityService.java
│ │ ├── MyWindowManager.java
│ │ ├── ScriptLib.java
│ │ ├── Tools.java
│ │ ├── canvas
│ │ │ ├── BitmapLib.java
│ │ │ ├── CanvasLib.java
│ │ │ ├── PaintLib.java
│ │ │ └── ViewLib.java
│ │ ├── luaj
│ │ │ ├── LuaBitmap.java
│ │ │ ├── LuaCanvas.java
│ │ │ ├── LuaPaint.java
│ │ │ └── LuaView.java
│ │ └── socket
│ │ │ ├── LuaServerSocket.java
│ │ │ └── LuaSocket.java
│ └── com
│ │ └── gg
│ │ └── function
│ │ └── MainActivity.java
│ └── res
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable
│ └── ic_launcher_background.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-mdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── values-night
│ └── themes.xml
│ ├── values
│ ├── colors.xml
│ ├── strings.xml
│ └── themes.xml
│ └── xml
│ ├── accessibility_config.xml
│ ├── backup_rules.xml
│ └── data_extraction_rules.xml
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | local.properties
16 |
--------------------------------------------------------------------------------
/DrawGGDoc.md:
--------------------------------------------------------------------------------
1 | ## DrawGG函数教程
2 | 这里是DrawGG函数教程
3 |
4 | 简介:基于gg luaj包编写的扩展函数,包含绘制函数等。也可以用在官方luaj包上,只需要改一下Tools类的getContext方法即可。
5 |
6 |
7 | **提示:由于以下函数比较占内存,编写代码时建议赋值为局部变量。可以有效加快脚本运行速度**
8 |
9 | **[函数演示效果代码和视频](#_382)**
10 | **[源码和成品](#_454)**
11 |
12 | @[TOC](函数教程)
13 |
14 | 下面开始函数教程:
15 |
16 | **v1.1新增函数**
17 | 由于android12以上系统限制,使用穿透触摸事件的悬浮窗需要无障碍权限,但无障碍由于无障碍的不便捷性,新增了对非无障碍的支持
18 | 在脚本开头调用如下函数,即可在android12及以上系统免于开启无障碍
19 |
20 | ```lua
21 | --强制禁用android12以上的无障碍申请
22 | disDrawAcc()
23 | ```
24 | 原理:将悬浮窗的透明度强制锁定为0.8f,代价是所有绘制的内容透明度都会降低
25 |
26 | **-----下面是画笔函数-----**
27 | # 画笔函数
28 | **1、新建画笔:newPaint**
29 | 函数作用:新建并返回一个画笔
30 |
31 | ```lua
32 | -- 新建画笔
33 | paint = newPaint()
34 | ```
35 | ## 设置抗锯齿
36 | **1.1、setAntialias**
37 | 函数作用:开启和关闭画笔的抗锯齿功能。参数:true或false
38 | true为开启抗锯齿,false为关闭抗锯齿。开启抗锯齿后会增加计算量。画笔默认关闭抗锯齿。
39 | 开启抗锯齿后绘制内容不会出现锯齿,更加圆润。
40 | 下图仔细看就能看出开了抗锯齿和没开的区别:
41 | 
42 |
43 | 示例:
44 |
45 | ```lua
46 | -- 初始化画笔
47 | paint = newPaint()
48 | paint:setAntialias(true) -- 开启抗锯齿
49 | ```
50 | ## 设置颜色
51 | **1.2、setColor**
52 | 函数作用:设置画笔画出的内容颜色。参数:ARGB十六进制字符串
53 | 比如:#FF998877,FF表示的是透明度,FF不透明,00未完全透明。99为红色深浅度,88为绿色深浅度,77为蓝色深浅度。透明值不写默认为FF。
54 | 详情请百度。
55 |
56 | 示例:
57 |
58 | ```lua
59 | -- 初始化画笔
60 | paint = newPaint()
61 | paint:setColor("#FFFFFF") -- 设置画笔白色
62 | ```
63 | ## 设置样式
64 | **1.3、设置画笔样式:setStyle**
65 | 函数作用:设置画笔画出的内容样式。参数:画笔样式
66 | 样式值分别有:**0**:描边,**1**:填充,**2**:描边并填充;
67 | "**描边**":描边, "**填充**":填充,"**描边并填充**":描边并填充
68 | 示例:
69 |
70 | ```lua
71 | -- 初始化画笔
72 | paint = newPaint()
73 | paint:setStyle(0) -- 设置画笔样式为描边
74 | --或者
75 | paint:setStyle("描边")
76 | ```
77 | ## 设置画笔画出的字符串大小
78 | **1.4、setTextSize**
79 | 函数作用:设置画笔画出来的文本大小。参数:大小值
80 | 示例:
81 |
82 | ```lua
83 | -- 初始化画笔
84 | paint = newPaint()
85 | paint:setTextSize(5) -- 设置画笔绘制的文本大小为5
86 | ```
87 | ## 设置画笔笔触宽度
88 | **1.5、setWidth**
89 | 函数作用:设置画笔笔触宽度。参数:宽度大小值,参数类型:数字。返回值:无
90 | 画笔笔触默认值为:1(应该是,我也不太清楚)
91 | 示例:
92 |
93 | ```lua
94 | -- 初始化画笔
95 | paint = newPaint()
96 | paint:setWidth(10) -- 设置笔触宽度为10
97 | ```
98 | **----------------------好了,以上就是画笔的所有函数了------------------------**
99 | **下面是图片的函数**
100 | # 图片函数
101 | **2.1、从文件加载图片:loadFile**
102 | 函数作用:新建一个图片对象并返回。参数:(图片文件路径)或(图片字符串),参数类型:文件路径 或 文件字符串
103 | 示例:
104 |
105 | ```lua
106 | -- 新建图片方式一
107 | bitmap = loadFile("图片文件路径")
108 | ```
109 | ## 从LuaString加载图片
110 | **2.2、load**
111 | 函数作用:从lua的字符串中加载图片
112 | 和从文件加载图片函数类似,我就不多说了。
113 | 示例:
114 |
115 | ```lua
116 | -- 新建图片方式二,从LuaString读取图片
117 | file = io.open("图片文件路径", "r")
118 | content = file:read("*a")
119 | file:close()
120 | bitmap = load(content)
121 | ```
122 | ## 设置图片的宽
123 | **2.3、setWidth**
124 | 函数作用:按比例将图片缩放到设置的宽。参数:要设置的宽。
125 | 示例:
126 |
127 | ```lua
128 | bitmap = loadFile("图片文件路径")
129 | bitmap:setWidth(500) --将图片的宽设置为500像素
130 | ```
131 | ## 设置图片的高
132 | **2.4、setHeight**
133 | 函数作用:按比例将图片缩放到设置的高。参数:要设置的高。
134 | 示例:
135 |
136 | ```lua
137 | bitmap = loadFile("图片文件路径")
138 | bitmap:setHeight(500) --将图片的高设置为500像素
139 | ```
140 |
141 | ## 获取图片的宽高
142 | **2.6、getWH**
143 | 函数作用:获取图片的宽和高
144 | 示例:
145 |
146 | ```lua
147 | bitmap = loadFile("图片文件路径")
148 | -- 获取图片宽搞
149 | wh = bitmap:getWH()
150 | print("宽为:"..wh[1].."高为:"..wh[2])
151 | ```
152 | ## 删除图片
153 | **2.8、remove**
154 | 函数作用:删除图片,释放内存。当某个图片对象不再需要使用时调用此方法删除图片
155 | 调用次函数后的Bitma对象将无法再继续使用。
156 | 示例:
157 |
158 | ```lua
159 | bitmap = loadFile("图片文件路径")
160 | --删除图片,并释放内存
161 | bitmap:remove()
162 | ```
163 |
164 | **———————————以上就是图片函数的所有内容了—————————————**
165 | **下面是画布函数,也是最主要的函数**
166 | # 画布函数
167 | 提示:画布不需要手动创建,写一个带有一个参数的方法。用view:show调用此方法就会传入画布(后面有教程)。每次传入的画布都是不同的,所以不需要把画布保存
168 | 示例:
169 |
170 | ```lua
171 | --带有一个参数的方法,用来接收画布并进行绘制操作
172 | function onDraw(canvas) --方法名随便写,没有要求
173 | --创建画笔
174 | paint = newPaint()
175 | --使用传入的画布参数进行绘制一个圆的操作
176 | canvas:drawCircle(200,200,100,paint) --在坐标(x200,y200)的地方为圆心画一个半径为100像素的圆
177 | end
178 | --View函数,后面有教程
179 | view = newView()
180 | view:show(onDraw) -- 显示绘制并自动刷新
181 | sleep(1000) --休眠1000ms,避免脚本运行结束后绘制内容被系统回收
182 | view:close()
183 | ```
184 | 效果图
185 | ## 绘制线段
186 | **3.1、drawLine**
187 | 函数作用:在屏幕上绘制一条线段。参数(线段开头x坐标,y坐标,线段结尾x坐标,y坐标)。
188 | ```lua
189 | paint = newPaint()
190 | canvas:drawLine(0,0,300,200,paint)
191 | ```
192 | 下面的绘制函数也是这样使用自定义画笔进行绘制内容
193 | ## 绘制多条线段
194 | **3.2、drawLines**
195 | 函数作用:绘制多条线段。参数:{线段开头x坐标,y坐标,结尾x坐标,y坐标,......}
196 | 参数个数无限制
197 | ```lua
198 | -- 初始化画布
199 | paint = newPaint()
200 | canvas:drawLines({50, 600, 400, 600, 400, 600, 400, 50,400, 50, 50, 50, 50, 50, 50, 600}, paint)
201 | ```
202 | 执行后就会出现如下效果。
203 |
204 | 
205 | 以此类推,参数个数无限制!
206 | 如果实在不会的话,那就跳过吧!你们应该用不上
207 | ## 绘制矩形
208 | **3.3、drawRect**
209 | 函数作用:绘制一个矩形。参数:({矩形左上角x坐标,y坐标,矩形右下角x坐标,y坐标},画笔)。
210 | 示例:
211 |
212 | ```lua
213 | -- 初始化canvas
214 | paint = newPaint()
215 | canvas:drawRect({100,100,400,200}, paint)
216 | ```
217 |
218 | ## 绘制圆
219 | **3.4、drawCircle**
220 | 函数作用:绘制一个圆。参数:(圆心x坐标,y坐标,圆的半径,画笔)。
221 |
222 | ```lua
223 | -- 初始化画布
224 | paint = newPaint()
225 | canvas:drawCorcle(400,400,200, paint)
226 | ```
227 | ## 绘制背景颜色
228 | **3.5、drawColor**
229 | 函数作用:绘制一个颜色作为背景。参数:颜色值。参数类型:字符串。
230 | 此方法不接收画笔对象!
231 | 示例:
232 |
233 | ```lua
234 | -- 绘制一个半透明的白色作为背景
235 | paint = newPaint()
236 | canvas.drawColor("#80FFFFFF")
237 | ```
238 | ## 绘制文本
239 | **3.5、drawText**
240 | 函数作用:绘制一个文本。参数:(要绘制的字符串,要绘制的左上角x坐标,y坐标,画笔)。
241 | 示例:
242 |
243 | ```lua
244 | -- 初始化画布
245 | paint = newPaint()
246 | canvas.drawText("绘制测试", 200,200, paint)
247 | ```
248 | ## 绘制Bitmap图片
249 | **3.6、draweBitmap**
250 | 函数作用:绘制一个Bitmap图片。参数:(bitmap对象,x坐标,y坐标,画笔)。
251 | 示例:
252 |
253 | ```lua-- 初始化bitmap图片
254 | paint = newPaint()
255 | bitmap = loadFile("图片文件路径")
256 | canvas.drawBitmap(bitmap, 200,200, paint)
257 | ```
258 |
259 | ## 绘制圆弧
260 | **3.8、drawArc**
261 | 函数作用:绘制一个圆弧。参数:({**圆弧的绘制范围左上角x坐标,y坐标,右下角x坐标,y坐标**},圆弧开始角度,经过角度,是否经过圆心,画笔)。。
262 | 这个相对比较复杂,看不懂可以跳过!
263 | 示例:
264 |
265 | ```lua
266 | -- 初始化画布
267 | paint = newPaint()
268 | canvas:drawArc({100,100,400,400},0,90,false, paint)
269 | ```
270 | ## 裁剪绘制内容
271 | **3.9、clipRect**
272 | 函数作用:将绘制范围裁剪为一个四边形。只有在四边形内的绘制内容才能显示。参数和drawRect一样:({{四边形左上角x坐标,y坐标,右下角x坐标,y坐标},画笔)
273 | 示例:
274 |
275 | ```lua
276 | paint = newPaint()
277 | canvas:clipRect({100,100,200,200}, paint)
278 | ```
279 | ## 移动画布
280 | **3.10、translate**
281 | 函数作用:移动画布原点。参数:原点x坐标,y坐标
282 | 画布原点默认为x:0, y:0
283 | 示例:
284 |
285 | ```lua
286 | canvas:translate(100,100)
287 | ```
288 | ## 旋转画布
289 | **3.11、rotate**
290 | 函数作用:将画布顺时针旋转。参数(旋转角度)或者(旋转角度,旋转中心x坐标,y坐标)
291 | 示例:
292 |
293 | ```lua
294 | canvas:rotate(90) --以画布原点为中心顺时针旋转90度
295 | canvas:rotate(90, 300, 300) --以坐标(x:300,y:300)为中心顺时针旋转90度
296 | ```
297 | ## 保存画布状态
298 | **3.12、save**
299 | 函数作用:保存画布的当前状态。用于对画布状态进行自定义前保存状态,配合恢复状态函数使用。
300 | ## 恢复画布状态
301 | **3.13、restore**
302 | 函数作用:将上一次保存的画布状态恢复。用于配合保存画布状态函数使用。
303 | 示例:
304 | ```lua
305 | canvas:save() --保存画布状态
306 | canvas:translte(200,200) --移动画布原点到x:200,y:200
307 | canvas:drawRect({0,0,100,100}, newPaint()) --绘制一个四边形
308 | canvas:restore() --恢复状态
309 | ```
310 | # 视图函数
311 | 视图函数是绘制内容的载体,用于加载显示和刷新绘制内容
312 |
313 | ## 新建视图
314 | **1.1、newView()**
315 | 函数作用:新建一个视图对象并返回
316 | 示例:
317 |
318 | ```lua
319 | view = newView()
320 | ```
321 | ## 显示绘制
322 | **1.2、show**
323 | 函数作用:加载Lua绘制方法。并进行初始显示。参数:Lua的绘制方法, 帧数(可选)
324 | 一个视图对象只能使用一个Lua函数。下一次show将会把上一次的覆盖
325 |
326 | **注意:绘制方法内不应进行耗时操作,因为绘制方法是在主线程被调用,执行的耗时直接决定了帧率的上限!**
327 | 示例:
328 | ```lua
329 | paint = newPaint()
330 | function onDraw(canvas) --方法名随意,没有要求。必须要有一个参数用来接收画布
331 | --特别注意:绘制方法内不应该进行耗时操作和创建视图、画笔、图片等。会造成性能问题,应当在绘制方法外部先声明所需的变量
332 | canvas:drawCircle(200,200,100, paint) --画圆
333 | end
334 | view = newView() --新建视图对象
335 | view:show(onDraw) --调用onDraw方法进行绘制,并进行初始显示
336 | --或者如下,增加有一个帧率参数,就会自动以60帧刷新绘制
337 | view:show(onDraw, 60)
338 | ```
339 | 以上代码,在调用了view:show(onDraw)后,系统将会自动的多次调用onDraw方法,调用频率取决于帧率,所以绘制的内容也就是canvas函数需要写在onDraw(绘制方法)方法中。注意:onDraw(绘制方法) 中不要调用newPaint函数,加载图片,休眠等耗时操作。会影响刷新率
340 | ## 手动刷新绘制
341 | **1.3、invalidate**
342 | 函数作用:调用已经show的方法进行刷新绘制。
343 | 注:调用show函数后会自动刷新绘图,特殊情况下才需要使用invalidate刷新绘图
344 | 示例:
345 |
346 | ```lua
347 | view = newView()
348 | i = 0
349 | paint = newPaint()
350 | view:show(function(canvas)
351 | canvas:drawCircle(i,i,50,paint())
352 | end) --将匿名方法作为绘制函数
353 |
354 | for i = 1,200 do
355 | i = i+2
356 | invalidate()
357 | sleep(20)
358 | end
359 | ```
360 | ## 删除视图中的绘制内容
361 | **1.4、close**
362 | 函数作用:删除视图中的所有绘制内容。
363 | 示例:
364 |
365 | ```lua
366 | view = newView()
367 | view:show(function(canvas)
368 | --绘制操作
369 | end)
370 | view:close()
371 | ```
372 | ## 删除所有绘制视图
373 | **1.5、removeAll**
374 |
375 | ```lua
376 | view = newView()
377 | view:show(function(canvas)
378 | --绘制操作
379 | end)
380 | removeAllView()
381 | ```
382 |
383 | # 代码演示和视频
384 | ```lua
385 | --强制禁用android12以上的无障碍申请
386 | disDrawAcc()
387 |
388 | --创建画笔
389 | paint = newPaint()
390 | --画笔红色
391 | paint:setColor("#FF0000")
392 | --画笔笔触宽度10像素
393 | paint:setWidth(10)
394 | --创建绘制载体视图
395 | view = newView()
396 |
397 | --绘制方法
398 | y = 0
399 | function onDraw(canvas)
400 | --移动画布原点
401 | canvas:translate(200, y)
402 | --画圆
403 | canvas:drawCircle(0, 100, 100, paint)
404 | --画矩形
405 | canvas:drawRect({200, 0, 400, 200}, paint)
406 | y = y + 5
407 | end
408 |
409 | --以60帧刷新率显示绘制
410 | view:show(onDraw, 60)
411 | gg.sleep(3000)
412 | ```
413 |
414 |
415 | [video(video-oxoe0UmK-1679757389544)(type-csdn)(url-https://live.csdn.net/v/embed/245908)(image-https://video-community.csdnimg.cn/vod-84deb4/f6ac6e502c05434b9270fd72f8a3abb4/snapshots/bab47786f4a543658f2fe0d74e77ff8a-00001.jpg?auth_key=4819537868-0-0-b429d81f07b93211f3519377af86f5cb)(title-代码演示效果)]
416 |
417 |
418 |
419 | # 其他函数
420 | ## 多线程函数
421 | **1.1、thread**
422 | 函数作用:启动新线程调用Lua方法
423 | 多线程函数有个bug暂时无法修复。不能多个线程同时调用sleep函数。否则会报错。
424 | 示例:
425 |
426 | ```lua
427 | function run()
428 | --要在新线程里执行的内容
429 | for i = 1,1000 do
430 | print(i)
431 | end
432 | end
433 | thread(run)
434 | ----------------------------------------
435 | --或者使用匿名方法
436 | thread(function()
437 | --要在新线程中执行的内容
438 | for i = 1, 1000 do
439 | print(i)
440 | end
441 | end)
442 | ```
443 |
444 | ## 获取屏幕分辨率
445 | **1.4、getWH**
446 | 函数作用:获取屏幕可显示范围的长和宽
447 | 示例:
448 |
449 | ```lua
450 | wh = getWH()
451 | print("屏幕的宽:"..wh[1])
452 | print("屏幕的高为:"..wh[2])
453 | ```
454 |
455 | ## 源码和成品
456 | 以上就是全部内容了,项目源码地址如下:
457 | gg96版:https://github.com/gnahz77/GG-CustomizeFunction
458 | gg101版:https://github.com/gnahz77/GG-CustomizeFunction-101
459 | 成品下载地址也在里面
460 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GG-CustomizeFunction
2 | 对GameGuardian进行自定义的函数,目前只添加绘制函数(在悬浮窗对View进行自定义绘制)和多线程函数。如需运行在非gg luaj上,只需要修改Thousand_Dust/Tools.getContext()方法即可。
3 | ## 制作不易给个☆star吧,谢谢啦!!!
4 |
5 | # gg版本
6 | 此项目基于96版gg的jar进行编写,需要101版移步:
7 | https://github.com/Thousand-Dust/GG-CustomizeFunction-101
8 | 代码不同但函数库效果是一样的
9 |
10 | ## [函数文档](DrawGGDoc.md)
11 |
12 | # 给其他gg添加此函数库教程
13 | 视频录制者文艺:https://b23.tv/LcXSQap
14 |
15 | # 成品安装包
16 | https://wwt.lanzoul.com/b02vn048j
17 | 密码:draw
18 | ## [releases](https://github.com/Thousand-Dust/GG-CustomizeFunction/releases)
19 |
20 |
21 | # 测试脚本
22 |
23 | ```lua
24 | --强制禁用android12以上的无障碍申请
25 | disDrawAcc()
26 |
27 | --创建画笔
28 | paint = newPaint()
29 | --画笔红色
30 | paint:setColor("#FF0000")
31 | --画笔笔触宽度10像素
32 | paint:setWidth(10)
33 | --创建绘制载体视图
34 | view = newView()
35 |
36 | --绘制方法
37 | y = 0
38 | function onDraw(canvas)
39 | --移动画布原点
40 | canvas:translate(200, y)
41 | --画圆
42 | canvas:drawCircle(0, 100, 100, paint)
43 | --画矩形
44 | canvas:drawRect({200, 0, 400, 200}, paint)
45 | y = y + 5
46 | end
47 |
48 | --以60帧刷新率显示绘制
49 | view:show(onDraw, 60)
50 | gg.sleep(3000)
51 |
52 | ```
53 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | }
4 |
5 | android {
6 | compileSdk 31
7 |
8 | defaultConfig {
9 | applicationId "com.gg.function"
10 | minSdk 22
11 | targetSdk 31
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 | compileOptions {
25 | sourceCompatibility JavaVersion.VERSION_1_8
26 | targetCompatibility JavaVersion.VERSION_1_8
27 | }
28 | }
29 |
30 | dependencies {
31 |
32 | implementation 'androidx.appcompat:appcompat:1.3.0'
33 | implementation 'com.google.android.material:material:1.4.0'
34 | implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
35 | implementation files('libs\\gg96.jar')
36 | testImplementation 'junit:junit:4.13.2'
37 | androidTestImplementation 'androidx.test.ext:junit:1.1.3'
38 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
39 | }
--------------------------------------------------------------------------------
/app/libs/gg96.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnahz77/GG-CustomizeFunction/0419d92aab270e562459c85fa90002cce5620d22/app/libs/gg96.jar
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
18 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
31 |
32 |
33 |
34 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/java/Thousand_Dust/DevInfo.java:
--------------------------------------------------------------------------------
1 | package Thousand_Dust;
2 |
3 | public class DevInfo
4 | {
5 | public static String getVersion() {
6 | return "1.0";
7 | }
8 |
9 | public static String getAuthor(){
10 | return "多线程、绘制函数开发者信息:\n" +
11 | "源码链接: https://github.com/Thousand-Dust/GG-CustomizeFunction 给个Star谢谢\n" +
12 | "开发者: 执念;" +
13 | "特别鸣谢: 小五";
14 | }
15 |
16 | public static String getUpdateTime()
17 | {
18 | return "2022/10/16";
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/Thousand_Dust/DrawView.java:
--------------------------------------------------------------------------------
1 | package Thousand_Dust;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.Canvas;
6 |
7 | import luaj.Globals;
8 | import Thousand_Dust.luaj.LuaCanvas;
9 | import luaj.LuaFunction;
10 |
11 | import android.graphics.Paint;
12 | import android.util.Log;
13 | import android.view.View;
14 |
15 | import androidx.annotation.NonNull;
16 |
17 | /**
18 | * @author Thousand-Dust
19 | */
20 | public class DrawView extends View {
21 |
22 | private Globals globals;
23 | private final Refresh refresh = new Refresh();
24 |
25 | private Paint paint;
26 | //缓冲图
27 | private Bitmap bufBitmap;
28 | //缓冲画布
29 | public Canvas canvas;
30 | public LuaCanvas luaCanvas;
31 | private LuaFunction drawFun;
32 | private boolean isRemove = false;
33 |
34 | public DrawView(Context context, Globals globals) {
35 | super(context);
36 | this.globals = globals;
37 | paint = new Paint();
38 | int[] wh = Tools.getWH(context);
39 | //防canvas的绘制内容画到缓冲图上
40 | bufBitmap = Bitmap.createBitmap(wh[0], wh[1], Bitmap.Config.ARGB_8888);
41 | canvas = new Canvas(bufBitmap);
42 | luaCanvas = LuaCanvas.valueOf(canvas);
43 | }
44 |
45 | public void setDrawFun(LuaFunction drawFun) {
46 | this.drawFun = drawFun;
47 | }
48 |
49 | @Override
50 | protected void onDraw(Canvas canvas) {
51 | canvas.drawBitmap(bufBitmap, 0, 0, paint);
52 | }
53 |
54 | @Override
55 | public void invalidate() {
56 | //将bitmap清空
57 | bufBitmap.eraseColor(0);
58 | if (drawFun != null) {
59 | canvas.save();
60 | drawFun.call(luaCanvas);
61 | canvas.restore();
62 | }
63 | super.invalidate();
64 | }
65 |
66 | @Override
67 | public void postInvalidate() {
68 | super.postInvalidate();
69 | }
70 |
71 | @Override
72 | protected void onDetachedFromWindow() {
73 | super.onDetachedFromWindow();
74 | close();
75 | }
76 |
77 | public void start(int fps) {
78 | refresh.fps = fps;
79 | if (!refresh.isStart) {
80 | new Thread(refresh).start();
81 | }
82 | }
83 |
84 | public void close() {
85 | refresh.isStart = false;
86 | }
87 |
88 | class Refresh implements Runnable {
89 | private boolean isStart = false;
90 | private int fps = 60;
91 |
92 | @Override
93 | public void run() {
94 | isStart = true;
95 | //每帧间隔时间
96 | long interval = 1000 / fps;
97 | try {
98 | while (isStart) {
99 | //按设置帧率刷新画面
100 | long startTime = System.currentTimeMillis();
101 | DrawView.this.postInvalidate();
102 | long timeConsuming = System.currentTimeMillis() - startTime;
103 | if (timeConsuming < interval) {
104 | Thread.sleep(interval - timeConsuming);
105 | }
106 | }
107 | } catch (Exception e) {
108 | e.printStackTrace(globals.STDOUT);
109 | android.ext.Tools.showToast("error: " + e.getMessage());
110 | } finally {
111 | if (isStart) {
112 | isStart = false;
113 | }
114 | }
115 | }
116 | }
117 |
118 | }
119 |
--------------------------------------------------------------------------------
/app/src/main/java/Thousand_Dust/MyAccessibilityService.java:
--------------------------------------------------------------------------------
1 | package Thousand_Dust;
2 |
3 | import android.accessibilityservice.AccessibilityService;
4 | import android.content.Intent;
5 | import android.os.Build;
6 | import android.util.Log;
7 | import android.view.accessibility.AccessibilityEvent;
8 |
9 | /**
10 | * @author Thousand-Dust
11 | */
12 | public class MyAccessibilityService extends AccessibilityService {
13 |
14 | @Override
15 | protected void onServiceConnected() {
16 | super.onServiceConnected();
17 | MyWindowManager.newInstance(this);
18 | }
19 |
20 | @Override
21 | public boolean onUnbind(Intent intent) {
22 | if (!MyWindowManager.isInstanceEmpty()) {
23 | MyWindowManager.destInstance();
24 | }
25 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
26 | MyWindowManager.newInstance(Tools.getContext());
27 | }
28 | return super.onUnbind(intent);
29 | }
30 |
31 | @Override
32 | public void onAccessibilityEvent(AccessibilityEvent event) {
33 |
34 | }
35 |
36 | @Override
37 | public void onInterrupt() {
38 | }
39 | }
--------------------------------------------------------------------------------
/app/src/main/java/Thousand_Dust/MyWindowManager.java:
--------------------------------------------------------------------------------
1 | package Thousand_Dust;
2 |
3 | import android.content.Context;
4 | import android.graphics.PixelFormat;
5 | import android.os.Build;
6 | import android.os.Handler;
7 | import android.os.Looper;
8 | import android.view.Gravity;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.view.WindowManager;
12 | import android.widget.LinearLayout;
13 |
14 | import luaj.LuaError;
15 |
16 | /**
17 | * @author Thousand-Dust
18 | */
19 | public class MyWindowManager {
20 |
21 | private static MyWindowManager mWm;
22 | private static float alpha = 1f;
23 |
24 | public static final float MAXIMUM_OBSCURING_OPACITY = 0.8f;
25 |
26 | public static void newInstance(Context context) {
27 | if (mWm == null) {
28 | mWm = new MyWindowManager(context);
29 | }
30 | }
31 |
32 | public static boolean isInstanceEmpty() {
33 | return mWm == null;
34 | }
35 |
36 | public static MyWindowManager getInstance() {
37 | if (mWm == null) {
38 | throw new LuaError("悬浮窗未初始化,可能是无障碍功能可能未开启");
39 | }
40 | return mWm;
41 | }
42 |
43 | public static void destInstance() {
44 | mWm.removeAllViews();
45 | mWm.wm.removeView(mWm.viewGroup);
46 | mWm = null;
47 | System.gc();
48 | }
49 |
50 | public static void setAlpha(float alpha) {
51 | MyWindowManager.alpha = alpha;
52 | if (!isInstanceEmpty()) {
53 | //悬浮窗已实例化,更新悬浮窗透明度
54 | mWm.lp.alpha = alpha;
55 | mWm.handler.post(() -> {
56 | mWm.wm.updateViewLayout(mWm.viewGroup, mWm.lp);
57 | });
58 | }
59 | }
60 |
61 | public static float getAlpha() {
62 | return alpha;
63 | }
64 |
65 | private Handler handler = new Handler(Looper.getMainLooper());
66 | private WindowManager wm;
67 | private WindowManager.LayoutParams lp;
68 | private ViewGroup viewGroup;
69 |
70 | private MyWindowManager(Context context) {
71 | initView(context);
72 | initWindow(context);
73 | }
74 |
75 | private void initView(Context context) {
76 | viewGroup = new LinearLayout(context);
77 | }
78 |
79 | private void initWindow(Context context) {
80 | //悬浮窗类型
81 | int type;
82 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
83 | type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
84 | } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && alpha > MAXIMUM_OBSCURING_OPACITY) {
85 | type = WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
86 | } else {
87 | type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
88 | }
89 |
90 | wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
91 | lp = new WindowManager.LayoutParams(
92 | ViewGroup.LayoutParams.MATCH_PARENT,
93 | ViewGroup.LayoutParams.MATCH_PARENT,
94 | type,
95 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
96 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
97 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
98 | WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW,
99 | PixelFormat.RGBA_8888
100 | );
101 | lp.alpha = alpha;
102 | lp.gravity = Gravity.TOP | Gravity.LEFT;
103 |
104 | wm.addView(viewGroup, lp);
105 | }
106 |
107 | public synchronized void addView(View view) {
108 | handler.post(() -> viewGroup.addView(view));
109 | }
110 |
111 | public synchronized void removeView(View view) {
112 | handler.post(() -> viewGroup.removeView(view));
113 | }
114 |
115 | public synchronized void removeAllViews() {
116 | handler.post(() -> viewGroup.removeAllViews());
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/app/src/main/java/Thousand_Dust/ScriptLib.java:
--------------------------------------------------------------------------------
1 | package Thousand_Dust;
2 |
3 | import Thousand_Dust.canvas.BitmapLib;
4 | import Thousand_Dust.canvas.CanvasLib;
5 | import Thousand_Dust.canvas.PaintLib;
6 | import android.content.Context;
7 | import android.os.Looper;
8 |
9 | import Thousand_Dust.canvas.ViewLib;
10 |
11 | import luaj.Globals;
12 | import luaj.LoadState;
13 | import luaj.LuaTable;
14 | import luaj.LuaValue;
15 | import luaj.Varargs;
16 | import luaj.compiler.LuaC;
17 | import luaj.lib.TwoArgFunction;
18 | import luaj.lib.VarArgFunction;
19 |
20 | /**
21 | * @author Thousand-Dust
22 | */
23 | public class ScriptLib extends TwoArgFunction {
24 |
25 | private Globals globals;
26 | private final String tabName = "pro";
27 |
28 | public ScriptLib(Globals globals) {
29 | this.globals = globals;
30 | init();
31 | }
32 |
33 | @Override
34 | public LuaValue call(LuaValue arg1, LuaValue env) {
35 | LuaTable tab = new LuaTable();
36 | tab.set("VERSION", DevInfo.getVersion());
37 | tab.set("UPTIME", DevInfo.getUpdateTime());
38 | tab.set("AUTHOR", DevInfo.getAuthor());
39 | // tab.set("killMTP", new closeMTP());
40 | // tab.set("execCmd", new execCmd());
41 | // tab.set("toast",new toast());
42 | // tab.set("sleep",new sleep());
43 | env.set(tabName, tab);
44 | //获取屏幕分辨率
45 | env.set("getWH", new GetWH());
46 | //线程函数
47 | env.set("thread", new newThread());
48 | return env;
49 | }
50 |
51 | private void init() {
52 | this.globals.load(this);
53 | this.globals.load(new ViewLib());
54 | this.globals.load(new CanvasLib());
55 | this.globals.load(new PaintLib());
56 | this.globals.load(new BitmapLib());
57 | LoadState.install(this.globals);
58 | LuaC.install(this.globals);
59 | }
60 |
61 | class GetWH extends VarArgFunction {
62 | @Override
63 | public Varargs invoke(Varargs args) {
64 | LuaTable table = new LuaTable();
65 | int[] wh = Tools.getWH(Tools.getContext());
66 | table.set("width", wh[0]);
67 | table.set("height", wh[1]);
68 | return table;
69 | }
70 | }
71 |
72 | //新线程
73 | class newThread extends VarArgFunction {
74 | @Override
75 | public Varargs invoke(final Varargs args) {
76 | new Thread(() -> args.checkfunction(1).call()).start();
77 | return NONE;
78 | }
79 | }
80 |
81 | //关闭MTP检测
82 | class closeMTP extends VarArgFunction {
83 | @Override
84 | public Varargs invoke(final Varargs args) {
85 | try {
86 | Context appContext = Tools.getContext().createPackageContext(args.checkjstring(1), Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
87 | String path = appContext.getFilesDir().getAbsolutePath();
88 | String rs = args.checkboolean(2) ? "su " : "sh ";
89 | Runtime.getRuntime().exec(rs + "chmod 0000 " + path + "/tss_tmp/tssmua.zip\n exit");
90 | Runtime.getRuntime().exec(rs + "chmod 0000 " + path + "/files/tss_tmp/\n exit");
91 | } catch (Exception e) {
92 | return LuaValue.valueOf(e.toString());
93 | }
94 | return LuaValue.valueOf(args.checkjstring(1) + ":MTP搜索检测已关闭");
95 | }
96 | }
97 |
98 |
99 |
100 | //执行系统命令
101 | /*class execCmd extends VarArgFunction {
102 | boolean isClock = false;
103 | private String result = "";
104 | private Map PermisDescrip = new ArrayMap();
105 | private String[][] p = new String[][]{
106 | {"rm","此命令会删除您的文件/文件夹,且无法恢复。"},
107 | {"wget","此命令会从指定链接下载脚本,若您无法确认下载源是否安全,请不要继续执行。"},
108 | {"curl","此命令会访问网络或下载文件,若您无法确认访问是否安全,请不要继续执行。"},
109 | {"reboot","此命令会重启手机。"},
110 | {"shutdown","此命令会在设定时间重启/关闭手机。"},
111 | {"halt","此命令会直接关机。"},
112 | {"poweroff","此命令会直接关机。"},
113 | {":(){:|: &};:","此命令会无终止的条件递归。如果执行此操作,它将快速复制自己,从而消耗完所有的内存和CPU资源,导致冻结您的整个系统,若非特殊需求请勿继续执行!"}
114 | };
115 |
116 | private void initPermisDescrip()
117 | {
118 | for(String[] obj:p)
119 | PermisDescrip.put(obj[0],obj[1]);
120 | }
121 |
122 | @Override
123 | public Varargs invoke(Varargs args) {
124 | initPermisDescrip();
125 | String cmd = args.checkjstring(1);
126 | for(String[] s :p){
127 | if(cmd.indexOf(s[0]) != -1){
128 | showAlert(getMsg(s[0],cmd),cmd);
129 | return LuaValue.valueOf(result);
130 | }
131 | }
132 | try {
133 | return LuaValue.valueOf(Tools.execCmd(cmd, null));
134 | } catch (Exception e) {
135 | return LuaValue.valueOf(e.getMessage());
136 | }
137 | }
138 |
139 | public String getMsg(String name,String cmd)
140 | {
141 | String result =
142 | "脚本正在执行高危命令:" + name +
143 | "\n\n" +
144 | "执行的代码:" +
145 | cmd +
146 | "\n\n" +
147 | PermisDescrip.get(name) +
148 | "\n\n" +
149 | "是否忽略风险并执行?";
150 | return result;
151 | }
152 |
153 | public void showAlert(final String content,final String cmd) {
154 |
155 | Runnable run = new Runnable(){
156 | public void run() {
157 | final AlertDialog.Builder ab = new AlertDialog.Builder(Tools.getContext());
158 | ab.setTitle("注意");
159 | ab.setMessage(content);
160 | ab.setCancelable(false);
161 | ab.setPositiveButton("取消执行", new AlertDialog.OnClickListener(){
162 | @Override
163 | public void onClick(DialogInterface p1, int p2) {
164 | isClock = true;
165 | result = "refuse";
166 | ab.create().dismiss();
167 | }
168 | });
169 | ab.setNegativeButton("继续执行", new AlertDialog.OnClickListener(){
170 | @Override
171 | public void onClick(DialogInterface p1, int p2) {
172 | isClock = true;
173 | try {
174 | result = Tools.execCmd(cmd, null);
175 | } catch (Exception e) {
176 | result = e.getMessage();
177 | }
178 | }
179 | });
180 | final AlertDialog dialog = ab.create();
181 | if (Build.VERSION.SDK_INT >= 26) {
182 | dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
183 | } else {
184 | dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
185 | }
186 | dialog.show();
187 | }
188 | };
189 | ThreadManager.runOnUiThread(run);
190 | while(isClock == false)Thread.yield();
191 | }
192 | }*/
193 |
194 | /*class toast extends VarArgFunction
195 | {
196 | private Toast toast = null;
197 |
198 | public void showToast(Context context, String str){
199 | if(toast != null) {
200 | toast.cancel();
201 | }
202 | toast = Toast.makeText(context, str, Toast.LENGTH_SHORT);
203 | toast.show();
204 | }
205 |
206 | @Override
207 | public Varargs invoke(final Varargs args) {
208 | ThreadManager.runOnUiThread(new Runnable(){
209 | @Override
210 | public void run(){
211 | showToast(Tools.getContext(),args.checkjstring(1));
212 | }
213 | });
214 | return NONE;
215 | }
216 | }*/
217 |
218 |
219 | /*class sleep extends VarArgFunction
220 | {
221 | @Override
222 | public Varargs invoke(Varargs args) {
223 | try {
224 | Thread.sleep(args.checkint(1));
225 | } catch (InterruptedException e)
226 | {}
227 | return NONE;
228 | }
229 | }*/
230 | }
231 |
--------------------------------------------------------------------------------
/app/src/main/java/Thousand_Dust/Tools.java:
--------------------------------------------------------------------------------
1 | package Thousand_Dust;
2 |
3 | import android.content.Context;
4 | import android.util.DisplayMetrics;
5 | import android.widget.Toast;
6 | import java.io.File;
7 | import java.io.BufferedReader;
8 | import java.io.InputStreamReader;
9 | import java.io.Closeable;
10 | import android.ext.ThreadManager;
11 | import android.graphics.Bitmap;
12 | import android.os.StrictMode;
13 | import java.net.URL;
14 | import java.net.HttpURLConnection;
15 | import java.io.InputStream;
16 | import android.graphics.BitmapFactory;
17 | import android.os.Looper;
18 | import android.graphics.drawable.Drawable;
19 | import android.graphics.Canvas;
20 | import android.graphics.PixelFormat;
21 |
22 | public class Tools
23 | {
24 | public static Context getContext(){
25 | return android.ext.Tools.getContext();
26 | }
27 |
28 | public void toast(final String str)
29 | {
30 | Runnable run = new Runnable(){
31 | @Override
32 | public void run() {
33 | Toast.makeText(getContext(),str,Toast.LENGTH_SHORT).show();
34 | }
35 | };
36 | ThreadManager.runOnUiThread(run);
37 | }
38 |
39 | /**
40 | * 执行系统命令, 返回执行结果
41 | * @param cmd 需要执行的命令
42 | * @param dir 执行命令的子进程的工作目录, null 表示和当前主进程工作目录相同
43 | */
44 | public static String execCmd(String cmd, File dir) throws Exception {
45 | StringBuilder result = new StringBuilder();
46 |
47 | Process process = null;
48 | BufferedReader bufrIn = null;
49 | BufferedReader bufrError = null;
50 |
51 | try {
52 | // 执行命令, 返回一个子进程对象(命令在子进程中执行)
53 | process = Runtime.getRuntime().exec(cmd, null, dir);
54 |
55 | // 方法阻塞, 等待命令执行完成(成功会返回0)
56 | process.waitFor();
57 |
58 | // 获取命令执行结果, 有两个结果: 正常的输出 和 错误的输出(PS: 子进程的输出就是主进程的输入)
59 | bufrIn = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
60 | bufrError = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));
61 |
62 | // 读取输出
63 | String line = null;
64 | while ((line = bufrIn.readLine()) != null) {
65 | result.append(line).append('\n');
66 | }
67 | while ((line = bufrError.readLine()) != null) {
68 | result.append(line).append('\n');
69 | }
70 |
71 | } finally {
72 | closeStream(bufrIn);
73 | closeStream(bufrError);
74 | // 销毁子进程
75 | if (process != null) {
76 | process.destroy();
77 | }
78 | }
79 |
80 | // 返回执行结果
81 | return result.toString().substring(0,result.length()-1);
82 | }
83 |
84 | private static void closeStream(Closeable stream) {
85 | if (stream != null) {
86 | try {
87 | stream.close();
88 | } catch (Exception e) {
89 | // nothing
90 | }
91 | }
92 | }
93 |
94 | public static boolean isMainThread() {
95 | return Looper.getMainLooper().getThread().getId() == Thread.currentThread().getId();
96 | }
97 |
98 | public static Bitmap getHttpBitmap(String url) {
99 | if (isMainThread()) {
100 | StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
101 | StrictMode.setThreadPolicy(policy);
102 | }
103 | URL myFileURL;
104 | Bitmap bitmap=null;
105 | try {
106 | myFileURL = new URL(url);
107 | HttpURLConnection conn=(HttpURLConnection)myFileURL.openConnection();
108 | conn.setConnectTimeout(6000);
109 | conn.setDoInput(true);
110 | conn.setUseCaches(false);
111 | conn.connect();
112 | InputStream is = conn.getInputStream();
113 | bitmap = BitmapFactory.decodeStream(is);
114 | is.close();
115 | } catch (Exception e) {
116 | e.printStackTrace();
117 | }
118 | return bitmap;
119 | }
120 |
121 | public static Bitmap drawableToBitmap(Drawable drawable) {
122 | Bitmap bitmap = Bitmap.createBitmap( drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
123 | drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
124 | Canvas canvas = new Canvas(bitmap);
125 | drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
126 | drawable.draw(canvas);
127 | return bitmap;
128 | }
129 |
130 | public static int[] getWH(Context context) {
131 | DisplayMetrics dm = context.getResources().getDisplayMetrics();
132 | return new int[]{dm.widthPixels, dm.heightPixels};
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/app/src/main/java/Thousand_Dust/canvas/BitmapLib.java:
--------------------------------------------------------------------------------
1 | package Thousand_Dust.canvas;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapFactory;
5 | import android.graphics.Matrix;
6 |
7 | import Thousand_Dust.luaj.LuaBitmap;
8 | import luaj.LuaNumber;
9 | import luaj.LuaTable;
10 | import luaj.LuaValue;
11 | import luaj.Varargs;
12 | import luaj.lib.TwoArgFunction;
13 | import luaj.lib.VarArgFunction;
14 |
15 | /**
16 | * @author Thousand-Dust
17 | */
18 | public class BitmapLib extends TwoArgFunction {
19 |
20 | @Override
21 | public LuaValue call(LuaValue arg1, LuaValue env) {
22 | env.set("loadBitmap", new loadBitmap());
23 | LuaTable table = new LuaTable();
24 | table.set("setWidth", new setWidth());
25 | table.set("setHeight", new setHeight());
26 | table.set("getWH", new getWH());
27 | table.set("remove", new remove());
28 |
29 | if (LuaBitmap.s_metatable == null) {
30 | LuaTable mt = LuaValue.tableOf(
31 | new LuaValue[] { INDEX, table});
32 | LuaBitmap.s_metatable = mt;
33 | }
34 |
35 | return env;
36 | }
37 |
38 | class loadBitmap extends VarArgFunction {
39 | @Override
40 | public Varargs invoke(Varargs args) {
41 | return LuaBitmap.valueOf(BitmapFactory.decodeFile(args.checkjstring(1)));
42 | }
43 | }
44 |
45 | class setWidth extends VarArgFunction {
46 | @Override
47 | public Varargs invoke(Varargs args) {
48 | Bitmap bitmap = LuaBitmap.checkbitmap(args.arg(1));
49 | int width = bitmap.getWidth();
50 | int height = bitmap.getHeight();
51 | Matrix matrix = new Matrix();
52 | matrix.postScale(width/args.tofloat(2), 1);
53 | return LuaBitmap.valueOf(Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true));
54 | }
55 | }
56 |
57 | class setHeight extends VarArgFunction {
58 | @Override
59 | public Varargs invoke(Varargs args) {
60 | Bitmap bitmap = LuaBitmap.checkbitmap(args.arg(1));
61 | int width = bitmap.getWidth();
62 | int height = bitmap.getHeight();
63 | Matrix matrix = new Matrix();
64 | matrix.postScale(1, height/args.tofloat(2));
65 | return LuaBitmap.valueOf(Bitmap.createBitmap(bitmap, 0,0, width, height, matrix, true));
66 | }
67 | }
68 |
69 | class getWH extends VarArgFunction {
70 | @Override
71 | public Varargs invoke(Varargs args) {
72 | Bitmap bitmap = LuaBitmap.checkbitmap(args.arg(1));
73 | int width = bitmap.getWidth();
74 | int height = bitmap.getHeight();
75 | return LuaValue.tableOf(new LuaValue[]{ LuaValue.valueOf(width), LuaValue.valueOf(height) });
76 | }
77 | }
78 |
79 | class remove extends VarArgFunction {
80 | @Override
81 | public Varargs invoke(Varargs args) {
82 | Bitmap bitmap = LuaBitmap.checkbitmap(args.arg(1));
83 | bitmap.recycle();
84 | return NONE;
85 | }
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/app/src/main/java/Thousand_Dust/canvas/CanvasLib.java:
--------------------------------------------------------------------------------
1 | package Thousand_Dust.canvas;
2 |
3 | import Thousand_Dust.luaj.LuaBitmap;
4 | import Thousand_Dust.luaj.LuaCanvas;
5 | import luaj.LuaFunction;
6 | import Thousand_Dust.luaj.LuaPaint;
7 | import luaj.lib.TwoArgFunction;
8 | import luaj.LuaValue;
9 | import luaj.LuaTable;
10 | import luaj.lib.VarArgFunction;
11 |
12 | import android.graphics.Canvas;
13 |
14 | import luaj.Varargs;
15 |
16 | import android.graphics.RectF;
17 | import android.graphics.Paint;
18 |
19 | import luaj.LuaError;
20 |
21 | import android.graphics.Color;
22 | import android.util.Log;
23 |
24 | /**
25 | * @author Thousand-Dust
26 | */
27 | public class CanvasLib extends TwoArgFunction {
28 |
29 | @Override
30 | public LuaValue call(LuaValue modname, LuaValue env) {
31 | LuaTable canvas = new LuaTable();
32 | //绘制圆弧
33 | canvas.set("drawArc", new drawArc());
34 | //绘制Bitmap图片
35 | canvas.set("drawBitmap", new drawBitmap());
36 | //绘制圆
37 | canvas.set("drawCircle", new drawCircle());
38 | //绘制背景颜色
39 | canvas.set("drawColor", new drawColor());
40 | //绘制线段
41 | canvas.set("drawLine", new drawLine());
42 | //绘制多条线段
43 | canvas.set("drawLines", new drawLines());
44 | //绘制四边形
45 | canvas.set("drawRect", new drawRect());
46 | //绘制字符串
47 | canvas.set("drawText", new drawText());
48 | //裁剪绘制内容(四边形)
49 | canvas.set("clipRect", new clipRect());
50 | //旋转画布
51 | canvas.set("rotate", new rotate());
52 | //移动画布原点
53 | canvas.set("translate", new translate());
54 | //保存画布状态
55 | canvas.set("save", new Save());
56 | //恢复上次保存的画布状态
57 | canvas.set("restore", new Restore());
58 |
59 | if (!env.get("package").isnil()) {
60 | env.get("package").get("loaded").set("canvas", canvas);
61 | }
62 | if (LuaCanvas.s_metatable == null) {
63 | LuaTable mt = LuaValue.tableOf(
64 | new LuaValue[] { INDEX, canvas});
65 | LuaCanvas.s_metatable = mt;
66 | }
67 |
68 | return canvas;
69 | }
70 |
71 | class MyThread extends VarArgFunction {
72 | @Override
73 | public Varargs invoke(final Varargs args) {
74 | new Thread() {
75 | @Override
76 | public void run() {
77 | LuaFunction fun = args.checkfunction(1);
78 | try {
79 | if (args.narg() == 1) {
80 | fun.call();
81 | } else {
82 | fun.call(args.checktable(2));
83 | }
84 | } catch (Exception e) {
85 | throw new LuaError(e.toString());
86 | }
87 | }
88 | }.start();
89 |
90 | return NONE;
91 | }
92 |
93 | }
94 |
95 | class drawArc extends VarArgFunction {
96 | @Override
97 | public Varargs invoke(Varargs args) {
98 | Canvas canvas = LuaCanvas.checkcanvas(args.arg(1));
99 |
100 | LuaTable table = args.checktable(2);
101 | RectF rectF = new RectF(table.get(1).tofloat(), table.get(2).tofloat(), table.get(3).tofloat(), table.get(4).tofloat());
102 |
103 | canvas.drawArc(rectF, args.tofloat(3), args.tofloat(4), args.checkboolean(5), LuaPaint.checkpaint(args.arg(6)));
104 | return NONE;
105 | }
106 | }
107 |
108 | class drawBitmap extends VarArgFunction {
109 | @Override
110 | public Varargs invoke(Varargs args) {
111 | LuaCanvas.checkcanvas(args.arg(1)).drawBitmap(LuaBitmap.checkbitmap(args.arg(2)), args.tofloat(3), args.tofloat(4), LuaPaint.checkpaint(args.arg(5)));
112 | return NONE;
113 | }
114 | }
115 |
116 | class drawCircle extends VarArgFunction {
117 | @Override
118 | public Varargs invoke(Varargs args) {
119 | LuaCanvas.checkcanvas(args.arg(1))
120 | .drawCircle(args.tofloat(2), args.tofloat(3), args.tofloat(4), LuaPaint.checkpaint(args.arg(5)));
121 | return NONE;
122 | }
123 | }
124 |
125 | class drawColor extends VarArgFunction {
126 | @Override
127 | public Varargs invoke(Varargs args) {
128 | LuaCanvas.checkcanvas(args.arg(1)).drawColor(Color.parseColor(args.tojstring(2)));
129 | return NONE;
130 | }
131 | }
132 |
133 | class drawLine extends VarArgFunction {
134 | @Override
135 | public Varargs invoke(Varargs args) {
136 | LuaCanvas.checkcanvas(args.arg(1))
137 | .drawLine(args.tofloat(2), args.tofloat(3), args.tofloat(4), args.tofloat(5), LuaPaint.checkpaint(args.arg(6)));
138 | return NONE;
139 | }
140 | }
141 |
142 | class drawLines extends VarArgFunction {
143 | @Override
144 | public Varargs invoke(Varargs args) {
145 | LuaTable table = args.checktable(2);
146 | float[] floats = new float[table.length()];
147 | for (int i = 0; i < floats.length; i++) {
148 | floats[i] = table.get(i).tofloat();
149 | }
150 | LuaCanvas.checkcanvas(args.arg(1)).drawLines(floats, LuaPaint.checkpaint(args.arg(3)));
151 | return NONE;
152 | }
153 | }
154 |
155 | /*class drawProgress extends VarArgFunction {
156 | private Paint framePaint;
157 | private Paint progressPaint;
158 |
159 | public drawProgress(Paint paint) {
160 | this.framePaint = paint;
161 | progressPaint = new Paint();
162 | progressPaint.setStyle(Paint.Style.FILL);
163 | }
164 |
165 | @Override
166 | public Varargs invoke(Varargs args) {
167 | int narg = args.narg();
168 | if (narg >= 6) {
169 | framePaint.setColor(Color.parseColor(args.checkjstring(6))); //使用用户自定义背景颜色
170 | } else {
171 | framePaint.setColor(Color.parseColor("#FFFFFF"));
172 | //判断是否使用用户自定义进度颜色
173 | if (narg == 5) {
174 | progressPaint.setColor(Color.parseColor(args.checkjstring(5)));
175 | } else {
176 | progressPaint.setColor(Color.parseColor("#FF0000"));
177 | }
178 | }
179 | Canvas canvas = LuaCanvas.checkcanvas(args.arg(1)); //使用默认画笔
180 | //获得进度条背景矩形
181 | float left, top, right, bottom;
182 | {
183 | LuaTable table = args.checktable(2);
184 | left = table.get(1).tofloat();
185 | top = table.get(2).tofloat();
186 | right = table.get(3).tofloat();
187 | bottom = table.get(4).tofloat();
188 | }
189 | RectF frameRect = new RectF(left, top, right, bottom);
190 | //绘制进度条背景
191 | canvas.drawRect(frameRect, framePaint);
192 | //计算进度矩形
193 | float max = args.tofloat(3);
194 | float progress = args.tofloat(4);
195 | float proportion = (right - left) / max;
196 | RectF internel = new RectF(left, top, left + (progress * proportion), bottom);
197 | //绘制进度
198 | canvas.drawRect(internel, progressPaint);
199 |
200 | return NONE;
201 | }
202 | }*/
203 |
204 | class drawRect extends VarArgFunction {
205 | @Override
206 | public Varargs invoke(Varargs args) {
207 | LuaTable table = args.checktable(2);
208 | RectF rectF = new RectF(table.get(1).tofloat(), table.get(2).tofloat(), table.get(3).tofloat(), table.get(4).tofloat());
209 | LuaCanvas.checkcanvas(args.arg(1)).drawRect(rectF, LuaPaint.checkpaint(args.arg(3)));
210 | return NONE;
211 | }
212 | }
213 |
214 | class drawText extends VarArgFunction {
215 | @Override
216 | public Varargs invoke(Varargs args) {
217 | LuaCanvas.checkcanvas(args.arg(1))
218 | .drawText(args.checkjstring(2), args.tofloat(3), args.tofloat(4), LuaPaint.checkpaint(args.arg(5)));
219 | return NONE;
220 | }
221 | }
222 |
223 | class clipRect extends VarArgFunction {
224 | @Override
225 | public Varargs invoke(Varargs args) {
226 | LuaTable table = args.checktable(2);
227 | LuaCanvas.checkcanvas(args.arg(1)).clipRect(new RectF(table.tofloat(1), table.tofloat(2), table.tofloat(3), table.tofloat(4)));
228 | return NONE;
229 | }
230 | }
231 |
232 | class rotate extends VarArgFunction {
233 | @Override
234 | public Varargs invoke(Varargs args) {
235 | Canvas canvas = LuaCanvas.checkcanvas(args.arg(1));
236 | switch (args.narg()) {
237 | case 2:
238 | canvas.rotate(args.tofloat(2));
239 | break;
240 | case 4:
241 | canvas.rotate(args.tofloat(2), args.tofloat(3), args.tofloat(4));
242 | break;
243 | default:
244 | throw new LuaError("there is no such method: " + args);
245 | }
246 | return NONE;
247 | }
248 | }
249 |
250 | class translate extends VarArgFunction {
251 | @Override
252 | public Varargs invoke(Varargs args) {
253 | LuaCanvas.checkcanvas(args.arg(1)).translate(args.tofloat(2), args.tofloat(3));
254 | return NONE;
255 | }
256 | }
257 |
258 | class Save extends VarArgFunction {
259 | @Override
260 | public Varargs invoke(Varargs args) {
261 | LuaCanvas.checkcanvas(args.arg(1)).save();
262 | return NONE;
263 | }
264 | }
265 |
266 | class Restore extends VarArgFunction {
267 | @Override
268 | public Varargs invoke(Varargs args) {
269 | LuaCanvas.checkcanvas(args.arg(1)).restore();
270 | return NONE;
271 | }
272 | }
273 |
274 | }
--------------------------------------------------------------------------------
/app/src/main/java/Thousand_Dust/canvas/PaintLib.java:
--------------------------------------------------------------------------------
1 | package Thousand_Dust.canvas;
2 | import Thousand_Dust.luaj.LuaPaint;
3 | import luaj.LuaString;
4 | import luaj.lib.TwoArgFunction;
5 | import luaj.LuaValue;
6 | import luaj.lib.VarArgFunction;
7 | import luaj.LuaTable;
8 | import luaj.Varargs;
9 | import android.graphics.Paint;
10 | import luaj.LuaError;
11 | import android.graphics.Color;
12 |
13 | /**
14 | * @author Thousand-Dust
15 | */
16 | public class PaintLib extends TwoArgFunction {
17 |
18 | @Override
19 | public LuaValue call(LuaValue arg1, LuaValue env) {
20 |
21 | env.set("newPaint", new newPaint());
22 |
23 | LuaTable paint = new LuaTable();
24 | //设置画笔笔触宽
25 | paint.set("setWidth", new setWidth());
26 | //设置画笔样式
27 | paint.set("setStyle", new setStyle());
28 | //设置画笔颜色
29 | paint.set("setColor", new setColor());
30 | //设置画笔画出的字符大小
31 | paint.set("setTextSize", new setTextSize());
32 | //设置抗锯齿
33 | paint.set("setAntiAlias", new setAntiAlias());
34 |
35 | if (!env.get("package").isnil()) {
36 | env.get("package").get("loaded").set("paint", paint);
37 | }
38 | if (LuaPaint.s_metatable == null) {
39 | LuaTable mt = LuaValue.tableOf(
40 | new LuaValue[] { INDEX, paint});
41 | LuaPaint.s_metatable = mt;
42 | }
43 |
44 | return env;
45 | }
46 |
47 | class newPaint extends VarArgFunction {
48 | @Override
49 | public Varargs invoke(Varargs args) {
50 | return LuaPaint.valueOf(new Paint());
51 | }
52 | }
53 |
54 | class setWidth extends VarArgFunction {
55 | @Override
56 | public Varargs invoke(Varargs args) {
57 | LuaPaint.checkpaint(args.arg(1)).setStrokeWidth(args.checkint(2));
58 | return NONE;
59 | }
60 | }
61 |
62 | class setStyle extends VarArgFunction {
63 | @Override
64 | public Varargs invoke(Varargs args) {
65 | LuaValue value = args.checkvalue(2);
66 |
67 | Paint.Style style;
68 | if (value instanceof LuaString) {
69 | String styleStr = value.checkjstring();
70 | switch (styleStr) {
71 | case "描边":
72 | style = Paint.Style.STROKE;
73 | break;
74 | case "填充":
75 | style = Paint.Style.FILL;
76 | break;
77 | case "描边并填充":
78 | style = Paint.Style.FILL_AND_STROKE;
79 | break;
80 |
81 | default:
82 | throw new LuaError("未知的画笔类型");
83 | }
84 | } else {
85 | int styleNum = value.checkint();
86 | switch (styleNum) {
87 | case 0:
88 | //描边
89 | style = Paint.Style.STROKE;
90 | break;
91 | case 1:
92 | //填充
93 | style = Paint.Style.FILL;
94 | break;
95 | case 2:
96 | //描边并填充
97 | style = Paint.Style.FILL_AND_STROKE;
98 | break;
99 |
100 | default:
101 | throw new LuaError("未知的画笔类型");
102 | }
103 | }
104 |
105 | LuaPaint.checkpaint(args.arg(1)).setStyle(style);
106 |
107 | return NONE;
108 | }
109 | }
110 |
111 | class setColor extends VarArgFunction {
112 | @Override
113 | public Varargs invoke(Varargs args) {
114 | LuaPaint.checkpaint(args.arg(1)).setColor(Color.parseColor(args.checkjstring(2)));
115 | return NONE;
116 | }
117 | }
118 |
119 | class setTextSize extends VarArgFunction {
120 | @Override
121 | public Varargs invoke(Varargs args) {
122 | LuaPaint.checkpaint(args.arg(1)).setTextSize(args.tofloat(2));
123 | return NONE;
124 | }
125 | }
126 |
127 | class setAntiAlias extends VarArgFunction {
128 | @Override
129 | public Varargs invoke(Varargs args) {
130 | LuaPaint.checkpaint(args.arg(1)).setAntiAlias(args.checkboolean(2));
131 | return NONE;
132 | }
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/app/src/main/java/Thousand_Dust/canvas/ViewLib.java:
--------------------------------------------------------------------------------
1 | package Thousand_Dust.canvas;
2 |
3 | import static Thousand_Dust.MyWindowManager.MAXIMUM_OBSCURING_OPACITY;
4 |
5 | import android.app.AlertDialog;
6 | import android.content.Intent;
7 | import android.graphics.Color;
8 | import android.os.Build;
9 | import android.os.Handler;
10 | import android.os.Looper;
11 |
12 | import Thousand_Dust.DevInfo;
13 | import Thousand_Dust.DrawView;
14 | import Thousand_Dust.MyWindowManager;
15 | import Thousand_Dust.Tools;
16 |
17 | import android.provider.Settings;
18 | import android.util.Log;
19 | import android.view.Gravity;
20 | import android.view.WindowManager;
21 | import android.widget.TextView;
22 |
23 | import luaj.Globals;
24 | import Thousand_Dust.luaj.LuaView;
25 | import luaj.LuaError;
26 | import luaj.lib.TwoArgFunction;
27 | import luaj.LuaValue;
28 | import luaj.LuaTable;
29 | import luaj.lib.VarArgFunction;
30 | import luaj.Varargs;
31 |
32 | /**
33 | * @author Thousand-Dust
34 | */
35 | public class ViewLib extends TwoArgFunction {
36 |
37 | private Globals globals;
38 |
39 | @Override
40 | public LuaValue call(LuaValue arg1, LuaValue env) {
41 | globals = env.checkglobals();
42 | //强制关闭绘图无障碍
43 | env.set("disDrawAcc", new disDrawAcc());
44 |
45 | env.set("newView", new newView());
46 | env.set("removeAllView", new removeAllView());
47 |
48 | LuaTable view = new LuaTable();
49 | //调用Lua绘制函数更新绘制
50 | view.set("invalidate", new invalidate());
51 | //显示绘制
52 | view.set("show", new showDraw());
53 | //删除绘制内容
54 | view.set("close", new closeDraw());
55 |
56 | if (!env.get("package").isnil()) {
57 | env.get("package").get("loaded").set("view", view);
58 | }
59 | if (LuaView.s_metatable == null) {
60 | LuaTable mt = LuaValue.tableOf(
61 | new LuaValue[]{INDEX, view});
62 | LuaView.s_metatable = mt;
63 | }
64 |
65 | return env;
66 | }
67 |
68 | class disDrawAcc extends VarArgFunction {
69 | @Override
70 | public Varargs invoke(Varargs args) {
71 | MyWindowManager.setAlpha(MAXIMUM_OBSCURING_OPACITY);
72 | return LuaValue.NONE;
73 | }
74 | }
75 |
76 | class newView extends VarArgFunction {
77 | private boolean isPrint = false;
78 |
79 | @Override
80 | public Varargs invoke(Varargs args) {
81 | if (MyWindowManager.isInstanceEmpty()) {
82 | //android版本12及以上需要开启无障碍
83 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && MyWindowManager.getAlpha() > MAXIMUM_OBSCURING_OPACITY) {
84 | showPermissionAlert();
85 | } else {
86 | showOrdinaryAlert();
87 | }
88 | }
89 | DrawView drawView = new DrawView(Tools.getContext(), globals);
90 | MyWindowManager.getInstance().addView(drawView);
91 | return LuaView.valueOf(drawView);
92 | }
93 |
94 | public void showOrdinaryAlert() {
95 | final boolean[] result = {false, false};
96 | Runnable run = () -> {
97 | //复制函数开发者信息可点击文字
98 | TextView devText = new TextView(Tools.getContext());
99 | devText.setText("输出并复制函数开发者信息");
100 | devText.setTextColor(Color.parseColor("#00FFFF"));
101 | devText.setGravity(Gravity.CENTER_HORIZONTAL);
102 | devText.setPadding(0, 20, 0, 0);
103 | devText.setOnClickListener((v) -> {
104 | android.ext.Tools.copyText(DevInfo.getAuthor());
105 | if (!isPrint) {
106 | globals.STDOUT.println(DevInfo.getAuthor());
107 | isPrint = true;
108 | }
109 | });
110 |
111 | //绘制提示弹窗
112 | final AlertDialog.Builder ab = new AlertDialog.Builder(Tools.getContext());
113 | ab.setTitle("绘制");
114 | ab.setMessage("脚本即将在屏幕上绘图\n同意继续,拒绝则退出脚本。");
115 | ab.setView(devText);
116 | ab.setCancelable(false);
117 | ab.setPositiveButton("同意", (p1, p2) -> {
118 | MyWindowManager.newInstance(Tools.getContext());
119 | result[1] = true;
120 | });
121 | ab.setNegativeButton("拒绝", (p1, p2) -> {
122 | result[1] = false;
123 | });
124 | ab.setOnDismissListener((dialogInterface) -> result[0] = true);
125 | final AlertDialog dialog = ab.create();
126 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
127 | dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
128 | } else {
129 | dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
130 | }
131 | dialog.show();
132 | };
133 |
134 | new Handler(Looper.getMainLooper()).post(run);
135 | while (!result[0]) {
136 | Thread.yield();
137 | }
138 | //拒绝在屏幕上绘制
139 | if (!result[1]) {
140 | throw new LuaError("用户拒绝在屏幕上绘制");
141 | }
142 | }
143 |
144 | public void showPermissionAlert() {
145 | final boolean[] isClock = {false};
146 | Runnable run = () -> {
147 | //复制函数开发者信息可点击文字
148 | TextView devText = new TextView(Tools.getContext());
149 | devText.setText("输出并复制函数开发者信息");
150 | devText.setTextColor(Color.parseColor("#00FFFF"));
151 | devText.setGravity(Gravity.CENTER_HORIZONTAL);
152 | devText.setPadding(0, 20, 0, 0);
153 | devText.setOnClickListener((v) -> {
154 | android.ext.Tools.copyText(DevInfo.getAuthor());
155 | if (!isPrint) {
156 | globals.STDOUT.println(DevInfo.getAuthor());
157 | isPrint = true;
158 | }
159 | });
160 |
161 | //权限请求弹窗
162 | final AlertDialog.Builder ab = new AlertDialog.Builder(Tools.getContext());
163 | ab.setTitle("权限请求");
164 | ab.setMessage("脚本即将在屏幕上绘图\n" +
165 | "但因为您的Android设备版本为12或以上,需要开启无障碍(或调用函数\"disDrawAcc()\")\n" +
166 | "同意跳转权限页面,拒绝结束脚本。");
167 | ab.setView(devText);
168 | ab.setCancelable(false);
169 | ab.setPositiveButton("同意", (p1, p2) -> {
170 | Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
171 | Tools.getContext().startActivity(intent);
172 | });
173 | ab.setNegativeButton("拒绝", null);
174 | ab.setOnDismissListener((dialogInterface) -> isClock[0] = true);
175 | final AlertDialog dialog = ab.create();
176 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
177 | dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
178 | } else {
179 | dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
180 | }
181 | dialog.show();
182 | };
183 |
184 | new Handler(Looper.getMainLooper()).post(run);
185 | while (!isClock[0]) {
186 | Thread.yield();
187 | }
188 | }
189 | }
190 |
191 | class invalidate extends VarArgFunction {
192 | @Override
193 | public Varargs invoke(Varargs args) {
194 | LuaView.checkview(args.arg(1)).postInvalidate();
195 | return NONE;
196 | }
197 | }
198 |
199 | class showDraw extends VarArgFunction {
200 | @Override
201 | public Varargs invoke(Varargs varargs) {
202 | DrawView luaView = LuaView.checkview(varargs.arg(1));
203 | luaView.setDrawFun(varargs.checkfunction(2));
204 | luaView.start(varargs.optint(3, 60));
205 | return LuaValue.NONE;
206 | }
207 | }
208 |
209 | class closeDraw extends VarArgFunction {
210 | @Override
211 | public Varargs invoke(Varargs varargs) {
212 | DrawView luaView = LuaView.checkview(varargs.arg(1));
213 | MyWindowManager.getInstance().removeView(luaView);
214 | return LuaValue.NONE;
215 | }
216 | }
217 |
218 | private class removeAllView extends VarArgFunction {
219 | @Override
220 | public Varargs invoke(Varargs varargs) {
221 | MyWindowManager.getInstance().removeAllViews();
222 | return LuaValue.NONE;
223 | }
224 | }
225 | }
226 |
--------------------------------------------------------------------------------
/app/src/main/java/Thousand_Dust/luaj/LuaBitmap.java:
--------------------------------------------------------------------------------
1 | package Thousand_Dust.luaj;
2 |
3 | import android.graphics.Bitmap;
4 |
5 | import luaj.LuaValue;
6 |
7 | /**
8 | * @author Thousand-Dust
9 | */
10 | public class LuaBitmap extends LuaValue {
11 |
12 | private Bitmap bitmap;
13 | public static LuaValue s_metatable;
14 |
15 | @Override
16 | public int type() {
17 | return 11;
18 | }
19 |
20 | @Override
21 | public String typename() {
22 | return "bitmap";
23 | }
24 |
25 | @Override
26 | public LuaValue getmetatable() {
27 | return s_metatable;
28 | }
29 |
30 | public static LuaBitmap valueOf(Bitmap bitmap){
31 | return new LuaBitmap(bitmap);
32 | }
33 |
34 | private LuaBitmap(Bitmap bitmap){
35 | this.bitmap = bitmap;
36 | }
37 |
38 | public static Bitmap checkbitmap(LuaValue luaValue) {
39 | return luaValue instanceof LuaBitmap ? ((LuaBitmap) luaValue).bitmap : null;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/Thousand_Dust/luaj/LuaCanvas.java:
--------------------------------------------------------------------------------
1 | package Thousand_Dust.luaj;
2 | import android.graphics.Canvas;
3 |
4 | import luaj.LuaValue;
5 |
6 | /**
7 | * @author Thousand-Dust
8 | */
9 | public class LuaCanvas extends LuaValue {
10 |
11 | private Canvas canvas;
12 | public static LuaValue s_metatable;
13 |
14 | @Override
15 | public int type() {
16 | return 12;
17 | }
18 |
19 | @Override
20 | public String typename() {
21 | return "canvas";
22 | }
23 |
24 | @Override
25 | public LuaValue getmetatable() {
26 | return s_metatable;
27 | }
28 |
29 | public static LuaCanvas valueOf(Canvas canvas){
30 | return new LuaCanvas(canvas);
31 | }
32 |
33 | private LuaCanvas(Canvas canvas){
34 | this.canvas = canvas;
35 | }
36 |
37 | public static Canvas checkcanvas(LuaValue luaValue) {
38 | return luaValue instanceof LuaCanvas ? ((LuaCanvas) luaValue).canvas : null;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/Thousand_Dust/luaj/LuaPaint.java:
--------------------------------------------------------------------------------
1 | package Thousand_Dust.luaj;
2 | import android.graphics.Paint;
3 |
4 | import luaj.LuaValue;
5 |
6 | /**
7 | * @author Thousand-Dust
8 | */
9 | public class LuaPaint extends LuaValue {
10 |
11 | private Paint paint;
12 | public static LuaValue s_metatable;
13 |
14 | @Override
15 | public int type() {
16 | return 13;
17 | }
18 |
19 | @Override
20 | public String typename() {
21 | return "paint";
22 | }
23 |
24 | @Override
25 | public LuaValue getmetatable() {
26 | return s_metatable;
27 | }
28 |
29 | public static LuaPaint valueOf(Paint paint){
30 | return new LuaPaint(paint);
31 | }
32 |
33 | private LuaPaint(Paint paint){
34 | this.paint = paint;
35 | }
36 |
37 | public static Paint checkpaint(LuaValue luaValue) {
38 | return luaValue instanceof LuaPaint ? ((LuaPaint) luaValue).paint : null;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/Thousand_Dust/luaj/LuaView.java:
--------------------------------------------------------------------------------
1 | package Thousand_Dust.luaj;
2 |
3 | import Thousand_Dust.DrawView;
4 |
5 | import luaj.LuaValue;
6 |
7 | /**
8 | * @author Thousand-Dust
9 | */
10 | public class LuaView extends LuaValue {
11 |
12 | private DrawView view;
13 | public static LuaValue s_metatable;
14 |
15 | @Override
16 | public int type() {
17 | return 10;
18 | }
19 |
20 | @Override
21 | public String typename() {
22 | return "view";
23 | }
24 |
25 | @Override
26 | public LuaValue getmetatable() {
27 | return s_metatable;
28 | }
29 |
30 | public static LuaView valueOf(DrawView v){
31 | return new LuaView(v);
32 | }
33 |
34 | private LuaView(DrawView view){
35 | this.view = view;
36 | }
37 |
38 | public static DrawView checkview(LuaValue luaValue) {
39 | return luaValue instanceof LuaView ? ((LuaView) luaValue).view : null;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/Thousand_Dust/socket/LuaServerSocket.java:
--------------------------------------------------------------------------------
1 | package Thousand_Dust.socket;
2 |
3 | import android.os.Handler;
4 | import android.os.Message;
5 |
6 | import androidx.annotation.NonNull;
7 |
8 | import luaj.LuaString;
9 | import luaj.LuaTable;
10 | import luaj.LuaValue;
11 | import luaj.Varargs;
12 | import luaj.lib.TwoArgFunction;
13 | import luaj.lib.VarArgFunction;
14 |
15 | import java.io.ByteArrayOutputStream;
16 | import java.io.IOException;
17 | import java.io.InputStream;
18 | import java.net.ServerSocket;
19 | import java.net.Socket;
20 |
21 | public class LuaServerSocket extends TwoArgFunction {
22 |
23 | private interface SocketEvent {
24 | void socketEvent(LuaString luaStr);
25 | }
26 |
27 | @Override
28 | public LuaValue call(LuaValue arg1, LuaValue arg2) {
29 | LuaTable t = new LuaTable();
30 | t.set("setSocketEvent", new setSocketEvent());
31 | arg2.set("SeverSocket", t);
32 |
33 | return t;
34 | }
35 |
36 | class setSocketEvent extends VarArgFunction {
37 |
38 | private ServerSocket ss;
39 | private Socket socket;
40 | private SocketEvent event;
41 |
42 | private Handler handler = new Handler() {
43 | @Override
44 | public void handleMessage(@NonNull Message msg) {
45 | switch (msg.what) {
46 | case 0x001:
47 | //向lua发送接收到的Socket消息内容
48 | event.socketEvent((LuaString)msg.obj);
49 | break;
50 | }
51 | }
52 | };
53 |
54 | @Override
55 | public Varargs invoke(final Varargs args) {
56 | new Thread() {
57 | @Override
58 | public void run() {
59 | InputStream in = null;
60 | ByteArrayOutputStream out = null;
61 | while (true) {
62 | try {
63 | ss = new ServerSocket(args.checkint(1));
64 | socket = ss.accept();
65 | in = socket.getInputStream();
66 | out = new ByteArrayOutputStream();
67 | byte[] bytes = new byte[1024];
68 | int len = -1;
69 | while ((len = in.read(bytes)) != -1) {
70 | out.write(bytes, 0, len);
71 | }
72 |
73 | //发送消息,让lua线程向lua发送接收到的Socket消息内容
74 | Message message = new Message();
75 | message.what = 0x001;
76 | message.obj = LuaString.valueOf(out.toByteArray());
77 | handler.sendMessage(message);
78 | } catch (IOException e) {
79 | continue;
80 | } finally {
81 | try {
82 | if (in != null)
83 | in.close();
84 | if (out != null)
85 | out.close();
86 | } catch (IOException e) {
87 | }
88 | }
89 | }
90 |
91 | }
92 | }.start();
93 |
94 | event = new SocketEvent() {
95 | @Override
96 | public void socketEvent(LuaString luaStr) {
97 | args.checkfunction(2).call(luaStr);
98 | }
99 | };
100 |
101 | return NONE;
102 | }
103 |
104 | }
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/app/src/main/java/Thousand_Dust/socket/LuaSocket.java:
--------------------------------------------------------------------------------
1 | package Thousand_Dust.socket;
2 |
3 | import luaj.LuaError;
4 | import luaj.LuaString;
5 | import luaj.LuaTable;
6 | import luaj.LuaValue;
7 | import luaj.Varargs;
8 | import luaj.lib.TwoArgFunction;
9 | import luaj.lib.VarArgFunction;
10 |
11 | import java.io.IOException;
12 | import java.io.OutputStream;
13 | import java.net.Socket;
14 |
15 | public class LuaSocket extends TwoArgFunction {
16 |
17 | @Override
18 | public LuaValue call(LuaValue arg1, LuaValue arg2) {
19 | LuaTable t = new LuaTable();
20 | t.set("new", new newSocket());
21 | arg2.set("Socket", t);
22 |
23 | return t;
24 | }
25 |
26 | class mSocket {
27 |
28 | private Socket socket;
29 |
30 | public Varargs get(Varargs arg) {
31 | try {
32 | socket = new Socket(arg.checkjstring(1), arg.checkint(2));
33 | } catch (IOException e) {
34 | throw new LuaError("来自Socket的错误:"+e.toString());
35 | }
36 |
37 | LuaTable t = new LuaTable();
38 | t.set("write", new Write());
39 |
40 | return t;
41 | }
42 |
43 | class Write extends VarArgFunction {
44 | @Override
45 | public Varargs invoke(Varargs args) {
46 | LuaString content = args.checkstring(1);
47 | OutputStream out = null;
48 | try {
49 | out = socket.getOutputStream();
50 | out.write(content.m_bytes, content.m_offset, content.m_length);
51 | out.flush();
52 | } catch (IOException e) {
53 | throw new LuaError("来自Socket.write:"+e.toString());
54 | } finally {
55 | try {
56 | if (out != null)
57 | out.close();
58 | } catch (IOException e) {
59 | }
60 | }
61 |
62 | return NONE;
63 | }
64 | }
65 |
66 | }
67 |
68 | class newSocket extends VarArgFunction {
69 | @Override
70 | public Varargs invoke(Varargs arg) {
71 | return new mSocket().get(arg);
72 | }
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/app/src/main/java/com/gg/function/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.gg.function;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 |
6 | public class MainActivity extends Activity {
7 |
8 | @Override
9 | protected void onCreate(Bundle savedInstanceState) {
10 | super.onCreate(savedInstanceState);
11 | }
12 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnahz77/GG-CustomizeFunction/0419d92aab270e562459c85fa90002cce5620d22/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnahz77/GG-CustomizeFunction/0419d92aab270e562459c85fa90002cce5620d22/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnahz77/GG-CustomizeFunction/0419d92aab270e562459c85fa90002cce5620d22/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnahz77/GG-CustomizeFunction/0419d92aab270e562459c85fa90002cce5620d22/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnahz77/GG-CustomizeFunction/0419d92aab270e562459c85fa90002cce5620d22/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnahz77/GG-CustomizeFunction/0419d92aab270e562459c85fa90002cce5620d22/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnahz77/GG-CustomizeFunction/0419d92aab270e562459c85fa90002cce5620d22/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnahz77/GG-CustomizeFunction/0419d92aab270e562459c85fa90002cce5620d22/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnahz77/GG-CustomizeFunction/0419d92aab270e562459c85fa90002cce5620d22/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnahz77/GG-CustomizeFunction/0419d92aab270e562459c85fa90002cce5620d22/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | GG-CustomizeFunction
3 | 用于创建可穿透事件悬浮窗,android版本12及以上才需要开启
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/accessibility_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/backup_rules.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
12 |
13 |
19 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | plugins {
3 | id 'com.android.application' version '7.2.1' apply false
4 | id 'com.android.library' version '7.2.1' apply false
5 | }
6 |
7 | task clean(type: Delete) {
8 | delete rootProject.buildDir
9 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Enables namespacing of each library's R class so that its R class includes only the
19 | # resources declared in the library itself and none from the library's dependencies,
20 | # thereby reducing the size of the R class for that library
21 | android.nonTransitiveRClass=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnahz77/GG-CustomizeFunction/0419d92aab270e562459c85fa90002cce5620d22/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sun Sep 25 21:54:28 CST 2022
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | gradlePluginPortal()
4 | google()
5 | mavenCentral()
6 | }
7 | }
8 | dependencyResolutionManagement {
9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
10 | repositories {
11 | google()
12 | mavenCentral()
13 | }
14 | }
15 | rootProject.name = "GG-CustomizeFunction"
16 | include ':app'
17 |
--------------------------------------------------------------------------------