UNPKG

phaser4-rex-plugins

Version:
1,253 lines (1,073 loc) 38 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.rexparseplugin = factory()); })(this, (function () { 'use strict'; var LoadScript = function (url, onload) { var scripts = document.getElementsByTagName('script'); for (var i = 0, cnt = scripts.length; i < cnt; i++) { if (scripts[i].src.indexOf(url) != -1) { if (onload) { onload(); } return; } } var newScriptTag = document.createElement('script'); newScriptTag.setAttribute('src', url); if (onload) { newScriptTag.onload = onload; } document.head.appendChild(newScriptTag); }; var LoadScriptPromise = function (url) { return new Promise(function (resolve, reject) { LoadScript(url, resolve); }); }; const VERSION = '2.11.0'; const CDNURL = `https://npmcdn.com/parse@${VERSION}/dist/parse.min.js`; var Preload = function (url) { if (url === undefined) { url = CDNURL; } return LoadScriptPromise(url); }; const FILE_POPULATED = Phaser.Loader.FILE_POPULATED; const UUID = Phaser.Utils.String.UUID; class AwaitFile extends Phaser.Loader.File { constructor(loader, fileConfig) { if (!fileConfig.hasOwnProperty('type')) { fileConfig.type = 'await'; } if (!fileConfig.hasOwnProperty('url')) { fileConfig.url = ''; } if (!fileConfig.hasOwnProperty('key')) { fileConfig.key = UUID(); } super(loader, fileConfig); } load() { if (this.state === FILE_POPULATED) { // Can happen for example in a JSONFile if they've provided a JSON object instead of a URL this.loader.nextFile(this, true); } else { // start loading task var config = this.config; var callback = config.callback; var scope = config.scope; if (callback) { var self = this; var runOnce = false; var successCallback = function () { if (runOnce) { return; } // Invoke onLoad next tick setTimeout(function () { self.onLoad(); }, 0); runOnce = true; }; var failureCallback = function () { if (runOnce) { return; } // Invoke onError next tick setTimeout(function () { self.onError(); }, 0); runOnce = true; }; if (scope) { callback.call(scope, successCallback, failureCallback); } else { callback(successCallback, failureCallback); } } else { this.onLoad(); } } } onLoad() { this.loader.nextFile(this, true); } onError() { this.loader.nextFile(this, false); } } const LoaderCallback = function (url) { var callback = function (successCallback, failureCallback) { return Preload(url) .then(function () { setTimeout(successCallback, 0); }) .catch(failureCallback) }; this.addFile(new AwaitFile(this, { config: { callback: callback } })); return this; }; class ObjectFactory { constructor() { } initializeApp(config) { firebase.initializeApp(config); return this; } static register(type, callback) { ObjectFactory.prototype[type] = callback; } } var GetValue = function (source, key, defaultValue) { if (!source || typeof source === 'number') { return defaultValue; } if (typeof (key) === 'string') { if (source.hasOwnProperty(key)) { return source[key]; } if (key.indexOf('.') !== -1) { key = key.split('.'); } else { return defaultValue; } } var keys = key; var parent = source; var value = defaultValue; // Use for loop here so we can break early for (var i = 0; i < keys.length; i++) { key = keys[i]; if (parent.hasOwnProperty(key)) { // Yes it has a key property, let's carry on down value = parent[key]; parent = value; } else { // Can't go any further, so reset to default value = defaultValue; break; } } return value; }; var Query = function (config) { if (config.startIndex === undefined) { config.startIndex = 0; } if (config.totalLines === undefined) { config.totalLines = Infinity; } if (config.linesPerPage === undefined) { config.linesPerPage = 1000; } config.remainderLines = config.totalLines; return QueryNextPage(config); }; var QueryNextPage = function (config) { var query = config.query; var lineCount = Math.min(config.remainderLines, config.linesPerPage); config.remainderLines -= lineCount; return query.skip(config.startIndex).limit(lineCount).find() .then(function (items) { var done = (config.remainderLines === 0) || (items.length < lineCount); // Is last page if (config.forEachPageCallback) { done |= !!config.forEachPageCallback(items); } if (done) { var out; if (config.resolveCallback) { out = config.resolveCallback(); } return Promise.resolve(out); } else { config.startIndex += items.length; return QueryNextPage(config); } }) }; var Load = function (query, startIndex, totalLines) { var out = []; return Query({ query: query, startIndex: startIndex, totalLines: totalLines, forEachPageCallback: function (items) { out.push(...items); }, resolveCallback: function () { return out; } }) }; var Methods$5 = { loadItems(startIndex, itemCount) { if (startIndex === undefined) { startIndex = 0; } if (itemCount === undefined) { itemCount = Infinity; } this.items.length = 0; var self = this; return Load(this.query, startIndex, itemCount) .then(function (items) { self.items = items; self.startIndex = startIndex; self.pageIndex = Math.floor(startIndex / self.itemCount); self.isFullPage = (itemCount === Infinity) ? true : (itemCount === items.length); return Promise.resolve(items); }) .catch(function (error) { self.isFullPage = false; return Promise.reject(error); }) }, loadPage(pageIndex) { var startIndex = pageIndex * this.itemCount; return this.loadItems(startIndex, this.itemCount); }, loadFirstPage() { return this.loadItems(0, this.itemCount); }, loadCurrentPage() { return this.loadItems(this.startIndex, this.itemCount); }, loadNextPage() { var startIndex = this.startIndex + this.itemCount; return this.loadItems(startIndex, this.itemCount); }, loadPreviousPage() { var startIndex = this.startIndex - this.itemCount; return this.loadItems(startIndex, this.itemCount); } }; class PageLoader { constructor(config) { this.items = []; this.startIndex = 0; this.pageIndex = 0; this.isFullPage = false; this.setItemCount(GetValue(config, 'itemCount', 100)); this.setQuery(GetValue(config, 'query', undefined)); } setItemCount(itemCount) { this.itemCount = itemCount; this.pageIndex = Math.floor(this.startIndex / itemCount); return this; } setQuery(query) { this.query = query; return this; } getItem(i) { return this.items[i - this.startIndex]; } findFirst(key, value) { for (var i, cnt = this.items.length; i < cnt; i++) { if (this.items[i].get(key) === value) { return i + this.startIndex; } } return -1; } } Object.assign( PageLoader.prototype, Methods$5 ); var IsInValidKey = function (keys) { return (keys == null) || (keys === '') || (keys.length === 0); }; var GetEntry = function (target, keys, defaultEntry) { var entry = target; if (IsInValidKey(keys)) ; else { if (typeof (keys) === 'string') { keys = keys.split('.'); } var key; for (var i = 0, cnt = keys.length; i < cnt; i++) { key = keys[i]; if ((entry[key] == null) || (typeof (entry[key]) !== 'object')) { var newEntry; if (i === cnt - 1) { if (defaultEntry === undefined) { newEntry = {}; } else { newEntry = defaultEntry; } } else { newEntry = {}; } entry[key] = newEntry; } entry = entry[key]; } } return entry; }; var SetValue = function (target, keys, value, delimiter) { if (delimiter === undefined) { delimiter = '.'; } // no object if (typeof (target) !== 'object') { return; } // invalid key else if (IsInValidKey(keys)) { // don't erase target if (value == null) { return; } // set target to another object else if (typeof (value) === 'object') { target = value; } } else { if (typeof (keys) === 'string') { keys = keys.split(delimiter); } var lastKey = keys.pop(); var entry = GetEntry(target, keys); entry[lastKey] = value; } return target; }; ObjectFactory.register('pageLoader', function (config) { return new PageLoader(config); }); SetValue(window, 'RexPlugins.Parse.PageLoader', PageLoader); var GetQuery = function (data) { var query = this.baseQuery; var isItem = (data instanceof this.customClass); var key, value; for (var i = 0, cnt = this.primaryKeys.length; i < cnt; i++) { key = this.primaryKeys[i]; value = (isItem) ? data.get(key) : data[key]; query.equalTo(key, value); } return query; }; /** * @author Richard Davey <rich@photonstorm.com> * @copyright 2018 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ /** * Shuffles the contents of the given array using the Fisher-Yates implementation. * * The original array is modified directly and returned. * * @function Phaser.Utils.Array.Shuffle * @since 3.0.0 * * @param {array} array - The array to shuffle. This array is modified in place. * * @return {array} The shuffled array. */ var Shuffle = function (array) { for (var i = array.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = array[i]; array[i] = array[j]; array[j] = temp; } return array; }; var LoadRandomItems = function (query, count) { if (typeof (query) === 'number') { count = query; query = undefined; } if (query === undefined) { query = this.baseQuery; } if (count === undefined) { count = 1; } // Load all item Id query.select('id'); var self = this; return Load(query) .then(function (items) { // Shuffle items Shuffle(items); count = Math.min(count, items.length); var itemIds = []; for (var i = 0; i < count; i++) { itemIds.push(items[i].id); } // Load first N items by item Id query = self.baseQuery.containedIn('objectId', itemIds); return Load(query) }) }; var Methods$4 = { loadItem(itemId, select) { if (typeof (itemId) === 'string') { var query = this.baseQuery; if (select) { query = query.select(select); } return query.get(itemId); } else { // Query by primary keys var query = this.getQuery(itemId).limit(1); if (select) { query = query.select(select); } return query.find() .then(function (result) { return Promise.resolve(result[0]); }) } }, loadPage(pageIndex) { return this.pageLoader.loadPage(pageIndex); }, loadCurrentPage() { return this.pageLoader.loadCurrentPage(); }, loadNextPage() { return this.pageLoader.loadNextPage(); }, loadPreviousPage() { return this.pageLoader.loadPreviousPage(); }, loadItems(startIndex, itemCount) { return this.pageLoader.loadItems(startIndex, itemCount); }, load(query) { if (query === undefined) { query = this.baseQuery; } return Load(query); }, loadRandomItems: LoadRandomItems }; var Delete = function (query) { query.select('id'); return Load(query) .then(function (items) { if (items.length === 0) { return Promise.resolve(); } return Parse.Object.destroyAll(items); }); }; var Methods$3 = { deleteItem(itemId) { return this.createItem().set('id', itemId).destroy(); }, delete(query) { if (query === undefined) { query = this.baseQuery; } return Delete(query); } }; var Copy = function (dest, src, startIdx, endIdx) { if (startIdx === undefined) { startIdx = 0; } if (endIdx === undefined) { endIdx = src.length; } dest.length = endIdx - startIdx; for (var i = 0, len = dest.length; i < len; i++) { dest[i] = src[i + startIdx]; } return dest; }; var IsArray = function(obj) { return Object.prototype.toString.call(obj) === '[object Array]'; }; var DataToItem = function (data, itemClass, item) { if (!item) { item = new itemClass(); } item.set(data); return item; }; var SetOwnerAccessMode = function (item, ownerRead, ownerWrite) { if (!ownerRead && !ownerWrite) { return item; } var currentUser = Parse.User.current(); if (!currentUser) { return item; } var acl = new Parse.ACL(currentUser); if (!ownerWrite) { acl.setPublicWriteAccess(true); } if (!ownerRead) { acl.setPublicReadAccess(true); } item.setACL(acl); return item; }; var Save = function (data) { // JSON data, or parse object if (IsArray(data)) { return this.saveItems(data); } var self = this; return new Promise(function (resolve, reject) { if (self.primaryKeys.length > 0) { self.loadItem(data, 'id') .then(resolve, reject); } else { return resolve(); } }) .then(function (item) { item = DataToItem(data, self.customClass, item); SetOwnerAccessMode(item, self.ownerRead, self.ownerWrite); return item.save(); }) }; var SaveItems = function (dataArray) { var self = this; return new Promise(function (resolve, reject) { var items = []; if (self.primaryKeys.length > 0) { var promises = [], promise; for (var i = 0, cnt = dataArray.length; i < cnt; i++) { let data = dataArray[i]; promise = self.loadItem(data, 'id') .then(function (item) { item = DataToItem(data, self.customClass, item); SetOwnerAccessMode(item, self.ownerRead, self.ownerWrite); items.push(item); }); promises.push(promise); } Promise.all(promises) .then(function () { return resolve(items); }) .catch(reject); } else { for (var i = 0, cnt = dataArray.length; i < cnt; i++) { var item = DataToItem(dataArray[i], self.customClass); SetOwnerAccessMode(item, self.ownerRead, self.ownerWrite); items.push(item); } return resolve(items); } }) .then(function (items) { return Parse.Object.saveAll(items); }) }; var GetItemCount = function (query) { if (query === undefined) { query = this.baseQuery; } return query.count(); }; class ItemTable { constructor(config) { this.pageLoader = new PageLoader(); this.setClassName(GetValue(config, 'className', 'Item')); this.setItemCount(GetValue(config, 'itemCount', 100)); this.setQuery(); // Reset to base query this.primaryKeys = []; var primaryKeys = GetValue(config, 'primaryKeys', undefined); if (primaryKeys) { this.setPrimaryKey(primaryKeys); } this.setOwnerReadMode(GetValue(config, 'ownerRead', undefined)); this.setOwnerWriteMode(GetValue(config, 'ownerWrite', undefined)); } setClassName(className) { this.customClass = Parse.Object.extend(className); return this; } setPrimaryKey(key) { if (!key) { this.primaryKeys.length = 0; } else if (typeof (key) === 'string') { this.primaryKeys.length = 1; this.primaryKeys[0] = key; } else { Copy(this.primaryKeys, key); } return this; } setOwnerReadMode(mode) { this.ownerRead = mode; return this; } setOwnerWriteMode(mode) { this.ownerWrite = mode; return this; } createItem() { return new this.customClass(); } setItemCount(itemCount) { this.pageLoader.setItemCount(itemCount); return this; } setQuery(query) { if (query === undefined) { query = this.baseQuery; } this.pageLoader.setQuery(query); return this; } get baseQuery() { return new Parse.Query(this.customClass); } get startIndex() { return this.pageLoader.startIndex; } get pageIndex() { return this.pageLoader.pageIndex; } get isLastPage() { return this.pageLoader.isLastPage; } } var methods$2 = { getQuery: GetQuery, save: Save, saveItems: SaveItems, getItemCount: GetItemCount, }; Object.assign( ItemTable.prototype, Methods$4, Methods$3, methods$2 ); ObjectFactory.register('itemTable', function (config) { return new ItemTable(config); }); SetValue(window, 'RexPlugins.Parse.ItemTable', ItemTable); var IsPlainObject = function (obj) { // Not plain objects: // - Any object or value whose internal [[Class]] property is not "[object Object]" // - DOM nodes // - window if (typeof(obj) !== 'object' || obj.nodeType || obj === obj.window) { return false; } // Support: Firefox <20 // The try/catch suppresses exceptions thrown when attempting to access // the "constructor" property of certain host objects, ie. |window.location| // https://bugzilla.mozilla.org/show_bug.cgi?id=814622 try { if (obj.constructor && !({}).hasOwnProperty.call(obj.constructor.prototype, 'isPrototypeOf')) { return false; } } catch (e) { return false; } // If the function hasn't returned already, we're confident that // |obj| is a plain object, created by {} or constructed with new Object return true; }; var GetTime = function (timeStamp) { var date = (timeStamp) ? (new Date(timeStamp)) : (new Date()); var y = date.getFullYear(); var m = date.getMonth() + 1; var d = date.getDate(); var Jan1st = new Date(date.getFullYear(), 0, 1); var w = Math.ceil((((date - Jan1st) / 86400000) + Jan1st.getDay() + 1) / 7); return { d: `${y}-${m}-${d}`, w: `${y}-${w}`, m: `${y}-${m}`, y: `${y}` }; }; var TimeTagKeys = { d: 'tagD', w: 'tagW', m: 'tagM', y: 'tagY' }; var ScoreKeys = { d: 'scoreD', w: 'scoreW', m: 'scoreM', y: 'scoreY' }; var Post = function (score, extraData, timeStamp) { var newRecord = { userID: this.userID }; if (this.boardID !== undefined) { newRecord.boardID = this.boardID; } if (this.userName) { newRecord.userName = this.userName; } var curTimeData = GetTime(timeStamp); if (this.timeFilters !== false) { for (var t in this.timeFilters) { if (!this.timeFilters[t]) { continue; } newRecord[TimeTagKeys[t]] = curTimeData[t]; newRecord[ScoreKeys[t]] = score; } } else { // No time filters newRecord.score = score; } if (this.tag) { newRecord.tag = this.tag; } if (extraData) { Object.assign(newRecord, extraData); } var curTimeData = GetTime(); var self = this; return this.getMyRecordQuery().find() .then(function (results) { var prevRecord = results[0]; if (prevRecord) { if (self.timeFilters !== false) { for (var t in self.timeFilters) { if (!self.timeFilters[t]) { continue; } var timeTagKey = TimeTagKeys[t]; if (prevRecord.get(timeTagKey) === newRecord[timeTagKey]) { var scoreKey = ScoreKeys[t]; newRecord[scoreKey] = Math.max(prevRecord.get(scoreKey), newRecord[scoreKey]); } } } else { // No time filters newRecord.score = Math.max(prevRecord.get('score'), newRecord.score); } } var item = DataToItem(newRecord, self.customClass, prevRecord); return item.save(); }); }; var Methods$2 = { loadFirstPage() { this.resetPageQuery(); var self = this; return this.page.loadFirstPage() .then(function (items) { return Promise.resolve(ItemsToDataArray.call(self, items)); }) }, loadNextPage() { this.resetPageQuery(); var self = this; return this.page.loadNextPage() .then(function (items) { return Promise.resolve(ItemsToDataArray.call(self, items)); }) }, loadPreviousPage() { this.resetPageQuery(); var self = this; return this.page.loadPreviousPage() .then(function (items) { return Promise.resolve(ItemsToDataArray.call(self, items)); }) }, loadCurrentPage() { this.resetPageQuery(); var self = this; return this.page.loadCurrentPage() .then(function (items) { return Promise.resolve(ItemsToDataArray.call(self, items)); }) }, load(count, skip) { this.resetPageQuery(); var self = this; return this.page.load(count, skip) .then(function (items) { return Promise.resolve(ItemsToDataArray.call(self, items)); }) }, resetPageQuery() { if (!this.resetQueryFlag) { return this; } this.resetQueryFlag = false; this.page.setQuery(this.getPageQuery()); return this; } }; var ItemsToDataArray = function (items) { var dataArray = [], data; var scoreKey = ScoreKeys[this.timeFilterType[0]]; for (var i = 0, cnt = items.length; i < cnt; i++) { data = items[i].toJSON(); if (this.timeFilters !== false) { data.score = data[scoreKey]; // Remove timeFilterKeys, and scoreKeys for (var t in this.timeFilters) { delete data[TimeTagKeys[t]]; delete data[ScoreKeys[t]]; } } dataArray.push(data); } return dataArray; }; var GetScore = function (userID) { return this.getMyRecordQuery(userID).find() .then(function (results) { var myRecord = results[0]; if (myRecord) { myRecord = myRecord.toJSON(); } return Promise.resolve(myRecord); }); }; var FindFirst = function (query, testCallback) { var out = { item: undefined, index: undefined }; var startIndex = 0; return Query({ query: query, forEachPageCallback: function (items) { var item; for (var i = 0, cnt = items.length; i < cnt; i++) { item = items[i]; if (testCallback(item)) { out.item = item; out.index = startIndex + i; return true; } } startIndex += items.length; }, resolveCallback: function () { return out; } }); }; var GetRank = function (userID) { if (userID === undefined) { userID = this.userID; } var query = this.getPageQuery(); var testCallback = function (item) { return (item.get('userID') === userID); }; return FindFirst(query, testCallback) .then(function (result) { return Promise.resolve({ userID: userID, rank: result.index }); }) }; var Methods$1 = { deleteUser(userID) { if (userID === undefined) { userID = this.userID; } var query = this.getRecordQuery(undefined, undefined, userID, undefined); return Delete(query); }, deleteBoard(boardId, tag) { if (boardId === undefined) { boardId = this.boardID; } if (tag === undefined) { tag = this.tag; } var query = this.getRecordQuery(boardId, tag, undefined, undefined); return Delete(query); } }; var Methods = { getRecordQuery(boardID, customTag, userID, timeTagKey) { var query = this.baseQuery; query = (boardID !== undefined) ? query.equalTo('boardID', boardID) : query; query = (customTag !== undefined) ? query.equalTo('tag', customTag) : query; query = (userID !== undefined) ? query.equalTo('userID', userID) : query; if (timeTagKey !== undefined) { query = query.equalTo(timeTagKey[0], timeTagKey[1]); } return query; }, getMyRecordQuery(userID) { if (userID === undefined) { userID = this.userID; } return this.getRecordQuery(this.boardID, this.tag, userID, undefined).limit(1); }, getPageQuery() { var timeTagKey, scoreKey; if (this.timeFilters !== false) { var t = this.timeFilterType[0]; timeTagKey = [TimeTagKeys[t], GetTime()[t]]; scoreKey = ScoreKeys[t]; } else { // No time filters timeTagKey = undefined; scoreKey = 'score'; } var query = this.getRecordQuery(this.boardID, this.tag, undefined, timeTagKey); query = query.descending(scoreKey); return query; } }; class LeaderBoard { constructor(config) { this.setClassName(GetValue(config, 'className', 'Item')); this.userInfo = { userID: undefined, userName: undefined }; this.setUser(GetValue(config, 'userID', ''), GetValue(config, 'userName', undefined)); this.setBoardID(GetValue(config, 'boardID', undefined)); this.setTag(GetValue(config, 'tag', undefined)); this.setTimeFilters(GetValue(config, 'timeFilters', false)); this.setTimeFilterType(GetValue(config, 'timeFilterType', 'year')); this.page = new PageLoader({ itemCount: GetValue(config, 'pageItemCount', 100) }); this.resetQueryFlag = true; } shutdown() { } destroy() { this.shutdown(); } get userID() { return this.userInfo.userID; } set userID(value) { this.userInfo.userID = value; } get userName() { return this.userInfo.userName; } set userName(value) { this.userInfo.userName = value; } setClassName(className) { this.resetQueryFlag = true; this.customClass = Parse.Object.extend(className); return this; } setUser(userID, userName) { if (IsPlainObject(userID)) { this.userInfo = userID; } else { this.userID = userID; this.userName = userName; } return this; } setBoardID(boardID) { this.resetQueryFlag |= (this.boardID !== boardID); this.boardID = boardID; return this; } setTag(tag) { this.resetQueryFlag |= (this.tag !== tag); this.tag = tag; return this; } setTimeFilters(filters) { if (filters === false) { this.timeFilters = false; } else { // filters is true, or a plain object this.timeFilters = { d: GetValue(filters, 'day', true), w: GetValue(filters, 'week', true), m: GetValue(filters, 'month', true), y: GetValue(filters, 'year', true) }; } return this; } setTimeFilterType(type) { this.resetQueryFlag |= (this.timeFilterType !== type); this.timeFilterType = type; return this; } setPageItemCount(count) { this.page.setItemCount(count); return this; } get baseQuery() { return new Parse.Query(this.customClass); } get pageIndex() { return this.page.pageIndex; } get isFirstPage() { return (this.page.pageIndex === 0); } get isLastPage() { return (this.page.isFullPage === false); } } var methods$1 = { post: Post, getScore: GetScore, getRank: GetRank }; Object.assign( LeaderBoard.prototype, methods$1, Methods, Methods$2, Methods$1 ); ObjectFactory.register('leaderBoard', function (config) { return new LeaderBoard(config); }); SetValue(window, 'RexPlugins.Parse.Leaderboard', LeaderBoard); var QuickLogin = function (userName, password) { return Parse.User.logOut() // // Log-out first .then(function () { return Parse.User.logIn(userName, password); // Try login }) .catch(function () { // Login fail, try sign-up, then login again return SignUpThenLogin(userName, password); }) }; var SignUpThenLogin = function (userName, password) { var user = new Parse.User(); user .set('username', userName) .set('password', password); return user.signUp() .then(function () { // Sign up success, try login again return Parse.User.logIn(userName, password); }) }; class ParsePlugin extends Phaser.Plugins.BasePlugin { constructor(pluginManager) { super(pluginManager); this.add = new ObjectFactory(); } start() { var eventEmitter = this.game.events; eventEmitter.on('destroy', this.destroy, this); } preload(scene, url) { LoaderCallback.call(scene.sys.load, url); return this; } } var methods = { quickLogin: QuickLogin }; Object.assign( ParsePlugin.prototype, methods ); return ParsePlugin; }));