Cuberealm.io render tools library

threejs, camera, scenes

이 스크립트는 직접 설치하는 용도가 아닙니다. 다른 스크립트에서 메타 지시문 // @require https://update.greasyfork.org/scripts/586391/1899935/Cuberealmio%20render%20tools%20library.js을(를) 사용하여 포함하는 라이브러리입니다.

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// license: GPL3
(function(){
    if(window.renderToolsExports){
        console.warn("Render Tools: This library is already running and multiple at a time don't do anything different");
        return;
    }
    
    let THREE, camera, renderer;
    window.renderToolsExports = {};
 
    function search() {
        if (!window.webpackChunkcuberealm_client) return setTimeout(search, 50);
 
        /* 3 of these lines are a THREE.js hook
        from https://greasyfork.org/en/scripts/578395 by Story Man Licensed under MIT */
        let __wp = null;
        window.webpackChunkcuberealm_client.push([[Symbol()], {}, r => __wp = r]);
        if (!__wp) return setTimeout(search, 50);
        THREE = __wp('16259');
        window.renderToolsExports.THREE = THREE;
 
        if (THREE && THREE.PerspectiveCamera) {
            /* Handy thing to capture the camera */
            const proto = THREE.PerspectiveCamera.prototype;
            const originalUpdate = proto.updateMatrixWorld;
 
            proto.updateMatrixWorld = function(...args) {
                if (this.isPerspectiveCamera || this.isCamera) {
                    if (!camera) {
                        camera = this;
                        window.renderToolsExports.camera = camera;
                    }
                }
                return originalUpdate.apply(this, args);
            };
        }
        
        /* Captures the three.js renderer */
        Object.defineProperty(Object.prototype, "setRenderTarget", {
            get() {
                return this.ts ?? this.renderer;
            },
            set(nv) {
                renderer = this;
                window.renderToolsExports.renderer = renderer;
                return this.ts = nv;
            }
        });
    }
    search();
 
 
    function getScenes() {
        const foundScenes = new Set();
        const origUpdateMatrixWorld = THREE.Object3D.prototype.updateMatrixWorld;
 
        THREE.Object3D.prototype.updateMatrixWorld = function(...args) {
            if (this.isScene || this.constructor?.name === 'Scene') {
                foundScenes.add(this);
            }
            return origUpdateMatrixWorld.apply(this, args);
        };
 
        return new Promise((resolve) => {
            requestAnimationFrame(() => {
                THREE.Object3D.prototype.updateMatrixWorld = origUpdateMatrixWorld;
                resolve(Array.from(foundScenes));
            });
        });
    }
    
    async function getPlayer(scene2 = undefined){
        // if the main scene is passed, don't call getScenes cuz that returns a promise
        let scene = scene2;
        if(!scene2){
            const [scene1] = await getScenes();
            scene = scene1;
        }
        if(!scene || !camera) return null;
 
        /* adapted from [Kb+](https://greasyfork.org/en/scripts/538928-kb-cuberealm-io/) by Thibb1 */
        if (camera.children.length !== 1 || camera.children[0].type !== 'AudioListener') return null;
        if (scene.children.length > 0) {
            const main = scene.children[0].children;
            if (main.length > 7) {
                let player = main[6].children[0];
                return player;
            }
        }
    }
    
    async function getPlayers(scene2 = undefined, filterUnwanted = true){
        // if the main scene is passed, don't call getScenes cuz that returns a promise
        let scene = scene2;
        if(!scene2){
            const [scene1] = await getScenes();
            scene = scene1;
        }
        
        if(!scene || !THREE) return [];
        const r = [];
        scene.traverse((e) => {
            // only get players
            if(!e.isSkinnedMesh || e.name !== 'Whole') return;
            // filter out things that look like players but are duplicates-ish I think it's armor
            if (filterUnwanted && !e.parent.children.some((e1) => e1.type === 'Sprite')) return;
            if (filterUnwanted && !e.visible) return;
            r.push(e);
        });
        
        const player = getPlayer(scene);
        const i = r.indexOf(player);
        if(i >= 0){
            r.splice(i, 1);
        }
        return r;
    }
 
    const toExport = { THREE, camera, getScenes, renderer, getPlayer, getPlayers };
    for(let k in toExport){
        window.renderToolsExports[k] = toExport[k];
    }
})();