mirror of
https://github.com/lexogrine/dota2-react-hud.git
synced 2026-05-04 04:23:10 +02:00
init
This commit is contained in:
@@ -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
@@ -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 };
|
||||
@@ -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%;
|
||||
}
|
||||
Reference in New Issue
Block a user