您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Makes editor a bit better
// ==UserScript== // @name bonk editor // @version e2.2_t1.4 // @description Makes editor a bit better // @author Apx // @match https://bonk.io/gameframe-release.html // @match https://bonkisback.io/gameframe-release.html // @run-at document-end // @namespace https://gf.qytechs.cn/users/1272759 // @grant none // ==/UserScript== const scriptName = "editer"; const guiSettings = { noWindow: true, settingsContent: null, bonkLIBVersion: "1.1.3", modVersion: "e2.2_t1.4", } window.bonkEditor = { /*transparency mod*/ fromColor: function (color) { return { hex: color & 0xffffff, transparency: (color >> 24 & 127) == 0? 1 : ((color >> 24 & 127) - 1) / 100, noshadow: !!(color >> 31 & 1), }; }, /*transparency mod*/ toColor: function () { // for slider return (document.getElementById("mapeditor_colorpicker_transparency_slider").value != "1"? (document.getElementById("mapeditor_colorpicker_transparency_slider").valueAsNumber * 100 + 1) * 0x01000000 : 0) + (document.getElementById("mapeditor_colorpicker_noshadow").checked == true? 0x80000000 : 0); }, /*transparency mod*/ elements: function () { return { slider: document.getElementById("mapeditor_colorpicker_transparency_slider"), noshadow: document.getElementById("mapeditor_colorpicker_noshadow"), }; }, /*transparency mod*/ updateElements: function (hex) { if(hex){ if(window.bonkEditor.fromColor(hex).noshadow) document.getElementById("mapeditor_colorpicker_noshadow").checked = true; else document.getElementById("mapeditor_colorpicker_noshadow").checked = false; document.getElementById("mapeditor_colorpicker_transparency_slider").value = window.bonkEditor.fromColor(hex).transparency; } let label = document.getElementById("mapeditor_colorpicker_transparencylabel"); switch (parseFloat(document.getElementById("mapeditor_colorpicker_transparency_slider").value)) { case 1: label.textContent = `Transparency: opaque`; break; case 0: label.textContent = `Transparency: transparent`; break; default: label.textContent = `Transparency: ${document.getElementById("mapeditor_colorpicker_transparency_slider").valueAsNumber * 100}%`; } }, rangeView: 100 * 1024, isCrashed: false, degree: 1, scale: () => 1, lineWidth: function (width, isEditor) { return isEditor? width * 2 / this.scale() : width; }, doAlignment: false, alignmentMode: 0, createVertexData: physics => { let vertexData = []; const bodies = physics.bodies; const shapes = physics.shapes; const fixtures = physics.fixtures; let calcCoordinates = (vertice, shapeAngle, shapePos, bodyAngle, bodyPos) => { let rotate = (vertex, angle) => { let n = [ Math.cos(angle) * vertex[0], Math.sin(angle) * vertex[0] ]; let d = [ Math.cos(angle + Math.PI/2) * vertex[1], Math.sin(angle + Math.PI/2) * vertex[1] ]; return [n[0] + d[0], n[1] + d[1]]; } let result = rotate( rotate( vertice, shapeAngle ).map( ( x, i ) => x + shapePos[i] ), bodyAngle).map( ( x, i ) => x + bodyPos[i] ).map( x => Math.round( x * 1000000 ) ).map( x => x / 1000000); return result; } for(let body in bodies) { for(let fx in bodies[body].fx) { let shape = shapes[fixtures[bodies[body].fx[fx]].sh]; if(shape.type == "po") { shape.v.forEach(x => { vertexData.push({ c: calcCoordinates(x, shape.a, shape.c, bodies[body].a, bodies[body].p), type: "po" }); }); } else if(shape.type == "bx") { vertexData.push( {c: calcCoordinates([shape.w / 2, shape.h / 2], shape.a, shape.c, bodies[body].a, bodies[body].p), type: "bx"}, {c: calcCoordinates([-shape.w / 2, shape.h / 2], shape.a, shape.c, bodies[body].a, bodies[body].p), type: "bx"}, {c: calcCoordinates([-shape.w / 2, -shape.h / 2], shape.a, shape.c, bodies[body].a, bodies[body].p), type: "bx"}, {c: calcCoordinates([shape.w / 2, -shape.h / 2], shape.a, shape.c, bodies[body].a, bodies[body].p), type: "bx"} ); } } } window.bonkEditor.vertexData = vertexData; }, vertexData: null, findClosestVertice: function (point, max = 20) { if(!this.vertexData) return; if(!point.x) point = {x: point[0], y: point[1]} let filtered = []; let closest = null; this.vertexData.forEach(elem => { if(Math.abs(point.x - elem.c[0]) < max && Math.abs(point.y - elem.c[1]) < max) { filtered.push([elem.c[0], elem.c[1]]) } }); filtered.forEach(elem => { let clc = Math.sqrt((point.x - elem[0])**2 + (point.y - elem[1])**2); if(clc < max) { if(!closest || closest.d > clc) closest = {d: clc, c: elem}; } }); return closest; }, calcPos: (vertice, body) => { vertice = [vertice.x - body.p[0], vertice.y - body.p[1], -body.a]; return [vertice[0] * Math.cos(vertice[2]) - vertice[1] * Math.sin(vertice[2]), vertice[0] * Math.sin(vertice[2]) + vertice[1] * Math.cos(vertice[2])]; }, canvas: document.createElement("canvas"), } function injector(src){ let newSrc = src; let CSS = document.createElement('style'); CSS.innerHTML = ` #mapeditor_colorpicker_transparency_slider{ margin-left: 0px; background-color: transparent; margin-top: -2px; } #mapeditor_colorpicker_transparencylabel, #mapeditor_colorpicker_shadowlabel { color: #ffffff; } #mapeditor_colorpicker_noshadow { position: relative; top: 1px; margin-left: 6px; margin-bottom: 11px; } .mapeditor_colorpicker_existingtile { background-repeat: no-repeat; } #mapeditor_colorpicker_existingcontainer { margin-top: 11px; } .mapeditor_colorpicker_button { background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 50 50' xmlns='http://www.w3.org/2000/svg' fill='%23fff' transform='matrix(-1,0,0,1,0,0)'%3E%3Cpath d='M6.5,16.5 38,48 50,50 45,45 40,44 11,15 l4,-4 29,29 1,5 5,5 L48,38 16.5,6.5 20,3 17,0 11,6 5,0 0,5 6,11 0,17 3,20'/%3E%3C/svg%3E"); background-repeat: no-repeat; width: 30px; height: 22px; background-size: 18px; background-position-x: calc(15px - 9px); background-position-y: calc(11px - 9px); border: 1px solid #fff; border-radius: 4px; } .mapeditor_colorpicker_button:hover { background-color: rgba(50, 66, 84, 0.5); } .mapeditor_colorpicker_button_on { pointer-events: none !important; background-color: rgba(50, 66, 84, 1); border: 1px solid #00000000 !important; } `; document.getElementsByTagName('head')[0].appendChild(CSS); let transparencylabel = document.createElement('span'); document.getElementById('mapeditor_colorpicker').insertBefore(transparencylabel, document.getElementById("mapeditor_colorpicker_existingcontainer")); transparencylabel.outerHTML = `<span id="mapeditor_colorpicker_transparencylabel">Transparency: Opaque</span>`; let slider = document.createElement('input'); document.getElementById('mapeditor_colorpicker').insertBefore(slider, document.getElementById("mapeditor_colorpicker_existingcontainer")); slider.outerHTML = `<input type="range" class="compactSlider compactSlider_classic" min="0" max="1" value="1" step="0.01" id="mapeditor_colorpicker_transparency_slider">`; let shadowlabel = document.createElement('span'); document.getElementById('mapeditor_colorpicker').insertBefore(shadowlabel, document.getElementById("mapeditor_colorpicker_existingcontainer")); shadowlabel.outerHTML = `<span id="mapeditor_colorpicker_shadowlabel">No Shadow</span>`; let shadowcheckbox = document.createElement('input'); document.getElementById('mapeditor_colorpicker').insertBefore(shadowcheckbox, document.getElementById("mapeditor_colorpicker_existingcontainer")); shadowcheckbox.outerHTML = `<input type="checkbox" id="mapeditor_colorpicker_noshadow"></input>`; let droppercheckbox = document.createElement('input'); document.getElementById('mapeditor_colorpicker').insertBefore(droppercheckbox, document.getElementById("mapeditor_colorpicker_existingcontainer")); droppercheckbox.outerHTML = `<div id="mapeditor_colorpicker_dropper" class="mapeditor_colorpicker_button"></div>`; // thanks salama const chatHandler = e => { if(e.keyCode === 13) { if(e.target.value.length > 0) { if(e.target.value[0] === "/") { let command = e.target.value.split(" ")[0].substring(1); let args = e.target.value.split(" ").slice(1); newArgs = []; for(let i = 0; i < args.length; i++) { if(args[i][0] === '"' && args[i][args[i].length - 1] !== '"') { let str = args[i]; for(let j = i + 1; j < args.length; j++) { str += " " + args[j]; if(args[j][args[j].length - 1] === '"') { i = j; break; } } newArgs.push(str.substring(1, str.length - 1)); } else if(args[i][0] === '"' && args[i][args[i].length - 1] === '"') { newArgs.push(args[i].substring(1, args[i].length - 1)); } else { newArgs.push(args[i]); } } args = newArgs; // Save without reference let oldMsg = e.target.value + ""; e.target.value = ""; if(command == "help") { window.bonkEditor.menu.showStatusMessage("/rangeview 0 to 1024 KB/MB -- Sets rangeview for maps (for loading huge maps). Default value is 100KB","#b53030",false); //return; } if(command == "rangeview") { if(args.length > 1) { if(isNaN(args[0]) || (args[1] != "KB" && args[1] != "MB")) { window.bonkEditor.menu.showStatusMessage("* Unknown parameters","#b53030",false); return; } window.bonkEditor.rangeview = Math.max(0, Math.min(1024, parseInt(args[0]))); window.bonkEditor.degree = args[1] == "KB"? 1 : 2; localStorage.setItem("bonkEditor", JSON.stringify({ rangeView: window.bonkEditor.rangeView, degree: window.bonkEditor.degree, })); } else if(args.length == 1) { if(args[0].match(/[0-9]+/) == null || (args[0].match(/[A-Za-z]+/) != "KB" && args[0].match(/[A-Za-z]+/) != "MB")) { window.bonkEditor.menu.showStatusMessage("* Unknown parameters","#b53030",false); return; } window.bonkEditor.rangeview = Math.max(0, Math.min(1024, parseInt(args[0].match(/[0-9]+/)))); window.bonkEditor.degree = args[0].match(/[A-Za-z]+/) == "KB"? 1 : 2; localStorage.setItem("bonkEditor", JSON.stringify({ rangeView: window.bonkEditor.rangeView, degree: window.bonkEditor.degree, })); } else { window.bonkEditor.menu.showStatusMessage("* Unknown parameters","#b53030",false); } return; } else { e.target.value = oldMsg; } } } } } document.getElementById("newbonklobby_chat_input").addEventListener("keydown", chatHandler, true); document.getElementById("ingamechatinputtext").addEventListener("keydown", chatHandler, true); function patch (src, newsrc) { newSrc = newSrc.replace(src, newsrc); }; function log(regex){ console.log(typeof(regex) == "string"?regex:(Array.isArray(regex)?regex:newSrc.match(regex))); }; function escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); }; // TRANSPARENCY (alpha) // add 4th channel patch(/<= 0xffffff\){/, `<= 0xffffffff){`); // add shape transparency to map preview const mapPreviewFixtColor = newSrc.match(/(?<=\(0xff0000\);).*?;/); let color = mapPreviewFixtColor[0].match(/(?<=\().*?\)/)[0].replace(")", ""); patch(mapPreviewFixtColor, `${mapPreviewFixtColor[0].split("(")[0]}(window.bonkEditor.fromColor(${color}).hex, window.bonkEditor.fromColor(${color}).transparency);`); // add shape transparency to map game & editor const mapFixtColor = newSrc.match(/\];}}}else {this.*?(?=\))/); color = mapFixtColor[0].split("(")[1]; patch(mapFixtColor,`${mapFixtColor[0].split("(")[0]}(window.bonkEditor.fromColor(${color}).hex, window.bonkEditor.fromColor(${color}).transparency`); // color picker (add transparency and no shadow) const colorPicker = newSrc.match(/,[a-zA-Z0-9\$_]{3}[[0-9]{1,3}]\);}}}(?=(?!catch)...[[0-9]{1,3}](?=\[))/); const onColorPicker = newSrc.match(/(?:...\[[0-9]{1,3}]=...\[0]\[[0-9]{1,3}];){3}(?=...\(false)/); const saveColor = newSrc.match(/\)\);}...\[[0-9]{1,3}]=null/); patch(colorPicker, colorPicker + ` window.bonkEditor.elements().slider.oninput = function(){ ${newSrc.match(new RegExp(`(?<=${escapeRegExp(colorPicker[0])}.*?0.73;).*?false\\)`))}; }; window.bonkEditor.elements().slider.onchange=window.bonkEditor.elements().slider.oninput; window.bonkEditor.elements().noshadow.onchange=window.bonkEditor.elements().slider.oninput; `); patch(onColorPicker, onColorPicker[0] + `window.bonkEditor.updateElements(arguments[0]);`); patch(saveColor, saveColor[0].replace("))",`),window.bonkEditor.toColor())`)); // right color picker const rightColorPicker = newSrc.match(/\]\],function\(...\){(?:[^\.]*?;){3}/); color = rightColorPicker[0].split("]]="); patch(rightColorPicker, `${color[0]}]]=${color[1].replace(";","")} + (arguments[1] == undefined? 0 : arguments[1]);window.bonkEditor.updateElements();`); // left color picker const leftColorPicker = newSrc.match(/;...\(\);},null\);};/); patch(leftColorPicker, ` + (arguments[1] == undefined? 0 : arguments[1]);window.bonkEditor.updateElements();` + leftColorPicker); // no shadows in game const gameShadow = newSrc.match(/if\(this.shapes\[...\].shadowTexture/); patch(gameShadow, `if(window.bonkEditor.fromColor(arguments[0].physics.fixtures[${gameShadow[0].match(/(?<=\[)...(?=\])/)}].f).noshadow){}else ` + gameShadow); // no shadows in preview const shadow = newSrc.match(/\){...\[[0-9]{1,3}]=0\.17;/); patch(shadow, `&&!window.bonkEditor.fromColor(${newSrc.match(new RegExp(`if\\([^;]*?` + escapeRegExp(shadow[0])))[0].match(/(?<=if\()...\[[0-9]{1,3}]/)}.f).noshadow` + shadow[0]); // existing tiles const tile = newSrc.match(/(?:...\[[0-9]{1,3}]=...\[[0-9]{1,3}]\[...\[[0-9]{1,5}]\[[0-9]{1,5}]];){3}[a-zA-Z0-9\$_]{3}\(false\);};}}function ...\(...(?:,...){3}\)/)[0]; patch(tile, ` window.bonkEditor.updateElements(this.name); ` + tile.split("}}")[0] + ` let elem = document.getElementById("mapeditor_colorpicker_existingcontainer").lastChild; let color = window.bonkEditor.fromColor(elem.name); if(color.transparency < 1) { elem.style.backgroundImage = \`url("data:image/svg+xml,%3Csvg viewBox='0 0 23 10' xmlns='http://www.w3.org/2000/svg' fill='\${elem.style.backgroundColor}'%3E%3Cpath d='m23,0 l-23,0v10'/%3E\${color.noshadow? "%3Ccircle style='fill:%23000' cx='11.5' cy='5' r='3.5'/%3E" : ''}%3C/svg%3E")\`; elem.style.backgroundColor = elem.style.backgroundColor.replace("rgb", "rgba").replace(")", \`, \${color.transparency})\`); } if(color.noshadow && elem.style.backgroundImage.length == 0) { elem.style.backgroundImage = \`url("data:image/svg+xml,%3Csvg viewBox='0 0 23 10' xmlns='http://www.w3.org/2000/svg' fill='%23000'%3E%3Ccircle style='fill:%23000' cx='11.5' cy='5' r='3.5'/%3E%3C/svg%3E")\`; } }}` + tile.split("}}")[1]) // EDITOR const updateRenderer = newSrc.match(/Error\(\);break;}...\(true\)/)[0].split("}")[1].split("(")[0]; const widthRoundingRegex = newSrc.match(/[a-zA-Z0-9\$_]{3}\[[0-9]{1,3}]]\[[a-zA-Z0-9\$_]{3}\[[0-9]{1,3}]\[[0-9]{1,3}]]=Math\[[a-zA-Z0-9\$_]{3}\[[0-9]{1,3}]\[[0-9]{1,3}]]\([a-zA-Z0-9\$_]{3}\[[0-9]{2,3}]\);[a-zA-Z0-9\$_]{3}\(true\)/)[0]; const rectPosRegex = newSrc.match(/[a-zA-Z0-9\$_]{3}\[[0-9]{1,3}]\[[a-zA-Z0-9\$_]{3}\[[0-9]{1,3}]\[[0-9]{1,3}]]\[[0-1]]=Math\[[a-zA-Z0-9\$_]{3}\[[0-9]{1,3}]\[[0-9]{1,3}]]\([a-zA-Z0-9\$_\[\]]+\);/g).map((x) => {return x.split("=")}); const platZindex = newSrc.match(/function [a-zA-Z0-9\$_]{3}\(\){[a-zA-Z0-9-+=_ \$;\(\)[\]{}\.,!]*?}}[a-zA-Z0-9\$_]{3}\(\);[a-zA-Z0-9\$_]{3}\(true\);}/g)[0]; const arrayBufferRegex = newSrc.match(/(?<=new ArrayBuffer\()k7V\.Q5\$\(100,1024\)/)[0]; const spawnId = newSrc.match(/[a-zA-Z0-9\$_]{3}\[[0-9]{1,3}](?=--;}else {(?!if))/)[0]; /**/ // render editor const theResetFunction = newSrc.match(new RegExp("function ...\\(\\){.{0,40}\(...\\[\\d+\\]=-1;){2}.{0,40}(...\\(true\\);).{0,40}(...\\(\\);){2}[^}]+\\}"))[0];// thanks kklkkj & salama let regExp = newSrc.match(new RegExp(`}}...\\(\\);${escapeRegExp(theResetFunction.match(/...\(true\);/)[0])}}`,"g")); patch(regExp, regExp + `window.bonkEditor.renderEditor = ${theResetFunction.match(/...\(true\);/)[0].replace('(true)', '')}`); /**/ // gameObject const gameObject = newSrc.match(/[a-zA-Z0-9\$_]{3}\[[0-9]{1,3}]\[0]={userName:[a-zA-Z0-9\$_]{3}\[[0-9]{1,3}]/)[0].split(":")[1]; // move up / down spawns let vars = platZindex.match(/(?<![\.a-zA-Z])(?:[a-zA-Z0-9\$_]{3})(?=[\[=]{1})(?:\[[0-9]{1,3}])?/g); const modifiedPlatZindex = platZindex .replace(/}}(?!else)/, ` } } } else{ if(this==${vars[10]}){ if(${vars[4]}.spawns[${spawnId}-1]!=undefined){ ${vars[15]}=${vars[4]}.spawns[${spawnId}-1]; ${vars[4]}.spawns[${spawnId}-1]=${vars[0]}[100]; ${vars[4]}.spawns[${spawnId}]=${vars[15]}; ${spawnId}--; } } else if(this==${vars[33]}){ if(${vars[4]}.spawns[${spawnId}+1]!=undefined){ ${vars[38]}=${vars[4]}.spawns[${spawnId}+1]; ${vars[4]}.spawns[${spawnId}+1]=${vars[0]}[100]; ${vars[4]}.spawns[${spawnId}]=${vars[38]}; ${spawnId}++; } } }`) .replace(/if\(.*?\){.*?}/, "") .replace(/;if\(.*?\){.*?}/, `;${vars[0]}[100]=${vars[4]}.spawns[${spawnId}];if(${vars[3]} == -1 && ${vars[4]}.spawns.indexOf(${vars[0]}[100]) == -1){return;}if(${vars[3]}!=-1){`); patch(platZindex,modifiedPlatZindex); // disable width rounding to integers patch(widthRoundingRegex.split(";")[0] + ";", `${widthRoundingRegex.split("=")[0]}=${widthRoundingRegex.split("=")[1].split(";")[0].match(/.{7}(?=\))/)};`); // disable rectangle position rounding to integers for(let i = 0; i < 4; i++) patch(rectPosRegex[i].join("="), `${rectPosRegex[i][0]}=${rectPosRegex[i][1].match(/.{6}(?=\))/)};`); // replace the minimum number of width, height and radius with MIN_VALUE (values lower than 1e-100 are not recommended) const precission = newSrc.match(/function [a-zA-Z0-9\$_]{3}\([a-zA-Z0-9\$_]{3}\){[a-zA-Z0-9\$_\[\]= ]+;[a-zA-Z0-9\$_\[\]=]+;[a-zA-Z0-9\$_\[\]=]+\*=10000;[a-zA-Z0-9\$_\[\]=]+\([a-zA-Z0-9\$_\[\]=]+\);[a-zA-Z0-9\$_\[\]=]+\/=10000;return [a-zA-Z0-9\$_\[\]=]+;}/)[0]; patch(`min:1,`, `min:0.0001,`); patch(precission ,`function ${precission.split(" ")[1].substring(0,3)}(arg_){return arg_;}`); // replace the constant with a variable patch(arrayBufferRegex ,`(window.bonkEditor.rangeView*(1024**window.bonkEditor.degree))`); // alignment const newPolyPlat = newSrc.match(/{x:0,y:0};...\[[0-9]{1,3}]=null;(?=[a-zA-Z0-9\$_]{3})/); const mapObject = newSrc.match(/0,999999\)\){...\[[0-9]{1,3}]/)[0].split("{")[1]; const editorPreview = newSrc.match(/\< 3\){return;}...\[[0-9]{1,3}]/)[0].split("}")[1]; patch(newPolyPlat, newPolyPlat + `window.`); const createPolygon = newSrc.match(/\)\);return;}}(?=if\()/); let thing = newSrc.match(/[a-zA-Z0-9\$_]{3}\([a-zA-Z0-9\$_]{3}\[0]\[0]\);...\[[0-9]{1,3}]={x:0[^;]*?;[^;]*?;window\./)[0]; const scaleMouse = thing.split("(")[0]; const body = thing.split(";")[2].split("=")[0]; const whiteBlackCrossPos = thing.split(";")[1].split("=")[0]; patch(newPolyPlat + 'window.', newPolyPlat + ` window.bonkEditor.createVertexData(${mapObject}.physics); window.bonkEditor.polygonPreviewArgs = null; let input = e => { window.bonkEditor.doAlignment = e.shiftKey; if(window.bonkEditor.polygonPreviewArgs) ${editorPreview}.drawPolygonPreview(...window.bonkEditor.polygonPreviewArgs); } document.addEventListener("keydown", input); document.addEventListener("keyup", input); document.getElementById("mapeditor_midbox_cancel_drawing").addEventListener("click", () => {window.bonkEditor.polygonPreviewArgs = null;}); let closestDefined = false; this.onmousemove = function (mouse) { if(!window.bonkEditor.doAlignment) return; mouse = ${scaleMouse}(mouse); let closest = window.bonkEditor.findClosestVertice(mouse, 20 / ${editorPreview}.getStageScale()); let body = ${body}; if(closest){ closestDefined = true; ${editorPreview}.drawPolygonPreview(${whiteBlackCrossPos}, [window.bonkEditor.calcPos(mouse, body)], body.p[0], body.p[1], body.a); }else if (closestDefined) { closestDefined = false; ${editorPreview}.drawPolygonPreview(${whiteBlackCrossPos}, [], body.p[0], body.p[1], body.a); } };`); patch(createPolygon, `));document.removeEventListener("keydown", input);document.removeEventListener("keyup", input);window.bonkEditor.polygonPreviewArgs = null;` + createPolygon[0].substring(3) + ` let closestPoint = window.bonkEditor.findClosestVertice(${scaleMouse}(arguments[0]), 20 / ${editorPreview}.getStageScale()); if(closestPoint && window.bonkEditor.doAlignment){ let body = ${body}; let shape = ${mapObject}.physics.shapes[${mapObject}.physics.shapes.length-1]; shape.v.push(closestPoint.c.map((x,i) => x - body.p[i])); let v = shape.v.slice(); let mouse = ${scaleMouse}(arguments[0]); v.push(window.bonkEditor.calcPos(mouse, body)); ${editorPreview}.drawPolygonPreview(${whiteBlackCrossPos}, v, body.p[0], body.p[1], body.a); return; }`); const polygonPreview = newSrc.match(/[a-zA-Z0-9\$_]{3}\[0]\[4];}[a-zA-Z0-9\$_]{3}\[[0-9]{1,3}]/)[0].split("}")[1]; patch(newSrc.match(/[a-zA-Z0-9\$_]{3}\[0]\[4];}(?=[a-zA-Z0-9\$_]{3}\[[0-9]{1,3}])/), newSrc.match(/[a-zA-Z0-9\$_]{3}\[0]\[4];}(?=[a-zA-Z0-9\$_]{3}\[[0-9]{1,3}])/) + `if(arguments[1].length > 0){ window.bonkEditor.polygonPreviewArgs = arguments; let vertices = arguments[1].slice().reverse(); let closestPoint = window.bonkEditor.findClosestVertice(vertices[0].map((x,i) => x + arguments[2+i]), 20 / this.getStageScale()); if(Math.sqrt(((vertices[0][0] - arguments[1][0][0])**2) + ((vertices[0][1] - arguments[1][0][1])**2)) < 20 / this.getStageScale() && arguments[1].length > 2) { let line = new PIXI.Graphics(); line.lineStyle(window.bonkEditor.lineWidth(4, true), 0x7777ff, 0.75); line.moveTo(...arguments[1][0]); line.lineTo(...vertices[1]); ${polygonPreview}.addChild(line); } else if(closestPoint && window.bonkEditor.doAlignment) { let line = new PIXI.Graphics(); line.lineStyle(window.bonkEditor.lineWidth(4, true), 0x7777ff, 0.5); line.moveTo(closestPoint.c[0] - arguments[2], closestPoint.c[1] - arguments[3]); line.lineTo(...(vertices[1]?vertices[1]:vertices[0])); ${polygonPreview}.addChild(line); } }`); // anti-crash type 1 const anticrash1 = newSrc.match(/(?<=null)\){var [a-zA-Z0-9\$_]{3}=[a-zA-Z0-9\$_]{3}\..*?;/g); for(let i = 1; i < anticrash1.length; i++) { patch(anticrash1[i], `&&this.shapes[${anticrash1[i].split("=")[1].replace(";","")}]!=undefined${anticrash1[i]}`); } // anti-crash type 2 const anticrash2 = newSrc.match(/(?<=0xccbbaa;)if\(this...../); patch(anticrash2,`if(this.capFill==null){return;}${anticrash2}`); // 0fps fix const gameExit = newSrc.match(/\(\);[a-zA-Z0-9\$_]{3}\[[0-9]{1,3}]=false;}else {.*?}/); const frame = newSrc.match(/requestAnimationFrame\([a-zA-Z0-9\$_]{1,3}\);(?=})/); const frameDispatch = newSrc.match(/[a-zA-Z0-9\$_]{1,3}\(\){}(;window.*?;(?=func))?function [a-zA-Z0-9\$_]{1,3}\(\){.*?;.*?;.*?(?=;)/)[0].split(";").reverse()[0]; const visibilityChange = newSrc.match(/}\);}document.*?{/); patch(visibilityChange, visibilityChange + `window.bonkEditor.visibilityStateChanged = true;`); patch(frameDispatch, `try{${frameDispatch}}catch(e){window.bonkEditor.isCrashed = true;throw e;}`); patch(gameExit, gameExit + `if(window.bonkEditor.isCrashed){window.bonkEditor.isCrashed = false;${frame}}`); // anti circle crash let antiCircleCrash = newSrc.match(/createTexture\(...,...\) {/); patch(antiCircleCrash, antiCircleCrash + `return;`); // eye dropper !!! colorPicker FROM TRANSPARENCY MOD !!! tile FROM TRANSPARENCY MOD const getEditor = newSrc.match(/};};};}/); patch(getEditor, getEditor + `window.bonkEditor.map = function(){return ${mapObject};};window.bonkEditor.editor = ${editorPreview};`); const mapRenderer = newSrc.match(/if\(...\[[0-9]{1,3}]\){[^;]*?;return ...\[[0-9]{1,3}];}(?=};})/); thing = tile.match(/(?:.*?;){3}/)[0].split(";").map(x => x.split("=")[0]); patch(mapRenderer, mapRenderer + ` if(classArguments[1] == "editor" && document.getElementById("mapeditor_colorpicker_dropper").classList.contains("mapeditor_colorpicker_button_on")) { let ctx = window.bonkEditor.canvas.getContext("2d"); let img = new Image(); img.src = ${mapRenderer[0].split(";")[0].split("=")[1].match(/...\[[0-9]{1,3}]/)}.extract.base64(); img.onload = function () { ctx.drawImage(img,0,0); } document.getElementsByClassName("gamecanvas")[0].style.border = "2px solid red"; } `) const toHSV = newSrc.match(/...\[[0-9]{1,3}]=...\....\(...\[[0-9]{1,3}],256,65536,...\[[0-9]{1,3}],...\[[0-9]{1,3}]\);return ...\[[0-9]{1,3}];}function .../)[0].split("function ")[1]; patch(colorPicker, colorPicker + ` document.getElementById("mapeditor_colorpicker_dropper").onclick = function () { let editorCanvas = document.getElementsByClassName("gamecanvas")[0]; let canvas = window.bonkEditor.canvas; let ctx = canvas.getContext("2d"); let normalColor = null; let mapMouseDown = function (e) { let a = e.target.getBoundingClientRect(); let x = Math.round(e.clientX - a.left) - 2; let y = Math.round(e.clientY - a.top) - 2; let color = ctx.getImageData(x, y, 1, 1).data; color = color[0] * 65536 + color[1] * 256 + color[2]; let hsv = ${toHSV}(color); ${thing[0]} = hsv.hue; ${thing[1]} = hsv.brightness; ${thing[2]} = hsv.saturation; ${tile.match(/...\(false\);/)} //document.getElementById("mapeditor_colorpicker_lefttile").style["background-color"] = color; }; let mapMouseMove = function (e) { let a = e.target.getBoundingClientRect(); let x = Math.round(e.clientX - a.left) - 2; let y = Math.round(e.clientY - a.top) - 2; let color = ctx.getImageData(x, y, 1, 1).data; color = \`rgb(\${color[0]}, \${color[1]}, \${color[2]})\`; document.getElementById("mapeditor_colorpicker_lefttile").style["background-color"] = color; }; let docMouseDown = () => { editorCanvas.style.cursor = "grab"; editorCanvas.style.border = "none"; editorCanvas.removeEventListener("mousedown", mapMouseDown); editorCanvas.removeEventListener("mousemove", mapMouseMove); document.removeEventListener("mousedown", docMouseDown); //document.getElementById("mapeditor_colorpicker_lefttile").style["background-color"] = normalColor; this.classList.remove("mapeditor_colorpicker_button_on"); }; if(this.classList.contains("mapeditor_colorpicker_button_on")) { this.classList.remove("mapeditor_colorpicker_button_on"); } else { this.classList.add("mapeditor_colorpicker_button_on"); normalColor = document.getElementById("mapeditor_colorpicker_lefttile").style["background-color"]; window.bonkEditor.renderEditor(false); let base64 = window.bonkEditor.extractedMapPreview; editorCanvas.style.cursor = "crosshair"; editorCanvas.style.border = "2px solid red"; canvas.width = parseFloat(editorCanvas.style.width); canvas.height = parseFloat(editorCanvas.style.height); editorCanvas.addEventListener("mousedown", mapMouseDown); editorCanvas.addEventListener("mousemove", mapMouseMove); document.addEventListener("mousedown", docMouseDown); } } `); // menu const menuRegex = newSrc.match(/== 13\){...\(\);}}/)[0]; patch(menuRegex, menuRegex + "window.bonkEditor.menu = this;"); // anti lobby kick const ws = window.WebSocket.prototype.send; window.WebSocket.prototype.send = function(args){ if(this.url.includes("socket.io/?EIO=3&transport=websocket&sid=") && typeof(args) == "string" && args.length > 250000){ window.bonkEditor.menu.showStatusMessage("* Protected from being kicked out of the room.","#b53030",false); return; } ws.call(this,args); } // cap zone highlight const capZoneColor = newSrc.match(/}else if\(...\[[0-9]{1,3}] == ...\[[0-9]{1,3}] \|\| ...\[[0-9]{1,3}] == ...\[[0-9]{1,3}]\){...\[[0-9]{1,3}]/)[0]; const hasCZ = newSrc.match(/if\(...\[[0-9]{1,3}]\[...\[[0-9]{1,3}]]\){[^;]*?\(3,0x/)[0].substring(3).split(")")[0]; patch(capZoneColor, `if(${capZoneColor.split("(")[1].split(")")[0]} || window.bonkEditor.highlightedCapZone == ${hasCZ}.capID){${capZoneColor.split("{")[1]}.lineStyle(3, 0xff0000, 1);}` + capZoneColor); const capZoneSelection = newSrc.match(/...\[[0-9]{1,3}],1\);...\[[0-9]{1,3}]=-1/)[0].split(",")[0]; const addCZHighlightFunction = newSrc.match(/false;};...\[[0-9]{1,3}]=new TWEEN/); patch(addCZHighlightFunction, `false;};this.highlightCapZone=function(capZone){window.bonkEditor.highlightedCapZone=capZone};this.clearHighlightCapZone=function(){window.bonkEditor.highlightedCapZone=null};` + addCZHighlightFunction[0].split(";};")[1]); const onHoverCZFunction = newSrc.match(/};[^;]*?=function\(\){};[^;]*?=function\(\){};};for/); patch(onHoverCZFunction, onHoverCZFunction[0].replaceAll("function(){}", `(e)=>{if(e.type == "mouseover"){${editorPreview}.highlightCapZone(arguments[0]);${updateRenderer}(true);}else if(e.type == "mouseout"){${editorPreview}.clearHighlightCapZone();${updateRenderer}(true);}}`)); // zoom const xdidkhowtoname = newSrc.match(/[a-zA-Z0-9\$_]{3}\[[0-9]{1,3}]=0.5;[a-zA-Z0-9\$_]{3}\[[0-9]{1,3}]=\[];/) patch(xdidkhowtoname, xdidkhowtoname[0] + `let classArguments = arguments;`); const zoom = newSrc.match(/(?<=4,500\)\);)[a-zA-Z0-9\$_]{3}\[[0-9]{1,3}]/)[0]; patch(new RegExp(zoom.replaceAll("[","\\[") + `=new.*?;`), zoom + `=new PIXI.Container();window.bonkEditor.scale = function(){return ${zoom}.transform.scale.x;};`); // update render on zoom in/out/reset const mouseEvents = newSrc.match(/(...\[[0-9]{1,3}]\[.{0,12}\]\[[0-9]{1,3}\]]\(\)\[.{0,20}]=...;){2}/)[0]; const resetZoom = newSrc.match(/(?:...\[[0-9]{1,3}]\[...\[[0-9]{1,3}]\[[0-9]{1,3}]]=0;){2}(?:...\[[0-9]{1,3}]\[...\[[0-9]{1,3}]\[[0-9]{1,3}]]\[...\[[0-9]{1,3}]\[[0-9]{1,3}]]=1;){2}};/); patch(mouseEvents, `${mouseEvents.split(")[")[0]}).onwheel=function(){window.bonkEditor.renderEditor(true);${newSrc.match(/function\(\){...\[[0-9]{1,3}]=!...\[[0-9]{1,3}];...\(\)/)[0].split(";")[1]};};`); // i dunno why on mouse wheel P5l not called if you have kklee enabled patch(new RegExp(`(?<=${newSrc.match(/(?<=\(0\.8\);if\()...\[[0-9]{1,3}]/)[0].replace("[","\\[")} == false\\){...\\()false`, "g"), `true`); patch(resetZoom, `window.bonkEditor.renderEditor(true);` + resetZoom); // make line width variable patch(/(?=...\[[0-9]{1,3}]=1;...\[[0-9]{1,3}]=0.5;...\[[0-9]{1,3}]=\[];)/, `let isEditor = arguments[1] == "editor";`) patch(/(?=...\[[0-9]{1,3}]=2\.0;...\[[0-9]{1,3}]=\[];...\[[0-9]{1,3}]=\[];)/, `let isEditor = false;`) patch(/(?=var ...=this\.bodyID;)/, `let isEditor = false;`) patch(/2,0x7777ff/, `window.bonkEditor.lineWidth(2, isEditor),0x7777ff`); patch(/1,0xcccccc,0\.5\);(?!...\....\([0-9]{1,10}\))(?!this)/g, `window.bonkEditor.lineWidth(1, isEditor),0xcccccc, 0.5);`); patch(/1(?=,0xf4a7a7)/g, `window.bonkEditor.lineWidth(1, isEditor)`); patch(/4(?=,0x[F0]{6})/g, `window.bonkEditor.lineWidth(4, isEditor)`); patch(/(?<=\(-?)10(?=,0\))/g, `window.bonkEditor.lineWidth(10, isEditor)`); patch(/(?<=\(0,-?)10(?=\))/g, `window.bonkEditor.lineWidth(10, isEditor)`); patch(/1,0xffffff,0.5/g, `window.bonkEditor.lineWidth(1, isEditor),0xffffff,0.5`); patch(/0\.5,0xffffff/g, `window.bonkEditor.lineWidth(0.5, isEditor),0xffffff`); if(src === newSrc) throw "Injection failed!"; console.log(`${scriptName} injector run`); return newSrc; } if(!window.bonkCodeInjectors) window.bonkCodeInjectors = []; window.bonkCodeInjectors.push(bonkCode => { try { return injector(bonkCode); } catch (error) { alert(`Whoops! ${scriptName} was unable to load.`); throw error; } }); if (window.bonkHUD) { function updateVariables (variables) { for(let i = 0; i < Object.keys(variables).length; i++) window.bonkEditor[Object.keys(variables)[i]] = Object.values(variables)[i]; } let storage = localStorage.getItem("bonkEditor"); if(storage != null){ storage = JSON.parse(storage); updateVariables(storage); } else storage = {}; const label = (target, ...elements) => { let div = document.createElement("div"); div.margin = "5px"; target.appendChild(div); for(let element in elements) { if(typeof(elements[element]) == "string"){ let labelElement = document.createElement("label"); labelElement.classList.add("bonkhud-settings-label"); labelElement.textContent = elements[element]; labelElement.style.padding = "0 5px"; labelElement.style.display = "inline-block"; div.appendChild(labelElement); } else div.appendChild(elements[element]); div.lastChild.style.verticalAlign = "middle"; } } // functions const notAppliedText = target => { if(target.lastChild.className == "bonkeditor_not_applied_text") return; let span = document.createElement("span"); span.className = "bonkeditor_not_applied_text"; span.textContent = "* not applied"; span.style["margin-left"] = "5px"; span.style.color = "#000000aa"; span.style.verticalAlign = "middle"; target.appendChild(span); } const checkbox = value => { let checkbox = document.createElement("input"); checkbox.type = "checkbox"; checkbox.checked = value; checkbox.style["vertical-align"] = "middle"; return checkbox; } const inputText = value => { let text = document.createElement("input"); text.style.width = "40px"; text.style.height = "19px"; text.style["vertical-align"] = "middle"; text.value = value; return text; } let settings = window.bonkHUD.generateSection(); guiSettings.settingsContent = settings; const ind = window.bonkHUD.createMod("bonk editor & transparency", guiSettings); // section /(1024**window.bonkEditor.degree) let rangeView = inputText(storage.rangeView || window.bonkEditor.rangeView); rangeView.oninput = (event) => { event.target.value = event.target.value.replaceAll(/[^0-9]+/g, ''); event.target.value = String(Math.min(Math.max(parseInt(event.target.value) || 0, 0), 1024)); notAppliedText(event.target.parentNode); } let unit = document.createElement("select"); let units = ["KB","MB"]; units.forEach((text,key) => { unit.appendChild(new Option(text, key, false, (storage.degree || window.bonkEditor.degree) == key + 1)); }); unit.onchange = (event) => { window.bonkEditor.degree = parseInt(event.target.value); notAppliedText(event.target.parentNode); } // apply button let applyButton = window.bonkHUD.generateButton("Apply"); applyButton.style.display = "inline-block"; applyButton.style.padding = "0 5px"; applyButton.onclick = () => { updateVariables({ rangeView: parseInt(rangeView.value), degree: (parseInt(unit.selectedIndex) + 1), }); [...settings.getElementsByClassName("bonkeditor_not_applied_text")].forEach(x => x.parentNode.removeChild(x)); localStorage.setItem("bonkEditor", JSON.stringify({ rangeView: window.bonkEditor.rangeView, degree: window.bonkEditor.degree, })); } // apply button let clearStorageButton = window.bonkHUD.generateButton("Clear Storage"); clearStorageButton.style.display = "inline-block"; clearStorageButton.style.padding = "0 5px"; clearStorageButton.onclick = () => { localStorage.removeItem("bonkEditor"); } label(settings, "Array buffer range view", rangeView, unit); label(settings, applyButton); label(settings, clearStorageButton); window.bonkHUD.updateStyleSettings(); }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址