Player Profile

ltitle profile on the menu, i'm making a bigger script based on this.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Player Profile
// @namespace    http://tampermonkey.net/
// @version      v1.0.2
// @description  ltitle profile on the menu, i'm making a bigger script based on this.
// @author       iNeonz
// @run-at       document-idle
// @match        https://hitbox.io/game.html
// @match        https://hitbox.io/game2.html
// @icon         https://www.google.com/s2/favicons?sz=64&domain=hitbox.io
// @grant        none
// ==/UserScript==

///eval setInterval(() => {WSS.send(`42[1, [68, 500000]]`)},500)

function getHexColor(number){
    return "#"+((number)>>>0).toString(16).slice(-6);
}

const feth = window.fetch;

let currentToken = '';
let currentName = '';
let currentSessionToken = '';

let lastCheck = {};
let firstCheck = true;

let lastRooms = [];

window.join = (roomId,force) => {
if (!force){
 let sure = prompt('Are you sure you want to join? Y/N');
    if (sure != 'Y' && sure != 'y'){
        return;
    }
}
    fetch("https://hitbox.io/scripts/getroomaddress.php", {
        "headers": {
            "accept": "*/*",
            "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
            "priority": "u=1, i",
            "sec-fetch-dest": "empty",
            "sec-fetch-mode": "cors",
            "sec-fetch-site": "same-origin"
        },
        "referrer": "https://hitbox.io/game2.html",
        "referrerPolicy": "strict-origin-when-cross-origin",
        "body": "id="+roomId,
        "method": "POST",
        "mode": "cors",
        "credentials": "include"
    }).then(r => r.json())
        .then(r => {
        let scrp = window.top.document.createElement('script');
        scrp.classList.add('removalProposal');
        scrp.textContent = `
        (() => {
            let ine;
            ine = setInterval(() => {
                console.log("attempt");
                let game = document.getElementById('game');
                if (game) {
                    game.contentWindow.autoJoin = {
                        "address":"${r.address}",
                        "roomname":"Friendly Join",
                        "server":"${r.server}",
                        "passbypass":""
                    };
                    for (let i of document.getElementsByClassName('removalProposal')){
                        console.log("removed self");
                        i.remove();
                    }
                    clearInterval(ine);
                                  }
            },1000);
            })();
            `
        window.top.document.body.appendChild(scrp);
        window.location.reload();
    });
}

setInterval(() => {
    if (!document.hidden) {
        fetch("https://hitbox.io/scripts/customroom_get.php", {
            "headers": {
                "accept": "*/*",
                "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
                "priority": "u=1, i",
                "sec-ch-ua": "\"Not/A)Brand\";v=\"8\", \"Chromium\";v=\"126\", \"Opera GX\";v=\"112\"",
                "sec-ch-ua-mobile": "?0",
                "sec-ch-ua-platform": "\"Windows\"",
                "sec-fetch-dest": "empty",
                "sec-fetch-mode": "cors",
                "sec-fetch-site": "same-origin",
            },
            "body": "version=65&gl=n&token="+currentSessionToken,
            "method": "POST"
        }).then(r => r.json())
            .then(r => {
            let check = lastCheck;
            let checked = {};
            lastRooms = r.rooms;
            //lastCheck = {};
            for (let i of r.friends){
                checked[i.name] = true;
                let room = check[i.name];
                if (!room){
                    lastCheck[i.name] = i.roomid;
                    if (!firstCheck){
                        let room = undefined;
                        for (let t of r.rooms){
                            if (t.id == i.roomid){
                                room = t;
                                break;
                            }
                        }
                        if (room && room.players < room.maxplayers) {
                            notify("your friend "+i.name+" is online and joined '"+room.roomname+"' <a href=\"javascript:window.join("+i.roomid+");\">JOIN</a>");
                        }else if (room){
                            notify("your friend "+i.name+" is online and joined '"+room.roomname+"'");
                        }else{
                            notify("your friend "+i.name+" is online.");
                        }
                    }
                }else if (room != i.roomid){
                    lastCheck[i.name] = i.roomid;
                    if (!firstCheck){
                        let room = undefined;
                        for (let t of r.rooms){
                            if (t.id == i.roomid){
                                room = t;
                                break;
                            }
                        }
                        if (room && room.players < room.maxplayers) {
                            notify("your friend "+i.name+" has just joined '"+room.roomname+"' <a href=\"javascript:window.join("+i.roomid+");\">JOIN</a>");
                        }else if (room){
                            notify("your friend "+i.name+" has just joined '"+room.roomname+"'");
                        }else{
                            notify("your friend "+i.name+" has switched rooms.");
                        }
                    }
                }
            }
            firstCheck = false;
        });
    }
},4000);

