콘텐츠로 이동

스니펫

이 섹션에는 LightScript를 위한 세 가지 유용한 코드 스니펫이 포함되어 있습니다: 미터, 상태 핸들러, 효과 핸들러.

이전 섹션의 연속으로, Meter 클래스는 불안정한 미터 데이터에서 의미 있는 변화를 추적하는 데 도움이 되도록 설계되었습니다. 코드의 브레이크 페달처럼 생각하십시오. 복잡한 영역에서도 안정성을 제공합니다. 각 미터는 업데이트 함수의 각 실행 중에 수집된 사용자 지정 가능한 값 배열을 보관합니다. 해당 배열의 모든 값이 동일해지면(데이터가 “안정적”이면) 미터는 값을 업데이트하고 연결된 콜백 함수를 트리거하여 효과를 활성화합니다.

메서드설명
Meter(size, callback)생성자는 sizecallback을 모두 허용합니다.\n\nsize - 미터 값이 처리될 만큼 ‘안정적’으로 간주되기 위해 동일한 값이 있어야 하는 횟수. 값이 높을수록 정확도가 높아지고, 낮을수록 지연이 줄어듭니다.\n\ncallback - 미터 값이 안정적이고 변경되었을 때 호출할 함수.
Meter.setValue(value)매 프레임마다, 또는 이 미터에 대한 새로운 원시 데이터가 있을 때마다 setValue(value)를 호출해야 합니다.

화면 데이터 수집 프로세스는 일반적으로 다음 구조를 따라야 합니다:

  1. engine.vision.meter 값이 화면의 새 데이터를 기반으로 업데이트됩니다.
  2. 업데이트 함수 내부에서 **Meter.setValue(engine.vision.meter)**가 호출되어 새 값을 기록합니다.
  3. Meter는 내부 배열을 확인하여 모든 값이 동일한지 검사합니다. 동일하면 자체 상태를 업데이트하고 할당된 콜백 함수를 실행합니다.
  4. 콜백 함수는 Meter의 변수를 사용하여 특정 조건을 평가하고 조건이 충족되면 코드를 실행합니다.

중요 참고 사항:

콜백 사용을 건너뛰지 마십시오. 업데이트 함수는 지속적으로 실행되므로 최대한 효율적으로 유지해야 합니다. 주요 역할은 Meter 값을 업데이트하는 것이어야 합니다. 업데이트 내에서 미터를 확인하고 효과를 트리거하기 위해 조건문을 체인으로 연결하는 것을 피하십시오. 이는 모든 사이클에서 불필요한 검사로 이어집니다. 대신 효과를 별도의 함수로 정의하고 콜백으로 Meter에 전달하십시오.

안정화되면 Meter는 콜백 함수에 몇 가지 값을 제공합니다:

변수설명
Meter.value미터의 현재 값.
Meter.increased이번 업데이트에서 값이 증가했는지 여부를 나타내는 불리언.
Meter.decreased이번 업데이트에서 값이 감소했는지 여부를 나타내는 불리언.
Meter.diff이번 업데이트에서 미터가 경험한 변화의 절댓값.

Meter 클래스 코드를 포함한 기본 단일 미터 설정입니다:

<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");
// Initialize meter
var healthMeter = new Meter(5, healthEffect);
function update(){
// Update Meter values
healthMeter.setValue(engine.vision.health);
window.requestAnimationFrame(update);
}
function healthEffect(){
if(healthMeter.increased){
// Trigger effect
} else if (healthMeter.value == 0){
// Trigger effect
} else if (healthMeter.diff > .3){
// Trigger effect
}
}
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) {
// Add and shift.
values.push(updatedValue);
if (values.length > this.size) {
values.shift();
}
// Exit early if we don't have a long-term match.
for (var i = 0; i < values.length - 1; i++) {
if (values[i] !== values[i + 1]) return;
}
// We got here, so we've got a matching value collection. Set variables and execute callback.
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) {
// Add and shift.
values.push(updatedValue);
if (values.length > this.size) {
values.shift();
}
// Exit early if we don't have a long-term match.
for (var i = 0; i < values.length - 1; i++) {
if (values[i] !== values[i + 1]) return;
}
// We got here, so we've got a matching value collection. Set variables and execute callback.
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();
}
};
}

상태 핸들러는 다른 모든 효과보다 우선순위를 가진 효과를 특별히 처리하는 효과 스택입니다. 하나의 크고 지배적인 애니메이션이 중단 없이 완료될 때까지 실행되기를 원한다면 상태 핸들러에 삽입하십시오.

