diff --git a/babel.config.js b/babel.config.js
new file mode 100644
index 0000000..a313bdb
--- /dev/null
+++ b/babel.config.js
@@ -0,0 +1,35 @@
+module.exports = function (api) {
+ api.cache(false);
+ const presets = [
+ [ "@babel/preset-typescript"],
+ [
+ "@babel/preset-env",
+ {
+ "corejs": { "version": "3.8" },
+ "useBuiltIns": "usage",
+ "targets": {
+ "edge": "15",
+ "firefox": "51",
+ "chrome": "56",
+ "safari": "11.1",
+ "ie": "11"
+ }
+ }
+ ]
+ ];
+ const plugins = [
+ "@babel/plugin-proposal-class-properties",
+ [
+ "@babel/plugin-transform-runtime",
+ {
+ "corejs": 3,
+ "version": "^7.12.5",
+ },
+ ],
+ "@babel/plugin-transform-arrow-functions",
+ ];
+ return {
+ presets,
+ plugins
+ };
+};
diff --git a/package.json b/package.json
index 1b71370..e023678 100644
--- a/package.json
+++ b/package.json
@@ -3,25 +3,38 @@
"version": "1.0.0",
"description": "ChatChat ported to HTML5",
"scripts": {
- "build": "webpack"
+ "build": "webpack",
+ "start": "webpack serve"
},
"private": true,
"repository": "https://gitdab.com/s/chatchat.git",
- "author": "Soren",
+ "author": "Aly",
"license": "GPL2",
"devDependencies": {
+ "@babel/core": "^7.12.10",
+ "@babel/plugin-proposal-class-properties": "^7.12.1",
+ "@babel/plugin-transform-arrow-functions": "^7.12.1",
+ "@babel/plugin-transform-runtime": "^7.12.10",
+ "@babel/preset-env": "^7.12.11",
+ "@babel/preset-typescript": "^7.12.7",
+ "@babel/runtime-corejs3": "^7.12.5",
"@types/fontfaceobserver": "^0.0.6",
- "css-loader": "^4.3.0",
- "file-loader": "^6.1.0",
+ "babel-loader": "^8.2.2",
+ "css-loader": "^5.0.1",
+ "file-loader": "^6.2.0",
"html-webpack-plugin": "^4.5.0",
- "style-loader": "^1.2.1",
- "ts-loader": "^8.0.4",
- "typescript": "^4.0.3",
- "webpack": "^4.44.2",
- "webpack-cli": "^3.3.12"
+ "style-loader": "^2.0.0",
+ "ts-loader": "^8.0.12",
+ "typescript": "^4.1.3",
+ "webpack": "^5.11.0",
+ "webpack-cli": "^4.3.0",
+ "webpack-dev-server": "^3.11.0"
},
"dependencies": {
+ "@babel/runtime": "^7.12.5",
+ "core-js": "^3.8.1",
"fontfaceobserver": "^2.1.0",
- "pixi.js": "^5.3.3"
+ "pixi.js": "^5.3.6",
+ "whatwg-fetch": "^3.5.0"
}
}
diff --git a/src/PlayerIOAsync.ts b/src/PlayerIOAsync.ts
deleted file mode 100644
index c6c8115..0000000
--- a/src/PlayerIOAsync.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import './PlayerIOClient.development';
-
-export const authenticate = function (
- gameId: string,
- connectionId: string,
- authenticationArguments: Record,
- playerInsightSegments: Array,
-): Promise {
- return new Promise((resolve, reject) => {
- PlayerIO.authenticate(gameId, connectionId, authenticationArguments, playerInsightSegments, resolve, reject);
- });
-}
-
-export const listRooms = function (
- multiplayer: PlayerIO.Multiplayer,
- roomType: string,
- searchCriteria: Record,
- resultLimit: number,
- resultOffset: number,
-): Promise> {
- return new Promise>((resolve, reject) => {
- multiplayer.listRooms(roomType, searchCriteria, resultLimit, resultOffset, resolve, reject);
- });
-}
diff --git a/src/PlayerIOClient.development.d.ts b/src/PlayerIOClient.development.d.ts
deleted file mode 100644
index 413f7fa..0000000
--- a/src/PlayerIOClient.development.d.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-declare enum PlayerIOErrorCode {
-
-}
-
-declare class PlayerIOError {
- code: PlayerIOErrorCode;
- message: string;
- stack: any;
-}
-
-declare namespace PlayerIO {
- let useSecureApiRequests: boolean;
- const authenticate: (gameId: string, connectionId: string, authenticationArguments: Record, playerInsightSegments: Array, successCallback: (client: PlayerIO.Client) => void, errorCallback: (error: PlayerIOError) => void) => void;
-
- class Client {
- multiplayer: Multiplayer;
- }
-
- class Multiplayer {
- useSecureConnections: boolean;
- listRooms: (roomType: string, searchCriteria: Record, resultLimit: number, resultOffset: number, successCallback: (rooms: Array) => void, errorCallback: (error: PlayerIOError) => void) => void
- }
-
- class RoomInfo {
- id: string;
- onlineUsers: number;
- roomData: Record;
- roomType: string;
- }
-}
-
diff --git a/src/PlayerIOClient.development.js b/src/PlayerIOClient.development.js
deleted file mode 100644
index 7830a86..0000000
--- a/src/PlayerIOClient.development.js
+++ /dev/null
@@ -1,5081 +0,0 @@
-if (typeof (_pio) == 'undefined') { _pio = {} }
-(function () {
- _pio.channel = function () { };
- _pio.channel.prototype.call = function (method, args, successCallback, errorCallback, converter) {
- var url = typeof(PLAYERIO_API_HOST) != 'undefined' ? PLAYERIO_API_HOST : ((PlayerIO.useSecureApiRequests ? 'https' : 'http') + '://api.playerio.com/json/');
-
- var webrequest = new XMLHttpRequest();
- if ("withCredentials" in webrequest) { // Both Safari 4 and Firefox 3.5 provide the withCredentials property on XMLHttpRequest
- //webrequest.withCredentials = true;
- webrequest.open("post", url, true);
- } else if (typeof XDomainRequest != "undefined") { // IE uses XDomainRequest for some reason (?)
- webrequest = new XDomainRequest();
- webrequest.open("post", url);
- } else {
- // USE FLASH
- webrequest = new _pio.flashWebRequest("post",url );
- }
-
- var originalStack = new Error();
-
- if (webrequest != null) {
- webrequest.send("[" +method + "|" + (this.token||"") + "]" + JSON.stringify(args));
- webrequest.onload = function () {
- var result = null;
- try{
- var response = webrequest.response || webrequest.responseText;
- if( response[0] == "[" ){
- var end = response.indexOf("]");
- this.token = response.substring(1,end);
- response = response.substring(end+1)
- }
- result = JSON.parse(response)
- }catch(e){
- _pio.handleError(originalStack, errorCallback, PlayerIOErrorCode.GeneralError, "Error decoding response from webservice: " + e)
- return;
- }
-
- // success or error?
- if( typeof(result.errorcode) == 'undefined' && typeof(result.message) == 'undefined' ){
- var value = result;
- if( converter ){
- try{
- value = converter(result);
- } catch (e) {
- _pio.handleError(originalStack, errorCallback, PlayerIOErrorCode.GeneralError, e.message)
- }
- }
- if( successCallback ){
- successCallback(value)
- }
- }else{
- _pio.handleError(originalStack, errorCallback, result.errorcode, result.message)
- }
- }
- webrequest.onerror = function (req) {
- _pio.handleError(originalStack, errorCallback, PlayerIOErrorCode.GeneralError, "Error talking to webservice: " + JSON.stringify(req))
- }
- } else {
- _pio.handleError(originalStack, errorCallback, PlayerIOErrorCode.GeneralError, "Need to implement flash calling")
- }
- };
- _pio.runCallback = function(callback, callbackArg, originalStackError){
- try{
- if( callback ){
- callback(callbackArg);
- }
- } catch (e) {
- var message = "Unhandled error in callback: " + e.message;
- message += "\nStack:\n"
- message += (e.stack||e.stacktrace||e.StackTrace);
- if( originalStackError ){
- message += "\nCallsite stack:\n"
- message += (originalStackError.stack||originalStackError.stacktrace||originalStackError.StackTrace);
- }
- console.log(message)
- }
- }
- _pio.handleError = function(originalStackError,errorCallback,code,message){
- var err = _pio.error(code, message)
- if(originalStackError){
- if(originalStackError.stack) err.stack = originalStackError.stack;
- if(originalStackError.stacktrace) err.stacktrace = originalStackError.stacktrace;
- if(originalStackError.StackTrace) err.StackTrace = originalStackError.StackTrace
- }
-
- if( errorCallback ){
- _pio.runCallback(errorCallback, err, originalStackError)
- }else if(typeof(console) != 'undefined'){
- console.log("No error callback specified for: "+err.code + ": " + err.message + "\n" + (err.stack||err.stacktrace||err.StackTrace));
- }else{
- alert("No error callback specified for: "+err.code + ": " + err.message + "\n" + (err.stack||err.stacktrace||err.StackTrace));
- }
- }
- _pio.error = function(code,message){
- if(arguments.length == 1 ){
- message = code;
- code = PlayerIOErrorCode.GeneralError;
- }
-
- if( typeof(code) == 'number' ){
- code = PlayerIOErrorCode.codes[code]
- }
- if( typeof(code) != 'string' ){
- console.log(code, message, new Error().stack)
- throw "Code must be a string!"
- }
- var e = new Error()
- return new PlayerIOError(code, message, (e.stack || e.stacktrace || e.StackTrace));
- }
- _pio.debugLog = function(message){
- if (typeof (console) != 'undefined') {
- console.log(message);
- }
- }
-
- _pio.convertToKVArray = function(object){
- var result = []
- if( object ){
- for(var k in object){
- result.push({key:(''+k),value:(''+object[k])})
- }
- }
- return result;
- }
-
- _pio.convertFromKVArray = function(arr){
- var result = {}
- if( arr && arr.length){
- for(var k in arr){
- result[ arr[k].key ] = arr[k].value
- }
- }
- return result;
- }
-
- _pio.convertToSegmentArray = function (object) {
- var result = [];
- if (object) {
- for (var k in object) {
- result.push(k + ':' + object[k]);
- }
- }
- return result;
- };
-})();
-/**
-* @class Main class for authenticating a user and getting a client.
-* @example Here is an example of using the class to authenticate:
-*
-* PlayerIO.authenticate(
-* '[Enter your game id here]', //Game id
-* 'public', //Connection id
-* { userId:'user-id' }, //Authentication arguments
-* { campaign:'2017' }, //Optional PlayerInsight segments
-* function(client) {
-* //Success!
-* //You can now use the client object to make API calls.
-* },
-* function(error) {
-* if (error.code == PlayerIOErrorCode.UnknownGame) {
-* //Unknown game id used
-* } else {
-* //Another error
-* }
-* }
-* );
-*
-*/
-PlayerIO = {
- /**
- * If set to true, all API Requests will be encrypted using TLS/SSL. Be aware that this will cause a performance degradation by introducting secure connection negotiation latency for all requests.
- * @type bool
- */
- useSecureApiRequests: false,
-
- /**
- * Authenticates a user to Player.IO. See the Authentication documentation on which authenticationArguments that are needed for each authentication provider.
- * @param {string} gameId The game id of the game you wish to connect to. This value can be found in the admin panel.
- * @param {string} connectionId The id of the connection, as given in the settings section of the admin panel. 'public' should be used as the default
- * @param {object} authenticationArguments A dictionary of arguments for the given connection.
- * @param {object} playerInsightSegments Custom segments for the user in PlayerInsight.
- * @param {function(client)} successCallback Callback function that will be called with a client when succesfully connected
- * @param {function(PlayerIOError)} errorCallback Callback function that will be called if an error occurs
- */
- authenticate: function (gameId, connectionId, authenticationArguments, playerInsightSegments, successCallback, errorCallback) {
- if (authenticationArguments.publishingnetworklogin == 'auto') {
- if (typeof (window.PublishingNetwork) == 'undefined') {
- errorCallback(new PlayerIOError(PlayerIOErrorCode.GeneralError, "Could not find the PublishingNetwork object on the current page. Did you include the PublishingNetwork.js script?"));
- return
- }
- PublishingNetwork.dialog("login", { gameId: gameId, connectionId: connectionId, __use_usertoken__: true }, function (r) {
- if (r.error) {
- errorCallback(new PlayerIOError(PlayerIOErrorCode.GeneralError, r.error));
- } else if (typeof(r.userToken) == 'undefined') {
- errorCallback(new PlayerIOError(PlayerIOErrorCode.GeneralError, "Missing userToken value in result, but no error message given."));
- } else {
- PlayerIO.authenticate(gameId, connectionId, {userToken:r.userToken}, playerInsightSegments, successCallback, errorCallback)
- }
- })
- return
- }
-
- var channel = new _pio.channel();
- channel.authenticate(gameId, connectionId, _pio.convertToKVArray(authenticationArguments), _pio.convertToSegmentArray(playerInsightSegments), "javascript", _pio.convertToKVArray({}), null, successCallback, errorCallback, function (result) {
- channel.token = result.token;
- return new _pio.client(channel, gameId, result.gamefsredirectmap, result.userid);
- });
- },
-
- /**
- * Access the QuickConnect service
- * @type {quickConnect}
- */
- quickConnect: null, // gets overwritten at runtime.
-
- /**
- * Get a gameFS instance for a specific game (only use this method when you don't have a valid client).
- * @param {string} gameId The game id of the game you wish to access.
- */
- gameFS: function (gameId) {
- return new _pio.gameFS(gameId);
- }
-};
-var JSON;
-if (!JSON) {
- JSON = {};
-}
-
-(function () {
- 'use strict';
-
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
-
- if (typeof Date.prototype.toJSON !== 'function') {
-
- Date.prototype.toJSON = function (key) {
-
- return isFinite(this.valueOf())
- ? this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z'
- : null;
- };
-
- String.prototype.toJSON =
- Number.prototype.toJSON =
- Boolean.prototype.toJSON = function (key) {
- return this.valueOf();
- };
- }
-
- var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- gap,
- indent,
- meta = { // table of character substitutions
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '"': '\\"',
- '\\': '\\\\'
- },
- rep;
-
-
- function quote(string) {
-
- // If the string contains no control characters, no quote characters, and no
- // backslash characters, then we can safely slap some quotes around it.
- // Otherwise we must also replace the offending characters with safe escape
- // sequences.
-
- escapable.lastIndex = 0;
- return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
- var c = meta[a];
- return typeof c === 'string'
- ? c
- : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- }) + '"' : '"' + string + '"';
- }
-
-
- function str(key, holder) {
-
- // Produce a string from holder[key].
-
- var i, // The loop counter.
- k, // The member key.
- v, // The member value.
- length,
- mind = gap,
- partial,
- value = holder[key];
-
- // If the value has a toJSON method, call it to obtain a replacement value.
-
- if (value && typeof value === 'object' &&
- typeof value.toJSON === 'function') {
- value = value.toJSON(key);
- }
-
- // If we were called with a replacer function, then call the replacer to
- // obtain a replacement value.
-
- if (typeof rep === 'function') {
- value = rep.call(holder, key, value);
- }
-
- // What happens next depends on the value's type.
-
- switch (typeof value) {
- case 'string':
- return quote(value);
-
- case 'number':
-
- // JSON numbers must be finite. Encode non-finite numbers as null.
-
- return isFinite(value) ? String(value) : 'null';
-
- case 'boolean':
- case 'null':
-
- // If the value is a boolean or null, convert it to a string. Note:
- // typeof null does not produce 'null'. The case is included here in
- // the remote chance that this gets fixed someday.
-
- return String(value);
-
- // If the type is 'object', we might be dealing with an object or an array or
- // null.
-
- case 'object':
-
- // Due to a specification blunder in ECMAScript, typeof null is 'object',
- // so watch out for that case.
-
- if (!value) {
- return 'null';
- }
-
- // Make an array to hold the partial results of stringifying this object value.
-
- gap += indent;
- partial = [];
-
- // Is the value an array?
-
- if (Object.prototype.toString.apply(value) === '[object Array]') {
-
- // The value is an array. Stringify every element. Use null as a placeholder
- // for non-JSON values.
-
- length = value.length;
- for (i = 0; i < length; i += 1) {
- partial[i] = str(i, value) || 'null';
- }
-
- // Join all of the elements together, separated with commas, and wrap them in
- // brackets.
-
- v = partial.length === 0
- ? '[]'
- : gap
- ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
- : '[' + partial.join(',') + ']';
- gap = mind;
- return v;
- }
-
- // If the replacer is an array, use it to select the members to be stringified.
-
- if (rep && typeof rep === 'object') {
- length = rep.length;
- for (i = 0; i < length; i += 1) {
- if (typeof rep[i] === 'string') {
- k = rep[i];
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- } else {
-
- // Otherwise, iterate through all of the keys in the object.
-
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- }
-
- // Join all of the member texts together, separated with commas,
- // and wrap them in braces.
-
- v = partial.length === 0
- ? '{}'
- : gap
- ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
- : '{' + partial.join(',') + '}';
- gap = mind;
- return v;
- }
- }
-
- // If the JSON object does not yet have a stringify method, give it one.
-
- if (typeof JSON.stringify !== 'function') {
- JSON.stringify = function (value, replacer, space) {
-
- // The stringify method takes a value and an optional replacer, and an optional
- // space parameter, and returns a JSON text. The replacer can be a function
- // that can replace values, or an array of strings that will select the keys.
- // A default replacer method can be provided. Use of the space parameter can
- // produce text that is more easily readable.
-
- var i;
- gap = '';
- indent = '';
-
- // If the space parameter is a number, make an indent string containing that
- // many spaces.
-
- if (typeof space === 'number') {
- for (i = 0; i < space; i += 1) {
- indent += ' ';
- }
-
- // If the space parameter is a string, it will be used as the indent string.
-
- } else if (typeof space === 'string') {
- indent = space;
- }
-
- // If there is a replacer, it must be a function or an array.
- // Otherwise, throw an error.
-
- rep = replacer;
- if (replacer && typeof replacer !== 'function' &&
- (typeof replacer !== 'object' ||
- typeof replacer.length !== 'number')) {
- throw new Error('JSON.stringify');
- }
-
- // Make a fake root object containing our value under the key of ''.
- // Return the result of stringifying the value.
-
- return str('', { '': value });
- };
- }
-
-
- // If the JSON object does not yet have a parse method, give it one.
-
- if (typeof JSON.parse !== 'function') {
- JSON.parse = function (text, reviver) {
-
- // The parse method takes a text and an optional reviver function, and returns
- // a JavaScript value if the text is a valid JSON text.
-
- var j;
-
- function walk(holder, key) {
-
- // The walk method is used to recursively walk the resulting structure so
- // that modifications can be made.
-
- var k, v, value = holder[key];
- if (value && typeof value === 'object') {
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = walk(value, k);
- if (v !== undefined) {
- value[k] = v;
- } else {
- delete value[k];
- }
- }
- }
- }
- return reviver.call(holder, key, value);
- }
-
-
- // Parsing happens in four stages. In the first stage, we replace certain
- // Unicode characters with escape sequences. JavaScript handles many characters
- // incorrectly, either silently deleting them, or treating them as line endings.
-
- text = String(text);
- cx.lastIndex = 0;
- if (cx.test(text)) {
- text = text.replace(cx, function (a) {
- return '\\u' +
- ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- });
- }
-
- // In the second stage, we run the text against regular expressions that look
- // for non-JSON patterns. We are especially concerned with '()' and 'new'
- // because they can cause invocation, and '=' because it can cause mutation.
- // But just to be safe, we want to reject all unexpected forms.
-
- // We split the second stage into 4 regexp operations in order to work around
- // crippling inefficiencies in IE's and Safari's regexp engines. First we
- // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
- // replace all simple value tokens with ']' characters. Third, we delete all
- // open brackets that follow a colon or comma or that begin the text. Finally,
- // we look to see that the remaining characters are only whitespace or ']' or
- // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
-
- if (/^[\],:{}\s]*$/
- .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
- .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
- .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
-
- // In the third stage we use the eval function to compile the text into a
- // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
- // in JavaScript: it can begin a block or an object literal. We wrap the text
- // in parens to eliminate the ambiguity.
-
- j = eval('(' + text + ')');
-
- // In the optional fourth stage, we recursively walk the new structure, passing
- // each name/value pair to a reviver function for possible transformation.
-
- return typeof reviver === 'function'
- ? walk({ '': j }, '')
- : j;
- }
-
- // If the text is not JSON parseable, then a SyntaxError is thrown.
-
- throw new SyntaxError('JSON.parse');
- };
- }
-}());
-(function () {
- var callbacks = {};
- var idCounter = 0;
- var flashUrl = "http://192.168.30.154/html5client/FlashFallback/bin-debug/FlashFallback.swf"
-
- // this method gets called back from flash
- __pio_flashfallback_callback__ = function () {
- var callback = callbacks[arguments[0]];
- if (callback) {
- var args = []
- for (var i = 1; i != arguments.length; i++) {
- args[i - 1] = arguments[i];
- }
- callback.apply(null, args);
- }
- }
-
- _pio.flashWebRequest = function (method, url) {
- var self = this;
-
- this.response = null;
- this.onload = function () { }
- this.onerror = function () { }
-
- this.send = function (data) {
- getFlashFallbackObj(function (obj) {
- if (obj == null) {
- self.onerror("Browser does not support Cross-Origin (CORS) webrequest or Flash as a fallback method");
- } else {
- var id = "cb" + (idCounter++)
-
- callbacks[id] = function (success, response) {
- delete callbacks[id];
- if (success) {
- self.response = response;
- self.onload();
- } else {
- self.onerror(response);
- }
- }
-
- // start the web request via flash
- obj.webrequest(id, method, url, data)
- }
- })
- }
- }
-
- _pio.flashSocketConnection = function (endpoint, connectTimeout, onConnectResult, onDisconnect, onMessage) {
- var id = "cb" + (idCounter++)
- var self = this;
- var serializer = new _pio.messageSerializer();
- var connectComplete = false;
- var connected = false;
- var timeout = setTimeout(function () {
- if (!connectComplete) {
- connectComplete = true;
- onConnectResult(false, "Connect attempt timed out");
- }
- }, connectTimeout);
-
- this.disconnect = function () { console.log("... this shouldn't happen"); }
- this.sendMessage = function (message) { console.log("... send msg. this shouldn't happen"); }
-
- getFlashFallbackObj(function (obj) {
- if (obj == null) {
- connectComplete = true;
- onConnectResult(false, "Browser does not support WebSocket connections and the Flash fallback failed.");
- } else {
- callbacks[id] = function (evt, data) {
- switch (evt) {
- case 'onopen':
- if (!connectComplete) {
- clearTimeout(timeout)
- connectComplete = true;
- connected = true;
- obj.socketSend(id, [0]); // protocol selection
- onConnectResult(connected);
- }
- break;
- case 'onclose':
- self.disconnect();
- break;
- case 'onerror':
- self.disconnect();
- break;
- case 'onmessage':
- onMessage(serializer.deserializeMessage(data, 0, data.length))
- break;
- }
- }
-
- self.disconnect = function () {
- if (connected) {
- connected = false;
- onDisconnect();
- try {
- obj.socketClose(id);
- } catch (e) { _pio.debugLog(e) }
- }
- }
-
- self.sendMessage = function (message) {
- var serialized = serializer.serializeMessage(message);
- obj.socketSend(id, serialized);
- }
-
- // start the web request via flash
- obj.socketConnection(id, endpoint)
- }
- })
- }
-
- _pio.isFlashFallbackEnabled = function (callback) {
- getFlashFallbackObj(function (obj) {
- callback(obj != null);
- })
- }
-
- var fallbackObj = null;
- var fallbackFailed = false;
- var waitingGetFallbacks = null;
-
- function getFlashFallbackObj(callback) {
- if (fallbackObj != null) {
- callback(fallbackObj);
- } else if (fallbackFailed) {
- callback(null);
- } else {
- if (waitingGetFallbacks == null) {
- // create the list for future listners
- waitingGetFallbacks = [callback];
-
- // try to create the flash object
- var tryInterval = setInterval(function () {
- var obj = createFallbackObj();
- if (obj != null) {
- done(obj);
- }
- }, 50);
-
- // set a timeout to timeout the request if it does not work
- setTimeout(function () {
- if (fallbackObj == null) {
- done(null);
- }
- }, 30000);
-
- var done = function (obj) {
- fallbackObj = obj;
- fallbackFailed = obj == null;
- clearInterval(tryInterval);
- for (var i = 0; i != waitingGetFallbacks.length; i++) {
- waitingGetFallbacks[i](obj);
- }
- }
- } else {
- waitingGetFallbacks.push(callback);
- }
- }
- }
-
- function createFallbackObj() {
- var id = "__pio_flashfallback__";
- var containerId = "__pio_flashfallback_container__";
- var html = ""
- html += ''
- html = html.replace(/\$id\$/gi, id);
- html = html.replace(/\$src\$/gi, flashUrl);
- html = html.replace(/\$style\$/gi, "width:10px;height:10px");
-
- var container = document.getElementById("containerId");
- if (!container) {
- var div = document.createElement("div");
- div.setAttribute("id", container)
- div.setAttribute("style", "position:absolute;top:-20px;left:-20px")
- div.innerHTML = html;
- try {
- document.body.appendChild(div);
- } catch (e) { }
- }
-
- var find = function (tag) {
- var list = document.getElementsByTagName(tag);
- for (var i = 0; i != list.length; i++) {
- if (list[i].ping && list[i].ping() == "pong") {
- return list[i]
- }
- }
- };
-
- return find("embed") || find("object");
- }
-})();
-
-(function () {
- var c = _pio.channel.prototype;
- c.connect = function(gameId, connectionId, userId, auth, partnerId, playerInsightSegments, clientAPI, clientInfo, successCallback, errorCallback, converter){this.call(10, {gameid:gameId, connectionid:connectionId, userid:userId, auth:auth, partnerid:partnerId, playerinsightsegments:playerInsightSegments, clientapi:clientAPI, clientinfo:clientInfo}, successCallback, errorCallback, converter)}
- _pio.ApiSecurityRule = {RespectClientSetting:0,UseHttp:1,UseHttps:2}
- c.authenticate = function(gameId, connectionId, authenticationArguments, playerInsightSegments, clientAPI, clientInfo, playCodes, successCallback, errorCallback, converter){this.call(13, {gameid:gameId, connectionid:connectionId, authenticationarguments:authenticationArguments, playerinsightsegments:playerInsightSegments, clientapi:clientAPI, clientinfo:clientInfo, playcodes:playCodes}, successCallback, errorCallback, converter)}
- c.createRoom = function(roomId, roomType, visible, roomData, isDevRoom, successCallback, errorCallback, converter){this.call(21, {roomid:roomId, roomtype:roomType, visible:visible, roomdata:roomData, isdevroom:isDevRoom}, successCallback, errorCallback, converter)}
- c.joinRoom = function(roomId, joinData, isDevRoom, serverDomainNameNeeded, successCallback, errorCallback, converter){this.call(24, {roomid:roomId, joindata:joinData, isdevroom:isDevRoom, serverdomainnameneeded:serverDomainNameNeeded}, successCallback, errorCallback, converter)}
- c.createJoinRoom = function(roomId, roomType, visible, roomData, joinData, isDevRoom, serverDomainNameNeeded, successCallback, errorCallback, converter){this.call(27, {roomid:roomId, roomtype:roomType, visible:visible, roomdata:roomData, joindata:joinData, isdevroom:isDevRoom, serverdomainnameneeded:serverDomainNameNeeded}, successCallback, errorCallback, converter)}
- c.listRooms = function(roomType, searchCriteria, resultLimit, resultOffset, onlyDevRooms, successCallback, errorCallback, converter){this.call(30, {roomtype:roomType, searchcriteria:searchCriteria, resultlimit:resultLimit, resultoffset:resultOffset, onlydevrooms:onlyDevRooms}, successCallback, errorCallback, converter)}
- c.userLeftRoom = function(extendedRoomId, newPlayerCount, closed, successCallback, errorCallback, converter){this.call(40, {extendedroomid:extendedRoomId, newplayercount:newPlayerCount, closed:closed}, successCallback, errorCallback, converter)}
- c.writeError = function(source, error, details, stacktrace, extraData, successCallback, errorCallback, converter){this.call(50, {source:source, error:error, details:details, stacktrace:stacktrace, extradata:extraData}, successCallback, errorCallback, converter)}
- c.updateRoom = function(extendedRoomId, visible, roomData, successCallback, errorCallback, converter){this.call(53, {extendedroomid:extendedRoomId, visible:visible, roomdata:roomData}, successCallback, errorCallback, converter)}
- _pio.ValueType = {String:0,Int:1,UInt:2,Long:3,Bool:4,Float:5,Double:6,ByteArray:7,DateTime:8,Array:9,Obj:10}
- c.createObjects = function(objects, loadExisting, successCallback, errorCallback, converter){this.call(82, {objects:objects, loadexisting:loadExisting}, successCallback, errorCallback, converter)}
- c.loadObjects = function(objectIds, successCallback, errorCallback, converter){this.call(85, {objectids:objectIds}, successCallback, errorCallback, converter)}
- _pio.LockType = {NoLocks:0,LockIndividual:1,LockAll:2}
- c.saveObjectChanges = function(lockType, changesets, createIfMissing, successCallback, errorCallback, converter){this.call(88, {locktype:lockType, changesets:changesets, createifmissing:createIfMissing}, successCallback, errorCallback, converter)}
- c.deleteObjects = function(objectIds, successCallback, errorCallback, converter){this.call(91, {objectids:objectIds}, successCallback, errorCallback, converter)}
- c.loadMatchingObjects = function(table, index, indexValue, limit, successCallback, errorCallback, converter){this.call(94, {table:table, index:index, indexvalue:indexValue, limit:limit}, successCallback, errorCallback, converter)}
- c.loadIndexRange = function(table, index, startIndexValue, stopIndexValue, limit, successCallback, errorCallback, converter){this.call(97, {table:table, index:index, startindexvalue:startIndexValue, stopindexvalue:stopIndexValue, limit:limit}, successCallback, errorCallback, converter)}
- c.deleteIndexRange = function(table, index, startIndexValue, stopIndexValue, successCallback, errorCallback, converter){this.call(100, {table:table, index:index, startindexvalue:startIndexValue, stopindexvalue:stopIndexValue}, successCallback, errorCallback, converter)}
- c.loadMyPlayerObject = function(successCallback, errorCallback, converter){this.call(103, {}, successCallback, errorCallback, converter)}
- c.payVaultReadHistory = function(page, pageSize, targetUserId, successCallback, errorCallback, converter){this.call(160, {page:page, pagesize:pageSize, targetuserid:targetUserId}, successCallback, errorCallback, converter)}
- c.payVaultRefresh = function(lastVersion, targetUserId, successCallback, errorCallback, converter){this.call(163, {lastversion:lastVersion, targetuserid:targetUserId}, successCallback, errorCallback, converter)}
- c.payVaultConsume = function(ids, targetUserId, successCallback, errorCallback, converter){this.call(166, {ids:ids, targetuserid:targetUserId}, successCallback, errorCallback, converter)}
- c.payVaultCredit = function(amount, reason, targetUserId, successCallback, errorCallback, converter){this.call(169, {amount:amount, reason:reason, targetuserid:targetUserId}, successCallback, errorCallback, converter)}
- c.payVaultDebit = function(amount, reason, targetUserId, successCallback, errorCallback, converter){this.call(172, {amount:amount, reason:reason, targetuserid:targetUserId}, successCallback, errorCallback, converter)}
- c.payVaultBuy = function(items, storeItems, targetUserId, successCallback, errorCallback, converter){this.call(175, {items:items, storeitems:storeItems, targetuserid:targetUserId}, successCallback, errorCallback, converter)}
- c.payVaultGive = function(items, targetUserId, successCallback, errorCallback, converter){this.call(178, {items:items, targetuserid:targetUserId}, successCallback, errorCallback, converter)}
- c.payVaultPaymentInfo = function(provider, purchaseArguments, items, successCallback, errorCallback, converter){this.call(181, {provider:provider, purchasearguments:purchaseArguments, items:items}, successCallback, errorCallback, converter)}
- c.payVaultUsePaymentInfo = function(provider, providerArguments, successCallback, errorCallback, converter){this.call(184, {provider:provider, providerarguments:providerArguments}, successCallback, errorCallback, converter)}
- c.partnerPayTrigger = function(key, count, successCallback, errorCallback, converter){this.call(200, {key:key, count:count}, successCallback, errorCallback, converter)}
- c.partnerPaySetTag = function(partnerId, successCallback, errorCallback, converter){this.call(203, {partnerid:partnerId}, successCallback, errorCallback, converter)}
- c.notificationsRefresh = function(lastVersion, successCallback, errorCallback, converter){this.call(213, {lastversion:lastVersion}, successCallback, errorCallback, converter)}
- c.notificationsRegisterEndpoints = function(lastVersion, endpoints, successCallback, errorCallback, converter){this.call(216, {lastversion:lastVersion, endpoints:endpoints}, successCallback, errorCallback, converter)}
- c.notificationsSend = function(notifications, successCallback, errorCallback, converter){this.call(219, {notifications:notifications}, successCallback, errorCallback, converter)}
- c.notificationsToggleEndpoints = function(lastVersion, endpoints, enabled, successCallback, errorCallback, converter){this.call(222, {lastversion:lastVersion, endpoints:endpoints, enabled:enabled}, successCallback, errorCallback, converter)}
- c.notificationsDeleteEndpoints = function(lastVersion, endpoints, successCallback, errorCallback, converter){this.call(225, {lastversion:lastVersion, endpoints:endpoints}, successCallback, errorCallback, converter)}
- c.gameRequestsSend = function(requestType, requestData, requestRecipients, successCallback, errorCallback, converter){this.call(241, {requesttype:requestType, requestdata:requestData, requestrecipients:requestRecipients}, successCallback, errorCallback, converter)}
- c.gameRequestsRefresh = function(playCodes, successCallback, errorCallback, converter){this.call(244, {playcodes:playCodes}, successCallback, errorCallback, converter)}
- c.gameRequestsDelete = function(requestIds, successCallback, errorCallback, converter){this.call(247, {requestids:requestIds}, successCallback, errorCallback, converter)}
- c.achievementsRefresh = function(lastVersion, successCallback, errorCallback, converter){this.call(271, {lastversion:lastVersion}, successCallback, errorCallback, converter)}
- c.achievementsLoad = function(userIds, successCallback, errorCallback, converter){this.call(274, {userids:userIds}, successCallback, errorCallback, converter)}
- c.achievementsProgressSet = function(achievementId, progress, successCallback, errorCallback, converter){this.call(277, {achievementid:achievementId, progress:progress}, successCallback, errorCallback, converter)}
- c.achievementsProgressAdd = function(achievementId, progressDelta, successCallback, errorCallback, converter){this.call(280, {achievementid:achievementId, progressdelta:progressDelta}, successCallback, errorCallback, converter)}
- c.achievementsProgressMax = function(achievementId, progress, successCallback, errorCallback, converter){this.call(283, {achievementid:achievementId, progress:progress}, successCallback, errorCallback, converter)}
- c.achievementsProgressComplete = function(achievementId, successCallback, errorCallback, converter){this.call(286, {achievementid:achievementId}, successCallback, errorCallback, converter)}
- c.playerInsightRefresh = function(successCallback, errorCallback, converter){this.call(301, {}, successCallback, errorCallback, converter)}
- c.playerInsightSetSegments = function(segments, successCallback, errorCallback, converter){this.call(304, {segments:segments}, successCallback, errorCallback, converter)}
- c.playerInsightTrackInvitedBy = function(invitingUserId, invitationChannel, successCallback, errorCallback, converter){this.call(307, {invitinguserid:invitingUserId, invitationchannel:invitationChannel}, successCallback, errorCallback, converter)}
- c.playerInsightTrackEvents = function(events, successCallback, errorCallback, converter){this.call(311, {events:events}, successCallback, errorCallback, converter)}
- c.playerInsightTrackExternalPayment = function(currency, amount, successCallback, errorCallback, converter){this.call(314, {currency:currency, amount:amount}, successCallback, errorCallback, converter)}
- c.playerInsightSessionKeepAlive = function(successCallback, errorCallback, converter){this.call(317, {}, successCallback, errorCallback, converter)}
- c.playerInsightSessionStop = function(successCallback, errorCallback, converter){this.call(320, {}, successCallback, errorCallback, converter)}
- c.oneScoreLoad = function(userIds, successCallback, errorCallback, converter){this.call(351, {userids:userIds}, successCallback, errorCallback, converter)}
- c.oneScoreSet = function(score, successCallback, errorCallback, converter){this.call(354, {score:score}, successCallback, errorCallback, converter)}
- c.oneScoreAdd = function(score, successCallback, errorCallback, converter){this.call(357, {score:score}, successCallback, errorCallback, converter)}
- c.oneScoreRefresh = function(successCallback, errorCallback, converter){this.call(360, {}, successCallback, errorCallback, converter)}
- c.simpleConnect = function(gameId, usernameOrEmail, password, playerInsightSegments, clientAPI, clientInfo, successCallback, errorCallback, converter){this.call(400, {gameid:gameId, usernameoremail:usernameOrEmail, password:password, playerinsightsegments:playerInsightSegments, clientapi:clientAPI, clientinfo:clientInfo}, successCallback, errorCallback, converter)}
- c.simpleRegister = function(gameId, username, password, email, captchaKey, captchaValue, extraData, partnerId, playerInsightSegments, clientAPI, clientInfo, successCallback, errorCallback, converter){this.call(403, {gameid:gameId, username:username, password:password, email:email, captchakey:captchaKey, captchavalue:captchaValue, extradata:extraData, partnerid:partnerId, playerinsightsegments:playerInsightSegments, clientapi:clientAPI, clientinfo:clientInfo}, successCallback, errorCallback, converter)}
- c.simpleRecoverPassword = function(gameId, usernameOrEmail, successCallback, errorCallback, converter){this.call(406, {gameid:gameId, usernameoremail:usernameOrEmail}, successCallback, errorCallback, converter)}
- c.kongregateConnect = function(gameId, userId, gameAuthToken, playerInsightSegments, clientAPI, clientInfo, successCallback, errorCallback, converter){this.call(412, {gameid:gameId, userid:userId, gameauthtoken:gameAuthToken, playerinsightsegments:playerInsightSegments, clientapi:clientAPI, clientinfo:clientInfo}, successCallback, errorCallback, converter)}
- c.simpleGetCaptcha = function(gameId, width, height, successCallback, errorCallback, converter){this.call(415, {gameid:gameId, width:width, height:height}, successCallback, errorCallback, converter)}
- c.facebookOAuthConnect = function(gameId, accessToken, partnerId, playerInsightSegments, clientAPI, clientInfo, successCallback, errorCallback, converter){this.call(418, {gameid:gameId, accesstoken:accessToken, partnerid:partnerId, playerinsightsegments:playerInsightSegments, clientapi:clientAPI, clientinfo:clientInfo}, successCallback, errorCallback, converter)}
- c.steamConnect = function(gameId, steamAppId, steamSessionTicket, playerInsightSegments, clientAPI, clientInfo, successCallback, errorCallback, converter){this.call(421, {gameid:gameId, steamappid:steamAppId, steamsessionticket:steamSessionTicket, playerinsightsegments:playerInsightSegments, clientapi:clientAPI, clientinfo:clientInfo}, successCallback, errorCallback, converter)}
- c.simpleUserGetSecureLoginInfo = function(successCallback, errorCallback, converter){this.call(424, {}, successCallback, errorCallback, converter)}
- c.leaderboardsGet = function(group, leaderboard, index, count, neighbourUserId, filterUserIds, successCallback, errorCallback, converter){this.call(431, {group:group, leaderboard:leaderboard, index:index, count:count, neighbouruserid:neighbourUserId, filteruserids:filterUserIds}, successCallback, errorCallback, converter)}
- c.leaderboardsSet = function(group, leaderboard, score, successCallback, errorCallback, converter){this.call(434, {group:group, leaderboard:leaderboard, score:score}, successCallback, errorCallback, converter)}
- c.leaderboardsCount = function(group, leaderboard, successCallback, errorCallback, converter){this.call(437, {group:group, leaderboard:leaderboard}, successCallback, errorCallback, converter)}
- c.joinCluster = function(clusterAccessKey, isDevelopmentServer, ports, machineName, version, machineId, os, cpu, cpuCores, cpuLogicalCores, cpuAddressWidth, cpuMaxClockSpeed, ramMegabytes, ramSpeed, successCallback, errorCallback, converter){this.call(504, {clusteraccesskey:clusterAccessKey, isdevelopmentserver:isDevelopmentServer, ports:ports, machinename:machineName, version:version, machineid:machineId, os:os, cpu:cpu, cpucores:cpuCores, cpulogicalcores:cpuLogicalCores, cpuaddresswidth:cpuAddressWidth, cpumaxclockspeed:cpuMaxClockSpeed, rammegabytes:ramMegabytes, ramspeed:ramSpeed}, successCallback, errorCallback, converter)}
- c.serverHeartbeat = function(serverId, appDomains, serverTypes, machineCPU, processCPU, memoryUsage, avaliableMemory, freeMemory, runningRooms, usedResources, aPIRequests, aPIRequestsError, aPIRequestsFailed, aPIRequestsExecuting, aPIRequestsQueued, aPIRequestsTime, serverUnixTimeUtc, successCallback, errorCallback, converter){this.call(510, {serverid:serverId, appdomains:appDomains, servertypes:serverTypes, machinecpu:machineCPU, processcpu:processCPU, memoryusage:memoryUsage, avaliablememory:avaliableMemory, freememory:freeMemory, runningrooms:runningRooms, usedresources:usedResources, apirequests:aPIRequests, apirequestserror:aPIRequestsError, apirequestsfailed:aPIRequestsFailed, apirequestsexecuting:aPIRequestsExecuting, apirequestsqueued:aPIRequestsQueued, apirequeststime:aPIRequestsTime, serverunixtimeutc:serverUnixTimeUtc}, successCallback, errorCallback, converter)}
- c.getGameAssemblyUrl = function(clusterAccessKey, gameCodeId, machineId, successCallback, errorCallback, converter){this.call(513, {clusteraccesskey:clusterAccessKey, gamecodeid:gameCodeId, machineid:machineId}, successCallback, errorCallback, converter)}
- c.devServerLogin = function(username, password, successCallback, errorCallback, converter){this.call(524, {username:username, password:password}, successCallback, errorCallback, converter)}
- c.webserviceOnlineTest = function(successCallback, errorCallback, converter){this.call(533, {}, successCallback, errorCallback, converter)}
- c.getServerInfo = function(machineId, successCallback, errorCallback, converter){this.call(540, {machineid:machineId}, successCallback, errorCallback, converter)}
- c.socialRefresh = function(successCallback, errorCallback, converter){this.call(601, {}, successCallback, errorCallback, converter)}
- c.socialLoadProfiles = function(userIds, successCallback, errorCallback, converter){this.call(604, {userids:userIds}, successCallback, errorCallback, converter)}
-})();
-
-/**
-* @class Instances of this class are returned in all error callbacks and contain information about the error that occurred.
-* @example Here is an example of authenticating and then handling an UnknownGame error:
-*
-* PlayerIO.authenticate(
-* '[Enter your game id here]', //Game id
-* 'public', //Connection id
-* { userId: 'user-id' }, //Authentication arguments
-* { campaign: '2017' }, //Optional PlayerInsight segments
-* function(client) {
-* //Success!
-* //You can now use the client object to make API calls.
-* },
-* function(error) {
-* if (error.code == PlayerIOErrorCode.UnknownGame) {
-* //Unknown game id used
-* } else {
-* //Another error
-* }
-* }
-* );
-*
-*/
-PlayerIOError = function (code, message, stack) {
- /** The PlayerIO error code for this error
- * @type string
- */
- this.code = code
-
- /** The error message for this error
- * @type string
- */
- this.message = message
-
- /** The stack for this error, if any. The type depends on the current browser.
- * @type object
- */
- this.stack = stack
- if (!this.stack) {
- var e = new Error()
- this.stack = e.stack || e.stacktrace || e.StackTrace
- }
-
- /** Get a string representation of error
- * @return string */
- this.toString = function () {
- return "PlayerIOError[" + code + "]: " + message;
- }
-};
-PlayerIOError.prototype = new Error();
-
-/**
-* @class This class contains a list of all the error codes that can be returned from PlayerIO calls
-* @example Here is an example of authenticating and then handling an UnknownGame error:
-*
-* PlayerIO.authenticate(
-* '[Enter your game id here]', //Game id
-* 'public', //Connection id
-* { userId: 'user-id' }, //Authentication arguments
-* { campaign: '2017' }, //Optional PlayerInsight segments
-* function(client) {
-* //Success!
-* //You can now use the client object to make API calls.
-* },
-* function(error) {
-* if (error.code == PlayerIOErrorCode.UnknownGame) {
-* //Unknown game id used
-* } else {
-* //Another error
-* }
-* }
-* );
-*
-*/
-PlayerIOErrorCode = {
- /** The method requested is not supported */
- UnsupportedMethod:"UnsupportedMethod",
- /** A general error occurred */
- GeneralError:"GeneralError",
- /** An unexpected error occurred inside the Player.IO webservice. Please try again. */
- InternalError:"InternalError",
- /** Access is denied */
- AccessDenied:"AccessDenied",
- /** The message is malformatted */
- InvalidMessageFormat:"InvalidMessageFormat",
- /** A value is missing */
- MissingValue:"MissingValue",
- /** A game is required to do this action */
- GameRequired:"GameRequired",
- /** An error occurred while contacting an external service */
- ExternalError:"ExternalError",
- /** The given argument value is outside the range of allowed values. */
- ArgumentOutOfRange:"ArgumentOutOfRange",
- /** The game has been disabled, most likely because of missing payment. */
- GameDisabled:"GameDisabled",
- /** The game requested is not known by the server */
- UnknownGame:"UnknownGame",
- /** The connection requested is not known by the server */
- UnknownConnection:"UnknownConnection",
- /** The auth given is invalid or malformatted */
- InvalidAuth:"InvalidAuth",
- /** There is no server in any of the selected server clusters for the game that are eligible to start a new room in (they're all at full capacity or there are no servers in any of the clusters). Either change the selected clusters for your game in the admin panel, try again later or start some more servers for one of your clusters. */
- NoServersAvailable:"NoServersAvailable",
- /** The room data for the room was over the allowed size limit */
- RoomDataTooLarge:"RoomDataTooLarge",
- /** You are unable to create room because there is already a room with the specified id */
- RoomAlreadyExists:"RoomAlreadyExists",
- /** The game you're connected to does not have a room type with the specified name */
- UnknownRoomType:"UnknownRoomType",
- /** There is no room running with that id */
- UnknownRoom:"UnknownRoom",
- /** You can't join the room when the RoomID is null or the empty string */
- MissingRoomId:"MissingRoomId",
- /** The room already has the maxmium amount of users in it. */
- RoomIsFull:"RoomIsFull",
- /** The key you specified is not set as searchable. You can change the searchable keys in the admin panel for the server type */
- NotASearchColumn:"NotASearchColumn",
- /** The QuickConnect method (simple, facebook, kongregate...) is not enabled for the game. You can enable the various methods in the admin panel for the game */
- QuickConnectMethodNotEnabled:"QuickConnectMethodNotEnabled",
- /** The user is unknown */
- UnknownUser:"UnknownUser",
- /** The password supplied is incorrect */
- InvalidPassword:"InvalidPassword",
- /** The supplied data is incorrect */
- InvalidRegistrationData:"InvalidRegistrationData",
- /** The key given for the BigDB object is not a valid BigDB key. Keys must be between 1 and 50 characters. Only letters, numbers, hyphens, underbars, and spaces are allowed. */
- InvalidBigDBKey:"InvalidBigDBKey",
- /** The object exceeds the maximum allowed size for BigDB objects. */
- BigDBObjectTooLarge:"BigDBObjectTooLarge",
- /** Could not locate the database object. */
- BigDBObjectDoesNotExist:"BigDBObjectDoesNotExist",
- /** The specified table does not exist. */
- UnknownTable:"UnknownTable",
- /** The specified index does not exist. */
- UnknownIndex:"UnknownIndex",
- /** The value given for the index, does not match the expected type. */
- InvalidIndexValue:"InvalidIndexValue",
- /** The operation was aborted because the user attempting the operation was not the original creator of the object accessed. */
- NotObjectCreator:"NotObjectCreator",
- /** The key is in use by another database object */
- KeyAlreadyUsed:"KeyAlreadyUsed",
- /** BigDB object could not be saved using optimistic locks as it's out of date. */
- StaleVersion:"StaleVersion",
- /** Cannot create circular references inside database objects */
- CircularReference:"CircularReference",
- /** The server could not complete the heartbeat */
- HeartbeatFailed:"HeartbeatFailed",
- /** The game code is invalid */
- InvalidGameCode:"InvalidGameCode",
- /** Cannot access coins or items before vault has been loaded. Please refresh the vault first. */
- VaultNotLoaded:"VaultNotLoaded",
- /** There is no PayVault provider with the specified id */
- UnknownPayVaultProvider:"UnknownPayVaultProvider",
- /** The specified PayVault provider does not support direct purchase */
- DirectPurchaseNotSupportedByProvider:"DirectPurchaseNotSupportedByProvider",
- /** The specified PayVault provider does not support buying coins */
- BuyingCoinsNotSupportedByProvider:"BuyingCoinsNotSupportedByProvider",
- /** The user does not have enough coins in the PayVault to complete the purchase or debit. */
- NotEnoughCoins:"NotEnoughCoins",
- /** The item does not exist in the vault. */
- ItemNotInVault:"ItemNotInVault",
- /** The chosen provider rejected one or more of the purchase arguments */
- InvalidPurchaseArguments:"InvalidPurchaseArguments",
- /** The chosen provider is not configured correctly in the admin panel */
- InvalidPayVaultProviderSetup:"InvalidPayVaultProviderSetup",
- /** Unable to locate the custom PartnerPay action with the given key */
- UnknownPartnerPayAction:"UnknownPartnerPayAction",
- /** The given type was invalid */
- InvalidType:"InvalidType",
- /** The index was out of bounds from the range of acceptable values */
- IndexOutOfBounds:"IndexOutOfBounds",
- /** The given identifier does not match the expected format */
- InvalidIdentifier:"InvalidIdentifier",
- /** The given argument did not have the expected value */
- InvalidArgument:"InvalidArgument",
- /** This client has been logged out */
- LoggedOut:"LoggedOut",
- /** The given segment was invalid. */
- InvalidSegment:"InvalidSegment",
- /** Cannot access requests before Refresh() has been called. */
- GameRequestsNotLoaded:"GameRequestsNotLoaded",
- /** Cannot access achievements before Refresh() has been called. */
- AchievementsNotLoaded:"AchievementsNotLoaded",
- /** Cannot find the achievement with the specified id. */
- UnknownAchievement:"UnknownAchievement",
- /** Cannot access notification endpoints before Refresh() has been called. */
- NotificationsNotLoaded:"NotificationsNotLoaded",
- /** The given notifications endpoint is invalid */
- InvalidNotificationsEndpoint:"InvalidNotificationsEndpoint",
- /** There is an issue with the network */
- NetworkIssue:"NetworkIssue",
- /** Cannot access OneScore before Refresh() has been called. */
- OneScoreNotLoaded:"OneScoreNotLoaded",
- /** The Publishing Network features are only avaliable when authenticated to PlayerIO using Publishing Network authentication. Authentication methods are managed in the connections setting of your game in the admin panel on PlayerIO. */
- PublishingNetworkNotAvailable:"PublishingNetworkNotAvailable",
- /** Cannot access profile, friends, ignored before Publishing Network has been loaded. Please refresh Publishing Network first. */
- PublishingNetworkNotLoaded:"PublishingNetworkNotLoaded",
- /** The dialog was closed by the user */
- DialogClosed:"DialogClosed",
- /** Check cookie required. */
- AdTrackCheckCookie:"AdTrackCheckCookie",
- codes:{0:"UnsupportedMethod",1:"GeneralError",2:"InternalError",3:"AccessDenied",4:"InvalidMessageFormat",5:"MissingValue",6:"GameRequired",7:"ExternalError",8:"ArgumentOutOfRange",9:"GameDisabled",10:"UnknownGame",11:"UnknownConnection",12:"InvalidAuth",13:"NoServersAvailable",14:"RoomDataTooLarge",15:"RoomAlreadyExists",16:"UnknownRoomType",17:"UnknownRoom",18:"MissingRoomId",19:"RoomIsFull",20:"NotASearchColumn",21:"QuickConnectMethodNotEnabled",22:"UnknownUser",23:"InvalidPassword",24:"InvalidRegistrationData",25:"InvalidBigDBKey",26:"BigDBObjectTooLarge",27:"BigDBObjectDoesNotExist",28:"UnknownTable",29:"UnknownIndex",30:"InvalidIndexValue",31:"NotObjectCreator",32:"KeyAlreadyUsed",33:"StaleVersion",34:"CircularReference",40:"HeartbeatFailed",41:"InvalidGameCode",50:"VaultNotLoaded",51:"UnknownPayVaultProvider",52:"DirectPurchaseNotSupportedByProvider",54:"BuyingCoinsNotSupportedByProvider",55:"NotEnoughCoins",56:"ItemNotInVault",57:"InvalidPurchaseArguments",58:"InvalidPayVaultProviderSetup",70:"UnknownPartnerPayAction",80:"InvalidType",81:"IndexOutOfBounds",82:"InvalidIdentifier",83:"InvalidArgument",84:"LoggedOut",90:"InvalidSegment",100:"GameRequestsNotLoaded",110:"AchievementsNotLoaded",111:"UnknownAchievement",120:"NotificationsNotLoaded",121:"InvalidNotificationsEndpoint",130:"NetworkIssue",131:"OneScoreNotLoaded",200:"PublishingNetworkNotAvailable",201:"PublishingNetworkNotLoaded",301:"DialogClosed",302:"AdTrackCheckCookie"}
-};
-
-(function () {
- /**
- * @class
- * An instance of this class is returned after successfully authenticating a user to PlayerIO.
- * It contains the id of the current user, and methods for making all API calls on behalf of that user.
- * @example Authenticate and create a BigDB Object
- *
- * PlayerIO.authenticate(
- * "[Enter your game id here]",
- * "public", //Default Basic connection
- * { userId:'user-id' }, //Basic auth only requires a user id
- * {}, //Optional PlayerInsight segments
- * function(client) {
- * //The user was successfully authenticated, we can now access the various PlayerIO services:
- * var obj = { name:"Charlie", age:20 };
- * client.bigDB.createObject("Users", client.connectUserId, obj, function(dbObj) {
- * dbObj.location = 'Paris';
- * dbObj.save();
- * });
- * },
- * function(error){
- * //Something went wrong while authenticating.
- * console.log(error);
- * }
- * );
- *
- */
- _pio.client = function (channel, gameId, gameFsRedirectMap, userId) {
- /**
- * User id of the currently connected user
- * @type string
- */
- this.connectUserId = userId;
-
- /**
- * The game id of the client
- * @type string
- */
- this.gameId = gameId;
-
- /**
- * The GameFS service
- * @type gameFS
- */
- this.gameFS = new _pio.gameFS(gameId, gameFsRedirectMap);
-
- /**
- * The ErrorLog service
- * @type errorLog
- */
- this.errorLog = new _pio.errorLog(channel);
-
- /**
- * The PayVault service
- * @type payVault
- */
- this.payVault = new _pio.payVault(channel);
-
- /**
- * The BigDB service
- * @type bigDB
- */
- this.bigDB = new _pio.bigDB(channel);
-
- /**
- * The Multiplayer service
- * @type multiplayer
- */
- this.multiplayer = new _pio.multiplayer(channel);
-
- /**
- * The GameRequests service
- * @type gameRequests
- */
- this.gameRequests = new _pio.gameRequests(channel);
-
- /**
- * The Achievements service
- * @type achievements
- */
- this.achievements = new _pio.achievements(channel);
-
- /**
- * The PlayerInsight service
- * @type playerInsight
- */
- this.playerInsight = new _pio.playerInsight(channel);
-
- /**
- * The OneScore service
- * @type oneScore
- */
- this.oneScore = new _pio.oneScore(channel);
-
- /**
- * The Leaderboards service
- * @type leaderboards
- */
- this.leaderboards = new _pio.leaderboards(channel, this.connectUserId);
-
- /**
- * The Notifications service
- * @type notifications
- */
- this.notifications = new _pio.notifications(channel);
-
- /**
- * The PlayerIO Publishing Network service
- * @type publishingNetwork
- */
- this.publishingNetwork = new _pio.publishingNetwork(channel, this.connectUserId);
- }
-})();
-(function () {
- var maps = {}
- /**
- * @class The GameFS service. This class is used to get an absolute URL for assets you have stored in GameFS.
- * @example Example of how to request the file game.swf from your games GameFS via PlayerIO
- *
- * var url = PlayerIO.gameFS("[Enter your game id here]").getURL("game.swf");
- *
- *
- * @example Example of how to request the file game.swf from your games GameFS via client
- *
- * var url = client.gameFS.getURL("game.swf");
- *
- */
- _pio.gameFS = function(gameId, redirectMap){
- if( typeof(redirectMap) == 'string' && redirectMap.length>0 ){
- var parts = (redirectMap||"").split("|");
- if( parts.length >= 1 ){
- var map = maps[gameId.toLowerCase()] = {}
- for(var i=0;i!=parts.length;i++){
- var part = parts[i];
- if(part =="alltoredirect" || part == "cdnmap"){
- map.baseUrl = parts[i+1];
- }else if( part == "alltoredirectsecure" || part == "cdnmapsecure" ){
- map.secureBaseUrl = parts[i+1];
- }else{
- map["."+part] = parts[i+1];
- }
- }
- }
- }
-
- /**
- * Converts a GameFS path (like '/mygame.swf') into a full url, that can be downloaded over the internet.
- * Important! Do not save or otherwise persist (bigdb, cookies, etc) the returned url, since the url will change over time.
- * @param {string} path The path of the file in the GameFS, including the initial slash. Examples: '/mygame.swf' or '/characters/bob.jpg'
- * @param {boolean} secure If true, this method returns a secure (https) url.
- * @return {string} An url that can be used to download the resource over the internet.
- */
- this.getUrl = function (path, secure) {
- if(!path[0] == "/") {
- throw _pio.error("The path given to getUrl must start with a slash, like: '/myfile.swf' or '/folder/file.jpg'");
- }
- var map = maps[gameId];
- if( map ){
- return (secure ? map.secureBaseUrl : map.baseUrl) + (map["."+path] || path);
- }else{
- return (secure ? "https" : "http") + "://r.playerio.com/r/" + gameId + path;
- }
- }
- }
-})();
-(function () {
- /**
- * @class The GameRequest service. This class has methods for sending game requests to other users, and for
- * handling the requests received by the current user. All game request types have to be defined in the admin panel first.
- * @example Refresh local requests
- *
- * client.gameRequests.refresh(function() {
- * for (var i = 0; i != client.gameRequests.waitingRequests.length; i++) {
- * var request = client.gameRequests.waitingRequests[i];
- * console.log(request.id)
- * console.log(request.type)
- * console.log(request.senderUserId)
- * console.log(request.created)
- * console.log(request.data)
- * }
- * }, function(error) {
- * console.log(error);
- * });
- *
-
- * @example Send a game request to another player
- *
- * client.gameRequests.send(
- * 'invite', //Type
- * { game: "poker", bonus: 5 }, //Extra data
- * ['userid1', 'userid2'], //Recipients
- * function () {
- * //Success
- * }, function(error) {
- * console.log(error);
- * }
- * );
- *
-
- * @example Delete all waiting requests
- *
- * client.gameRequests.delete(client.gameRequests.waitingRequests, function () {
- * //Success, all waiting requests have been deleted.
- * }, function(error) {
- * console.log(error);
- * });
- *
- */
- _pio.gameRequests = function (channel) {
- var _playCodes = [];
-
- /** The list of waiting requests for the current user. You must call refresh() first to initialize this list.
- * @type gameRequest[]
- */
- this.waitingRequests = "[ERROR: You tried to access gameRequests.waitingRequests before loading waiting requests. You have to call the refresh method first.]";
- var self = this;
-
- /**
- * Send a GameRequest to the specified recipients.
- * @param {number} requestType The request type of the request to send.
- * @param {object} requestData Data that will be available to the recipient of the request with information about the request. Useful for passing any kind of data to the recipient.
- * @param {string[]} requestRecipients The recipients to send this request to.
- * @param {function()} successCallback Callback function that will be called when the request has been sent.
- * @param {function(PlayerIOError)} errorCallback Callback function that will be called if an error occurs.
- */
- this.send = function (requestType, requestData, requestRecipients, successCallback, errorCallback) {
- channel.gameRequestsSend(requestType, _pio.convertToKVArray(requestData), requestRecipients, successCallback, errorCallback, function (result) {
- //...
- });
- }
-
- /**
- * Refresh the list of received requests.
- * @param {function()} successCallback Callback function that will be called when the refresh is complete
- * @param {function(PlayerIOError)} errorCallback Callback function that will be called if an error occurs
- */
- this.refresh = function (successCallback, errorCallback) {
- channel.gameRequestsRefresh(_playCodes, successCallback, errorCallback, function (result) {
- self._playCodes = result.newplaycodes;
- self.waitingRequests = readRequests(result.requests);
- var foo = result.morerequestswaiting;
- });
- }
-
- /**
- * Delete the given requests. Will also update the waitingRequests property after deletion is complete.
- * @param {gameRequest[]} requests The list of requests to delete.
- * @param {function()} successCallback Callback function that will be called when the delete has been completed.
- * @param {function(PlayerIOError)} errorCallback Callback function that will be called if an error occurs.
- */
- this.delete = function (requests, successCallback, errorCallback) {
- if (typeof (requests) != 'object' && !requests.length) {
- var e = _pio.error("The first argument to delete should be an array: client.gameRequests.delete([requests], ...)");
- _pio.handleError(e, errorCallback, e.code, e.message);
- return;
- }
-
- var ids = [];
- for (var i = 0; i != requests.length; i++) {
- var id = requests[i].id;
- if (id) {
- ids.push(id);
- } else {
- var e = _pio.error("No GameRequest id found on item#" + i + ". You have to use requests from the gameRequests.waitingRequests array. For instance: client.gameRequests.delete(client.gameRequests.waitingRequests, ...)");
- _pio.handleError(e, errorCallback, e.code, e.message);
- return;
- }
- }
- channel.gameRequestsDelete(ids, successCallback, errorCallback, function (result) {
- self.waitingRequests = readRequests(result.requests);
- var foo = result.morerequestswaiting;
- });
- }
-
- function readRequests(requests) {
- if (requests == null || requests.length == 0) { return []; }
- var arr = [];
- for (var i = 0; i != requests.length; i++) {
- var item = requests[i];
- arr.push(new _pio.gameRequest(item.id, item.type, item.senderuserid, item.created, item.data));
- }
- return arr;
- }
- }
-
- /**
- * @class This class encapsulates all the data of a received game request.
- */
- _pio.gameRequest = function (id, type, senderUserId, created, data) {
- /** The id of this request.
- * @type string
- */
- this.id = id;
- /** The type of this request.
- * @type string
- */
- this.type = type;
- /** The sender user id of this request.
- * @type string
- */
- this.senderUserId = senderUserId;
- /** When this request was created.
- * @type Date
- */
- this.created = new Date(created);
- /** The custom data that was passed in when this request was created
- * @type object
- */
- this.data = _pio.convertFromKVArray(data);
- }
-})();
-(function () {
- /**
- * @class The ErrorLog service. This class has methods for writing custom errors to your game's error log.
- * You can browse your game's error log in the PlayerIO admin panel.
- * @example Writing an error to the error log
- *
- * client.errorLog.writeError(
- * "Could not perform action",
- * "time: "+(new Date()).getTime(),
- * err.stack,
- * {name:'john'}
- * );
- *
- */
- _pio.errorLog = function (channel) {
- /**
- * Writes an entry to the error log
- * @param {string} error A short string describing the error without details. Example 'Object not set to instance of an object'
- * @param {string} details The message describing the error in detail. Example 'couldn't find the user 'bob' in the current game'
- * @param {string} stacktrace The stacktrace (if available) of the error
- * @param {object} extraData Any extra data you'd like to associate with the error log entry. Example: {score:200, level:'skyland'}
- */
- this.writeError = function(error, details, stacktrace, extradata){
- channel.writeError("Javascript", error, details, stacktrace, _pio.convertToKVArray(extradata));
- }
- }
-})();
-
-(function () {
- /**
- * @class The QuickConnect service. This class is used for support methods for users created and authenticated
- * through the Simple Users feature.
- * @example Here's an example on how to fetch a captcha for display, and submitting it when registering a Simple User.
- *
- * //Fetch a captcha
- * PlayerIO.quickConnect.simpleGetCaptcha(
- * "[your-game-id-here]",
- * 200, //Image width
- * 100, //Image height
- * function (captcha) {
- * var url = captcha.captchaImageUrl; //Display this in the user registration form
- * var key = captcha.captchaKey; //Save this for later
- * }, function (error) {
- * console.log(error);
- * }
- * );
- *
- *
- * //After the user has submitted the registration form, register a new Simple User:
- * PlayerIO.authenticate(
- * "[Enter your game id here]",
- * "public", //A connection with the authentication type SimpleUsers
- * {
- * register: "true",
- * username: "[The username]",
- * password: "[The password]",
- * email: "[The email address]",
- * captchaKey: key, //The captcha key we got earlier
- * captchaValue:"[The captcha value]", //What the user entered
- * },
- * {},
- * function (client) {
- * //Success!
- * //The user is now registered and connected.
- * },
- * function (error) {
- * //Error registering.
- * //Check error.message to find out in what way it failed,
- * //if any registration data was missing or invalid, or if
- * //the entered captcha value didn't match the captcha image.
- * }
- * );
- *
- */
- _pio.quickConnect = function () {
- /**
- * Creates a Captcha image and key, to be used for registrations where the added security of Captcha is required.
- * @param {string} gameId The game id of the game you wish to make a captcha for. This value can be found in the admin panel.
- * @param {number} width The width of the Captcha image.
- * @param {number} height The height of the Captcha image.
- * @param {function(simpleGetCaptchaOutput)} successCallback Callback function that will be called with the captcha information
- * @param {function(PlayerIOError)} errorCallback Callback function that will be called if an error occurs
- */
- this.simpleGetCaptcha = function (gameId, width, height, successCallback, errorCallback) {
- var channel = new _pio.channel();
- channel.simpleGetCaptcha(gameId, width, height, successCallback, errorCallback, function (result) {
- return new _pio.simpleGetCaptchaOutput(result.captchakey, result.captchaimageurl);
- })
- }
-
- /**
- * Initiates the password recovery process for a user by sending him an email. The user must have supplied an email address during registration.
- * @param {string} gameId The game id of the game the user is registered in.
- * @param {string} usernameOrEmail The username or email address of the user that wishes to recover his password.
- * @param {function()} successCallback Callback function that will be called when the recovery e-mail has been sent
- * @param {function(PlayerIOError)} errorCallback Callback function that will be called if an error occurs
- */
- this.simpleRecoverPassword = function (gameId, usernameOrEmail, successCallback, errorCallback) {
- var channel = new _pio.channel();
- channel.simpleRecoverPassword(gameId, usernameOrEmail, successCallback, errorCallback, function (result) {})
- }
- }
-
- /**
- * @class Captcha information for the QuickConnect simple users feature.
- */
- _pio.simpleGetCaptchaOutput = function (captchaKey, captchaImageUrl) {
- /** The key for this captcha image. This value must be kept and sent to the PlayerIO.authenticate() method along with the input from the user.
- * @type string
- */
- this.captchaKey = captchaKey;
-
- /** An url for the captcha image. You must show the image to the user, and ask what text is shown in the image
- * @type string
- */
- this.captchaImageUrl = captchaImageUrl;
- }
-
- PlayerIO.quickConnect = new _pio.quickConnect();
-})();
-(function () {
- /**
- * @class The PayVault service.
- * Instances of this class represent a specific user's Vault, and contains methods and properties both for inspecting and manipulating the contents.
- * All properties and methods that inspect the Vault requires that it is up-to-date first. This can be achieved explicitly by calling the refresh() method
- * or implicitly by calling any method which modifies the Vault such as credit() or debit().
- * @example Here is how to read the Coins balance:
- *
- * client.payVault.refresh(function() {
- * var coins = client.payVault.coins;
- * }, function(error) { console.log(error); });
- *
- *
- * @example This is how to list all items in a vault:
- *
- * client.payVault.refresh(function() {
- * for (var i = 0; i != client.payVault.items.length; i++) {
- * var item = client.payVault.items[i];
- * console.log(item.itemkey);
- * console.log(item.purchaseDate);
- * console.log(item.id);
- * }
- * }, function(error) { console.log(error); });
- *
- *
- * @example This is how you check if an item exists:
- *
- * client.payVault.refresh(function() {
- * if (client.payVault.has('simplecar')) {
- * //Vault contains at least one item of type 'simplecar'.
- * }
- * }, function(error) { console.log(error); });
- *
- *
- * @example Credit and Debit can be used like this:
- *
- * client.payVault.credit(100, 'New player bonus', function() {
- * var newcoins = client.payVault.coins;
- * //Show new amount to user...
- * }, function(error) { console.log(error); });
- *
- * client.payVault.debit(10, 'Race starting fee', function() {
- * //Let player start race...
- * }, function(error) {
- * //Something went wrong, or the user doesn't have enough coins in his Vault.
- * console.log(error);
- * });
- *
- *
- * @example Buying items with Coins is really easy. This requires that you have created an item in the PayVaultItems table in BigDB with the key "speedboost", and a property "PriceCoins" containing the price.
- *
- * client.payVault.buy(true, [{itemkey:'speedboost'}], function() {
- * var boosts = client.payVault.count('speedboost');
- * //Show new number of boosts to user.
- * }, function(error) {
- * //Something went wrong, or the user couldn't afford the item.
- * console.log(error);
- * });
- *
- *
- * @example And here's how to consume an item:
- *
- * client.payVault.refresh(function() {
- * var boost = client.payVault.first('speedboost');
- * client.payVault.consume([boost], function(){
- * //Boost the player's car
- * })
- * }, function(error) { console.log(error); });
- *
- *
- * @example When it's time for a user to add more Coins, you can do it like this:
- *
- * client.payVault.getBuyCoinsInfo(
- * 'paypal', //PayVault provider
- * {
- * coinamount: 1000, //Provider-specific arguments
- * currency:'USD',
- * item_name:'1000 Coins'
- * },
- * function(result){
- * var url = result.paypalurl; //Provider-specific result
- * //Show url to user
- * }, function(error) {
- * console.log(error);
- * }
- * );
- *
- *
- * @example And this is how to let the user buy an item directly. This requires that you have created an item in the PayVaultItems table in BigDB with the key "supercar", and a property "PriceUSD" containing the price.
- *
- * client.payVault.getBuyDirectInfo(
- * 'paypal', //PayVault provider
- * {
- * currency:'USD', //Provider-specific arguments
- * item_name:'Red Supercar'
- * },
- * [{ //Array of items to buy.
- * itemkey:'supercar', //Item key
- * color:'red' //Optional payload
- * }],
- * function(result){ //Provider-specific result
- * var url = result.paypalurl;
- * // show url to player...
- * }, function(error) {
- * console.log(error);
- * }
- * );
- *
- *
- * @example Finally, there are methods for retrieving the payment history of a user:
- *
- * client.payVault.readHistory(1, 10, function(historyEntries){
- * if (historyEntries.length > 0) {
- * var lastprice = historyEntries[0].providerPrice;
- * }
- * }, function(error) { console.log(error); });
- *
- */
- _pio.payVault = function (channel) {
- var currentVersion = null;
-
- /** The number of coins in this user's Vault. You must call refresh() first to initialize this value.
- * @type Number
- */
- this.coins = "[ERROR: you tried to access payVault.coins before the vault was loaded. You have to refresh the vault before the .coins property is set to the right value]";
- /** The list of items in this user's Vault. You must call refresh() first to initialize this value.
- * @type Number
- */
- this.items = "[ERROR: you tried to access payVault.items before the vault was loaded. You have to refresh the vault before the .items property is set to the right value]";
-
- /**
- * This method checks if the Vault contains at least one item of the given itemKey. This method can only be called on an up-to-date vault.
- * @param {string} itemKey The itemKey to check for.
- * @return {boolean} True if the user has at least one item of the given type (itemKey).
- */
- this.has = function (itemKey) {
- if (currentVersion == null) { throw new PlayerIOError(PlayerIOErrorCode.VaultNotLoaded, "Cannot access items before vault has been loaded. Please refresh the vault first"); }
- for (var i = 0; i != this.items.length; i++) {
- if (this.items[i].itemKey == itemKey) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns the first item of the given itemKey from this Vault. This method can only be called on an up-to-date vault.
- * @param {string} itemKey The itemKey of the item to get.
- * @return {number} A VaultItem if one was found, or null if not.
- */
- this.first = function (itemKey) {
- if (currentVersion == null) { throw new PlayerIOError(PlayerIOErrorCode.VaultNotLoaded, "Cannot access items before vault has been loaded. Please refresh the vault first"); }
- for (var i = 0; i != this.items.length; i++) {
- if (this.items[i].itemKey == itemKey) {
- return this.items[i];
- }
- }
- return null;
- }
- /**
- * Returns the number of items of a given itemKey is in this Vault. This method can only be called on an up-to-date vault.
- * @param string itemKey The itemKey of the items to count.
- * @return number The number of items of the given type that the user has in the vault.
- */
- this.count = function (itemKey) {
- if (currentVersion == null) { throw new PlayerIOError(PlayerIOErrorCode.VaultNotLoaded, "Cannot access items before vault has been loaded. Please refresh the vault first"); }
- var result = 0;
- for (var i = 0; i != this.items.length; i++) {
- if (this.items[i].itemKey == itemKey) {
- result++;
- }
- }
- return result;
- }
-
- /**
- * Refreshes this Vault, making sure the Items and Coins are up-to-date.
- * @param {function()} successCallback Callback function that will be called when the refresh is complete
- * @param {function(PlayerIOError)} errorCallback Callback function that will be called if an error occurs
- */
- this.refresh = function (successCallback, errorCallback) {
- channel.payVaultRefresh(currentVersion, null, successCallback, errorCallback, function (result) {
- readContent(result.vaultcontents);
- });
- }
-
- /**
- * Loads a page of entries from this Vaults history, in reverse chronological order, i.e. newest first.
- * @param {number} page The page of entries to load. The first page has number 0.
- * @param {number} pageSize The number of entries per page.
- * @param {function(payVaultHistoryEntries)} successCallback Callback function that will be called with the history entries found
- * @param {function(PlayerIOError)} errorCallback Callback function that will be called if an error occurs
- */
- this.readHistory = function (page, pageSize, successCallback, errorCallback) {
- channel.payVaultReadHistory(page, pageSize, null, successCallback, errorCallback, function (result) {
- var arr = [];
- for (var i = 0; i != result.entries.length; i++) {
- var item = result.entries[i];
- arr.push(new _pio.payVaultHistoryEntry(item.type, item.amount, item.timestamp, item.itemkeys || [], item.reason, item.providertransactionid, item.providerprice))
- }
- return arr;
- })
- }
-
- /**
- * Give coins to this Vault
- * @param {number} coinAmount The amount of coins to give.
- * @param {string} reason Your reason for giving the coins to this user. This will show up in the vault history, and in the PayVault admin panel for this user.
- * @param {function()} successCallback Callback function that will be called when the credit has been completed. You don't need to call refresh after this call.
- * @param {function(PlayerIOError)} errorCallback Callback function that will be called if an error occurs
- */
- this.credit = function (coinAmount, reason, successCallback, errorCallback) {
- channel.payVaultCredit(coinAmount, reason, null, successCallback, errorCallback, function (result) {
- readContent(result.vaultcontents);
- })
- }
-
- /**
- * Take coins from this Vault
- * @param {number} coinAmount The amount of coins to take.
- * @param {string} reason Your reason for taking the coins from this user. This will show up in the vault history, and in the PayVault admin panel for this user.
- * @param {function()} successCallback Callback function that will be called when the credit has been completed. You don't need to call refresh after this call.
- * @param {function(PlayerIOError)} errorCallback Callback function that will be called if an error occurs
- */
- this.debit = function (coinAmount, reason, successCallback, errorCallback) {
- channel.payVaultDebit(coinAmount, reason, null, successCallback, errorCallback, function (result) {
- readContent(result.vaultcontents);
- })
- }
-
- /**
- * Consume items in this Vault. This will cause them to be removed, but this action will not show up in the vault history.
- * @param {vaultItem[]} items The VaultItems to use from the users vault - this should be instances of items in this Vault.
- * @param {function()} successCallback Callback function that will be called when the item(s) has been consumed. You don't need to call refresh after this call.
- * @param {function(PlayerIOError)} errorCallback Callback function that will be called if an error occurs
- */
- this.consume = function (items, successCallback, errorCallback) {
- if (typeof (items) != 'object' && !items.length) {
- var e = _pio.error("The first argument to consume should be an array: client.payVault.consume([item], ...)");
- _pio.handleError(e, errorCallback, e.code, e.message)
- return;
- }
-
- var ids = [];
- for (var i = 0; i != items.length; i++) {
- var id = items[i].id;
- if (id) {
- ids.push(id);
- } else {
- var e = _pio.error("No PayVault item id found on item#" + i + ". You have to use items from the payVault.items array. For instance: client.payVault.consume([client.payVault.first('sportscar')], ...)")
- _pio.handleError(e, errorCallback, e.code, e.message)
- return;
- }
- }
-
- channel.payVaultConsume(ids, null, successCallback, errorCallback, function (result) {
- readContent(result.vaultcontents);
- })
- }
-
-
- /**
- * Buy items with Coins.
- * @param {object[]} items A list of items to buy. Each item must have a property called 'itemkey' with the item key. Any additional properties will be converted to item payload.
- * @param {boolean} storeItems Whether or not to store the items in the vault after purchase
- * @param {function()} successCallback Callback function that will be called when the item(s) have been bought and added to the vault. You don't need to call refresh after this call.
- * @param {function(PlayerIOError)} errorCallback Callback function that will be called if an error occurs
- */
- this.buy = function (items, storeItems, successCallback, errorCallback) {
- channel.payVaultBuy(_pio.convertBuyItems(items), storeItems, null, successCallback, errorCallback, function (result) {
- readContent(result.vaultcontents);
- })
- }
-
- /**
- * Give the user items without taking any of his coins from the vault.
- * @param {object[]} items A list of items to give. Each item must have a property called 'itemkey' with the item key. Any additional properties will be converted to item payload.
- * @param {function()} successCallback Callback function that will be called when the item(s) have been added to the vault. You don't need to call refresh after this call.
- * @param {function(PlayerIOError)} errorCallback Callback function that will be called if an error occurs
- */
- this.give = function (items, successCallback, errorCallback) {
- channel.payVaultGive(_pio.convertBuyItems(items), null, successCallback, errorCallback, function (result) {
- readContent(result.vaultcontents);
- })
- }
-
- /**
- * Gets information about how to make a coin purchase with the specified PayVault provider.
- * @param {string} provider The name of the PayVault provider to use for the coin purchase.
- * @param {object} purchaseArguments Any additional information that will be given to the PayVault provider to configure this purchase.
- * @param {function(object)} successCallback Callback function that will be called with provider specifics about how to complete the purchase.
- * @param {function(PlayerIOError)} errorCallback Callback function that will be called if an error occurs
- */
- this.getBuyCoinsInfo = function (provider, purchaseArguments, successCallback, errorCallback) {
- channel.payVaultPaymentInfo(provider, _pio.convertToKVArray(purchaseArguments), null, successCallback, errorCallback, function (result) {
- return _pio.convertFromKVArray(result.providerarguments)
- })
- }
-
- /**
- * Gets information about how to make a direct item purchase with the specified PayVault provider.
- * @param {string} provider The name of the PayVault provider to use for the item purchase.
- * @param {object} purchaseArguments Any additional information that will be given to the PayVault provider to configure this purchase.
- * @param {object[]} items A list of items to buy. Each item must have a property called 'itemkey' with the item key. Any additional properties will be converted to item payload.
- * @param {function(object)} successCallback Callback function that will be called with provider specifics about how to complete the purchase.
- * @param {function(PlayerIOError)} errorCallback Callback function that will be called if an error occurs
- */
- this.getBuyDirectInfo = function (provider, purchaseArguments, items, successCallback, errorCallback) {
- channel.payVaultPaymentInfo(provider, _pio.convertToKVArray(purchaseArguments), _pio.convertBuyItems(items), successCallback, errorCallback, function (result) {
- return _pio.convertFromKVArray(result.providerarguments)
- })
- }
-
- var self = this;
- function readContent(content) {
- if (content != null) {
- currentVersion = content.version;
- self.coins = content.coins || 0;
- self.items = [];
- if (content.items && content.items.length) {
- for (var i = 0; i != content.items.length; i++) {
- var item = content.items[i];
- var obj = self.items[i] = new _pio.vaultItem(item.id, item.itemkey, (new Date()).setTime(item.purchasedate))
-
- _pio.bigDBDeserialize(item.properties, obj, true);
- }
- }
- }
- }
-
- }
-
- _pio.convertBuyItems = function(items) {
- if (items == null) return [];
- var results = [];
- for (var i = 0; i != items.length; i++) {
- var itemKey = items[i].itemkey
-
- if (!itemKey) {
- throw _pio.error("You have to specify an itemkey for the payvault item. Example: {itemkey:'car'}")
- }
-
- results.push({
- itemkey: itemKey,
- payload: _pio.compareForChanges({ itemkey: itemKey }, items[i], true, true)
- })
- }
- return results;
- }
-
- /**
- * @class This class represents an item in a user's Vault
- */
- _pio.vaultItem = function (id, itemKey, purchaseDate) {
- /** The unique id of this particular vault item in the user's vault
- * @type string
- */
- this.id = id;
-
- /** The key of the underlying item in the PayVaultItems BigDB table
- * @type string
- */
- this.itemKey = itemKey;
-
- /** The time when the vault item was originally purchased
- * @type Date
- */
- this.purchaseDate = purchaseDate;
- }
-
- /**
- * @class This class represents an entry in a user's PayVault history.
- */
- _pio.payVaultHistoryEntry = function (type, amount, timestamp, itemkeys, reason, providerTransactionId, providerPrice) {
- /** The type of this entry, for example 'buy','credit','debit'...
- * @type string
- */
- this.type = type;
- /** The coin amount of this entry.
- * @type number
- */
- this.amount = amount;
- /** When this entry was created.
- * @type Date
- */
- this.timestamp = new Date().setTime(timestamp);
- /** The item keys related to this entry (entries with type 'buy').
- * @type string[]
- */
- this.itemKeys = itemkeys;
- /** The developer supplied reason for entries of type 'credit' and 'debit'.
- * @type string
- */
- this.reason = reason;
- /** The transaction id from the PayVault provider corresponding to this entry.
- * @type string
- */
- this.providerTransactionId = providerTransactionId;
- /** The price in real currency of this entry formatted as a human readable currency string, e.g. $10.00 USD
- * @type string
- */
- this.providerPrice = providerPrice;
- }
-})();
-(function () {
- /**
- * @class The BigDB service.
- *
This class is used to create, load, and delete database objects. All database objects are stored in tables and have a unique key.
- * You can set up tables in your admin panel, and you can also set up indexes there for when you want to load objects by properties
- * or ranges of properties.
- * @example Here's how to store and update an object:
- *
- * //Make new object and set some properties
- * var obj = {username:"Adam",location:"London", age:20};
- *
- * //Create object in table Users with ConnectUserId as key
- * client.bigDB.createObject("Users", connectUserId, obj, function(dbObj) {
- * dbObj.location = 'Paris';
- * dbObj.save();
- * }, function(error) { console.log(error); });
- *
- * @example This is how you load an object:
- *
- * client.bigDB.load("Users", connectUserId, function(obj) {
- * if (obj != null) {
- * obj.location = 'Paris';
- * obj.save();
- * }
- * }, function(error) { console.log(error); });
- *
- * @example In case you always want to modify an object, you can use the LoadOrCreate method to ensure you get an object back:
- *
- * client.bigDB.loadOrCreate("Users", connectUserId, function(obj) {
- * if(!obj.username) {
- * dbObj.username = 'Charlie';
- * dbObj.age = 20;
- * }
- * obj.location = 'London';
- * obj.save();
- * }, function(error) { console.log(error); });
- *
- * @example
- *
- * BigDB also supports indexes for retrieving objects by a specific property, a range of properties,
- * or to sort objects by properties. Indexes need to be set up in the admin panel for each table,
- * each index needs a name, and a list of properties, and for each property you also need to specify a
- * sort order.
- *
- *
- * //Get the object where username="Adam"
- * client.bigDB.loadSingle("Users", "ByUsername", ["Adam"], function(obj) {
- * //...
- * }, function(error) { console.log(error); });
- *
- * //Get all users with usernames between "Adam" and "Charlie".
- * //This would retrieve users named "Adamsson" and "Barney",
- * //but not users named "Abel" or "Charlotte".
- * client.bigDB.loadRange("Users", "ByUsername", null, "Adam", "Charlie", 100, function(objects) {
- * //objects is an array of found objects...
- * }, function(error) { console.log(error); });
- *
- * //Get all users up to and including "Adam". This would retrieve
- * //users named "Aaron" and "Ackerman", but not "Adamsson" or "Barney".
- * client.bigDB.loadRange("Users", "ByUsername", null, null, "Adam", 100, function(objects) {
- * //objects is an array of found objects...
- * }, function(error) { console.log(error); });
- *
- * //Get all users from "Xerxes". This would retrieve users named
- * //"Yngwie" and "Zed", but not "Charlie" or "Xantippa".
- * client.bigDB.loadRange("Users", "ByUsername", null, "Xerxes", null, 100, function(objects) {
- * //objects is an array of found objects...
- * }, function(error) { console.log(error); });
- *
- * //Retrieve the ten first objects by the ByCreated index.
- * //Since that index is sorted in descending order, this will actually
- * //retrieve the 10 latest created users.
- * client.bigDB.loadRange("Users", "ByCreated", null, null, null, 10, function(objects) {
- * //objects is an array of found objects...
- * }, function(error) { console.log(error); });
- *
- * //Get the 10 latest users that were created more than 7 days ago.
- * var weekago = new Date();
- * weekago.setDate(weekago.getDate() - 7);
- *
- * client.bigDB.loadRange("Users", "ByCreated", null, weekago, null, 10, function(objects) {
- * //objects is an array of found objects...
- * }, function(error) { console.log(error); });
- *
- * @example
- *
- * BigDB also supports compound indexes, that is indexes with more than one property. Given our example object above, we can create an index called "ByLocationAgeCreated" that looks like this:
- *
- * With this index, we can then lookup on either location, or location and age, or location and age and created. If we use more than one property in the lookup, we can only specify the range for the last one, the preceding ones have to be fixed and are sent in via the path parameter.
- *
- *
- * //Load all users where location is "London"
- * client.bigDB.loadRange("Users", "ByLocationAgeCreated", null, "London", "London", 100, function(objects) {
- * //objects is an array of found objects...
- * }, function(error) { console.log(error); });
- *
- * //Load all users from London between 20 and 30 years of age
- * client.bigDB.loadRange("Users", "ByLocationAgeCreated", ["London"], 20, 30, 100, function(objects) {
- * //objects is an array of found objects...
- * }, function(error) { console.log(error); });
- *
- * //Load all users from London that are above 50
- * client.bigDB.loadRange("Users", "ByLocationAgeCreated", ["London"], 50, null, 100, function(objects) {
- * //objects is an array of found objects...
- * }, function(error) { console.log(error); });
- *
- * //Load all users from Paris that are 30 years old, and were created in April
- * client.bigDB.loadRange("Users", "ByLocationAgeCreated", ["Paris", 30], new Date(2010, 4, 1), new Date(2010, 4, 30), 100, function(objects) {
- * //objects is an array of found objects...
- * }, function(error) { console.log(error); });
- *
- * //Load the 10 latest 20-year old users from Amsterdam
- * client.bigDB.loadRange("Users", "ByLocationAgeCreated", ["Amsterdam", 20], null, null, 10, function(objects) {
- * //objects is an array of found objects...
- * }, function(error) { console.log(error); });
- *
- *
- * @example
- *
Finally, deleting objects is as easy as calling the DeleteKeys method, or DeleteRange if you want to delete by an index.