gdcore-tools 2.0.0-beta5 → 2.0.0-beta6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Runtime/CustomRuntimeObject.js +1 -1
- package/dist/Runtime/CustomRuntimeObject.js.map +2 -2
- package/dist/Runtime/CustomRuntimeObjectInstanceContainer.js +1 -1
- package/dist/Runtime/CustomRuntimeObjectInstanceContainer.js.map +2 -2
- package/dist/Runtime/Extensions/3D/CustomRuntimeObject3D.js +1 -1
- package/dist/Runtime/Extensions/3D/CustomRuntimeObject3D.js.map +2 -2
- package/dist/Runtime/Extensions/AdMob/admobtools.js +1 -1
- package/dist/Runtime/Extensions/AdMob/admobtools.js.map +2 -2
- package/dist/Runtime/Extensions/AnchorBehavior/anchorruntimebehavior.js +1 -1
- package/dist/Runtime/Extensions/AnchorBehavior/anchorruntimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/JsExtension.js +2 -2
- package/dist/Runtime/Extensions/Multiplayer/JsExtension.js +97 -7
- package/dist/Runtime/Extensions/Multiplayer/messageManager.js +1 -1
- package/dist/Runtime/Extensions/Multiplayer/messageManager.js.map +2 -2
- package/dist/Runtime/Extensions/Multiplayer/multiplayercomponents.js +1 -1
- package/dist/Runtime/Extensions/Multiplayer/multiplayercomponents.js.map +2 -2
- package/dist/Runtime/Extensions/Multiplayer/multiplayerobjectruntimebehavior.js +1 -1
- package/dist/Runtime/Extensions/Multiplayer/multiplayerobjectruntimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/Multiplayer/multiplayertools.js +1 -1
- package/dist/Runtime/Extensions/Multiplayer/multiplayertools.js.map +2 -2
- package/dist/Runtime/Extensions/PanelSpriteObject/panelspriteruntimeobject-pixi-renderer.js +1 -1
- package/dist/Runtime/Extensions/PanelSpriteObject/panelspriteruntimeobject-pixi-renderer.js.map +2 -2
- package/dist/Runtime/Extensions/Physics2Behavior/JsExtension.js +62 -27
- package/dist/Runtime/Extensions/Physics2Behavior/physics2runtimebehavior.js +1 -1
- package/dist/Runtime/Extensions/Physics2Behavior/physics2runtimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/Spine/JsExtension.js +32 -0
- package/dist/Runtime/Extensions/Spine/spineruntimeobject-pixi-renderer.js +1 -1
- package/dist/Runtime/Extensions/Spine/spineruntimeobject-pixi-renderer.js.map +2 -2
- package/dist/Runtime/Extensions/Spine/spineruntimeobject.js +1 -1
- package/dist/Runtime/Extensions/Spine/spineruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/TextInput/JsExtension.js +3 -1
- package/dist/Runtime/Extensions/TileMap/JsExtension.js +84 -29
- package/dist/Runtime/Extensions/TileMap/collision/TransformedTileMap.js +1 -1
- package/dist/Runtime/Extensions/TileMap/collision/TransformedTileMap.js.map +2 -2
- package/dist/Runtime/Extensions/TileMap/helper/TileMapHelper.js +1 -1
- package/dist/Runtime/Extensions/TileMap/helper/TileMapHelper.js.map +1 -1
- package/dist/Runtime/Extensions/TileMap/helper/dts/load/tiled/TiledTileMapLoader.d.ts.map +1 -1
- package/dist/Runtime/Extensions/TileMap/helper/dts/model/TileMapModel.d.ts +12 -1
- package/dist/Runtime/Extensions/TileMap/helper/dts/model/TileMapModel.d.ts.map +1 -1
- package/dist/Runtime/Extensions/TileMap/helper/dts/render/TileMapManager.d.ts.map +1 -1
- package/dist/Runtime/Extensions/TileMap/simpletilemapruntimeobject.js +1 -1
- package/dist/Runtime/Extensions/TileMap/simpletilemapruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/TileMap/tilemapruntimeobject-pixi-renderer.js +1 -1
- package/dist/Runtime/Extensions/TileMap/tilemapruntimeobject-pixi-renderer.js.map +2 -2
- package/dist/Runtime/Extensions/TweenBehavior/JsExtension.js +1 -0
- package/dist/Runtime/RuntimeInstanceContainer.js.map +2 -2
- package/dist/Runtime/SpriteAnimator.js +1 -1
- package/dist/Runtime/SpriteAnimator.js.map +2 -2
- package/dist/Runtime/debugger-client/InGameDebugger.js +1 -1
- package/dist/Runtime/debugger-client/InGameDebugger.js.map +2 -2
- package/dist/Runtime/debugger-client/abstract-debugger-client.js +1 -1
- package/dist/Runtime/debugger-client/abstract-debugger-client.js.map +2 -2
- package/dist/Runtime/debugger-client/hot-reloader.js +2 -1
- package/dist/Runtime/debugger-client/hot-reloader.js.map +2 -2
- package/dist/Runtime/debugger-client/minimal-debugger-client.js +2 -0
- package/dist/Runtime/debugger-client/minimal-debugger-client.js.map +7 -0
- package/dist/Runtime/debugger-client/websocket-debugger-client.js.map +2 -2
- package/dist/Runtime/debugger-client/window-message-debugger-client.js.map +2 -2
- package/dist/Runtime/pixi-renderers/spriteruntimeobject-pixi-renderer.js +1 -1
- package/dist/Runtime/pixi-renderers/spriteruntimeobject-pixi-renderer.js.map +2 -2
- package/dist/Runtime/runtimegame.js +1 -1
- package/dist/Runtime/runtimegame.js.map +2 -2
- package/dist/Runtime/runtimescene.js +1 -1
- package/dist/Runtime/runtimescene.js.map +2 -2
- package/dist/Runtime/scenestack.js +1 -1
- package/dist/Runtime/scenestack.js.map +2 -2
- package/dist/Runtime/spriteruntimeobject.js +1 -1
- package/dist/Runtime/spriteruntimeobject.js.map +2 -2
- package/dist/Runtime/types/project-data.d.ts +31 -8
- package/dist/Runtime/variablescontainer.js +1 -1
- package/dist/Runtime/variablescontainer.js.map +2 -2
- package/dist/lib/libGD.cjs +1 -1
- package/dist/lib/libGD.wasm +0 -0
- package/gd.d.ts +77 -47
- package/package.json +2 -2
- package/dist/lib/libGD.d.cts +0 -5
- package/dist/loaders.d.cts +0 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../GDevelop/Extensions/AdMob/admobtools.ts"],
|
|
4
|
-
"sourcesContent": ["namespace gdjs {\n declare var admob: any;\n declare var cordova: any;\n\n export namespace adMob {\n const logger = new gdjs.Logger('AdMob');\n\n const testAdIds = {\n appOpen: {\n android: 'ca-app-pub-3940256099942544/9257395921',\n ios: 'ca-app-pub-3940256099942544/5575463023',\n },\n banner: {\n android: 'ca-app-pub-3940256099942544/6300978111',\n ios: 'ca-app-pub-3940256099942544/2934735716',\n },\n interstitial: {\n android: 'ca-app-pub-3940256099942544/1033173712',\n ios: 'ca-app-pub-3940256099942544/4411468910',\n },\n interstitialVideo: {\n android: 'ca-app-pub-3940256099942544/8691691433',\n ios: 'ca-app-pub-3940256099942544/5135589807',\n },\n rewarded: {\n android: 'ca-app-pub-3940256099942544/5224354917',\n ios: 'ca-app-pub-3940256099942544/1712485313',\n },\n rewardedInterstitial: {\n android: 'ca-app-pub-3940256099942544/5354046379',\n ios: 'ca-app-pub-3940256099942544/6978759866',\n },\n native: {\n android: 'ca-app-pub-3940256099942544/2247696110',\n ios: 'ca-app-pub-3940256099942544/3986624511',\n },\n nativeVideo: {\n android: 'ca-app-pub-3940256099942544/1044960115',\n ios: 'ca-app-pub-3940256099942544/2521693316',\n },\n };\n\n enum AdSizeType {\n BANNER,\n LARGE_BANNER,\n MEDIUM_RECTANGLE,\n FULL_BANNER,\n LEADERBOARD,\n SMART_BANNER,\n }\n\n const adSizeTypes = {\n BANNER: AdSizeType.BANNER,\n LARGE_BANNER: AdSizeType.LARGE_BANNER,\n MEDIUM_RECTANGLE: AdSizeType.MEDIUM_RECTANGLE,\n FULL_BANNER: AdSizeType.FULL_BANNER,\n LEADERBOARD: AdSizeType.LEADERBOARD,\n SMART_BANNER: AdSizeType.SMART_BANNER,\n };\n\n enum AppOpenAdOrientation {\n Portrait = 1,\n PortraitUpsideDown = 2,\n LandscapeRight = 3,\n LandscapeLeft = 4,\n }\n\n // Admob does not initialize automatically, so we store a flag to know if it's initialized.\n let admobStarted = false;\n let isStarting = false;\n let isUsingTestAds = false;\n\n // Banner\n let banner;\n let bannerRequestedAdSizeType: AdSizeType = AdSizeType.SMART_BANNER;\n let bannerConfigured = false; // Becomes true when the user configures the ad id and the position of the banner.\n let bannerLoaded = false; // Becomes true when the banner is loaded by loaded.\n let bannerShowing = false; // Becomes true when loaded or when the user shows/hides the banner.\n let bannerErrored = false; // Becomes true when the banner fails to load.\n\n // Interstitial\n let interstitial;\n let interstitialLoading = false; // Becomes true when the interstitial is loading.\n let interstitialReady = false; // Becomes true when the interstitial is loaded and ready to be shown.\n let interstitialShowing = false; // Becomes true when the interstitial is showing.\n let interstitialErrored = false; // Becomes true when the interstitial fails to load.\n\n // App Open\n let appOpen;\n let appOpenLoading = false; // Becomes true when the appOpen is loading.\n let appOpenReady = false; // Becomes true when the appOpen is loaded and ready to be shown.\n let appOpenShowing = false; // Becomes true when the appOpen is showing.\n let appOpenErrored = false; // Becomes true when the appOpen fails to load.\n\n // Rewarded interstitial\n let rewardedInterstitial;\n let rewardedInterstitialLoading = false; // Becomes true when the interstitial is loading.\n let rewardedInterstitialReady = false; // Becomes true when the interstitial is loaded and ready to be shown.\n let rewardedInterstitialShowing = false; // Becomes true when the interstitial is showing.\n let rewardedInterstitialRewardReceived = false; // Becomes true when the interstitial is closed and the reward is received.\n let rewardedInterstitialErrored = false; // Becomes true when the interstitial fails to load.\n\n // Rewarded video\n let rewardedVideo;\n let rewardedVideoLoading = false; // Becomes true when the video is loading.\n let rewardedVideoReady = false; // Becomes true when the video is loaded and ready to be shown.\n let rewardedVideoShowing = false; // Becomes true when the video is showing.\n let rewardedVideoRewardReceived = false; // Becomes true when the video is closed and the reward is received.\n let rewardedVideoErrored = false; // Becomes true when the video fails to load.\n\n let npaValue = '0'; // TODO: expose an API to change this and also an automatic way using the consent SDK.\n\n // Admob initialization listener\n document.addEventListener(\n 'deviceready',\n async () => {\n // Obtain user consent ?\n\n logger.info('Starting AdMob.');\n isStarting = true;\n\n await admob.start();\n\n logger.info('AdMob successfully started.');\n isStarting = false;\n admobStarted = true;\n },\n false\n );\n\n /**\n * Helper to know if we are on mobile and admob is correctly initialized.\n */\n const checkIfAdMobIsAvailable = async () => {\n if (typeof cordova === 'undefined') {\n logger.warn('We are not on mobile, AdMob will not be available.');\n return false;\n }\n if (typeof admob === 'undefined') {\n logger.warn('AdMob has not been configured properly.');\n return false;\n }\n\n if (!admobStarted) {\n if (isStarting) {\n // Delay the call until AdMob is started, up to 5 seconds.\n let time = 0;\n while (!admobStarted && time < 5000) {\n await new Promise((resolve) => setTimeout(resolve, 100));\n time += 100;\n }\n }\n\n if (!admobStarted) {\n logger.warn('AdMob is not started.');\n return false;\n }\n }\n\n return true;\n };\n\n /**\n * Helper to get the correct ad id depending on the platform. Android and iOS use different ids.\n */\n const getAdUnitId = (androidAdUnitId, iosAdUnitId, type) => {\n if (typeof cordova === 'undefined') {\n logger.warn('Cordova is not available.');\n return;\n }\n if (cordova.platformId === 'android') {\n return isUsingTestAds ? testAdIds[type].android : androidAdUnitId;\n } else if (cordova.platformId === 'ios') {\n return isUsingTestAds ? testAdIds[type].ios : iosAdUnitId;\n }\n\n logger.error('Unsupported platform: ', cordova.platformId);\n return null;\n };\n\n /**\n * Activate or deactivate the test mode (\"development\" mode).\n * When activated, tests ads will be served instead of real ones.\n *\n * It is important to enable test ads during development so that you can click on them without\n * charging advertisers. If you click on too many ads without being in test mode, you risk your\n * account being flagged for invalid activity.\n */\n export const setTestMode = async (enable: boolean) => {\n if (!(await checkIfAdMobIsAvailable())) return;\n\n logger.info('Setting AdMob test mode to:', enable);\n\n isUsingTestAds = enable;\n };\n\n // -------------------\n // ---- App Open -----\n // -------------------\n export const isAppOpenLoading = () => appOpenLoading;\n export const isAppOpenReady = () => appOpenReady;\n export const isAppOpenShowing = () => appOpenShowing;\n export const isAppOpenErrored = () => appOpenErrored;\n\n /** Load an AppOpen. */\n export const loadAppOpen = async (\n androidAdUnitId,\n iosAdUnitId,\n displayLandscape,\n displayWhenLoaded\n ) => {\n if (!(await checkIfAdMobIsAvailable())) return;\n // If an appOpen is already loading or showing, we don't stop it.\n if (appOpenLoading || appOpenShowing) {\n return;\n }\n\n const adUnitId = getAdUnitId(androidAdUnitId, iosAdUnitId, 'appOpen');\n if (!adUnitId) return;\n\n appOpenLoading = true;\n appOpenReady = false;\n appOpenErrored = false;\n\n appOpen = new admob.AppOpenAd({\n adUnitId,\n orientation: displayLandscape\n ? AppOpenAdOrientation.LandscapeLeft\n : AppOpenAdOrientation.Portrait,\n });\n\n appOpen.on('load', () => {\n appOpenReady = true;\n appOpenLoading = false;\n });\n appOpen.on('loadfail', () => {\n appOpenLoading = false;\n appOpenErrored = true;\n });\n appOpen.on('show', () => {\n appOpenShowing = true;\n appOpenReady = false;\n });\n appOpen.on('showfail', () => {\n appOpenShowing = false;\n appOpenErrored = true;\n });\n appOpen.on('dismiss', () => {\n appOpenShowing = false;\n });\n\n try {\n logger.info('Loading Admob App Open.');\n await appOpen.load();\n logger.info('AdMob App Open successfully loaded.');\n appOpenLoading = false;\n appOpenReady = true;\n if (displayWhenLoaded) showAppOpen();\n } catch (error) {\n logger.error('Error while loading an App Open:', error);\n appOpenLoading = false;\n appOpenReady = false;\n appOpenErrored = true;\n }\n };\n\n /** Show the loaded appOpen. */\n export const showAppOpen = async () => {\n if (!(await checkIfAdMobIsAvailable())) return;\n\n if (!appOpen) {\n logger.warn('App Open has not been set up, call loadAppOpen first.');\n return;\n }\n if (!appOpenReady) {\n logger.info('App Open not loaded yet, cannot display it.');\n return;\n }\n appOpenErrored = false;\n\n try {\n logger.info('Showing AdMob App Open.');\n await appOpen.show();\n // AppOpen will be shown and\n // `appOpenShowing` will be updated thanks to events\n // (but it's too early to change it now).\n } catch (error) {\n logger.error('Error while showing an AdMob App Open:', error);\n appOpenShowing = false;\n appOpenErrored = true;\n }\n };\n\n // -----------------\n // ---- Banner -----\n // -----------------\n export const isBannerConfigured = () => bannerConfigured;\n export const isBannerLoaded = () => bannerLoaded;\n export const isBannerShowing = () => bannerShowing;\n export const isBannerErrored = () => bannerErrored;\n\n export const setBannerAdSizeType = (\n bannerAdSizeType:\n | 'BANNER'\n | 'LARGE_BANNER'\n | 'MEDIUM_RECTANGLE'\n | 'FULL_BANNER'\n | 'LEADERBOARD'\n | 'SMART_BANNER'\n ) => {\n bannerRequestedAdSizeType =\n adSizeTypes[bannerAdSizeType] || AdSizeType.SMART_BANNER;\n };\n\n /**\n * Set up a banner that can then be displayed by calling `showBanner`.\n * If a banner is already set up, it will be hidden and replaced by the new one.\n */\n export const setupBanner = async (androidAdUnitId, iosAdUnitId, atTop) => {\n if (!(await checkIfAdMobIsAvailable())) return;\n const adUnitId = getAdUnitId(androidAdUnitId, iosAdUnitId, 'banner');\n if (!adUnitId) return;\n\n if (banner && bannerShowing) {\n logger.info('Banner already visible, hiding it to display new one.');\n await hideBanner();\n }\n\n bannerConfigured = false;\n bannerLoaded = false;\n\n banner = new admob.BannerAd({\n adUnitId,\n position: atTop ? 'top' : 'bottom',\n size: bannerRequestedAdSizeType,\n });\n\n banner.on('load', () => {\n bannerShowing = true;\n bannerLoaded = true;\n });\n banner.on('loadfail', () => {\n bannerShowing = false;\n bannerLoaded = false;\n bannerErrored = true;\n });\n\n bannerConfigured = true;\n };\n\n /**\n * Display a banner that was set up with `setupBanner` (and `setBannerAdSizeType`).\n */\n export const showBanner = async () => {\n if (!banner) {\n logger.info('Banner not configured, use setupBanner first.');\n return;\n }\n if (bannerShowing) {\n logger.info('Banner already visible. Ignoring.');\n return;\n }\n bannerErrored = false;\n\n try {\n logger.info('Showing AdMob banner.');\n await banner.show();\n if (bannerLoaded) {\n // Banner is already loaded, so it will be shown immediately.\n bannerShowing = true;\n }\n } catch (error) {\n bannerShowing = false;\n bannerErrored = true;\n logger.error('Error while showing an AdMob banner:', error);\n }\n };\n\n /** Hide the banner shown on screen. */\n export const hideBanner = async () => {\n if (!(await checkIfAdMobIsAvailable())) return;\n\n if (!banner || !bannerShowing) {\n logger.warn('No banner is being shown.');\n return;\n }\n\n await banner.hide();\n bannerShowing = false;\n // Note that the banner is still loaded, which is why bannerLoaded is not set to false.\n // We hide the banner, but keep it configured to display it again if needed.\n };\n\n // -----------------------\n // ---- Interstitial -----\n // -----------------------\n export const isInterstitialLoading = () => interstitialLoading;\n export const isInterstitialReady = () => interstitialReady;\n export const isInterstitialShowing = () => interstitialShowing;\n export const isInterstitialErrored = () => interstitialErrored;\n\n /** Load an interstitial. */\n export const loadInterstitial = async (\n androidAdUnitId,\n iosAdUnitId,\n displayWhenLoaded\n ) => {\n if (!(await checkIfAdMobIsAvailable())) return;\n // If an interstitial is already loading or showing, we don't stop it.\n if (interstitialLoading || interstitialShowing) {\n return;\n }\n\n const adUnitId = getAdUnitId(\n androidAdUnitId,\n iosAdUnitId,\n 'interstitial'\n );\n if (!adUnitId) return;\n\n interstitialLoading = true;\n interstitialReady = false;\n interstitialErrored = false;\n\n interstitial = new admob.InterstitialAd({\n adUnitId,\n npa: npaValue,\n });\n\n interstitial.on('load', () => {\n interstitialReady = true;\n interstitialLoading = false;\n });\n interstitial.on('loadfail', () => {\n interstitialLoading = false;\n interstitialErrored = true;\n });\n interstitial.on('show', () => {\n interstitialShowing = true;\n interstitialReady = false;\n });\n interstitial.on('showfail', () => {\n interstitialShowing = false;\n interstitialErrored = true;\n });\n interstitial.on('dismiss', () => {\n interstitialShowing = false;\n });\n\n try {\n logger.info('Loading Admob interstitial.');\n await interstitial.load();\n logger.info('AdMob interstitial successfully loaded.');\n interstitialLoading = false;\n interstitialReady = true;\n if (displayWhenLoaded) showInterstitial();\n } catch (error) {\n logger.error('Error while loading a interstitial:', error);\n interstitialLoading = false;\n interstitialReady = false;\n interstitialErrored = true;\n }\n };\n\n /** Show the loaded interstitial. */\n export const showInterstitial = async () => {\n if (!(await checkIfAdMobIsAvailable())) return;\n\n if (!interstitial) {\n logger.warn(\n 'Interstitial has not been set up, call loadInterstitial first.'\n );\n return;\n }\n if (!interstitialReady) {\n logger.info('Interstitial not loaded yet, cannot display it.');\n return;\n }\n interstitialErrored = false;\n\n try {\n logger.info('Showing AdMob interstitial.');\n await interstitial.show();\n // Interstitial will be shown and\n // `interstitialShowing` will be updated thanks to events\n // (but it's too early to change it now).\n } catch (error) {\n logger.error('Error while showing an AdMob interstitial:', error);\n interstitialShowing = false;\n interstitialErrored = true;\n }\n };\n\n // --------------------------------\n // ---- Rewarded Interstitial -----\n // --------------------------------\n export const isRewardedInterstitialLoading = () =>\n rewardedInterstitialLoading;\n export const isRewardedInterstitialReady = () => rewardedInterstitialReady;\n export const isRewardedInterstitialShowing = () =>\n rewardedInterstitialShowing;\n export const isRewardedInterstitialErrored = () =>\n rewardedInterstitialErrored;\n\n /** Check if the reward of the rewarded interstitial was received. */\n export const wasRewardedInterstitialRewardReceived = function (\n markAsClaimed\n ) {\n const reward = rewardedInterstitialRewardReceived;\n if (markAsClaimed) {\n rewardedInterstitialRewardReceived = false;\n }\n return reward;\n };\n\n /** Load a rewarded interstitial. */\n export const loadRewardedInterstitial = async (\n androidAdUnitID,\n iosAdUnitID,\n displayWhenLoaded\n ) => {\n if (!(await checkIfAdMobIsAvailable())) return;\n if (rewardedInterstitialLoading || rewardedInterstitialShowing) {\n return;\n }\n\n const adUnitId = getAdUnitId(\n androidAdUnitID,\n iosAdUnitID,\n 'rewardedInterstitial'\n );\n if (!adUnitId) return;\n\n rewardedInterstitialLoading = true;\n rewardedInterstitialReady = false;\n rewardedInterstitialErrored = false;\n\n rewardedInterstitial = new admob.RewardedInterstitialAd({\n adUnitId,\n npa: npaValue,\n });\n\n // Rewarded video event listeners\n rewardedInterstitial.on('load', () => {\n rewardedInterstitialReady = true;\n rewardedInterstitialLoading = false;\n });\n rewardedInterstitial.on('loadfail', () => {\n rewardedInterstitialLoading = false;\n rewardedInterstitialErrored = true;\n });\n rewardedInterstitial.on('show', () => {\n rewardedInterstitialShowing = true;\n rewardedInterstitialReady = false;\n });\n rewardedInterstitial.on('showfail', () => {\n rewardedInterstitialShowing = false;\n rewardedInterstitialErrored = true;\n });\n rewardedInterstitial.on('dismiss', () => {\n rewardedInterstitialShowing = false;\n });\n rewardedInterstitial.on('reward', () => {\n rewardedInterstitialRewardReceived = true;\n });\n\n try {\n logger.info('Loading AdMob rewarded interstitial.');\n await rewardedInterstitial.load();\n logger.info('AdMob rewarded interstitial successfully loaded.');\n rewardedInterstitialLoading = false;\n rewardedInterstitialReady = true;\n if (displayWhenLoaded) showRewardedInterstitial();\n } catch (error) {\n rewardedInterstitialLoading = false;\n rewardedInterstitialReady = false;\n rewardedInterstitialErrored = true;\n logger.error('Error while loading a rewarded interstitial:', error);\n }\n };\n\n /** Show the loaded reward interstitial. */\n export const showRewardedInterstitial = async () => {\n if (!(await checkIfAdMobIsAvailable())) return;\n\n if (!rewardedInterstitial) {\n logger.warn(\n 'interstitial has not been set up, call loadRewardedInterstitial first.'\n );\n return;\n }\n if (!rewardedInterstitialReady) {\n logger.info('Rewarded interstitial not loaded yet, cannot display it.');\n }\n rewardedInterstitialErrored = false;\n\n try {\n logger.info('Showing AdMob rewarded interstitial.');\n await rewardedInterstitial.show();\n // Rewarded interstitial will be shown and\n // `rewardedInterstitialShowing` will be updated thanks to events\n // (but it's too early to change it now).\n } catch (error) {\n logger.error(\n 'Error while showing an AdMob rewarded interstitial:',\n error\n );\n rewardedInterstitialShowing = false;\n rewardedInterstitialErrored = true;\n }\n };\n\n /** Mark the reward of the interstitial as claimed. */\n export const markRewardedInterstitialRewardAsClaimed = () => {\n rewardedInterstitialRewardReceived = false;\n };\n\n // -------------------------\n // ---- Rewarded Video -----\n // -------------------------\n export const isRewardedVideoLoading = () => rewardedVideoLoading;\n export const isRewardedVideoReady = () => rewardedVideoReady;\n export const isRewardedVideoShowing = () => rewardedVideoShowing;\n export const isRewardedVideoErrored = () => rewardedVideoErrored;\n\n /** Check if the reward of the rewarded video was received. */\n export const wasRewardedVideoRewardReceived = function (markAsClaimed) {\n const reward = rewardedVideoRewardReceived;\n if (markAsClaimed) {\n rewardedVideoRewardReceived = false;\n }\n return reward;\n };\n\n /** Load a rewarded video. */\n export const loadRewardedVideo = async (\n androidAdUnitID,\n iosAdUnitID,\n displayWhenLoaded\n ) => {\n if (!(await checkIfAdMobIsAvailable())) return;\n if (rewardedVideoLoading || rewardedVideoShowing) {\n return;\n }\n\n const adUnitId = getAdUnitId(androidAdUnitID, iosAdUnitID, 'rewarded');\n if (!adUnitId) return;\n\n rewardedVideoLoading = true;\n rewardedVideoReady = false;\n rewardedVideoErrored = false;\n\n rewardedVideo = new admob.RewardedAd({\n adUnitId,\n npa: npaValue,\n });\n\n // Rewarded video event listeners\n rewardedVideo.on('load', () => {\n rewardedVideoReady = true;\n rewardedVideoLoading = false;\n });\n rewardedVideo.on('loadfail', () => {\n rewardedVideoLoading = false;\n rewardedVideoErrored = true;\n });\n rewardedVideo.on('show', () => {\n rewardedVideoShowing = true;\n rewardedVideoReady = false;\n });\n rewardedVideo.on('showfail', () => {\n rewardedVideoShowing = false;\n rewardedVideoErrored = true;\n });\n rewardedVideo.on('dismiss', () => {\n rewardedVideoShowing = false;\n });\n rewardedVideo.on('reward', () => {\n rewardedVideoRewardReceived = true;\n });\n\n try {\n logger.info('Loading AdMob rewarded video.');\n await rewardedVideo.load();\n logger.info('AdMob rewarded video successfully loaded.');\n rewardedVideoLoading = false;\n rewardedVideoReady = true;\n if (displayWhenLoaded) showRewardedVideo();\n } catch (error) {\n rewardedVideoLoading = false;\n rewardedVideoReady = false;\n rewardedVideoErrored = true;\n logger.error('Error while loading a rewarded video:', error);\n }\n };\n\n /** Show the loaded reward video. */\n export const showRewardedVideo = async () => {\n if (!(await checkIfAdMobIsAvailable())) return;\n\n if (!rewardedVideo) {\n logger.warn('Video has not been set up, call loadRewardedVideo first.');\n return;\n }\n if (!rewardedVideoReady) {\n logger.info('Rewarded video not loaded yet, cannot display it.');\n }\n rewardedVideoErrored = false;\n\n try {\n logger.info('Showing AdMob rewarded video.');\n await rewardedVideo.show();\n // Rewarded video will be shown and\n // `rewardedVideoShowing` will be updated thanks to events\n // (but it's too early to change it now).\n } catch (error) {\n logger.error('Error while showing an AdMob rewarded video:', error);\n rewardedVideoShowing = false;\n rewardedVideoErrored = true;\n }\n };\n\n /** Mark the reward of the video as claimed. */\n export const markRewardedVideoRewardAsClaimed = () => {\n rewardedVideoRewardReceived = false;\n };\n }\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["namespace gdjs {\n declare var admob: any;\n declare var cordova: any;\n\n export namespace adMob {\n const logger = new gdjs.Logger('AdMob');\n\n const testAdIds = {\n appOpen: {\n android: 'ca-app-pub-3940256099942544/9257395921',\n ios: 'ca-app-pub-3940256099942544/5575463023',\n },\n banner: {\n android: 'ca-app-pub-3940256099942544/6300978111',\n ios: 'ca-app-pub-3940256099942544/2934735716',\n },\n interstitial: {\n android: 'ca-app-pub-3940256099942544/1033173712',\n ios: 'ca-app-pub-3940256099942544/4411468910',\n },\n interstitialVideo: {\n android: 'ca-app-pub-3940256099942544/8691691433',\n ios: 'ca-app-pub-3940256099942544/5135589807',\n },\n rewarded: {\n android: 'ca-app-pub-3940256099942544/5224354917',\n ios: 'ca-app-pub-3940256099942544/1712485313',\n },\n rewardedInterstitial: {\n android: 'ca-app-pub-3940256099942544/5354046379',\n ios: 'ca-app-pub-3940256099942544/6978759866',\n },\n native: {\n android: 'ca-app-pub-3940256099942544/2247696110',\n ios: 'ca-app-pub-3940256099942544/3986624511',\n },\n nativeVideo: {\n android: 'ca-app-pub-3940256099942544/1044960115',\n ios: 'ca-app-pub-3940256099942544/2521693316',\n },\n };\n\n enum AdSizeType {\n BANNER,\n LARGE_BANNER,\n MEDIUM_RECTANGLE,\n FULL_BANNER,\n LEADERBOARD,\n SMART_BANNER,\n }\n\n const adSizeTypes = {\n BANNER: AdSizeType.BANNER,\n LARGE_BANNER: AdSizeType.LARGE_BANNER,\n MEDIUM_RECTANGLE: AdSizeType.MEDIUM_RECTANGLE,\n FULL_BANNER: AdSizeType.FULL_BANNER,\n LEADERBOARD: AdSizeType.LEADERBOARD,\n SMART_BANNER: AdSizeType.SMART_BANNER,\n };\n\n enum AppOpenAdOrientation {\n Portrait = 1,\n PortraitUpsideDown = 2,\n LandscapeRight = 3,\n LandscapeLeft = 4,\n }\n\n // Admob does not initialize automatically, so we store a flag to know if it's initialized.\n let admobStarted = false;\n let isStarting = false;\n let isUsingTestAds = false;\n\n // Banner\n let banner;\n let bannerRequestedAdSizeType: AdSizeType = AdSizeType.SMART_BANNER;\n let bannerConfigured = false; // Becomes true when the user configures the ad id and the position of the banner.\n let bannerLoaded = false; // Becomes true when the banner is loaded by loaded.\n let bannerShowing = false; // Becomes true when loaded or when the user shows/hides the banner.\n let bannerErrored = false; // Becomes true when the banner fails to load.\n\n // Interstitial\n let interstitial;\n let interstitialLoading = false; // Becomes true when the interstitial is loading.\n let interstitialReady = false; // Becomes true when the interstitial is loaded and ready to be shown.\n let interstitialShowing = false; // Becomes true when the interstitial is showing.\n let interstitialErrored = false; // Becomes true when the interstitial fails to load.\n\n // App Open\n let appOpen;\n let appOpenLoading = false; // Becomes true when the appOpen is loading.\n let appOpenReady = false; // Becomes true when the appOpen is loaded and ready to be shown.\n let appOpenShowing = false; // Becomes true when the appOpen is showing.\n let appOpenErrored = false; // Becomes true when the appOpen fails to load.\n\n // Rewarded interstitial\n let rewardedInterstitial;\n let rewardedInterstitialLoading = false; // Becomes true when the interstitial is loading.\n let rewardedInterstitialReady = false; // Becomes true when the interstitial is loaded and ready to be shown.\n let rewardedInterstitialShowing = false; // Becomes true when the interstitial is showing.\n let rewardedInterstitialRewardReceived = false; // Becomes true when the interstitial is closed and the reward is received.\n let rewardedInterstitialErrored = false; // Becomes true when the interstitial fails to load.\n\n // Rewarded video\n let rewardedVideo;\n let rewardedVideoLoading = false; // Becomes true when the video is loading.\n let rewardedVideoReady = false; // Becomes true when the video is loaded and ready to be shown.\n let rewardedVideoShowing = false; // Becomes true when the video is showing.\n let rewardedVideoRewardReceived = false; // Becomes true when the video is closed and the reward is received.\n let rewardedVideoErrored = false; // Becomes true when the video fails to load.\n\n let npaValue = '0'; // TODO: expose an API to change this and also an automatic way using the consent SDK.\n\n // Admob initialization listener\n document.addEventListener(\n 'deviceready',\n async () => {\n // Obtain user consent ?\n\n logger.info('Starting AdMob.');\n isStarting = true;\n\n await admob.start();\n\n logger.info('AdMob successfully started.');\n isStarting = false;\n admobStarted = true;\n },\n false\n );\n\n /**\n * Helper to know if we are on mobile and admob is correctly initialized.\n */\n const checkIfAdMobIsAvailable = async () => {\n if (typeof cordova === 'undefined') {\n logger.warn('We are not on mobile, AdMob will not be available.');\n return false;\n }\n if (typeof admob === 'undefined') {\n logger.warn('AdMob has not been configured properly.');\n return false;\n }\n\n if (!admobStarted) {\n if (isStarting) {\n // Delay the call until AdMob is started, up to 5 seconds.\n let time = 0;\n while (!admobStarted && time < 5000) {\n await new Promise((resolve) => setTimeout(resolve, 100));\n time += 100;\n }\n }\n\n if (!admobStarted) {\n logger.warn('AdMob is not started.');\n return false;\n }\n }\n\n return true;\n };\n\n /**\n * Helper to get the correct ad id depending on the platform. Android and iOS use different ids.\n */\n const getAdUnitId = (androidAdUnitId, iosAdUnitId, type) => {\n if (typeof cordova === 'undefined') {\n logger.warn('Cordova is not available.');\n return;\n }\n if (cordova.platformId === 'android') {\n return isUsingTestAds ? testAdIds[type].android : androidAdUnitId;\n } else if (cordova.platformId === 'ios') {\n return isUsingTestAds ? testAdIds[type].ios : iosAdUnitId;\n }\n\n logger.error('Unsupported platform: ', cordova.platformId);\n return null;\n };\n\n /**\n * Activate or deactivate the test mode (\"development\" mode).\n * When activated, tests ads will be served instead of real ones.\n *\n * It is important to enable test ads during development so that you can click on them without\n * charging advertisers. If you click on too many ads without being in test mode, you risk your\n * account being flagged for invalid activity.\n */\n export const setTestMode = async (enable: boolean) => {\n if (!(await checkIfAdMobIsAvailable())) return;\n\n logger.info('Setting AdMob test mode to:', enable);\n\n isUsingTestAds = enable;\n };\n\n // -------------------\n // ---- App Open -----\n // -------------------\n export const isAppOpenLoading = () => appOpenLoading;\n export const isAppOpenReady = () => appOpenReady;\n export const isAppOpenShowing = () => appOpenShowing;\n export const isAppOpenErrored = () => appOpenErrored;\n\n /** Load an AppOpen. */\n export const loadAppOpen = async (\n androidAdUnitId,\n iosAdUnitId,\n displayLandscape,\n displayWhenLoaded\n ) => {\n if (!(await checkIfAdMobIsAvailable())) return;\n // If an appOpen is already loading or showing, we don't stop it.\n if (appOpenLoading || appOpenShowing) {\n return;\n }\n\n const adUnitId = getAdUnitId(androidAdUnitId, iosAdUnitId, 'appOpen');\n if (!adUnitId) return;\n\n appOpenLoading = true;\n appOpenReady = false;\n appOpenErrored = false;\n\n appOpen = new admob.AppOpenAd({\n adUnitId,\n orientation: displayLandscape\n ? AppOpenAdOrientation.LandscapeLeft\n : AppOpenAdOrientation.Portrait,\n });\n\n appOpen.on('load', () => {\n appOpenReady = true;\n appOpenLoading = false;\n });\n appOpen.on('loadfail', () => {\n appOpenLoading = false;\n appOpenErrored = true;\n });\n appOpen.on('show', () => {\n appOpenShowing = true;\n appOpenReady = false;\n });\n appOpen.on('showfail', () => {\n appOpenShowing = false;\n appOpenErrored = true;\n });\n appOpen.on('dismiss', () => {\n appOpenShowing = false;\n });\n\n try {\n logger.info('Loading Admob App Open.');\n await appOpen.load();\n logger.info('AdMob App Open successfully loaded.');\n appOpenLoading = false;\n appOpenReady = true;\n if (displayWhenLoaded) showAppOpen();\n } catch (error) {\n logger.error('Error while loading an App Open:', error);\n appOpenLoading = false;\n appOpenReady = false;\n appOpenErrored = true;\n }\n };\n\n /** Show the loaded appOpen. */\n export const showAppOpen = async () => {\n if (!(await checkIfAdMobIsAvailable())) return;\n\n if (!appOpen) {\n logger.warn('App Open has not been set up, call loadAppOpen first.');\n return;\n }\n if (!appOpenReady) {\n logger.info('App Open not loaded yet, cannot display it.');\n return;\n }\n appOpenErrored = false;\n\n try {\n logger.info('Showing AdMob App Open.');\n await appOpen.show();\n // AppOpen will be shown and\n // `appOpenShowing` will be updated thanks to events\n // (but it's too early to change it now).\n } catch (error) {\n logger.error('Error while showing an AdMob App Open:', error);\n appOpenShowing = false;\n appOpenErrored = true;\n }\n };\n\n // -----------------\n // ---- Banner -----\n // -----------------\n export const isBannerConfigured = () => bannerConfigured;\n export const isBannerLoaded = () => bannerLoaded;\n export const isBannerShowing = () => bannerShowing;\n export const isBannerErrored = () => bannerErrored;\n\n export const setBannerAdSizeType = (\n bannerAdSizeType:\n | 'BANNER'\n | 'LARGE_BANNER'\n | 'MEDIUM_RECTANGLE'\n | 'FULL_BANNER'\n | 'LEADERBOARD'\n | 'SMART_BANNER'\n ) => {\n bannerRequestedAdSizeType =\n adSizeTypes[bannerAdSizeType] || AdSizeType.SMART_BANNER;\n };\n\n /**\n * Set up a banner that can then be displayed by calling `showBanner`.\n * If a banner is already set up, it will be hidden and replaced by the new one.\n */\n export const setupBanner = async (androidAdUnitId, iosAdUnitId, atTop) => {\n if (!(await checkIfAdMobIsAvailable())) return;\n const adUnitId = getAdUnitId(androidAdUnitId, iosAdUnitId, 'banner');\n if (!adUnitId) return;\n\n if (banner && bannerShowing) {\n logger.info('Banner already visible, hiding it to display new one.');\n await hideBanner();\n }\n\n bannerConfigured = false;\n bannerLoaded = false;\n\n banner = new admob.BannerAd({\n adUnitId,\n position: atTop ? 'top' : 'bottom',\n size: bannerRequestedAdSizeType,\n offset: 0,\n });\n\n banner.on('load', () => {\n bannerShowing = true;\n bannerLoaded = true;\n });\n banner.on('loadfail', () => {\n bannerShowing = false;\n bannerLoaded = false;\n bannerErrored = true;\n });\n\n bannerConfigured = true;\n };\n\n /**\n * Display a banner that was set up with `setupBanner` (and `setBannerAdSizeType`).\n */\n export const showBanner = async () => {\n if (!banner) {\n logger.info('Banner not configured, use setupBanner first.');\n return;\n }\n if (bannerShowing) {\n logger.info('Banner already visible. Ignoring.');\n return;\n }\n bannerErrored = false;\n\n try {\n logger.info('Showing AdMob banner.');\n await banner.show();\n if (bannerLoaded) {\n // Banner is already loaded, so it will be shown immediately.\n bannerShowing = true;\n }\n } catch (error) {\n bannerShowing = false;\n bannerErrored = true;\n logger.error('Error while showing an AdMob banner:', error);\n }\n };\n\n /** Hide the banner shown on screen. */\n export const hideBanner = async () => {\n if (!(await checkIfAdMobIsAvailable())) return;\n\n if (!banner || !bannerShowing) {\n logger.warn('No banner is being shown.');\n return;\n }\n\n await banner.hide();\n bannerShowing = false;\n // Note that the banner is still loaded, which is why bannerLoaded is not set to false.\n // We hide the banner, but keep it configured to display it again if needed.\n };\n\n // -----------------------\n // ---- Interstitial -----\n // -----------------------\n export const isInterstitialLoading = () => interstitialLoading;\n export const isInterstitialReady = () => interstitialReady;\n export const isInterstitialShowing = () => interstitialShowing;\n export const isInterstitialErrored = () => interstitialErrored;\n\n /** Load an interstitial. */\n export const loadInterstitial = async (\n androidAdUnitId,\n iosAdUnitId,\n displayWhenLoaded\n ) => {\n if (!(await checkIfAdMobIsAvailable())) return;\n // If an interstitial is already loading or showing, we don't stop it.\n if (interstitialLoading || interstitialShowing) {\n return;\n }\n\n const adUnitId = getAdUnitId(\n androidAdUnitId,\n iosAdUnitId,\n 'interstitial'\n );\n if (!adUnitId) return;\n\n interstitialLoading = true;\n interstitialReady = false;\n interstitialErrored = false;\n\n interstitial = new admob.InterstitialAd({\n adUnitId,\n npa: npaValue,\n });\n\n interstitial.on('load', () => {\n interstitialReady = true;\n interstitialLoading = false;\n });\n interstitial.on('loadfail', () => {\n interstitialLoading = false;\n interstitialErrored = true;\n });\n interstitial.on('show', () => {\n interstitialShowing = true;\n interstitialReady = false;\n });\n interstitial.on('showfail', () => {\n interstitialShowing = false;\n interstitialErrored = true;\n });\n interstitial.on('dismiss', () => {\n interstitialShowing = false;\n });\n\n try {\n logger.info('Loading Admob interstitial.');\n await interstitial.load();\n logger.info('AdMob interstitial successfully loaded.');\n interstitialLoading = false;\n interstitialReady = true;\n if (displayWhenLoaded) showInterstitial();\n } catch (error) {\n logger.error('Error while loading a interstitial:', error);\n interstitialLoading = false;\n interstitialReady = false;\n interstitialErrored = true;\n }\n };\n\n /** Show the loaded interstitial. */\n export const showInterstitial = async () => {\n if (!(await checkIfAdMobIsAvailable())) return;\n\n if (!interstitial) {\n logger.warn(\n 'Interstitial has not been set up, call loadInterstitial first.'\n );\n return;\n }\n if (!interstitialReady) {\n logger.info('Interstitial not loaded yet, cannot display it.');\n return;\n }\n interstitialErrored = false;\n\n try {\n logger.info('Showing AdMob interstitial.');\n await interstitial.show();\n // Interstitial will be shown and\n // `interstitialShowing` will be updated thanks to events\n // (but it's too early to change it now).\n } catch (error) {\n logger.error('Error while showing an AdMob interstitial:', error);\n interstitialShowing = false;\n interstitialErrored = true;\n }\n };\n\n // --------------------------------\n // ---- Rewarded Interstitial -----\n // --------------------------------\n export const isRewardedInterstitialLoading = () =>\n rewardedInterstitialLoading;\n export const isRewardedInterstitialReady = () => rewardedInterstitialReady;\n export const isRewardedInterstitialShowing = () =>\n rewardedInterstitialShowing;\n export const isRewardedInterstitialErrored = () =>\n rewardedInterstitialErrored;\n\n /** Check if the reward of the rewarded interstitial was received. */\n export const wasRewardedInterstitialRewardReceived = function (\n markAsClaimed\n ) {\n const reward = rewardedInterstitialRewardReceived;\n if (markAsClaimed) {\n rewardedInterstitialRewardReceived = false;\n }\n return reward;\n };\n\n /** Load a rewarded interstitial. */\n export const loadRewardedInterstitial = async (\n androidAdUnitID,\n iosAdUnitID,\n displayWhenLoaded\n ) => {\n if (!(await checkIfAdMobIsAvailable())) return;\n if (rewardedInterstitialLoading || rewardedInterstitialShowing) {\n return;\n }\n\n const adUnitId = getAdUnitId(\n androidAdUnitID,\n iosAdUnitID,\n 'rewardedInterstitial'\n );\n if (!adUnitId) return;\n\n rewardedInterstitialLoading = true;\n rewardedInterstitialReady = false;\n rewardedInterstitialErrored = false;\n\n rewardedInterstitial = new admob.RewardedInterstitialAd({\n adUnitId,\n npa: npaValue,\n });\n\n // Rewarded video event listeners\n rewardedInterstitial.on('load', () => {\n rewardedInterstitialReady = true;\n rewardedInterstitialLoading = false;\n });\n rewardedInterstitial.on('loadfail', () => {\n rewardedInterstitialLoading = false;\n rewardedInterstitialErrored = true;\n });\n rewardedInterstitial.on('show', () => {\n rewardedInterstitialShowing = true;\n rewardedInterstitialReady = false;\n });\n rewardedInterstitial.on('showfail', () => {\n rewardedInterstitialShowing = false;\n rewardedInterstitialErrored = true;\n });\n rewardedInterstitial.on('dismiss', () => {\n rewardedInterstitialShowing = false;\n });\n rewardedInterstitial.on('reward', () => {\n rewardedInterstitialRewardReceived = true;\n });\n\n try {\n logger.info('Loading AdMob rewarded interstitial.');\n await rewardedInterstitial.load();\n logger.info('AdMob rewarded interstitial successfully loaded.');\n rewardedInterstitialLoading = false;\n rewardedInterstitialReady = true;\n if (displayWhenLoaded) showRewardedInterstitial();\n } catch (error) {\n rewardedInterstitialLoading = false;\n rewardedInterstitialReady = false;\n rewardedInterstitialErrored = true;\n logger.error('Error while loading a rewarded interstitial:', error);\n }\n };\n\n /** Show the loaded reward interstitial. */\n export const showRewardedInterstitial = async () => {\n if (!(await checkIfAdMobIsAvailable())) return;\n\n if (!rewardedInterstitial) {\n logger.warn(\n 'interstitial has not been set up, call loadRewardedInterstitial first.'\n );\n return;\n }\n if (!rewardedInterstitialReady) {\n logger.info('Rewarded interstitial not loaded yet, cannot display it.');\n }\n rewardedInterstitialErrored = false;\n\n try {\n logger.info('Showing AdMob rewarded interstitial.');\n await rewardedInterstitial.show();\n // Rewarded interstitial will be shown and\n // `rewardedInterstitialShowing` will be updated thanks to events\n // (but it's too early to change it now).\n } catch (error) {\n logger.error(\n 'Error while showing an AdMob rewarded interstitial:',\n error\n );\n rewardedInterstitialShowing = false;\n rewardedInterstitialErrored = true;\n }\n };\n\n /** Mark the reward of the interstitial as claimed. */\n export const markRewardedInterstitialRewardAsClaimed = () => {\n rewardedInterstitialRewardReceived = false;\n };\n\n // -------------------------\n // ---- Rewarded Video -----\n // -------------------------\n export const isRewardedVideoLoading = () => rewardedVideoLoading;\n export const isRewardedVideoReady = () => rewardedVideoReady;\n export const isRewardedVideoShowing = () => rewardedVideoShowing;\n export const isRewardedVideoErrored = () => rewardedVideoErrored;\n\n /** Check if the reward of the rewarded video was received. */\n export const wasRewardedVideoRewardReceived = function (markAsClaimed) {\n const reward = rewardedVideoRewardReceived;\n if (markAsClaimed) {\n rewardedVideoRewardReceived = false;\n }\n return reward;\n };\n\n /** Load a rewarded video. */\n export const loadRewardedVideo = async (\n androidAdUnitID,\n iosAdUnitID,\n displayWhenLoaded\n ) => {\n if (!(await checkIfAdMobIsAvailable())) return;\n if (rewardedVideoLoading || rewardedVideoShowing) {\n return;\n }\n\n const adUnitId = getAdUnitId(androidAdUnitID, iosAdUnitID, 'rewarded');\n if (!adUnitId) return;\n\n rewardedVideoLoading = true;\n rewardedVideoReady = false;\n rewardedVideoErrored = false;\n\n rewardedVideo = new admob.RewardedAd({\n adUnitId,\n npa: npaValue,\n });\n\n // Rewarded video event listeners\n rewardedVideo.on('load', () => {\n rewardedVideoReady = true;\n rewardedVideoLoading = false;\n });\n rewardedVideo.on('loadfail', () => {\n rewardedVideoLoading = false;\n rewardedVideoErrored = true;\n });\n rewardedVideo.on('show', () => {\n rewardedVideoShowing = true;\n rewardedVideoReady = false;\n });\n rewardedVideo.on('showfail', () => {\n rewardedVideoShowing = false;\n rewardedVideoErrored = true;\n });\n rewardedVideo.on('dismiss', () => {\n rewardedVideoShowing = false;\n });\n rewardedVideo.on('reward', () => {\n rewardedVideoRewardReceived = true;\n });\n\n try {\n logger.info('Loading AdMob rewarded video.');\n await rewardedVideo.load();\n logger.info('AdMob rewarded video successfully loaded.');\n rewardedVideoLoading = false;\n rewardedVideoReady = true;\n if (displayWhenLoaded) showRewardedVideo();\n } catch (error) {\n rewardedVideoLoading = false;\n rewardedVideoReady = false;\n rewardedVideoErrored = true;\n logger.error('Error while loading a rewarded video:', error);\n }\n };\n\n /** Show the loaded reward video. */\n export const showRewardedVideo = async () => {\n if (!(await checkIfAdMobIsAvailable())) return;\n\n if (!rewardedVideo) {\n logger.warn('Video has not been set up, call loadRewardedVideo first.');\n return;\n }\n if (!rewardedVideoReady) {\n logger.info('Rewarded video not loaded yet, cannot display it.');\n }\n rewardedVideoErrored = false;\n\n try {\n logger.info('Showing AdMob rewarded video.');\n await rewardedVideo.show();\n // Rewarded video will be shown and\n // `rewardedVideoShowing` will be updated thanks to events\n // (but it's too early to change it now).\n } catch (error) {\n logger.error('Error while showing an AdMob rewarded video:', error);\n rewardedVideoShowing = false;\n rewardedVideoErrored = true;\n }\n };\n\n /** Mark the reward of the video as claimed. */\n export const markRewardedVideoRewardAsClaimed = () => {\n rewardedVideoRewardReceived = false;\n };\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var gdjs;(function(c){
|
|
1
|
+
var gdjs;(function(c){let i;(function(t){t[t.None=0]="None",t[t.WindowLeft=1]="WindowLeft",t[t.WindowRight=2]="WindowRight",t[t.Proportional=3]="Proportional",t[t.WindowCenter=4]="WindowCenter"})(i||(i={}));let o;(function(t){t[t.None=0]="None",t[t.WindowTop=1]="WindowTop",t[t.WindowBottom=2]="WindowBottom",t[t.Proportional=3]="Proportional",t[t.WindowCenter=4]="WindowCenter"})(o||(o={}));class P extends c.RuntimeBehavior{constructor(n,e,s){super(n,e,s);this._invalidDistances=!0;this._leftEdgeDistance=0;this._rightEdgeDistance=0;this._topEdgeDistance=0;this._bottomEdgeDistance=0;this._useLegacyBottomAndRightAnchors=!1;this._relativeToOriginalWindowSize=!!e.relativeToOriginalWindowSize,this._leftEdgeAnchor=e.leftEdgeAnchor,this._rightEdgeAnchor=e.rightEdgeAnchor,this._topEdgeAnchor=e.topEdgeAnchor,this._bottomEdgeAnchor=e.bottomEdgeAnchor,this._useLegacyBottomAndRightAnchors=e.useLegacyBottomAndRightAnchors===void 0?!0:e.useLegacyBottomAndRightAnchors}updateFromBehaviorData(n,e){return n.leftEdgeAnchor!==e.leftEdgeAnchor&&(this._leftEdgeAnchor=e.leftEdgeAnchor),n.rightEdgeAnchor!==e.rightEdgeAnchor&&(this._rightEdgeAnchor=e.rightEdgeAnchor),n.topEdgeAnchor!==e.topEdgeAnchor&&(this._topEdgeAnchor=e.topEdgeAnchor),n.bottomEdgeAnchor!==e.bottomEdgeAnchor&&(this._bottomEdgeAnchor=e.bottomEdgeAnchor),n.useLegacyTrajectory!==e.useLegacyTrajectory&&(this._useLegacyBottomAndRightAnchors=e.useLegacyBottomAndRightAnchors),n.relativeToOriginalWindowSize===e.relativeToOriginalWindowSize}onActivate(){this._invalidDistances=!0}doStepPreEvents(n){const e=c.staticArray(c.AnchorRuntimeBehavior.prototype.doStepPreEvents);let s=n.getUnrotatedViewportMinX(),g=n.getUnrotatedViewportMinY(),t=n.getUnrotatedViewportMaxX(),d=n.getUnrotatedViewportMaxY(),E=(t+s)/2,_=(d+g)/2,l=t-s,f=d-g;const m=n.getLayer(this.owner.getLayer());if(this._invalidDistances){this._relativeToOriginalWindowSize&&(s=n.getInitialUnrotatedViewportMinX(),g=n.getInitialUnrotatedViewportMinY(),t=n.getInitialUnrotatedViewportMaxX(),d=n.getInitialUnrotatedViewportMaxY(),E=(t+s)/2,_=(d+g)/2,l=t-s,f=d-g);const h=m.convertCoords(this.owner.getDrawableX(),this.owner.getDrawableY(),0,e);this._leftEdgeAnchor===1?this._leftEdgeDistance=h[0]-s:this._leftEdgeAnchor===2?this._leftEdgeDistance=h[0]-t:this._leftEdgeAnchor===3?this._leftEdgeDistance=(h[0]-s)/l:this._leftEdgeAnchor===4&&(this._leftEdgeDistance=h[0]-E),this._topEdgeAnchor===1?this._topEdgeDistance=h[1]-g:this._topEdgeAnchor===2?this._topEdgeDistance=h[1]-d:this._topEdgeAnchor===3?this._topEdgeDistance=(h[1]-g)/f:this._topEdgeAnchor===4&&(this._topEdgeDistance=h[1]-_);const r=m.convertCoords(this.owner.getDrawableX()+this.owner.getWidth(),this.owner.getDrawableY()+this.owner.getHeight(),0,e);this._rightEdgeAnchor===1?this._rightEdgeDistance=r[0]-s:this._rightEdgeAnchor===2?this._rightEdgeDistance=r[0]-t:this._rightEdgeAnchor===3?this._rightEdgeDistance=(r[0]-s)/l:this._rightEdgeAnchor===4&&(this._rightEdgeDistance=r[0]-E),this._bottomEdgeAnchor===1?this._bottomEdgeDistance=r[1]-g:this._bottomEdgeAnchor===2?this._bottomEdgeDistance=r[1]-d:this._bottomEdgeAnchor===3?this._bottomEdgeDistance=(r[1]-g)/f:this._bottomEdgeAnchor===4&&(this._bottomEdgeDistance=r[1]-_),this._invalidDistances=!1}else{let h=0,r=0,w=0,A=0;this._leftEdgeAnchor===1?h=s+this._leftEdgeDistance:this._leftEdgeAnchor===2?h=t+this._leftEdgeDistance:this._leftEdgeAnchor===3?h=s+this._leftEdgeDistance*l:this._leftEdgeAnchor===4&&(h=E+this._leftEdgeDistance),this._topEdgeAnchor===1?r=g+this._topEdgeDistance:this._topEdgeAnchor===2?r=d+this._topEdgeDistance:this._topEdgeAnchor===3?r=g+this._topEdgeDistance*f:this._topEdgeAnchor===4&&(r=_+this._topEdgeDistance),this._rightEdgeAnchor===1?w=s+this._rightEdgeDistance:this._rightEdgeAnchor===2?w=t+this._rightEdgeDistance:this._rightEdgeAnchor===3?w=s+this._rightEdgeDistance*l:this._rightEdgeAnchor===4&&(w=E+this._rightEdgeDistance),this._bottomEdgeAnchor===1?A=g+this._bottomEdgeDistance:this._bottomEdgeAnchor===2?A=d+this._bottomEdgeDistance:this._bottomEdgeAnchor===3?A=g+this._bottomEdgeDistance*f:this._bottomEdgeAnchor===4&&(A=_+this._bottomEdgeDistance);const u=m.convertInverseCoords(h,r,0,e),p=u[0],a=u[1],D=m.convertInverseCoords(w,A,0,e),b=D[0],W=D[1];this._useLegacyBottomAndRightAnchors?(this._rightEdgeAnchor!==0&&this.owner.setWidth(b-p),this._bottomEdgeAnchor!==0&&this.owner.setHeight(W-a),this._leftEdgeAnchor!==0&&this.owner.setX(p+this.owner.getX()-this.owner.getDrawableX()),this._topEdgeAnchor!==0&&this.owner.setY(a+this.owner.getY()-this.owner.getDrawableY())):(this._rightEdgeAnchor!==0&&this._leftEdgeAnchor!==0?(this.owner.setWidth(b-p),this.owner.setX(p)):(this._leftEdgeAnchor!==0&&this.owner.setX(p+this.owner.getX()-this.owner.getDrawableX()),this._rightEdgeAnchor!==0&&this.owner.setX(b+this.owner.getX()-this.owner.getDrawableX()-this.owner.getWidth())),this._bottomEdgeAnchor!==0&&this._topEdgeAnchor!==0?(this.owner.setHeight(W-a),this.owner.setY(a)):(this._topEdgeAnchor!==0&&this.owner.setY(a+this.owner.getY()-this.owner.getDrawableY()),this._bottomEdgeAnchor!==0&&this.owner.setY(W+this.owner.getY()-this.owner.getDrawableY()-this.owner.getHeight())))}}doStepPostEvents(n){}}c.AnchorRuntimeBehavior=P,c.registerBehavior("AnchorBehavior::AnchorBehavior",c.AnchorRuntimeBehavior)})(gdjs||(gdjs={}));
|
|
2
2
|
//# sourceMappingURL=anchorruntimebehavior.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../GDevelop/Extensions/AnchorBehavior/anchorruntimebehavior.ts"],
|
|
4
|
-
"sourcesContent": ["/*\nGDevelop - Anchor Behavior Extension\nCopyright (c) 2013-2016 Florian Rival (Florian.Rival@gmail.com)\n */\n\nnamespace gdjs {\n export class AnchorRuntimeBehavior extends gdjs.RuntimeBehavior {\n _relativeToOriginalWindowSize: any;\n _leftEdgeAnchor: any;\n _rightEdgeAnchor: any;\n _topEdgeAnchor: any;\n _bottomEdgeAnchor: any;\n _invalidDistances: boolean = true;\n _leftEdgeDistance: number = 0;\n _rightEdgeDistance: number = 0;\n _topEdgeDistance: number = 0;\n _bottomEdgeDistance: number = 0;\n _useLegacyBottomAndRightAnchors: boolean = false;\n\n constructor(\n instanceContainer: gdjs.RuntimeInstanceContainer,\n behaviorData,\n owner: gdjs.RuntimeObject\n ) {\n super(instanceContainer, behaviorData, owner);\n this._relativeToOriginalWindowSize = !!behaviorData.relativeToOriginalWindowSize;\n this._leftEdgeAnchor = behaviorData.leftEdgeAnchor;\n this._rightEdgeAnchor = behaviorData.rightEdgeAnchor;\n this._topEdgeAnchor = behaviorData.topEdgeAnchor;\n this._bottomEdgeAnchor = behaviorData.bottomEdgeAnchor;\n this._useLegacyBottomAndRightAnchors =\n behaviorData.useLegacyBottomAndRightAnchors === undefined\n ? true\n : behaviorData.useLegacyBottomAndRightAnchors;\n }\n\n updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {\n if (oldBehaviorData.leftEdgeAnchor !== newBehaviorData.leftEdgeAnchor) {\n this._leftEdgeAnchor = newBehaviorData.leftEdgeAnchor;\n }\n if (oldBehaviorData.rightEdgeAnchor !== newBehaviorData.rightEdgeAnchor) {\n this._rightEdgeAnchor = newBehaviorData.rightEdgeAnchor;\n }\n if (oldBehaviorData.topEdgeAnchor !== newBehaviorData.topEdgeAnchor) {\n this._topEdgeAnchor = newBehaviorData.topEdgeAnchor;\n }\n if (\n oldBehaviorData.bottomEdgeAnchor !== newBehaviorData.bottomEdgeAnchor\n ) {\n this._bottomEdgeAnchor = newBehaviorData.bottomEdgeAnchor;\n }\n if (\n oldBehaviorData.useLegacyTrajectory !==\n newBehaviorData.useLegacyTrajectory\n ) {\n this._useLegacyBottomAndRightAnchors =\n newBehaviorData.useLegacyBottomAndRightAnchors;\n }\n if (\n oldBehaviorData.relativeToOriginalWindowSize !==\n newBehaviorData.relativeToOriginalWindowSize\n ) {\n return false;\n }\n return true;\n }\n\n onActivate() {\n this._invalidDistances = true;\n }\n\n doStepPreEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {\n const workingPoint: FloatPoint = gdjs.staticArray(\n gdjs.AnchorRuntimeBehavior.prototype.doStepPreEvents\n ) as FloatPoint;\n // TODO EBO Make it work with event based objects or hide this behavior for them.\n const game = instanceContainer.getGame();\n let rendererWidth = game.getGameResolutionWidth();\n let rendererHeight = game.getGameResolutionHeight();\n const layer = instanceContainer.getLayer(this.owner.getLayer());\n if (this._invalidDistances) {\n if (this._relativeToOriginalWindowSize) {\n rendererWidth = game.getOriginalWidth();\n rendererHeight = game.getOriginalHeight();\n }\n\n //Calculate the distances from the window's bounds.\n const topLeftPixel = layer.convertCoords(\n this.owner.getDrawableX(),\n this.owner.getDrawableY(),\n 0,\n workingPoint\n );\n\n //Left edge\n if (\n this._leftEdgeAnchor ===\n AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_LEFT\n ) {\n this._leftEdgeDistance = topLeftPixel[0];\n } else {\n if (\n this._leftEdgeAnchor ===\n AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_RIGHT\n ) {\n this._leftEdgeDistance = rendererWidth - topLeftPixel[0];\n } else {\n if (\n this._leftEdgeAnchor ===\n AnchorRuntimeBehavior.HorizontalAnchor.PROPORTIONAL\n ) {\n this._leftEdgeDistance = topLeftPixel[0] / rendererWidth;\n }\n }\n }\n\n //Top edge\n if (\n this._topEdgeAnchor ===\n AnchorRuntimeBehavior.VerticalAnchor.WINDOW_TOP\n ) {\n this._topEdgeDistance = topLeftPixel[1];\n } else {\n if (\n this._topEdgeAnchor ===\n AnchorRuntimeBehavior.VerticalAnchor.WINDOW_BOTTOM\n ) {\n this._topEdgeDistance = rendererHeight - topLeftPixel[1];\n } else {\n if (\n this._topEdgeAnchor ===\n AnchorRuntimeBehavior.VerticalAnchor.PROPORTIONAL\n ) {\n this._topEdgeDistance = topLeftPixel[1] / rendererHeight;\n }\n }\n }\n // It's fine to reuse workingPoint as topLeftPixel is no longer used.\n const bottomRightPixel = layer.convertCoords(\n this.owner.getDrawableX() + this.owner.getWidth(),\n this.owner.getDrawableY() + this.owner.getHeight(),\n 0,\n workingPoint\n );\n\n //Right edge\n if (\n this._rightEdgeAnchor ===\n AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_LEFT\n ) {\n this._rightEdgeDistance = bottomRightPixel[0];\n } else {\n if (\n this._rightEdgeAnchor ===\n AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_RIGHT\n ) {\n this._rightEdgeDistance = rendererWidth - bottomRightPixel[0];\n } else {\n if (\n this._rightEdgeAnchor ===\n AnchorRuntimeBehavior.HorizontalAnchor.PROPORTIONAL\n ) {\n this._rightEdgeDistance = bottomRightPixel[0] / rendererWidth;\n }\n }\n }\n\n //Bottom edge\n if (\n this._bottomEdgeAnchor ===\n AnchorRuntimeBehavior.VerticalAnchor.WINDOW_TOP\n ) {\n this._bottomEdgeDistance = bottomRightPixel[1];\n } else {\n if (\n this._bottomEdgeAnchor ===\n AnchorRuntimeBehavior.VerticalAnchor.WINDOW_BOTTOM\n ) {\n this._bottomEdgeDistance = rendererHeight - bottomRightPixel[1];\n } else {\n if (\n this._bottomEdgeAnchor ===\n AnchorRuntimeBehavior.VerticalAnchor.PROPORTIONAL\n ) {\n this._bottomEdgeDistance = bottomRightPixel[1] / rendererHeight;\n }\n }\n }\n this._invalidDistances = false;\n } else {\n //Move and resize the object if needed\n let leftPixel = 0;\n let topPixel = 0;\n let rightPixel = 0;\n let bottomPixel = 0;\n\n //Left edge\n if (\n this._leftEdgeAnchor ===\n AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_LEFT\n ) {\n leftPixel = this._leftEdgeDistance;\n } else {\n if (\n this._leftEdgeAnchor ===\n AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_RIGHT\n ) {\n leftPixel = rendererWidth - this._leftEdgeDistance;\n } else {\n if (\n this._leftEdgeAnchor ===\n AnchorRuntimeBehavior.HorizontalAnchor.PROPORTIONAL\n ) {\n leftPixel = this._leftEdgeDistance * rendererWidth;\n }\n }\n }\n\n //Top edge\n if (\n this._topEdgeAnchor ===\n AnchorRuntimeBehavior.VerticalAnchor.WINDOW_TOP\n ) {\n topPixel = this._topEdgeDistance;\n } else {\n if (\n this._topEdgeAnchor ===\n AnchorRuntimeBehavior.VerticalAnchor.WINDOW_BOTTOM\n ) {\n topPixel = rendererHeight - this._topEdgeDistance;\n } else {\n if (\n this._topEdgeAnchor ===\n AnchorRuntimeBehavior.VerticalAnchor.PROPORTIONAL\n ) {\n topPixel = this._topEdgeDistance * rendererHeight;\n }\n }\n }\n\n //Right edge\n if (\n this._rightEdgeAnchor ===\n AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_LEFT\n ) {\n rightPixel = this._rightEdgeDistance;\n } else {\n if (\n this._rightEdgeAnchor ===\n AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_RIGHT\n ) {\n rightPixel = rendererWidth - this._rightEdgeDistance;\n } else {\n if (\n this._rightEdgeAnchor ===\n AnchorRuntimeBehavior.HorizontalAnchor.PROPORTIONAL\n ) {\n rightPixel = this._rightEdgeDistance * rendererWidth;\n }\n }\n }\n\n //Bottom edge\n if (\n this._bottomEdgeAnchor ===\n AnchorRuntimeBehavior.VerticalAnchor.WINDOW_TOP\n ) {\n bottomPixel = this._bottomEdgeDistance;\n } else {\n if (\n this._bottomEdgeAnchor ===\n AnchorRuntimeBehavior.VerticalAnchor.WINDOW_BOTTOM\n ) {\n bottomPixel = rendererHeight - this._bottomEdgeDistance;\n } else {\n if (\n this._bottomEdgeAnchor ===\n AnchorRuntimeBehavior.VerticalAnchor.PROPORTIONAL\n ) {\n bottomPixel = this._bottomEdgeDistance * rendererHeight;\n }\n }\n }\n // It's fine to reuse workingPoint as topLeftPixel is no longer used.\n const topLeftCoord = layer.convertInverseCoords(\n leftPixel,\n topPixel,\n 0,\n workingPoint\n );\n const left = topLeftCoord[0];\n const top = topLeftCoord[1];\n\n const bottomRightCoord = layer.convertInverseCoords(\n rightPixel,\n bottomPixel,\n 0,\n workingPoint\n );\n const right = bottomRightCoord[0];\n const bottom = bottomRightCoord[1];\n\n // Compatibility with GD <= 5.0.133\n if (this._useLegacyBottomAndRightAnchors) {\n //Move and resize the object according to the anchors\n if (\n this._rightEdgeAnchor !==\n AnchorRuntimeBehavior.HorizontalAnchor.NONE\n ) {\n this.owner.setWidth(right - left);\n }\n if (\n this._bottomEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE\n ) {\n this.owner.setHeight(bottom - top);\n }\n if (\n this._leftEdgeAnchor !== AnchorRuntimeBehavior.HorizontalAnchor.NONE\n ) {\n this.owner.setX(\n left + this.owner.getX() - this.owner.getDrawableX()\n );\n }\n if (\n this._topEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE\n ) {\n this.owner.setY(\n top + this.owner.getY() - this.owner.getDrawableY()\n );\n }\n }\n // End of compatibility code\n else {\n // Resize if right and left anchors are set\n if (\n this._rightEdgeAnchor !==\n AnchorRuntimeBehavior.HorizontalAnchor.NONE &&\n this._leftEdgeAnchor !== AnchorRuntimeBehavior.HorizontalAnchor.NONE\n ) {\n this.owner.setWidth(right - left);\n this.owner.setX(left);\n } else {\n if (\n this._leftEdgeAnchor !==\n AnchorRuntimeBehavior.HorizontalAnchor.NONE\n ) {\n this.owner.setX(\n left + this.owner.getX() - this.owner.getDrawableX()\n );\n }\n if (\n this._rightEdgeAnchor !==\n AnchorRuntimeBehavior.HorizontalAnchor.NONE\n ) {\n this.owner.setX(\n right +\n this.owner.getX() -\n this.owner.getDrawableX() -\n this.owner.getWidth()\n );\n }\n }\n // Resize if top and bottom anchors are set\n if (\n this._bottomEdgeAnchor !==\n AnchorRuntimeBehavior.VerticalAnchor.NONE &&\n this._topEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE\n ) {\n this.owner.setHeight(bottom - top);\n this.owner.setY(top);\n } else {\n if (\n this._topEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE\n ) {\n this.owner.setY(\n top + this.owner.getY() - this.owner.getDrawableY()\n );\n }\n if (\n this._bottomEdgeAnchor !==\n AnchorRuntimeBehavior.VerticalAnchor.NONE\n ) {\n this.owner.setY(\n bottom +\n this.owner.getY() -\n this.owner.getDrawableY() -\n this.owner.getHeight()\n );\n }\n }\n }\n }\n }\n\n doStepPostEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {}\n\n static HorizontalAnchor = {\n NONE: 0,\n WINDOW_LEFT: 1,\n WINDOW_RIGHT: 2,\n PROPORTIONAL: 3,\n };\n static VerticalAnchor = {\n NONE: 0,\n WINDOW_TOP: 1,\n WINDOW_BOTTOM: 2,\n PROPORTIONAL: 3,\n };\n }\n gdjs.registerBehavior(\n 'AnchorBehavior::AnchorBehavior',\n gdjs.AnchorRuntimeBehavior\n );\n}\n"],
|
|
5
|
-
"mappings": "AAKA,GAAU,MAAV,UAAU,EAAV,
|
|
4
|
+
"sourcesContent": ["/*\nGDevelop - Anchor Behavior Extension\nCopyright (c) 2013-2016 Florian Rival (Florian.Rival@gmail.com)\n */\n\nnamespace gdjs {\n const enum HorizontalAnchor {\n None = 0,\n WindowLeft,\n WindowRight,\n Proportional,\n WindowCenter,\n }\n const enum VerticalAnchor {\n None = 0,\n WindowTop,\n WindowBottom,\n Proportional,\n WindowCenter,\n }\n\n export class AnchorRuntimeBehavior extends gdjs.RuntimeBehavior {\n _relativeToOriginalWindowSize: any;\n _leftEdgeAnchor: HorizontalAnchor;\n _rightEdgeAnchor: HorizontalAnchor;\n _topEdgeAnchor: any;\n _bottomEdgeAnchor: any;\n _invalidDistances: boolean = true;\n _leftEdgeDistance: number = 0;\n _rightEdgeDistance: number = 0;\n _topEdgeDistance: number = 0;\n _bottomEdgeDistance: number = 0;\n _useLegacyBottomAndRightAnchors: boolean = false;\n\n constructor(\n instanceContainer: gdjs.RuntimeInstanceContainer,\n behaviorData,\n owner: gdjs.RuntimeObject\n ) {\n super(instanceContainer, behaviorData, owner);\n this._relativeToOriginalWindowSize = !!behaviorData.relativeToOriginalWindowSize;\n this._leftEdgeAnchor = behaviorData.leftEdgeAnchor;\n this._rightEdgeAnchor = behaviorData.rightEdgeAnchor;\n this._topEdgeAnchor = behaviorData.topEdgeAnchor;\n this._bottomEdgeAnchor = behaviorData.bottomEdgeAnchor;\n this._useLegacyBottomAndRightAnchors =\n behaviorData.useLegacyBottomAndRightAnchors === undefined\n ? true\n : behaviorData.useLegacyBottomAndRightAnchors;\n }\n\n updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {\n if (oldBehaviorData.leftEdgeAnchor !== newBehaviorData.leftEdgeAnchor) {\n this._leftEdgeAnchor = newBehaviorData.leftEdgeAnchor;\n }\n if (oldBehaviorData.rightEdgeAnchor !== newBehaviorData.rightEdgeAnchor) {\n this._rightEdgeAnchor = newBehaviorData.rightEdgeAnchor;\n }\n if (oldBehaviorData.topEdgeAnchor !== newBehaviorData.topEdgeAnchor) {\n this._topEdgeAnchor = newBehaviorData.topEdgeAnchor;\n }\n if (\n oldBehaviorData.bottomEdgeAnchor !== newBehaviorData.bottomEdgeAnchor\n ) {\n this._bottomEdgeAnchor = newBehaviorData.bottomEdgeAnchor;\n }\n if (\n oldBehaviorData.useLegacyTrajectory !==\n newBehaviorData.useLegacyTrajectory\n ) {\n this._useLegacyBottomAndRightAnchors =\n newBehaviorData.useLegacyBottomAndRightAnchors;\n }\n if (\n oldBehaviorData.relativeToOriginalWindowSize !==\n newBehaviorData.relativeToOriginalWindowSize\n ) {\n return false;\n }\n return true;\n }\n\n onActivate() {\n this._invalidDistances = true;\n }\n\n doStepPreEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {\n const workingPoint: FloatPoint = gdjs.staticArray(\n gdjs.AnchorRuntimeBehavior.prototype.doStepPreEvents\n ) as FloatPoint;\n // TODO EBO Make it work with event based objects or hide this behavior for them.\n let parentMinX = instanceContainer.getUnrotatedViewportMinX();\n let parentMinY = instanceContainer.getUnrotatedViewportMinY();\n let parentMaxX = instanceContainer.getUnrotatedViewportMaxX();\n let parentMaxY = instanceContainer.getUnrotatedViewportMaxY();\n let parentCenterX = (parentMaxX + parentMinX) / 2;\n let parentCenterY = (parentMaxY + parentMinY) / 2;\n let parentWidth = parentMaxX - parentMinX;\n let parentHeight = parentMaxY - parentMinY;\n const layer = instanceContainer.getLayer(this.owner.getLayer());\n if (this._invalidDistances) {\n if (this._relativeToOriginalWindowSize) {\n parentMinX = instanceContainer.getInitialUnrotatedViewportMinX();\n parentMinY = instanceContainer.getInitialUnrotatedViewportMinY();\n parentMaxX = instanceContainer.getInitialUnrotatedViewportMaxX();\n parentMaxY = instanceContainer.getInitialUnrotatedViewportMaxY();\n parentCenterX = (parentMaxX + parentMinX) / 2;\n parentCenterY = (parentMaxY + parentMinY) / 2;\n parentWidth = parentMaxX - parentMinX;\n parentHeight = parentMaxY - parentMinY;\n }\n\n //Calculate the distances from the window's bounds.\n const topLeftPixel = layer.convertCoords(\n this.owner.getDrawableX(),\n this.owner.getDrawableY(),\n 0,\n workingPoint\n );\n\n // Left edge\n if (this._leftEdgeAnchor === HorizontalAnchor.WindowLeft) {\n this._leftEdgeDistance = topLeftPixel[0] - parentMinX;\n } else if (this._leftEdgeAnchor === HorizontalAnchor.WindowRight) {\n this._leftEdgeDistance = topLeftPixel[0] - parentMaxX;\n } else if (this._leftEdgeAnchor === HorizontalAnchor.Proportional) {\n this._leftEdgeDistance = (topLeftPixel[0] - parentMinX) / parentWidth;\n } else if (this._leftEdgeAnchor === HorizontalAnchor.WindowCenter) {\n this._leftEdgeDistance = topLeftPixel[0] - parentCenterX;\n }\n\n // Top edge\n if (this._topEdgeAnchor === VerticalAnchor.WindowTop) {\n this._topEdgeDistance = topLeftPixel[1] - parentMinY;\n } else if (this._topEdgeAnchor === VerticalAnchor.WindowBottom) {\n this._topEdgeDistance = topLeftPixel[1] - parentMaxY;\n } else if (this._topEdgeAnchor === VerticalAnchor.Proportional) {\n this._topEdgeDistance = (topLeftPixel[1] - parentMinY) / parentHeight;\n } else if (this._topEdgeAnchor === VerticalAnchor.WindowCenter) {\n this._topEdgeDistance = topLeftPixel[1] - parentCenterY;\n }\n\n // It's fine to reuse workingPoint as topLeftPixel is no longer used.\n const bottomRightPixel = layer.convertCoords(\n this.owner.getDrawableX() + this.owner.getWidth(),\n this.owner.getDrawableY() + this.owner.getHeight(),\n 0,\n workingPoint\n );\n\n // Right edge\n if (this._rightEdgeAnchor === HorizontalAnchor.WindowLeft) {\n this._rightEdgeDistance = bottomRightPixel[0] - parentMinX;\n } else if (this._rightEdgeAnchor === HorizontalAnchor.WindowRight) {\n this._rightEdgeDistance = bottomRightPixel[0] - parentMaxX;\n } else if (this._rightEdgeAnchor === HorizontalAnchor.Proportional) {\n this._rightEdgeDistance =\n (bottomRightPixel[0] - parentMinX) / parentWidth;\n } else if (this._rightEdgeAnchor === HorizontalAnchor.WindowCenter) {\n this._rightEdgeDistance = bottomRightPixel[0] - parentCenterX;\n }\n\n // Bottom edge\n if (this._bottomEdgeAnchor === VerticalAnchor.WindowTop) {\n this._bottomEdgeDistance = bottomRightPixel[1] - parentMinY;\n } else if (this._bottomEdgeAnchor === VerticalAnchor.WindowBottom) {\n this._bottomEdgeDistance = bottomRightPixel[1] - parentMaxY;\n } else if (this._bottomEdgeAnchor === VerticalAnchor.Proportional) {\n this._bottomEdgeDistance =\n (bottomRightPixel[1] - parentMinY) / parentHeight;\n } else if (this._bottomEdgeAnchor === VerticalAnchor.WindowCenter) {\n this._bottomEdgeDistance = bottomRightPixel[1] - parentCenterY;\n }\n\n this._invalidDistances = false;\n } else {\n //Move and resize the object if needed\n let leftPixel = 0;\n let topPixel = 0;\n let rightPixel = 0;\n let bottomPixel = 0;\n\n // Left edge\n if (this._leftEdgeAnchor === HorizontalAnchor.WindowLeft) {\n leftPixel = parentMinX + this._leftEdgeDistance;\n } else if (this._leftEdgeAnchor === HorizontalAnchor.WindowRight) {\n leftPixel = parentMaxX + this._leftEdgeDistance;\n } else if (this._leftEdgeAnchor === HorizontalAnchor.Proportional) {\n leftPixel = parentMinX + this._leftEdgeDistance * parentWidth;\n } else if (this._leftEdgeAnchor === HorizontalAnchor.WindowCenter) {\n leftPixel = parentCenterX + this._leftEdgeDistance;\n }\n\n // Top edge\n if (this._topEdgeAnchor === VerticalAnchor.WindowTop) {\n topPixel = parentMinY + this._topEdgeDistance;\n } else if (this._topEdgeAnchor === VerticalAnchor.WindowBottom) {\n topPixel = parentMaxY + this._topEdgeDistance;\n } else if (this._topEdgeAnchor === VerticalAnchor.Proportional) {\n topPixel = parentMinY + this._topEdgeDistance * parentHeight;\n } else if (this._topEdgeAnchor === VerticalAnchor.WindowCenter) {\n topPixel = parentCenterY + this._topEdgeDistance;\n }\n\n // Right edge\n if (this._rightEdgeAnchor === HorizontalAnchor.WindowLeft) {\n rightPixel = parentMinX + this._rightEdgeDistance;\n } else if (this._rightEdgeAnchor === HorizontalAnchor.WindowRight) {\n rightPixel = parentMaxX + this._rightEdgeDistance;\n } else if (this._rightEdgeAnchor === HorizontalAnchor.Proportional) {\n rightPixel = parentMinX + this._rightEdgeDistance * parentWidth;\n } else if (this._rightEdgeAnchor === HorizontalAnchor.WindowCenter) {\n rightPixel = parentCenterX + this._rightEdgeDistance;\n }\n\n // Bottom edge\n if (this._bottomEdgeAnchor === VerticalAnchor.WindowTop) {\n bottomPixel = parentMinY + this._bottomEdgeDistance;\n } else if (this._bottomEdgeAnchor === VerticalAnchor.WindowBottom) {\n bottomPixel = parentMaxY + this._bottomEdgeDistance;\n } else if (this._bottomEdgeAnchor === VerticalAnchor.Proportional) {\n bottomPixel = parentMinY + this._bottomEdgeDistance * parentHeight;\n } else if (this._bottomEdgeAnchor === VerticalAnchor.WindowCenter) {\n bottomPixel = parentCenterY + this._bottomEdgeDistance;\n }\n\n // It's fine to reuse workingPoint as topLeftPixel is no longer used.\n const topLeftCoord = layer.convertInverseCoords(\n leftPixel,\n topPixel,\n 0,\n workingPoint\n );\n const left = topLeftCoord[0];\n const top = topLeftCoord[1];\n\n const bottomRightCoord = layer.convertInverseCoords(\n rightPixel,\n bottomPixel,\n 0,\n workingPoint\n );\n const right = bottomRightCoord[0];\n const bottom = bottomRightCoord[1];\n\n // Compatibility with GD <= 5.0.133\n if (this._useLegacyBottomAndRightAnchors) {\n //Move and resize the object according to the anchors\n if (this._rightEdgeAnchor !== HorizontalAnchor.None) {\n this.owner.setWidth(right - left);\n }\n if (this._bottomEdgeAnchor !== VerticalAnchor.None) {\n this.owner.setHeight(bottom - top);\n }\n if (this._leftEdgeAnchor !== HorizontalAnchor.None) {\n this.owner.setX(\n left + this.owner.getX() - this.owner.getDrawableX()\n );\n }\n if (this._topEdgeAnchor !== VerticalAnchor.None) {\n this.owner.setY(\n top + this.owner.getY() - this.owner.getDrawableY()\n );\n }\n }\n // End of compatibility code\n else {\n // Resize if right and left anchors are set\n if (\n this._rightEdgeAnchor !== HorizontalAnchor.None &&\n this._leftEdgeAnchor !== HorizontalAnchor.None\n ) {\n this.owner.setWidth(right - left);\n this.owner.setX(left);\n } else {\n if (this._leftEdgeAnchor !== HorizontalAnchor.None) {\n this.owner.setX(\n left + this.owner.getX() - this.owner.getDrawableX()\n );\n }\n if (this._rightEdgeAnchor !== HorizontalAnchor.None) {\n this.owner.setX(\n right +\n this.owner.getX() -\n this.owner.getDrawableX() -\n this.owner.getWidth()\n );\n }\n }\n // Resize if top and bottom anchors are set\n if (\n this._bottomEdgeAnchor !== VerticalAnchor.None &&\n this._topEdgeAnchor !== VerticalAnchor.None\n ) {\n this.owner.setHeight(bottom - top);\n this.owner.setY(top);\n } else {\n if (this._topEdgeAnchor !== VerticalAnchor.None) {\n this.owner.setY(\n top + this.owner.getY() - this.owner.getDrawableY()\n );\n }\n if (this._bottomEdgeAnchor !== VerticalAnchor.None) {\n this.owner.setY(\n bottom +\n this.owner.getY() -\n this.owner.getDrawableY() -\n this.owner.getHeight()\n );\n }\n }\n }\n }\n }\n\n doStepPostEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {}\n }\n gdjs.registerBehavior(\n 'AnchorBehavior::AnchorBehavior',\n gdjs.AnchorRuntimeBehavior\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -52,7 +52,7 @@ module.exports = {
|
|
|
52
52
|
.setType('number');
|
|
53
53
|
adjustmentProperties
|
|
54
54
|
.getOrCreate('saturation')
|
|
55
|
-
.setValue('
|
|
55
|
+
.setValue('1')
|
|
56
56
|
.setLabel(_('Saturation (between 0 and 5)'))
|
|
57
57
|
.setType('number');
|
|
58
58
|
adjustmentProperties
|
|
@@ -77,7 +77,7 @@ module.exports = {
|
|
|
77
77
|
.setType('number');
|
|
78
78
|
adjustmentProperties
|
|
79
79
|
.getOrCreate('blue')
|
|
80
|
-
.setValue('
|
|
80
|
+
.setValue('1')
|
|
81
81
|
.setLabel(_('Blue (between 0 and 5)'))
|
|
82
82
|
.setType('number');
|
|
83
83
|
adjustmentProperties
|
|
@@ -369,6 +369,36 @@ module.exports = {
|
|
|
369
369
|
'gdjs.multiplayerMessageManager.hasCustomMessageBeenReceived'
|
|
370
370
|
);
|
|
371
371
|
|
|
372
|
+
extension
|
|
373
|
+
.addExpressionAndConditionAndAction(
|
|
374
|
+
'number',
|
|
375
|
+
'ObjectsSynchronizationRate',
|
|
376
|
+
_('Objects synchronization rate'),
|
|
377
|
+
_(
|
|
378
|
+
'objects synchronization rate (between 1 and 60, default is 30 times per second)'
|
|
379
|
+
),
|
|
380
|
+
_('objects synchronization rate'),
|
|
381
|
+
_('Advanced'),
|
|
382
|
+
'JsPlatform/Extensions/multiplayer.svg'
|
|
383
|
+
)
|
|
384
|
+
.useStandardParameters(
|
|
385
|
+
'number',
|
|
386
|
+
gd.ParameterOptions.makeNewOptions().setDescription(_('Sync rate'))
|
|
387
|
+
)
|
|
388
|
+
.setIncludeFile('Extensions/Multiplayer/peer.js')
|
|
389
|
+
.addIncludeFile('Extensions/Multiplayer/peerJsHelper.js')
|
|
390
|
+
.addIncludeFile(
|
|
391
|
+
'Extensions/PlayerAuthentication/playerauthenticationcomponents.js'
|
|
392
|
+
)
|
|
393
|
+
.addIncludeFile(
|
|
394
|
+
'Extensions/PlayerAuthentication/playerauthenticationtools.js'
|
|
395
|
+
)
|
|
396
|
+
.addIncludeFile('Extensions/Multiplayer/messageManager.js')
|
|
397
|
+
.addIncludeFile('Extensions/Multiplayer/multiplayerVariablesManager.js')
|
|
398
|
+
.addIncludeFile('Extensions/Multiplayer/multiplayertools.js')
|
|
399
|
+
.setFunctionName('gdjs.multiplayer.setObjectsSynchronizationRate')
|
|
400
|
+
.setGetter('gdjs.multiplayer.getObjectsSynchronizationRate');
|
|
401
|
+
|
|
372
402
|
extension
|
|
373
403
|
.addCondition(
|
|
374
404
|
'IsPlayerHost',
|
|
@@ -392,13 +422,13 @@ module.exports = {
|
|
|
392
422
|
.addIncludeFile('Extensions/Multiplayer/messageManager.js')
|
|
393
423
|
.addIncludeFile('Extensions/Multiplayer/multiplayerVariablesManager.js')
|
|
394
424
|
.addIncludeFile('Extensions/Multiplayer/multiplayertools.js')
|
|
395
|
-
.setFunctionName('gdjs.multiplayer.
|
|
425
|
+
.setFunctionName('gdjs.multiplayer.isCurrentPlayerHost');
|
|
396
426
|
|
|
397
427
|
extension
|
|
398
428
|
.addCondition(
|
|
399
429
|
'HasAnyPlayerLeft',
|
|
400
430
|
_('Any player has left'),
|
|
401
|
-
_('Check if any player has left the lobby.'),
|
|
431
|
+
_('Check if any player has left the lobby game.'),
|
|
402
432
|
_('Any player has left'),
|
|
403
433
|
_('Lobbies'),
|
|
404
434
|
'JsPlatform/Extensions/multiplayer.svg',
|
|
@@ -423,7 +453,7 @@ module.exports = {
|
|
|
423
453
|
.addCondition(
|
|
424
454
|
'HasPlayerLeft',
|
|
425
455
|
_('Player has left'),
|
|
426
|
-
_('Check if the player has left the lobby.'),
|
|
456
|
+
_('Check if the player has left the lobby game.'),
|
|
427
457
|
_('Player _PARAM0_ has left'),
|
|
428
458
|
_('Lobbies'),
|
|
429
459
|
'JsPlatform/Extensions/multiplayer.svg',
|
|
@@ -448,8 +478,10 @@ module.exports = {
|
|
|
448
478
|
extension
|
|
449
479
|
.addExpression(
|
|
450
480
|
'LastLeftPlayerNumber',
|
|
451
|
-
_('
|
|
452
|
-
_(
|
|
481
|
+
_('Player number that just left'),
|
|
482
|
+
_(
|
|
483
|
+
'Returns the player number of the player that has just left the lobby.'
|
|
484
|
+
),
|
|
453
485
|
_('Lobbies'),
|
|
454
486
|
'JsPlatform/Extensions/multiplayer.svg'
|
|
455
487
|
)
|
|
@@ -524,8 +556,10 @@ module.exports = {
|
|
|
524
556
|
extension
|
|
525
557
|
.addExpression(
|
|
526
558
|
'LastJoinedPlayerNumber',
|
|
527
|
-
_('
|
|
528
|
-
_(
|
|
559
|
+
_('Player number that just joined'),
|
|
560
|
+
_(
|
|
561
|
+
'Returns the player number of the player that has just joined the lobby.'
|
|
562
|
+
),
|
|
529
563
|
_('Lobbies'),
|
|
530
564
|
'JsPlatform/Extensions/multiplayer.svg'
|
|
531
565
|
)
|
|
@@ -546,6 +580,61 @@ module.exports = {
|
|
|
546
580
|
'gdjs.multiplayerMessageManager.getLatestPlayerWhoJustJoined'
|
|
547
581
|
);
|
|
548
582
|
|
|
583
|
+
extension
|
|
584
|
+
.addCondition(
|
|
585
|
+
'IsMigratingHost',
|
|
586
|
+
_('Host is migrating'),
|
|
587
|
+
_(
|
|
588
|
+
'Check if the host is migrating, in order to adapt the game state (like pausing the game).'
|
|
589
|
+
),
|
|
590
|
+
_('Host is migrating'),
|
|
591
|
+
_('Lobbies'),
|
|
592
|
+
'JsPlatform/Extensions/multiplayer.svg',
|
|
593
|
+
'JsPlatform/Extensions/multiplayer.svg'
|
|
594
|
+
)
|
|
595
|
+
.getCodeExtraInformation()
|
|
596
|
+
.setIncludeFile('Extensions/Multiplayer/peer.js')
|
|
597
|
+
.addIncludeFile('Extensions/Multiplayer/peerJsHelper.js')
|
|
598
|
+
.addIncludeFile(
|
|
599
|
+
'Extensions/PlayerAuthentication/playerauthenticationcomponents.js'
|
|
600
|
+
)
|
|
601
|
+
.addIncludeFile(
|
|
602
|
+
'Extensions/PlayerAuthentication/playerauthenticationtools.js'
|
|
603
|
+
)
|
|
604
|
+
.addIncludeFile('Extensions/Multiplayer/multiplayercomponents.js')
|
|
605
|
+
.addIncludeFile('Extensions/Multiplayer/messageManager.js')
|
|
606
|
+
.addIncludeFile('Extensions/Multiplayer/multiplayerVariablesManager.js')
|
|
607
|
+
.addIncludeFile('Extensions/Multiplayer/multiplayertools.js')
|
|
608
|
+
.setFunctionName('gdjs.multiplayer.isMigratingHost');
|
|
609
|
+
|
|
610
|
+
extension
|
|
611
|
+
.addAction(
|
|
612
|
+
'EndLobbyWhenHostLeaves',
|
|
613
|
+
_('Configure lobby game to end when host leaves'),
|
|
614
|
+
_(
|
|
615
|
+
'Configure the lobby game to end when the host leaves. This will trigger the "Lobby game has just ended" condition. (Default behavior is to migrate the host)'
|
|
616
|
+
),
|
|
617
|
+
_('Configure lobby game to end when host leaves'),
|
|
618
|
+
_('Advanced'),
|
|
619
|
+
'JsPlatform/Extensions/multiplayer.svg',
|
|
620
|
+
'JsPlatform/Extensions/multiplayer.svg'
|
|
621
|
+
)
|
|
622
|
+
.addParameter('yesorno', _('End lobby game when host leaves'), '', false)
|
|
623
|
+
.setHelpPath('/all-features/multiplayer')
|
|
624
|
+
.getCodeExtraInformation()
|
|
625
|
+
.setIncludeFile('Extensions/Multiplayer/peer.js')
|
|
626
|
+
.addIncludeFile('Extensions/Multiplayer/peerJsHelper.js')
|
|
627
|
+
.addIncludeFile(
|
|
628
|
+
'Extensions/PlayerAuthentication/playerauthenticationcomponents.js'
|
|
629
|
+
)
|
|
630
|
+
.addIncludeFile(
|
|
631
|
+
'Extensions/PlayerAuthentication/playerauthenticationtools.js'
|
|
632
|
+
)
|
|
633
|
+
.addIncludeFile('Extensions/Multiplayer/messageManager.js')
|
|
634
|
+
.addIncludeFile('Extensions/Multiplayer/multiplayerVariablesManager.js')
|
|
635
|
+
.addIncludeFile('Extensions/Multiplayer/multiplayertools.js')
|
|
636
|
+
.setFunctionName('gdjs.multiplayer.endLobbyWhenHostLeaves');
|
|
637
|
+
|
|
549
638
|
extension
|
|
550
639
|
.addStrExpression(
|
|
551
640
|
'MessageData',
|
|
@@ -997,6 +1086,7 @@ module.exports = {
|
|
|
997
1086
|
multiplayerObjectBehavior,
|
|
998
1087
|
sharedData
|
|
999
1088
|
)
|
|
1089
|
+
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden)
|
|
1000
1090
|
.setIncludeFile('Extensions/Multiplayer/peer.js')
|
|
1001
1091
|
.addIncludeFile('Extensions/Multiplayer/peerJsHelper.js')
|
|
1002
1092
|
.addIncludeFile(
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var gdjs;(function(a){const D=new a.Logger("Multiplayer"),g=new a.Logger("Multiplayer - Debug");a.Logger.getDefaultConsoleLoggerOutput().discardGroup("Multiplayer - Debug");class Ae{constructor(k){this.clear=()=>{this.cache.clear(),this.keys=[]};this.maxSize=k,this.cache=new Set,this.keys=[]}has(k){return this.cache.has(k)}add(k){if(this.cache.size>=this.maxSize){const S=this.keys.shift();S&&this.cache.delete(S)}this.cache.add(k),this.keys.push(k)}}class ue{constructor(){this._updates=[]}store(k){this._updates.push(k),this._updates.length>10&&this._updates.shift()}getUpdates(){return this._updates}remove(k){const S=this._updates.indexOf(k);S!==-1&&this._updates.splice(S,1)}clear(){this._updates=[]}}const Ce=({target:A,source:k})=>{for(const S in k)k.hasOwnProperty(S)&&!A.hasOwnProperty(S)&&(A[S]=k[S]);for(const S in A)A.hasOwnProperty(S)&&!k.hasOwnProperty(S)&&delete A[S]};a.makeMultiplayerMessageManager=()=>{const A=0,k=0,S=0,Te=0,v=window.performance&&typeof window.performance.now=="function"?window.performance.now.bind(window.performance):Date.now,_e=200,Je=4,U=new Ae(500);let N={},_={};const He=1;let de=0,Q=null,W=0,V=new ue;const xe=1;let me=0,J=null,F=0,B=new ue;const Le=1;let E=0,K={},pe={},O={},C=[],$=[],Y={};const L=({originalMessageName:e,originalData:t,expectedMessageName:n,otherPeerIds:r,shouldCancelMessageIfTimesOut:s,maxNumberOfRetries:o,messageRetryTime:i})=>{!a.multiplayer.isLobbyGameRunning()||(N[n]||(N[n]={}),g.info(`Adding expected message ${n} from ${r.join(", ")}.`),r.forEach(c=>{N[n][c]={acknowledged:!1,lastMessageSentAt:v(),originalMessageName:e,originalData:t,shouldCancelMessageIfTimesOut:s,numberOfRetries:0,maxNumberOfRetries:o||Je,messageRetryTime:i||_e}}))},fe=({sceneNetworkId:e,instanceNetworkId:t})=>(_[e]||(_[e]={}),_[e][t]||0),ye=({sceneNetworkId:e,instanceNetworkId:t,clock:n})=>{_[e]||(_[e]={}),_[e][t]=n},P=(e,t,n)=>{if(!(k>0&&Math.random()<k)){if(S>0&&Math.random()<S){setTimeout(()=>{a.multiplayerPeerJsHelper.sendDataTo(e,t,n)},Te);return}if(A>0){setTimeout(()=>{a.multiplayerPeerJsHelper.sendDataTo(e,t,n)},A);return}a.multiplayerPeerJsHelper.sendDataTo(e,t,n)}},Ge=(e,t,n)=>{if(!e.length)return null;let r=null,s=1/0;for(let o=0;o<e.length;++o){if(e[o].networkId)continue;const i=e[o],c=Math.pow(i.getX()-t,2)+Math.pow(i.getY()-n,2);c<s&&(r=i,s=c)}return r},Z=({runtimeScene:e,objectName:t,instanceNetworkId:n,instanceX:r,instanceY:s,shouldCreateIfNotFound:o})=>{const i=e.getInstancesOf(t);if(!i)return null;let c=i.find(l=>l.networkId===n)||null;if(!c&&r!==void 0&&s!==void 0){g.info(`instance ${t} ${n} not found with network ID, trying to find it with position ${r}/${s}.`);const l=Ge(i,r,s);l&&(g.info(`Found closest instance for object ${t} ${n} with no network ID.`),c=l,c.networkId=n)}if(!c&&o){g.info(`Instance ${n} still not found, Creating instance ${t}.`);const l=e.createObject(t);if(!l)return null;l.networkId=n,c=l}return c},q="#changeInstanceOwner",he=/#changeInstanceOwner#owner_(\d+)#object_(.+)#instance_(.+)/,Ee=({objectOwner:e,objectName:t,instanceNetworkId:n,newObjectOwner:r,instanceX:s,instanceY:o,sceneNetworkId:i})=>({messageName:`${q}#owner_${e}#object_${t}#instance_${n}`,messageData:{previousOwner:e,newOwner:r,instanceX:s,instanceY:o,sceneNetworkId:i}}),ee="#instanceOwnerChanged",Ue=/#instanceOwnerChanged#owner_(\d+)#object_(.+)#instance_(.+)/,be=e=>e.replace(q,ee),We=e=>{if(!a.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=a.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(s=>s.startsWith(q)).forEach(s=>{const o=t.get(s);if(!o)return;const i=o.getMessages();!i.length||i.forEach(c=>{const l=c.getData(),d=c.getSender(),p=he.exec(s);if(!p)return;const f=p[2],u=p[3],m=l.previousOwner,y=l.newOwner,M=l.sceneNetworkId;if(M!==e.networkId){g.info(`Object ${f} is in scene ${M}, but we are on ${e.networkId}. Skipping.`);return}const w=Z({runtimeScene:e,objectName:f,instanceNetworkId:u,instanceX:l.instanceX,instanceY:l.instanceY});if(!w){g.info(`Instance ${u} not found, it must have been destroyed.`);return}const h=w.getBehavior("MultiplayerObject");if(!h){g.info(`Object ${f} does not have the MultiplayerObjectBehavior, cannot change ownership.`);return}const b=h.getPlayerObjectOwnership(),I=b===m||b===y;if(a.multiplayer.isPlayerHost()&&!I){g.info(`Object ${f} with instance network ID ${u} does not have the expected owner. Wanted to change from ${m} to ${y}, but object has owner ${b}.`);return}g.info(`Changing ownership of object ${f} to ${y}.`),h.playerNumber=y;const H=be(s);if(g.info(`Sending acknowledgment of ownership change of object ${f} from ${m} to ${y} with instance network ID ${u} to ${d}.`),P([d],H,{}),a.multiplayer.isPlayerHost()){const j=a.multiplayerPeerJsHelper.getAllPeers().filter(R=>R!==d);if(!j.length)return;L({originalMessageName:s,originalData:l,expectedMessageName:H,otherPeerIds:j,shouldCancelMessageIfTimesOut:!1}),g.info(`Relaying ownership change of object ${f} with instance network ID ${u} to ${j.join(", ")}.`),P(j,s,l)}})})},Me="#updateInstance",Ve=/#updateInstance#owner_(\d+)#object_(.+)#instance_(.+)#scene_(.+)/,Fe=({objectOwner:e,objectName:t,instanceNetworkId:n,objectNetworkSyncData:r,sceneNetworkId:s})=>({messageName:`${Me}#owner_${e}#object_${t}#instance_${n}#scene_${s}`,messageData:r}),Be=e=>{if(!a.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=a.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(s=>s.startsWith(Me)).forEach(s=>{const o=t.get(s);if(!o)return;const i=o.getMessages();if(!i.length)return;i.slice().reverse().forEach(l=>{const d=l.getData(),p=l.getSender(),f=Ve.exec(s);if(!f)return;const u=parseInt(f[1],10);if(u===a.multiplayer.playerNumber)return;const m=f[2],y=f[3],M=f[4];if(M!==e.networkId){g.info(`Object ${m} is in scene ${M}, but we are on ${e.networkId}. Skipping.`);return}const w=d._clock,h=fe({sceneNetworkId:M,instanceNetworkId:y});if(w<=h)return;const b=Z({runtimeScene:e,objectName:m,instanceNetworkId:y,shouldCreateIfNotFound:!0,instanceX:d.x,instanceY:d.y});if(!b){D.error("Instance could not be found or created.");return}const I=b.getBehavior("MultiplayerObject");if(!I){D.error(`Object ${m} does not have the MultiplayerObjectBehavior, cannot update it.`);return}if(I.getPlayerObjectOwnership()===a.multiplayer.playerNumber){g.info(`Object ${m} with instance network ID ${y} is owned by us ${a.multiplayer.playerNumber}, ignoring update message from ${u}.`);return}if(I.getPlayerObjectOwnership()!==u&&(g.info(`Object ${m} with instance network ID ${y} is owned by ${I.getPlayerObjectOwnership()} on our game, changing ownership to ${u} as part of the update event.`),I.playerNumber=u),b.updateFromNetworkSyncData(d),ye({sceneNetworkId:M,instanceNetworkId:y,clock:w}),I._clock=w,a.multiplayer.isPlayerHost()){const T=a.multiplayerPeerJsHelper.getAllPeers().filter(j=>j!==p);if(!T.length)return;P(T,s,d)}})})},X="#changeVariableOwner",we=/#changeVariableOwner#owner_(\d+)#variable_(.+)/,Ke=({variableOwner:e,variableNetworkId:t,newVariableOwner:n})=>({messageName:`${X}#owner_${e}#variable_${t}`,messageData:{previousOwner:e,newOwner:n}}),te="#variableOwnerChanged",Ye=/#variableOwnerChanged#owner_(\d+)#variable_(.+)/,Ie=e=>e.replace(X,te),qe=e=>{if(!a.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=a.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(s=>s.startsWith(X)).forEach(s=>{const o=t.get(s);if(!o)return;const i=o.getMessages();!i.length||i.forEach(c=>{const l=c.getData(),d=c.getSender(),p=we.exec(s);if(!p)return;const f=p[2],u=l.previousOwner,m=l.newOwner,{type:y,name:M,containerId:w}=a.multiplayerVariablesManager.getVariableTypeAndNameFromNetworkId(f);if(y==="scene"&&w!==e.networkId){g.info(`Variable ${M} is in scene ${w}, but we are on ${e.networkId}. Skipping.`);return}const h=w==="game"?e.getGame().getVariables():e.getVariables();if(!h.has(M)){D.error(`Variable with ID ${f} not found whilst syncing. This should not happen.`);return}const b=h.get(M),I=b.getPlayerOwnership(),H=I===u||I===m;if(a.multiplayer.isPlayerHost()&&!H){g.info(`Variable with ID ${f} does not have the expected owner. Wanted to change from ${u} to ${m}, but variable has owner ${I}.`);return}g.info(`Changing ownership of variable ${M} to ${m}.`),b.setPlayerOwnership(m);const T=Ie(s);if(g.info(`Sending acknowledgment of ownership change of variable with ID ${f} from ${u} to ${m} to ${d}.`),P([d],T,{}),a.multiplayer.isPlayerHost()){const R=a.multiplayerPeerJsHelper.getAllPeers().filter(G=>G!==d);if(!R.length)return;L({originalMessageName:s,originalData:l,expectedMessageName:T,otherPeerIds:R,shouldCancelMessageIfTimesOut:!1});for(const G of R)g.info(`Relaying ownership change of variable with Id ${f} to ${G}.`),P(R,s,l)}})})},Xe=e=>e.startsWith(ne)?st:e.startsWith(ee)?Ue:e.startsWith(te)?Ye:e.startsWith(re)?ot:null,ze=e=>e.startsWith(ne)||e.startsWith(ee)||e.startsWith(te)||e.startsWith(re),Qe=()=>{if(!a.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const e=a.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(e.keys()).filter(ze).forEach(r=>{const s=e.get(r);if(!s)return;const o=s.getMessages();!o.length||o.forEach(i=>{const c=i.getData(),l=i.getSender();g.info(`Received acknowledgment for message ${r}.`);const d=Xe(r);if(!d){D.error(`Invalid acknowledgment message ${r}.`);return}const p=d.exec(r);if(!p){D.error(`Invalid acknowledgment message ${r}.`);return}if(!N[r]||!N[r][l])return;const f=c._clock;if(f!==void 0){const u=p[3],m=p[4],y=fe({sceneNetworkId:m,instanceNetworkId:u});if(f<=y)return;ye({sceneNetworkId:m,instanceNetworkId:u,clock:f})}g.info(`Marking message ${r} as acknowledged from ${l}.`),N[r][l].acknowledged=!0})})},Ze=e=>{if(!a.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;Object.keys(N).forEach(n=>{const r=N[n],s=Object.keys(r).filter(o=>!r[o].acknowledged);if(!s.length)g.info(`All peers have acknowledged message ${n}.`),delete N[n];else for(const o of s){const{lastMessageSentAt:i,originalMessageName:c,originalData:l,numberOfRetries:d,maxNumberOfRetries:p,messageRetryTime:f}=r[o];if(v()-i>f){if(d>=p){if(g.info(`Giving up on message ${n} for ${o}.`),r[o].shouldCancelMessageIfTimesOut){if(c.startsWith(q)){const u=he.exec(c);if(!u){delete N[n];return}const m=u[2],y=u[3],M=e.getInstancesOf(m);if(!M){delete N[n];return}let w=M.find(I=>I.networkId===y);if(!w){delete N[n];return}const h=w.getBehavior("MultiplayerObject");if(!h){D.error(`Object ${m} does not have the MultiplayerObjectBehavior, cannot revert ownership.`),delete N[n];return}const b=l.previousOwner;if(b===void 0){delete N[n];return}h.playerNumber=b||0}if(c.startsWith(X)){const u=we.exec(c);if(!u){delete N[n];return}const m=u[2],y=l.previousOwner,{type:M,name:w,containerId:h}=a.multiplayerVariablesManager.getVariableTypeAndNameFromNetworkId(m);if(M==="scene"&&h!==e.networkId){g.info(`Variable ${w} is in scene ${h}, but we are on ${e.networkId}. Skipping ownership revert.`),delete N[n];return}const b=h==="game"?e.getGame().getVariables():e.getVariables();if(!b.has(w)){D.error(`Variable with ID ${m} not found while reverting ownership. This should not happen.`),delete N[n];return}const I=b.get(w);if(y===void 0){delete N[n];return}I.setPlayerOwnership(y||0)}}delete N[n];continue}P([o],c,l),r[o].lastMessageSentAt=v(),r[o].numberOfRetries=d+1}}})},se="#destroyInstance",et=/#destroyInstance#owner_(\d+)#object_(.+)#instance_(.+)#scene_(.+)/,tt=({objectOwner:e,objectName:t,instanceNetworkId:n,sceneNetworkId:r})=>({messageName:`${se}#owner_${e}#object_${t}#instance_${n}#scene_${r}`,messageData:{}}),ne="#instanceDestroyed",st=/#instanceDestroyed#owner_(\d+)#object_(.+)#instance_(.+)/,Oe=e=>e.replace(se,ne),nt=e=>{if(!a.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=a.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(s=>s.startsWith(se)).forEach(s=>{const o=t.get(s);if(!o)return;const i=o.getMessages();!i.length||i.forEach(c=>{const l=c.getData(),d=c.getSender();g.info(`Received message ${s} with data ${JSON.stringify(l)}.`);const p=et.exec(s);if(!p||parseInt(p[1],10)===a.multiplayer.playerNumber)return;const u=p[2],m=p[3],y=p[4];if(y!==e.networkId){g.info(`Object ${u} is in scene ${y}, but we are on ${e.networkId}. Skipping.`);return}const M=Z({runtimeScene:e,objectName:u,instanceNetworkId:m}),w=Oe(s);if(!M){g.info("Instance was not found in the scene, sending acknowledgment anyway."),P([d],w,{});return}if(g.info(`Destroying object ${u} with instance network ID ${m}.`),M.deleteFromScene(e),g.info(`Sending acknowledgment of destruction of object ${u} with instance network ID ${m} to ${d}.`),P([d],w,{}),a.multiplayer.isPlayerHost()){const b=a.multiplayerPeerJsHelper.getAllPeers().filter(I=>I!==d);if(!b.length)return;L({originalMessageName:s,originalData:l,expectedMessageName:w,otherPeerIds:b,shouldCancelMessageIfTimesOut:!1}),P(b,s,l)}})})},ae="#customMessage",at=/#customMessage#(.+)/,z=e=>`${ae}#${e}`,rt=({userMessageName:e,userMessageData:t,senderPlayerNumber:n})=>{const r=a.makeUuid();return{messageName:z(e),messageData:{data:t,uniqueId:r,senderPlayerNumber:n}}},re="#ackCustomMessage",ot=/#ackCustomMessage#(.+)/,Pe=e=>e.replace(ae,re),Ne=(e,t)=>{const n=a.multiplayerPeerJsHelper.getAllPeers(),r=a.multiplayer.getCurrentPlayerNumber(),{messageName:s,messageData:o}=rt({userMessageName:e,userMessageData:t,senderPlayerNumber:r}),i=Pe(s);L({originalMessageName:s,originalData:o,expectedMessageName:i,otherPeerIds:n,shouldCancelMessageIfTimesOut:!1}),g.info(`Sending custom message ${e} with data ${JSON.stringify(t)}.`),P(n,s,o),a.multiplayer.isPlayerHost()&&a.multiplayerPeerJsHelper.getOrCreateMessagesList(s).pushMessage(o,a.multiplayerPeerJsHelper.getCurrentId())},it=(e,t)=>{const n=t.toJSObject();g.info(`Sending custom message ${e} with data ${JSON.stringify(n)}.`),Ne(e,n)},ct=e=>{const t=z(e),r=a.multiplayerPeerJsHelper.getAllMessagesMap().get(t);if(!r)return;const s=r.getMessages();if(!s.length)return;g.info(`custom message ${e} has been received.`);let o=!1;return s.forEach(i=>{const l=i.getData().uniqueId,d=`${t}#${l}`;U.has(d)||(U.add(d),o=!0)}),o},ke=e=>{const t=z(e),r=a.multiplayerPeerJsHelper.getAllMessagesMap().get(t);if(!r)return;const s=r.getMessages();return s.length?s[s.length-1].getData().data:void 0},lt=(e,t)=>{const n=ke(e);!n||(g.info(`Received custom message ${e} with data ${JSON.stringify(n)}.`),t.fromJSObject(n))},gt=e=>{const t=z(e),r=a.multiplayerPeerJsHelper.getAllMessagesMap().get(t);if(!r)return 0;const s=r.getMessages();return s.length?s[s.length-1].getData().senderPlayerNumber:0},ut=()=>{if(!a.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const e=a.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(e.keys()).filter(r=>r.startsWith(ae)).forEach(r=>{const s=e.get(r);if(!s){D.error(`No messages list found for ${r}.`);return}const o=s.getMessages();!o.length||o.forEach(i=>{const c=i.getData(),l=i.getSender(),d=c.uniqueId;if(g.info(`Received custom message ${r} with data ${JSON.stringify(c)}.`),!at.exec(r)){D.error(`Invalid custom message ${r}.`);return}const f=`${r}#${d}`;if(U.has(f)){g.info(`Message ${r} has already been processed, skipping.`);return}const u=Pe(r);if(g.info(`Sending acknowledgment of custom message ${r} to ${l}.`),P([l],u,{}),a.multiplayer.isPlayerHost()){const m=a.multiplayerPeerJsHelper.getAllPeers();if(!m.length)return;L({originalMessageName:r,originalData:c,expectedMessageName:u,otherPeerIds:m,shouldCancelMessageIfTimesOut:!1}),P(m,r,c)}})})},Se="#updateScene",De=({sceneNetworkSyncData:e})=>({messageName:`${Se}`,messageData:e}),dt=e=>e.var?Q?JSON.stringify(e.var)!==JSON.stringify(Q.var):!0:!1,mt=()=>v()-de<1e3/He,pt=e=>{if(!a.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=e.getNetworkSyncData({playerNumber:a.multiplayer.getCurrentPlayerNumber()});if(!t)return;const n=dt(t),r=!mt()||n||W>0;if(n&&(W=3),!r)return;const s=a.multiplayerPeerJsHelper.getAllPeers(),{messageName:o,messageData:i}=De({sceneNetworkSyncData:t});P(s,o,i),de=v(),Q=t,W=Math.max(W-1,0)},ft=e=>{const t=a.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(s=>s.startsWith(Se)).forEach(s=>{const o=t.get(s);if(!o)return;const i=o.getMessages();!i.length||i.forEach(c=>{const l=c.getData(),d=c.getSender(),p=l.id;if(a.multiplayer.isReadyToSendOrReceiveGameUpdateMessages()){if(p!==e.networkId){g.info(`Received update of scene ${p}, but we are on ${e.networkId}. Skipping.`);return}e.updateFromNetworkSyncData(l)}else{g.info(`Saving scene ${p} update message for later use.`),V.store(l);return}if(a.multiplayer.isPlayerHost()){const u=a.multiplayerPeerJsHelper.getAllPeers().filter(m=>m!==d);P(u,s,l)}})})},ve="#updateGame",$e=({gameNetworkSyncData:e})=>({messageName:`${ve}`,messageData:e}),yt=e=>{const t=e.var,n=e.ss;if(!t&&!n)return!1;if(!J||!J.var||!J.ss||t&&JSON.stringify(t)!==JSON.stringify(J.var))return!0;if(n){if(n.length!==J.ss.length)return!0;for(let r=0;r<n.length;++r){const s=n[r],o=J.ss[r];if(s.name!==o.name||s.networkId!==o.networkId)return!0}}return!1},ht=()=>v()-me<1e3/xe,bt=e=>{if(!a.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=e.getGame().getNetworkSyncData({playerNumber:a.multiplayer.getCurrentPlayerNumber()});if(!t)return;const n=yt(t),r=!ht()||n||F>0;if(n&&(F=3),!r)return;const s=a.multiplayerPeerJsHelper.getAllPeers(),{messageName:o,messageData:i}=$e({gameNetworkSyncData:t});P(s,o,i),me=v(),J=t,F=Math.max(F-1,0)},Mt=e=>{const t=a.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(s=>s.startsWith(ve)).forEach(s=>{const o=t.get(s);if(!o)return;const i=o.getMessages();!i.length||i.forEach(c=>{const l=c.getData(),d=c.getSender();if(a.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())e.getGame().updateFromNetworkSyncData(l);else{g.info("Saving game update message for later use."),B.store(l);return}if(a.multiplayer.isPlayerHost()){const f=a.multiplayerPeerJsHelper.getAllPeers().filter(u=>u!==d);P(f,s,l)}})})},wt=e=>{B.getUpdates().forEach(t=>{g.info("Reapplying saved update of game."),e.getGame().updateFromNetworkSyncData(t)}),B.clear(),V.getUpdates().forEach(t=>{const n=t.id;if(n!==e.networkId){g.info(`Trying to apply saved update of scene ${n}, but we are on ${e.networkId}. Skipping.`);return}g.info(`Reapplying saved update of scene ${n}.`),e.updateFromNetworkSyncData(t),V.remove(t)})},oe="#heartbeat",It=/#heartbeat#(.+)/,ie=()=>{O[1]={ping:0,playerId:a.playerAuthentication.getUserId(),username:a.playerAuthentication.getUsername()};for(const e in O)O[e]={...O[e],ping:ce(parseInt(e,10))};return{messageName:`${oe}#${a.multiplayer.getCurrentPlayerNumber()}`,messageData:{now:v(),playersInfo:O}}},Ot=({heartbeatSentAt:e})=>({messageName:`${oe}#${a.multiplayer.getCurrentPlayerNumber()}`,messageData:{sentAt:e,playerId:a.playerAuthentication.getUserId(),username:a.playerAuthentication.getUsername()}}),Pt=()=>!!E&&v()-E<1e3/Le,Nt=()=>{if(!a.multiplayer.isPlayerHost()||!!Pt())return;const t=a.multiplayerPeerJsHelper.getAllPeers(),{messageName:n,messageData:r}=ie();P(t,n,r),E=v()},kt=()=>{const e=a.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(e.keys()).filter(r=>r.startsWith(oe)).forEach(r=>{const s=e.get(r);if(!s)return;const o=s.getMessages();!o.length||o.forEach(i=>{const c=i.getData(),l=i.getSender(),d=It.exec(r);if(!d)return;const p=parseInt(d[1],10);if(pe[l]=p,!a.multiplayer.isPlayerHost()){const h=a.multiplayer.getCurrentPlayerNumber(),b=Object.keys(O).map(R=>parseInt(R,10)),I=Object.keys(c.playersInfo).map(R=>parseInt(R,10)),H=O[h]&&O[h].ping;if(b.length){const R=I.filter(x=>!b.includes(x)&&x!==h);$.push(...R);const G=b.filter(x=>!I.includes(x));C.push(...G);for(const x of G)Y[x]=le(x)}Ce({source:c.playersInfo,target:O});const{messageName:T,messageData:j}=Ot({heartbeatSentAt:c.now});P([l],T,j),O[h]!==void 0&&O[h].ping!==void 0&&(a.multiplayer.markConnectionAsConnected(),H===void 0&&$.push(h));return}O[p]||$.push(p);const f=v(),u=c.sentAt,m=Math.round(f-u),y=K[p]||[];y.push(m),y.length>5&&y.shift(),K[p]=y;let M=0;for(const h of y)M+=h;const w=Math.round(M/y.length/2);if(O[p]={ping:w,playerId:c.playerId,username:c.username},$.length){const h=a.multiplayerPeerJsHelper.getAllPeers(),{messageName:b,messageData:I}=ie();P(h,b,I),E=v()}})})},ce=e=>{const t=O[e];return t&&t.ping||0},St=()=>{const e=a.multiplayer.getCurrentPlayerNumber();return ce(e)},Dt=e=>{if(D.info(`Marking player ${e} as disconnected.`),C.push(e),Y[e]=le(e),e===1){D.info("Host has disconnected, ending the game."),ge(),a.multiplayer.handleLobbyGameEnded();return}if(Bt(e),a.multiplayer.isPlayerHost()){const t=a.multiplayerPeerJsHelper.getAllPeers(),{messageName:n,messageData:r}=ie();P(t,n,r),E=v()}},le=e=>(O[e]||{}).username||Y[e]||`Player ${e}`,vt=e=>(O[e]||{}).playerId||"",$t=e=>{if(!a.multiplayer.isLobbyGameRunning())return;const t=[],n=a.multiplayerPeerJsHelper.getJustDisconnectedPeers();if(n.length)for(const r of n){const s=pe[r];if(!s)return;D.info(`Player ${s} has disconnected.`),t.push(s)}for(const r of t){if(a.multiplayer.isPlayerHost()){const s=e.getAdhocListOfAllInstances();for(const o of s){const i=o.getBehavior("MultiplayerObject");if(i&&i.getPlayerObjectOwnership()===r){const c=i.getActionOnPlayerDisconnect();c==="DestroyObject"?o.deleteFromScene(e):c==="GiveOwnershipToHost"&&i.removeObjectOwnership()}}}Dt(r)}},Rt=()=>C.length>0,At=e=>C.includes(e),Ct=()=>C,jt=()=>C[0]||0,Tt=()=>{const e=C[0];e!==void 0&&(C=C.slice(1),delete Y[e])},_t=()=>$.length>0,Jt=e=>$.includes(e),Ht=()=>$,xt=()=>$[0]||0,Lt=()=>{$[0]!==void 0&&($=$.slice(1))},Gt=()=>Object.keys(O).map(e=>({playerNumber:parseInt(e,10),playerId:O[e].playerId})),Et=()=>Object.keys(O).length,Ut=e=>O[e]!==void 0,Re="#endGame",Wt=()=>({messageName:Re,messageData:{}}),Vt=()=>{if(!a.multiplayer.isPlayerHost())return;g.info("Sending endgame message.");const e=a.multiplayerPeerJsHelper.getAllPeers(),{messageName:t,messageData:n}=Wt();P(e,t,n)},Ft=()=>{if(a.multiplayer.isPlayerHost())return;const t=a.multiplayerPeerJsHelper.getAllMessagesMap().get(Re);!t||!t.getMessages().length||(D.info("Received endgame message."),ge(),a.multiplayer.handleLobbyGameEnded())},ge=()=>{K={},O={},B.clear(),V.clear(),U.clear(),C=[],$=[],N={},_={}},Bt=e=>{delete K[e],delete O[e]};return{sendDataTo:P,addExpectedMessageAcknowledgement:L,handleAcknowledgeMessagesReceived:Qe,resendClearOrCancelAcknowledgedMessages:Ze,createChangeInstanceOwnerMessage:Ee,createInstanceOwnerChangedMessageNameFromChangeInstanceOwnerMessage:be,handleChangeInstanceOwnerMessagesReceived:We,createUpdateInstanceMessage:Fe,handleUpdateInstanceMessagesReceived:Be,createDestroyInstanceMessage:tt,createInstanceDestroyedMessageNameFromDestroyInstanceMessage:Oe,handleDestroyInstanceMessagesReceived:nt,createChangeVariableOwnerMessage:Ke,createVariableOwnerChangedMessageNameFromChangeVariableOwnerMessage:Ie,handleChangeVariableOwnerMessagesReceived:qe,sendCustomMessage:Ne,getCustomMessageData:ke,sendVariableCustomMessage:it,getVariableCustomMessageData:lt,hasCustomMessageBeenReceived:ct,handleCustomMessagesReceived:ut,getCustomMessageSender:gt,createUpdateSceneMessage:De,handleUpdateSceneMessagesToSend:pt,handleUpdateSceneMessagesReceived:ft,createUpdateGameMessage:$e,handleUpdateGameMessagesToSend:bt,handleUpdateGameMessagesReceived:Mt,handleSavedUpdateMessages:wt,handleHeartbeatsToSend:Nt,handleHeartbeatsReceived:kt,getPlayerPing:ce,getCurrentPlayerPing:St,getPlayerUsername:le,getPlayerId:vt,handleJustDisconnectedPeers:$t,getConnectedPlayers:Gt,getNumberOfConnectedPlayers:Et,isPlayerConnected:Ut,hasAnyPlayerJustLeft:Rt,hasPlayerJustLeft:At,getPlayersWhoJustLeft:Ct,getLatestPlayerWhoJustLeft:jt,removePlayerWhoJustLeft:Tt,hasAnyPlayerJustJoined:_t,hasPlayerJustJoined:Jt,getPlayersWhoJustJoined:Ht,getLatestPlayerWhoJustJoined:xt,removePlayerWhoJustJoined:Lt,sendEndGameMessage:Vt,handleEndGameMessages:Ft,clearAllMessagesTempData:ge}},a.multiplayerMessageManager=a.makeMultiplayerMessageManager()})(gdjs||(gdjs={}));
|
|
1
|
+
var gdjs;(function(s){const k=new s.Logger("Multiplayer"),g=new s.Logger("Multiplayer - Debug");s.Logger.getDefaultConsoleLoggerOutput().discardGroup("Multiplayer - Debug");class je{constructor(S){this.clear=()=>{this.cache.clear(),this.keys=[]};this.maxSize=S,this.cache=new Set,this.keys=[]}has(S){return this.cache.has(S)}add(S){if(this.cache.size>=this.maxSize){const D=this.keys.shift();D&&this.cache.delete(D)}this.cache.add(S),this.keys.push(S)}}class ue{constructor(){this._updates=[]}store(S){this._updates.push(S),this._updates.length>10&&this._updates.shift()}getUpdates(){return this._updates}remove(S){const D=this._updates.indexOf(S);D!==-1&&this._updates.splice(D,1)}clear(){this._updates=[]}}const Te=({target:C,source:S})=>{for(const D in S)S.hasOwnProperty(D)&&!C.hasOwnProperty(D)&&(C[D]=S[D]);for(const D in C)C.hasOwnProperty(D)&&!S.hasOwnProperty(D)&&delete C[D]};s.makeMultiplayerMessageManager=()=>{const C=0,S=0,D=0,Je=0,v=window.performance&&typeof window.performance.now=="function"?window.performance.now.bind(window.performance):Date.now,_e=200,Le=4,W=new je(500);let O={},H={};const xe=1;let me=0,Q=null,V=0,F=new ue;const Ge=1;let de=0,J=null,B=0,K=new ue;const Ee=1;let E=0,U={},pe={},M={},A=[],$=[],Y={};const x=({originalMessageName:e,originalData:t,expectedMessageName:n,otherPeerIds:r,shouldCancelMessageIfTimesOut:a,maxNumberOfRetries:o,messageRetryTime:l})=>{!s.multiplayer.isLobbyGameRunning()||(O[n]||(O[n]={}),g.info(`Adding expected message ${n} from ${r.join(", ")}.`),r.forEach(c=>{O[n][c]={acknowledged:!1,lastMessageSentAt:v(),originalMessageName:e,originalData:t,shouldCancelMessageIfTimesOut:a,numberOfRetries:0,maxNumberOfRetries:o||Le,messageRetryTime:l||_e}}))},fe=({sceneNetworkId:e,instanceNetworkId:t})=>(H[e]||(H[e]={}),H[e][t]||0),ye=({sceneNetworkId:e,instanceNetworkId:t,clock:n})=>{H[e]||(H[e]={}),H[e][t]=n},w=(e,t,n)=>{if(!(S>0&&Math.random()<S)){if(D>0&&Math.random()<D){setTimeout(()=>{s.multiplayerPeerJsHelper.sendDataTo(e,t,n)},Je);return}if(C>0){setTimeout(()=>{s.multiplayerPeerJsHelper.sendDataTo(e,t,n)},C);return}s.multiplayerPeerJsHelper.sendDataTo(e,t,n)}},Ue=(e,t,n)=>{if(!e.length)return null;let r=null,a=1/0;for(let o=0;o<e.length;++o){if(e[o].networkId)continue;const l=e[o],c=Math.pow(l.getX()-t,2)+Math.pow(l.getY()-n,2);c<a&&(r=l,a=c)}return r},Z=({runtimeScene:e,objectName:t,instanceNetworkId:n,instanceX:r,instanceY:a,shouldCreateIfNotFound:o})=>{const l=e.getInstancesOf(t);if(!l)return null;let c=l.find(i=>i.networkId===n)||null;if(!c&&r!==void 0&&a!==void 0){g.info(`instance ${t} ${n} not found with network ID, trying to find it with position ${r}/${a}.`);const i=Ue(l,r,a);i&&(g.info(`Found closest instance for object ${t} ${n} with no network ID.`),c=i,c.networkId=n)}if(!c&&o){g.info(`Instance ${n} still not found, Creating instance ${t}.`);const i=e.createObject(t);if(!i)return null;i.networkId=n,c=i}return c},q="#changeInstanceOwner",he=/#changeInstanceOwner#owner_(\d+)#object_(.+)#instance_(.+)/,We=({objectOwner:e,objectName:t,instanceNetworkId:n,newObjectOwner:r,instanceX:a,instanceY:o,sceneNetworkId:l})=>({messageName:`${q}#owner_${e}#object_${t}#instance_${n}`,messageData:{previousOwner:e,newOwner:r,instanceX:a,instanceY:o,sceneNetworkId:l}}),ee="#instanceOwnerChanged",Ve=/#instanceOwnerChanged#owner_(\d+)#object_(.+)#instance_(.+)/,be=e=>e.replace(q,ee),Fe=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(a=>a.startsWith(q)).forEach(a=>{const o=t.get(a);if(!o)return;const l=o.getMessages();!l.length||l.forEach(c=>{const i=c.getData(),m=c.getSender(),p=he.exec(a);if(!p)return;const f=p[2],u=p[3],d=i.previousOwner,y=i.newOwner,I=i.sceneNetworkId;if(I!==e.networkId){g.info(`Object ${f} is in scene ${I}, but we are on ${e.networkId}. Skipping.`);return}const P=Z({runtimeScene:e,objectName:f,instanceNetworkId:u,instanceX:i.instanceX,instanceY:i.instanceY});if(!P){g.info(`Instance ${u} not found, it must have been destroyed.`);return}const h=P.getBehavior("MultiplayerObject");if(!h){g.info(`Object ${f} does not have the MultiplayerObjectBehavior, cannot change ownership.`);return}const b=h.getPlayerObjectOwnership(),N=b===d||b===y;if(s.multiplayer.isCurrentPlayerHost()&&!N){g.info(`Object ${f} with instance network ID ${u} does not have the expected owner. Wanted to change from ${d} to ${y}, but object has owner ${b}.`);return}g.info(`Changing ownership of object ${f} to ${y}.`),h.playerNumber=y;const _=be(a);if(g.info(`Sending acknowledgment of ownership change of object ${f} from ${d} to ${y} with instance network ID ${u} to ${m}.`),w([m],_,{}),s.multiplayer.isCurrentPlayerHost()){const j=s.multiplayerPeerJsHelper.getAllPeers().filter(R=>R!==m);if(!j.length)return;x({originalMessageName:a,originalData:i,expectedMessageName:_,otherPeerIds:j,shouldCancelMessageIfTimesOut:!1}),g.info(`Relaying ownership change of object ${f} with instance network ID ${u} to ${j.join(", ")}.`),w(j,a,i)}})})},Me="#updateInstance",Be=/#updateInstance#owner_(\d+)#object_(.+)#instance_(.+)#scene_(.+)/,Ke=({objectOwner:e,objectName:t,instanceNetworkId:n,objectNetworkSyncData:r,sceneNetworkId:a})=>({messageName:`${Me}#owner_${e}#object_${t}#instance_${n}#scene_${a}`,messageData:r}),Ye=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(a=>a.startsWith(Me)).forEach(a=>{const o=t.get(a);if(!o)return;const l=o.getMessages();if(!l.length)return;l.slice().reverse().forEach(i=>{const m=i.getData(),p=i.getSender(),f=Be.exec(a);if(!f)return;const u=parseInt(f[1],10);if(u===s.multiplayer.playerNumber)return;const d=f[2],y=f[3],I=f[4];if(I!==e.networkId){g.info(`Object ${d} is in scene ${I}, but we are on ${e.networkId}. Skipping.`);return}const P=m._clock,h=fe({sceneNetworkId:I,instanceNetworkId:y});if(P<=h)return;const b=Z({runtimeScene:e,objectName:d,instanceNetworkId:y,shouldCreateIfNotFound:!0,instanceX:m.x,instanceY:m.y});if(!b){k.error("Instance could not be found or created.");return}const N=b.getBehavior("MultiplayerObject");if(!N){k.error(`Object ${d} does not have the MultiplayerObjectBehavior, cannot update it.`);return}if(N.getPlayerObjectOwnership()===s.multiplayer.playerNumber){g.info(`Object ${d} with instance network ID ${y} is owned by us ${s.multiplayer.playerNumber}, ignoring update message from ${u}.`);return}if(N.getPlayerObjectOwnership()!==u&&(g.info(`Object ${d} with instance network ID ${y} is owned by ${N.getPlayerObjectOwnership()} on our game, changing ownership to ${u} as part of the update event.`),N.playerNumber=u),b.updateFromNetworkSyncData(m),ye({sceneNetworkId:I,instanceNetworkId:y,clock:P}),N._clock=P,s.multiplayer.isCurrentPlayerHost()){const T=s.multiplayerPeerJsHelper.getAllPeers().filter(j=>j!==p);if(!T.length)return;w(T,a,m)}})})},X="#changeVariableOwner",we=/#changeVariableOwner#owner_(\d+)#variable_(.+)/,qe=({variableOwner:e,variableNetworkId:t,newVariableOwner:n})=>({messageName:`${X}#owner_${e}#variable_${t}`,messageData:{previousOwner:e,newOwner:n}}),te="#variableOwnerChanged",Xe=/#variableOwnerChanged#owner_(\d+)#variable_(.+)/,Ie=e=>e.replace(X,te),ze=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(a=>a.startsWith(X)).forEach(a=>{const o=t.get(a);if(!o)return;const l=o.getMessages();!l.length||l.forEach(c=>{const i=c.getData(),m=c.getSender(),p=we.exec(a);if(!p)return;const f=p[2],u=i.previousOwner,d=i.newOwner,{type:y,name:I,containerId:P}=s.multiplayerVariablesManager.getVariableTypeAndNameFromNetworkId(f);if(y==="scene"&&P!==e.networkId){g.info(`Variable ${I} is in scene ${P}, but we are on ${e.networkId}. Skipping.`);return}const h=P==="game"?e.getGame().getVariables():e.getVariables();if(!h.has(I)){k.error(`Variable with ID ${f} not found whilst syncing. This should not happen.`);return}const b=h.get(I),N=b.getPlayerOwnership(),_=N===u||N===d;if(s.multiplayer.isCurrentPlayerHost()&&!_){g.info(`Variable with ID ${f} does not have the expected owner. Wanted to change from ${u} to ${d}, but variable has owner ${N}.`);return}g.info(`Changing ownership of variable ${I} to ${d}.`),b.setPlayerOwnership(d);const T=Ie(a);if(g.info(`Sending acknowledgment of ownership change of variable with ID ${f} from ${u} to ${d} to ${m}.`),w([m],T,{}),s.multiplayer.isCurrentPlayerHost()){const R=s.multiplayerPeerJsHelper.getAllPeers().filter(G=>G!==m);if(!R.length)return;x({originalMessageName:a,originalData:i,expectedMessageName:T,otherPeerIds:R,shouldCancelMessageIfTimesOut:!1});for(const G of R)g.info(`Relaying ownership change of variable with Id ${f} to ${G}.`),w(R,a,i)}})})},Qe=e=>e.startsWith(ne)?at:e.startsWith(ee)?Ve:e.startsWith(te)?Xe:e.startsWith(re)?ct:null,Ze=e=>e.startsWith(ne)||e.startsWith(ee)||e.startsWith(te)||e.startsWith(re),et=()=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const e=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(e.keys()).filter(Ze).forEach(r=>{const a=e.get(r);if(!a)return;const o=a.getMessages();!o.length||o.forEach(l=>{const c=l.getData(),i=l.getSender();g.info(`Received acknowledgment for message ${r}.`);const m=Qe(r);if(!m){k.error(`Invalid acknowledgment message ${r}.`);return}const p=m.exec(r);if(!p){k.error(`Invalid acknowledgment message ${r}.`);return}if(!O[r]||!O[r][i])return;const f=c._clock;if(f!==void 0){const u=p[3],d=p[4],y=fe({sceneNetworkId:d,instanceNetworkId:u});if(f<=y)return;ye({sceneNetworkId:d,instanceNetworkId:u,clock:f})}g.info(`Marking message ${r} as acknowledged from ${i}.`),O[r][i].acknowledged=!0})})},tt=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;Object.keys(O).forEach(n=>{const r=O[n],a=Object.keys(r).filter(o=>!r[o].acknowledged);if(!a.length)g.info(`All peers have acknowledged message ${n}.`),delete O[n];else for(const o of a){const{lastMessageSentAt:l,originalMessageName:c,originalData:i,numberOfRetries:m,maxNumberOfRetries:p,messageRetryTime:f}=r[o];if(v()-l>f){if(m>=p){if(g.info(`Giving up on message ${n} for ${o}.`),r[o].shouldCancelMessageIfTimesOut){if(c.startsWith(q)){const u=he.exec(c);if(!u){delete O[n];return}const d=u[2],y=u[3],I=e.getInstancesOf(d);if(!I){delete O[n];return}let P=I.find(N=>N.networkId===y);if(!P){delete O[n];return}const h=P.getBehavior("MultiplayerObject");if(!h){k.error(`Object ${d} does not have the MultiplayerObjectBehavior, cannot revert ownership.`),delete O[n];return}const b=i.previousOwner;if(b===void 0){delete O[n];return}h.playerNumber=b||0}if(c.startsWith(X)){const u=we.exec(c);if(!u){delete O[n];return}const d=u[2],y=i.previousOwner,{type:I,name:P,containerId:h}=s.multiplayerVariablesManager.getVariableTypeAndNameFromNetworkId(d);if(I==="scene"&&h!==e.networkId){g.info(`Variable ${P} is in scene ${h}, but we are on ${e.networkId}. Skipping ownership revert.`),delete O[n];return}const b=h==="game"?e.getGame().getVariables():e.getVariables();if(!b.has(P)){k.error(`Variable with ID ${d} not found while reverting ownership. This should not happen.`),delete O[n];return}const N=b.get(P);if(y===void 0){delete O[n];return}N.setPlayerOwnership(y||0)}}delete O[n];continue}w([o],c,i),r[o].lastMessageSentAt=v(),r[o].numberOfRetries=m+1}}})},se="#destroyInstance",st=/#destroyInstance#owner_(\d+)#object_(.+)#instance_(.+)#scene_(.+)/,nt=({objectOwner:e,objectName:t,instanceNetworkId:n,sceneNetworkId:r})=>({messageName:`${se}#owner_${e}#object_${t}#instance_${n}#scene_${r}`,messageData:{}}),ne="#instanceDestroyed",at=/#instanceDestroyed#owner_(\d+)#object_(.+)#instance_(.+)/,Pe=e=>e.replace(se,ne),rt=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(a=>a.startsWith(se)).forEach(a=>{const o=t.get(a);if(!o)return;const l=o.getMessages();!l.length||l.forEach(c=>{const i=c.getData(),m=c.getSender();g.info(`Received message ${a} with data ${JSON.stringify(i)}.`);const p=st.exec(a);if(!p||parseInt(p[1],10)===s.multiplayer.playerNumber)return;const u=p[2],d=p[3],y=p[4];if(y!==e.networkId){g.info(`Object ${u} is in scene ${y}, but we are on ${e.networkId}. Skipping.`);return}const I=Z({runtimeScene:e,objectName:u,instanceNetworkId:d}),P=Pe(a);if(!I){g.info("Instance was not found in the scene, sending acknowledgment anyway."),w([m],P,{});return}if(g.info(`Destroying object ${u} with instance network ID ${d}.`),I.deleteFromScene(e),g.info(`Sending acknowledgment of destruction of object ${u} with instance network ID ${d} to ${m}.`),w([m],P,{}),s.multiplayer.isCurrentPlayerHost()){const b=s.multiplayerPeerJsHelper.getAllPeers().filter(N=>N!==m);if(!b.length)return;x({originalMessageName:a,originalData:i,expectedMessageName:P,otherPeerIds:b,shouldCancelMessageIfTimesOut:!1}),w(b,a,i)}})})},ae="#customMessage",ot=/#customMessage#(.+)/,z=e=>`${ae}#${e}`,it=({userMessageName:e,userMessageData:t,senderPlayerNumber:n})=>{const r=s.makeUuid();return{messageName:z(e),messageData:{data:t,uniqueId:r,senderPlayerNumber:n}}},re="#ackCustomMessage",ct=/#ackCustomMessage#(.+)/,Ne=e=>e.replace(ae,re),Oe=(e,t)=>{const n=s.multiplayerPeerJsHelper.getAllPeers(),r=s.multiplayer.getCurrentPlayerNumber(),{messageName:a,messageData:o}=it({userMessageName:e,userMessageData:t,senderPlayerNumber:r}),l=Ne(a);x({originalMessageName:a,originalData:o,expectedMessageName:l,otherPeerIds:n,shouldCancelMessageIfTimesOut:!1}),g.info(`Sending custom message ${e} with data ${JSON.stringify(t)}.`),w(n,a,o),s.multiplayer.isCurrentPlayerHost()&&s.multiplayerPeerJsHelper.getOrCreateMessagesList(a).pushMessage(o,s.multiplayerPeerJsHelper.getCurrentId())},lt=(e,t)=>{const n=t.toJSObject();g.info(`Sending custom message ${e} with data ${JSON.stringify(n)}.`),Oe(e,n)},gt=e=>{const t=z(e),r=s.multiplayerPeerJsHelper.getAllMessagesMap().get(t);if(!r)return;const a=r.getMessages();if(!a.length)return;g.info(`custom message ${e} has been received.`);let o=!1;return a.forEach(l=>{const i=l.getData().uniqueId,m=`${t}#${i}`;W.has(m)||(W.add(m),o=!0)}),o},Se=e=>{const t=z(e),r=s.multiplayerPeerJsHelper.getAllMessagesMap().get(t);if(!r)return;const a=r.getMessages();return a.length?a[a.length-1].getData().data:void 0},ut=(e,t)=>{const n=Se(e);!n||(g.info(`Received custom message ${e} with data ${JSON.stringify(n)}.`),t.fromJSObject(n))},mt=e=>{const t=z(e),r=s.multiplayerPeerJsHelper.getAllMessagesMap().get(t);if(!r)return 0;const a=r.getMessages();return a.length?a[a.length-1].getData().senderPlayerNumber:0},dt=()=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const e=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(e.keys()).filter(r=>r.startsWith(ae)).forEach(r=>{const a=e.get(r);if(!a){k.error(`No messages list found for ${r}.`);return}const o=a.getMessages();!o.length||o.forEach(l=>{const c=l.getData(),i=l.getSender(),m=c.uniqueId;if(g.info(`Received custom message ${r} with data ${JSON.stringify(c)}.`),!ot.exec(r)){k.error(`Invalid custom message ${r}.`);return}const f=`${r}#${m}`;if(W.has(f)){g.info(`Message ${r} has already been processed, skipping.`);return}const u=Ne(r);if(g.info(`Sending acknowledgment of custom message ${r} to ${i}.`),w([i],u,{}),s.multiplayer.isCurrentPlayerHost()){const d=s.multiplayerPeerJsHelper.getAllPeers();if(!d.length)return;x({originalMessageName:r,originalData:c,expectedMessageName:u,otherPeerIds:d,shouldCancelMessageIfTimesOut:!1}),w(d,r,c)}})})},De="#updateScene",ke=({sceneNetworkSyncData:e})=>({messageName:`${De}`,messageData:e}),pt=e=>e.var?Q?JSON.stringify(e.var)!==JSON.stringify(Q.var):!0:!1,ft=()=>v()-me<1e3/xe,yt=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=e.getNetworkSyncData({playerNumber:s.multiplayer.getCurrentPlayerNumber(),isHost:s.multiplayer.isCurrentPlayerHost()});if(!t)return;const n=pt(t),r=!ft()||n||V>0;if(n&&(V=3),!r)return;const a=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:o,messageData:l}=ke({sceneNetworkSyncData:t});w(a,o,l),me=v(),Q=t,V=Math.max(V-1,0)},ht=e=>{const t=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(a=>a.startsWith(De)).forEach(a=>{const o=t.get(a);if(!o)return;const l=o.getMessages();!l.length||l.forEach(c=>{const i=c.getData(),m=c.getSender(),p=i.id;if(s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages()){if(p!==e.networkId){g.info(`Received update of scene ${p}, but we are on ${e.networkId}. Skipping.`);return}e.updateFromNetworkSyncData(i)}else{g.info(`Saving scene ${p} update message for later use.`),F.store(i);return}if(s.multiplayer.isCurrentPlayerHost()){const u=s.multiplayerPeerJsHelper.getAllPeers().filter(d=>d!==m);w(u,a,i)}})})},ve="#updateGame",$e=({gameNetworkSyncData:e})=>({messageName:`${ve}`,messageData:e}),bt=e=>{const t=e.var,n=e.ss;if(!t&&!n)return!1;if(!J||!J.var||!J.ss||t&&JSON.stringify(t)!==JSON.stringify(J.var))return!0;if(n){if(n.length!==J.ss.length)return!0;for(let r=0;r<n.length;++r){const a=n[r],o=J.ss[r];if(a.name!==o.name||a.networkId!==o.networkId)return!0}}return!1},Mt=()=>v()-de<1e3/Ge,wt=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=e.getGame().getNetworkSyncData({playerNumber:s.multiplayer.getCurrentPlayerNumber(),isHost:s.multiplayer.isCurrentPlayerHost()});if(!t)return;const n=bt(t),r=!Mt()||n||B>0;if(n&&(B=3),!r)return;const a=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:o,messageData:l}=$e({gameNetworkSyncData:t});w(a,o,l),de=v(),J=t,B=Math.max(B-1,0)},It=e=>{const t=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(a=>a.startsWith(ve)).forEach(a=>{const o=t.get(a);if(!o)return;const l=o.getMessages();!l.length||l.forEach(c=>{const i=c.getData(),m=c.getSender();if(s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())e.getGame().updateFromNetworkSyncData(i);else{g.info("Saving game update message for later use."),K.store(i);return}if(s.multiplayer.isCurrentPlayerHost()){const f=s.multiplayerPeerJsHelper.getAllPeers().filter(u=>u!==m);w(f,a,i)}})})},Pt=e=>{K.getUpdates().forEach(t=>{g.info("Reapplying saved update of game."),e.getGame().updateFromNetworkSyncData(t)}),K.clear(),F.getUpdates().forEach(t=>{const n=t.id;if(n!==e.networkId){g.info(`Trying to apply saved update of scene ${n}, but we are on ${e.networkId}. Skipping.`);return}g.info(`Reapplying saved update of scene ${n}.`),e.updateFromNetworkSyncData(t),F.remove(t)})},oe="#heartbeat",Nt=/#heartbeat#(.+)/,ie=()=>{M[s.multiplayer.getCurrentPlayerNumber()]={ping:0,playerId:s.playerAuthentication.getUserId(),username:s.playerAuthentication.getUsername()};for(const e in M)M[e]={...M[e],ping:ce(parseInt(e,10))};return{messageName:`${oe}#${s.multiplayer.getCurrentPlayerNumber()}`,messageData:{now:v(),playersInfo:M}}},Ot=({heartbeatSentAt:e})=>({messageName:`${oe}#${s.multiplayer.getCurrentPlayerNumber()}`,messageData:{sentAt:e,playerId:s.playerAuthentication.getUserId(),username:s.playerAuthentication.getUsername()}}),St=()=>!!E&&v()-E<1e3/Ee,Dt=()=>{if(!s.multiplayer.isCurrentPlayerHost()||!!St())return;const t=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:n,messageData:r}=ie();w(t,n,r),E=v()},kt=()=>{const e=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(e.keys()).filter(r=>r.startsWith(oe)).forEach(r=>{const a=e.get(r);if(!a)return;const o=a.getMessages();!o.length||o.forEach(l=>{const c=l.getData(),i=l.getSender(),m=Nt.exec(r);if(!m)return;const p=parseInt(m[1],10);if(pe[i]=p,!s.multiplayer.isCurrentPlayerHost()){const h=s.multiplayer.getCurrentPlayerNumber(),b=Object.keys(M).map(R=>parseInt(R,10)),N=Object.keys(c.playersInfo).map(R=>parseInt(R,10)),_=M[h]&&M[h].ping;if(b.length){const R=N.filter(L=>!b.includes(L)&&L!==h);$.push(...R);const G=b.filter(L=>!N.includes(L));A.push(...G);for(const L of G)Y[L]=le(L)}Te({source:c.playersInfo,target:M});const{messageName:T,messageData:j}=Ot({heartbeatSentAt:c.now});w([i],T,j),M[h]!==void 0&&M[h].ping!==void 0&&(s.multiplayer.markConnectionAsConnected(),_===void 0&&$.push(h));return}M[p]||$.push(p);const f=v(),u=c.sentAt,d=Math.round(f-u),y=U[p]||[];y.push(d),y.length>5&&y.shift(),U[p]=y;let I=0;for(const h of y)I+=h;const P=Math.round(I/y.length/2);if(M[p]={ping:P,playerId:c.playerId,username:c.username},$.length){const h=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:b,messageData:N}=ie();w(h,b,N),E=v()}})})},vt=e=>(U[e]||[]).length>0,ce=e=>{const t=M[e];return t&&t.ping||0},$t=()=>{const e=s.multiplayer.getCurrentPlayerNumber();return ce(e)},Re=({runtimeScene:e,playerNumber:t,peerId:n})=>{if(k.info(`Marking player ${t} as disconnected.`),A.push(t),Y[t]=le(t),Qt(t),n&&n===s.multiplayer.hostPeerId)if(s.multiplayer.shouldEndLobbyWhenHostLeaves())k.info("Host has disconnected, ending the game."),ge(),s.multiplayer.handleLobbyGameEnded();else{k.info("Host has disconnected, switching host."),s.multiplayer.handleHostDisconnected({runtimeScene:e});return}if(s.multiplayer.isCurrentPlayerHost()){const r=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:a,messageData:o}=ie();w(r,a,o),E=v()}},le=e=>(M[e]||{}).username||Y[e]||`Player ${e}`,Rt=e=>(M[e]||{}).playerId||"",Ct=e=>{if(!s.multiplayer.isLobbyGameRunning())return;const t=[],n=s.multiplayerPeerJsHelper.getJustDisconnectedPeers();if(n.length)for(const r of n){const a=pe[r];if(!a)return;k.info(`Player ${a} has disconnected.`),t.push({playerNumber:a,peerId:r})}for(const{playerNumber:r,peerId:a}of t){if(s.multiplayer.isCurrentPlayerHost()){const o=e.getAdhocListOfAllInstances();for(const l of o){const c=l.getBehavior("MultiplayerObject");if(c&&c.getPlayerObjectOwnership()===r){const i=c.getActionOnPlayerDisconnect();i==="DestroyObject"?l.deleteFromScene(e):i==="GiveOwnershipToHost"&&c.removeObjectOwnership()}}}Re({runtimeScene:e,playerNumber:r,peerId:a})}},At=()=>A.length>0,jt=e=>A.includes(e),Tt=()=>A,Ht=()=>A[0]||0,Jt=()=>{const e=A[0];e!==void 0&&(A=A.slice(1),delete Y[e])},_t=()=>$.length>0,Lt=e=>$.includes(e),xt=()=>$,Gt=()=>$[0]||0,Et=()=>{$[0]!==void 0&&($=$.slice(1))},Ut=()=>Object.keys(M).map(e=>({playerNumber:parseInt(e,10),playerId:M[e].playerId})),Wt=()=>Object.keys(M).length,Vt=e=>M[e]!==void 0,Ft=()=>M,Ce="#endGame",Bt=()=>({messageName:Ce,messageData:{}}),Kt=()=>{if(!s.multiplayer.isCurrentPlayerHost())return;g.info("Sending endgame message.");const e=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:t,messageData:n}=Bt();w(e,t,n)},Yt=()=>{if(s.multiplayer.isCurrentPlayerHost())return;const t=s.multiplayerPeerJsHelper.getAllMessagesMap().get(Ce);!t||!t.getMessages().length||(k.info("Received endgame message."),ge(),s.multiplayer.handleLobbyGameEnded())},Ae="#resumeGame",qt=()=>({messageName:Ae,messageData:{}}),Xt=()=>{if(!s.multiplayer.isCurrentPlayerHost())return;g.info("Sending resumeGame message.");const e=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:t,messageData:n}=qt();w(e,t,n)},zt=e=>{if(s.multiplayer.isCurrentPlayerHost())return;const n=s.multiplayerPeerJsHelper.getAllMessagesMap().get(Ae);!n||!n.getMessages().length||(k.info("Received resumeGame message."),s.multiplayer.resumeGame(e))},ge=()=>{U={},M={},K.clear(),F.clear(),W.clear(),A=[],$=[],O={},H={}},Qt=e=>{delete U[e],delete M[e]};return{sendDataTo:w,addExpectedMessageAcknowledgement:x,handleAcknowledgeMessagesReceived:et,resendClearOrCancelAcknowledgedMessages:tt,createChangeInstanceOwnerMessage:We,createInstanceOwnerChangedMessageNameFromChangeInstanceOwnerMessage:be,handleChangeInstanceOwnerMessagesReceived:Fe,createUpdateInstanceMessage:Ke,handleUpdateInstanceMessagesReceived:Ye,createDestroyInstanceMessage:nt,createInstanceDestroyedMessageNameFromDestroyInstanceMessage:Pe,handleDestroyInstanceMessagesReceived:rt,createChangeVariableOwnerMessage:qe,createVariableOwnerChangedMessageNameFromChangeVariableOwnerMessage:Ie,handleChangeVariableOwnerMessagesReceived:ze,sendCustomMessage:Oe,getCustomMessageData:Se,sendVariableCustomMessage:lt,getVariableCustomMessageData:ut,hasCustomMessageBeenReceived:gt,handleCustomMessagesReceived:dt,getCustomMessageSender:mt,createUpdateSceneMessage:ke,handleUpdateSceneMessagesToSend:yt,handleUpdateSceneMessagesReceived:ht,createUpdateGameMessage:$e,handleUpdateGameMessagesToSend:wt,handleUpdateGameMessagesReceived:It,handleSavedUpdateMessages:Pt,handleHeartbeatsToSend:Dt,handleHeartbeatsReceived:kt,hasReceivedHeartbeatFromPlayer:vt,getPlayerPing:ce,getCurrentPlayerPing:$t,getPlayerUsername:le,getPlayerId:Rt,handleJustDisconnectedPeers:Ct,getConnectedPlayers:Ut,getNumberOfConnectedPlayers:Wt,isPlayerConnected:Vt,getPlayersInfo:Ft,hasAnyPlayerJustLeft:At,hasPlayerJustLeft:jt,getPlayersWhoJustLeft:Tt,getLatestPlayerWhoJustLeft:Ht,removePlayerWhoJustLeft:Jt,markPlayerAsDisconnected:Re,hasAnyPlayerJustJoined:_t,hasPlayerJustJoined:Lt,getPlayersWhoJustJoined:xt,getLatestPlayerWhoJustJoined:Gt,removePlayerWhoJustJoined:Et,sendEndGameMessage:Kt,handleEndGameMessagesReceived:Yt,clearAllMessagesTempData:ge,sendResumeGameMessage:Xt,handleResumeGameMessagesReceived:zt}},s.multiplayerMessageManager=s.makeMultiplayerMessageManager()})(gdjs||(gdjs={}));
|
|
2
2
|
//# sourceMappingURL=messageManager.js.map
|