Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

525
LINES

< > BotCompany Repo | #1033548 // Standalone Gazelle V, November Edition [backup]

JavaX source code (desktop) [tags: jar-with-libs no-compiler standalone use-pretranspiled]

Download Jar. Uses 2032K of libraries. Click here for Pure Java version (11364L/61K).

// WELCOME!! This is THE PROGRAM YOU ARE LOOKING FOR.

!7

lib 1400521 // FlatLAF

set flag PingV3.
set flag NotifyingPrintLog.

// Do the JavaX init
svoid standaloneInit {
  __javax = x30.class;
  x30.__javax = x30.class; // for hotwire
  x30_pkg.x30_util.__setJavaX(x30.class);
  x30.cleanKillMsg = "";
  callOnLoadMethods(mc());
}

sclass GazelleHost {
  S windowTitle = "November Gazelle v.5";
  S downloadURL = "https://botcompany.de/jar/" 
    + psI(programID()) + "?withLibs=1&noCompiler=1";
  sS trayIconImageID = #1103047;
  int borderSize = 5;
  Color color1 = awtColor("ADD8E6");
  Color color2 = awtColor("EEEEEE");
  Color color3 = awtColor("A3C0AA");
  IF0<DynModule> moduleMaker;
  ThreadPool threadPool;
  
  *(ThreadPool *threadPool, IF0<DynModule> *moduleMaker) {}

  class Stem {
    JFrame window;
    
    Rect getFrameRect() {
      ret toRect(getBounds(window));
    }
  }
  
  Stem stem;
  DynModule gazelle;
  TrayIcon trayIcon;
  JFrame mainWindow;
  Set<S> argsSet;
  
  void trayIconLeftClick {
    activateFrame_v3(mainWindow);
  }
  
  void makeTrayIcon {
    pcall-short {
      trayIcon_imageAutoSize = false;
      trayIcon = installTrayIcon(trayIconImageID, windowTitle,
        r trayIconLeftClick,
        "Show Gazelle", r { activateFrame(mainWindow) },
        "Exit Gazelle", r cleanExit
      );
    }
  }
  
  void run(S[] args) {
    argsSet = asSet(args);
    
    if (!argsSet.contains("noflatlaf"))
      com.formdev.flatlaf.FlatLightLaf.setup();
    
    if (contains(args, "profile"))
      profileToConsole(() -> actualMain(args));
    else
      actualMain(args);
      
    if (argsSet.contains("brexit")) System.exit(0);
  }
  
  void actualMain(S... args) {
    vm_generalMap_put(stefansOS := this);
    
    System.out.println(hmsWithColonsAndMS() + ": Init");
    //x30.coreInit();
    
    // Ready to roll
    
    if (containsOneOf(argsSet, "upgrade", "update"))
      ret with upgradeGazelle();
  
    makeTrayIcon();
    
    makeModule();
    
    stem = new Stem;
    gazelle._host = stem;
    copyLocalLog(gazelle, mc());
  
    JComponent vis;
    {
      temp gazelle.enter();
      gazelle.start();
    
      printWithMS("Visualize");
      vis = swing(-> {
        temp gazelle.enter();
        ret gazelle.visualize();
      });
    }
    
    vis = makeWindowBorderAndTitle(vis, windowTitle);
    printWithMS("Show frame");
    //stem.window = showMainFrame("Gazella", vis);
    JFrame frame = makeUndecoratedFrame(windowTitle, vis);
    setFrameIcon(frame, trayIconImageID);
    stem.window = mainWindow = frame;
    onWindowClosing(stem.window, r cleanExit);
    showWindow(stem.window);
    printWithMS("Dudadoneski");
  }
  
  void minimize {
    if (trayIcon == null)
      minimizeWindow(mainWindow);
    else
      hideWindow(mainWindow);
  }  
  
  JComponent makeWindowBorderAndTitle(JComponent contents, S title) {
    //ret jCenteredSection_fontSizePlus(10, title, vis);
    
    var icons = jline();
    icons.add(jbutton("Minimize", r minimize));
    icons.add(jbutton("Close", r { disposeWindow(icons) }));
    icons.add(jPopDownButton_noText(
      "Update Gazelle", rThread upgradeGazelle,
      "Dump threads", rThread { showText("User threads", renderUserThreadsWithStackTraces()); },
    ));
    
    var actualTitle = fontSizePlus(7, jCenteredLabel(title));
    var spacer = gazelle_wavySpacer();
    var titleBarMain = setOpaqueBackground(color1,
      westCenterAndEastWithMargin(
        jImage_scaledToHeight(24, trayIconImageID),
        actualTitle,
        setOpaqueBackground(color2, spacer));
    
    installWindowDragger(actualTitle);
    installWindowDragger(spacer);
    
    var titleBar = setBackground(color2, centerAndEast(
      titleBarMain,
      icons));
    
    var border =
      // createBevelBorder();
      BorderFactory.createLineBorder(color1, borderSize);
      
    var outerPanel = withBorder(border,
      northAndCenter(titleBar, contents));
      
    installWindowResizeDraggerOnBorder(outerPanel);
    ret outerPanel;
  }
  
  O dm_getStem(O moduleOrID) {
    ret stem;
  }
  
  O resolveModule(O moduleOrID) { ret moduleOrID == stem ? gazelle : moduleOrID; }
  
  void cleanExit {
    System.exit(0);
  }
  
  void upgradeGazelle {
    File myJar = getBytecodePathForClass(this);
    print(+myJar);
    
    S javaCmd = or2(currentProcessCommand(), "java");
    S date = ymdMinusHMS();
    File f = javaxCodeDir("Downloaded Updates/" + "gazelle-" + date + ".jar");
    infoBox("Downloading Update...");
    loadBinaryPageToFile(downloadURL, f);
    printFileInfo(f);
    if (!isNonEmptySingleZip_byMagicHeader(f))
      ret with  infoBox("Bad file downloaded... :(");
      
    bool replaced;
    if (isFile(myJar)) {
      print("Loaded " + nClasses(loadAllClassesInByteCodePath(myJar)));
      print("Replacing with new version: " + myJar);
      renameFile(myJar, appendToBaseName(myJar, ".bak." + date));
      copyFile(f, myJar);
      printFileInfo(myJar);
      set replaced;
    }
      
    infoBox(replaced
      ? "Installed update, replaced " + f2s(myJar) + " - now starting"
      : "Starting update, but could not replace originally downloaded jar");
    S cmd = pqO(javaCmd) + " -jar " + pqO(replaced ? myJar : f);
    print(cmd);
    nohup(cmd);
    cleanExit();
  }
  
  void makeModule() {
    if (gazelle == null)
      gazelle = callF(moduleMaker);
  }
}

!include early #1033506 // Compact Module Include Gazelle V

module GazelleV > DynPrintLogAndEnabled {
  /*switchable int x1;
  switchable int y1;
  switchable int w = screenWidth();
  switchable int h = screenHeight();*/
  switchable double maxFPS = 10;
  switchable int previewWidth = 200;
  switchable double statsEvery = 5;
  switchable volatile bool brokenMethod;
  int lookAtScreen;
  S previewMode;
  int gridRows = 20;

  PersistableThrowable lastProcessingError;
  transient WithTimestamp<OKOrError<BufferedImage>> lastScreen;
  transient new Average screenShotTime;
  transient new Average iiTime;
  transient Timestamp loopStarted;
  transient new RestartableCountdown screenShotCountdown;
  //transient ImageSurface imageSurface;
  transient IIImageSurface imageSurface;
  transient Throwable currentProcessingError;
  transient BufferedImage previewImage;
  transient JButton popDownButton;
  transient JComponent topControls;
  transient long screenShotsTaken;
  transient double fps;
  transient Compression ongoingCompression, completedCompression;
  transient S longTermCompressionProbability;
  transient S longTermCompressionScore;
  transient JComponent topControls2;
  transient JTabbedPane tabs;
  transient ThreadPool threadPool;

  Rect area() {
    ret screenBounds(min(lookAtScreen, screenCount()-1));
  }

  class Compression {
    settable BufferedImage image;
    settable BWIntegralImage ii;
    CompressionSearch_AnyType search;
    int baseLineLength; // length of trivial compression
    GridCodec1 codec;
    double compressionPercentage;

    S score() {
      var submission = search?.bestSubmission();
      Int compressedSize = or(submission.compressedSize(), baseLineLength);
      compressionPercentage = doubleRatio(compressedSize, baseLineLength)*100;
      ret formatDouble(compressionPercentage, 3) + "%";
    }

    IProbabilisticScheduler scheduler() {
      ret search?.scheduler();
    }

    S probability() {
      var scheduler = scheduler();
      if (scheduler == null) ret "-";
      var prob = scheduler.lastExecutedProbability();
      ret formatDouble(prob, 3);
    }

    event compressionDone;
      
    run {
      int lHex = pixelCount(image)*8;
      baseLineLength = calculateLengthOfFunctionCall imageFromHex(lHex+2);
      print(+baseLineLength);

      codec = new GridCodec1(image);
      codec.rows = gridRows;
      search = codec.forward();
      //showImage(codec.renderCellsLinearly());

      thread "Gazelle Visual" {
        repeat 60 {
          stepForNSeconds(1, search);
          //print(stepCount := search.scheduler().stepCount());
          setFields(
            longTermCompressionProbability := probability(),
            longTermCompressionScore := score());
        }

        try {
          compressionDone();
          
          L<IJavaExpr> cellCompressions = codec.strat.codeForElements();
          //showText("Compression", lines(map shorten_str(cellCompressions)));

          /*S code = str(codec.winnerCode());
          S name = "Screenshot " + ymdMinusHMS();
          File f = makeFileNameUnique_beforeExtension(
            javaxDataDir("Compressed Screenshots/" + name + ".javax"));
          saveTextFile(f, code);
          printFileInfo(f);          
          saveGZTextFile(f = replaceExtension(f, ".jgz"), code);
          printFileInfo(f);*/

          /*
          print("Evaling " + nChars(code));
          //LL<Int> lol = cast dm_javaEval(code);
          BufferedImage restored = cast dm_javaEval(code);
          assertImagesIdentical(restored, image);
          print("Image restored!");

          dm_showImage("Restored from " + nChars(code), restored);
          */
        } catch e { printStackTrace(e); }
      }
    }
    
    void drawOverlay(ImageSurface is, Graphics2D g) pcall {
      codec.drawOverlay(is, g);
    }
  }
  
  start {
    componentFieldsToKeep = litset("tabs");
    
    dm_registerAs_direct gazelleV();
    dm_watchField enabled(r { if (enabled) dm_reload(); });

    // TODO: react to event sent by OS
    dm_doEvery(1.0, r {
      if (dm_moduleIsPoppedOut()) adjustUIForPoppedOutWindow();
    });
    
    print("Screen bounds: " + allScreenBounds());
    
    // We are making some UI elements even if the module is hidden
    // because that's easier.
    
    tabs = jtabs(
      "Log", super.visualize(),
      "Local Data", jcenteredlabel("TODO"));

    dm_doEvery(min(statsEvery, 10.0), statsEvery, r { if (enabled) printStats(); });
    
    threadPool.do("Start Loop", rEnter {
      ping();
      loopStarted = tsNow();
      shoot();
    });
  }

  void shoot enter {
    if (!enabled) ret;
    
    long targetTime = sysNow()+iround(1000/maxFPS);
    long time = nanoTime();

    try {
      lastScreen = withTimestamp(okOrError(-> screenshot(area())));
      ++screenShotsTaken;
      setField(fps := doubleRatio(screenShotsTaken, elapsedSeconds(loopStarted)));
      screenShotTime.add(nanosToSeconds(nanoTime()-time));
      time = nanoTime();
      if (lastScreen->isOK()) {
        var img = lastScreen!!;
        var ii = BWIntegralImage(img);
        //var ii = BWIntegralImage_luminosity(lastScreen!!);
        iiTime.add(nanosToSeconds(nanoTime()-time));
      
        if (eq(previewMode, "showLatestGrabbed"))
          imageSurface?.setImage(ii, img);

        if (ongoingCompression == null)
          startCompression(ii);
      }
      
      cpuTotal();
      currentProcessingError = null;
    } catch print e {
      setField(lastProcessingError := currentProcessingError = e);
      sleepSeconds(60); // errors in processing are no good
    }
    
    screenShotCountdown.setTargetTime(targetTime, r shoot);
  }

  void startCompression(BWIntegralImage ii) {  
    if (ongoingCompression == null) {
      ongoingCompression = new Compression()
        .image(lastScreen!!)
        .ii(ii);
      ongoingCompression.onCompressionDone(-> {
        completedCompression = ongoingCompression;
        ongoingCompression = null;
        
        imageSurface?.setImage(completedCompression.ii, completedCompression.image);
        imageSurface.setOverlay(g -> completedCompression.drawOverlay(imageSurface, g));
      });
      ongoingCompression.run();
    }
  }

  void printStats() { print(stats()); }

  S stats() {
    var screen = lastScreen?!;
    ret formatColonProperties_noNulls(
      "Monitored area", area(),
      "Error", screen?.getError(),
      "Last screenshot taken", lastScreen?.timeStamp(),
      "Average time to take a screenshot", screenShotTime,
      "Average time to make integral image", iiTime,
      "Capacity left in first core", percentRatioStrOneDigit(freeInCore()),
      "Total CPU used", cpuTotal(),
    );
  }

  S cpuTotal() {
    ret setFieldAndReturn(cpuTotal := percentRatioStrOneDigit((1-freeInCore())/numberOfCores()));
  }

  double freeInCore() {
    ret ratio(toSeconds(screenShotCountdown.totalSleepTime),
      elapsedSeconds(loopStarted));
  }

  replace jSection with jCenteredSection.  
  {}
  visualize {
    imageSurface = new IIImageSurface;
    setDoubleBuffered(imageSurface, true);
    imageSurface.noAlpha = true;
    
    var screenSelectors = jRadioButtons(
      countIteratorAsList(screenCount(),
        i -> "Screen " + (i+1)));
    onRadioButtonChange(screenSelectors, i -> { lookAtScreen = i; });
    
    ret hsplit(northAndCenterWithMargin(
      topControls = hgrid(
        jSection("FPS", dm_calculatedCenteredLabel(() -> iround(fps))),
        jSection("Compression", dm_centeredFieldLabel longTermCompressionScore()),
        jSection("Probability", dm_centeredFieldLabel longTermCompressionProbability()),
        jSection("CPU (" + numberOfCores() + ")", dm_centeredFieldLabel cpuTotal())
      ),
      tabs),
      northAndCenterWithMargin(
        topControls2 = jCenteredLine(listPlus(wideningListCast Component(buttonsInGroup(screenSelectors)),
          dm_spinnerWithLabel gridRows(1, 500))),
        jscroll_center(imageSurface)));
  }
  
  BufferedImage lastScreenImage() { ret getVar(getVar(lastScreen)); }

  void adjustUIForPoppedOutWindow swing {
    if (popDownButton == null) {
      Window window = cast getWindow(dm_vis());

      var popBackInButton = findButton(window, "Pop Back In");
      var parent = getParent(popBackInButton);
      print(+parent);
      
      removeFromParent(parent); // hide controls
      
      popDownButton = jPopDownButton_noText(
        "Pop Back In", r { dm_popInModule(me()) },
        jCheckBoxMenuItem("Always On Top", isAlwaysOnTop(window),
          rEnter dm_toggleAlwaysOnTop),
      );
      addControl(popDownButton);      
    }
  }
  
  public bool useErrorHandling() { false; }
}

sS windowTitle = "November Gazelle v1";
sS progIDForAutoUpdate = #1033525;
sbool pingSourceStrictMode;

static GazelleHost host;
static GazelleV client;
static ThreadPool threadPool;

p {
  loadableUtils.utils.__setJavaX(x30.class);
  standaloneInit();
  
  ping_v3_setPingSourceMaker(-> {
    System.out.println("pingSourceMaker");
    if (pingSourceStrictMode)
      fail("Strict mode - make a ping source first!!");
    ret new PingSource(threadPool, "legacy");
  });
  
  threadPool = new ThreadPool(findIntArg cores(args, numberOfCores()));
  print(threadPool);
  threadPool.verbose = true;
  PingSource ps = new(threadPool, print("Starting Gazelle"));
  ps.do(-> {
    System.out.println("Pinging");
    ping();
    //if (true) fail("error test");
  
    print("Pinged");
    
    programID = progIDForAutoUpdate;
      
    host = new GazelleHost(threadPool, -> {
      new GazelleV g;
      g.threadPool = threadPool();
      ret client = g;
    });
    host.windowTitle = windowTitle;
    host.run(args);
  });
  print("aha.");
}

Author comment

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: 278 / 761
Version history: 2 change(s)
Referenced in: [show references]