diff --git a/css/style.css b/css/style.css new file mode 100644 index 0000000..041da53 --- /dev/null +++ b/css/style.css @@ -0,0 +1,229 @@ +html { + box-sizing: border-box; +} + +*, +*:before, +*:after { + box-sizing: inherit; +} + +body { + margin: 0; + background: #000!important; + overflow: hidden; +} + +#gameContainer { + width: 100vw; + height: 100vh; + background: #000!important; +} + +#canvas { + width: 100%; + height: 100%; + display: block; +} +/* try to handle mobile dialog */ + +#canvas + * { + z-index: 2; +} + +.logo { + display: block; + max-width: 15vw; + max-height: 15vh; +} + +.progress { + margin: 1.5em; + border: 1px solid white; + width: 30vw; + display: none; +} + +.progress .full { + margin: 2px; + background: white; + height: 1em; + transform-origin: top left; +} + +#loader { + position: absolute; + left: 0; + top: 0; + width: 100vw; + height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.spinner, +.spinner:after { + border-radius: 50%; + width: 5em; + height: 5em; +} + +#unity-progress-bar-empty { + width: 30%; + height: 24px; + margin: 10px 20px 20px 10px; + text-align: left; + border: 1px solid white; + padding: 2px; +} +#unity-progress-bar-full { + width: 0%; + height: 100%; + background: white; +} +.light #unity-progress-bar-empty { + border-color: black; +} +.light #unity-progress-bar-full { + background: black; +} + +.spinner { + margin: 10px; + font-size: 10px; + position: relative; + text-indent: -9999em; + border-top: 1.1em solid rgba(255, 255, 255, 0.2); + border-right: 1.1em solid rgba(255, 255, 255, 0.2); + border-bottom: 1.1em solid rgba(255, 255, 255, 0.2); + border-left: 1.1em solid #ffffff; + transform: translateZ(0); + animation: spinner-spin 1.1s infinite linear; +} + +@keyframes spinner-spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} + +.ad { + background: rgba(0, 0, 0, 0.4); + overflow: hidden; + display: none; +} + +.modal{ + background:rgba(0,0,0,.4); + display:none; + height:100%; + width: 100%; + position:fixed; + z-index:10000; + top: 0; + left: 0; + bottom: 0; + right: 0; +} + +.modalContent{ + margin: auto; + width: 100%; +} + +.centered { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +/* The Close Button */ +.close { + color: #aaa; + float: right; + font-size: 28px; + font-weight: bold; +} + +.close:hover, +.close:focus { + color: black; + text-decoration: none; + cursor: pointer; +} + +#continueWindow{ + background-color: #fefefe; + margin: 15% auto; + padding: 20px; + border: 1px solid #888; + width: 30%; +} + +#adWindow{ + background: #4382f5; + border: 10px solid #4382f5; + width: 660px; + border-top: 0; + height: 540px; +} + +.ads{ + height:100%; + display: flex; + flex-direction: column; + justify-content: space-evenly; + position: absolute; + z-index:40; +} + +.ad-rectangle-bottom { + width: 304px; + height: 258px; + border-style: solid; + border-width: 4px 4px 4px 0px; + border-color: rgba(0, 0, 0, 0.01); +} + +.ad-rectangle-upper { + width: 304px; + height: 258px; + border-style: solid; + border-width: 4px 4px 4px 0px; + border-color: rgba(0, 0, 0, 0.01); +} +.ad-leaderboard-bottom { + width: 304px; + height: 608px; + border-style: solid; + border-width: 4px 4px 4px 0px; + border-color: rgba(0, 0, 0, 0.01); +} + +@media (min-height: 900px) { + .ad-smallscreen{ + display: none; + } +} + +@media (max-height: 900px) { + .ad-largescreen{ + display: none; + } +} + +#adWindow { + border: 10px solid #4382f5 !important; + height: 500px !important; +} + +a[onclick*="showConsentToolSettings"] { + right: 0px; + left: auto !important; +} \ No newline at end of file diff --git a/img/favicon.png b/img/favicon.png new file mode 100644 index 0000000..f35b214 Binary files /dev/null and b/img/favicon.png differ diff --git a/img/logo.png b/img/logo.png new file mode 100644 index 0000000..b50e96f Binary files /dev/null and b/img/logo.png differ diff --git a/js/IronSourceRV.js b/js/IronSourceRV.js new file mode 100644 index 0000000..0285d99 --- /dev/null +++ b/js/IronSourceRV.js @@ -0,0 +1,33 @@ +window.InitRV = function InitRV(id) { + $.getScript("https://static.ultra-rv.com/rv-min.js", function () { + + let userId = id === undefined ? "Guest" : id; + let ironRV = IronRV.getInstance({ + applicationKey: "1-mb5whk", + applicationUserId: userId, + }); + + ironRV.addListener(IronRV.EVENTS.READY, function () { + window.unityInstance.SendMessage("MainMenuManagers", "RvReady"); + }); + + ironRV.addListener(IronRV.EVENTS.CLOSE, function () { + window.unityInstance.SendMessage("MainMenuManagers", "RvWatchComplete", "false"); + }); + + ironRV.addListener(IronRV.EVENTS.COMPLETION, function () { + window.unityInstance.SendMessage("MainMenuManagers", "RvWatchComplete", "true"); + }); + + ironRV.addListener(IronRV.EVENTS.AD_BLOCK, function () { + ironRV.showAdBlockMessage(); + }); + + ironRV.addListener(IronRV.EVENTS.INIT_ERROR, function () { + }); + + window.showRV = () => { + ironRV.show(); + }; + }); +} diff --git a/js/cpmstar.js b/js/cpmstar.js new file mode 100644 index 0000000..c905e81 --- /dev/null +++ b/js/cpmstar.js @@ -0,0 +1,60 @@ +//init the interstitial +window.adsLoaded = true; +let iAd; + +async function initAds() { + while (window.cpmstarAPI === undefined) { + await sleep(500) + } + window.cpmstarAPI(function (api) { + //console.log("Setting iAD") + iAd = new api.game.InterstitialView("interstitial"); + iAd.load(); + iAd.addEventListener("ad_opened", function (e) { + iAdPause(); //Pause the game when ad is open + }); + + iAd.addEventListener("ad_closed", function (e) { + setTimeout(function () { + iAdUnpause(); //Unpause when ad closed. + }, 700); + iAd.load(); //Preload another ad. + }); + }); +} + +function iAdPause() { + +} +function iAdUnpause() { + unityAdFinishedCallback("true") +} + + +window.requestNewAd = () => { + //console.log("requested AD") + //console.log(iAd) + if (iAd && iAd.isLoaded()) { + iAd.show(); //Show loaded ad + } + else { + if (iAd) iAd.load(); //If no ad available, load another + unityAdFinishedCallback("false") + } +} + +// This function calls Unity to tell the ad finished +function unityAdFinishedCallback(state) { + try { + if (window.unityInstance) { + window.unityInstance.SendMessage('PersistantObjects', 'OnWebCallback', state); + } + } + catch (error) { + console.log(error); + } +} + +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} \ No newline at end of file diff --git a/js/dependencyLoader.js b/js/dependencyLoader.js new file mode 100644 index 0000000..0f046f0 --- /dev/null +++ b/js/dependencyLoader.js @@ -0,0 +1,67 @@ +let dependencyUrls = [] +const maxLoadTimesTrys = 4; + +//Main Libraries +dependencyUrls.push("https://www.googletagmanager.com/gtag/js?id=UA-118283086-6", "https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"); +//Ads Libraries +dependencyUrls.push("js/ads-prebid.js", "js/IronSourceRV.js", "js/cpmstar.js", "js/adsController.js"); +//Firebase/Google Libraries +dependencyUrls.push("js/googleAnalytics.js", "js/firebase.js", "js/login.js", "js/firebase-config.js", "js/firestore.js") +//Game Libraries +dependencyUrls.push("js/unityUrls.js", "js/unityGame.js", "js/mobileRedirect.js", "js/fullscreen.js") +//etc. Libraries +dependencyUrls.push("js/windowResize.js", "js/adblockManager.js", "js/macUserAgent.js", "js/visibilityChangeListener.js", "PC/payment/js/xsolla.js") + +dynamicallyLoadScripts(); + +async function dynamicallyLoadScripts() { + for (let i = 0; i < dependencyUrls.length; i++) { + let url = dependencyUrls[i]; + let script = document.createElement("script"); + script.src = url; + + document.head.appendChild(script); + } + + let trys = 0; + while (window.loadedUrls === undefined || window.firebaseLoaded === undefined || window.adsLoaded === undefined + || window.gameScriptLoaded === undefined || window.configInit === undefined || window.adsControllerLoaded === undefined) { + await sleep(500) + trys++; + if(trys >= maxLoadTimesTrys) { + break; + } + } + + initAds(); + loadGame(); + initFirebaseLibraries(); + fixMacUserAgent(); +} + +function loadGame() { + let gameLoader = document.createElement("script") + gameLoader.src = getGameLoaderUrl(); + gameLoader.id = "unity-loader" + gameLoader.onload = function () { + showGame(); + }; + + let gameLoadDiv = document.getElementById("unity-loader-div"); + gameLoadDiv.innerHTML = ""; + gameLoadDiv.appendChild(gameLoader); +} + +function initFirebaseLibraries() { + initializeFireBase(); + initRemoteConfig(); +} + +function onUnityReady() { + checkAdBlock(); + sendConfig(); +} + +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} \ No newline at end of file diff --git a/js/firebase-config.js b/js/firebase-config.js new file mode 100644 index 0000000..66b0a2e --- /dev/null +++ b/js/firebase-config.js @@ -0,0 +1,48 @@ +window.configInit = true; + +let conf; +let initWasCalled = false; + +function initRemoteConfig() { + initWasCalled = true; + const remoteConfig = firebase.remoteConfig(); + remoteConfig.settings.minimumFetchIntervalMillis = 2000; + + remoteConfig.fetchAndActivate().then(() => { + conf = {}; + // Convert all of the remote config parameters to a dict: + for (const [key, value] of Object.entries(remoteConfig.getAll())) { + conf[key] = value.asString(); + } + }) + .catch((err) => { + console.warn("config error: " + err); + }); +} + +// Being called from unity embedded browser on pc version +async function getRemoteConfigAsync(onFinish) { + if (!initWasCalled) + initRemoteConfig(); + + while(conf === undefined) + { + await sleep(500) + } + + onFinish(conf); +} + +async function sendConfig() { + while(conf === undefined || window.unityInstance === undefined) + { + await sleep(500) + } + + await sleep(3000) + window.unityInstance.SendMessage('PersistantObjects', 'ActivateRemoteConfig', JSON.stringify(conf)); +} + +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} diff --git a/js/firebase.js b/js/firebase.js new file mode 100644 index 0000000..eaa81d3 --- /dev/null +++ b/js/firebase.js @@ -0,0 +1,59 @@ +window.firebaseLoaded = true; + +function initializeFireBase() { + var hostname = window.location.hostname; + + if(hostname.indexOf("dev1v1") >= 0 || hostname.indexOf("dev.1v1") >= 0 || hostname.indexOf("test1v1") >= 0 || hostname.indexOf("test.1v1") >= 0 || hostname.indexOf("localhost") >= 0) { + initializeFireBaseDev(); + } + else if(hostname.indexOf("rc.1v1") >= 0){ + initializeFireBaseRC(); + } + else{ + initializeFireBaseProd(); + } +} + +function initializeFireBaseProd(){ + // Your web app's Firebase configuration + var firebaseConfig = { + apiKey: "AIzaSyBPrAfspM9RFxuNuDtSyaOZ5YRjDBNiq5I", + authDomain: "1v1.lol", + databaseURL: "https://justbuild-cdb86.firebaseio.com", + projectId: "justbuild-cdb86", + storageBucket: "justbuild-cdb86.appspot.com", + messagingSenderId: "93158914000", + appId: "1:93158914000:web:e73a8b453338ab7c" + }; + // Initialize Firebase + firebase.initializeApp(firebaseConfig); +} + +function initializeFireBaseDev(){ + // Your web app's Firebase configuration + var firebaseConfig = { + apiKey: "AIzaSyANZ0SDhqoc62msSooQFs3SEb4XbC7gvk4", + authDomain: "dev.1v1.lol", + databaseURL: "https://dev1v1.firebaseio.com", + projectId: "dev1v1", + storageBucket: "dev1v1.appspot.com", + messagingSenderId: "90097883404", + appId: "1:90097883404:android:0931a7bbf3e74f2b9a5129" + }; + // Initialize Firebase + firebase.initializeApp(firebaseConfig); +} + +function initializeFireBaseRC(){ + // Your web app's Firebase configuration + var firebaseConfig = { + apiKey: "AIzaSyA1H3OsFttu-57p0f7mXxUdgJ2Y0iHZRJg", + authDomain: "rcfunctions1v1.firebaseapp.com", + projectId: "rcfunctions1v1", + storageBucket: "rcfunctions1v1.appspot.com", + messagingSenderId: "896755136685", + appId: "1:896755136685:web:1ccd8f30abdce578dbee24" + }; + // Initialize Firebase + firebase.initializeApp(firebaseConfig); +} \ No newline at end of file diff --git a/js/firestore.js b/js/firestore.js new file mode 100644 index 0000000..c196168 --- /dev/null +++ b/js/firestore.js @@ -0,0 +1,25 @@ +const cache = {}; +let callbackId = 0; + +// This is being called directly from unity. +function getFirestoreListener(collection, documentId, successCallback, errorCallback) { + callbackId++; + const id = callbackId; // capture value + const unsubscribe = firebase.firestore().collection(collection).doc(documentId).onSnapshot(doc => { + if (doc.exists) + successCallback([id, JSON.stringify(doc.data())]); + }, error => { + errorCallback(error.message); + }); + + cache[id] = unsubscribe; + return id; +} + +// This is being called directly from unity. +function detachFirestoreListener(id) { + if (cache[id] !== undefined) { + cache[id](); + delete cache[id]; + } +} \ No newline at end of file diff --git a/js/fullscreen.js b/js/fullscreen.js new file mode 100644 index 0000000..bf11d07 --- /dev/null +++ b/js/fullscreen.js @@ -0,0 +1,37 @@ +/* View in fullscreen */ +var elem = document.documentElement; +function openFullscreen() { + if (elem.requestFullscreen) { + elem.requestFullscreen(); + } else if (elem.mozRequestFullScreen) { /* Firefox */ + elem.mozRequestFullScreen(); + } else if (elem.webkitRequestFullscreen) { /* Chrome, Safari and Opera */ + elem.webkitRequestFullscreen(); + } else if (elem.msRequestFullscreen) { /* IE/Edge */ + elem.msRequestFullscreen(); + } +} + +/* Close fullscreen */ +function closeFullscreen() { + if (document.exitFullscreen) { + document.exitFullscreen(); + } else if (document.mozCancelFullScreen) { /* Firefox */ + document.mozCancelFullScreen(); + } else if (document.webkitExitFullscreen) { /* Chrome, Safari and Opera */ + document.webkitExitFullscreen(); + } else if (document.msExitFullscreen) { /* IE/Edge */ + document.msExitFullscreen(); + } +} + +function updateFullscreen() { + var isInFullScreen = (document.fullscreenElement && document.fullscreenElement !== null) || + (document.webkitFullscreenElement && document.webkitFullscreenElement !== null) || + (document.mozFullScreenElement && document.mozFullScreenElement !== null) || + (document.msFullscreenElement && document.msFullscreenElement !== null); + if (!isInFullScreen) + openFullscreen(); + else + closeFullscreen(); +} \ No newline at end of file diff --git a/js/googleAnalytics.js b/js/googleAnalytics.js new file mode 100644 index 0000000..102e71b --- /dev/null +++ b/js/googleAnalytics.js @@ -0,0 +1,8 @@ +window.dataLayer = window.dataLayer || []; + +function gtag() { + dataLayer.push(arguments); +} +gtag('js', new Date()); + +gtag('config', 'UA-118283086-6'); \ No newline at end of file diff --git a/js/login.js b/js/login.js new file mode 100644 index 0000000..4b36989 --- /dev/null +++ b/js/login.js @@ -0,0 +1,175 @@ +var tempErrorCreds; +var tempProviderName; + +// This is being called directly from unity. +function getSignInResults(successCallback, errorCallback) { + firebase.auth().getRedirectResult().then( + (result) => onFirebaseSignInSuccess(successCallback, errorCallback), + (err) => onFirebaseSignInError(err, errorCallback)); +} + +// This is being called directly from unity. +function retrieveIdToken(successCallback, errorCallback) { + if(firebase.auth().currentUser === null){ + if(errorCallback !== null) + errorCallback("User is null"); + return; + } + + firebase.auth().currentUser.getIdToken().then(function (idToken) { + var resultObj = { + token: idToken, + displayName: firebase.auth().currentUser.displayName + }; + + if (successCallback !== undefined) { + + successCallback(resultObj); + } + }) + .catch(function (error) { + console.log(error); + if (errorCallback !== undefined) + errorCallback(error.message); + }); +} + +function anonymousLogin(successCallback, errorCallback) { + var resultObj = { + token: "", + displayName: "guest" + }; + + if (successCallback !== undefined) { + + successCallback(resultObj); + } +} + +/** + * This is being called directly from unity. + * Use firebase auth. + * @param providerName for example - Google + * @param successCallback + * @param errorCallback + * @param useRedirect Use redirect auth or popup. Redirect the page to google auth, or open a popup for the auth. + * For the pc version (embedded browser) we use redirect, but for the webgl version we use a popup. + */ +function firebaseLogin(providerName, successCallback, errorCallback, useRedirect=false) { + if (providerName === "anonymous") { + anonymousLogin(successCallback, errorCallback); + return; + } + + var user = firebase.auth().currentUser; + + if(user != null && !user.isAnonymous){ + retrieveIdToken(successCallback, errorCallback); + return; + } + + var provider = getProvider(providerName); + firebase.auth().useDeviceLanguage(); + + if (useRedirect) { + firebase.auth().signInWithRedirect(provider); + } + else { + firebase.auth().signInWithPopup(provider) + .then((result) => onFirebaseSignInSuccess(successCallback, errorCallback)) + .catch((err) => onFirebaseSignInError(err, errorCallback)); + } +} + +function onFirebaseSignInSuccess (successCallback, errorCallback) { + console.log("Successful sign in"); + retrieveIdToken(successCallback, errorCallback); +} + +function onFirebaseSignInError(error, errorCallback) { + // Handle Errors here. + var errorCode = error.code; + var errorMessage = error.message; + // The email of the user's account used. + var email = error.email; + // The firebase.auth.AuthCredential type that was used. + tempErrorCreds = error.credential; + console.log(error); + + if (errorCallback !== undefined) + errorCallback(error.message); + + if (errorCode === 'auth/account-exists-with-different-credential') { + // User's email already exists. + // Get sign-in methods for this email. + firebase.auth().fetchSignInMethodsForEmail(email).then(function (methods) { + // the first method in the list will be the "recommended" method to use. + if (methods.length == 0) + return; + // Sign in to provider. + tempProviderName = methods[0].trim(); + setModalContent("generalModalContent", + "
Please press the button to login: