Download Jar. Uses 2032K of libraries. Click here for Pure Java version (11364L/61K).
1 | // WELCOME!! This is THE PROGRAM YOU ARE LOOKING FOR. |
2 | |
3 | !7 |
4 | |
5 | lib 1400521 // FlatLAF |
6 | |
7 | set flag PingV3. |
8 | set flag NotifyingPrintLog. |
9 | |
10 | // Do the JavaX init |
11 | svoid standaloneInit { |
12 | __javax = x30.class; |
13 | x30.__javax = x30.class; // for hotwire |
14 | x30_pkg.x30_util.__setJavaX(x30.class); |
15 | x30.cleanKillMsg = ""; |
16 | callOnLoadMethods(mc()); |
17 | } |
18 | |
19 | sclass GazelleHost { |
20 | S windowTitle = "November Gazelle v.5"; |
21 | S downloadURL = "https://botcompany.de/jar/" |
22 | + psI(programID()) + "?withLibs=1&noCompiler=1"; |
23 | sS trayIconImageID = #1103047; |
24 | int borderSize = 5; |
25 | Color color1 = awtColor("ADD8E6"); |
26 | Color color2 = awtColor("EEEEEE"); |
27 | Color color3 = awtColor("A3C0AA"); |
28 | IF0<DynModule> moduleMaker; |
29 | ThreadPool threadPool; |
30 | |
31 | *(ThreadPool *threadPool, IF0<DynModule> *moduleMaker) {} |
32 | |
33 | class Stem { |
34 | JFrame window; |
35 | |
36 | Rect getFrameRect() { |
37 | ret toRect(getBounds(window)); |
38 | } |
39 | } |
40 | |
41 | Stem stem; |
42 | DynModule gazelle; |
43 | TrayIcon trayIcon; |
44 | JFrame mainWindow; |
45 | Set<S> argsSet; |
46 | |
47 | void trayIconLeftClick { |
48 | activateFrame_v3(mainWindow); |
49 | } |
50 | |
51 | void makeTrayIcon { |
52 | pcall-short { |
53 | trayIcon_imageAutoSize = false; |
54 | trayIcon = installTrayIcon(trayIconImageID, windowTitle, |
55 | r trayIconLeftClick, |
56 | "Show Gazelle", r { activateFrame(mainWindow) }, |
57 | "Exit Gazelle", r cleanExit |
58 | ); |
59 | } |
60 | } |
61 | |
62 | void run(S[] args) { |
63 | argsSet = asSet(args); |
64 | |
65 | if (!argsSet.contains("noflatlaf")) |
66 | com.formdev.flatlaf.FlatLightLaf.setup(); |
67 | |
68 | if (contains(args, "profile")) |
69 | profileToConsole(() -> actualMain(args)); |
70 | else |
71 | actualMain(args); |
72 | |
73 | if (argsSet.contains("brexit")) System.exit(0); |
74 | } |
75 | |
76 | void actualMain(S... args) { |
77 | vm_generalMap_put(stefansOS := this); |
78 | |
79 | System.out.println(hmsWithColonsAndMS() + ": Init"); |
80 | //x30.coreInit(); |
81 | |
82 | // Ready to roll |
83 | |
84 | if (containsOneOf(argsSet, "upgrade", "update")) |
85 | ret with upgradeGazelle(); |
86 | |
87 | makeTrayIcon(); |
88 | |
89 | makeModule(); |
90 | |
91 | stem = new Stem; |
92 | gazelle._host = stem; |
93 | copyLocalLog(gazelle, mc()); |
94 | |
95 | JComponent vis; |
96 | { |
97 | temp gazelle.enter(); |
98 | gazelle.start(); |
99 | |
100 | printWithMS("Visualize"); |
101 | vis = swing(-> { |
102 | temp gazelle.enter(); |
103 | ret gazelle.visualize(); |
104 | }); |
105 | } |
106 | |
107 | vis = makeWindowBorderAndTitle(vis, windowTitle); |
108 | printWithMS("Show frame"); |
109 | //stem.window = showMainFrame("Gazella", vis); |
110 | JFrame frame = makeUndecoratedFrame(windowTitle, vis); |
111 | setFrameIcon(frame, trayIconImageID); |
112 | stem.window = mainWindow = frame; |
113 | onWindowClosing(stem.window, r cleanExit); |
114 | showWindow(stem.window); |
115 | printWithMS("Dudadoneski"); |
116 | } |
117 | |
118 | void minimize { |
119 | if (trayIcon == null) |
120 | minimizeWindow(mainWindow); |
121 | else |
122 | hideWindow(mainWindow); |
123 | } |
124 | |
125 | JComponent makeWindowBorderAndTitle(JComponent contents, S title) { |
126 | //ret jCenteredSection_fontSizePlus(10, title, vis); |
127 | |
128 | var icons = jline(); |
129 | icons.add(jbutton("Minimize", r minimize)); |
130 | icons.add(jbutton("Close", r { disposeWindow(icons) })); |
131 | icons.add(jPopDownButton_noText( |
132 | "Update Gazelle", rThread upgradeGazelle, |
133 | "Dump threads", rThread { showText("User threads", renderUserThreadsWithStackTraces()); }, |
134 | )); |
135 | |
136 | var actualTitle = fontSizePlus(7, jCenteredLabel(title)); |
137 | var spacer = gazelle_wavySpacer(); |
138 | var titleBarMain = setOpaqueBackground(color1, |
139 | westCenterAndEastWithMargin( |
140 | jImage_scaledToHeight(24, trayIconImageID), |
141 | actualTitle, |
142 | setOpaqueBackground(color2, spacer)); |
143 | |
144 | installWindowDragger(actualTitle); |
145 | installWindowDragger(spacer); |
146 | |
147 | var titleBar = setBackground(color2, centerAndEast( |
148 | titleBarMain, |
149 | icons)); |
150 | |
151 | var border = |
152 | // createBevelBorder(); |
153 | BorderFactory.createLineBorder(color1, borderSize); |
154 | |
155 | var outerPanel = withBorder(border, |
156 | northAndCenter(titleBar, contents)); |
157 | |
158 | installWindowResizeDraggerOnBorder(outerPanel); |
159 | ret outerPanel; |
160 | } |
161 | |
162 | O dm_getStem(O moduleOrID) { |
163 | ret stem; |
164 | } |
165 | |
166 | O resolveModule(O moduleOrID) { ret moduleOrID == stem ? gazelle : moduleOrID; } |
167 | |
168 | void cleanExit { |
169 | System.exit(0); |
170 | } |
171 | |
172 | void upgradeGazelle { |
173 | File myJar = getBytecodePathForClass(this); |
174 | print(+myJar); |
175 | |
176 | S javaCmd = or2(currentProcessCommand(), "java"); |
177 | S date = ymdMinusHMS(); |
178 | File f = javaxCodeDir("Downloaded Updates/" + "gazelle-" + date + ".jar"); |
179 | infoBox("Downloading Update..."); |
180 | loadBinaryPageToFile(downloadURL, f); |
181 | printFileInfo(f); |
182 | if (!isNonEmptySingleZip_byMagicHeader(f)) |
183 | ret with infoBox("Bad file downloaded... :("); |
184 | |
185 | bool replaced; |
186 | if (isFile(myJar)) { |
187 | print("Loaded " + nClasses(loadAllClassesInByteCodePath(myJar))); |
188 | print("Replacing with new version: " + myJar); |
189 | renameFile(myJar, appendToBaseName(myJar, ".bak." + date)); |
190 | copyFile(f, myJar); |
191 | printFileInfo(myJar); |
192 | set replaced; |
193 | } |
194 | |
195 | infoBox(replaced |
196 | ? "Installed update, replaced " + f2s(myJar) + " - now starting" |
197 | : "Starting update, but could not replace originally downloaded jar"); |
198 | S cmd = pqO(javaCmd) + " -jar " + pqO(replaced ? myJar : f); |
199 | print(cmd); |
200 | nohup(cmd); |
201 | cleanExit(); |
202 | } |
203 | |
204 | void makeModule() { |
205 | if (gazelle == null) |
206 | gazelle = callF(moduleMaker); |
207 | } |
208 | } |
209 | |
210 | !include early #1033506 // Compact Module Include Gazelle V |
211 | |
212 | module GazelleV > DynPrintLogAndEnabled { |
213 | /*switchable int x1; |
214 | switchable int y1; |
215 | switchable int w = screenWidth(); |
216 | switchable int h = screenHeight();*/ |
217 | switchable double maxFPS = 10; |
218 | switchable int previewWidth = 200; |
219 | switchable double statsEvery = 5; |
220 | switchable volatile bool brokenMethod; |
221 | int lookAtScreen; |
222 | S previewMode; |
223 | int gridRows = 20; |
224 | |
225 | PersistableThrowable lastProcessingError; |
226 | transient WithTimestamp<OKOrError<BufferedImage>> lastScreen; |
227 | transient new Average screenShotTime; |
228 | transient new Average iiTime; |
229 | transient Timestamp loopStarted; |
230 | transient new RestartableCountdown screenShotCountdown; |
231 | //transient ImageSurface imageSurface; |
232 | transient IIImageSurface imageSurface; |
233 | transient Throwable currentProcessingError; |
234 | transient BufferedImage previewImage; |
235 | transient JButton popDownButton; |
236 | transient JComponent topControls; |
237 | transient long screenShotsTaken; |
238 | transient double fps; |
239 | transient Compression ongoingCompression, completedCompression; |
240 | transient S longTermCompressionProbability; |
241 | transient S longTermCompressionScore; |
242 | transient JComponent topControls2; |
243 | transient JTabbedPane tabs; |
244 | transient ThreadPool threadPool; |
245 | |
246 | Rect area() { |
247 | ret screenBounds(min(lookAtScreen, screenCount()-1)); |
248 | } |
249 | |
250 | class Compression { |
251 | settable BufferedImage image; |
252 | settable BWIntegralImage ii; |
253 | CompressionSearch_AnyType search; |
254 | int baseLineLength; // length of trivial compression |
255 | GridCodec1 codec; |
256 | double compressionPercentage; |
257 | |
258 | S score() { |
259 | var submission = search?.bestSubmission(); |
260 | Int compressedSize = or(submission.compressedSize(), baseLineLength); |
261 | compressionPercentage = doubleRatio(compressedSize, baseLineLength)*100; |
262 | ret formatDouble(compressionPercentage, 3) + "%"; |
263 | } |
264 | |
265 | IProbabilisticScheduler scheduler() { |
266 | ret search?.scheduler(); |
267 | } |
268 | |
269 | S probability() { |
270 | var scheduler = scheduler(); |
271 | if (scheduler == null) ret "-"; |
272 | var prob = scheduler.lastExecutedProbability(); |
273 | ret formatDouble(prob, 3); |
274 | } |
275 | |
276 | event compressionDone; |
277 | |
278 | run { |
279 | int lHex = pixelCount(image)*8; |
280 | baseLineLength = calculateLengthOfFunctionCall imageFromHex(lHex+2); |
281 | print(+baseLineLength); |
282 | |
283 | codec = new GridCodec1(image); |
284 | codec.rows = gridRows; |
285 | search = codec.forward(); |
286 | //showImage(codec.renderCellsLinearly()); |
287 | |
288 | thread "Gazelle Visual" { |
289 | repeat 60 { |
290 | stepForNSeconds(1, search); |
291 | //print(stepCount := search.scheduler().stepCount()); |
292 | setFields( |
293 | longTermCompressionProbability := probability(), |
294 | longTermCompressionScore := score()); |
295 | } |
296 | |
297 | try { |
298 | compressionDone(); |
299 | |
300 | L<IJavaExpr> cellCompressions = codec.strat.codeForElements(); |
301 | //showText("Compression", lines(map shorten_str(cellCompressions))); |
302 | |
303 | /*S code = str(codec.winnerCode()); |
304 | S name = "Screenshot " + ymdMinusHMS(); |
305 | File f = makeFileNameUnique_beforeExtension( |
306 | javaxDataDir("Compressed Screenshots/" + name + ".javax")); |
307 | saveTextFile(f, code); |
308 | printFileInfo(f); |
309 | saveGZTextFile(f = replaceExtension(f, ".jgz"), code); |
310 | printFileInfo(f);*/ |
311 | |
312 | /* |
313 | print("Evaling " + nChars(code)); |
314 | //LL<Int> lol = cast dm_javaEval(code); |
315 | BufferedImage restored = cast dm_javaEval(code); |
316 | assertImagesIdentical(restored, image); |
317 | print("Image restored!"); |
318 | |
319 | dm_showImage("Restored from " + nChars(code), restored); |
320 | */ |
321 | } catch e { printStackTrace(e); } |
322 | } |
323 | } |
324 | |
325 | void drawOverlay(ImageSurface is, Graphics2D g) pcall { |
326 | codec.drawOverlay(is, g); |
327 | } |
328 | } |
329 | |
330 | start { |
331 | componentFieldsToKeep = litset("tabs"); |
332 | |
333 | dm_registerAs_direct gazelleV(); |
334 | dm_watchField enabled(r { if (enabled) dm_reload(); }); |
335 | |
336 | // TODO: react to event sent by OS |
337 | dm_doEvery(1.0, r { |
338 | if (dm_moduleIsPoppedOut()) adjustUIForPoppedOutWindow(); |
339 | }); |
340 | |
341 | print("Screen bounds: " + allScreenBounds()); |
342 | |
343 | // We are making some UI elements even if the module is hidden |
344 | // because that's easier. |
345 | |
346 | tabs = jtabs( |
347 | "Log", super.visualize(), |
348 | "Local Data", jcenteredlabel("TODO")); |
349 | |
350 | dm_doEvery(min(statsEvery, 10.0), statsEvery, r { if (enabled) printStats(); }); |
351 | |
352 | threadPool.do("Start Loop", rEnter { |
353 | ping(); |
354 | loopStarted = tsNow(); |
355 | shoot(); |
356 | }); |
357 | } |
358 | |
359 | void shoot enter { |
360 | if (!enabled) ret; |
361 | |
362 | long targetTime = sysNow()+iround(1000/maxFPS); |
363 | long time = nanoTime(); |
364 | |
365 | try { |
366 | lastScreen = withTimestamp(okOrError(-> screenshot(area()))); |
367 | ++screenShotsTaken; |
368 | setField(fps := doubleRatio(screenShotsTaken, elapsedSeconds(loopStarted))); |
369 | screenShotTime.add(nanosToSeconds(nanoTime()-time)); |
370 | time = nanoTime(); |
371 | if (lastScreen->isOK()) { |
372 | var img = lastScreen!!; |
373 | var ii = BWIntegralImage(img); |
374 | //var ii = BWIntegralImage_luminosity(lastScreen!!); |
375 | iiTime.add(nanosToSeconds(nanoTime()-time)); |
376 | |
377 | if (eq(previewMode, "showLatestGrabbed")) |
378 | imageSurface?.setImage(ii, img); |
379 | |
380 | if (ongoingCompression == null) |
381 | startCompression(ii); |
382 | } |
383 | |
384 | cpuTotal(); |
385 | currentProcessingError = null; |
386 | } catch print e { |
387 | setField(lastProcessingError := currentProcessingError = e); |
388 | sleepSeconds(60); // errors in processing are no good |
389 | } |
390 | |
391 | screenShotCountdown.setTargetTime(targetTime, r shoot); |
392 | } |
393 | |
394 | void startCompression(BWIntegralImage ii) { |
395 | if (ongoingCompression == null) { |
396 | ongoingCompression = new Compression() |
397 | .image(lastScreen!!) |
398 | .ii(ii); |
399 | ongoingCompression.onCompressionDone(-> { |
400 | completedCompression = ongoingCompression; |
401 | ongoingCompression = null; |
402 | |
403 | imageSurface?.setImage(completedCompression.ii, completedCompression.image); |
404 | imageSurface.setOverlay(g -> completedCompression.drawOverlay(imageSurface, g)); |
405 | }); |
406 | ongoingCompression.run(); |
407 | } |
408 | } |
409 | |
410 | void printStats() { print(stats()); } |
411 | |
412 | S stats() { |
413 | var screen = lastScreen?!; |
414 | ret formatColonProperties_noNulls( |
415 | "Monitored area", area(), |
416 | "Error", screen?.getError(), |
417 | "Last screenshot taken", lastScreen?.timeStamp(), |
418 | "Average time to take a screenshot", screenShotTime, |
419 | "Average time to make integral image", iiTime, |
420 | "Capacity left in first core", percentRatioStrOneDigit(freeInCore()), |
421 | "Total CPU used", cpuTotal(), |
422 | ); |
423 | } |
424 | |
425 | S cpuTotal() { |
426 | ret setFieldAndReturn(cpuTotal := percentRatioStrOneDigit((1-freeInCore())/numberOfCores())); |
427 | } |
428 | |
429 | double freeInCore() { |
430 | ret ratio(toSeconds(screenShotCountdown.totalSleepTime), |
431 | elapsedSeconds(loopStarted)); |
432 | } |
433 | |
434 | replace jSection with jCenteredSection. |
435 | {} |
436 | visualize { |
437 | imageSurface = new IIImageSurface; |
438 | setDoubleBuffered(imageSurface, true); |
439 | imageSurface.noAlpha = true; |
440 | |
441 | var screenSelectors = jRadioButtons( |
442 | countIteratorAsList(screenCount(), |
443 | i -> "Screen " + (i+1))); |
444 | onRadioButtonChange(screenSelectors, i -> { lookAtScreen = i; }); |
445 | |
446 | ret hsplit(northAndCenterWithMargin( |
447 | topControls = hgrid( |
448 | jSection("FPS", dm_calculatedCenteredLabel(() -> iround(fps))), |
449 | jSection("Compression", dm_centeredFieldLabel longTermCompressionScore()), |
450 | jSection("Probability", dm_centeredFieldLabel longTermCompressionProbability()), |
451 | jSection("CPU (" + numberOfCores() + ")", dm_centeredFieldLabel cpuTotal()) |
452 | ), |
453 | tabs), |
454 | northAndCenterWithMargin( |
455 | topControls2 = jCenteredLine(listPlus(wideningListCast Component(buttonsInGroup(screenSelectors)), |
456 | dm_spinnerWithLabel gridRows(1, 500))), |
457 | jscroll_center(imageSurface))); |
458 | } |
459 | |
460 | BufferedImage lastScreenImage() { ret getVar(getVar(lastScreen)); } |
461 | |
462 | void adjustUIForPoppedOutWindow swing { |
463 | if (popDownButton == null) { |
464 | Window window = cast getWindow(dm_vis()); |
465 | |
466 | var popBackInButton = findButton(window, "Pop Back In"); |
467 | var parent = getParent(popBackInButton); |
468 | print(+parent); |
469 | |
470 | removeFromParent(parent); // hide controls |
471 | |
472 | popDownButton = jPopDownButton_noText( |
473 | "Pop Back In", r { dm_popInModule(me()) }, |
474 | jCheckBoxMenuItem("Always On Top", isAlwaysOnTop(window), |
475 | rEnter dm_toggleAlwaysOnTop), |
476 | ); |
477 | addControl(popDownButton); |
478 | } |
479 | } |
480 | |
481 | public bool useErrorHandling() { false; } |
482 | } |
483 | |
484 | sS windowTitle = "November Gazelle v1"; |
485 | sS progIDForAutoUpdate = #1033525; |
486 | sbool pingSourceStrictMode; |
487 | |
488 | static GazelleHost host; |
489 | static GazelleV client; |
490 | static ThreadPool threadPool; |
491 | |
492 | p { |
493 | loadableUtils.utils.__setJavaX(x30.class); |
494 | standaloneInit(); |
495 | |
496 | ping_v3_setPingSourceMaker(-> { |
497 | System.out.println("pingSourceMaker"); |
498 | if (pingSourceStrictMode) |
499 | fail("Strict mode - make a ping source first!!"); |
500 | ret new PingSource(threadPool, "legacy"); |
501 | }); |
502 | |
503 | threadPool = new ThreadPool(findIntArg cores(args, numberOfCores())); |
504 | print(threadPool); |
505 | threadPool.verbose = true; |
506 | PingSource ps = new(threadPool, print("Starting Gazelle")); |
507 | ps.do(-> { |
508 | System.out.println("Pinging"); |
509 | ping(); |
510 | //if (true) fail("error test"); |
511 | |
512 | print("Pinged"); |
513 | |
514 | programID = progIDForAutoUpdate; |
515 | |
516 | host = new GazelleHost(threadPool, -> { |
517 | new GazelleV g; |
518 | g.threadPool = threadPool(); |
519 | ret client = g; |
520 | }); |
521 | host.windowTitle = windowTitle; |
522 | host.run(args); |
523 | }); |
524 | print("aha."); |
525 | } |
Began life as a copy of #1033525
download show line numbers debug dex old transpilations
Travelled to 2 computer(s): bhatertpkbcr, mqqgnosmbjvj
No comments. add comment
Snippet ID: | #1033548 |
Snippet name: | Standalone Gazelle V, November Edition [backup] |
Eternal ID of this version: | #1033548/3 |
Text MD5: | 90d0dc15dc89fe434b3e4f6b906d159a |
Transpilation MD5: | a73b1f43a83003d0af1d5f3abf487a04 |
Author: | stefan |
Category: | javax / screen recognition |
Type: | JavaX source code (desktop) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2021-11-02 03:58:52 |
Source code size: | 15663 bytes / 525 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 280 / 767 |
Version history: | 2 change(s) |
Referenced in: | [show references] |