메서드설명
StateHandler()생성자에는 인수가 필요하지 않습니다.
StateHandler.push(new State())push를 사용하여 새 상태를 상태 스택에 추가할 수 있으며 처리가 즉시 시작됩니다.
StateHandler.pop()현재 상태를 상태 스택에서 팝하고 상태 스택의 이전 상태 처리를 시작합니다.

상태 핸들러에 삽입된 모든 객체는 반드시 Process()를 구현해야 합니다. Process 함수는 핸들러에서 효과의 수명을 결정합니다.

다음은 효과 함수 내부에서 실행되어야 하는 Process 함수와 함께 기본 상태 핸들러를 보여줍니다:

var stateHdlr = new StateHandler();
function StateHandler() {
var stack = [];
var state = null;
// Set current state to the top item in the stack
var updateState = function () {
if (stack.length > 0) {
state = stack[stack.length - 1];
} else {
state = null;
}
};
// Allows dev to add effect to state handler
this.Push = function (newState) {
stack.push(newState);
updateState();
};
// Allows dev to remove effect from handler
this.Pop = function () {
stack.pop();
updateState();
};
// Call the Process function of the current state (effect)
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 () {
// Evaluate time since effect start
this.elapsed = new Date.now() - this.start;
// If the effect has reached its lifespan, remove it from the state handler
if (this.elapsed > this.duration) {
stateMgr.Pop();
}
// If the effect is still running, call the effect draw function
this.Draw();
};

효과 핸들러는 더 작고 가벼운 효과를 모두 함께 저장하고 렌더링하는 데 탁월합니다. 핸들러의 각 효과는 각 업데이트 호출에서 평가되며 수명이 끝나면 제거됩니다.

효과 핸들러는 효과를 저장하기 위한 배열에 불과합니다. 그게 전부입니다.

// Declare effects array
let effects = [];
// (Not shown) Evaluate Meter, callback function pushes effect into effects array
effects.push(new SpecialEffect());
// Iterate through the array, animating a frame for each effect
for (let i = 0; i < effects.length; i++) {
effects[i].draw();
// Remove effect if the lifetime has ended
if (effects[i].lifetime <= 0) {
effects.splice(i, 1);
}
}

상태 관리자는 우선순위 효과를 위한 것이므로 실행 중에 우선순위를 부여해야 합니다. 업데이트 함수에서 효과 핸들러를 처리한 다음 상태 핸들러를 처리하십시오. 이렇게 하면 효과 핸들러의 항목 위에 상태 효과가 그려집니다.

다음과 같이 사용하십시오:

function update(){
// Evaluate effects handler
for (let i = 0; i < effects.length; i++) {
effects[i].draw();
if (effects[i].lifetime <= 0) {
effects.splice(i, 1);
}
}
// THEN evaluate state handler
stateMgr.Process();
}

USB 데이터를 저장하는 것은 간단한 프로세스이지만, 이러한 프로그램이 사용하는 드라이버는 일부 시스템과 충돌하는 것으로 알려져 있으며, 소프트웨어가 제거될 때까지 USB 포트를 비활성화하는 경우가 있습니다. 일반적인 해결 방법은 BIOS/UEFI 설정에서 **‘보안 부팅’**을 비활성화하는 것입니다. 진행하기 전에 플래시 드라이브에 시스템 복원을 준비하거나 부팅 시 사용자 입력에 의존하지 않는 방법으로 컴퓨터에 원격으로 접근할 수 있는 방법을 갖추는 것을 강력히 권장합니다. 보안 부팅을 비활성화해도 문제가 해결되지 않고 프로그램을 제거하기 위해 시스템에 접근할 수 없는 경우에 대비하여 중요합니다. 그런 경우 Windows 새로 고침이 개인 파일을 유지하면서 설치된 모든 프로그램을 제거하는 데 필요할 수 있습니다. 이 작업은 본인의 책임 하에 수행하십시오. 시도하기 불편하다면 여기에서 장치를 요청하십시오. 노트북에서는 이 프로세스를 사용하지 마십시오.

설치 후 프로세스는 간단하며 USB 장치를 통과하는 모든 데이터를 캡처합니다. 데이터를 공유할 계획이라면 캡처 중에 민감한 정보를 입력하지 마십시오. 키 입력이 녹화에 포함됩니다. 사용할 수 있는 두 가지 서드파티 프로그램은 Usblyzer(무료 체험) 및 Wireshark(무료)입니다. 둘 다 작동하지만 Wireshark를 선택한다면 USBPcap이 선택되어 있는지 확인하십시오.

미터 콜백 및 효과 함수 구성에 대한 자세한 내용은 다음 콜백 페이지를 확인하십시오.