Compare commits

...

4 Commits

Author SHA1 Message Date
Gregory519
b4a5dac46b обновлён плеер и загрузка 2026-06-03 12:12:03 +03:00
Gregory519
8b60fd541f загрузка плейсов 2026-06-03 12:05:21 +03:00
Gregory519
b0f9a6353b тест загрузка 2026-06-03 12:05:21 +03:00
Gregory519
2ec32077bf обновил загрузку плейсов 2026-06-03 12:05:21 +03:00
4 changed files with 2559 additions and 29 deletions

10
package-lock.json generated
View File

@ -65,7 +65,6 @@
"integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.29.0",
"@babel/generator": "^7.29.0",
@ -321,8 +320,7 @@
"version": "7.54.3",
"resolved": "https://registry.npmjs.org/@babylonjs/core/-/core-7.54.3.tgz",
"integrity": "sha512-P5ncXVd8GEUJLhwloP9V0oVwQYIrvZztguVeLlvd5Rx+9aQnenKjpV8auJ6SRsUlAmNZU4pFTKzwF6o2EUfhAw==",
"license": "Apache-2.0",
"peer": true
"license": "Apache-2.0"
},
"node_modules/@babylonjs/loaders": {
"version": "7.54.3",
@ -1495,7 +1493,6 @@
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@ -1802,7 +1799,6 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.10.12",
"caniuse-lite": "^1.0.30001782",
@ -2466,7 +2462,6 @@
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
@ -4278,7 +4273,6 @@
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
},
@ -4291,7 +4285,6 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.2"
@ -5151,7 +5144,6 @@
"integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"esbuild": "^0.21.3",
"postcss": "^8.4.43",

View File

