Skip to content

Instantly share code, notes, and snippets.

@muratcorlu
Last active October 11, 2018 22:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save muratcorlu/f5a9da629b3a727dec772844cc545fd8 to your computer and use it in GitHub Desktop.
Save muratcorlu/f5a9da629b3a727dec772844cc545fd8 to your computer and use it in GitHub Desktop.
GameSpark SDK for TypeScript (for using with NativeScript)
const OpCodes = {
LOGIN_RESULT: -1,
PING_RESULT: -3,
UDP_CONNECT_MESSAGE: -5,
PLAYER_READY_MESSAGE: -7,
PLAYER_CONNECT_MESSAGE: -101,
PLAYER_DISCONNECT_MESSAGE: -103,
}
export class Connection {
stopped: boolean;
constructor(public session) {
this.stopped = false;
}
stopInternal() {
}
stop() {
this.stopped = true;
this.stopInternal();
}
onPacketReceived(p, packetSize) {
if (p.command) {
if (p.command["abstractResultType"]) {
var result = p.command;
result.configure(p, this.session);
if (result.executeAsync()) {
this.session.submitAction(p.command)
} else {
p.command.execute()
}
} else {
this.session.submitAction(p.command)
}
} else {
if (!p.hasPayload) {
var cmd;
if (p.sender) {
cmd = CustomCommand.pool.pop().configure(p.opCode, p.sender, null, p.data, 0, this.session, packetSize)
} else {
cmd = CustomCommand.pool.pop().configure(p.opCode, 0, null, p.data, 0, this.session, packetSize)
}
if (cmd) {
this.session.submitAction(cmd)
}
}
}
}
};
export class ReliableConnection extends Connection {
client: WebSocket;
constructor(public remotehost, public remoteport, session) {
super(session);
console.log('ReliableConnection constructor');
};
connect() {
this.client = new WebSocket("wss://" + this.remotehost + ":" + this.remoteport);
this.client.addEventListener('open', (e) => {
this.onopen(e);
});
this.client.addEventListener('message', (e) => {this.onmessage(e)});
this.client.addEventListener('close', (e) => {this.onclose(e)});
this.client.addEventListener('error', (e) => {this.onerror(e)});
this.client.binaryType = "arraybuffer";
// this.client.onopen = this.onopen.bind(this);
// this.client.onclose = this.onclose.bind(this);
// this.client.onerror = this.onerror.bind(this);
// this.client.onmessage = this.onmessage.bind(this)
};
onopen(e) {
if (this.stopped || this.session == null) {
if (this.client != null) {
this.client.close();
this.client = null
}
return
}
this.session.log("ReliableConnection", GameSparksRT.logLevel.DEBUG, " TCP Connection Established");
var loginCmd = new LoginCommand(this.session.connectToken);
console.log(loginCmd);
this.send(loginCmd)
};
onmessage(e) {
if (this.stopped) {
if (this.client != null) {
this.client.close();
this.client = null
}
return
}
var data = e.data;
var read = data.byteLength;
var rss = new Stream;
var array = Array.from(new Uint8Array(data));
rss.writeBytes(array, 0, read);
rss.setPosition(0);
while (rss.getPosition() < read) {
var p = PooledObjects.packetPool.pop();
var bytesRead = this.read(rss, p);
this.onPacketReceived(p, bytesRead);
PooledObjects.packetPool.push(p);
p = PooledObjects.packetPool.pop()
}
};
onclose(e) {
if (this.session != null) {
this.session.log("ReliableConnection", GameSparksRT.logLevel.DEBUG, " TCP Connection Closed")
}
if (!this.stopped && this.client != null) { } else { }
};
onerror(e) {
if (this.session != null) {
this.session.log("ReliableConnection", GameSparksRT.logLevel.DEBUG, " TCP Connection Error")
}
console.log(e)
};
send(request) {
if (this.client != null && this.client.readyState == WebSocket.OPEN) {
var stream = new Stream;
var p = request.toPacket(this.session, false);
var ret = Packet.serializeLengthDelimited(stream, p);
var buffer = new Uint8Array(stream.getBuffer());
this.client.send(buffer);
PooledObjects.packetPool.push(p);
return ret
} else {
return -1
}
};
read(stream, p) {
if (this.stopped) {
return 0
}
p.session = this.session;
p.reliable = true;
var ret = Packet.deserializeLengthDelimited(stream, p);
if (p.reliable == null) {
p.reliable = true
}
return ret
}
stopInternal() {
if (this.client != null && this.client.readyState == WebSocket.OPEN) {
this.client.close();
this.client = null
}
}
}
const Wire = {
VARINT: 0,
FIXED64: 1,
LENGTH_DELIMITED: 2,
FIXED32: 5
};
export class Key {
constructor(public field, public wireType) { }
toString() {
return "[Key: " + this.field + ", " + this.wireType + "]"
}
};
function assert(condition, message) {
if (!condition) {
message = message || "Assertion failed";
if (typeof Error !== "undefined") {
throw new Error(message)
}
throw message
}
}
class Stream {
buffer = "";
position = 0;
getPosition() {
return this.position
}
setPosition(position) {
this.position = position
}
getLength() {
return this.buffer.length
}
bytesAvailable() {
return this.buffer.length - this.position
}
readByte() {
var ret = this.readChar();
if (typeof ret === "number" && ret == -1) {
return 0
} else {
return (ret as string).charCodeAt(0)
}
}
readChar() {
var buffer = "";
var totalBytes;
var ret;
ret = this.readChars(buffer, this.position, 1);
totalBytes = ret[0];
buffer = ret[1];
if (totalBytes == 1) {
return buffer.slice(0, 1)
} else {
return -1
}
}
readChars(buffer, position, length) {
assert(typeof buffer === "string", "buffer must be string");
if (this.bytesAvailable() <= 0) {
console.log("WARNING: Reached end of the stream");
return [0, buffer]
}
if (length <= 0) {
console.log("WARNING: no characters read (length = 0)");
return [0, buffer]
}
if (buffer.length > 0) {
assert(position >= 0 && position < buffer.length, "position out of range")
} else {
position = 0
}
var subString;
var newBuffer = "";
var startPosition = this.position;
var endPosition = startPosition + length;
var newLength;
if (endPosition > this.buffer.length) {
endPosition = this.buffer.length
}
newLength = endPosition - startPosition;
subString = this.buffer.slice(startPosition, endPosition);
this.position = endPosition;
if (position == 0) {
newBuffer = subString;
if (subString.length < buffer.length) {
newBuffer = newBuffer + buffer.slice(newLength)
}
} else {
newBuffer = buffer.slice(0, position) + subString;
if (position + newLength + 1 <= buffer.length) {
newBuffer = newBuffer + buffer.slice(position + newLength)
}
}
return [newLength, newBuffer]
}
read(buffer, position, length) {
assert(typeof buffer === "object" && Array.isArray(buffer), "buffer must be array");
var ret;
var totalBytes;
var newBuffer = "";
var newArray = [];
for (var i = 0; i < buffer.length; i++) {
newBuffer = newBuffer + String.fromCharCode(buffer[i])
}
ret = this.readChars(newBuffer, position, length);
totalBytes = ret[0];
newBuffer = ret[1];
for (var i = 0; i < newBuffer.length; i++) {
newArray.push(newBuffer.charCodeAt(i))
}
return [totalBytes, newArray]
}
writeByte(byte) {
assert(typeof byte === "number", "not valid byte");
assert(byte >= 0 && byte <= 255, "not valid byte");
this.writeChar(String.fromCharCode(byte))
}
writeChar(char) {
this.writeChars(char, 0, 1)
}
writeChars(buffer, position, length) {
assert(typeof buffer === "string", "buffer must be string");
assert(buffer && buffer.length > 0, "buffer must not be nil or empty");
if (this.bytesAvailable() < 0) {
console.log("WARNING: Reached end of the stream");
return
}
if (length <= 0) {
console.log("WARNING: no characters written (length = 0)");
return [0, buffer]
}
assert(position >= 0 && position < buffer.length, "position out of range");
var subString;
var newBuffer = "";
var startPosition = position;
var endPosition = startPosition + length;
var newLength;
if (endPosition > buffer.length) {
endPosition = buffer.length
}
newLength = endPosition - startPosition;
subString = buffer.slice(startPosition, endPosition);
if (this.position == 0) {
newBuffer = subString;
if (this.buffer.length > subString.length) {
newBuffer = newBuffer + this.buffer.slice(newLength)
}
} else {
newBuffer = this.buffer.slice(0, this.position) + subString;
if (this.position + newLength + 1 <= this.buffer.length) {
newBuffer = newBuffer + this.buffer.slice(this.position + newLength)
}
}
this.buffer = newBuffer;
this.position = this.position + newLength
}
writeBytes(buffer, position, length) {
assert(typeof buffer === "object" && Array.isArray(buffer), "buffer must be array");
var newBuffer = "";
for (var i = position; i < position + length; i++) {
if (i >= buffer.length) {
break
}
newBuffer = newBuffer + String.fromCharCode(buffer[i])
}
this.writeChars(newBuffer, 0, length)
}
seek(offset) {
this.position = this.position - offset;
if (this.position < 0) {
this.position = 0
} else if (this.position >= this.buffer.length) {
this.position = this.buffer.length - 1
}
}
toHex() {
var ret = "";
for (var i = 0; i < Math.ceil(this.buffer.length / 16) * 16; i++) {
if (i % 16 == 0) {
var value = i.toString(16);
for (var a = value.length; a < 8; a++) {
ret = ret + "0"
}
ret = ret + value + " "
}
if (i >= this.buffer.length) {
ret = ret + "## "
} else {
var val = this.buffer.charCodeAt(i).toString(16);
for (var b = val.length; b < 2; b++) {
ret = ret + "0"
}
ret = ret + val + " "
}
if ((i + 1) % 8 == 0) {
ret = ret + " "
}
if ((i + 1) % 16 == 0) {
ret = ret + this.buffer.slice(i - 16 + 1, i + 1).replace("[^ -~]", ".") + "\n"
}
}
return ret
}
toString() {
return this.buffer
}
getBuffer() {
var buffer = [];
for (var i = 0; i < this.buffer.length; i++) {
buffer.push(this.buffer.charCodeAt(i))
}
return buffer
}
};
class PositionStream {
tempBuffer = [];
bytesRead = 0;
stream = null
wrap(baseStream, limit?) {
this.bytesRead = 0;
this.stream = baseStream
}
read(buffer, offset, count) {
var ret = this.stream.read(buffer, offset, count);
this.bytesRead = this.bytesRead + ret[0];
return ret
}
readByte() {
var ret = this.read(this.tempBuffer, 0, 1);
if (ret[0] == 1) {
this.tempBuffer = ret[1];
return this.tempBuffer[0]
}
return -1
}
seek(offset) {
for (var i = 0; i < offset; i++) {
this.readByte()
}
return this.bytesRead
}
getLength() {
return this.stream.getLength()
}
getPosition() {
return this.bytesRead
}
};
class LimitedPositionStream extends PositionStream {
limit = 0;
wrap(baseStream, limit) {
super.wrap(baseStream);
this.limit = limit
};
read(buffer, offset, count) {
var toRead;
if (count > this.limit - this.bytesRead) {
toRead = this.limit - this.bytesRead
} else {
toRead = count
}
return super.read(buffer, offset, toRead)
};
readByte() {
if (this.bytesRead >= this.limit) {
return -1
} else {
return super.readByte()
}
};
skipToEnd() {
if (this.bytesRead < this.limit) {
var discardBytes = PooledObjects.byteBufferPool.pop();
while (this.read(discardBytes, this.bytesRead, 256)[0] == 256) { }
PooledObjects.byteBufferPool.push(discardBytes)
}
}
}
export class ProtocolParser {
static readBool(stream) {
var b = stream.readByte();
if (b < 0) {
console.log("WARNING: Stream ended too early");
return false
} else if (b == 1) {
return true
} else if (b == 0) {
return false
}
console.log("WARNING: Invalid boolean value");
return false
};
static readUInt32(stream) {
var b;
var val = 0;
for (var n = 0; n <= 4; n++) {
b = stream.readByte();
if (b < 0) {
console.log("WARNING: Stream ended too early");
return 0
}
if (n == 4 && (b & 240) != 0) {
console.log("WARNING: Got larger VarInt than 32bit unsigned");
return 0
}
if ((b & 128) == 0) {
return val | b << 7 * n
}
val = val | (b & 127) << 7 * n
}
console.log("WARNING: Got larger VarInt than 32bit unsigned");
return 0
};
static readZInt32(stream) {
var val = ProtocolParser.readUInt32(stream);
return val >> 1 ^ val << 31 >> 31
};
static readSingle(stream) {
var bytes = [];
var val = 0;
for (var n = 1; n <= 4; n++) {
bytes[4 - n] = stream.readByte()
}
val = bytes[0] << 24 | bytes[1] << 16 | (bytes[2] << 8 | bytes[3]);
var negative = (bytes[0] & 128) == 128;
var exponent = (val & 2139095040) >> 23;
var sign;
var mantissa = 0;
if (negative) {
sign = -1
} else {
sign = 1
}
if (exponent == 255) {
if (negative) {
value = Number.NEGATIVE_INFINITY
} else {
value = Number.POSITIVE_INFINITY
}
} else if (exponent == 0) {
value = 0
} else {
exponent = exponent - 127 + 1;
for (var i = 3; i >= 2; i--) {
mantissa += bytes[i];
mantissa /= 256
}
mantissa += bytes[1] & 127;
mantissa = (mantissa / 128 + 1) / 2;
var value = sign * Math.pow(2, exponent) * mantissa
}
return value
};
static readUInt64(stream) {
var b;
var val = 0;
for (var n = 0; n <= 9; n++) {
b = stream.readByte();
if (b < 0) {
console.log("WARNING: Stream ended too early");
return 0
}
if (n == 9 && (b & 254) != 0) {
console.log("WARNING: Got larger VarInt than 64 bit unsigned");
return 0
}
if ((b & 128) == 0) {
return val + b * Math.pow(128, n)
}
val = val + (b & 127) * Math.pow(128, n)
}
console.log("WARNING: Got larger VarInt than 64 bit unsigned");
return 0
};
static readZInt64(stream) {
var val = ProtocolParser.readUInt64(stream);
var sign = false;
if (val % 2 == 1) {
sign = true
}
val = Math.floor(val / 2);
if (sign == true) {
return -val
} else {
return val
}
};
static readDouble(stream) {
var bytes = [];
var valh = 0;
for (var n = 1; n <= 8; n++) {
bytes[8 - n] = stream.readByte()
}
valh = bytes[0] << 24 | bytes[1] << 16;
var negative = (bytes[0] & 128) == 128;
var exponent = (valh & 2146435072) >> 20;
var mantissa = 0;
var sign;
if (negative) {
sign = -1
} else {
sign = 1
}
if (exponent == 2047) {
if (negative) {
value = Number.NEGATIVE_INFINITY
} else {
value = Number.POSITIVE_INFINITY
}
} else if (exponent == 0) {
value = 0
} else {
exponent = exponent - 1023 + 1;
for (var i = 7; i >= 2; i--) {
mantissa += bytes[i];
mantissa /= 256
}
mantissa += bytes[1] & 15;
mantissa = (mantissa / 16 + 1) / 2;
var value = sign * Math.pow(2, exponent) * mantissa
}
return value
};
static readString(stream) {
var length = ProtocolParser.readUInt32(stream);
var ms = PooledObjects.memoryStreamPool.pop();
var buffer = PooledObjects.byteBufferPool.pop();
var read = 0;
var ret;
var r;
while (read < length) {
ret = stream.read(buffer, 0, Math.min(length - read, buffer.length));
r = ret[0];
buffer = ret[1];
if (r == 0) {
console.log("WARNING: Expected " + (length - read).toString() + " got " + read);
return 0
}
ms.writeBytes(buffer, 0, r);
read = read + r
}
ret = ms.toString().slice(0, ms.getPosition());
PooledObjects.byteBufferPool.push(buffer);
PooledObjects.memoryStreamPool.push(ms);
return ret
};
static readKey(firstByte, stream) {
if (firstByte < 128) {
return new Key(firstByte >> 3, firstByte & 7)
}
var fieldID = ProtocolParser.readUInt32(stream) << 4 | firstByte >> 3 & 15;
return new Key(fieldID, firstByte & 7)
};
static skipKey(stream, key) {
if (key.wireType == Wire.FIXED32) {
stream.seek(4)
} else if (key.wireType == Wire.FIXED64) {
stream.seek(8)
} else if (key.wireType == Wire.LENGTH_DELIMITED) {
stream.seek(ProtocolParser.readUInt32(stream))
} else if (key.wireType == Wire.VARINT) {
ProtocolParser.readSkipVarInt(stream)
} else {
console.log("WARNING: Unknown wire type: " + key.wireType)
}
};
static readSkipVarInt(stream) {
while (true) {
var b = stream.readByte();
if (b < 0) {
console.log("WARNING: Stream ended too early");
return
}
if ((b & 128) == 0) {
return
}
}
};
static writeBool(stream, val) {
if (val) {
return stream.writeByte(1)
} else {
return stream.writeByte(0)
}
};
static writeUInt32(stream, val) {
var b;
val = Math.abs(val);
while (true) {
b = val & 127;
val = val >>> 7;
if (val == 0) {
stream.writeByte(b);
break
} else {
b = b | 128;
stream.writeByte(b)
}
}
};
static writeZInt32(stream, val) {
var val1 = val << 1;
var val2 = val >> 31;
ProtocolParser.writeUInt32(stream, val1 ^ val2)
};
static writeUInt64(stream, val) {
var b;
val = Math.abs(val);
while (true) {
b = val & 127;
val = Math.floor(val / 128);
if (val == 0) {
stream.writeByte(b);
break
} else {
b = b | 128;
stream.writeByte(b)
}
}
};
static writeZInt64(stream, val) {
var sign = false;
if (val < 0) {
val = -val;
sign = true
}
val = val * 2;
if (sign == true) {
val = val + 1
}
ProtocolParser.writeUInt64(stream, val)
};
static frexp(arg) {
arg = Number(arg);
const result = [arg, 0];
if (arg !== 0 && Number.isFinite(arg)) {
const absArg = Math.abs(arg);
const log2 = Math.log2 || function log2(n) {
return Math.log(n) * Math.LOG2E
};
let exp = Math.max(-1023, Math.floor(log2(absArg)) + 1);
let x = absArg * Math.pow(2, -exp);
while (x < .5) {
x *= 2;
exp--
}
while (x >= 1) {
x *= .5;
exp++
}
if (arg < 0) {
x = -x
}
result[0] = x;
result[1] = exp
}
return result
};
static writeSingle(stream, val) {
var bytes = [0, 0, 0, 0];
if (val != 0) {
var anum = Math.abs(val);
var ret = ProtocolParser.frexp(anum);
var mantissa = ret[0];
var exponent = ret[1];
var sign = val != anum && 128 || 0;
mantissa = mantissa * 2 - 1;
if (mantissa == Infinity) {
mantissa = 0;
exponent = 255
} else {
exponent = exponent - 1;
exponent = exponent + 127;
if (exponent < 0 || exponent >= 255) {
mantissa = 0;
if (exponent < 0) {
exponent = 0
} else {
exponent = 255
}
}
}
bytes[0] = sign + (exponent >> 1);
mantissa *= 128;
var currentmantissa = Math.floor(mantissa);
mantissa -= currentmantissa;
bytes[1] = ((exponent & 1) << 7) + currentmantissa;
for (var i = 2; i < 4; i++) {
mantissa *= 256;
currentmantissa = Math.floor(mantissa);
mantissa -= currentmantissa;
bytes[i] = currentmantissa
}
}
for (var i = bytes.length - 1; i >= 0; i--) {
stream.writeByte(bytes[i])
}
};
static writeDouble(stream, val) {
var bytes = [0, 0, 0, 0, 0, 0, 0, 0];
if (val != 0) {
var anum = Math.abs(val);
var ret = ProtocolParser.frexp(anum);
var mantissa = ret[0];
var exponent = ret[1];
var sign = val != anum && 128 || 0;
mantissa = mantissa * 2 - 1;
if (mantissa == Infinity) {
mantissa = 0;
exponent = 2047
} else {
exponent = exponent - 1;
exponent = exponent + 1023;
if (exponent < 0 || exponent >= 2047) {
mantissa = 0;
if (exponent < 0) {
exponent = 0
} else {
exponent = 2047
}
}
}
bytes[0] = sign + (exponent >> 4);
mantissa *= 16;
var currentmantissa = Math.floor(mantissa);
mantissa -= currentmantissa;
bytes[1] = ((exponent & 15) << 4) + currentmantissa;
for (var i = 2; i < 8; i++) {
mantissa *= 256;
currentmantissa = Math.floor(mantissa);
mantissa -= currentmantissa;
bytes[i] = currentmantissa
}
}
for (var i = bytes.length - 1; i >= 0; i--) {
stream.writeByte(bytes[i])
}
};
static writeBytes(stream, val, len) {
ProtocolParser.writeUInt32(stream, len);
stream.writeBytes(val, 0, len)
};
static writeString(stream, val) {
var array = [];
for (var i = 0; i < val.length; i++) {
array.push(val.charCodeAt(i))
}
ProtocolParser.writeBytes(stream, array, val.length)
};
}
export class ObjectPool {
stack = [];
constructor(public creator, public refresher, public maxSize) { }
pop() {
if (this.stack.length == 0) {
return this.creator()
} else {
return this.stack.shift()
}
}
push(item) {
if (item) {
if (this.stack.indexOf(item) >= 0) {
return
}
if (this.stack.length < this.maxSize) {
if (this.refresher) {
this.refresher(item)
}
this.stack.push(item)
}
}
}
dispose() {
this.stack = []
}
};
export class LogCommand {
tag;
msg;
level;
session;
static pool = new ObjectPool(function () {
return new LogCommand
}, null, 5);
configure(session, tag, level, msg) {
this.tag = tag;
this.msg = msg;
this.level = level;
this.session = session;
return this
}
execute() {
if (GameSparksRT.shouldLog(this.tag, this.level)) {
if (this.session.peerId) {
GameSparksRT.logger(this.session.peerId + " " + this.tag + ":" + this.msg)
} else {
GameSparksRT.logger(" " + this.tag + ":" + this.msg)
}
}
LogCommand.pool.push(this)
}
};
export class CustomCommand {
session = null;
opCode = 0;
sender = 0;
limit = 0;
packetSize = 0;
ms = null;
limitedStream = null;
data = null
static pool = new ObjectPool(function () {
return new CustomCommand
}, null, 5);
configure(opCode, sender, lps, data, limit, session, packetSize) {
this.ms = PooledObjects.memoryStreamPool.pop();
this.packetSize = packetSize;
this.opCode = opCode;
this.sender = sender;
this.data = data;
this.session = session;
this.limit = limit;
this.limitedStream = null;
if (lps != null) {
this.limitedStream = PooledObjects.limitedPositionStreamPool.pop();
for (var i = 1; i <= limit; i++) {
var read = lps.readByte();
this.ms.writeByte(read)
}
this.ms.setPosition(0);
this.limitedStream.wrap(this.ms, limit)
}
return this
}
execute() {
this.session.onPacket(new RTPacket(this.opCode, this.sender, this.limitedStream, this.limit, this.data, this.packetSize));
PooledObjects.memoryStreamPool.push(this.ms);
PooledObjects.limitedPositionStreamPool.push(this.limitedStream);
CustomCommand.pool.push(this)
}
};
export class ActionCommand {
action;
static pool = new ObjectPool(function () {
return new ActionCommand
}, null, 5);
configure(action) {
this.action = action;
return this
}
execute() {
this.action();
ActionCommand.pool.push(this)
}
};
export class CommandFactory {
static getCommand(opCode, sender, sequence, stream, session, data, packetSize) {
var ret = null;
var limit = ProtocolParser.readUInt32(stream);
var lps = PooledObjects.limitedPositionStreamPool.pop();
lps.wrap(stream, limit);
if (opCode == OpCodes.LOGIN_RESULT) {
ret = LoginResult.deserialize(lps, LoginResult.pool.pop())
} else if (opCode == OpCodes.PING_RESULT) {
ret = PingResult.deserialize(lps, PingResult.pool.pop())
} else if (opCode == OpCodes.UDP_CONNECT_MESSAGE) {
ret = UDPConnectMessage.deserialize(lps, UDPConnectMessage.pool.pop())
} else if (opCode == OpCodes.PLAYER_CONNECT_MESSAGE) {
ret = PlayerConnectMessage.deserialize(lps, PlayerConnectMessage.pool.pop())
} else if (opCode == OpCodes.PLAYER_DISCONNECT_MESSAGE) {
ret = PlayerDisconnectMessage.deserialize(lps, PlayerDisconnectMessage.pool.pop())
} else {
if (session.shouldExecute(sender, sequence)) {
ret = CustomCommand.pool.pop().configure(opCode, sender, lps, data, limit, session, packetSize)
}
}
lps.skipToEnd();
PooledObjects.limitedPositionStreamPool.push(lps);
return ret
};
}
export abstract class AbstractResult {
abstractResultType = true;
packet = null;
session = null
configure(packet, session) {
this.packet = packet;
this.session = session
}
executeAsync() {
return true
}
};
export class LoginResult extends AbstractResult {
success = false;
reconnectToken = null;
peerId = null;
activePeers = [];
fastPort = null
static pool = new ObjectPool(function () {
return new LoginResult
}, function (instance) {
instance.activePeers = [];
instance.fastPort = null;
instance.reconnectToken = null;
instance.peerId = null
}, 5);
execute() {
this.session.connectToken = this.reconnectToken;
this.session.peerId = this.peerId;
if (this.packet.reliable == null || this.packet.reliable == true) {
if (this.fastPort != null && this.fastPort) {
this.session.fastPort = this.fastPort
}
this.session.activePeers = this.activePeers.slice();
this.session.setConnectState(GameSparksRT.connectState.RELIABLE_ONLY);
this.session.connectFast();
this.session.log("LoginResult", GameSparksRT.logLevel.DEBUG, this.session.peerId + " TCP LoginResult, ActivePeers " + this.session.activePeers.length)
} else {
this.session.setConnectState(GameSparksRT.connectState.RELIABLE_AND_FAST_SEND)
}
LoginResult.pool.push(this)
};
executeAsync() {
return false
};
static deserialize(stream, instance) {
if (instance.activePeers == null) {
instance.activePeers = []
}
while (true) {
var keyByte = stream.readByte();
if (keyByte == -1) {
break
}
var _continue = false;
if (keyByte == 8) {
instance.success = ProtocolParser.readBool(stream);
_continue = true
} else if (keyByte == 18) {
instance.reconnectToken = ProtocolParser.readString(stream);
_continue = true
} else if (keyByte == 24) {
instance.peerId = ProtocolParser.readUInt64(stream);
_continue = true
} else if (keyByte == 32) {
instance.activePeers.push(ProtocolParser.readUInt64(stream));
_continue = true
} else if (keyByte == 40) {
instance.fastPort = ProtocolParser.readUInt64(stream);
_continue = true
}
if (!_continue) {
var key = ProtocolParser.readKey(keyByte, stream);
if (key.field == 0) {
console.log("WARNING: Invalid field id: 0, something went wrong in the stream");
return null
} else {
ProtocolParser.skipKey(stream, key)
}
}
}
return instance
};
}
export class PingResult extends AbstractResult {
static pool = new ObjectPool(function () {
return new PingResult
}, null, 5);
execute() {
this.session.log("PingResult", GameSparksRT.logLevel.DEBUG, "");
PingResult.pool.push(this)
};
executeAsync() {
return false
};
static deserialize(stream, instance) {
while (true) {
var keyByte = stream.readByte();
if (keyByte == -1) {
break
}
var key = ProtocolParser.readKey(keyByte, stream);
if (key.field == 0) {
console.log("WARNING: Invalid field id: 0, something went wrong in the stream");
return null
} else {
ProtocolParser.skipKey(stream, key)
}
}
return instance
};
}
export class PlayerConnectMessage extends AbstractResult {
peerId = 0;
activePeers = [];
static pool = new ObjectPool(function () {
return new PlayerConnectMessage
}, function (instance) {
instance.activePeers = []
}, 5);
execute() {
this.session.activePeers = [];
this.session.activePeers = this.activePeers.slice();
this.session.log("PlayerConnectMessage", GameSparksRT.logLevel.DEBUG, "PeerId=" + this.peerId + ", ActivePeers " + this.session.activePeers.length);
this.session.onPlayerConnect(this.peerId);
PlayerConnectMessage.pool.push(this)
};
static deserialize(stream, instance) {
if (instance.activePeers == null) {
instance.activePeers = []
}
while (true) {
var keyByte = stream.readByte();
if (keyByte == -1) {
break
}
var _continue = false;
if (keyByte == 8) {
instance.peerId = ProtocolParser.readUInt64(stream);
_continue = true
} else if (keyByte == 32) {
instance.activePeers.push(ProtocolParser.readUInt64(stream));
_continue = true
}
if (!_continue) {
var key = ProtocolParser.readKey(keyByte, stream);
if (key.field == 0) {
console.log("WARNING: Invalid field id: 0, something went wrong in the stream");
return null
} else {
ProtocolParser.skipKey(stream, key)
}
}
}
return instance
};
}
export class PlayerDisconnectMessage extends AbstractResult {
peerId = 0;
activePeers = [];
static pool = new ObjectPool(function () {
return new PlayerDisconnectMessage
}, function (instance) {
instance.activePeers = []
}, 5);
execute() {
this.session.activePeers = [];
this.session.activePeers = this.activePeers.slice();
this.session.log("PlayerDisconnectMessage", GameSparksRT.logLevel.DEBUG, "PeerId=" + this.peerId + ", ActivePeers " + this.session.activePeers.length);
this.session.onPlayerDisconnect(this.peerId);
PlayerDisconnectMessage.pool.push(this)
};
static deserialize(stream, instance) {
if (instance.activePeers == null) {
instance.activePeers = []
}
while (true) {
var keyByte = stream.readByte();
if (keyByte == -1) {
break
}
var _continue = false;
if (keyByte == 8) {
instance.peerId = ProtocolParser.readUInt64(stream);
_continue = true
} else if (keyByte == 32) {
instance.activePeers.push(ProtocolParser.readUInt64(stream));
_continue = true
}
if (!_continue) {
var key = ProtocolParser.readKey(keyByte, stream);
if (key.field == 0) {
console.log("WARNING: Invalid field id: 0, something went wrong in the stream");
return null
} else {
ProtocolParser.skipKey(stream, key)
}
}
}
return instance
};
}
export class UDPConnectMessage extends AbstractResult {
static pool = new ObjectPool(function () {
return new UDPConnectMessage
}, null, 5);
execute() {
var reliable;
if (this.packet.reliable != null) {
reliable = this.packet.reliable
} else {
reliable = false
}
this.session.log("UDPConnectMessage", GameSparksRT.logLevel.DEBUG, "(UDP) reliable=" + reliable.toString() + ", ActivePeers " + this.session.activePeers.length);
if (!reliable) {
this.session.setConnectState(GameSparksRT.connectState.RELIABLE_AND_FAST);
this.session.sendData(-5, GameSparksRT.deliveryIntent.RELIABLE, null, null)
} else {
this.session.log("UDPConnectMessage", GameSparksRT.logLevel.DEBUG, "TCP (Unexpected) UDPConnectMessage")
}
UDPConnectMessage.pool.push(this)
};
executeAsync() {
return false
};
static deserialize(stream, instance) {
while (true) {
var keyByte = stream.readByte();
if (keyByte == -1) {
break
}
var key = ProtocolParser.readKey(keyByte, stream);
if (key.field == 0) {
console.log("WARNING: Invalid field id: 0, something went wrong in the stream");
return null
} else {
ProtocolParser.skipKey(stream, key)
}
}
return instance
};
}
export class RTRequest {
data = null;
opCode = 0;
targetPlayers = [];
intent = GameSparksRT.deliveryIntent.RELIABLE
toPacket(session, fast) {
return null
}
reset() {
this.targetPlayers = []
}
serialize(stream) { }
};
export class LoginCommand extends RTRequest {
opCode = 0;
clientVersion = 2
constructor(public token) {
super();
}
toPacket(session, fast) {
var p = PooledObjects.packetPool.pop();
p.opCode = this.opCode;
p.data = this.data;
p.session = session;
if (!fast && this.intent != GameSparksRT.deliveryIntent.RELIABLE) {
p.reliable = false
}
if (this.intent == GameSparksRT.deliveryIntent.UNRELIABLE_SEQUENCED) {
p.sequenceNumber = session.nextSequenceNumber()
}
if (this.targetPlayers.length > 0) {
p.targetPlayers = this.targetPlayers
}
p.request = this;
return p
};
serialize(stream) {
if (this.token != null) {
stream.writeByte(10);
ProtocolParser.writeString(stream, this.token)
}
if (this.clientVersion != null) {
stream.writeByte(16);
ProtocolParser.writeUInt64(stream, this.clientVersion)
}
};
}
export class PingCommand extends RTRequest {
opCode = -2;
toPacket(session, fast) {
var p = PooledObjects.packetPool.pop();
p.opCode = this.opCode;
p.data = this.data;
p.session = session;
if (!fast && this.intent != GameSparksRT.deliveryIntent.RELIABLE) {
p.reliable = false
}
if (this.intent == GameSparksRT.deliveryIntent.UNRELIABLE_SEQUENCED) {
p.sequenceNumber = session.nextSequenceNumber()
}
if (this.targetPlayers.length > 0) {
p.targetPlayers = this.targetPlayers
}
p.request = this;
return p
}
serialize(stream) { };
}
export class CustomRequest extends RTRequest {
payload = null;
configure(opCode, intent, payload, data, targetPlayers) {
this.opCode = opCode;
this.payload = payload;
this.intent = intent;
this.data = data;
if (targetPlayers != null) {
for (var i in targetPlayers) {
this.targetPlayers.push(targetPlayers[i])
}
}
}
toPacket(session, fast) {
var p = PooledObjects.packetPool.pop();
p.opCode = this.opCode;
p.data = this.data;
p.session = session;
if (!fast && this.intent != GameSparksRT.deliveryIntent.RELIABLE) {
p.reliable = false
}
if (this.intent == GameSparksRT.deliveryIntent.UNRELIABLE_SEQUENCED) {
p.sequenceNumber = session.nextSequenceNumber()
}
if (this.targetPlayers.length > 0) {
p.targetPlayers = this.targetPlayers
}
p.request = this;
return p
}
serialize(stream) {
if (this.payload) {
stream.writeBytes(this.payload, 0, this.payload.length)
}
}
reset() {
this.payload = null;
super.reset();
};
}
export class Packet {
opCode = 0;
sequenceNumber = null;
requestId = null;
targetPlayers = null;
sender = null;
reliable = null;
data = null;
payload = null;
request = null;
hasPayload = false;
command = null;
session = null
reset() {
this.opCode = 0;
this.sequenceNumber = null;
this.requestId = null;
this.targetPlayers = null;
this.sender = null;
this.reliable = null;
this.payload = null;
this.command = null;
this.request = null;
this.hasPayload = false;
this.data = null
}
toString() {
return "{OpCode:" + this.opCode + ",TargetPlayers:" + this.targetToString() + "}"
}
targetToString() {
var s = "[";
if (this.targetPlayers != null) {
for (var i = 0; i < this.targetPlayers.length; i++) {
s = s + this.targetPlayers[i] + " "
}
}
return s + "]"
}
readPayload(stream, packetSize) {
this.hasPayload = true;
if (this.sender != null) {
this.command = CommandFactory.getCommand(this.opCode, this.sender, this.sequenceNumber, stream, this.session, this.data, packetSize)
} else {
this.command = CommandFactory.getCommand(this.opCode, 0, this.sequenceNumber, stream, this.session, this.data, packetSize)
}
return null
}
writePayload(stream) {
if (this.request != null) {
var ms = PooledObjects.memoryStreamPool.pop();
this.request.serialize(ms);
var written = ms.getBuffer();
if (ms.getPosition() > 0) {
stream.writeByte(122);
ProtocolParser.writeBytes(stream, written, ms.getPosition())
}
PooledObjects.memoryStreamPool.push(ms)
} else if (this.payload != null) {
stream.writeByte(122);
ProtocolParser.writeBytes(stream, this.payload, this.payload.length)
}
}
static serialize(stream, instance) {
stream.writeByte(8);
ProtocolParser.writeZInt32(stream, instance.opCode);
if (instance.sequenceNumber != null) {
stream.writeByte(16);
ProtocolParser.writeUInt64(stream, instance.sequenceNumber)
}
if (instance.requestId != null) {
stream.writeByte(24);
ProtocolParser.writeUInt64(stream, instance.requestId)
}
if (instance.targetPlayers != null) {
for (var i = 0; i < instance.targetPlayers.length; i++) {
stream.writeByte(32);
ProtocolParser.writeUInt64(stream, instance.targetPlayers[i])
}
}
if (instance.sender != null) {
stream.writeByte(40);
ProtocolParser.writeUInt64(stream, instance.sender)
}
if (instance.reliable != null) {
stream.writeByte(48);
ProtocolParser.writeBool(stream, instance.reliable)
}
if (instance.data != null) {
stream.writeByte(114);
RTData.writeRTData(stream, instance.data)
}
instance.writePayload(stream);
return stream
};
static serializeLengthDelimited(stream, instance) {
var ms = PooledObjects.memoryStreamPool.pop();
var ret;
Packet.serialize(ms, instance);
var data = ms.getBuffer();
ProtocolParser.writeBytes(stream, data, ms.getPosition());
ret = ms.getPosition();
PooledObjects.memoryStreamPool.push(ms);
return ret
};
static deserializeLengthDelimited(stream, instance) {
var limit = ProtocolParser.readUInt32(stream);
var origLimit = limit;
limit = limit + stream.getPosition();
while (true) {
if (stream.getPosition() >= limit) {
if (stream.getPosition() == limit) {
break
} else {
console.log("WARNING: Read past max limit");
return 0
}
}
var keyByte = stream.readByte();
if (keyByte == -1) {
console.log("WARNING: End of stream");
return 0
}
var _continue = false;
if (keyByte == 8) {
instance.opCode = ProtocolParser.readZInt32(stream);
_continue = true
} else if (keyByte == 16) {
instance.sequenceNumber = ProtocolParser.readUInt64(stream);
_continue = true
} else if (keyByte == 24) {
instance.requestId = ProtocolParser.readUInt64(stream);
_continue = true
} else if (keyByte == 40) {
instance.sender = ProtocolParser.readUInt64(stream);
_continue = true
} else if (keyByte == 48) {
instance.reliable = ProtocolParser.readBool(stream);
_continue = true
} else if (keyByte == 114) {
if (instance.data == null) {
instance.data = RTData.readRTData(stream, instance.data)
} else {
RTData.readRTData(stream, instance.data)
}
_continue = true
} else if (keyByte == 122) {
instance.payload = instance.readPayload(stream, origLimit);
_continue = true
}
if (!_continue) {
var key = ProtocolParser.readKey(keyByte, stream);
if (key.field == 0) {
console.log("WARNING: Invalid field id: 0, something went wrong in the stream");
return 0
} else {
ProtocolParser.skipKey(stream, key)
}
}
}
return origLimit
};
}
export class PooledObjects {
static packetPool = new ObjectPool(function () {
return new Packet
}, function (packet) {
packet.reset()
}, 5);
static memoryStreamPool = new ObjectPool(function () {
return new Stream
}, function (stream) {
stream.setPosition(0)
}, 5);
static positionStreamPool = {};
static limitedPositionStreamPool = new ObjectPool(function () {
return new LimitedPositionStream
}, null, 5);
static byteBufferPool = new ObjectPool(function () {
var array = [];
for (var i = 0; i < 256; i++) {
array.push(0)
}
return array
}, null, 5);
static customRequestPool = new ObjectPool(function () {
return new CustomRequest
}, function (cr) {
cr.reset()
}, 5);
}
export class RTDataSerializer {
static cache = new ObjectPool(function () {
return new RTData
}, function (rtData) {
for (var i = 0; i < rtData.data.length; i++) {
if (rtData.data[i].data_val) {
rtData.data[i].data_val.dispose()
}
rtData.data[i].reset()
}
}, 5);
static get() {
return RTDataSerializer.cache.pop()
};
static readRTData(stream, instance) {
if (instance == null) {
instance = RTDataSerializer.cache.pop()
}
var limit = ProtocolParser.readUInt32(stream);
limit = limit + stream.getPosition();
while (true) {
if (stream.getPosition() >= limit) {
if (stream.getPosition() == limit) {
break
} else {
console.log("WARNING: Read past max limit");
return null
}
}
var keyByte = stream.readByte();
if (keyByte == -1) {
break
}
var key = ProtocolParser.readKey(keyByte, stream);
if (key.wireType == Wire.VARINT) {
instance.data[key.field] = RTVal.newLong(ProtocolParser.readZInt64(stream))
} else if (key.wireType == Wire.FIXED32) {
instance.data[key.field] = RTVal.newFloat(ProtocolParser.readSingle(stream))
} else if (key.wireType == Wire.FIXED64) {
instance.data[key.field] = RTVal.newDouble(ProtocolParser.readDouble(stream))
} else if (key.wireType == Wire.LENGTH_DELIMITED) {
instance.data[key.field] = RTVal.deserializeLengthDelimited(stream)
}
if (key.field == 0) {
console.log("WARNING: Invalid field id: 0, something went wrong in the stream");
return null
}
}
return instance
};
static writeRTData(stream, instance) {
var ms = PooledObjects.memoryStreamPool.pop();
for (var index = 1; index < instance.data.length; index++) {
var entry = instance.data[index];
if (entry.long_val != null) {
ProtocolParser.writeUInt32(ms, index << 3);
ProtocolParser.writeZInt64(ms, entry.long_val)
} else if (entry.float_val != null) {
ProtocolParser.writeUInt32(ms, index << 3 | 5);
ProtocolParser.writeSingle(ms, entry.float_val)
} else if (entry.double_val != null) {
ProtocolParser.writeUInt32(ms, index << 3 | 1);
ProtocolParser.writeDouble(ms, entry.double_val)
} else if (entry.data_val || entry.string_val || entry.vec_val) {
ProtocolParser.writeUInt32(ms, index << 3 | 2);
entry.serializeLengthDelimited(ms)
}
}
var buffer = ms.getBuffer();
ProtocolParser.writeBytes(stream, buffer, ms.getPosition());
PooledObjects.memoryStreamPool.push(ms)
};
}
export class RTVector {
x;
y;
z;
w;
}
export class RTVal {
long_val = null;
float_val = null;
double_val = null;
data_val = null;
string_val = null;
vec_val = null;
serializeLengthDelimited(stream) {
var ms = PooledObjects.memoryStreamPool.pop();
if (this.string_val) {
ms.writeByte(10);
ProtocolParser.writeString(ms, this.string_val)
} else if (this.data_val) {
ms.writeByte(114);
RTData.writeRTData(ms, this.data_val)
} else if (this.vec_val) {
var vec_value = this.vec_val;
var numberOfFloatsSet = 0;
ms.writeByte(18);
if (vec_value.x != null) {
numberOfFloatsSet = numberOfFloatsSet + 1
}
if (vec_value.y != null) {
numberOfFloatsSet = numberOfFloatsSet + 1
}
if (vec_value.z != null) {
numberOfFloatsSet = numberOfFloatsSet + 1
}
if (vec_value.w != null) {
numberOfFloatsSet = numberOfFloatsSet + 1
}
ProtocolParser.writeUInt32(ms, 4 * numberOfFloatsSet);
for (var i = 1; i <= numberOfFloatsSet; i++) {
if (i == 1) {
ProtocolParser.writeSingle(ms, vec_value.x)
} else if (i == 2) {
ProtocolParser.writeSingle(ms, vec_value.y)
} else if (i == 3) {
ProtocolParser.writeSingle(ms, vec_value.z)
} else if (i == 4) {
ProtocolParser.writeSingle(ms, vec_value.w)
}
}
}
var data = ms.getBuffer();
ProtocolParser.writeBytes(stream, data, ms.getPosition());
PooledObjects.memoryStreamPool.push(ms)
}
reset() {
if (this.data_val) {
this.data_val.dispose()
}
this.long_val = null;
this.float_val = null;
this.double_val = null;
this.data_val = null;
this.string_val = null;
this.vec_val = null
}
dirty() {
if (this.long_val != null) {
return true
} else if (this.float_val != null) {
return true
} else if (this.double_val != null) {
return true
} else if (this.data_val) {
return true
} else if (this.string_val) {
return true
} else if (this.vec_val) {
return true
}
return false
}
asString() {
if (this.long_val != null) {
return this.long_val.toString()
} else if (this.float_val != null) {
return this.float_val.toString()
} else if (this.double_val != null) {
return this.double_val.toString()
} else if (this.data_val) {
return this.data_val.toString()
} else if (this.string_val) {
return '"' + this.string_val + '"'
} else if (this.vec_val) {
var ret = "|";
if (this.vec_val.x != null) {
ret = ret + this.vec_val.x.toString() + "|"
}
if (this.vec_val.y != null) {
ret = ret + this.vec_val.y.toString() + "|"
}
if (this.vec_val.z != null) {
ret = ret + this.vec_val.z.toString() + "|"
}
if (this.vec_val.w != null) {
ret = ret + this.vec_val.w.toString() + "|"
}
return ret
}
return null
}
static newLong(value) {
var instance = new RTVal;
instance.long_val = value;
return instance
};
static newFloat(value) {
var instance = new RTVal;
instance.float_val = value;
return instance
};
static newDouble(value) {
var instance = new RTVal;
instance.double_val = value;
return instance
};
static newRTData(value) {
var instance = new RTVal;
instance.data_val = value;
return instance
};
static newString(value) {
var instance = new RTVal;
instance.string_val = value;
return instance
};
static newRTVector(value) {
var instance = new RTVal;
instance.vec_val = value;
return instance
};
static deserializeLengthDelimited(stream) {
var instance = new RTVal;
var limit = ProtocolParser.readUInt32(stream);
limit = limit + stream.getPosition();
while (true) {
if (stream.getPosition() >= limit) {
if (stream.getPosition() == limit) {
break
} else {
console.log("WARNING: Read past max limit");
return 0
}
}
var keyByte = stream.readByte();
if (keyByte == -1) {
console.log("WARNING: End of stream");
return 0
}
var _continue = false;
if (keyByte == 10) {
instance.string_val = ProtocolParser.readString(stream);
_continue = true
} else if (keyByte == 18) {
var end2 = ProtocolParser.readUInt32(stream);
end2 = end2 + stream.getPosition();
var v = new RTVector;
var i = 0;
while (stream.getPosition() < end2) {
var read = ProtocolParser.readSingle(stream);
if (i == 0) {
v.x = read
} else if (i == 1) {
v.y = read
} else if (i == 2) {
v.z = read
} else if (i == 3) {
v.w = read
}
i = i + 1
}
instance.vec_val = v;
if (stream.getPosition() != end2) {
console.log("WARNING: Read too many bytes in packed data");
return null
}
_continue = true
} else if (keyByte == 114) {
if (instance.data_val == null) {
instance.data_val = RTDataSerializer.cache.pop()
}
RTData.readRTData(stream, instance.data_val);
_continue = true
}
if (!_continue) {
var key = ProtocolParser.readKey(keyByte, stream);
if (key.field == 0) {
console.log("WARNING: Invalid field id: 0, something went wrong in the stream");
return null
} else {
ProtocolParser.skipKey(stream, key)
}
}
}
return instance
}
}
export class RTData {
data: RTVal[] = [];
constructor() {
for (var i = 0; i < GameSparksRT.MAX_RTDATA_SLOTS; i++) {
this.data.push(new RTVal)
}
};
static get() {
return RTDataSerializer.cache.pop()
};
static readRTData(stream, instance) {
return RTDataSerializer.readRTData(stream, instance)
};
static writeRTData(stream, instance) {
RTDataSerializer.writeRTData(stream, instance)
};
dispose() {
for (var i = 0; i < this.data.length; i++) {
if (this.data[i].dirty()) {
this.data[i] = new RTVal
}
}
RTDataSerializer.cache.push(this)
}
getRTVector(index) {
return this.data[index].vec_val
}
getLong(index) {
return this.data[index].long_val
}
getFloat(index) {
return this.data[index].float_val
}
getDouble(index) {
return this.data[index].double_val
}
getString(index) {
return this.data[index].string_val
}
getData(index) {
return this.data[index].data_val
}
setRTVector(index, value) {
this.data[index] = RTVal.newRTVector(value);
return this
}
setLong(index, value) {
if (isFinite(value)) {
this.data[index] = RTVal.newLong(value)
} else {
console.error("Not a valid number error")
}
return this
}
setFloat(index, value) {
if (isFinite(value)) {
this.data[index] = RTVal.newFloat(value)
} else {
console.error("Not a valid number error")
}
return this
}
setDouble(index, value) {
if (isFinite(value)) {
this.data[index] = RTVal.newDouble(value)
} else {
console.error("Not a valid number error")
}
return this
}
setString(index, value) {
this.data[index] = RTVal.newString(value);
return this
}
setData(index, value) {
this.data[index] = RTVal.newRTData(value);
return this
}
toString() {
return this.asString()
}
asString() {
var builder = " {";
for (var i = 0; i < GameSparksRT.MAX_RTDATA_SLOTS; i++) {
var val = this.data[i].asString();
if (val != null) {
builder = builder + " [" + i.toString() + " " + val + "] "
}
}
builder = builder + "} ";
return builder
}
};
export class RTPacket {
constructor(public opCode, public sender, public stream, public streamLength, public data, public packetSize) { }
toString() {
var string = "OpCode=" + this.opCode + ",Sender=" + this.sender + ",streamExists=";
if (this.stream != null) {
string = string + "true,StreamLength=" + this.streamLength
} else {
string = string + "false"
}
string = string + ",Data=";
if (this.data != null) {
string = string + this.data.toString()
} else {
string = string + ".PacketSize=" + this.packetSize
}
return string
}
};
export class RTSessionImpl {
fastPort;
activePeers = [];
running = false;
ready = false;
actionQueue = [];
connectState = GameSparksRT.connectState.DISCONNECTED;
mustConnnectBy = (new Date).getTime();
reliableConnection = null;
sequenceNumber = 0;
peerId = null;
peerMaxSequenceNumbers = [];
constructor(public connectToken, public hostName, public tcpPort, public listener) {
this.fastPort = tcpPort;
}
start() {
this.running = true
}
stop() {
this.log("IRTSession", GameSparksRT.logLevel.DEBUG, "Stopped");
this.running = false;
this.ready = false;
if (this.reliableConnection) {
this.reliableConnection.stop()
}
this.setConnectState(GameSparksRT.connectState.DISCONNECTED)
}
update() {
if (this.running) {
this.checkConnection()
}
var toExecute = null;
while (true) {
toExecute = this.getNextAction();
if (toExecute) {
toExecute.execute()
} else {
break
}
}
}
getNextAction() {
if (this.actionQueue.length > 0) {
return this.actionQueue.shift()
}
return null
}
submitAction(action) {
this.actionQueue.push(action)
}
checkConnection() {
if (this.connectState == GameSparksRT.connectState.DISCONNECTED) {
this.log("IRTSession", GameSparksRT.logLevel.INFO, "Disconnected, trying to connect");
this.setConnectState(GameSparksRT.connectState.CONNECTING);
this.connectReliable()
} else if (this.connectState == GameSparksRT.connectState.CONNECTING && (new Date).getTime() > this.mustConnnectBy) {
this.setConnectState(GameSparksRT.connectState.DISCONNECTED);
this.log("IRTSession", GameSparksRT.logLevel.INFO, "Not connected in time, retrying");
if (this.reliableConnection) {
this.reliableConnection.stopInternal();
this.reliableConnection = null
}
}
}
setConnectState(value) {
if (value == GameSparksRT.connectState.RELIABLE_AND_FAST_SEND || value == GameSparksRT.connectState.RELIABLE_AND_FAST) {
value = GameSparksRT.connectState.RELIABLE_ONLY
}
if (value != this.connectState) {
if (this.connectState < value || value == GameSparksRT.connectState.DISCONNECTED) {
this.log("IRTSession", GameSparksRT.logLevel.DEBUG, "State Change : from " + this.connectState + " to " + value + ", ActivePeers " + this.activePeers.length);
this.connectState = value
}
if (value == GameSparksRT.connectState.RELIABLE_ONLY) {
this.onReady(true)
}
}
}
connectFast() { }
connectReliable() {
this.mustConnnectBy = (new Date).getTime() + GameSparksRT.TCP_CONNECT_TIMEOUT_SECONDS * 1e3;
this.reliableConnection = new ReliableConnection(this.hostName, this.tcpPort, this);
this.reliableConnection.connect()
}
nextSequenceNumber() {
var sequenceNumber = this.sequenceNumber;
this.sequenceNumber = this.sequenceNumber + 1;
return sequenceNumber
}
shouldExecute(peerId, sequence) {
if (sequence == null) {
return true
} else if (this.peerMaxSequenceNumbers[peerId] == null) {
this.peerMaxSequenceNumbers[peerId] = 0
}
if (this.peerMaxSequenceNumbers[peerId] > sequence) {
this.log("IRTSession", GameSparksRT.logLevel.DEBUG, "Discarding sequence id " + sequence + " from peer " + peerId.toString());
return false
} else {
this.peerMaxSequenceNumbers[peerId] = sequence;
return true
}
}
resetSequenceForPeer(peerId) {
if (this.peerMaxSequenceNumbers[peerId]) {
this.peerMaxSequenceNumbers[peerId] = 0
}
}
onPlayerConnect(peerId) {
this.resetSequenceForPeer(peerId);
if (this.listener) {
if (this.ready) {
this.listener.onPlayerConnect(peerId)
}
}
}
onPlayerDisconnect(peerId) {
if (this.listener) {
if (this.ready) {
this.listener.onPlayerDisconnect(peerId)
}
}
}
onReady(ready) {
if (!this.ready && ready) {
this.sendData(OpCodes.PLAYER_READY_MESSAGE, GameSparksRT.deliveryIntent.RELIABLE, null, null, null);
if (this.peerId) {
var ok = false;
for (var k in this.activePeers) {
if (this.activePeers[k] == this.peerId) {
ok = true;
break
}
}
if (!ok) {
this.activePeers.push(this.peerId)
}
}
}
this.ready = ready;
if (!this.ready) {
this.setConnectState(GameSparksRT.connectState.DISCONNECTED)
}
if (this.listener) {
var myListener = this.listener;
this.submitAction(ActionCommand.pool.pop().configure(function () {
myListener.onReady(ready)
}))
}
}
onPacket(packet) {
if (this.listener) {
this.listener.onPacket(packet)
} else {
throw new Error("AccessViolationException")
}
}
sendData(opCode, intent, payload, data, targetPlayers) {
return this.sendRTDataAndBytes(opCode, intent, payload, data, targetPlayers)
}
sendRTData(opCode, intent, data, targetPlayers) {
return this.sendRTDataAndBytes(opCode, intent, null, data, targetPlayers)
}
sendBytes(opCode, intent, payload, targetPlayers) {
return this.sendRTDataAndBytes(opCode, intent, payload, null, targetPlayers)
}
sendRTDataAndBytes(opCode, intent, payload, data, targetPlayers) {
var csr = PooledObjects.customRequestPool.pop();
var ret;
csr.configure(opCode, intent, payload, data, targetPlayers);
if (this.connectState >= GameSparksRT.connectState.RELIABLE_ONLY) {
ret = this.reliableConnection.send(csr);
PooledObjects.customRequestPool.push(csr);
return ret
}
PooledObjects.customRequestPool.push(csr);
return 0
}
log(tag, level, msg) {
if (GameSparksRT.shouldLog(tag, level)) {
this.submitAction(LogCommand.pool.pop().configure(this, tag, level, msg))
}
}
};
export class GameSparksRT {
static MAX_RTDATA_SLOTS = 128;
static TCP_CONNECT_TIMEOUT_SECONDS = 5;
static logLevel = {
DEBUG: 0,
INFO: 1,
WARN: 2,
ERROR: 3
};
static connectState = {
DISCONNECTED: 0,
CONNECTING: 1,
RELIABLE_ONLY: 2,
RELIABLE_AND_FAST_SEND: 3,
RELIABLE_AND_FAST: 4
};
static deliveryIntent = {
RELIABLE: 0,
UNRELIABLE: 1,
UNRELIABLE_SEQUENCED: 2
};
static currLogLevel = GameSparksRT.logLevel.INFO;
static tagLevels = {};
static logger(msg) {
console.log(msg)
};
static getSession(connectToken, hostName, tcpPort, listener) {
return new RTSessionImpl(connectToken, hostName, tcpPort, listener)
};
static setRootLogLevel(level) {
GameSparksRT.currLogLevel = level
};
static setLogLevel(tag, level) {
GameSparksRT.tagLevels[tag] = level
};
static shouldLog(tag, level) {
for (var key in GameSparksRT.tagLevels) {
var value = GameSparksRT.tagLevels[key];
if (key == tag) {
return value >= level
}
}
return GameSparksRT.currLogLevel <= level
};
};
import { isIOS } from "tns-core-modules/ui/page/page";
import { GameSparksRT, RTSessionImpl } from "~/gamesparks/gamesparks-realtime";
require('nativescript-websockets');
export interface GenericResponse {
/** A JSON Map of any data added either to the Request or the Response by your Cloud Code */
scriptData: Object;
};
export interface Player {
/** The achievements of the Player */
achievements: string[];
/** The display name of the Player */
displayName: string;
/** The external Id’s of the Player */
externalIds: Object;
/** The Id of the Player */
id: string;
/** The online status of the Player */
online: boolean;
/** The script data of the Player */
scriptData: Object;
/** The virtual goods of the Player */
virtualGoods: string[];
};
export interface MatchDetailsResponse {
/** The accessToken used to authenticate this player for this match */
accessToken: string;
/** The host to connect to for this match */
host: string;
/** MatchData is arbitrary data that can be stored in a Match instance by a Cloud Code script. */
matchData: JSON;
/** The id for this match instance */
matchId: string;
/** The opponents this player has been matched against */
opponents: Player[];
/** The peerId of this player within the match */
peerId: number;
/** The id of the current player */
playerId: string;
/** The port to connect to for this match */
port: number;
/** A JSON Map of any data added either to the Request or the Response by your Cloud Code */
scriptData: Object;
}
export interface ChallengeRequest {
/** Who can join this challenge */
accessType?: 'PUBLIC' | 'PRIVATE' | 'FRIENDS'
/** An optional message to include with the challenge */
challengeMessage?: string
/** The ammount of currency type 1 that the player is wagering on this challenge */
currency1Wager?
currency2Wager?
currency3Wager?
currency4Wager?
currency5Wager?
currency6Wager?
/** The time at which this challenge will end. This is required when the challenge is not linked to an achievement */
endTime?: string;
/** The latest time that players can join this challenge */
expiryTime?: string;
/** The maximum number of attempts */
maxAttempts?: number;
/** The maximum number of players that are allowed to join this challenge */
maxPlayers?: number;
/** The minimum number of players that are allowed to join this challenge */
minPlayers?: number;
/** If True no messaging is triggered */
silent?: boolean;
/** The time at which this challenge will begin */
startTime?: string;
/** A player id or an array of player ids who will recieve this challenge */
usersToChallenge?: string[]
}
export interface Participant {
/** The achievements of the Player */
achievements: string[];
/** The display name of the Player */
displayName: string;
/** The external Id’s of the Player */
externalIds: Object;
/** The Id of the Player */
id: string;
/** The online status of the Player */
online: boolean;
/** A JSON Map of any data that was associated to this user */
participantData: Object;
/** The peerId of this participant within the match */
peerId: number;
/** The script data of the Player */
scriptData: Object;
/** The virtual goods of the Player */
virtualGoods: string[];
}
export interface MatchFoundMessage {
/** The accessToken used to authenticate this player for this match */
accessToken: string;
/** The host to connect to for this match */
host: string;
/** The arbitrary data that is stored on a match instance in the matchData field */
matchData: JSON;
/** The group the player was assigned in the matchmaking request */
matchGroup: string;
/** The id for this match instance */
matchId: string;
/** The shortCode of the match type this message for */
matchShortCode: string;
/** A unique identifier for this message. */
messageId: string;
/** Flag indicating whether this message could be sent as a push notification or not. */
notification: boolean;
/** ] The participants in this match */
participants: Participant[];
/** The arbitrary data that is stored on a pendingMatch in the matchData field */
pendingMatchData: JSON;
/** The port to connect to for this match */
port: number;
/** ] ScriptData is arbitrary data that can be stored in a message by a Cloud Code script. */
scriptData: Object;
/** A textual title for the message. */
subTitle: string;
/** A textual summary describing the message’s purpose. */
summary: string;
/** A textual title for the message. */
title: string;
}
export class RealtimeSession {
static started = false;
static onPlayerConnectCB = null;
static onPlayerDisconnectCB = null;
static onReadyCB = null;
static onPacketCB = null;
static session: RTSessionImpl;
static start(connectToken, host, port) {
var index = host.indexOf(":");
var theHost;
if (index > 0) {
theHost = host.slice(0, index);
} else {
theHost = host;
}
console.log(theHost + " : " + port);
RealtimeSession.session = GameSparksRT.getSession(connectToken, theHost, port, RealtimeSession);
if (RealtimeSession.session != null) {
RealtimeSession.started = true;
RealtimeSession.session.start();
} else {
RealtimeSession.started = false;
}
};
static stop() {
RealtimeSession.started = false;
if (RealtimeSession.session != null) {
RealtimeSession.session.stop();
}
};
static log(message) {
var peers = "|";
for (var k in RealtimeSession.session.activePeers) {
peers = peers + RealtimeSession.session.activePeers[k] + "|";
}
console.log(RealtimeSession.session.peerId + ": " + message + " peers:" + peers);
};
static onPlayerConnect(peerId) {
RealtimeSession.log(" OnPlayerConnect:" + peerId);
if (RealtimeSession.onPlayerConnectCB != null) {
RealtimeSession.onPlayerConnectCB(peerId);
}
};
static onPlayerDisconnect(peerId) {
RealtimeSession.log(" OnPlayerDisconnect:" + peerId);
if (RealtimeSession.onPlayerDisconnectCB != null) {
RealtimeSession.onPlayerDisconnectCB(peerId);
}
};
static onReady(ready) {
RealtimeSession.log(" OnReady:" + ready.toString());
if (RealtimeSession.onReadyCB != null) {
RealtimeSession.onReadyCB(ready);
}
};
static onPacket(packet) {
RealtimeSession.log(" OnPacket:" + packet.toString());
if (RealtimeSession.onPacketCB != null) {
RealtimeSession.onPacketCB(packet);
}
};
}
export class GameSparks {
options;
socketUrl;
pendingRequests;
requestCounter;
init(options) {
this.options = options;
this.socketUrl = options.url;
this.pendingRequests = {};
this.requestCounter = 0;
this.connect();
}
buildServiceUrl(live, options) {
var stage;
var urlAddition = options.key;
var credential;
var index;
if (live) {
stage = "live";
} else {
stage = "preview";
}
if (!options.credential || options.credential.length === 0) {
credential = "device";
} else {
credential = options.credential;
}
if (options.secret) {
index = options.secret.indexOf(":");
if (index > 0) {
credential = "secure";
urlAddition = options.secret.substr(0, index) + "/" + urlAddition;
}
}
return "wss://" + stage + "-" + urlAddition + ".ws.gamesparks.net/ws/" + credential + "/" + urlAddition;
}
initPreview(options) {
options.url = this.buildServiceUrl(false, options);
this.init(options);
}
initLive(options) {
options.url = this.buildServiceUrl(true, options);
this.init(options);
}
initialised = false;
connected = false;
error = false;
disconnected = false;
webSocket;
reset() {
this.initialised = false;
this.connected = false;
this.error = false;
this.disconnected = false;
if (this.webSocket != null) {
this.webSocket.onclose = null;
this.webSocket.close();
}
}
connect() {
this.reset();
try {
this.webSocket = new WebSocket(this.socketUrl);
this.webSocket.onopen = this.onWebSocketOpen.bind(this);
this.webSocket.onclose = this.onWebSocketClose.bind(this);
this.webSocket.onerror = this.onWebSocketError.bind(this);
this.webSocket.onmessage = this.onWebSocketMessage.bind(this);
} catch (e) {
this.log(e.message);
}
}
disconnect() {
if (this.webSocket && this.connected) {
this.disconnected = true;
this.webSocket.close();
}
}
onWebSocketOpen(ev) {
this.log('WebSocket onOpen');
if (this.options.onOpen) {
this.options.onOpen(ev);
}
this.connected = true;
}
onWebSocketClose(ev) {
this.log('WebSocket onClose');
if (this.options.onClose) {
this.options.onClose(ev);
}
this.connected = false;
// Attemp a re-connection if not in error state or deliberately disconnected.
if (!this.error && !this.disconnected) {
this.connect();
}
}
onWebSocketError(ev) {
this.log('WebSocket onError: Sorry, but there is some problem with your socket or the server is down');
if (this.options.onError) {
this.options.onError(ev);
}
// Reset the socketUrl to the original.
this.socketUrl = this.options.url;
this.error = true;
}
authToken;
onWebSocketMessage(message) {
this.log('WebSocket onMessage: ' + message.data);
var result;
try {
result = JSON.parse(message.data);
} catch (e) {
this.log('An error ocurred while parsing the JSON Data: ' + message + '; Error: ' + e);
return;
}
if (this.options.onMessage) {
this.options.onMessage(result);
}
// Extract any auth token.
if (result['authToken']) {
this.authToken = result['authToken'];
delete result['authToken'];
}
if (result['connectUrl']) {
// Any time a connectUrl is in the response we should update and reconnect.
this.socketUrl = result['connectUrl'];
this.connect();
}
var resultType = result['@class'];
if (resultType === '.AuthenticatedConnectResponse') {
this.handshake(result);
} else if (resultType.match(/Response$/)) {
if (result['requestId']) {
var requestId = result['requestId'];
delete result['requestId'];
if (this.pendingRequests[requestId]) {
this.pendingRequests[requestId](result);
this.pendingRequests[requestId] = null;
}
}
}
}
sessionId;
keepAliveInterval;
handshake(result) {
if (result['nonce']) {
var hmac;
if (this.options.onNonce) {
hmac = this.options.onNonce(result['nonce']);
} else if (this.options.secret) {
var SHA256 = require('nativescript-toolbox/crypto-js/hmac-sha256');
var Base64 = require('nativescript-toolbox/crypto-js/enc-base64');
hmac = Base64.stringify(SHA256(result['nonce'], this.options.secret));
}
var toSend = {
'@class': '.AuthenticatedConnectRequest',
hmac: hmac
} as any;
if (this.authToken) {
toSend.authToken = this.authToken;
}
if (this.sessionId) {
toSend.sessionId = this.sessionId;
}
toSend.platform = 'mobile';
toSend.os =
? 'iOS' : 'ANDROID';
this.webSocketSend(toSend);
} else if (result['sessionId']) {
this.sessionId = result['sessionId'];
this.initialised = true;
if (this.options.onInit) {
this.options.onInit();
}
this.keepAliveInterval = setInterval(this.keepAlive.bind(this), 30000);
}
}
keepAlive() {
if (this.initialised && this.connected) {
this.webSocket.send(' ');
}
}
send(requestType, onResponse) {
this.sendWithData(requestType, {}, onResponse);
}
sendWithData(requestType, json, onResponse?) {
if (!this.initialised) {
if (onResponse) {
onResponse({ error: 'NOT_INITIALISED' });
}
return;
}
// Ensure requestType starts with a dot.
if (requestType.indexOf('.') !== 0) {
requestType = '.' + requestType;
}
json['@class'] = requestType;
json.requestId = (new Date()).getTime() + "_" + (++this.requestCounter);
if (onResponse != null) {
this.pendingRequests[json.requestId] = onResponse;
// Time out handler.
setTimeout((() => {
if (this.pendingRequests[json.requestId]) {
this.pendingRequests[json.requestId]({ error: 'NO_RESPONSE' });
}
}).bind(this), 32000);
}
this.webSocketSend(json);
}
webSocketSend(data) {
if (this.options.onSend) {
this.options.onSend(data);
}
var requestString = JSON.stringify(data);
this.log('WebSocket send: ' + requestString);
this.webSocket.send(requestString);
}
getSocketUrl() {
return this.socketUrl;
}
getSessionId() {
return this.sessionId;
}
getAuthToken() {
return this.authToken;
}
setAuthToken(authToken) {
this.authToken = authToken;
}
isConnected() {
return this.connected;
}
log(message) {
if (this.options.logger) {
this.options.logger(message);
}
}
acceptChallengeRequest(challengeInstanceId, message, onResponse) {
var request = {};
request["challengeInstanceId"] = challengeInstanceId;
request["message"] = message;
this.sendWithData("AcceptChallengeRequest", request, onResponse);
}
accountDetailsRequest(onResponse) {
var request = {};
this.sendWithData("AccountDetailsRequest", request, onResponse);
}
analyticsRequest(data, end, key, start, onResponse) {
var request = {};
request["data"] = data;
request["end"] = end;
request["key"] = key;
request["start"] = start;
this.sendWithData("AnalyticsRequest", request, onResponse);
}
aroundMeLeaderboardRequest(count, friendIds, leaderboardShortCode, social, onResponse) {
var request = {};
request["count"] = count;
request["friendIds"] = friendIds;
request["leaderboardShortCode"] = leaderboardShortCode;
request["social"] = social;
this.sendWithData("AroundMeLeaderboardRequest", request, onResponse);
}
authenticationRequest(password, userName, onResponse) {
var request = {};
request["password"] = password;
request["userName"] = userName;
this.sendWithData("AuthenticationRequest", request, onResponse);
}
buyVirtualGoodsRequest(currencyType, quantity, shortCode, onResponse) {
var request = {};
request["currencyType"] = currencyType;
request["quantity"] = quantity;
request["shortCode"] = shortCode;
this.sendWithData("BuyVirtualGoodsRequest", request, onResponse);
}
changeUserDetailsRequest(displayName, onResponse) {
var request = {};
request["displayName"] = displayName;
this.sendWithData("ChangeUserDetailsRequest", request, onResponse);
}
chatOnChallengeRequest(challengeInstanceId, message, onResponse) {
var request = {};
request["challengeInstanceId"] = challengeInstanceId;
request["message"] = message;
this.sendWithData("ChatOnChallengeRequest", request, onResponse);
}
consumeVirtualGoodRequest(quantity, shortCode, onResponse) {
var request = {};
request["quantity"] = quantity;
request["shortCode"] = shortCode;
this.sendWithData("ConsumeVirtualGoodRequest", request, onResponse);
}
matchmakingRequest(matchShortCode: string, options: {
/** The skill of the player looking for a match */
skill?: number,
/** A JSON Map of any data that will be associated to the pending match */
matchData?: Object,
/** Players will be grouped based on the distinct value passed in here, only players in the same group can be matched together */
matchGroup?: string,
/** The action to take on the already in-flight request for this match. Currently supported actions are: 'cancel’ */
action?: 'cancel',
/** The query that will be applied to the PendingMatch collection */
customQuery?: Object,
/** A JSON Map of any data that will be associated to this user in a pending match */
participantData?: Object
} = {}): Promise<GenericResponse> {
return new Promise((resolve, reject) => {
var request = Object.assign({
matchShortCode: matchShortCode
}, options);
this.sendWithData("MatchmakingRequest", request, (response) => {
resolve(response);
});
})
}
matchDetailsRequest(matchId: string, options: {
/** Adds realtime server details if the match has been created using Cloud Code and it has not been realtime enabled */
realtimeEnabled?: boolean
}): Promise<MatchDetailsResponse> {
return new Promise((resolve, reject) => {
var request = Object.assign({
matchId: matchId
});
this.sendWithData("MatchDetailsRequest", request, (response) => {
resolve(response);
});
})
}
createChallengeRequest(
challengeShortCode: string,
options: ChallengeRequest = {}
): Promise<{ challengeInstanceId: string }> {
var request = Object.assign({
challengeShortCode: challengeShortCode
}, options);
return new Promise((resolve, reject) => {
this.sendWithData("CreateChallengeRequest", request, (response) => {
resolve(response);
});
})
}
declineChallengeRequest(challengeInstanceId, message, onResponse) {
var request = {};
request["challengeInstanceId"] = challengeInstanceId;
request["message"] = message;
this.sendWithData("DeclineChallengeRequest", request, onResponse);
}
deviceAuthenticationRequest(deviceId, deviceModel, deviceName, deviceOS, deviceType, operatingSystem, onResponse) {
var request = {};
request["deviceId"] = deviceId;
request["deviceModel"] = deviceModel;
request["deviceName"] = deviceName;
request["deviceOS"] = deviceOS;
request["deviceType"] = deviceType;
request["operatingSystem"] = operatingSystem;
this.sendWithData("DeviceAuthenticationRequest", request, onResponse);
}
dismissMessageRequest(messageId, onResponse) {
var request = {};
request["messageId"] = messageId;
this.sendWithData("DismissMessageRequest", request, onResponse);
}
endSessionRequest(onResponse) {
var request = {};
this.sendWithData("EndSessionRequest", request, onResponse);
}
facebookConnectRequest(accessToken, code, onResponse) {
var request = {};
request["accessToken"] = accessToken;
request["code"] = code;
this.sendWithData("FacebookConnectRequest", request, onResponse);
}
findChallengeRequest(accessType, count, offset, onResponse) {
var request = {};
request["accessType"] = accessType;
request["count"] = count;
request["offset"] = offset;
this.sendWithData("FindChallengeRequest", request, onResponse);
}
getChallengeRequest(challengeInstanceId, message, onResponse) {
var request = {};
request["challengeInstanceId"] = challengeInstanceId;
request["message"] = message;
this.sendWithData("GetChallengeRequest", request, onResponse);
}
getDownloadableRequest(shortCode, onResponse) {
var request = {};
request["shortCode"] = shortCode;
this.sendWithData("GetDownloadableRequest", request, onResponse);
}
getMessageRequest(messageId, onResponse) {
var request = {};
request["messageId"] = messageId;
this.sendWithData("GetMessageRequest", request, onResponse);
}
getRunningTotalsRequest(friendIds, shortCode, onResponse) {
var request = {};
request["friendIds"] = friendIds;
request["shortCode"] = shortCode;
this.sendWithData("GetRunningTotalsRequest", request, onResponse);
}
getUploadUrlRequest(uploadData, onResponse) {
var request = {};
request["uploadData"] = uploadData;
this.sendWithData("GetUploadUrlRequest", request, onResponse);
}
getUploadedRequest(uploadId, onResponse) {
var request = {};
request["uploadId"] = uploadId;
this.sendWithData("GetUploadedRequest", request, onResponse);
}
googlePlayBuyGoodsRequest(currencyCode, signature, signedData, subUnitPrice, onResponse) {
var request = {};
request["currencyCode"] = currencyCode;
request["signature"] = signature;
request["signedData"] = signedData;
request["subUnitPrice"] = subUnitPrice;
this.sendWithData("GooglePlayBuyGoodsRequest", request, onResponse);
}
iOSBuyGoodsRequest(currencyCode, receipt, sandbox, subUnitPrice, onResponse) {
var request = {};
request["currencyCode"] = currencyCode;
request["receipt"] = receipt;
request["sandbox"] = sandbox;
request["subUnitPrice"] = subUnitPrice;
this.sendWithData("IOSBuyGoodsRequest", request, onResponse);
}
joinChallengeRequest(challengeInstanceId, message, onResponse) {
var request = {};
request["challengeInstanceId"] = challengeInstanceId;
request["message"] = message;
this.sendWithData("JoinChallengeRequest", request, onResponse);
}
leaderboardDataRequest(leaderboardShortCode, entryCount: number, onResponse) {
var request = {};
request["leaderboardShortCode"] = leaderboardShortCode;
request["entryCount"] = entryCount;
this.sendWithData("LeaderboardDataRequest", request, onResponse);
}
leaderboardDataRequestForChallenge(challengeInstanceId, entryCount, friendIds, leaderboardShortCode, offset, social, onResponse) {
var request = {};
request["challengeInstanceId"] = challengeInstanceId;
request["entryCount"] = entryCount;
request["friendIds"] = friendIds;
request["leaderboardShortCode"] = leaderboardShortCode;
request["offset"] = offset;
request["social"] = social;
this.sendWithData("LeaderboardDataRequest", request, onResponse);
}
listAchievementsRequest(onResponse) {
var request = {};
this.sendWithData("ListAchievementsRequest", request, onResponse);
}
listChallengeRequest(entryCount, offset, shortCode, state, onResponse) {
var request = {};
request["entryCount"] = entryCount;
request["offset"] = offset;
request["shortCode"] = shortCode;
request["state"] = state;
this.sendWithData("ListChallengeRequest", request, onResponse);
}
listChallengeTypeRequest(onResponse) {
var request = {};
this.sendWithData("ListChallengeTypeRequest", request, onResponse);
}
listGameFriendsRequest(onResponse) {
var request = {};
this.sendWithData("ListGameFriendsRequest", request, onResponse);
}
listInviteFriendsRequest(onResponse) {
var request = {};
this.sendWithData("ListInviteFriendsRequest", request, onResponse);
}
listLeaderboardsRequest(onResponse) {
var request = {};
this.sendWithData("ListLeaderboardsRequest", request, onResponse);
}
listMessageRequest(entryCount, offset, onResponse) {
var request = {};
request["entryCount"] = entryCount;
request["offset"] = offset;
this.sendWithData("ListMessageRequest", request, onResponse);
}
listMessageSummaryRequest(entryCount, offset, onResponse) {
var request = {};
request["entryCount"] = entryCount;
request["offset"] = offset;
this.sendWithData("ListMessageSummaryRequest", request, onResponse);
}
listVirtualGoodsRequest(onResponse) {
var request = {};
this.sendWithData("ListVirtualGoodsRequest", request, onResponse);
}
logChallengeEventRequest(challengeInstanceId, eventKey, onResponse) {
var request = {};
request["challengeInstanceId"] = challengeInstanceId;
request["eventKey"] = eventKey;
this.sendWithData("LogChallengeEventRequest", request, onResponse);
}
logEventRequest(eventKey: string, eventData: any = {}): Promise<any> {
var request = Object.assign({
eventKey: eventKey
}, eventData);
return new Promise((resolve, reject) => {
this.sendWithData("LogEventRequest", request, (response) => {
resolve(response);
});
})
}
pushRegistrationRequest(deviceOS, pushId, onResponse) {
var request = {};
request["deviceOS"] = deviceOS;
request["pushId"] = pushId;
this.sendWithData("PushRegistrationRequest", request, onResponse);
}
registrationRequest(displayName, password, userName, onResponse) {
var request = {};
request["displayName"] = displayName;
request["password"] = password;
request["userName"] = userName;
this.sendWithData("RegistrationRequest", request, onResponse);
}
sendFriendMessageRequest(friendIds, message, onResponse) {
var request = {};
request["friendIds"] = friendIds;
request["message"] = message;
this.sendWithData("SendFriendMessageRequest", request, onResponse);
}
socialLeaderboardDataRequest(challengeInstanceId, entryCount, friendIds, leaderboardShortCode, offset, social, onResponse) {
var request = {};
request["challengeInstanceId"] = challengeInstanceId;
request["entryCount"] = entryCount;
request["friendIds"] = friendIds;
request["leaderboardShortCode"] = leaderboardShortCode;
request["offset"] = offset;
request["social"] = social;
this.sendWithData("SocialLeaderboardDataRequest", request, onResponse);
}
twitterConnectRequest(accessSecret, accessToken, onResponse) {
var request = {};
request["accessSecret"] = accessSecret;
request["accessToken"] = accessToken;
this.sendWithData("TwitterConnectRequest", request, onResponse);
}
windowsBuyGoodsRequest(currencyCode, receipt, subUnitPrice, onResponse) {
var request = {};
request["currencyCode"] = currencyCode;
request["receipt"] = receipt;
request["subUnitPrice"] = subUnitPrice;
this.sendWithData("WindowsBuyGoodsRequest", request, onResponse);
}
withdrawChallengeRequest(challengeInstanceId, message, onResponse) {
var request = {};
request["challengeInstanceId"] = challengeInstanceId;
request["message"] = message;
this.sendWithData("WithdrawChallengeRequest", request, onResponse);
}
}
@muratcorlu
Copy link
Author

My main purpose for these was using GameSparks services with NativeScript. To use Websockets and CryptoJS in NativeScript, you'll need to add nativescript-websockets and nativescript-toolbox.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment