Player Profile

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

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==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);