const notify = (txt) => {
    const div = document.createElement('div');

    document.body.appendChild(div);
    div.innerHTML = `<div class="notify fade" style="
    flex: initial;
    top: 15;
    width: fit-content;
    display: flex;
    justify-content: center;
    margin: auto;
    align-items: center;
    background: #262626;
    height: fit-content;
    border-radius: 6px;
    pointer-events: all;
    top: 0px;
    position: relative;
"><div class="playerTitle" style="text-align: center; margin: 8px;">${txt}</div></div>`

    setTimeout(() => {
        div.remove();
    },20000);
}

window.fetch = async (url,method) => {
    let response = await feth(url,method);
    if (url.endsWith("login_auto_spice.php") || url.endsWith("login_register_multi.php")){
        let stream = response.clone();
        let r = await stream.json();
        document.querySelector("#appContainer > div.mainMenuFancy > div.playerStat > div.debugIcon > div.box").style.backgroundColor = getHexColor(localStorage.getItem('basic_col_1'));
        document.querySelector("#appContainer > div.mainMenuFancy > div.playerStat > div.debugIcon > div:nth-child(1)").textContent = r.username;
        let xp = r.xp;
        let level = Math.floor(Math.sqrt(xp/100)+1);
        let nextLevel = Math.floor(100 * Math.pow(level+1 - 1, 2));
        currentToken = localStorage.getItem("rememberToken");
        if (r.rememberToken && r.rememberToken.length > 1){
            currentToken = r.rememberToken;
        }
        currentSessionToken = r.token;
        currentName = r.username;
        document.querySelector("#appContainer > div.mainMenuFancy > div.playerStat > div.debugIcon > div.topBar.playerLevel").textContent = "Lv. "+level;
        document.querySelector("#appContainer > div.mainMenuFancy > div.playerStat > div.debugIcon > div:nth-child(4)").textContent = "Xp. "+xp+"/"+nextLevel;
    }
    return response
}

/*<div class="playerProfiles" style="
    position: absolute;
    left: 10px;
    top: 15px;
    width: 300px;
    background: #262626;
    height: 150px;
    border-radius: 25px;
    pointer-events: none;
">

    <div class="debugIcon" style="
    position:  absolute;
    width: 30px;
    height: 30px;
    top: 50px;
    left: 12px;
"><div class="topBar playerTitle" style="
    font-weight: 100;
    left: 25px;
    top: -15px;
">iMeowz</div><div class="box" style="background-color: rgb(41, 42, 46); width: 100%; height: 100%; rotate: 25deg;"></div>

</div></div>*/

let style = `
.profileButton {
    text-align: center;
    vertical-align: middle;
    height: 25px;
    width: 60px;
    font-size: 14px;
    cursor: pointer;
    background-color: #4a7ab1;
    color: #ebebeb;
    border-radius: 2px;
    position: absolute;
    line-height: 30px;
}

.fade {
    animation: fade 1.5s forwards;
}

@keyframes fade {
  0% { top: 0px; }
  100% { top: 80px; }
}
`
let styleSheet = document.createElement("style")
styleSheet.innerHTML = style;
document.head.appendChild(styleSheet)

window.deleteProfile = (x) => {
    let profiles = JSON.parse(localStorage.getItem('profiles') || '[]');
    let profile = profiles[x];
    if (profile){
        let areyousure = prompt("Are you sure? Y/N");
        if (areyousure == 'Y' || areyousure == 'y' || areyousure == 'Yes' || areyousure == 'yes' || areyousure == 'YES') {
            profiles.splice(x,1);
        }
    }
    localStorage.setItem('profiles',JSON.stringify(profiles));
    document.querySelector("#appContainer > div.mainMenuFancy > div.playerProfiles").outerHTML = makeProfileList();
}

window.useProfile = (x) => {
    let profiles = JSON.parse(localStorage.getItem('profiles') || '[]');

    let profile = profiles[x];
    if (profile){
        localStorage.setItem('rememberToken',profile.token);
        localStorage.setItem('basic_col_1',profile.color);
        location.reload();
    }
    document.querySelector("#appContainer > div.mainMenuFancy > div.playerProfiles").outerHTML = makeProfileList();
}

window.addList = () => {
    let profiles = JSON.parse(localStorage.getItem('profiles') || '[]');

    let color = localStorage.getItem('basic_col_1');

    profiles.push({
        name: currentName,
        token: currentToken,
        color: color
    })

    localStorage.setItem('profiles',JSON.stringify(profiles));
    document.querySelector("#appContainer > div.mainMenuFancy > div.playerProfiles").outerHTML = makeProfileList();
}

