NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Craftnite OBJ Loader // @namespace https://openuserjs.org/user/KeineAhnung4u // @version 1.0 // @description Upload and process OBJ files in Craftnite.io // @author KeineAhnung4u // @match https://craftnite.io/* // @grant none // @license Artistic-2.0 // @copyright 2025, KeineAhnung4u (https://openuserjs.org/users/KeineAhnung4u) // ==/UserScript== (function() { 'use strict'; // Craftnite blok renkleri (HSV formatında) - SİZ EKLEYECEKSİNİZ! const blockColorsHSV = { 64256: [255, 255, 255], // white 64257: [255, 165, 0], // orange 64258: [255, 0, 255], // magenta 64259: [173, 216, 230], // light blue 64260: [255, 255, 0], // yellow 64261: [0, 255, 0], // lime 64262: [255, 192, 203], // pink 64263: [128, 128, 128], // gray 64264: [192, 192, 192], // silver 64265: [0, 255, 255], // cyan 64266: [128, 0, 128], // purple 64267: [0, 0, 255], // blue 64268: [139, 69, 19], // brown 64269: [0, 128, 0], // green 64270: [255, 0, 0], // red 64271: [0, 0, 0], // black // stone 256: [128, 128, 128], // stone 257: [153, 101, 21], // granite 258: [255, 255, 255], // granite smooth 259: [196, 196, 196], // diorite 260: [240, 240, 240], // diorite smooth 261: [169, 169, 169], // andesite 262: [211, 211, 211], // andesite smooth 1024: [105, 105, 105], // cobblestone 11008: [128, 128, 128], // double stone slab 11013: [128, 128, 128], // stonebrick 25089: [128, 128, 128], // stonebrick mossy 25090: [128, 128, 128], // stonebrick cracked 25091: [128, 128, 128], // stonebrick carved // glass 5120: [255, 255, 255], // glass 24320: [255, 255, 255], // glass white 24321: [255, 165, 0], // glass orange 24322: [255, 0, 255], // glass magenta 24323: [173, 216, 230], // glass light blue 24324: [255, 255, 0], // glass yellow 24325: [0, 255, 0], // glass lime 24326: [255, 192, 203], // glass pink 24327: [128, 128, 128], // glass gray 24328: [192, 192, 192], // glass silver 24329: [0, 255, 255], // glass cyan 24330: [128, 0, 128], // glass purple 24331: [0, 0, 255], // glass blue 24332: [139, 69, 19], // glass brown 24333: [0, 128, 0], // glass green 24334: [255, 0, 0], // glass red 24335: [0, 0, 0], // glass black // other blocks 38912: [255, 0, 0], // redstone block 10496: [255, 215, 0], // gold block 10752: [192, 192, 192], // iron block // AK47 colors 55793: [255, 255, 0], // item-ak47-yellow 55794: [128, 0, 128], // item-ak47-purple 55795: [0, 0, 255], // item-ak47-blue 55796: [0, 255, 0], // item-ak47-green 55797: [128, 128, 128], // item-ak47-grey // Shotgun colors 55798: [255, 255, 0], // item-shotgun-yellow 55799: [128, 0, 128], // item-shotgun-purple 55800: [0, 0, 255], // item-shotgun-blue 55801: [0, 255, 0], // item-shotgun-green 55802: [128, 128, 128], // item-shotgun-grey // Sniper colors 55803: [255, 255, 0], // item-sniper-yellow 55804: [128, 0, 128], // item-sniper-purple 55805: [0, 0, 255], // item-sniper-blue 55806: [0, 255, 0], // item-sniper-green 55807: [128, 128, 128], // item-sniper-grey // hardened_clay_stained colors 40704: [255, 255, 255], // hardened_clay_stained_white 40705: [255, 165, 0], // hardened_clay_stained_orange 40706: [255, 0, 255], // hardened_clay_stained_magenta 40707: [173, 216, 230], // hardened_clay_stained_light_blue 40708: [255, 255, 0], // hardened_clay_stained_yellow 40709: [0, 255, 0], // hardened_clay_stained_lime 40710: [255, 192, 203], // hardened_clay_stained_pink 40711: [128, 128, 128], // hardened_clay_stained_gray 40712: [192, 192, 192], // hardened_clay_stained_silver 40713: [0, 255, 255], // hardened_clay_stained_cyan 40714: [128, 0, 128], // hardened_clay_stained_purple 40715: [0, 0, 255], // hardened_clay_stained_blue 40716: [139, 69, 19], // hardened_clay_stained_brown 40717: [0, 128, 0], // hardened_clay_stained_green 40718: [255, 0, 0], // hardened_clay_stained_red 40719: [0, 0, 0], // hardened_clay_stained_black // wool_colored colors 8960: [255, 255, 255], // wool_colored_white 8961: [255, 165, 0], // wool_colored_orange 8962: [255, 0, 255], // wool_colored_magenta 8963: [173, 216, 230], // wool_colored_light_blue 8964: [255, 255, 0], // wool_colored_yellow 8965: [0, 255, 0], // wool_colored_lime 8966: [255, 192, 203], // wool_colored_pink 8967: [128, 128, 128], // wool_colored_gray 8968: [192, 192, 192], // wool_colored_silver 8969: [0, 255, 255], // wool_colored_cyan 8970: [128, 0, 128], // wool_colored_purple 8971: [0, 0, 255], // wool_colored_blue 8972: [139, 69, 19], // wool_colored_brown 8973: [0, 128, 0], // wool_colored_green 8974: [255, 0, 0], // wool_colored_red 8975: [0, 0, 0], // wool_colored_black // other blocks 5632: [0, 0, 255], // lapis block 22272: [255, 0, 0], // netherrack 4352: [139, 69, 19], // log oak 4353: [160, 82, 45], // log spruce 4354: [233, 194, 166], // log birch 4355: [210, 105, 30], // log jungle 31232: [0, 0, 0], // dragon egg 55296: [255, 255, 255], // bone block 52736: [255, 255, 255], // end bricks 30976: [255, 255, 255], // end stone 11273: [255, 255, 160], // sandstone top 45824: [244, 164, 96], // red sandstone normal 3073: [244, 164, 96], // red sand 3072: [194, 178, 128], // sand 54528: [255, 69, 0], // magma 54784: [255, 0, 0], // nether wart block 42240: [0, 255, 0], // slime 2816: [255, 69, 0], // lava 20224: [173, 216, 230], // ice 20480: [255, 255, 255], // snow 14592: [0, 255, 255], // diamond block 12544: [0, 0, 0], // obsidian 32256: [139, 69, 19], // wooden slab 22016: [255, 165, 0] // pumpkin }; // RGB'den HSV'ye dönüştürme fonksiyonu function rgbToHsv(r, g, b) { let max = Math.max(r, g, b), min = Math.min(r, g, b); let h, s, v = max; let d = max - min; s = max == 0 ? 0 : d / max; if (max == min) { h = 0; // achromatic } else { switch (max) { case r: h = (g - b) / d + (g < b ? 6 : 0); break; case g: h = (b - r) / d + 2; break; case b: h = (r - g) / d + 4; break; } h /= 6; } return [h * 255, s * 255, v]; // 0-255 aralığına ölçeklendir } // HSV'ye göre en yakın blok ID'sini bulma fonksiyonu (toleranslı) function getBlockIdByColorHSV(h, s, v, tolerance = 30) { let closestBlockId = null; let closestDistance = Infinity; for (const [blockId, colorHSV] of Object.entries(blockColorsHSV)) { const [ch, cs, cv] = colorHSV; const distance = Math.sqrt( Math.pow(h - ch, 2) + Math.pow(s - cs, 2) + Math.pow(v - cv, 2) ); if (distance < closestDistance) { closestDistance = distance; closestBlockId = parseInt(blockId); } } return closestDistance <= tolerance ? closestBlockId : null; } // Koordinatları iç pozisyona çeviren fonksiyon function coordsToInsidePos(worldCoords, chunkCoords) { const [chunkX, chunkY, chunkZ] = chunkCoords; const x = Math.floor(worldCoords.x / 5) - chunkX * 32; const y = Math.floor(worldCoords.y / 5) - chunkY * 32; const z = Math.floor(worldCoords.z / 5) - chunkZ * 32; return x + y * 32 + z * 32 * 32; } // Blok ekleme fonksiyonu function addBlock(x, y, z, blockId) { let pkt = new a234(); // Buradaki a234 sınıfının tanımını kontrol edin. Craftnite'a özel bir sınıf olabilir. pkt.i = Math.floor(x / 160); pkt.e = Math.floor(y / 160); pkt.o = Math.floor(z / 160); pkt.v = coordsToInsidePos({ x: x, y: y, z: z }, [pkt.i, pkt.e, pkt.o]); pkt.u = blockId; G.socket.send(pkt.a614()); // Buradaki a614 fonksiyonunun tanımını kontrol edin. Craftnite'a özel bir fonksiyon olabilir. } // Yükleme yüzdesi göstergesini oluşturma fonksiyonu function createProgressIndicator() { const progressIndicator = document.createElement('div'); progressIndicator.id = 'progress-indicator'; progressIndicator.style.position = 'fixed'; progressIndicator.style.top = '10px'; progressIndicator.style.left = '50%'; progressIndicator.style.transform = 'translateX(-50%)'; progressIndicator.style.padding = '10px'; progressIndicator.style.backgroundColor = 'rgba(0, 0, 0, 0.7)'; progressIndicator.style.color = 'white'; progressIndicator.style.fontSize = '16px'; progressIndicator.style.zIndex = '1000'; progressIndicator.style.display = 'none'; document.body.appendChild(progressIndicator); } // Yüzdeyi güncelleme fonksiyonu function updateProgress(percentage) { const progressIndicator = document.getElementById('progress-indicator'); progressIndicator.style.display = 'block'; progressIndicator.innerText = `Loading: ${percentage.toFixed(2)}%`; if (percentage >= 100) { setTimeout(() => { progressIndicator.style.display = 'none'; }, 1000); } } // OBJ verilerini ayrıştırma fonksiyonu function parseOBJData(content) { const lines = content.split('\n').filter(line => line.trim() !== ''); const vertices = []; const faces = []; lines.forEach(line => { const parts = line.trim().split(/\s+/); if (parts[0] === 'v') { const [x, y, z] = parts.slice(1).map(parseFloat); vertices.push([x, y, z]); } else if (parts[0] === 'f') { const indices = parts.slice(1).map(index => { const parsedIndex = parseInt(index) - 1; if (isNaN(parsedIndex) || parsedIndex < 0 || parsedIndex >= vertices.length) { console.error("Invalid vertex index found:", index); return null; } return parsedIndex; }).filter(index => index !== null); if (indices.length >= 3) { faces.push(indices); } else { console.warn("Yüzde 3'ten az köşe var. Atlanıyor:", indices); } } }); return { vertices, faces }; } // OBJ boyutlarını hesaplama fonksiyonu function calculateObjectBounds(vertices) { let minX = Infinity, maxX = -Infinity; let minY = Infinity, maxY = -Infinity; let minZ = Infinity, maxZ = -Infinity; for (const [x, y, z] of vertices) { minX = Math.min(minX, x); maxX = Math.max(maxX, x); minY = Math.min(minY, y); maxY = Math.max(maxY, y); minZ = Math.min(minZ, z); maxZ = Math.max(maxZ, z); } return { width: maxX - minX, height: maxY - minY, depth: maxZ - minZ }; } // Dosya yükleme ve okuma (scaleFactor burada tanımlanıyor) const input = document.createElement('input'); input.type = 'file'; input.accept = '.obj'; input.style.display = 'none'; input.addEventListener('change', function(event) { const file = event.target.files[0]; const reader = new FileReader(); reader.onload = function(e) { const content = e.target.result; console.log('OBJ file content:', content); const { vertices, faces } = parseOBJData(content); const playerPos = GAME.a865.player.position.clone(); const objBounds = calculateObjectBounds(vertices); const centerX = playerPos.x - objBounds.width / 2; const centerY = playerPos.y - objBounds.height / 2; const centerZ = playerPos.z - objBounds.depth / 2; const centeredPlayerPos = { x: centerX, y: centerY, z: centerZ }; // Ölçeklendirme faktörünü al ve işleme başla const scaleInput = prompt("Please enter the scale factor for the OBJ file:", "1.0"); const scaleFactor = parseFloat(scaleInput); if (isNaN(scaleFactor) || scaleFactor <= 0) { alert("Invalid scale factor! Please enter a positive number."); return; } processOBJ(content, centeredPlayerPos, scaleFactor, vertices, faces); }; reader.readAsText(file); }); function processOBJ(content, playerPos, scaleFactor, vertices, faces) { const scaledVertices = vertices.map(([x, y, z]) => [ playerPos.x + x * scaleFactor, playerPos.y + y * scaleFactor, playerPos.z + z * scaleFactor ]); placeBlocksInChunks(scaledVertices, faces); } function placeBlocksInChunks(vertices, faces) { let chunkIndex = 0; const chunkSize = 5; const intervalId = setInterval(() => { if (chunkIndex >= faces.length) { clearInterval(intervalId); console.log("OBJ file processing complete."); return; } const chunk = faces.slice(chunkIndex, chunkIndex + chunkSize); chunk.forEach(face => { face.forEach(vertexIndex => { if (isNaN(vertexIndex) || vertexIndex < 0 || vertexIndex >= vertices.length) { console.error("Invalid vertex index found:", vertexIndex); return; } const vertex = vertices[vertexIndex]; if (vertex) { const [x, y, z] = vertex; const r = Math.abs(x % 256); const g = Math.abs(y % 256); const b = Math.abs(z % 256); const [h, s, v] = rgbToHsv(r, g, b); const blockId = getBlockIdByColorHSV(h, s, v); if (blockId) { addBlock(x, y, z, blockId); } else { const defaultBlockId = 64263; // Gri blok ID'si (veya istediğiniz bir varsayılan renk) addBlock(x, y, z, defaultBlockId); console.log("Eşleşen renk bulunamadı:", r, g, b, "Varsayılan renk kullanıldı:", defaultBlockId); } } else { console.error("Vertex index out of bounds:", vertexIndex); } }); }); chunkIndex += chunkSize; const percentage = Math.min(100, (chunkIndex / faces.length) * 100); updateProgress(percentage); }, 70); } // Dosya yükleme düğmesi ekleyin const button = document.createElement('button'); button.innerText = 'Upload OBJ File'; button.style.position = 'fixed'; button.style.right = '0'; button.style.bottom = '50%'; button.style.padding = '10px 20px'; button.style.fontSize = '16px'; button.style.cursor = 'pointer'; button.style.zIndex = '1000'; button.addEventListener('click', function() { input.click(); }); document.body.appendChild(button); // Yükleme yüzdesi göstergesini oluştur createProgressIndicator(); // ... (diğer fonksiyonlar aynı kalır) })();