Skip to content

Instantly share code, notes, and snippets.

@RimuruDev
Created November 4, 2023 21:51
Show Gist options
  • Save RimuruDev/4fd26f3c03fa414fc96947ded19b6951 to your computer and use it in GitHub Desktop.
Save RimuruDev/4fd26f3c03fa414fc96947ded19b6951 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>{{{ PRODUCT_NAME }}}</title>
<link rel="shortcut icon" href="TemplateData/favicon.ico">
<link rel="stylesheet" href="TemplateData/style.css">
<!-- Yandex Games SDK -->
<script src="https://yandex.ru/games/sdk/v2"></script>
<!-- Yandex.Metrika counter -->
#if BANNER_DYNAMIC_1
<style>
#RTB1 {
position: fixed;
display: none;
}
#RTB1.show {
display: block;
}
</style>
#endif
#if BANNER_DYNAMIC_2
<style>
#RTB2 {
position: fixed;
display: none;
}
#RTB2.show {
display: block;
}
</style>
#endif
#if BANNER_STATIC_1
<style>
#RTBStatic1 {
position: fixed;
width: 80%;
height: 15%;
left: 10%;
bottom: 0;
display: none;
}
#RTBStatic1.show {
display: block;
}
@media screen and (max-width: 800px) {
#RTBStatic1 {
width: 320px;
height: 50px;
left: 50%;
transform: translateX(-50%);
}
}
</style>
#endif
#if BANNER_STATIC_2
<style>
#RTBStatic2 {
position: fixed;
width: 80%;
height: 15%;
left: 10%;
top: 0;
display: none;
}
#RTBStatic2.show {
display: block;
}
@media screen and (max-width: 800px) {
#RTBStatic2 {
width: 320px;
height: 50px;
left: 50%;
transform: translateX(-50%);
}
}
</style>
#endif
</head>
<body class="{{{ SPLASH_SCREEN_STYLE.toLowerCase() }}}">
<div id="unity-container" class="unity-desktop">
<canvas id="unity-canvas"></canvas>
</div>
<div id="loading-cover" style="display:none;">
<div id="unity-loading-bar">
<div id="unity-logo"><img src="logo.png"></div>
<div id="unity-progress-bar-empty" style="display: none;">
<div id="unity-progress-bar-full"></div>
</div>
<div class="spinner"></div>
</div>
</div>
#if BANNER_DYNAMIC_1
<div id="RTB1">
<script>
const rbt1 = document.querySelector('#RTB1');
function ExecuteCodeRTB1() {
try {
{{{ BANNER_DYNAMIC_1 }}}
} catch (e) {
console.error('CRASH Render RTB1: ', e.message);
}
}
function ActivityRTB1(state) {
try {
if (state) {
rbt1.classList.add('show');
} else {
rbt1.classList.remove('show');
}
} catch (e) {
console.error('CRASH Activity RTB1: ', e.message);
}
}
function RecalculateRTB1(_width, _height, _left, _top) {
try {
document.getElementById('RTB1').style.width = _width;
document.getElementById('RTB1').style.height = _height;
document.getElementById('RTB1').style.left = _left;
document.getElementById('RTB1').style.top = _top;
} catch (e) {
console.error('CRASH Recalculate RTB1: ', e.message);
}
}
</script>
</div>
#endif
#if BANNER_DYNAMIC_2
<div id="RTB2">
<script>
const rbt2 = document.querySelector('#RTB2');
function ExecuteCodeRTB2() {
try {
{{{ BANNER_DYNAMIC_2 }}}
} catch (e) {
console.error('CRASH Render RTB2: ', e.message);
}
}
function ActivityRTB2(state) {
try {
if (state) {
rbt2.classList.add('show');
} else {
rbt2.classList.remove('show');
}
} catch (e) {
console.error('CRASH Activity RTB2: ', e.message);
}
}
function RecalculateRTB2(_width, _height, _left, _top) {
try {
document.getElementById('RTB2').style.width = _width;
document.getElementById('RTB2').style.height = _height;
document.getElementById('RTB2').style.left = _left;
document.getElementById('RTB2').style.top = _top;
} catch (e) {
console.error('CRASH Recalculate RTB2: ', e.message);
}
}
</script>
</div>
#endif
#if BANNER_STATIC_1
<div id="RTBStatic1">
<script>
const rbtLoadGame1 = document.querySelector('#RTBStatic1');
rbtLoadGame1.classList.add('show');
function ExecuteCodeStaticRTB1() {
try {
if (document.getElementById('RTBStatic1').style.display !== 'none') {
{{{ BANNER_STATIC_1 }}}
}
} catch (e) {
console.error('CRASH Render Static RTB1: ', e.message);
}
}
ExecuteCodeStaticRTB1();
</script>
</div>
#endif
#if BANNER_STATIC_2
<div id="RTBStatic2">
<script>
const rbtLoadGame2 = document.querySelector('#RTBStatic2');
rbtLoadGame2.classList.add('show');
function ExecuteCodeStaticRTB2() {
try {
if (document.getElementById('RTBStatic2').style.display !== 'none') {
{{{ BANNER_STATIC_2 }}}
}
} catch (e) {
console.error('CRASH Render Static RTB2: ', e.message);
}
}
ExecuteCodeStaticRTB2();
</script>
</div>
#endif
<script>
const hideFullScreenButton = "";
const buildUrl = "Build";
const loaderUrl = buildUrl + "/{{{ LOADER_FILENAME }}}";
const config = {
dataUrl: buildUrl + "/{{{ DATA_FILENAME }}}",
frameworkUrl: buildUrl + "/{{{ FRAMEWORK_FILENAME }}}",
codeUrl: buildUrl + "/{{{ CODE_FILENAME }}}",
#if MEMORY_FILENAME
memoryUrl: buildUrl + "/{{{ MEMORY_FILENAME }}}",
#endif
#if SYMBOLS_FILENAME
symbolsUrl: buildUrl + "/{{{ SYMBOLS_FILENAME }}}",
#endif
streamingAssetsUrl: "StreamingAssets",
companyName: "{{{ COMPANY_NAME }}}",
productName: "{{{ PRODUCT_NAME }}}",
productVersion: "{{{ PRODUCT_VERSION }}}",
};
const container = document.querySelector("#unity-container");
const canvas = document.querySelector("#unity-canvas");
const loadingCover = document.querySelector("#loading-cover");
const progressBarEmpty = document.querySelector("#unity-progress-bar-empty");
const progressBarFull = document.querySelector("#unity-progress-bar-full");
const spinner = document.querySelector('.spinner');
const canFullscreen = (function () {
for (const key of [
'exitFullscreen',
'webkitExitFullscreen',
'webkitCancelFullScreen',
'mozCancelFullScreen',
'msExitFullscreen',
]) {
if (key in document) {
return true;
}
}
return false;
}());
if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
container.className = "unity-mobile";
config.devicePixelRatio = 1;
}
var backgroundUnity = "url('" + buildUrl + "/{{{ BACKGROUND_FILENAME.replace(/'/g, '%27') }}}') center / cover";
canvas.style.background = "url('background.png') center / cover";
loadingCover.style.display = "";
canvas.addEventListener("touchstart", () => { window.focus() });
canvas.addEventListener("pointerdown", () => { window.focus() });
let player;
let leaderboard;
let myGameInstance = null;
let payments = null;
let promptCanShow = false;
let reviewCanShow = false;
let initSDK = false;
let initGame = false;
let photoSizeForInit;
let scopesForInit;
let firstAd = true;
const script = document.createElement("script");
script.src = loaderUrl;
script.onload = () => {
createUnityInstance(canvas, config, (progress) => {
spinner.style.display = "none";
progressBarEmpty.style.display = "";
progressBarFull.style.width = `${100 * progress}%`;
}).then((unityInstance) => {
myGameInstance = unityInstance;
loadingCover.style.display = "none";
}).catch((message) => {
alert(message);
});
};
YaGames.init()
.then(ysdk => {
console.log('Init Yandex SDK');
window.ysdk = ysdk;
initSDK = true;
InitPayments();
try {
ysdk.shortcut.canShowPrompt().then(prompt => {
if (prompt.canShow) {
promptCanShow = true;
}
});
} catch (e) {
console.error('CRASH canShowPrompt: ', e.message);
}
try {
ysdk.feedback.canReview().then(({ value, reason }) => {
if (value) {
reviewCanShow = true;
} else {
console.log('reviewCanShow = false', reason)
}
})
ysdk.shortcut.canShowPrompt().then(prompt => {
if (prompt.canShow) {
promptCanShow = true;
}
});
} catch (e) {
console.error('CRASH canShowFeedback: ', e.message);
}
if (initGame == true) {
InitSDK(photoSizeForInit, scopesForInit)
if (firstAd)
FullscreenShow();
}
else {
if (firstAd)
ysdk.adv.showFullscreenAdv();
}
});
function InitSDK(photoSize, scopes) {
console.log('Init GAME');
initGame = true;
photoSizeForInit = photoSize;
scopesForInit = scopes;
if (initSDK == true) {
ysdk.features.LoadingAPI?.ready();
InitPlayer(photoSize, scopes);
}
}
function NotAuthorized() {
try {
console.log('Authorized failed');
let authJson = {
"playerAuth": "rejected",
"playerName": "unauthorized",
"playerId": "unauthorized",
"playerPhoto": "null"
};
myGameInstance.SendMessage('YandexGame', 'SetInitializationSDK', JSON.stringify(authJson));
} catch (e) {
console.error('CRASH Not Authorized: ', e.message);
}
}
function InitPlayer(photoSize, _scopes) {
try {
return ysdk.getPlayer({scopes: _scopes}).then(_player => {
player = _player;
let playerName = player.getName();
let playerPhoto = player.getPhoto(photoSize);
if (!_scopes) {
playerName = "anonymous";
playerPhoto = "null";
}
if (player.getMode() === 'lite') {
console.log('Not Authorized');
NotAuthorized();
} else {
let authJson = {
"playerAuth": "resolved",
"playerName": playerName,
"playerId": player.getUniqueID(),
"playerPhoto": playerPhoto
};
myGameInstance.SendMessage('YandexGame', 'SetInitializationSDK', JSON.stringify(authJson));
window.focus();
}
}).catch(e => {
console.error('Authorized err: ', e.message);
NotAuthorized();
});
} catch (e) {
console.error('CRASH init Player: ', e.message);
window.focus();
}
}
function OpenAuthDialog(photoSize, scopes) {
try {
ysdk.auth.openAuthDialog().then(() => {
InitPlayer(photoSize, scopes);
}).catch(() => {
InitSDK(photoSize, scopes);
});
} catch (e) {
console.log('CRASH Open Auth Dialog: ', e.message);
}
}
function FullAdShow() {
try {
window.ysdk.adv.showFullscreenAdv(
{
callbacks: {
onOpen: () => {
console.log('Open Fullscreen Ad');
myGameInstance.SendMessage('YandexGame', 'OpenFullAd');
},
onClose: (wasShown) => {
if (wasShown) myGameInstance.SendMessage('YandexGame', 'CloseFullAd', 'true');
else myGameInstance.SendMessage('YandexGame', 'CloseFullAd', 'false');
window.focus();
},
onError: (error) => {
console.error('Error Fullscreen Ad', error);
myGameInstance.SendMessage('YandexGame', 'ErrorFullAd');
window.focus();
}
}
});
} catch (e) {
console.error('CRASH FullAd Show: ', e.message);
}
}
function RewardedShow(id) {
try {
window.ysdk.adv.showRewardedVideo(
{
callbacks:
{
onOpen: () => {
console.log('Opened Video Ad. Id: ' + id);
myGameInstance.SendMessage('YandexGame', 'OpenVideo');
},
onClose: () => {
console.log('Closed Video Ad. Id: ' + id);
myGameInstance.SendMessage('YandexGame', 'CloseVideo');
window.focus();
},
onRewarded: () => {
console.log('Reward Video Ad. Id: ' + id);
myGameInstance.SendMessage('YandexGame', 'RewardVideo', id);
},
onError: (e) => {
console.error('Error Video Ad. Id: ' + id, e);
myGameInstance.SendMessage('YandexGame', 'ErrorVideo');
}
}
});
} catch (err) {
console.error('CRASH Rewarded Video Ad Show: ', err.message);
}
}
function StickyAdActivity(show) {
try {
ysdk.adv.getBannerAdvStatus().then(({ stickyAdvIsShowing, reason }) => {
if (stickyAdvIsShowing) {
if (!show) {
ysdk.adv.hideBannerAdv();
}
}
else if (reason) {
console.log('Sticky ad are not shown. Reason:', reason);
}
else if (show) {
ysdk.adv.showBannerAdv();
}
})
} catch (e) {
console.error('CRASH Sticky Activity: ', e.message);
}
}
function InitPayments() {
try {
ysdk.getPayments().then(_payments => {
console.log('Purchases are available');
payments = _payments;
}).catch(e => {
console.log('Purchases are not available', e.message);
})
} catch (e) {
console.error('CRASH Init Payments: ', e.message);
}
}
function BuyPayments(id) {
try {
if (payments != null) {
payments.purchase(id).then(purchase => {
console.log('Purchase Success');
myGameInstance.SendMessage('YandexGame', 'OnPurchaseSuccess', id);
window.focus();
}).catch(e => {
console.error('Purchase Failed', e.message);
myGameInstance.SendMessage('YandexGame', 'OnPurchaseFailed', id);
window.focus();
})
} else {
console.log('Payments == null');
}
} catch (e) {
console.error('CRASH Buy Payments: ', e.message);
window.focus();
}
}
function GetPayments() {
try {
if (payments != null) {
payments.getCatalog()
.then(products => {
let productID = [products.length];
let title = [products.length];
let description = [products.length];
let imageURI = [products.length];
let priceValue = [products.length];
let purchased = [products.length];
for (i = 0; i < products.length; i++) {
productID[i] = products[i].id;
title[i] = products[i].title;
description[i] = products[i].description;
imageURI[i] = products[i].imageURI;
priceValue[i] = products[i].priceValue;
purchased[i] = 0;
}
payments.getPurchases().then(purchases => {
for (i1 = 0; i1 < products.length; i1++) {
for (i2 = 0; i2 < purchases.length; i2++) {
if (products[i1].id === purchases[i2].productID){
purchased[i1]++;
}
}
}
})
.then(() => {
var jsonPayments = {
"id": productID,
"title": title,
"description": description,
"imageURI": imageURI,
"priceValue": priceValue,
"purchased": purchased
};
myGameInstance.SendMessage('YandexGame', 'PaymentsEntries', JSON.stringify(jsonPayments));
})
});
}
else{
console.log('Get Payments: payments == null');
}
} catch (e) {
console.error('CRASH Get Payments: ', e.message);
}
}
function DeletePurchase(id) {
try {
if (payments != null) {
payments.getPurchases().then(purchases => {
for(i = 0; i < purchases.length; i++){
if (purchases[i].productID === id)
payments.consumePurchase(purchases[i].purchaseToken);
}
});
}
else console.log('Delete Purchase: payments == null');
} catch (e) {
console.error('CRASH Delete Purchase: ', e.message);
}
}
function DeleteAllPurchases() {
try {
if (payments != null) {
payments.getPurchases().then(purchases => {
for(i = 0; i < purchases.length; i++){
payments.consumePurchase(purchases[i].purchaseToken);
}
});
}
else console.log('Delete All Purchases: payments == null');
} catch (e) {
console.error('CRASH Delete All Purchases: ', e.message);
}
}
function SaveCloud(jsonData, flush) {
try {
player.setData({
saves: [jsonData],
}, flush);
} catch (e) {
console.error('CRASH Save Cloud: ', e.message);
}
}
function LoadCloud() {
try {
player.getData(["saves"]).then(data => {
if (data.saves) {
myGameInstance.SendMessage('YandexGame', 'SetLoadSaves', JSON.stringify(data.saves));
} else {
myGameInstance.SendMessage('YandexGame', 'SetLoadSaves', "noData");
}
}).catch(() => {
console.error('getData Error!');
myGameInstance.SendMessage('YandexGame', 'SetLoadSaves', "noData");
});
} catch (e) {
console.error('CRASH Load saves Cloud: ', e.message);
myGameInstance.SendMessage('YandexGame', 'SetLoadSaves', "noData");
}
}
function InitLeaderboard() {
try {
ysdk.getLeaderboards().then(_lb => {
leaderboard = _lb
myGameInstance.SendMessage('YandexGame', 'InitializedLB');
});
} catch (e) {
console.error('CRASH Init Leaderboard: ', e.message);
}
}
function SetLeaderboardScores(_name, score) {
try {
ysdk.getLeaderboards()
.then(leaderboard => {
leaderboard.setLeaderboardScore(_name, score);
});
} catch (e) {
console.error('CRASH Set Leader board Scores: ', e.message);
}
}
function GetLeaderboardScores(nameLB, maxPlayers, quantityTop, quantityAround, photoSize, auth) {
if (auth) {
try {
ysdk.getLeaderboards()
.then(leaderboard => {
leaderboard.getLeaderboardEntries('' + nameLB, {
quantityTop: quantityTop,
includeUser: true,
quantityAround: quantityAround
})
.then(res => {
EntriesLB(res, nameLB, maxPlayers, photoSize);
});
});
} catch (e) {
console.error('CRASH Get Leaderboard Scores: ', e.message);
}
} else {
try {
ysdk.getLeaderboards()
.then(leaderboard => {
leaderboard.getLeaderboardEntries('' + nameLB, {quantityTop: quantityTop})
.then(res => {
EntriesLB(res, nameLB, maxPlayers, photoSize);
});
});
} catch (e) {
console.error('CRASH Get Leaderboard Scores: ', e.message);
}
}
}
function EntriesLB(res, nameLB, maxPlayers, photoSize) {
let LeaderboardEntriesText = '';
let playersCount;
if (res.entries.length < maxPlayers) {
playersCount = res.entries.length;
} else {
playersCount = maxPlayers;
}
let rank = [maxPlayers];
let photo = [maxPlayers];
let playersName = [maxPlayers];
let scorePlayers = [maxPlayers];
for (i = 0; i < playersCount; i++) {
rank[i] = res.entries[i].rank;
scorePlayers[i] = res.entries[i].score;
if (photoSize === 'nonePhoto' || res.entries[i].player.scopePermissions.avatar !== "allow") {
photo[i] = 'nonePhoto';
} else {
photo[i] = res.entries[i].player.getAvatarSrc(photoSize);
}
if (res.entries[i].player.scopePermissions.public_name !== "allow") {
playersName[i] = "anonymous";
} else {
playersName[i] = res.entries[i].player.publicName;
}
LeaderboardEntriesText += rank[i] + '. ' + playersName[i] + ": " + scorePlayers[i] + '\n';
}
if (playersCount === 0) {
LeaderboardEntriesText = 'No data';
}
let jsonLB = {
"nameLB": nameLB,
"entries": LeaderboardEntriesText,
"rank": rank,
"photo": photo,
"playersName": playersName,
"scorePlayers": scorePlayers
};
myGameInstance.SendMessage('YandexGame', 'LeaderboardEntries', JSON.stringify(jsonLB));
}
function LanguageRequest() {
try {
myGameInstance.SendMessage('YandexGame', 'SetLanguage', ysdk.environment.i18n.lang);
} catch (e) {
console.error('CRASH Language Request: ', e.message);
}
}
function RequestingEnvironmentData() {
try {
let jsonEnvir = {
"language": ysdk.environment.i18n.lang,
"domain": ysdk.environment.i18n.tld,
"deviceType": ysdk.deviceInfo.type,
"isMobile": ysdk.deviceInfo.isMobile(),
"isDesktop": ysdk.deviceInfo.isDesktop(),
"isTablet": ysdk.deviceInfo.isTablet(),
"isTV": ysdk.deviceInfo.isTV(),
"appID": ysdk.environment.app.id,
"browserLang": ysdk.environment.browser.lang,
"payload": ysdk.environment.payload,
"promptCanShow": promptCanShow,
"reviewCanShow": reviewCanShow
};
myGameInstance.SendMessage('YandexGame', 'SetEnvironmentData', JSON.stringify(jsonEnvir));
} catch (e) {
console.error('CRASH Requesting Environment Data: ', e.message);
}
}
function Review() {
try {
ysdk.feedback.canReview()
.then(({ value, reason }) => {
if (value) {
ysdk.feedback.requestReview().then(({feedbackSent}) => {
console.log('feedbackSent ', feedbackSent);
if (feedbackSent)
myGameInstance.SendMessage('YandexGame', 'ReviewSent', 'true');
else myGameInstance.SendMessage('YandexGame', 'ReviewSent', 'false');
window.focus();
})
}
else {
console.log('reviewCanShow = false', reason)
window.focus();
}
})
} catch (e) {
console.error('CRASH Review: ', e.message);
window.focus();
}
}
function PromptShow() {
try {
ysdk.shortcut.showPrompt()
.then(result => {
console.log('Shortcut created?:', result);
if (result.outcome === 'accepted') {
console.log('Prompt Success');
myGameInstance.SendMessage('YandexGame', 'OnPromptSuccess');
}
else {
myGameInstance.SendMessage('YandexGame', 'OnPromptFail');
}
window.focus();
});
} catch (e) {
console.error('CRASH Prompt Show: ', e.message);
window.focus();
}
}
function PaintRBT(rbt) {
try {
document.getElementById(rbt).style.background = '#ff0000';
} catch (e) {
console.error('CRASH Paint RBT: ', e.message);
}
}
function StaticRBTDeactivate() {
#if BANNER_STATIC_1
try {
rbtLoadGame1.classList.remove('show');
document.getElementById('RTBStatic1').style.display = 'none';
} catch (e) {
console.error('CRASH off RTBStatic1: ', e.message);
}
#endif
#if BANNER_STATIC_2
try {
rbtLoadGame2.classList.remove('show');
document.getElementById('RTBStatic2').style.display = 'none';
} catch (e) {
console.error('CRASH off RTBStatic2: ', e.message);
}
#endif
}
document.body.appendChild(script);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment