1
0
mirror of https://github.com/lexogrine/dota2-react-hud.git synced 2026-05-04 04:23:10 +02:00
This commit is contained in:
Hubert Walczak
2021-07-10 20:25:28 +02:00
commit 52e2cd949b
1417 changed files with 35119 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
async function apiV2(url, method = 'GET', body) {
const options = {
method,
headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
}
if (body) {
options.body = JSON.stringify(body)
}
let data = null;
return fetch(`/api/${url}`, options)
.then(res => {
data = res;
return res.json().catch(_e => data && data.status < 300)
});
}
const api = {
match: {
get: async () => apiV2(`match`),
getCurrent: async () => apiV2(`match/current`)
},
teams: {
getOne: async (id) => apiV2(`teams/${id}`),
get: () => apiV2(`teams`),
},
players: {
get: async () => apiV2(`players`),
getAvatarURLs: async (steamid) => apiV2(`players/avatar/steamid/${steamid}`)
},
tournaments: {
get: () => apiV2('tournament')
}
}
export { api };
+133
View File
@@ -0,0 +1,133 @@
/* eslint-disable no-undef */
import { api } from './api.js';
let mesh = null;
// if cl_showpos 1 is 3300 -200 2100, then array should be:
// [-200, 2100, 3300]
// last element of the array is rotation in degrees
const positions = {
de_cache: [-200, 2100, 3300, 180],
de_mirage: [-2100, 159, -1970, 0],
de_dust2: [-450, 350, 727, 180],
de_inferno: [10, 141, -1866, 0],
de_train: [641, 125, -1800, 90],
de_overpass: [-1519, 475, -1105, 115],
de_nuke: [-3025, -10, 490, 90],
de_vertigo: [-615, 12605, -448, 0],
}
const startARModule = (scene, _camera, _renderer, GSI, actions) => {
let lastContent = '';
let scoreboardObject = null;
function updateScoreboard(content, map) {
if(!(map in positions)){
return;
}
const wrapper = scoreboardObject || document.createElement('div');
if(!wrapper.id){
wrapper.id = 'playerCanvas'
}
wrapper.innerHTML = content;
if (!scoreboardObject) {
scoreboardObject = wrapper;
const object = new THREE.CSS3DObject(wrapper);
mesh = object;
const position = positions[map];
object.position.set(position[0], position[1], position[2]);
object.rotateY(THREE.Math.degToRad(position[3]));
scene.add(object);
actions.on('arState', arState => {
const isHidden = arState === "hide";
wrapper.classList.toggle('hide', isHidden);
});
}
return wrapper;
}
api.match.getCurrent().then(match => {
if (!match) return;
let isReversed = false;
if (GSI.last) {
const mapName = GSI.last.map.name.substring(GSI.last.map.name.lastIndexOf('/') + 1);
const current = match.vetos.find(veto => veto.mapName === mapName);
if (current && current.reverseSide) {
isReversed = true;
}
}
api.teams.get().then(teams => {
if (match.left && match.left.id) {
const left = teams.find(team => team._id === match.left.id);
if (left) {
const gsiTeamData = { id: left._id, name: left.name, country: left.country, logo: left.logo, map_score: match.left.wins, extra: left.extra };
if (!isReversed) {
GSI.teams.left = gsiTeamData;
}
else GSI.teams.right = gsiTeamData;
}
}
if (match.right && match.right.id) {
const right = teams.find(team => team._id === match.right.id);
if (right) {
const gsiTeamData = { id: right._id, name: right.name, country: right.country, logo: right.logo, map_score: match.right.wins, extra: right.extra };
if (!isReversed) {
GSI.teams.right = gsiTeamData;
}
else GSI.teams.left = gsiTeamData;
}
}
});
});
GSI.on('data', (data) => {
if(!data || !data.map || !data.map.name) return;
const mapName = data.map.name.substring(data.map.name.lastIndexOf('/') + 1);
if(!mapName || !(mapName in positions)) return;
const { players } = data;
const playersLeft = players.filter(player => player.team.orientation === "left");
const playersRight = players.filter(player => player.team.orientation === "right");
const leftTeam = playersLeft[0].team;
const rightTeam = playersRight[0].team;
if (!leftTeam || !rightTeam) return;
let htmlEntry = ``;
htmlEntry += `<div class="teamContainer"><div class="teamName ${leftTeam.side}">${leftTeam.name}</div>${playersLeft.map(player => `
<div class="playerEntry">
<div class="playerUsername">${player.name}</div>
<div class="playerStats">${player.stats.kills}</div>
<div class="playerStats">${player.stats.assists}</div>
<div class="playerStats">${player.stats.deaths}</div>
</div>
`).join('')}</div>`;
htmlEntry += `<div class="teamContainer"><div class="teamName ${rightTeam.side}">${rightTeam.name}</div>${playersRight.map(player => `
<div class="playerEntry">
<div class="playerUsername">${player.name}</div>
<div class="playerStats">${player.stats.deaths}</div>
<div class="playerStats">${player.stats.assists}</div>
<div class="playerStats">${player.stats.kills}</div>
</div>
`).join('')}</div>`;
if (lastContent !== htmlEntry) {
lastContent = htmlEntry;
updateScoreboard(htmlEntry, mapName);
}
});
}
const cleanUpARModule = (scene, GSI) => {
if (mesh) {
scene.remove(mesh);
}
GSI.removeAllListeners("data");
}
export { startARModule, cleanUpARModule };
+59
View File
@@ -0,0 +1,59 @@
#playerCanvas {
width: 400px;
display: flex;
background: rgba(0, 0, 0, 0.7);
font-family: 'Montserrat';
font-size: 13px;
text-transform: uppercase;
padding-left: 10px;
position: absolute;
left: 400px;
padding-right: 10px;
justify-content: space-between;
transition: opacity 1s;
opacity:1;
}
#playerCanvas.hide {
opacity: 0;
}
.teamName {
width: 100%;
height: 30px;
display: flex;
align-items: center;
justify-content: space-around;
font-weight: 700;
}
.teamName img {
max-height: 25px;
}
.teamName.CT{
color: blue;
}
.teamName.T{
color: orange;
}
.playerEntry {
display: flex;
height: 25px;
align-items: center;
}
.teamContainer:nth-child(2) .playerEntry {
flex-direction: row-reverse;
}
.teamContainer:nth-child(2) .playerEntry .playerUsername {
text-align: right;
}
.playerUsername {
width: 120px;
}
.playerStats {
width: 20px;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}