@ -22,7 +22,7 @@ import { useAuth } from '../auth/PlayerAuth';
import RublocsLogo from '../components/RublocsLogo/RublocsLogo';
import useDeviceType from '../hooks/useDeviceType';
import KubikonMobileControls from './KubikonMobileControls';
// загрузка плейсов начинается на строке 1181
// Плеер живёт на player.rublox.pro он не знает SPA-роутов Майнкрафтии
// (/kubikon, /login, /auth). Поэтому вместо navigate(...) делаем
// явный window.location.assign на внешний домен.
@ -252,6 +252,9 @@ const KubikonPlayer = () => {
// Появляется после submitLeaderboard если бэк выдал rating_award текущему юзеру.
// null | { place: 1|2|3, amount: number }
const [ratingToast, setRatingToast] = useState(null);
const [placeName, setPlaceName] = useState('Загрузка игры…');
const [placeImage, setPlaceImage] = useState(null);
const [studioName, setStudioName] = useState(null);
const timerRafRef = useRef(null);
/** Кэш загруженного project_data для soft-restart игры. */
const initialStateRef = useRef(null);
@ -686,6 +689,47 @@ const KubikonPlayer = () => {
return () => { alive = false; clearInterval(t); };
}, [projectId, userId, sessionId, loading]);
// Загрузка названия и картинки плейса с сервера
// Загрузка названия, картинки и автора плейса с сервера
// Загрузка названия, картинки и автора плейса
useEffect(() => {
if (!projectId) return;
if (!userId) {
console.log('[Loading] Ждём userId...');
return; // Ждём пока userId загрузится
}
async function loadPlaceData() {
try {
// Пытаемся загрузить данные через API
const response = await Kubikon3DApi.getProjectForPlay(projectId, userId);
const title = response?.data?.title;
const thumbnail = response?.data?.thumbnail;
const author = response?.data?.author_username;
if (title) {
setPlaceName(title);
} else {
setPlaceName(`Плейс ${projectId}`);
}
if (thumbnail) {
setPlaceImage(thumbnail);
}
if (author) {
setStudioName(author);
}
} catch (error) {
console.warn('[KubikonPlayer] Не удалось загрузить данные плейса:', error);
setPlaceName(`Плейс ${projectId}`);
}
}
loadPlaceData();
}, [projectId, userId]); // Убрал meta из зависимостей!
// Хоткеи 1-5 для слотов инвентаря.
// Babylon ловит ввод на canvas слушаем в capture-phase на window
// и не привязываемся к isPlaying (state-флаг может быть ещё false на старте).
@ -1134,13 +1178,14 @@ const KubikonPlayer = () => {
}}
/>
{/* Loading-оверлей */}
{/*не меняйте пожалуйста загрузку, работаю над ней*/}
{loading && (
<div style={{
position: 'absolute', inset: 0,
display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
background:
'radial-gradient(ellipse at center, rgba(51,87,255,0.22) 0%, rgba(7,10,20,0.96) 60%)',
background: 'radial-gradient(ellipse at center, rgba(51,87,255,0.22) 0%, rgba(7,10,20,0.96) 60%)',
gap: 18, color: HUD.text,
zIndex: 50,
}}>
<div style={{
position: 'relative',
@ -1151,29 +1196,54 @@ const KubikonPlayer = () => {
borderRadius: 20,
animation: 'hudPulseRing 1.6s ease-out infinite',
}} />
<RublocsLogo size={72} />
{placeImage ? (
<img
src={placeImage}
alt={placeName}
style={{
width: 90, height: 90,
borderRadius: 16,
objectFit: 'cover',
boxShadow: '0 6px 20px rgba(0,0,0,0.4)',
}}
/>
) : (
<RublocsLogo size={90} />
)}
</div>
{/* Полупрозрачный тёмно-серый пузырь для текста */}
<div style={{
display: 'flex', alignItems: 'center', gap: 10,
fontSize: 15, fontWeight: 700, letterSpacing: 0.3,
background: 'rgba(30, 35, 55, 0.6)',
borderRadius: 60,
padding: '10px 24px',
marginTop: 8,
}}>
<div style={{
width: 14, height: 14,
border: `2.5px solid ${HUD.accentBg}`,
borderTopColor: HUD.accent,
borderRadius: '50%',
animation: 'hudSpin 0.8s linear infinite',
}} />
Загрузка игры
</div>
<div style={{
fontSize: 11, color: HUD.textDim,
textTransform: 'uppercase', letterSpacing: 1.4, fontWeight: 700,
}}>
Рублокс 3D
</div>
display: 'flex', alignItems: 'center', gap: 10,
fontSize: 15, fontWeight: 700, letterSpacing: 0.3,
}}>
<div style={{
width: 14, height: 14,
border: `2.5px solid ${HUD.accentBg}`,
borderTopColor: "#ffffff",
borderRadius: '50%',
animation: 'hudSpin 0.8s linear infinite',
}} />
{placeName || 'Загрузка игры…'}
</div>
<div style={{
fontSize: 13, color: HUD.textDim,
textTransform: 'uppercase', letterSpacing: 1.4, fontWeight: 700,
textAlign: 'center',
marginTop: 6,
}}>
{studioName || 'Имя автора'}
</div>
</div>
</div>
)}
{/* Игровой UI (HUD, GUI, hotbar, прицел в первом лице) */}
{/* Игровой UI (HUD, GUI, hotbar, прицел в первом лице) */}
{!loading && (

View File

@ -0,0 +1,40 @@
{loading && (
<div style={{
position: 'absolute', inset: 0,
display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
background:
'radial-gradient(ellipse at center, rgba(51,87,255,0.22) 0%, rgba(7,10,20,0.96) 60%)',
gap: 18, color: HUD.text,
}}>
<div style={{
position: 'relative',
animation: 'hudFloat 3s ease-in-out infinite',
}}>
<div style={{
position: 'absolute', inset: -10,
borderRadius: 20,
animation: 'hudPulseRing 1.6s ease-out infinite',
}} />
<RublocsLogo size={72} />
</div>
<div style={{
display: 'flex', alignItems: 'center', gap: 10,
fontSize: 15, fontWeight: 700, letterSpacing: 0.3,
}}>
<div style={{
width: 14, height: 14,
border: `2.5px solid ${HUD.accentBg}`,
borderTopColor: HUD.accent,
borderRadius: '50%',
animation: 'hudSpin 0.8s linear infinite',
}} />
Загрузка игры…
</div>
<div style={{
fontSize: 11, color: HUD.textDim,
textTransform: 'uppercase', letterSpacing: 1.4, fontWeight: 700,
}}>
Рублокс • 3D
</div>
</div>
)}

File diff suppressed because it is too large Load Diff