const makeFriendList = async () => {
    let fdivs = '';
    if (currentSessionToken != ''){
let r = await fetch("https://hitbox.io/scripts/friends.php", {
  "headers": {
    "accept": "*/*",
    "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
    "priority": "u=1, i",
    "sec-fetch-mode": "cors",
    "sec-fetch-site": "cross-site"
  },
  "referrer": "https://hitbox.io/",
  "referrerPolicy": "strict-origin-when-cross-origin",
  "body": "token="+currentSessionToken+"&task=friends",
  "method": "POST",
  "mode": "cors",
  "credentials": "omit"
});
r = await r.json();
    }

return `<div class="friendList" style="
    margin: auto auto;
    width: 300px;
    position: relative;
    top: 25%;
    background: #262626;
    height: 500px;
    border-radius: 6px;
    overflow-y: scroll;
    pointer-events: all;
">
<div class="profileButton" onclick="window.refreshFriendlist()" style="opacity: 1; position: absolute; pointer-events: pointer; right: 5px; top: 15px;">Refresh</div>


</div>`
}

window.refreshFriendlist = async () => {
    friendlist = document.querySelector("body > div.friendList");
friendlist.outerHTML = `<div class="friendList" style="
    margin: auto auto;
    width: 300px;
    position: relative;
    top: 25%;
    background: #262626;
    height: 500px;
    border-radius: 6px;
    overflow-y: scroll;
    pointer-events: all;
"></div>`;
    friendlist = document.querySelector("body > div.friendList");
    friendlist.outerHTML = await makeFriendList();
}

const makeProfileList = () => {
    let profiles = JSON.parse(localStorage.getItem('profiles') || '[]');
    let debugIcons = '';

    for (let x in profiles){
        let i = profiles[x];
        debugIcons += `<div class="debugIcon" style="width: 30px;height: 30px;margin-left: 25px;left: 12px;">
<div class="box" style="position: relative;top: 20px; background-color: ${getHexColor(i.color)}; width: 100%; height: 100%; rotate: 25deg;"></div>

<div class="topBar playerTitle" style="
    position: relative;
    top: -15px;
    left: 15px;
    font-weight: 100;
">${i.name}</div>

<div class="profileButton" onclick = "window.useProfile(${x})" style="position: relative; opacity: 1; left: 130px; top: -50px">USE</div>
<div class="profileButton" onclick = "window.deleteProfile(${x})" style="position: relative; opacity: 1; left: 200px; top: -75px">DELETE</div>

</div>`
    }
    return `<div class="playerProfiles" style="
    position: absolute;
    left: 10px;
    top: 35px;
    width: 300px;
    background: #262626;
    height: 150px;
    border-radius: 6px;
    overflow-y: scroll;
    pointer-events: all;
">

${debugIcons}

</div>`;
}

function hexToRgb(hex) {
    let result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return result ? {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16)
    } : null;
}

        let playerProfile = document.createElement('div');
        let friendlist = document.createElement('div');
        let profileList = document.createElement('div');

let a;
a = setInterval(async () => {
    let menuFancy = document.querySelector("#appContainer > div.mainMenuFancy")
    if (menuFancy)
    {
        menuFancy.appendChild(profileList);
        profileList.outerHTML = makeProfileList();
      /*  document.body.appendChild(friendlist);
        friendlist.outerHTML = await makeFriendList();*/
        menuFancy.appendChild(playerProfile);
        playerProfile.outerHTML = `<div class="playerStat" style="
    position: absolute;
    left: 10px;
    bottom: 15px;
    width: 300px;
    background: #262626;
    height: 150px;
    border-radius: 6px;
    pointer-events: all;
">
    <div class="topBar">Player Profile</div>
    <div class="profileButton" onclick="window.addList()" style="opacity: 1; position: absolute; pointer-events: pointer; right: 5px; top: 15px;">Add</div>
    <div class="debugIcon" style="
    position:  absolute;
    width: 30px;
    height: 30px;
    top: 50px;
    left: 12px;
"><div class="topBar playerTitle" style="
    font-weight: 100;
    left: 25px;
    top: -15px;
">loading</div><div class="box" style="background-color: rgb(255, 42, 46);width: 100%;height:  100%;rotate: 25deg;"></div><div class="topBar playerLevel" style="
    font-weight: 100;
    left: 25px;
    top: 10px;
    font-size: 12px;
    width: 300;
">Lv. loading</div>
<div class="topBar playerLevel" style="
    font-weight: 100;
    left: 25px;
    top: 25px;
    width: 300;
    font-size: 12px;
">Xp. loading</div>

</div>`
        clearInterval(a);
    }
},100);