Snippets
Dieser Abschnitt enthält drei nützliche Code-Snippets für LightScripts: Meter, State-Handler und Effect-Handler.
Der Meter
Abschnitt betitelt „Der Meter“Als Fortsetzung des vorherigen Abschnitts ist die Meter-Klasse dafür konzipiert, bedeutsame Änderungen in instabilen Meter-Daten zu verfolgen. Sie fungiert wie ein Bremspedal für den Code – selbst in komplexen Bereichen sorgt sie für Stabilität. Jeder Meter speichert ein anpassbares Array von Werten, die bei jedem Durchlauf der Update-Funktion gesammelt werden. Wenn alle Werte im Array gleich sind (d. h. die Daten sind “stabil”), aktualisiert der Meter seinen Wert und löst eine verknüpfte Callback-Funktion aus, um einen Effekt zu aktivieren.
| Methode | Beschreibung |
|---|---|
| Meter(size, callback) | Der Konstruktor akzeptiert sowohl eine size als auch einen callback.\n\n\n\nsize – die Anzahl der Male, wie oft ein identischer Wert vorhanden sein muss, damit der Meter-Wert als “stabil” genug gilt, um verarbeitet zu werden. Höhere Werte führen zu mehr Genauigkeit, niedrigere Werte zu weniger Latenz.\n\n\ncallback – eine Funktion, die aufgerufen wird, wenn der Meter-Wert stabil ist und sich geändert hat. |
| Meter.setValue(value) | setValue(value) sollte jeden Frame aufgerufen werden oder jedes Mal, wenn neue Rohdaten für diesen Meter verfügbar sind. |
Der Prozess der Bildschirmdatenerfassung sollte im Allgemeinen dieser Struktur folgen:
- Der engine.vision.meter-Wert wird anhand neuer Daten vom Bildschirm aktualisiert.
- Innerhalb der Update-Funktion wird Meter.setValue(engine.vision.meter) aufgerufen, um den neuen Wert aufzuzeichnen.
- Der Meter überprüft sein internes Array, ob alle Werte identisch sind. Wenn ja, aktualisiert er seinen eigenen Zustand und führt die zugewiesene Callback-Funktion aus.
- Die Callback-Funktion bewertet dann spezifische Bedingungen anhand der Meter-Variablen und führt den Code aus, wenn diese Bedingungen erfüllt sind.
WICHTIGER HINWEIS:
Callbacks nicht überspringen. Da die Update-Funktion kontinuierlich läuft, muss sie so effizient wie möglich bleiben. Ihre primäre Rolle sollte darin bestehen, Meter-Werte zu aktualisieren. Das Verketten von Bedingungen innerhalb von update, um Meter zu überprüfen und Effekte auszulösen, sollte vermieden werden, da dies bei jedem Zyklus zu unnötigen Überprüfungen führt. Stattdessen Effekte in separaten Funktionen definieren und sie als Callbacks in den Meter übergeben.
Meter-Variablen
Abschnitt betitelt „Meter-Variablen“Wenn stabil, stellt der Meter seiner Callback-Funktion einige Werte zur Verfügung:
| Variable | Beschreibung |
|---|---|
| Meter.value | Der aktuelle Wert des Meters. |
| Meter.increased | Ein Boolean, der angibt, ob der Wert in diesem Update gestiegen ist |
| Meter.decreased | Ein Boolean, der angibt, ob der Wert in diesem Update gesunken ist |
| Meter.diff | Der absolute Wert der Änderung, die der Meter in diesem Update erfahren hat. |
Meter-Beispiel
Abschnitt betitelt „Meter-Beispiel“Hier ist ein einfaches Einzelmeter-Setup einschließlich des Meter-Klassen-Codes:
<head> <title>Meter Example</title> <meta description="Step-by-step metering" /> <meta meter="health" tags="vlc,fortnite" x= ".05" y=".9" width=".189" h="70-140" s="40-100" l="40-100" type="linear" /></head>
<body style="margin: 0; padding: 0; background: #000;"> <canvas id="exCanvas" width="320" height="200"></canvas></body>
<script> var c = document.getElementById("exCanvas"); var ctx = c.getContext("2d");
// Meter initialisieren var healthMeter = new Meter(5, healthEffect);
function update(){ // Meter-Werte aktualisieren healthMeter.setValue(engine.vision.health);
window.requestAnimationFrame(update); }
function healthEffect(){ if(healthMeter.increased){ // Effekt auslösen } else if (healthMeter.value == 0){ // Effekt auslösen } else if (healthMeter.diff > .3){ // Effekt auslösen } }
function Meter(size, callback) { this.size = size; this.value = 0; this.diff = 0; this.increased = false; this.decreased = false; var values = [];
this.setValue = function (updatedValue) { // Hinzufügen und verschieben. values.push(updatedValue); if (values.length > this.size) { values.shift(); }
// Frühzeitig beenden, wenn keine langfristige Übereinstimmung vorliegt. for (var i = 0; i < values.length - 1; i++) { if (values[i] !== values[i + 1]) return; }
// Hier angekommen, liegt eine übereinstimmende Wertsammlung vor. Variablen setzen und Callback ausführen. if (this.value !== values[0]) { this.diff = Math.abs(this.value - values[0]); this.increased = this.value < values[0]; this.decreased = this.value > values[0]; this.value = values[0]; callback(); } }; }
window.requestAnimationFrame(update);
</script><head> <title>Meter Example</title> <meta description="Step-by-step metering" /> <meta meter="health" tags="vlc,fortnite" x= ".05" y=".9" width=".189" h="70-140" s="40-100" l="40-100" type="linear" /></head><body style="margin: 0; padding: 0; background: #000;"> <canvas id="exCanvas" width="320" height="200"></canvas></body><script> var c = document.getElementById("exCanvas"); var ctx = c.getContext("2d");
// Meter initialisieren var healthMeter = new Meter(5, healthEffect);
function update(){ // Meter-Werte aktualisieren healthMeter.setValue(engine.vision.health);
window.requestAnimationFrame(update); }
function healthEffect(){ if(healthMeter.increased){ // Effekt auslösen } else if (healthMeter.value == 0){ // Effekt auslösen } else if (healthMeter.diff > .3){ // Effekt auslösen } }
function Meter(size, callback) { this.size = size; this.value = 0; this.diff = 0; this.increased = false; this.decreased = false; var values = [];
this.setValue = function (updatedValue) { // Hinzufügen und verschieben. values.push(updatedValue); if (values.length > this.size) { values.shift(); }
// Frühzeitig beenden, wenn keine langfristige Übereinstimmung vorliegt. for (var i = 0; i < values.length - 1; i++) { if (values[i] !== values[i + 1]) return; }
// Hier angekommen, liegt eine übereinstimmende Wertsammlung vor. Variablen setzen und Callback ausführen. if (this.value !== values[0]) { this.diff = Math.abs(this.value - values[0]); this.increased = this.value < values[0]; this.decreased = this.value > values[0]; this.value = values[0]; callback(); } }; }
window.requestAnimationFrame(update);
</script>function Meter(size, callback) { this.size = size; this.value = 0; this.diff = 0; this.increased = false; this.decreased = false; var values = [];
this.setValue = function (updatedValue) { // Hinzufügen und verschieben. values.push(updatedValue); if (values.length > this.size) { values.shift(); }
// Frühzeitig beenden, wenn keine langfristige Übereinstimmung vorliegt. for (var i = 0; i < values.length - 1; i++) { if (values[i] !== values[i + 1]) return; }
// Hier angekommen, liegt eine übereinstimmende Wertsammlung vor. Variablen setzen und Callback ausführen. if (this.value !== values[0]) { this.diff = Math.abs(this.value - values[0]); this.increased = this.value < values[0]; this.decreased = this.value > values[0]; this.value = values[0]; callback(); } }; }Der State-Handler
Abschnitt betitelt „Der State-Handler“Der State-Handler ist ein Effekt-Stack, der speziell Effekte verwaltet, die Vorrang vor allen anderen haben. Wenn eine große dominante Animation ohne Unterbrechung bis zum Ende laufen soll, wird sie in den State-Handler eingefügt.
| Methode | Beschreibung |
|---|---|
| StateHandler() | Der Konstruktor erfordert keine Argumente. |
| StateHandler.push(new State()) | Mit push kann ein neuer Zustand auf den Zustandsstapel geschoben werden, und die Verarbeitung beginnt sofort. |
| StateHandler.pop() | Entfernt den aktuellen Zustand vom Zustandsstapel und beginnt mit der Verarbeitung des vorherigen Zustands auf dem Stapel. |
Jedes in den State-Handler geschobene Objekt muss Process() implementieren. Die Process-Funktion bestimmt die Lebensdauer eines Effekts im Handler.
State-Handler-Beispiel
Abschnitt betitelt „State-Handler-Beispiel“Das Folgende zeigt einen grundlegenden State-Handler sowie die Process-Funktion, die innerhalb der Effektfunktionen laufen sollte:
var stateHdlr = new StateHandler();
function StateHandler() { var stack = []; var state = null;
// Aktuellen Zustand auf das oberste Element im Stapel setzen var updateState = function () { if (stack.length > 0) { state = stack[stack.length - 1]; } else { state = null; } };
// Ermöglicht dem Entwickler, einen Effekt zum State-Handler hinzuzufügen this.Push = function (newState) { stack.push(newState); updateState(); }; // Ermöglicht dem Entwickler, einen Effekt aus dem Handler zu entfernen this.Pop = function () { stack.pop(); updateState(); }; // Process-Funktion des aktuellen Zustands (Effekts) aufrufen this.Process = function () { if (state != null) { state.Process(); } }; }
function update(){ stateHdlr.Process();}this.start = new Date.now()this.elapsed = 0;this.duration = 1000;
this.Process = function () { // Zeit seit Effektstart auswerten this.elapsed = new Date.now() - this.start; // Wenn der Effekt seine Lebensdauer erreicht hat, aus dem State-Handler entfernen if (this.elapsed > this.duration) { stateMgr.Pop(); } // Wenn der Effekt noch läuft, die Effekt-Zeichenfunktion aufrufen this.Draw();};Der Effect-Handler
Abschnitt betitelt „Der Effect-Handler“Effect-Handler eignen sich hervorragend zum gemeinsamen Speichern und Rendern kleinerer, leichterer Effekte. Jeder Effekt im Handler wird bei jedem Update-Aufruf ausgewertet und entfernt, wenn er das Ende seiner Lebensdauer erreicht.
Der Effects-Handler ist lediglich ein Array zum Speichern von Effekten. Das ist alles.
// Effekte-Array deklarierenlet effects = [];
// (Nicht gezeigt) Meter auswerten, Callback-Funktion schiebt Effekt in das Effekte-Arrayeffects.push(new SpecialEffect());
// Durch das Array iterieren und für jeden Effekt einen Frame animierenfor (let i = 0; i < effects.length; i++) { effects[i].draw(); // Effekt entfernen, wenn die Lebensdauer abgelaufen ist if (effects[i].lifetime <= 0) { effects.splice(i, 1); }}WARNUNG: EFFECT vs. STATE
Abschnitt betitelt „WARNUNG: EFFECT vs. STATE“Der State-Manager ist speziell für Prioritätseffekte, was bedeutet, dass ihm bei der Ausführung Priorität eingeräumt werden muss. In der Update-Funktion zuerst den Effect-Handler verarbeiten und dann den State-Handler. Dadurch wird der State-Effekt über die Elemente des Effect-Handlers gezeichnet.
So wie hier:
function update(){ // Effect-Handler auswerten for (let i = 0; i < effects.length; i++) { effects[i].draw(); if (effects[i].lifetime <= 0) { effects.splice(i, 1); } }
// DANN State-Handler auswerten stateMgr.Process();}USB-Datenerfassungsanleitung
Abschnitt betitelt „USB-Datenerfassungsanleitung“Das Speichern von USB-Daten ist ein unkomplizierter Prozess, aber die von diesen Programmen verwendeten Treiber sind dafür bekannt, bei bestimmten Systemen Konflikte zu verursachen und manchmal USB-Ports zu deaktivieren, bis die Software entfernt wird. Die übliche Lösung besteht darin, “Secure Boot” in den BIOS/UEFI-Einstellungen zu deaktivieren. Bevor fortgefahren wird, wird dringend empfohlen, eine Systemwiederherstellung auf einem USB-Stick oder eine Möglichkeit zur Remote-Zugriffssteuerung des Computers bereitzuhalten, die keine Benutzereingabe beim Booten erfordert. Dies ist wichtig für den Fall, dass die Deaktivierung von Secure Boot das Problem nicht behebt und kein Zugang zum System zum Deinstallieren des Programms möglich ist. In solchen Fällen kann eine Windows-Aktualisierung notwendig sein, um alle installierten Programme zu entfernen und dabei persönliche Dateien zu behalten. Dies geschieht auf eigene Gefahr. Wer sich nicht sicher fühlt, es auszuprobieren, kann sein Gerät hier anfordern. Für diesen Prozess kein Laptop-System verwenden.
Nach der Installation ist der Prozess einfach und erfasst alle Daten, die durch die USB-Geräte fließen. Während der Aufnahme keine sensiblen Informationen eingeben, wenn die Daten geteilt werden sollen, da Tastenanschläge in der Aufnahme enthalten sind. Zwei Drittanbieterprogramme, die verwendet werden können, sind Usblyzer (kostenlose Testversion) und Wireshark (kostenlos). Beide funktionieren, aber bei Wireshark muss sichergestellt werden, dass USBPcap ausgewählt ist.
Weitere Details zu Aufbau von Meter-Callbacks und Effektfunktionen findest du auf unserer nächsten Seite Callbacks.