Attempt to using Nakama as replacement of Low-Level ENet

This commit is contained in:
2025-12-02 00:58:44 +08:00
parent b27b612989
commit ead155afed
74 changed files with 14205 additions and 23315 deletions
+61
View File
@@ -0,0 +1,61 @@
@tool
extends Node
# The default host address of the server.
const DEFAULT_HOST : String = "127.0.0.1"
# The default port number of the server.
const DEFAULT_PORT : int = 7350
# The default timeout for the connections.
const DEFAULT_TIMEOUT = 3
# The default protocol scheme for the client connection.
const DEFAULT_CLIENT_SCHEME : String = "http"
# The default protocol scheme for the socket connection.
const DEFAULT_SOCKET_SCHEME : String = "ws"
# The default log level for the Nakama logger.
const DEFAULT_LOG_LEVEL = NakamaLogger.LOG_LEVEL.DEBUG
var _http_adapter = null
var logger = NakamaLogger.new()
func _ready() -> void:
process_mode = Node.PROCESS_MODE_ALWAYS
func get_client_adapter() -> NakamaHTTPAdapter:
if _http_adapter == null:
_http_adapter = NakamaHTTPAdapter.new()
_http_adapter.logger = logger
_http_adapter.name = "NakamaHTTPAdapter"
add_child(_http_adapter)
return _http_adapter
func create_socket_adapter() -> NakamaSocketAdapter:
var adapter = NakamaSocketAdapter.new()
adapter.name = "NakamaWebSocketAdapter"
adapter.logger = logger
add_child(adapter)
return adapter
func create_client(p_server_key : String,
p_host : String = DEFAULT_HOST,
p_port : int = DEFAULT_PORT,
p_scheme : String = DEFAULT_CLIENT_SCHEME,
p_timeout : int = DEFAULT_TIMEOUT,
p_log_level : int = DEFAULT_LOG_LEVEL) -> NakamaClient:
logger._level = p_log_level
return NakamaClient.new(get_client_adapter(), p_server_key, p_scheme, p_host, p_port, p_timeout)
func create_socket(p_host : String = DEFAULT_HOST,
p_port : int = DEFAULT_PORT,
p_scheme : String = DEFAULT_SOCKET_SCHEME) -> NakamaSocket:
return NakamaSocket.new(create_socket_adapter(), p_host, p_port, p_scheme, true)
func create_socket_from(p_client : NakamaClient) -> NakamaSocket:
var scheme = "ws"
if p_client.scheme == "https":
scheme = "wss"
return NakamaSocket.new(create_socket_adapter(), p_client.host, p_client.port, scheme, true)
@@ -0,0 +1 @@
uid://bueyqhhvxe0tx
+41
View File
@@ -0,0 +1,41 @@
@tool
extends Node
# The default host address of the server.
const DEFAULT_HOST : String = "127.0.0.1"
# The default port number of the server.
const DEFAULT_PORT : int = 7450
# The default timeout for the connections.
const DEFAULT_TIMEOUT = 15
# The default protocol scheme for the client connection.
const DEFAULT_CLIENT_SCHEME : String = "http"
# The default log level for the Satori logger.
const DEFAULT_LOG_LEVEL = SatoriLogger.LOG_LEVEL.DEBUG
var _http_adapter = null
var logger = SatoriLogger.new()
func _ready() -> void:
process_mode = Node.PROCESS_MODE_ALWAYS
func get_client_adapter() -> SatoriHTTPAdapter:
if _http_adapter == null:
_http_adapter = SatoriHTTPAdapter.new()
_http_adapter.logger = logger
_http_adapter.name = "SatoriHTTPAdapter"
add_child(_http_adapter)
return _http_adapter
func create_client(p_api_key : String,
p_host : String = DEFAULT_HOST,
p_port : int = DEFAULT_PORT,
p_scheme : String = DEFAULT_CLIENT_SCHEME,
p_timeout : int = DEFAULT_TIMEOUT,
p_log_level : int = DEFAULT_LOG_LEVEL,
) -> SatoriClient:
logger._level = p_log_level
return SatoriClient.new(get_client_adapter(), p_api_key, p_scheme, p_host, p_port, p_timeout)
@@ -0,0 +1 @@
uid://b8vev00s34b7
@@ -0,0 +1,65 @@
extends SatoriAsyncResult
class_name Event
# The name of the event.
var name: String
# The time when the event was triggered.
var timestamp: String
# Optional value.
var value: String
# Event metadata, if any.
var metadata: Dictionary
# Optional event ID assigned by the client, used to de-duplicate in retransmission scenarios.
# If not supplied the server will assign a randomly generated unique event identifier.
var id: String
# The event constructor.
# Initializes a new Event object.
#
# @param name The name of the event.
# @param timestamp The timestamp of the event.
# @param value The value associated with the event (optional).
# @param metadata The metadata associated with the event (optional).
# @param id The ID of the event (optional).
func _init(name: String, timestamp: float, value: String = "", metadata: Dictionary = {}, id: String = "", p_exception = null):
super(p_exception)
self.name = name
self.timestamp = unix_to_protobuf_timestamp_format(timestamp)
self.value = value
self.metadata = metadata
self.id = id
func to_api_event_dict() -> Dictionary:
return {
"name": self.name,
"timestamp": self.timestamp,
"value": self.value,
"metadata": self.metadata,
"id": self.id
}
func unix_to_protobuf_timestamp_format(unix_time: float) -> String:
# Extract microseconds precision from unix time
var microseconds = int(fmod(unix_time, 1.0) * 1_000_000)
# Convert seconds to datetime structure
var datetime = Time.get_datetime_dict_from_unix_time(int(unix_time))
var year = datetime.year
var month = str(datetime.month).pad_zeros(2)
var day = str(datetime.day).pad_zeros(2)
var hour = str(datetime.hour).pad_zeros(2)
var minute = str(datetime.minute).pad_zeros(2)
var second = str(datetime.second).pad_zeros(2)
var microsecond = str(microseconds).pad_zeros(6)
# Construct the protobuf timestamp format string
var timestamp_str = "%s-%s-%sT%s:%s:%s.%sZ" % [year, month, day, hour, minute, second, microsecond]
return timestamp_str
@@ -0,0 +1 @@
uid://ccldwb3ljqre2
@@ -0,0 +1,1396 @@
### Code generated by codegen/main.go. DO NOT EDIT. ###
extends RefCounted
class_name SatoriAPI
# Log out a session, invalidate a refresh token, or log out all sessions/refresh tokens for a user.
class ApiAuthenticateLogoutRequest extends SatoriAsyncResult:
const _SCHEMA = {
"refresh_token": {"name": "_refresh_token", "type": TYPE_STRING, "required": false},
"token": {"name": "_token", "type": TYPE_STRING, "required": false},
}
# Refresh token to invalidate.
var _refresh_token
var refresh_token : String:
get:
return "" if not _refresh_token is String else String(_refresh_token)
# Session token to log out.
var _token
var token : String:
get:
return "" if not _token is String else String(_token)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAuthenticateLogoutRequest:
return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiAuthenticateLogoutRequest", p_dict), ApiAuthenticateLogoutRequest) as ApiAuthenticateLogoutRequest
func serialize() -> Dictionary:
return SatoriSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
var map_string : String = ""
output += "refresh_token: %s, " % _refresh_token
output += "token: %s, " % _token
output += map_string
return output
# Authenticate against the server with a refresh token.
class ApiAuthenticateRefreshRequest extends SatoriAsyncResult:
const _SCHEMA = {
"refresh_token": {"name": "_refresh_token", "type": TYPE_STRING, "required": false},
}
# Refresh token.
var _refresh_token
var refresh_token : String:
get:
return "" if not _refresh_token is String else String(_refresh_token)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAuthenticateRefreshRequest:
return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiAuthenticateRefreshRequest", p_dict), ApiAuthenticateRefreshRequest) as ApiAuthenticateRefreshRequest
func serialize() -> Dictionary:
return SatoriSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
var map_string : String = ""
output += "refresh_token: %s, " % _refresh_token
output += map_string
return output
#
class ApiAuthenticateRequest extends SatoriAsyncResult:
const _SCHEMA = {
"custom": {"name": "_custom", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
"default": {"name": "_default", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
"id": {"name": "_id", "type": TYPE_STRING, "required": false},
}
# Optional custom properties to update with this call.
# If not set, properties are left as they are on the server.
var _custom
var custom : Dictionary:
get:
return Dictionary() if not _custom is Dictionary else _custom.duplicate()
# Optional default properties to update with this call.
# If not set, properties are left as they are on the server.
var _default
var default : Dictionary:
get:
return Dictionary() if not _default is Dictionary else _default.duplicate()
# Identity ID. Must be between eight and 128 characters (inclusive).
# Must be an alphanumeric string with only underscores and hyphens allowed.
var _id
var id : String:
get:
return "" if not _id is String else String(_id)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAuthenticateRequest:
return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiAuthenticateRequest", p_dict), ApiAuthenticateRequest) as ApiAuthenticateRequest
func serialize() -> Dictionary:
return SatoriSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
var map_string : String = ""
if typeof(_custom) == TYPE_DICTIONARY:
for k in _custom:
map_string += "{%s=%s}, " % [k, _custom[k]]
output += "custom: [%s], " % map_string
map_string = ""
if typeof(_default) == TYPE_DICTIONARY:
for k in _default:
map_string += "{%s=%s}, " % [k, _default[k]]
output += "default: [%s], " % map_string
map_string = ""
output += "id: %s, " % _id
output += map_string
return output
# A single event. Usually, but not necessarily, part of a batch.
class ApiEvent extends SatoriAsyncResult:
const _SCHEMA = {
"id": {"name": "_id", "type": TYPE_STRING, "required": false},
"metadata": {"name": "_metadata", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
"name": {"name": "_name", "type": TYPE_STRING, "required": false},
"timestamp": {"name": "_timestamp", "type": TYPE_STRING, "required": false},
"value": {"name": "_value", "type": TYPE_STRING, "required": false},
}
# Optional event ID assigned by the client, used to de-duplicate in retransmission scenarios.
# If not supplied the server will assign a randomly generated unique event identifier.
var _id
var id : String:
get:
return "" if not _id is String else String(_id)
# Event metadata, if any.
var _metadata
var metadata : Dictionary:
get:
return Dictionary() if not _metadata is Dictionary else _metadata.duplicate()
# Event name.
var _name
var name : String:
get:
return "" if not _name is String else String(_name)
# The time when the event was triggered on the producer side.
var _timestamp
var timestamp : String:
get:
return "" if not _timestamp is String else String(_timestamp)
# Optional value.
var _value
var value : String:
get:
return "" if not _value is String else String(_value)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiEvent:
return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiEvent", p_dict), ApiEvent) as ApiEvent
func serialize() -> Dictionary:
return SatoriSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
var map_string : String = ""
output += "id: %s, " % _id
if typeof(_metadata) == TYPE_DICTIONARY:
for k in _metadata:
map_string += "{%s=%s}, " % [k, _metadata[k]]
output += "metadata: [%s], " % map_string
map_string = ""
output += "name: %s, " % _name
output += "timestamp: %s, " % _timestamp
output += "value: %s, " % _value
output += map_string
return output
#
class ApiEventRequest extends SatoriAsyncResult:
const _SCHEMA = {
"events": {"name": "_events", "type": TYPE_ARRAY, "required": false, "content": TYPE_DICTIONARY},
}
# Some number of events produced by a client.
var _events
var events : Array:
get:
return Array() if not _events is Array else Array(_events)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiEventRequest:
return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiEventRequest", p_dict), ApiEventRequest) as ApiEventRequest
func serialize() -> Dictionary:
return SatoriSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
var map_string : String = ""
output += "events: %s, " % [_events]
output += map_string
return output
# An experiment that this user is partaking.
class ApiExperiment extends SatoriAsyncResult:
const _SCHEMA = {
"name": {"name": "_name", "type": TYPE_STRING, "required": false},
"value": {"name": "_value", "type": TYPE_STRING, "required": false},
}
#
var _name
var name : String:
get:
return "" if not _name is String else String(_name)
# Value associated with this Experiment.
var _value
var value : String:
get:
return "" if not _value is String else String(_value)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiExperiment:
return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiExperiment", p_dict), ApiExperiment) as ApiExperiment
func serialize() -> Dictionary:
return SatoriSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
var map_string : String = ""
output += "name: %s, " % _name
output += "value: %s, " % _value
output += map_string
return output
# All experiments that this identity is involved with.
class ApiExperimentList extends SatoriAsyncResult:
const _SCHEMA = {
"experiments": {"name": "_experiments", "type": TYPE_ARRAY, "required": false, "content": TYPE_DICTIONARY},
}
# All experiments for this identity.
var _experiments
var experiments : Array:
get:
return Array() if not _experiments is Array else Array(_experiments)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiExperimentList:
return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiExperimentList", p_dict), ApiExperimentList) as ApiExperimentList
func serialize() -> Dictionary:
return SatoriSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
var map_string : String = ""
output += "experiments: %s, " % [_experiments]
output += map_string
return output
# Feature flag available to the identity.
class ApiFlag extends SatoriAsyncResult:
const _SCHEMA = {
"condition_changed": {"name": "_condition_changed", "type": TYPE_BOOL, "required": false},
"name": {"name": "_name", "type": TYPE_STRING, "required": false},
"value": {"name": "_value", "type": TYPE_STRING, "required": false},
}
# Whether the value for this flag has conditionally changed from the default state.
var _condition_changed
var condition_changed : bool:
get:
return false if not _condition_changed is bool else bool(_condition_changed)
#
var _name
var name : String:
get:
return "" if not _name is String else String(_name)
# Value associated with this flag.
var _value
var value : String:
get:
return "" if not _value is String else String(_value)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiFlag:
return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiFlag", p_dict), ApiFlag) as ApiFlag
func serialize() -> Dictionary:
return SatoriSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
var map_string : String = ""
output += "condition_changed: %s, " % _condition_changed
output += "name: %s, " % _name
output += "value: %s, " % _value
output += map_string
return output
#
class ApiFlagList extends SatoriAsyncResult:
const _SCHEMA = {
"flags": {"name": "_flags", "type": TYPE_ARRAY, "required": false, "content": TYPE_DICTIONARY},
}
#
var _flags
var flags : Array:
get:
return Array() if not _flags is Array else Array(_flags)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiFlagList:
return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiFlagList", p_dict), ApiFlagList) as ApiFlagList
func serialize() -> Dictionary:
return SatoriSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
var map_string : String = ""
output += "flags: %s, " % [_flags]
output += map_string
return output
# A response containing all the messages for an identity.
class ApiGetMessageListResponse extends SatoriAsyncResult:
const _SCHEMA = {
"cacheable_cursor": {"name": "_cacheable_cursor", "type": TYPE_STRING, "required": false},
"messages": {"name": "_messages", "type": TYPE_ARRAY, "required": false, "content": TYPE_DICTIONARY},
"next_cursor": {"name": "_next_cursor", "type": TYPE_STRING, "required": false},
"prev_cursor": {"name": "_prev_cursor", "type": TYPE_STRING, "required": false},
}
# Cacheable cursor to list newer messages. Durable and designed to be stored, unlike next/prev cursors.
var _cacheable_cursor
var cacheable_cursor : String:
get:
return "" if not _cacheable_cursor is String else String(_cacheable_cursor)
# The list of messages.
var _messages
var messages : Array:
get:
return Array() if not _messages is Array else Array(_messages)
# The cursor to send when retrieving the next page, if any.
var _next_cursor
var next_cursor : String:
get:
return "" if not _next_cursor is String else String(_next_cursor)
# The cursor to send when retrieving the previous page, if any.
var _prev_cursor
var prev_cursor : String:
get:
return "" if not _prev_cursor is String else String(_prev_cursor)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiGetMessageListResponse:
return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiGetMessageListResponse", p_dict), ApiGetMessageListResponse) as ApiGetMessageListResponse
func serialize() -> Dictionary:
return SatoriSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
var map_string : String = ""
output += "cacheable_cursor: %s, " % _cacheable_cursor
output += "messages: %s, " % [_messages]
output += "next_cursor: %s, " % _next_cursor
output += "prev_cursor: %s, " % _prev_cursor
output += map_string
return output
# Enrich/replace the current session with a new ID.
class ApiIdentifyRequest extends SatoriAsyncResult:
const _SCHEMA = {
"custom": {"name": "_custom", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
"default": {"name": "_default", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
"id": {"name": "_id", "type": TYPE_STRING, "required": false},
}
# Optional custom properties to update with this call.
# If not set, properties are left as they are on the server.
var _custom
var custom : Dictionary:
get:
return Dictionary() if not _custom is Dictionary else _custom.duplicate()
# Optional default properties to update with this call.
# If not set, properties are left as they are on the server.
var _default
var default : Dictionary:
get:
return Dictionary() if not _default is Dictionary else _default.duplicate()
# Identity ID to enrich the current session and return a new session. Old session will no longer be usable.
var _id
var id : String:
get:
return "" if not _id is String else String(_id)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiIdentifyRequest:
return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiIdentifyRequest", p_dict), ApiIdentifyRequest) as ApiIdentifyRequest
func serialize() -> Dictionary:
return SatoriSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
var map_string : String = ""
if typeof(_custom) == TYPE_DICTIONARY:
for k in _custom:
map_string += "{%s=%s}, " % [k, _custom[k]]
output += "custom: [%s], " % map_string
map_string = ""
if typeof(_default) == TYPE_DICTIONARY:
for k in _default:
map_string += "{%s=%s}, " % [k, _default[k]]
output += "default: [%s], " % map_string
map_string = ""
output += "id: %s, " % _id
output += map_string
return output
# A single live event.
class ApiLiveEvent extends SatoriAsyncResult:
const _SCHEMA = {
"active_end_time_sec": {"name": "_active_end_time_sec", "type": TYPE_STRING, "required": false},
"active_start_time_sec": {"name": "_active_start_time_sec", "type": TYPE_STRING, "required": false},
"description": {"name": "_description", "type": TYPE_STRING, "required": false},
"id": {"name": "_id", "type": TYPE_STRING, "required": false},
"name": {"name": "_name", "type": TYPE_STRING, "required": false},
"value": {"name": "_value", "type": TYPE_STRING, "required": false},
}
# End time of current event run.
var _active_end_time_sec
var active_end_time_sec : String:
get:
return "" if not _active_end_time_sec is String else String(_active_end_time_sec)
# Start time of current event run.
var _active_start_time_sec
var active_start_time_sec : String:
get:
return "" if not _active_start_time_sec is String else String(_active_start_time_sec)
# Description.
var _description
var description : String:
get:
return "" if not _description is String else String(_description)
# The live event identifier.
var _id
var id : String:
get:
return "" if not _id is String else String(_id)
# Name.
var _name
var name : String:
get:
return "" if not _name is String else String(_name)
# Event value.
var _value
var value : String:
get:
return "" if not _value is String else String(_value)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiLiveEvent:
return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiLiveEvent", p_dict), ApiLiveEvent) as ApiLiveEvent
func serialize() -> Dictionary:
return SatoriSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
var map_string : String = ""
output += "active_end_time_sec: %s, " % _active_end_time_sec
output += "active_start_time_sec: %s, " % _active_start_time_sec
output += "description: %s, " % _description
output += "id: %s, " % _id
output += "name: %s, " % _name
output += "value: %s, " % _value
output += map_string
return output
# List of Live events.
class ApiLiveEventList extends SatoriAsyncResult:
const _SCHEMA = {
"live_events": {"name": "_live_events", "type": TYPE_ARRAY, "required": false, "content": TYPE_DICTIONARY},
}
# Live events.
var _live_events
var live_events : Array:
get:
return Array() if not _live_events is Array else Array(_live_events)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiLiveEventList:
return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiLiveEventList", p_dict), ApiLiveEventList) as ApiLiveEventList
func serialize() -> Dictionary:
return SatoriSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
var map_string : String = ""
output += "live_events: %s, " % [_live_events]
output += map_string
return output
# A scheduled message.
class ApiMessage extends SatoriAsyncResult:
const _SCHEMA = {
"consume_time": {"name": "_consume_time", "type": TYPE_STRING, "required": false},
"create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false},
"metadata": {"name": "_metadata", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
"read_time": {"name": "_read_time", "type": TYPE_STRING, "required": false},
"schedule_id": {"name": "_schedule_id", "type": TYPE_STRING, "required": false},
"send_time": {"name": "_send_time", "type": TYPE_STRING, "required": false},
"text": {"name": "_text", "type": TYPE_STRING, "required": false},
"update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false},
}
# The time the message was consumed by the identity.
var _consume_time
var consume_time : String:
get:
return "" if not _consume_time is String else String(_consume_time)
# The time the message was created.
var _create_time
var create_time : String:
get:
return "" if not _create_time is String else String(_create_time)
# A key-value pairs of metadata.
var _metadata
var metadata : Dictionary:
get:
return Dictionary() if not _metadata is Dictionary else _metadata.duplicate()
# The time the message was read by the client.
var _read_time
var read_time : String:
get:
return "" if not _read_time is String else String(_read_time)
# The identifier of the schedule.
var _schedule_id
var schedule_id : String:
get:
return "" if not _schedule_id is String else String(_schedule_id)
# The send time for the message.
var _send_time
var send_time : String:
get:
return "" if not _send_time is String else String(_send_time)
# The message's text.
var _text
var text : String:
get:
return "" if not _text is String else String(_text)
# The time the message was updated.
var _update_time
var update_time : String:
get:
return "" if not _update_time is String else String(_update_time)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiMessage:
return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiMessage", p_dict), ApiMessage) as ApiMessage
func serialize() -> Dictionary:
return SatoriSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
var map_string : String = ""
output += "consume_time: %s, " % _consume_time
output += "create_time: %s, " % _create_time
if typeof(_metadata) == TYPE_DICTIONARY:
for k in _metadata:
map_string += "{%s=%s}, " % [k, _metadata[k]]
output += "metadata: [%s], " % map_string
map_string = ""
output += "read_time: %s, " % _read_time
output += "schedule_id: %s, " % _schedule_id
output += "send_time: %s, " % _send_time
output += "text: %s, " % _text
output += "update_time: %s, " % _update_time
output += map_string
return output
# Properties associated with an identity.
class ApiProperties extends SatoriAsyncResult:
const _SCHEMA = {
"computed": {"name": "_computed", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
"custom": {"name": "_custom", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
"default": {"name": "_default", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
}
# Event computed properties.
var _computed
var computed : Dictionary:
get:
return Dictionary() if not _computed is Dictionary else _computed.duplicate()
# Event custom properties.
var _custom
var custom : Dictionary:
get:
return Dictionary() if not _custom is Dictionary else _custom.duplicate()
# Event default properties.
var _default
var default : Dictionary:
get:
return Dictionary() if not _default is Dictionary else _default.duplicate()
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiProperties:
return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiProperties", p_dict), ApiProperties) as ApiProperties
func serialize() -> Dictionary:
return SatoriSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
var map_string : String = ""
if typeof(_computed) == TYPE_DICTIONARY:
for k in _computed:
map_string += "{%s=%s}, " % [k, _computed[k]]
output += "computed: [%s], " % map_string
map_string = ""
if typeof(_custom) == TYPE_DICTIONARY:
for k in _custom:
map_string += "{%s=%s}, " % [k, _custom[k]]
output += "custom: [%s], " % map_string
map_string = ""
if typeof(_default) == TYPE_DICTIONARY:
for k in _default:
map_string += "{%s=%s}, " % [k, _default[k]]
output += "default: [%s], " % map_string
map_string = ""
output += map_string
return output
# A session.
class ApiSession extends SatoriAsyncResult:
const _SCHEMA = {
"properties": {"name": "_properties", "type": "ApiProperties", "required": false},
"refresh_token": {"name": "_refresh_token", "type": TYPE_STRING, "required": false},
"token": {"name": "_token", "type": TYPE_STRING, "required": false},
}
# Properties associated with this identity.
var _properties
var properties : ApiProperties:
get:
return _properties as ApiProperties
# Refresh token.
var _refresh_token
var refresh_token : String:
get:
return "" if not _refresh_token is String else String(_refresh_token)
# Token credential.
var _token
var token : String:
get:
return "" if not _token is String else String(_token)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiSession:
return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiSession", p_dict), ApiSession) as ApiSession
func serialize() -> Dictionary:
return SatoriSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
var map_string : String = ""
output += "properties: %s, " % _properties
output += "refresh_token: %s, " % _refresh_token
output += "token: %s, " % _token
output += map_string
return output
# Update Properties associated with this identity.
class ApiUpdatePropertiesRequest extends SatoriAsyncResult:
const _SCHEMA = {
"custom": {"name": "_custom", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
"default": {"name": "_default", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
"recompute": {"name": "_recompute", "type": TYPE_BOOL, "required": false},
}
# Event custom properties.
var _custom
var custom : Dictionary:
get:
return Dictionary() if not _custom is Dictionary else _custom.duplicate()
# Event default properties.
var _default
var default : Dictionary:
get:
return Dictionary() if not _default is Dictionary else _default.duplicate()
# Informs the server to recompute the audience membership of the identity.
var _recompute
var recompute : bool:
get:
return false if not _recompute is bool else bool(_recompute)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiUpdatePropertiesRequest:
return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiUpdatePropertiesRequest", p_dict), ApiUpdatePropertiesRequest) as ApiUpdatePropertiesRequest
func serialize() -> Dictionary:
return SatoriSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
var map_string : String = ""
if typeof(_custom) == TYPE_DICTIONARY:
for k in _custom:
map_string += "{%s=%s}, " % [k, _custom[k]]
output += "custom: [%s], " % map_string
map_string = ""
if typeof(_default) == TYPE_DICTIONARY:
for k in _default:
map_string += "{%s=%s}, " % [k, _default[k]]
output += "default: [%s], " % map_string
map_string = ""
output += "recompute: %s, " % _recompute
output += map_string
return output
#
class ProtobufAny extends SatoriAsyncResult:
const _SCHEMA = {
"type": {"name": "_type", "type": TYPE_STRING, "required": false},
}
#
var _type
var type : String:
get:
return "" if not _type is String else String(_type)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ProtobufAny:
return _safe_ret(SatoriSerializer.deserialize(p_ns, "ProtobufAny", p_dict), ProtobufAny) as ProtobufAny
func serialize() -> Dictionary:
return SatoriSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
var map_string : String = ""
output += "type: %s, " % _type
output += map_string
return output
#
class RpcStatus extends SatoriAsyncResult:
const _SCHEMA = {
"code": {"name": "_code", "type": TYPE_INT, "required": false},
"details": {"name": "_details", "type": TYPE_ARRAY, "required": false, "content": TYPE_DICTIONARY},
"message": {"name": "_message", "type": TYPE_STRING, "required": false},
}
#
var _code
var code : int:
get:
return 0 if not _code is int else int(_code)
#
var _details
var details : Array:
get:
return Array() if not _details is Array else Array(_details)
#
var _message
var message : String:
get:
return "" if not _message is String else String(_message)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> RpcStatus:
return _safe_ret(SatoriSerializer.deserialize(p_ns, "RpcStatus", p_dict), RpcStatus) as RpcStatus
func serialize() -> Dictionary:
return SatoriSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
var map_string : String = ""
output += "code: %s, " % _code
output += "details: %s, " % [_details]
output += "message: %s, " % _message
output += map_string
return output
# The low level client for the Satori API.
class ApiClient extends RefCounted:
var _base_uri : String
var _http_adapter
var _namespace : GDScript
var _server_key : String
var auto_refresh := true
var auto_refresh_time := 300
var auto_retry : bool:
set(p_value):
_http_adapter.auto_retry = p_value
get:
return _http_adapter.auto_retry
var auto_retry_count : int:
set(p_value):
_http_adapter.auto_retry_count = p_value
get:
return _http_adapter.auto_retry_count
var auto_retry_backoff_base : int:
set(p_value):
_http_adapter.auto_retry_backoff_base = p_value
get:
return _http_adapter.auto_retry_backoff_base
var last_cancel_token:
get:
return _http_adapter.get_last_token()
func _init(p_base_uri : String, p_http_adapter, p_namespace : GDScript, p_server_key : String, p_timeout : int = 10):
_base_uri = p_base_uri
_http_adapter = p_http_adapter
_http_adapter.timeout = p_timeout
_namespace = p_namespace
_server_key = p_server_key
func _refresh_session(p_session : SatoriSession):
if auto_refresh and p_session.is_valid() and p_session.refresh_token and not p_session.is_refresh_expired() and p_session.would_expire_in(auto_refresh_time):
var request = ApiAuthenticateRefreshRequest.new()
request._token = p_session.refresh_token
return await authenticate_refresh_async(_server_key, "", request)
return null
func cancel_request(p_token):
if p_token:
_http_adapter.cancel_request(p_token)
# A healthcheck which load balancers can use to check the service.
func healthcheck_async(
p_session : SatoriSession
) -> SatoriAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return SatoriAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/healthcheck"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray = PackedByteArray()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is SatoriException:
return SatoriAsyncResult.new(result)
return SatoriAsyncResult.new()
# A readycheck which load balancers can use to check the service.
func readycheck_async(
p_session : SatoriSession
) -> SatoriAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return SatoriAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/readycheck"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray = PackedByteArray()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is SatoriException:
return SatoriAsyncResult.new(result)
return SatoriAsyncResult.new()
# Authenticate against the server.
func authenticate_async(
p_basic_auth_username : String
, p_basic_auth_password : String
, p_body : ApiAuthenticateRequest
) -> ApiSession:
var urlpath : String = "/v1/authenticate"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password)
var header = "Basic %s" % credentials
headers["Authorization"] = header
var content : PackedByteArray = PackedByteArray()
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is SatoriException:
return ApiSession.new(result)
var out : ApiSession = SatoriSerializer.deserialize(_namespace, "ApiSession", result)
return out
# Log out a session, invalidate a refresh token, or log out all sessions/refresh tokens for a user.
func authenticate_logout_async(
p_session : SatoriSession
, p_body : ApiAuthenticateLogoutRequest
) -> SatoriAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return SatoriAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v1/authenticate/logout"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray = PackedByteArray()
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is SatoriException:
return SatoriAsyncResult.new(result)
return SatoriAsyncResult.new()
# Refresh a user's session using a refresh token retrieved from a previous authentication request.
func authenticate_refresh_async(
p_basic_auth_username : String
, p_basic_auth_password : String
, p_body : ApiAuthenticateRefreshRequest
) -> ApiSession:
var urlpath : String = "/v1/authenticate/refresh"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password)
var header = "Basic %s" % credentials
headers["Authorization"] = header
var content : PackedByteArray = PackedByteArray()
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is SatoriException:
return ApiSession.new(result)
var out : ApiSession = SatoriSerializer.deserialize(_namespace, "ApiSession", result)
return out
# Publish an event for this session.
func event_async(
p_session : SatoriSession
, p_body : ApiEventRequest
) -> SatoriAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return SatoriAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v1/event"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray = PackedByteArray()
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is SatoriException:
return SatoriAsyncResult.new(result)
return SatoriAsyncResult.new()
# Get or list all available experiments for this identity.
func get_experiments_async(
p_session : SatoriSession
, p_names = null # : array
) -> ApiExperimentList:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiExperimentList.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v1/experiment"
var query_params = ""
if p_names != null:
for elem in p_names:
query_params += "names=%s&" % elem
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray = PackedByteArray()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is SatoriException:
return ApiExperimentList.new(result)
var out : ApiExperimentList = SatoriSerializer.deserialize(_namespace, "ApiExperimentList", result)
return out
# List all available flags for this identity.
func get_flags_async(
p_bearer_token : String
, p_names = null # : array
) -> ApiFlagList:
var urlpath : String = "/v1/flag"
var query_params = ""
if p_names != null:
for elem in p_names:
query_params += "names=%s&" % elem
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
if (p_bearer_token):
var header = "Bearer %s" % p_bearer_token
headers["Authorization"] = header
var content : PackedByteArray = PackedByteArray()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is SatoriException:
return ApiFlagList.new(result)
var out : ApiFlagList = SatoriSerializer.deserialize(_namespace, "ApiFlagList", result)
return out
# Enrich/replace the current session with new identifier.
func identify_async(
p_session : SatoriSession
, p_body : ApiIdentifyRequest
) -> ApiSession:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiSession.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v1/identify"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "PUT"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray = PackedByteArray()
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is SatoriException:
return ApiSession.new(result)
var out : ApiSession = SatoriSerializer.deserialize(_namespace, "ApiSession", result)
return out
# Delete the caller's identity and associated data.
func delete_identity_async(
p_session : SatoriSession
) -> SatoriAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return SatoriAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v1/identity"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "DELETE"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray = PackedByteArray()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is SatoriException:
return SatoriAsyncResult.new(result)
return SatoriAsyncResult.new()
# List available live events.
func get_live_events_async(
p_session : SatoriSession
, p_names = null # : array
) -> ApiLiveEventList:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiLiveEventList.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v1/live-event"
var query_params = ""
if p_names != null:
for elem in p_names:
query_params += "names=%s&" % elem
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray = PackedByteArray()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is SatoriException:
return ApiLiveEventList.new(result)
var out : ApiLiveEventList = SatoriSerializer.deserialize(_namespace, "ApiLiveEventList", result)
return out
# Get the list of messages for the identity.
func get_message_list_async(
p_session : SatoriSession
, p_limit = null # : integer
, p_forward = null # : boolean
, p_cursor = null # : string
) -> ApiGetMessageListResponse:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiGetMessageListResponse.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v1/message"
var query_params = ""
if p_limit != null:
query_params += "limit=%d&" % p_limit
if p_forward != null:
query_params += "forward=%s&" % str(bool(p_forward)).to_lower()
if p_cursor != null:
query_params += "cursor=%s&" % SatoriSerializer.escape_http(p_cursor)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray = PackedByteArray()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is SatoriException:
return ApiGetMessageListResponse.new(result)
var out : ApiGetMessageListResponse = SatoriSerializer.deserialize(_namespace, "ApiGetMessageListResponse", result)
return out
# Deletes a message for an identity.
func delete_message_async(
p_session : SatoriSession
, p_id : String
) -> SatoriAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return SatoriAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v1/message/{id}"
urlpath = urlpath.replace("{id}", SatoriSerializer.escape_http(p_id))
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "DELETE"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray = PackedByteArray()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is SatoriException:
return SatoriAsyncResult.new(result)
return SatoriAsyncResult.new()
# Updates a message for an identity.
func update_message_async(
p_session : SatoriSession
, p_id : String
, p_body :
) -> SatoriAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return SatoriAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v1/message/{id}"
urlpath = urlpath.replace("{id}", SatoriSerializer.escape_http(p_id))
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "PUT"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray = PackedByteArray()
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is SatoriException:
return SatoriAsyncResult.new(result)
return SatoriAsyncResult.new()
# List properties associated with this identity.
func list_properties_async(
p_session : SatoriSession
) -> ApiProperties:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiProperties.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v1/properties"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray = PackedByteArray()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is SatoriException:
return ApiProperties.new(result)
var out : ApiProperties = SatoriSerializer.deserialize(_namespace, "ApiProperties", result)
return out
# Update identity properties.
func update_properties_async(
p_session : SatoriSession
, p_body : ApiUpdatePropertiesRequest
) -> SatoriAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return SatoriAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v1/properties"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "PUT"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray = PackedByteArray()
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is SatoriException:
return SatoriAsyncResult.new(result)
return SatoriAsyncResult.new()
@@ -0,0 +1 @@
uid://bjc75keigk02r
@@ -0,0 +1,212 @@
extends RefCounted
## A client for the API in Satori Server.
class_name SatoriClient
#region Properties
var _host
## The host address of the server.
var host : String:
get:
return _host
var _port
## The port number of the server.
var port : int:
get:
return _port
var _scheme
## The protocol scheme used to connect with the server. Must be either "http" or "https".
var scheme : String:
get:
return _scheme
## The key used to authenticate with the server without a session.
var api_key : String
## Set the timeout in seconds on requests sent to the server.
var timeout : int
var _api_client : SatoriAPI.ApiClient
var auto_refresh : bool = false:
set(v):
set_auto_refresh(v)
get:
return get_auto_refresh()
func get_auto_refresh():
return _api_client.auto_refresh
func set_auto_refresh(p_value):
_api_client.auto_refresh = p_value
#endregion
#region Initialization
func _init(p_adapter : SatoriHTTPAdapter,
p_api_key : String,
p_scheme : String,
p_host : String,
p_port : int,
p_timeout : int):
api_key = p_api_key
_scheme = p_scheme
_host = p_host
_port = p_port
timeout = p_timeout
_api_client = SatoriAPI.ApiClient.new(_scheme + "://" + _host + ":" + str(_port), p_adapter, SatoriAPI, api_key, p_timeout)
#endregion
#region Client APIs
## Authenticate against the server.
## [p_id]: An optional user id.
## [p_default_properties]: Optional default properties to update with this call.
## If not set, properties are left as they are on the server.
## [p_custom_properties]: Optional custom properties to update with this call.
## If not set, properties are left as they are on the server.
func authenticate_async(p_id: String, p_default_properties: Dictionary = {}, p_custom_properties: Dictionary = {}) -> SatoriSession:
return _parse_session(await _api_client.authenticate_async(api_key, "",
SatoriAPI.ApiAuthenticateRequest.create(SatoriAPI, {
"id": p_id,
"default": p_default_properties,
"custom": p_custom_properties
})))
## Log out a session, invalidate a refresh token, or log out all sessions/refresh tokens for a user.
## [p_session]: The session of the user.
func authenticate_logout_async(p_session: SatoriSession) -> SatoriAsyncResult:
return await _api_client.authenticate_logout_async(p_session,
SatoriAPI.ApiAuthenticateLogoutRequest.create(SatoriAPI, {
"refresh_token": p_session.refresh_token,
"token": p_session.token
}))
# Parses the Satori API session and returns a SatoriSession object.
func _parse_session(p_session: SatoriAPI.ApiSession) -> SatoriSession:
if p_session.is_exception():
return SatoriSession.new(null, null, p_session.get_exception())
return SatoriSession.new(p_session.token, p_session.refresh_token)
## Refresh a user's session using a refresh token retrieved from a previous authentication request.
## [p_sesison]: The session of the user.
func session_refresh_async(p_session : SatoriSession) -> SatoriSession:
return _parse_session(await _api_client.authenticate_refresh_async(api_key, "",
SatoriAPI.ApiAuthenticateRefreshRequest.create(SatoriAPI, {
"refresh_token": p_session.refresh_token,
})
))
## Send an event for this session.
## [p_session]: The session of the user.
## [p_event]: The event which will be sent.
func event_async(p_session: SatoriSession, p_event: Event) -> SatoriAsyncResult:
return await events_async(p_session, [
p_event
])
## Send a batch of events for this session.
## [p_session]: The session of the user.
## [p_events]: The batch of events which will be sent.
func events_async(p_session: SatoriSession, p_events: Array) -> SatoriAsyncResult:
var p_dict = {
"events": p_events.map(func(e):
return e.to_api_event_dict())
}
var req = SatoriAPI.ApiEventRequest.create(SatoriAPI, p_dict)
return await _api_client.event_async(p_session,
req)
## Get all experiments data.
## [p_session]: The session of the user.
func get_all_experiments_async(p_session: SatoriSession) -> SatoriAsyncResult:
return await _api_client.get_experiments_async(p_session)
## Get specific experiments data.
## [p_session]: The session of the user.
## [p_names]: Experiment names.
func get_experiments_async(p_session: SatoriSession, p_names: Array) -> SatoriAPI.ApiExperimentList:
return await _api_client.get_experiments_async(p_session, p_names)
## Get a single flag for this identity.
## This method will return the default value
## specified and will not raise an exception if the network is unavailable
## [p_session]: The session of the user.
## [p_name]: The name of the flag.
## [p_default]: The default value if the server is unreachable.
func get_flag_async(p_session: SatoriSession, p_name: String, p_default: String = "") -> SatoriAPI.ApiFlag:
var p_names = [p_name]
var flags = await get_flags_async(p_session, p_names)
if flags.is_exception():
return SatoriAPI.ApiFlag.create(SatoriAPI, {
"name": p_name,
"value": p_default
})
for flag in flags.flags:
if flag.name == p_name:
return flag
return null
## List all available flags for this identity.
## [p_session]: The session of the user.
## [p_names]: Flag names, if empty all flags will be returned.
func get_flags_async(p_session: SatoriSession, p_names: Array) -> SatoriAPI.ApiFlagList:
return await _api_client.get_flags_async(p_session.token, p_names)
## List available live events.
## [p_session]: The session of the user.
## [p_names]: Live event names, if null or empty all live events are returned.
func get_live_events_async(p_session: SatoriSession, p_names: Array = []) -> SatoriAPI.ApiLiveEventList:
return await _api_client.get_live_events_async(p_session, p_names)
## Identify a session with a new ID.
## [p_session]: The session of the user.
## [p_id]: Identity ID to enrich the current session and return a new session.
## The old session will no longer be usable.
## Must be between eight and 128 characters (inclusive).
## Must be an alphanumeric string with only underscores and hyphens allowed.
## [p_default_properties]: The default properties.
## [p_custom_properties]: The custom event properties.
func identify_async(p_session: SatoriSession, p_id: String, p_default_properties: Dictionary = {}, p_custom_properties: Dictionary = {}) -> SatoriSession:
var req = SatoriAPI.ApiIdentifyRequest.create(SatoriAPI, {
"id": p_id,
"default": p_default_properties,
"custom": p_custom_properties
})
return _parse_session(await _api_client.identify_async(p_session, req))
## List properties associated with this identity.
## [p_session]: The session of the user.
func list_properties_async(p_session: SatoriSession) -> SatoriAsyncResult:
return await _api_client.list_properties_async(p_session)
## Update properties associated with this identity.
## [p_session]: The session of the user.
## [p_default_properties]: The default properties to update.
## [p_custom_properties]: The custom properties to update.
## [p_recompute]: Whether or not to recompute the user's audience membership immediately after property update.
func update_properties_async(p_session: SatoriSession, p_default_properties: Dictionary, p_custom_properties: Dictionary, p_recompute: bool = false) -> SatoriAsyncResult:
var req = SatoriAPI.ApiUpdatePropertiesRequest.create(SatoriAPI, {
"default": p_default_properties,
"custom": p_custom_properties,
"recompute": p_recompute
})
return await _api_client.update_properties_async(p_session, req)
## Delete the caller's identity and associated data.
## [p_session]: The session of the user.
func delete_identity_async(p_session: SatoriSession) -> SatoriAsyncResult:
return await _api_client.delete_identity_async(p_session)
#endregion
@@ -0,0 +1 @@
uid://dp2dpam3ffqar
@@ -0,0 +1,208 @@
@tool
extends Node
# An adapter which implements the HTTP protocol.
class_name SatoriHTTPAdapter
# The logger to use with the adapter.
var logger : RefCounted = SatoriLogger.new()
# The timeout for requests
var timeout : int = 3
# If request should be automatically retried when a network error occurs.
var auto_retry : bool = true
# The maximum number of time a request will be retried when auto_retry is true
var auto_retry_count : int = 3
var auto_retry_backoff_base : int = 10
# Whether or not to use threads when making HTTP requests.
var use_threads : bool = true
var _pending = {}
var id : int = 0
class AsyncRequest:
var id : int
var request : HTTPRequest
var uri : String
var method : int
var headers : PackedStringArray
var body : PackedByteArray
var retry_count := 3
var backoff_time := 10
var logger : SatoriLogger
var cancelled = false
var result : int = HTTPRequest.RESULT_NO_RESPONSE
var response_code : int = -1
var response_body : PackedByteArray
var timer : SceneTreeTimer = null
var cur_try : int = 1
var rng = RandomNumberGenerator.new()
func _init(p_id : int, p_request : HTTPRequest, p_uri : String,
p_method : int, p_headers : PackedStringArray, p_body : PackedByteArray,
p_retry_count : int, p_backoff_time : int, p_logger : SatoriLogger):
rng.seed = Time.get_ticks_usec()
id = p_id
request = p_request
uri = p_uri
method = p_method
headers = p_headers
body = p_body
retry_count = p_retry_count
backoff_time = p_backoff_time
logger = p_logger
func should_retry():
return cur_try < retry_count and not cancelled
func retry():
var time = pow(backoff_time, cur_try) * rng.randf_range(0.5, 1)
logger.debug("Retrying request %d. Tries left: %d. Backoff: %d ms" % [
id, retry_count - cur_try, time
])
cur_try += 1
await backoff(time)
if cancelled:
return
return await make_request()
func make_request():
var err = request.request(uri, headers, method, body.get_string_from_utf8())
if err != OK:
await request.get_tree().process_frame
result = HTTPRequest.RESULT_CANT_CONNECT
logger.debug("Request %d failed to start, error: %d" % [id, err])
return
var args = await request.request_completed
result = args[0]
response_code = args[1]
response_body = args[3]
func backoff(p_time : int):
timer = request.get_tree().create_timer(p_time / 1000.0)
await timer.timeout
timer = null
func cancel():
cancelled = true
request.cancel_request()
if timer:
timer.time_left = 0
else:
request.call_deferred("emit_signal", "request_completed", HTTPRequest.RESULT_REQUEST_FAILED, 0, [], [])
func parse_result():
if cancelled:
return SatoriException.new("Request cancelled", -1, -1, true)
elif result != HTTPRequest.RESULT_SUCCESS:
if result == null:
result = 0
return SatoriException.new("HTTPRequest failed!", result)
var json = JSON.new()
var json_error = json.parse(response_body.get_string_from_utf8())
if json_error != OK:
logger.debug("Unable to parse request %d response. JSON error: %d, JSON error message: %s, response code: %d" % [
id, json_error, json.get_error_message(), response_code
])
return SatoriException.new("Failed to decode JSON response", response_code)
var parsed = json.get_data()
if response_code != HTTPClient.RESPONSE_OK:
var error = ""
var code = -1
if typeof(parsed) == TYPE_DICTIONARY:
if "message" in parsed:
error = parsed["message"]
elif "error" in parsed:
error = parsed["error"]
else:
error = str(parsed)
code = parsed["code"] if "code" in parsed else -1
else:
error = str(parsed)
if typeof(error) == TYPE_DICTIONARY:
error = JSON.stringify(error)
logger.debug("Request %d returned response code: %d, RPC code: %d, error: %s" % [
id, response_code, code, error
])
return SatoriException.new(error, response_code, code)
return parsed
# Send a HTTP request.
# @param method - HTTP method to use for this request.
# @param uri - The fully qualified URI to use.
# @param headers - Request headers to set.
# @param body - Request content body to set.
# @param timeoutSec - Request timeout.
# Returns a task which resolves to the contents of the response.
func send_async(p_method : String, p_uri : String, p_headers : Dictionary, p_body : PackedByteArray):
var req = HTTPRequest.new()
req.timeout = timeout
if use_threads and OS.get_name() != 'Web':
req.use_threads = true # Threads not available nor needed on the web.
# Parse method
var method = HTTPClient.METHOD_GET
if p_method == "POST":
method = HTTPClient.METHOD_POST
elif p_method == "PUT":
method = HTTPClient.METHOD_PUT
elif p_method == "DELETE":
method = HTTPClient.METHOD_DELETE
elif p_method == "HEAD":
method = HTTPClient.METHOD_HEAD
var headers = PackedStringArray()
# Parse headers
headers.append("Accept: application/json")
for k in p_headers:
headers.append("%s: %s" % [k, p_headers[k]])
id += 1
var retry = auto_retry_count if auto_retry else 0
var backoff = auto_retry_backoff_base
_pending[id] = AsyncRequest.new(id, req, p_uri, method, headers, p_body, retry, backoff, logger)
logger.debug("Sending request [ID: %d, Method: %s, Uri: %s, Headers: %s, Body: %s, Timeout: %d, Retries: %d, Backoff base: %d ms]" % [
id, p_method, p_uri, p_headers, p_body.get_string_from_utf8(), timeout, retry, backoff
])
add_child(req)
return await _send_async(id, _pending)
func get_last_token():
return id
func cancel_request(p_token):
if _pending.has(p_token):
_pending[p_token].cancel()
static func _clear_request(p_request : AsyncRequest, p_pending : Dictionary, p_id : int):
if not p_request.request.is_queued_for_deletion():
p_request.logger.debug("Freeing request %d" % p_id)
p_request.request.queue_free()
p_pending.erase(p_id)
static func _send_async(p_id : int, p_pending : Dictionary):
var req : AsyncRequest = p_pending[p_id]
await req.make_request()
while req.result != HTTPRequest.RESULT_SUCCESS:
req.logger.debug("Request %d failed with result: %d, response code: %d" % [
p_id, req.result, req.response_code
])
if not req.should_retry():
break
await req.retry()
_clear_request(req, p_pending, p_id)
return req.parse_result()
@@ -0,0 +1 @@
uid://b7i4l7xvmg5qe
@@ -0,0 +1,107 @@
extends SatoriAsyncResult
class_name SatoriSession
var _token: String = ""
var token: String:
get:
return _token
var _refresh_token: String = ""
var refresh_token: String:
get:
return _refresh_token
var _expire_time: int = 0
var expire_time: int:
get:
return _expire_time
var expired: bool:
get:
return is_expired()
var _refresh_expire_time: int = 0
var refresh_expire_time: int:
get:
return _refresh_expire_time
var _identity_id: String = ""
var identity_id: String:
get:
return _identity_id
var _valid : bool = false
var valid : bool:
get:
return _valid
func is_expired() -> bool:
return _expire_time < Time.get_unix_time_from_system()
func would_expire_in(p_secs : int) -> bool:
return _expire_time < Time.get_unix_time_from_system() + p_secs
func has_refresh_expired(offset: float) -> bool:
return _expire_time < offset
func is_refresh_expired() -> bool:
return _refresh_expire_time < Time.get_unix_time_from_system()
func is_valid():
return _valid
# Initializes a new instance of the SatoriSession class.
#
# @param p_token - The authentication token.
# @param p_refresh_token - The refresh token.
# @param p_exception - The exception to be thrown, if any.
func _init(p_token = null, p_refresh_token = null, p_exception = null):
super(p_exception)
_refresh_expire_time = 0
if p_token:
_update(p_token, p_refresh_token)
func _update(p_token, p_refresh_token):
_token = p_token
_refresh_token = p_refresh_token
var decoded = _jwt_unpack(p_token)
if decoded.is_empty():
_valid = false
return
_valid = true
_expire_time = int(decoded.get("exp", 0))
_identity_id = str(decoded.get("iid", ""))
_refresh_expire_time = int(_jwt_unpack(refresh_token).get("exp", 0)) if !refresh_token.is_empty() else 0
func _to_string():
if is_exception():
return get_exception()._to_string()
return "Session<AuthToken=%s, ExpireTime=%d, RefreshToken=%s, RefreshExpireTime=%d, IdentityId=%s>" % [
_token, _expire_time, _refresh_token, _refresh_expire_time, identity_id]
func _jwt_unpack(p_token : String) -> Dictionary:
# Hack decode JSON payload from JWT.
if p_token.find(".") == -1:
_ex = SatoriException.new("Missing payload: %s" % p_token)
return {}
var payload = p_token.split('.')[1];
var pad_length = ceil(payload.length() / 4.0) * 4;
# Pad base64
for i in range(0, pad_length - payload.length()):
payload += "="
payload = payload.replace("-", "+").replace("_", "/")
var unpacked = Marshalls.base64_to_utf8(payload)
var json = JSON.new()
var error = json.parse(unpacked)
if error == OK:
var decoded = json.get_data()
if typeof(decoded) == TYPE_DICTIONARY:
return decoded
_ex = SatoriException.new("Unable to unpack token: %s" % p_token)
return {}
@@ -0,0 +1 @@
uid://yreiavija6v4
@@ -0,0 +1,34 @@
extends RefCounted
class_name SatoriAsyncResult
var exception : SatoriException:
set(v):
pass
get:
return get_exception()
var _ex = null
func _init(p_ex = null):
_ex = p_ex
func is_exception():
return get_exception() != null
func was_cancelled():
return is_exception() and get_exception().cancelled
func get_exception() -> SatoriException:
return _ex as SatoriException
func _to_string():
if is_exception():
return get_exception()._to_string()
return "SatoriAsyncResult<>"
static func _safe_ret(p_obj, p_type : GDScript):
if is_instance_of(p_obj, p_type):
return p_obj
elif p_obj is SatoriException:
return p_type.new(p_obj)
return p_type.new(SatoriException.new())
@@ -0,0 +1 @@
uid://dhrty7nqady0k
@@ -0,0 +1,42 @@
extends RefCounted
# An exception generated during a request.
# Usually contains at least an error message.
class_name SatoriException
var _status_code : int = -1
var status_code : int:
set(v):
pass
get:
return _status_code
var _grpc_status_code : int = -1
var grpc_status_code : int:
set(v):
pass
get:
return _grpc_status_code
var _message : String = ""
var message : String:
set(v):
pass
get:
return _message
var _cancelled : bool = false
var cancelled : bool:
set(v):
pass
get:
return _cancelled
func _init(p_message : String = "", p_status_code : int = -1, p_grpc_status_code : int = -1, p_cancelled : bool = false):
_status_code = p_status_code
_grpc_status_code = p_grpc_status_code
_message = p_message
_cancelled = p_cancelled
func _to_string() -> String:
return "SatoriException(StatusCode={%s}, Message='{%s}', GrpcStatusCode={%s})" % [_status_code, _message, _grpc_status_code]
@@ -0,0 +1 @@
uid://ds56ldehv1e2i
@@ -0,0 +1,38 @@
extends RefCounted
class_name SatoriLogger
enum LOG_LEVEL {NONE, ERROR, WARNING, INFO, VERBOSE, DEBUG}
var _level = LOG_LEVEL.ERROR
var _module = "Satori"
func _init(p_module : String = "Satori", p_level : int = LOG_LEVEL.ERROR):
_level = p_level
_module = p_module
func _log(level : int, msg):
if level <= _level:
if level == LOG_LEVEL.ERROR:
printerr("=== %s : ERROR === %s" % [_module, str(msg)])
else:
var what = "=== UNKNOWN === "
for k in LOG_LEVEL:
if level == LOG_LEVEL[k]:
what = "=== %s : %s === " % [_module, k]
break
print(what + str(msg))
func error(msg):
_log(LOG_LEVEL.ERROR, msg)
func warning(msg):
_log(LOG_LEVEL.WARNING, msg)
func info(msg):
_log(LOG_LEVEL.INFO, msg)
func verbose(msg):
_log(LOG_LEVEL.VERBOSE, msg)
func debug(msg):
_log(LOG_LEVEL.DEBUG, msg)
@@ -0,0 +1 @@
uid://dk3qpgkfd74x0
@@ -0,0 +1,163 @@
extends RefCounted
class_name SatoriSerializer
static func serialize(p_obj : Object) -> Dictionary:
var out = {}
var schema = p_obj.get("_SCHEMA")
if schema == null:
return {} # No schema defined
for k in schema:
var prop = schema[k]
var val = p_obj.get(prop["name"])
if val == null:
continue
var type = prop["type"]
var content = prop.get("content", TYPE_NIL)
if typeof(content) == TYPE_STRING:
content = TYPE_OBJECT
var val_type = typeof(val)
match val_type:
TYPE_OBJECT: # Simple objects
out[k] = serialize(val)
TYPE_ARRAY: # Array of objects
var arr = []
if val.size() > 0 and typeof(val[0]) == TYPE_OBJECT: # Array of objects
for e in val:
arr.append(serialize(e))
else:
arr = val
out[k] = arr
TYPE_PACKED_INT32_ARRAY, TYPE_PACKED_STRING_ARRAY: # Array of ints, bools, or strings
var arr = []
for e in val:
if content == TYPE_BOOL:
e = bool(e)
if typeof(e) != content:
continue
arr.append(e)
out[k] = arr
TYPE_DICTIONARY: # Maps
var dict = {}
if content == TYPE_OBJECT: # Map of objects
for l in val:
if typeof(val[l]) != TYPE_OBJECT:
continue
dict[l] = serialize(val[l])
else: # Map of simple types
for l in val:
var e = val[l]
if content == TYPE_FLOAT:
e = float(e)
elif content == TYPE_INT:
e = int(e)
elif content == TYPE_BOOL:
e = bool(e)
if typeof(e) != content:
continue
dict[l] = e
out[k] = dict
_:
out[k] = val
return out
static func deserialize(p_ns : GDScript, p_cls_name : String, p_dict : Dictionary) -> Object:
var cls : GDScript = p_ns.get(p_cls_name)
var schema = cls.get("_SCHEMA")
if schema == null:
return SatoriException.new() # No schema defined
var obj = cls.new()
for k in schema:
var prop = schema[k]
var pname = prop["name"]
var type = prop["type"]
var required = prop["required"]
var content = prop.get("content", TYPE_NIL)
var type_cmp = type
if typeof(type) == TYPE_STRING: # A class
type_cmp = TYPE_DICTIONARY
if type_cmp == TYPE_PACKED_STRING_ARRAY or type_cmp == TYPE_PACKED_INT32_ARRAY: # A specialized array
type_cmp = TYPE_ARRAY
var content_cmp = content
if typeof(content) == TYPE_STRING: # A dictionary or array of classes
content_cmp = TYPE_DICTIONARY
var val = p_dict.get(k, null)
# Ints might and up being recognized as floats. Change that if needed
if type_cmp == TYPE_INT:
if typeof(val) == TYPE_FLOAT:
val = int(val)
elif typeof(val) == TYPE_STRING and val.is_valid_int():
val = val.to_int()
if typeof(val) == type_cmp:
if typeof(type) == TYPE_STRING:
obj.set(pname, deserialize(p_ns, type, val))
elif type_cmp == TYPE_DICTIONARY:
var v = {}
for l in val:
if typeof(content) == TYPE_STRING:
v[l] = deserialize(p_ns, content, val[l])
elif content == TYPE_FLOAT:
v[l] = float(val[l])
elif content == TYPE_INT:
v[l] = int(val[l])
elif content == TYPE_BOOL:
v[l] = bool(val[l])
else:
v[l] = str(val[l])
obj.set(pname, v)
elif type_cmp == TYPE_ARRAY:
var v
match content:
TYPE_INT, TYPE_BOOL: v = PackedInt32Array()
TYPE_STRING: v = PackedStringArray()
_: v = Array()
for e in val:
if typeof(e) == TYPE_DICTIONARY:
v.append(e) # Avoid deserialization if e is already a dictionary
elif typeof(content) == TYPE_STRING:
v.append(deserialize(p_ns, content, e))
elif content == TYPE_FLOAT:
v.append(float(e))
elif content == TYPE_INT:
v.append(int(e))
elif content == TYPE_BOOL:
v.append(bool(e))
else:
v.append(str(e))
obj.set(pname, v)
else:
obj.set(pname, val)
elif required:
obj._ex = SatoriException.new("ERROR [%s]: Missing or invalid required prop %s = %s:\n\t%s" % [p_cls_name, prop, p_dict.get(k), p_dict])
return obj
return obj
###
# Compatibility with Godot 3.1 which does not expose String.http_escape
###
const HEX = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"]
static func escape_http(p_str : String) -> String:
var out : String = ""
for o in p_str:
if (o == '.' or o == '-' or o == '_' or o == '~' or
(o >= 'a' and o <= 'z') or
(o >= 'A' and o <= 'Z') or
(o >= '0' and o <= '9')):
out += o
else:
for b in o.to_utf8_buffer():
out += "%%%s" % to_hex(b)
return out
static func to_hex(p_val : int) -> String:
var v := p_val
var o := ""
while v != 0:
o = HEX[v % 16] + o
v /= 16
return o
@@ -0,0 +1 @@
uid://dcgodt1wuq4ei
@@ -0,0 +1,6120 @@
### Code generated by codegen/main.go. DO NOT EDIT. ###
extends RefCounted
class_name NakamaAPI
# A single user-role pair.
class GroupUserListGroupUser extends NakamaAsyncResult:
const _SCHEMA = {
"state": {"name": "_state", "type": TYPE_INT, "required": false},
"user": {"name": "_user", "type": "ApiUser", "required": false},
}
# Their relationship to the group.
var _state
var state : int:
get:
return 0 if not _state is int else int(_state)
# User.
var _user
var user : ApiUser:
get:
return _user as ApiUser
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> GroupUserListGroupUser:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "GroupUserListGroupUser", p_dict), GroupUserListGroupUser) as GroupUserListGroupUser
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "state: %s, " % _state
output += "user: %s, " % _user
return output
# A single group-role pair.
class UserGroupListUserGroup extends NakamaAsyncResult:
const _SCHEMA = {
"group": {"name": "_group", "type": "ApiGroup", "required": false},
"state": {"name": "_state", "type": TYPE_INT, "required": false},
}
# Group.
var _group
var group : ApiGroup:
get:
return _group as ApiGroup
# The user's relationship to the group.
var _state
var state : int:
get:
return 0 if not _state is int else int(_state)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> UserGroupListUserGroup:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "UserGroupListUserGroup", p_dict), UserGroupListUserGroup) as UserGroupListUserGroup
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "group: %s, " % _group
output += "state: %s, " % _state
return output
# Record values to write.
class WriteLeaderboardRecordRequestLeaderboardRecordWrite extends NakamaAsyncResult:
const _SCHEMA = {
"metadata": {"name": "_metadata", "type": TYPE_STRING, "required": false},
"operator": {"name": "_operator", "type": TYPE_INT, "required": false},
"score": {"name": "_score", "type": TYPE_STRING, "required": false},
"subscore": {"name": "_subscore", "type": TYPE_STRING, "required": false},
}
# Optional record metadata.
var _metadata
var metadata : String:
get:
return "" if not _metadata is String else String(_metadata)
# Operator override.
var _operator
var operator : int:
get:
return ApiOperator.values()[0] if not ApiOperator.values().has(_operator) else _operator
# The score value to submit.
var _score
var score : String:
get:
return "" if not _score is String else String(_score)
# An optional secondary value.
var _subscore
var subscore : String:
get:
return "" if not _subscore is String else String(_subscore)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> WriteLeaderboardRecordRequestLeaderboardRecordWrite:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "WriteLeaderboardRecordRequestLeaderboardRecordWrite", p_dict), WriteLeaderboardRecordRequestLeaderboardRecordWrite) as WriteLeaderboardRecordRequestLeaderboardRecordWrite
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "metadata: %s, " % _metadata
output += "operator: %s, " % _operator
output += "score: %s, " % _score
output += "subscore: %s, " % _subscore
return output
# Record values to write.
class WriteTournamentRecordRequestTournamentRecordWrite extends NakamaAsyncResult:
const _SCHEMA = {
"metadata": {"name": "_metadata", "type": TYPE_STRING, "required": false},
"operator": {"name": "_operator", "type": TYPE_INT, "required": false},
"score": {"name": "_score", "type": TYPE_STRING, "required": false},
"subscore": {"name": "_subscore", "type": TYPE_STRING, "required": false},
}
# A JSON object of additional properties (optional).
var _metadata
var metadata : String:
get:
return "" if not _metadata is String else String(_metadata)
# Operator override.
var _operator
var operator : int:
get:
return ApiOperator.values()[0] if not ApiOperator.values().has(_operator) else _operator
# The score value to submit.
var _score
var score : String:
get:
return "" if not _score is String else String(_score)
# An optional secondary value.
var _subscore
var subscore : String:
get:
return "" if not _subscore is String else String(_subscore)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> WriteTournamentRecordRequestTournamentRecordWrite:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "WriteTournamentRecordRequestTournamentRecordWrite", p_dict), WriteTournamentRecordRequestTournamentRecordWrite) as WriteTournamentRecordRequestTournamentRecordWrite
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "metadata: %s, " % _metadata
output += "operator: %s, " % _operator
output += "score: %s, " % _score
output += "subscore: %s, " % _subscore
return output
# A user with additional account details. Always the current user.
class ApiAccount extends NakamaAsyncResult:
const _SCHEMA = {
"custom_id": {"name": "_custom_id", "type": TYPE_STRING, "required": false},
"devices": {"name": "_devices", "type": TYPE_ARRAY, "required": false, "content": "ApiAccountDevice"},
"disable_time": {"name": "_disable_time", "type": TYPE_STRING, "required": false},
"email": {"name": "_email", "type": TYPE_STRING, "required": false},
"user": {"name": "_user", "type": "ApiUser", "required": false},
"verify_time": {"name": "_verify_time", "type": TYPE_STRING, "required": false},
"wallet": {"name": "_wallet", "type": TYPE_STRING, "required": false},
}
# The custom id in the user's account.
var _custom_id
var custom_id : String:
get:
return "" if not _custom_id is String else String(_custom_id)
# The devices which belong to the user's account.
var _devices
var devices : Array:
get:
return Array() if not _devices is Array else Array(_devices)
# The UNIX time when the user's account was disabled/banned.
var _disable_time
var disable_time : String:
get:
return "" if not _disable_time is String else String(_disable_time)
# The email address of the user.
var _email
var email : String:
get:
return "" if not _email is String else String(_email)
# The user object.
var _user
var user : ApiUser:
get:
return _user as ApiUser
# The UNIX time when the user's email was verified.
var _verify_time
var verify_time : String:
get:
return "" if not _verify_time is String else String(_verify_time)
# The user's wallet data.
var _wallet
var wallet : String:
get:
return "" if not _wallet is String else String(_wallet)
var _wallet_dict = null
var wallet_dict : Dictionary:
get:
if _wallet_dict == null:
if _wallet == null:
return {}
var json = JSON.new()
if json.parse(_wallet) != OK:
return {}
_wallet_dict = json.get_data()
return _wallet_dict as Dictionary
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccount:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccount", p_dict), ApiAccount) as ApiAccount
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "custom_id: %s, " % _custom_id
output += "devices: %s, " % [_devices]
output += "disable_time: %s, " % _disable_time
output += "email: %s, " % _email
output += "user: %s, " % _user
output += "verify_time: %s, " % _verify_time
output += "wallet: %s, " % _wallet
return output
# Send a Apple Sign In token to the server. Used with authenticate/link/unlink.
class ApiAccountApple extends NakamaAsyncResult:
const _SCHEMA = {
"token": {"name": "_token", "type": TYPE_STRING, "required": false},
"vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
}
# The ID token received from Apple to validate.
var _token
var token : String:
get:
return "" if not _token is String else String(_token)
# Extra information that will be bundled in the session token.
var _vars
var vars : Dictionary:
get:
return Dictionary() if not _vars is Dictionary else _vars.duplicate()
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountApple:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountApple", p_dict), ApiAccountApple) as ApiAccountApple
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "token: %s, " % _token
var map_string : String = ""
if typeof(_vars) == TYPE_DICTIONARY:
for k in _vars:
map_string += "{%s=%s}, " % [k, _vars[k]]
output += "vars: [%s], " % map_string
return output
# Send a custom ID to the server. Used with authenticate/link/unlink.
class ApiAccountCustom extends NakamaAsyncResult:
const _SCHEMA = {
"id": {"name": "_id", "type": TYPE_STRING, "required": false},
"vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
}
# A custom identifier.
var _id
var id : String:
get:
return "" if not _id is String else String(_id)
# Extra information that will be bundled in the session token.
var _vars
var vars : Dictionary:
get:
return Dictionary() if not _vars is Dictionary else _vars.duplicate()
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountCustom:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountCustom", p_dict), ApiAccountCustom) as ApiAccountCustom
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "id: %s, " % _id
var map_string : String = ""
if typeof(_vars) == TYPE_DICTIONARY:
for k in _vars:
map_string += "{%s=%s}, " % [k, _vars[k]]
output += "vars: [%s], " % map_string
return output
# Send a device to the server. Used with authenticate/link/unlink and user.
class ApiAccountDevice extends NakamaAsyncResult:
const _SCHEMA = {
"id": {"name": "_id", "type": TYPE_STRING, "required": false},
"vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
}
# A device identifier. Should be obtained by a platform-specific device API.
var _id
var id : String:
get:
return "" if not _id is String else String(_id)
# Extra information that will be bundled in the session token.
var _vars
var vars : Dictionary:
get:
return Dictionary() if not _vars is Dictionary else _vars.duplicate()
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountDevice:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountDevice", p_dict), ApiAccountDevice) as ApiAccountDevice
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "id: %s, " % _id
var map_string : String = ""
if typeof(_vars) == TYPE_DICTIONARY:
for k in _vars:
map_string += "{%s=%s}, " % [k, _vars[k]]
output += "vars: [%s], " % map_string
return output
# Send an email with password to the server. Used with authenticate/link/unlink.
class ApiAccountEmail extends NakamaAsyncResult:
const _SCHEMA = {
"email": {"name": "_email", "type": TYPE_STRING, "required": false},
"password": {"name": "_password", "type": TYPE_STRING, "required": false},
"vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
}
# A valid RFC-5322 email address.
var _email
var email : String:
get:
return "" if not _email is String else String(_email)
# A password for the user account.
var _password
var password : String:
get:
return "" if not _password is String else String(_password)
# Extra information that will be bundled in the session token.
var _vars
var vars : Dictionary:
get:
return Dictionary() if not _vars is Dictionary else _vars.duplicate()
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountEmail:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountEmail", p_dict), ApiAccountEmail) as ApiAccountEmail
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "email: %s, " % _email
output += "password: %s, " % _password
var map_string : String = ""
if typeof(_vars) == TYPE_DICTIONARY:
for k in _vars:
map_string += "{%s=%s}, " % [k, _vars[k]]
output += "vars: [%s], " % map_string
return output
# Send a Facebook token to the server. Used with authenticate/link/unlink.
class ApiAccountFacebook extends NakamaAsyncResult:
const _SCHEMA = {
"token": {"name": "_token", "type": TYPE_STRING, "required": false},
"vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
}
# The OAuth token received from Facebook to access their profile API.
var _token
var token : String:
get:
return "" if not _token is String else String(_token)
# Extra information that will be bundled in the session token.
var _vars
var vars : Dictionary:
get:
return Dictionary() if not _vars is Dictionary else _vars.duplicate()
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountFacebook:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountFacebook", p_dict), ApiAccountFacebook) as ApiAccountFacebook
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "token: %s, " % _token
var map_string : String = ""
if typeof(_vars) == TYPE_DICTIONARY:
for k in _vars:
map_string += "{%s=%s}, " % [k, _vars[k]]
output += "vars: [%s], " % map_string
return output
# Send a Facebook Instant Game token to the server. Used with authenticate/link/unlink.
class ApiAccountFacebookInstantGame extends NakamaAsyncResult:
const _SCHEMA = {
"signed_player_info": {"name": "_signed_player_info", "type": TYPE_STRING, "required": false},
"vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
}
#
var _signed_player_info
var signed_player_info : String:
get:
return "" if not _signed_player_info is String else String(_signed_player_info)
# Extra information that will be bundled in the session token.
var _vars
var vars : Dictionary:
get:
return Dictionary() if not _vars is Dictionary else _vars.duplicate()
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountFacebookInstantGame:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountFacebookInstantGame", p_dict), ApiAccountFacebookInstantGame) as ApiAccountFacebookInstantGame
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "signed_player_info: %s, " % _signed_player_info
var map_string : String = ""
if typeof(_vars) == TYPE_DICTIONARY:
for k in _vars:
map_string += "{%s=%s}, " % [k, _vars[k]]
output += "vars: [%s], " % map_string
return output
# Send Apple's Game Center account credentials to the server. Used with authenticate/link/unlink.
class ApiAccountGameCenter extends NakamaAsyncResult:
const _SCHEMA = {
"bundle_id": {"name": "_bundle_id", "type": TYPE_STRING, "required": false},
"player_id": {"name": "_player_id", "type": TYPE_STRING, "required": false},
"public_key_url": {"name": "_public_key_url", "type": TYPE_STRING, "required": false},
"salt": {"name": "_salt", "type": TYPE_STRING, "required": false},
"signature": {"name": "_signature", "type": TYPE_STRING, "required": false},
"timestamp_seconds": {"name": "_timestamp_seconds", "type": TYPE_STRING, "required": false},
"vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
}
# Bundle ID (generated by GameCenter).
var _bundle_id
var bundle_id : String:
get:
return "" if not _bundle_id is String else String(_bundle_id)
# Player ID (generated by GameCenter).
var _player_id
var player_id : String:
get:
return "" if not _player_id is String else String(_player_id)
# The URL for the public encryption key.
var _public_key_url
var public_key_url : String:
get:
return "" if not _public_key_url is String else String(_public_key_url)
# A random "NSString" used to compute the hash and keep it randomized.
var _salt
var salt : String:
get:
return "" if not _salt is String else String(_salt)
# The verification signature data generated.
var _signature
var signature : String:
get:
return "" if not _signature is String else String(_signature)
# Time since UNIX epoch when the signature was created.
var _timestamp_seconds
var timestamp_seconds : String:
get:
return "" if not _timestamp_seconds is String else String(_timestamp_seconds)
# Extra information that will be bundled in the session token.
var _vars
var vars : Dictionary:
get:
return Dictionary() if not _vars is Dictionary else _vars.duplicate()
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountGameCenter:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountGameCenter", p_dict), ApiAccountGameCenter) as ApiAccountGameCenter
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "bundle_id: %s, " % _bundle_id
output += "player_id: %s, " % _player_id
output += "public_key_url: %s, " % _public_key_url
output += "salt: %s, " % _salt
output += "signature: %s, " % _signature
output += "timestamp_seconds: %s, " % _timestamp_seconds
var map_string : String = ""
if typeof(_vars) == TYPE_DICTIONARY:
for k in _vars:
map_string += "{%s=%s}, " % [k, _vars[k]]
output += "vars: [%s], " % map_string
return output
# Send a Google token to the server. Used with authenticate/link/unlink.
class ApiAccountGoogle extends NakamaAsyncResult:
const _SCHEMA = {
"token": {"name": "_token", "type": TYPE_STRING, "required": false},
"vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
}
# The OAuth token received from Google to access their profile API.
var _token
var token : String:
get:
return "" if not _token is String else String(_token)
# Extra information that will be bundled in the session token.
var _vars
var vars : Dictionary:
get:
return Dictionary() if not _vars is Dictionary else _vars.duplicate()
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountGoogle:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountGoogle", p_dict), ApiAccountGoogle) as ApiAccountGoogle
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "token: %s, " % _token
var map_string : String = ""
if typeof(_vars) == TYPE_DICTIONARY:
for k in _vars:
map_string += "{%s=%s}, " % [k, _vars[k]]
output += "vars: [%s], " % map_string
return output
# Send a Steam token to the server. Used with authenticate/link/unlink.
class ApiAccountSteam extends NakamaAsyncResult:
const _SCHEMA = {
"token": {"name": "_token", "type": TYPE_STRING, "required": false},
"vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
}
# The account token received from Steam to access their profile API.
var _token
var token : String:
get:
return "" if not _token is String else String(_token)
# Extra information that will be bundled in the session token.
var _vars
var vars : Dictionary:
get:
return Dictionary() if not _vars is Dictionary else _vars.duplicate()
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountSteam:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountSteam", p_dict), ApiAccountSteam) as ApiAccountSteam
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "token: %s, " % _token
var map_string : String = ""
if typeof(_vars) == TYPE_DICTIONARY:
for k in _vars:
map_string += "{%s=%s}, " % [k, _vars[k]]
output += "vars: [%s], " % map_string
return output
# A message sent on a channel.
class ApiChannelMessage extends NakamaAsyncResult:
const _SCHEMA = {
"channel_id": {"name": "_channel_id", "type": TYPE_STRING, "required": false},
"code": {"name": "_code", "type": TYPE_INT, "required": false},
"content": {"name": "_content", "type": TYPE_STRING, "required": false},
"create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false},
"group_id": {"name": "_group_id", "type": TYPE_STRING, "required": false},
"message_id": {"name": "_message_id", "type": TYPE_STRING, "required": false},
"persistent": {"name": "_persistent", "type": TYPE_BOOL, "required": false},
"room_name": {"name": "_room_name", "type": TYPE_STRING, "required": false},
"sender_id": {"name": "_sender_id", "type": TYPE_STRING, "required": false},
"update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false},
"user_id_one": {"name": "_user_id_one", "type": TYPE_STRING, "required": false},
"user_id_two": {"name": "_user_id_two", "type": TYPE_STRING, "required": false},
"username": {"name": "_username", "type": TYPE_STRING, "required": false},
}
# The channel this message belongs to.
var _channel_id
var channel_id : String:
get:
return "" if not _channel_id is String else String(_channel_id)
# The code representing a message type or category.
var _code
var code : int:
get:
return 0 if not _code is int else int(_code)
# The content payload.
var _content
var content : String:
get:
return "" if not _content is String else String(_content)
# The UNIX time when the message was created.
var _create_time
var create_time : String:
get:
return "" if not _create_time is String else String(_create_time)
# The ID of the group, or an empty string if this message was not sent through a group channel.
var _group_id
var group_id : String:
get:
return "" if not _group_id is String else String(_group_id)
# The unique ID of this message.
var _message_id
var message_id : String:
get:
return "" if not _message_id is String else String(_message_id)
# True if the message was persisted to the channel's history, false otherwise.
var _persistent
var persistent : bool:
get:
return false if not _persistent is bool else bool(_persistent)
# The name of the chat room, or an empty string if this message was not sent through a chat room.
var _room_name
var room_name : String:
get:
return "" if not _room_name is String else String(_room_name)
# Message sender, usually a user ID.
var _sender_id
var sender_id : String:
get:
return "" if not _sender_id is String else String(_sender_id)
# The UNIX time when the message was last updated.
var _update_time
var update_time : String:
get:
return "" if not _update_time is String else String(_update_time)
# The ID of the first DM user, or an empty string if this message was not sent through a DM chat.
var _user_id_one
var user_id_one : String:
get:
return "" if not _user_id_one is String else String(_user_id_one)
# The ID of the second DM user, or an empty string if this message was not sent through a DM chat.
var _user_id_two
var user_id_two : String:
get:
return "" if not _user_id_two is String else String(_user_id_two)
# The username of the message sender, if any.
var _username
var username : String:
get:
return "" if not _username is String else String(_username)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiChannelMessage:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiChannelMessage", p_dict), ApiChannelMessage) as ApiChannelMessage
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "channel_id: %s, " % _channel_id
output += "code: %s, " % _code
output += "content: %s, " % _content
output += "create_time: %s, " % _create_time
output += "group_id: %s, " % _group_id
output += "message_id: %s, " % _message_id
output += "persistent: %s, " % _persistent
output += "room_name: %s, " % _room_name
output += "sender_id: %s, " % _sender_id
output += "update_time: %s, " % _update_time
output += "user_id_one: %s, " % _user_id_one
output += "user_id_two: %s, " % _user_id_two
output += "username: %s, " % _username
return output
# A list of channel messages, usually a result of a list operation.
class ApiChannelMessageList extends NakamaAsyncResult:
const _SCHEMA = {
"cacheable_cursor": {"name": "_cacheable_cursor", "type": TYPE_STRING, "required": false},
"messages": {"name": "_messages", "type": TYPE_ARRAY, "required": false, "content": "ApiChannelMessage"},
"next_cursor": {"name": "_next_cursor", "type": TYPE_STRING, "required": false},
"prev_cursor": {"name": "_prev_cursor", "type": TYPE_STRING, "required": false},
}
# Cacheable cursor to list newer messages. Durable and designed to be stored, unlike next/prev cursors.
var _cacheable_cursor
var cacheable_cursor : String:
get:
return "" if not _cacheable_cursor is String else String(_cacheable_cursor)
# A list of messages.
var _messages
var messages : Array:
get:
return Array() if not _messages is Array else Array(_messages)
# The cursor to send when retrieving the next page, if any.
var _next_cursor
var next_cursor : String:
get:
return "" if not _next_cursor is String else String(_next_cursor)
# The cursor to send when retrieving the previous page, if any.
var _prev_cursor
var prev_cursor : String:
get:
return "" if not _prev_cursor is String else String(_prev_cursor)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiChannelMessageList:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiChannelMessageList", p_dict), ApiChannelMessageList) as ApiChannelMessageList
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "cacheable_cursor: %s, " % _cacheable_cursor
output += "messages: %s, " % [_messages]
output += "next_cursor: %s, " % _next_cursor
output += "prev_cursor: %s, " % _prev_cursor
return output
# Create a group with the current user as owner.
class ApiCreateGroupRequest extends NakamaAsyncResult:
const _SCHEMA = {
"avatar_url": {"name": "_avatar_url", "type": TYPE_STRING, "required": false},
"description": {"name": "_description", "type": TYPE_STRING, "required": false},
"lang_tag": {"name": "_lang_tag", "type": TYPE_STRING, "required": false},
"max_count": {"name": "_max_count", "type": TYPE_INT, "required": false},
"name": {"name": "_name", "type": TYPE_STRING, "required": false},
"open": {"name": "_open", "type": TYPE_BOOL, "required": false},
}
# A URL for an avatar image.
var _avatar_url
var avatar_url : String:
get:
return "" if not _avatar_url is String else String(_avatar_url)
# A description for the group.
var _description
var description : String:
get:
return "" if not _description is String else String(_description)
# The language expected to be a tag which follows the BCP-47 spec.
var _lang_tag
var lang_tag : String:
get:
return "" if not _lang_tag is String else String(_lang_tag)
# Maximum number of group members.
var _max_count
var max_count : int:
get:
return 0 if not _max_count is int else int(_max_count)
# A unique name for the group.
var _name
var name : String:
get:
return "" if not _name is String else String(_name)
# Mark a group as open or not where only admins can accept members.
var _open
var open : bool:
get:
return false if not _open is bool else bool(_open)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiCreateGroupRequest:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiCreateGroupRequest", p_dict), ApiCreateGroupRequest) as ApiCreateGroupRequest
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "avatar_url: %s, " % _avatar_url
output += "description: %s, " % _description
output += "lang_tag: %s, " % _lang_tag
output += "max_count: %s, " % _max_count
output += "name: %s, " % _name
output += "open: %s, " % _open
return output
# Storage objects to delete.
class ApiDeleteStorageObjectId extends NakamaAsyncResult:
const _SCHEMA = {
"collection": {"name": "_collection", "type": TYPE_STRING, "required": false},
"key": {"name": "_key", "type": TYPE_STRING, "required": false},
"version": {"name": "_version", "type": TYPE_STRING, "required": false},
}
# The collection which stores the object.
var _collection
var collection : String:
get:
return "" if not _collection is String else String(_collection)
# The key of the object within the collection.
var _key
var key : String:
get:
return "" if not _key is String else String(_key)
# The version hash of the object.
var _version
var version : String:
get:
return "" if not _version is String else String(_version)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiDeleteStorageObjectId:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiDeleteStorageObjectId", p_dict), ApiDeleteStorageObjectId) as ApiDeleteStorageObjectId
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "collection: %s, " % _collection
output += "key: %s, " % _key
output += "version: %s, " % _version
return output
# Batch delete storage objects.
class ApiDeleteStorageObjectsRequest extends NakamaAsyncResult:
const _SCHEMA = {
"object_ids": {"name": "_object_ids", "type": TYPE_ARRAY, "required": false, "content": "ApiDeleteStorageObjectId"},
}
# Batch of storage objects.
var _object_ids
var object_ids : Array:
get:
return Array() if not _object_ids is Array else Array(_object_ids)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiDeleteStorageObjectsRequest:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiDeleteStorageObjectsRequest", p_dict), ApiDeleteStorageObjectsRequest) as ApiDeleteStorageObjectsRequest
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "object_ids: %s, " % [_object_ids]
return output
# Represents an event to be passed through the server to registered event handlers.
class ApiEvent extends NakamaAsyncResult:
const _SCHEMA = {
"external": {"name": "_external", "type": TYPE_BOOL, "required": false},
"name": {"name": "_name", "type": TYPE_STRING, "required": false},
"properties": {"name": "_properties", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
"timestamp": {"name": "_timestamp", "type": TYPE_STRING, "required": false},
}
# True if the event came directly from a client call, false otherwise.
var _external
var external : bool:
get:
return false if not _external is bool else bool(_external)
# An event name, type, category, or identifier.
var _name
var name : String:
get:
return "" if not _name is String else String(_name)
# Arbitrary event property values.
var _properties
var properties : Dictionary:
get:
return Dictionary() if not _properties is Dictionary else _properties.duplicate()
# The time when the event was triggered.
var _timestamp
var timestamp : String:
get:
return "" if not _timestamp is String else String(_timestamp)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiEvent:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiEvent", p_dict), ApiEvent) as ApiEvent
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "external: %s, " % _external
output += "name: %s, " % _name
var map_string : String = ""
if typeof(_properties) == TYPE_DICTIONARY:
for k in _properties:
map_string += "{%s=%s}, " % [k, _properties[k]]
output += "properties: [%s], " % map_string
output += "timestamp: %s, " % _timestamp
return output
# A friend of a user.
class ApiFriend extends NakamaAsyncResult:
const _SCHEMA = {
"state": {"name": "_state", "type": TYPE_INT, "required": false},
"update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false},
"user": {"name": "_user", "type": "ApiUser", "required": false},
}
# The friend status.
var _state
var state : int:
get:
return 0 if not _state is int else int(_state)
# Time of the latest relationship update.
var _update_time
var update_time : String:
get:
return "" if not _update_time is String else String(_update_time)
# The user object.
var _user
var user : ApiUser:
get:
return _user as ApiUser
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiFriend:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiFriend", p_dict), ApiFriend) as ApiFriend
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "state: %s, " % _state
output += "update_time: %s, " % _update_time
output += "user: %s, " % _user
return output
# A collection of zero or more friends of the user.
class ApiFriendList extends NakamaAsyncResult:
const _SCHEMA = {
"cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false},
"friends": {"name": "_friends", "type": TYPE_ARRAY, "required": false, "content": "ApiFriend"},
}
# Cursor for the next page of results, if any.
var _cursor
var cursor : String:
get:
return "" if not _cursor is String else String(_cursor)
# The Friend objects.
var _friends
var friends : Array:
get:
return Array() if not _friends is Array else Array(_friends)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiFriendList:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiFriendList", p_dict), ApiFriendList) as ApiFriendList
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "cursor: %s, " % _cursor
output += "friends: %s, " % [_friends]
return output
# A group in the server.
class ApiGroup extends NakamaAsyncResult:
const _SCHEMA = {
"avatar_url": {"name": "_avatar_url", "type": TYPE_STRING, "required": false},
"create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false},
"creator_id": {"name": "_creator_id", "type": TYPE_STRING, "required": false},
"description": {"name": "_description", "type": TYPE_STRING, "required": false},
"edge_count": {"name": "_edge_count", "type": TYPE_INT, "required": false},
"id": {"name": "_id", "type": TYPE_STRING, "required": false},
"lang_tag": {"name": "_lang_tag", "type": TYPE_STRING, "required": false},
"max_count": {"name": "_max_count", "type": TYPE_INT, "required": false},
"metadata": {"name": "_metadata", "type": TYPE_STRING, "required": false},
"name": {"name": "_name", "type": TYPE_STRING, "required": false},
"open": {"name": "_open", "type": TYPE_BOOL, "required": false},
"update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false},
}
# A URL for an avatar image.
var _avatar_url
var avatar_url : String:
get:
return "" if not _avatar_url is String else String(_avatar_url)
# The UNIX time when the group was created.
var _create_time
var create_time : String:
get:
return "" if not _create_time is String else String(_create_time)
# The id of the user who created the group.
var _creator_id
var creator_id : String:
get:
return "" if not _creator_id is String else String(_creator_id)
# A description for the group.
var _description
var description : String:
get:
return "" if not _description is String else String(_description)
# The current count of all members in the group.
var _edge_count
var edge_count : int:
get:
return 0 if not _edge_count is int else int(_edge_count)
# The id of a group.
var _id
var id : String:
get:
return "" if not _id is String else String(_id)
# The language expected to be a tag which follows the BCP-47 spec.
var _lang_tag
var lang_tag : String:
get:
return "" if not _lang_tag is String else String(_lang_tag)
# The maximum number of members allowed.
var _max_count
var max_count : int:
get:
return 0 if not _max_count is int else int(_max_count)
# Additional information stored as a JSON object.
var _metadata
var metadata : String:
get:
return "" if not _metadata is String else String(_metadata)
# The unique name of the group.
var _name
var name : String:
get:
return "" if not _name is String else String(_name)
# Anyone can join open groups, otherwise only admins can accept members.
var _open
var open : bool:
get:
return false if not _open is bool else bool(_open)
# The UNIX time when the group was last updated.
var _update_time
var update_time : String:
get:
return "" if not _update_time is String else String(_update_time)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiGroup:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiGroup", p_dict), ApiGroup) as ApiGroup
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "avatar_url: %s, " % _avatar_url
output += "create_time: %s, " % _create_time
output += "creator_id: %s, " % _creator_id
output += "description: %s, " % _description
output += "edge_count: %s, " % _edge_count
output += "id: %s, " % _id
output += "lang_tag: %s, " % _lang_tag
output += "max_count: %s, " % _max_count
output += "metadata: %s, " % _metadata
output += "name: %s, " % _name
output += "open: %s, " % _open
output += "update_time: %s, " % _update_time
return output
# One or more groups returned from a listing operation.
class ApiGroupList extends NakamaAsyncResult:
const _SCHEMA = {
"cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false},
"groups": {"name": "_groups", "type": TYPE_ARRAY, "required": false, "content": "ApiGroup"},
}
# A cursor used to get the next page.
var _cursor
var cursor : String:
get:
return "" if not _cursor is String else String(_cursor)
# One or more groups.
var _groups
var groups : Array:
get:
return Array() if not _groups is Array else Array(_groups)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiGroupList:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiGroupList", p_dict), ApiGroupList) as ApiGroupList
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "cursor: %s, " % _cursor
output += "groups: %s, " % [_groups]
return output
# A list of users belonging to a group, along with their role.
class ApiGroupUserList extends NakamaAsyncResult:
const _SCHEMA = {
"cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false},
"group_users": {"name": "_group_users", "type": TYPE_ARRAY, "required": false, "content": "GroupUserListGroupUser"},
}
# Cursor for the next page of results, if any.
var _cursor
var cursor : String:
get:
return "" if not _cursor is String else String(_cursor)
# User-role pairs for a group.
var _group_users
var group_users : Array:
get:
return Array() if not _group_users is Array else Array(_group_users)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiGroupUserList:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiGroupUserList", p_dict), ApiGroupUserList) as ApiGroupUserList
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "cursor: %s, " % _cursor
output += "group_users: %s, " % [_group_users]
return output
# Represents a complete leaderboard record with all scores and associated metadata.
class ApiLeaderboardRecord extends NakamaAsyncResult:
const _SCHEMA = {
"create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false},
"expiry_time": {"name": "_expiry_time", "type": TYPE_STRING, "required": false},
"leaderboard_id": {"name": "_leaderboard_id", "type": TYPE_STRING, "required": false},
"max_num_score": {"name": "_max_num_score", "type": TYPE_INT, "required": false},
"metadata": {"name": "_metadata", "type": TYPE_STRING, "required": false},
"num_score": {"name": "_num_score", "type": TYPE_INT, "required": false},
"owner_id": {"name": "_owner_id", "type": TYPE_STRING, "required": false},
"rank": {"name": "_rank", "type": TYPE_STRING, "required": false},
"score": {"name": "_score", "type": TYPE_STRING, "required": false},
"subscore": {"name": "_subscore", "type": TYPE_STRING, "required": false},
"update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false},
"username": {"name": "_username", "type": TYPE_STRING, "required": false},
}
# The UNIX time when the leaderboard record was created.
var _create_time
var create_time : String:
get:
return "" if not _create_time is String else String(_create_time)
# The UNIX time when the leaderboard record expires.
var _expiry_time
var expiry_time : String:
get:
return "" if not _expiry_time is String else String(_expiry_time)
# The ID of the leaderboard this score belongs to.
var _leaderboard_id
var leaderboard_id : String:
get:
return "" if not _leaderboard_id is String else String(_leaderboard_id)
# The maximum number of score updates allowed by the owner.
var _max_num_score
var max_num_score : int:
get:
return 0 if not _max_num_score is int else int(_max_num_score)
# Metadata.
var _metadata
var metadata : String:
get:
return "" if not _metadata is String else String(_metadata)
# The number of submissions to this score record.
var _num_score
var num_score : int:
get:
return 0 if not _num_score is int else int(_num_score)
# The ID of the score owner, usually a user or group.
var _owner_id
var owner_id : String:
get:
return "" if not _owner_id is String else String(_owner_id)
# The rank of this record.
var _rank
var rank : String:
get:
return "" if not _rank is String else String(_rank)
# The score value.
var _score
var score : String:
get:
return "" if not _score is String else String(_score)
# An optional subscore value.
var _subscore
var subscore : String:
get:
return "" if not _subscore is String else String(_subscore)
# The UNIX time when the leaderboard record was updated.
var _update_time
var update_time : String:
get:
return "" if not _update_time is String else String(_update_time)
# The username of the score owner, if the owner is a user.
var _username
var username : String:
get:
return "" if not _username is String else String(_username)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiLeaderboardRecord:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiLeaderboardRecord", p_dict), ApiLeaderboardRecord) as ApiLeaderboardRecord
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "create_time: %s, " % _create_time
output += "expiry_time: %s, " % _expiry_time
output += "leaderboard_id: %s, " % _leaderboard_id
output += "max_num_score: %s, " % _max_num_score
output += "metadata: %s, " % _metadata
output += "num_score: %s, " % _num_score
output += "owner_id: %s, " % _owner_id
output += "rank: %s, " % _rank
output += "score: %s, " % _score
output += "subscore: %s, " % _subscore
output += "update_time: %s, " % _update_time
output += "username: %s, " % _username
return output
# A set of leaderboard records, may be part of a leaderboard records page or a batch of individual records.
class ApiLeaderboardRecordList extends NakamaAsyncResult:
const _SCHEMA = {
"next_cursor": {"name": "_next_cursor", "type": TYPE_STRING, "required": false},
"owner_records": {"name": "_owner_records", "type": TYPE_ARRAY, "required": false, "content": "ApiLeaderboardRecord"},
"prev_cursor": {"name": "_prev_cursor", "type": TYPE_STRING, "required": false},
"records": {"name": "_records", "type": TYPE_ARRAY, "required": false, "content": "ApiLeaderboardRecord"},
}
# The cursor to send when retrieving the next page, if any.
var _next_cursor
var next_cursor : String:
get:
return "" if not _next_cursor is String else String(_next_cursor)
# A batched set of leaderboard records belonging to specified owners.
var _owner_records
var owner_records : Array:
get:
return Array() if not _owner_records is Array else Array(_owner_records)
# The cursor to send when retrieving the previous page, if any.
var _prev_cursor
var prev_cursor : String:
get:
return "" if not _prev_cursor is String else String(_prev_cursor)
# A list of leaderboard records.
var _records
var records : Array:
get:
return Array() if not _records is Array else Array(_records)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiLeaderboardRecordList:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiLeaderboardRecordList", p_dict), ApiLeaderboardRecordList) as ApiLeaderboardRecordList
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "next_cursor: %s, " % _next_cursor
output += "owner_records: %s, " % [_owner_records]
output += "prev_cursor: %s, " % _prev_cursor
output += "records: %s, " % [_records]
return output
# Link Steam to the current user's account.
class ApiLinkSteamRequest extends NakamaAsyncResult:
const _SCHEMA = {
"account": {"name": "_account", "type": "ApiAccountSteam", "required": false},
"sync": {"name": "_sync", "type": TYPE_BOOL, "required": false},
}
# The Facebook account details.
var _account
var account : ApiAccountSteam:
get:
return _account as ApiAccountSteam
# Import Steam friends for the user.
var _sync
var sync : bool:
get:
return false if not _sync is bool else bool(_sync)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiLinkSteamRequest:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiLinkSteamRequest", p_dict), ApiLinkSteamRequest) as ApiLinkSteamRequest
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "account: %s, " % _account
output += "sync: %s, " % _sync
return output
# List user subscriptions.
class ApiListSubscriptionsRequest extends NakamaAsyncResult:
const _SCHEMA = {
"cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false},
"limit": {"name": "_limit", "type": TYPE_INT, "required": false},
}
#
var _cursor
var cursor : String:
get:
return "" if not _cursor is String else String(_cursor)
#
var _limit
var limit : int:
get:
return 0 if not _limit is int else int(_limit)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiListSubscriptionsRequest:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiListSubscriptionsRequest", p_dict), ApiListSubscriptionsRequest) as ApiListSubscriptionsRequest
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "cursor: %s, " % _cursor
output += "limit: %s, " % _limit
return output
# Represents a realtime match.
class ApiMatch extends NakamaAsyncResult:
const _SCHEMA = {
"authoritative": {"name": "_authoritative", "type": TYPE_BOOL, "required": false},
"handler_name": {"name": "_handler_name", "type": TYPE_STRING, "required": false},
"label": {"name": "_label", "type": TYPE_STRING, "required": false},
"match_id": {"name": "_match_id", "type": TYPE_STRING, "required": false},
"size": {"name": "_size", "type": TYPE_INT, "required": false},
"tick_rate": {"name": "_tick_rate", "type": TYPE_INT, "required": false},
}
# True if it's an server-managed authoritative match, false otherwise.
var _authoritative
var authoritative : bool:
get:
return false if not _authoritative is bool else bool(_authoritative)
#
var _handler_name
var handler_name : String:
get:
return "" if not _handler_name is String else String(_handler_name)
# Match label, if any.
var _label
var label : String:
get:
return "" if not _label is String else String(_label)
# The ID of the match, can be used to join.
var _match_id
var match_id : String:
get:
return "" if not _match_id is String else String(_match_id)
# Current number of users in the match.
var _size
var size : int:
get:
return 0 if not _size is int else int(_size)
#
var _tick_rate
var tick_rate : int:
get:
return 0 if not _tick_rate is int else int(_tick_rate)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiMatch:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiMatch", p_dict), ApiMatch) as ApiMatch
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "authoritative: %s, " % _authoritative
output += "handler_name: %s, " % _handler_name
output += "label: %s, " % _label
output += "match_id: %s, " % _match_id
output += "size: %s, " % _size
output += "tick_rate: %s, " % _tick_rate
return output
# A list of realtime matches.
class ApiMatchList extends NakamaAsyncResult:
const _SCHEMA = {
"matches": {"name": "_matches", "type": TYPE_ARRAY, "required": false, "content": "ApiMatch"},
}
# A number of matches corresponding to a list operation.
var _matches
var matches : Array:
get:
return Array() if not _matches is Array else Array(_matches)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiMatchList:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiMatchList", p_dict), ApiMatchList) as ApiMatchList
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "matches: %s, " % [_matches]
return output
# A notification in the server.
class ApiNotification extends NakamaAsyncResult:
const _SCHEMA = {
"code": {"name": "_code", "type": TYPE_INT, "required": false},
"content": {"name": "_content", "type": TYPE_STRING, "required": false},
"create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false},
"id": {"name": "_id", "type": TYPE_STRING, "required": false},
"persistent": {"name": "_persistent", "type": TYPE_BOOL, "required": false},
"sender_id": {"name": "_sender_id", "type": TYPE_STRING, "required": false},
"subject": {"name": "_subject", "type": TYPE_STRING, "required": false},
}
# Category code for this notification.
var _code
var code : int:
get:
return 0 if not _code is int else int(_code)
# Content of the notification in JSON.
var _content
var content : String:
get:
return "" if not _content is String else String(_content)
# The UNIX time when the notification was created.
var _create_time
var create_time : String:
get:
return "" if not _create_time is String else String(_create_time)
# ID of the Notification.
var _id
var id : String:
get:
return "" if not _id is String else String(_id)
# True if this notification was persisted to the database.
var _persistent
var persistent : bool:
get:
return false if not _persistent is bool else bool(_persistent)
# ID of the sender, if a user. Otherwise 'null'.
var _sender_id
var sender_id : String:
get:
return "" if not _sender_id is String else String(_sender_id)
# Subject of the notification.
var _subject
var subject : String:
get:
return "" if not _subject is String else String(_subject)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiNotification:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiNotification", p_dict), ApiNotification) as ApiNotification
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "code: %s, " % _code
output += "content: %s, " % _content
output += "create_time: %s, " % _create_time
output += "id: %s, " % _id
output += "persistent: %s, " % _persistent
output += "sender_id: %s, " % _sender_id
output += "subject: %s, " % _subject
return output
# A collection of zero or more notifications.
class ApiNotificationList extends NakamaAsyncResult:
const _SCHEMA = {
"cacheable_cursor": {"name": "_cacheable_cursor", "type": TYPE_STRING, "required": false},
"notifications": {"name": "_notifications", "type": TYPE_ARRAY, "required": false, "content": "ApiNotification"},
}
# Use this cursor to paginate notifications. Cache this to catch up to new notifications.
var _cacheable_cursor
var cacheable_cursor : String:
get:
return "" if not _cacheable_cursor is String else String(_cacheable_cursor)
# Collection of notifications.
var _notifications
var notifications : Array:
get:
return Array() if not _notifications is Array else Array(_notifications)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiNotificationList:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiNotificationList", p_dict), ApiNotificationList) as ApiNotificationList
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "cacheable_cursor: %s, " % _cacheable_cursor
output += "notifications: %s, " % [_notifications]
return output
# Operator that can be used to override the one set in the leaderboard.
# - NO_OVERRIDE: Do not override the leaderboard operator.
# - BEST: Override the leaderboard operator with BEST.
# - SET: Override the leaderboard operator with SET.
# - INCREMENT: Override the leaderboard operator with INCREMENT.
# - DECREMENT: Override the leaderboard operator with DECREMENT.# [ - NO_OVERRIDE: Do not override the leaderboard operator. - BEST: Override the leaderboard operator with BEST. - SET: Override the leaderboard operator with SET. - INCREMENT: Override the leaderboard operator with INCREMENT. - DECREMENT: Override the leaderboard operator with DECREMENT.]
enum ApiOperator {NO_OVERRIDE = 0,BEST = 1,SET = 2,INCREMENT = 3,DECREMENT = 4,}
# Storage objects to get.
class ApiReadStorageObjectId extends NakamaAsyncResult:
const _SCHEMA = {
"collection": {"name": "_collection", "type": TYPE_STRING, "required": false},
"key": {"name": "_key", "type": TYPE_STRING, "required": false},
"user_id": {"name": "_user_id", "type": TYPE_STRING, "required": false},
}
# The collection which stores the object.
var _collection
var collection : String:
get:
return "" if not _collection is String else String(_collection)
# The key of the object within the collection.
var _key
var key : String:
get:
return "" if not _key is String else String(_key)
# The user owner of the object.
var _user_id
var user_id : String:
get:
return "" if not _user_id is String else String(_user_id)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiReadStorageObjectId:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiReadStorageObjectId", p_dict), ApiReadStorageObjectId) as ApiReadStorageObjectId
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "collection: %s, " % _collection
output += "key: %s, " % _key
output += "user_id: %s, " % _user_id
return output
# Batch get storage objects.
class ApiReadStorageObjectsRequest extends NakamaAsyncResult:
const _SCHEMA = {
"object_ids": {"name": "_object_ids", "type": TYPE_ARRAY, "required": false, "content": "ApiReadStorageObjectId"},
}
# Batch of storage objects.
var _object_ids
var object_ids : Array:
get:
return Array() if not _object_ids is Array else Array(_object_ids)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiReadStorageObjectsRequest:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiReadStorageObjectsRequest", p_dict), ApiReadStorageObjectsRequest) as ApiReadStorageObjectsRequest
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "object_ids: %s, " % [_object_ids]
return output
# Execute an Lua function on the server.
class ApiRpc extends NakamaAsyncResult:
const _SCHEMA = {
"http_key": {"name": "_http_key", "type": TYPE_STRING, "required": false},
"id": {"name": "_id", "type": TYPE_STRING, "required": false},
"payload": {"name": "_payload", "type": TYPE_STRING, "required": false},
}
# The authentication key used when executed as a non-client HTTP request.
var _http_key
var http_key : String:
get:
return "" if not _http_key is String else String(_http_key)
# The identifier of the function.
var _id
var id : String:
get:
return "" if not _id is String else String(_id)
# The payload of the function which must be a JSON object.
var _payload
var payload : String:
get:
return "" if not _payload is String else String(_payload)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiRpc:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiRpc", p_dict), ApiRpc) as ApiRpc
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "http_key: %s, " % _http_key
output += "id: %s, " % _id
output += "payload: %s, " % _payload
return output
# A user's session used to authenticate messages.
class ApiSession extends NakamaAsyncResult:
const _SCHEMA = {
"created": {"name": "_created", "type": TYPE_BOOL, "required": false},
"refresh_token": {"name": "_refresh_token", "type": TYPE_STRING, "required": false},
"token": {"name": "_token", "type": TYPE_STRING, "required": false},
}
# True if the corresponding account was just created, false otherwise.
var _created
var created : bool:
get:
return false if not _created is bool else bool(_created)
# Refresh token that can be used for session token renewal.
var _refresh_token
var refresh_token : String:
get:
return "" if not _refresh_token is String else String(_refresh_token)
# Authentication credentials.
var _token
var token : String:
get:
return "" if not _token is String else String(_token)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiSession:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiSession", p_dict), ApiSession) as ApiSession
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "created: %s, " % _created
output += "refresh_token: %s, " % _refresh_token
output += "token: %s, " % _token
return output
# Log out a session, invalidate a refresh token, or log out all sessions/refresh tokens for a user.
class ApiSessionLogoutRequest extends NakamaAsyncResult:
const _SCHEMA = {
"refresh_token": {"name": "_refresh_token", "type": TYPE_STRING, "required": false},
"token": {"name": "_token", "type": TYPE_STRING, "required": false},
}
# Refresh token to invalidate.
var _refresh_token
var refresh_token : String:
get:
return "" if not _refresh_token is String else String(_refresh_token)
# Session token to log out.
var _token
var token : String:
get:
return "" if not _token is String else String(_token)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiSessionLogoutRequest:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiSessionLogoutRequest", p_dict), ApiSessionLogoutRequest) as ApiSessionLogoutRequest
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "refresh_token: %s, " % _refresh_token
output += "token: %s, " % _token
return output
# Authenticate against the server with a refresh token.
class ApiSessionRefreshRequest extends NakamaAsyncResult:
const _SCHEMA = {
"token": {"name": "_token", "type": TYPE_STRING, "required": false},
"vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
}
# Refresh token.
var _token
var token : String:
get:
return "" if not _token is String else String(_token)
# Extra information that will be bundled in the session token.
var _vars
var vars : Dictionary:
get:
return Dictionary() if not _vars is Dictionary else _vars.duplicate()
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiSessionRefreshRequest:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiSessionRefreshRequest", p_dict), ApiSessionRefreshRequest) as ApiSessionRefreshRequest
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "token: %s, " % _token
var map_string : String = ""
if typeof(_vars) == TYPE_DICTIONARY:
for k in _vars:
map_string += "{%s=%s}, " % [k, _vars[k]]
output += "vars: [%s], " % map_string
return output
# An object within the storage engine.
class ApiStorageObject extends NakamaAsyncResult:
const _SCHEMA = {
"collection": {"name": "_collection", "type": TYPE_STRING, "required": false},
"create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false},
"key": {"name": "_key", "type": TYPE_STRING, "required": false},
"permission_read": {"name": "_permission_read", "type": TYPE_INT, "required": false},
"permission_write": {"name": "_permission_write", "type": TYPE_INT, "required": false},
"update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false},
"user_id": {"name": "_user_id", "type": TYPE_STRING, "required": false},
"value": {"name": "_value", "type": TYPE_STRING, "required": false},
"version": {"name": "_version", "type": TYPE_STRING, "required": false},
}
# The collection which stores the object.
var _collection
var collection : String:
get:
return "" if not _collection is String else String(_collection)
# The UNIX time when the object was created.
var _create_time
var create_time : String:
get:
return "" if not _create_time is String else String(_create_time)
# The key of the object within the collection.
var _key
var key : String:
get:
return "" if not _key is String else String(_key)
# The read access permissions for the object.
var _permission_read
var permission_read : int:
get:
return 0 if not _permission_read is int else int(_permission_read)
# The write access permissions for the object.
var _permission_write
var permission_write : int:
get:
return 0 if not _permission_write is int else int(_permission_write)
# The UNIX time when the object was last updated.
var _update_time
var update_time : String:
get:
return "" if not _update_time is String else String(_update_time)
# The user owner of the object.
var _user_id
var user_id : String:
get:
return "" if not _user_id is String else String(_user_id)
# The value of the object.
var _value
var value : String:
get:
return "" if not _value is String else String(_value)
# The version hash of the object.
var _version
var version : String:
get:
return "" if not _version is String else String(_version)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiStorageObject:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiStorageObject", p_dict), ApiStorageObject) as ApiStorageObject
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "collection: %s, " % _collection
output += "create_time: %s, " % _create_time
output += "key: %s, " % _key
output += "permission_read: %s, " % _permission_read
output += "permission_write: %s, " % _permission_write
output += "update_time: %s, " % _update_time
output += "user_id: %s, " % _user_id
output += "value: %s, " % _value
output += "version: %s, " % _version
return output
# A storage acknowledgement.
class ApiStorageObjectAck extends NakamaAsyncResult:
const _SCHEMA = {
"collection": {"name": "_collection", "type": TYPE_STRING, "required": false},
"key": {"name": "_key", "type": TYPE_STRING, "required": false},
"user_id": {"name": "_user_id", "type": TYPE_STRING, "required": false},
"version": {"name": "_version", "type": TYPE_STRING, "required": false},
}
# The collection which stores the object.
var _collection
var collection : String:
get:
return "" if not _collection is String else String(_collection)
# The key of the object within the collection.
var _key
var key : String:
get:
return "" if not _key is String else String(_key)
# The owner of the object.
var _user_id
var user_id : String:
get:
return "" if not _user_id is String else String(_user_id)
# The version hash of the object.
var _version
var version : String:
get:
return "" if not _version is String else String(_version)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiStorageObjectAck:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiStorageObjectAck", p_dict), ApiStorageObjectAck) as ApiStorageObjectAck
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "collection: %s, " % _collection
output += "key: %s, " % _key
output += "user_id: %s, " % _user_id
output += "version: %s, " % _version
return output
# Batch of acknowledgements for the storage object write.
class ApiStorageObjectAcks extends NakamaAsyncResult:
const _SCHEMA = {
"acks": {"name": "_acks", "type": TYPE_ARRAY, "required": false, "content": "ApiStorageObjectAck"},
}
# Batch of storage write acknowledgements.
var _acks
var acks : Array:
get:
return Array() if not _acks is Array else Array(_acks)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiStorageObjectAcks:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiStorageObjectAcks", p_dict), ApiStorageObjectAcks) as ApiStorageObjectAcks
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "acks: %s, " % [_acks]
return output
# List of storage objects.
class ApiStorageObjectList extends NakamaAsyncResult:
const _SCHEMA = {
"cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false},
"objects": {"name": "_objects", "type": TYPE_ARRAY, "required": false, "content": "ApiStorageObject"},
}
# The cursor for the next page of results, if any.
var _cursor
var cursor : String:
get:
return "" if not _cursor is String else String(_cursor)
# The list of storage objects.
var _objects
var objects : Array:
get:
return Array() if not _objects is Array else Array(_objects)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiStorageObjectList:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiStorageObjectList", p_dict), ApiStorageObjectList) as ApiStorageObjectList
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "cursor: %s, " % _cursor
output += "objects: %s, " % [_objects]
return output
# Batch of storage objects.
class ApiStorageObjects extends NakamaAsyncResult:
const _SCHEMA = {
"objects": {"name": "_objects", "type": TYPE_ARRAY, "required": false, "content": "ApiStorageObject"},
}
# The batch of storage objects.
var _objects
var objects : Array:
get:
return Array() if not _objects is Array else Array(_objects)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiStorageObjects:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiStorageObjects", p_dict), ApiStorageObjects) as ApiStorageObjects
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "objects: %s, " % [_objects]
return output
# Environment where a purchase/subscription took place,
# - UNKNOWN: Unknown environment.
# - SANDBOX: Sandbox/test environment.
# - PRODUCTION: Production environment.# [- UNKNOWN: Unknown environment. - SANDBOX: Sandbox/test environment. - PRODUCTION: Production environment.]
enum ApiStoreEnvironment {UNKNOWN = 0,SANDBOX = 1,PRODUCTION = 2,}
# Validation Provider,
# - APPLE_APP_STORE: Apple App Store
# - GOOGLE_PLAY_STORE: Google Play Store
# - HUAWEI_APP_GALLERY: Huawei App Gallery# [- APPLE_APP_STORE: Apple App Store - GOOGLE_PLAY_STORE: Google Play Store - HUAWEI_APP_GALLERY: Huawei App Gallery]
enum ApiStoreProvider {APPLE_APP_STORE = 0,GOOGLE_PLAY_STORE = 1,HUAWEI_APP_GALLERY = 2,}
# A list of validated subscriptions stored by Nakama.
class ApiSubscriptionList extends NakamaAsyncResult:
const _SCHEMA = {
"cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false},
"prev_cursor": {"name": "_prev_cursor", "type": TYPE_STRING, "required": false},
"validated_subscriptions": {"name": "_validated_subscriptions", "type": TYPE_ARRAY, "required": false, "content": "ApiValidatedSubscription"},
}
# The cursor to send when retrieving the next page, if any.
var _cursor
var cursor : String:
get:
return "" if not _cursor is String else String(_cursor)
# The cursor to send when retrieving the previous page, if any.
var _prev_cursor
var prev_cursor : String:
get:
return "" if not _prev_cursor is String else String(_prev_cursor)
# Stored validated subscriptions.
var _validated_subscriptions
var validated_subscriptions : Array:
get:
return Array() if not _validated_subscriptions is Array else Array(_validated_subscriptions)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiSubscriptionList:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiSubscriptionList", p_dict), ApiSubscriptionList) as ApiSubscriptionList
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "cursor: %s, " % _cursor
output += "prev_cursor: %s, " % _prev_cursor
output += "validated_subscriptions: %s, " % [_validated_subscriptions]
return output
# A tournament on the server.
class ApiTournament extends NakamaAsyncResult:
const _SCHEMA = {
"authoritative": {"name": "_authoritative", "type": TYPE_BOOL, "required": false},
"can_enter": {"name": "_can_enter", "type": TYPE_BOOL, "required": false},
"category": {"name": "_category", "type": TYPE_INT, "required": false},
"create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false},
"description": {"name": "_description", "type": TYPE_STRING, "required": false},
"duration": {"name": "_duration", "type": TYPE_INT, "required": false},
"end_active": {"name": "_end_active", "type": TYPE_INT, "required": false},
"end_time": {"name": "_end_time", "type": TYPE_STRING, "required": false},
"id": {"name": "_id", "type": TYPE_STRING, "required": false},
"max_num_score": {"name": "_max_num_score", "type": TYPE_INT, "required": false},
"max_size": {"name": "_max_size", "type": TYPE_INT, "required": false},
"metadata": {"name": "_metadata", "type": TYPE_STRING, "required": false},
"next_reset": {"name": "_next_reset", "type": TYPE_INT, "required": false},
"operator": {"name": "_operator", "type": TYPE_INT, "required": false},
"prev_reset": {"name": "_prev_reset", "type": TYPE_INT, "required": false},
"size": {"name": "_size", "type": TYPE_INT, "required": false},
"sort_order": {"name": "_sort_order", "type": TYPE_INT, "required": false},
"start_active": {"name": "_start_active", "type": TYPE_INT, "required": false},
"start_time": {"name": "_start_time", "type": TYPE_STRING, "required": false},
"title": {"name": "_title", "type": TYPE_STRING, "required": false},
}
# Whether the leaderboard was created authoritatively or not.
var _authoritative
var authoritative : bool:
get:
return false if not _authoritative is bool else bool(_authoritative)
# True if the tournament is active and can enter. A computed value.
var _can_enter
var can_enter : bool:
get:
return false if not _can_enter is bool else bool(_can_enter)
# The category of the tournament. e.g. "vip" could be category 1.
var _category
var category : int:
get:
return 0 if not _category is int else int(_category)
# The UNIX time when the tournament was created.
var _create_time
var create_time : String:
get:
return "" if not _create_time is String else String(_create_time)
# The description of the tournament. May be blank.
var _description
var description : String:
get:
return "" if not _description is String else String(_description)
# Duration of the tournament in seconds.
var _duration
var duration : int:
get:
return 0 if not _duration is int else int(_duration)
# The UNIX time when the tournament stops being active until next reset. A computed value.
var _end_active
var end_active : int:
get:
return 0 if not _end_active is int else int(_end_active)
# The UNIX time when the tournament will be stopped.
var _end_time
var end_time : String:
get:
return "" if not _end_time is String else String(_end_time)
# The ID of the tournament.
var _id
var id : String:
get:
return "" if not _id is String else String(_id)
# The maximum score updates allowed per player for the current tournament.
var _max_num_score
var max_num_score : int:
get:
return 0 if not _max_num_score is int else int(_max_num_score)
# The maximum number of players for the tournament.
var _max_size
var max_size : int:
get:
return 0 if not _max_size is int else int(_max_size)
# Additional information stored as a JSON object.
var _metadata
var metadata : String:
get:
return "" if not _metadata is String else String(_metadata)
# The UNIX time when the tournament is next playable. A computed value.
var _next_reset
var next_reset : int:
get:
return 0 if not _next_reset is int else int(_next_reset)
# Operator.
var _operator
var operator : int:
get:
return ApiOperator.values()[0] if not ApiOperator.values().has(_operator) else _operator
# The UNIX time when the tournament was last reset. A computed value.
var _prev_reset
var prev_reset : int:
get:
return 0 if not _prev_reset is int else int(_prev_reset)
# The current number of players in the tournament.
var _size
var size : int:
get:
return 0 if not _size is int else int(_size)
# ASC (0) or DESC (1) sort mode of scores in the tournament.
var _sort_order
var sort_order : int:
get:
return 0 if not _sort_order is int else int(_sort_order)
# The UNIX time when the tournament start being active. A computed value.
var _start_active
var start_active : int:
get:
return 0 if not _start_active is int else int(_start_active)
# The UNIX time when the tournament will start.
var _start_time
var start_time : String:
get:
return "" if not _start_time is String else String(_start_time)
# The title for the tournament.
var _title
var title : String:
get:
return "" if not _title is String else String(_title)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiTournament:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiTournament", p_dict), ApiTournament) as ApiTournament
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "authoritative: %s, " % _authoritative
output += "can_enter: %s, " % _can_enter
output += "category: %s, " % _category
output += "create_time: %s, " % _create_time
output += "description: %s, " % _description
output += "duration: %s, " % _duration
output += "end_active: %s, " % _end_active
output += "end_time: %s, " % _end_time
output += "id: %s, " % _id
output += "max_num_score: %s, " % _max_num_score
output += "max_size: %s, " % _max_size
output += "metadata: %s, " % _metadata
output += "next_reset: %s, " % _next_reset
output += "operator: %s, " % _operator
output += "prev_reset: %s, " % _prev_reset
output += "size: %s, " % _size
output += "sort_order: %s, " % _sort_order
output += "start_active: %s, " % _start_active
output += "start_time: %s, " % _start_time
output += "title: %s, " % _title
return output
# A list of tournaments.
class ApiTournamentList extends NakamaAsyncResult:
const _SCHEMA = {
"cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false},
"tournaments": {"name": "_tournaments", "type": TYPE_ARRAY, "required": false, "content": "ApiTournament"},
}
# A pagination cursor (optional).
var _cursor
var cursor : String:
get:
return "" if not _cursor is String else String(_cursor)
# The list of tournaments returned.
var _tournaments
var tournaments : Array:
get:
return Array() if not _tournaments is Array else Array(_tournaments)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiTournamentList:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiTournamentList", p_dict), ApiTournamentList) as ApiTournamentList
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "cursor: %s, " % _cursor
output += "tournaments: %s, " % [_tournaments]
return output
# A set of tournament records which may be part of a tournament records page or a batch of individual records.
class ApiTournamentRecordList extends NakamaAsyncResult:
const _SCHEMA = {
"next_cursor": {"name": "_next_cursor", "type": TYPE_STRING, "required": false},
"owner_records": {"name": "_owner_records", "type": TYPE_ARRAY, "required": false, "content": "ApiLeaderboardRecord"},
"prev_cursor": {"name": "_prev_cursor", "type": TYPE_STRING, "required": false},
"records": {"name": "_records", "type": TYPE_ARRAY, "required": false, "content": "ApiLeaderboardRecord"},
}
# The cursor to send when retireving the next page (optional).
var _next_cursor
var next_cursor : String:
get:
return "" if not _next_cursor is String else String(_next_cursor)
# A batched set of tournament records belonging to specified owners.
var _owner_records
var owner_records : Array:
get:
return Array() if not _owner_records is Array else Array(_owner_records)
# The cursor to send when retrieving the previous page (optional).
var _prev_cursor
var prev_cursor : String:
get:
return "" if not _prev_cursor is String else String(_prev_cursor)
# A list of tournament records.
var _records
var records : Array:
get:
return Array() if not _records is Array else Array(_records)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiTournamentRecordList:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiTournamentRecordList", p_dict), ApiTournamentRecordList) as ApiTournamentRecordList
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "next_cursor: %s, " % _next_cursor
output += "owner_records: %s, " % [_owner_records]
output += "prev_cursor: %s, " % _prev_cursor
output += "records: %s, " % [_records]
return output
# Update a user's account details.
class ApiUpdateAccountRequest extends NakamaAsyncResult:
const _SCHEMA = {
"avatar_url": {"name": "_avatar_url", "type": TYPE_STRING, "required": false},
"display_name": {"name": "_display_name", "type": TYPE_STRING, "required": false},
"lang_tag": {"name": "_lang_tag", "type": TYPE_STRING, "required": false},
"location": {"name": "_location", "type": TYPE_STRING, "required": false},
"timezone": {"name": "_timezone", "type": TYPE_STRING, "required": false},
"username": {"name": "_username", "type": TYPE_STRING, "required": false},
}
# A URL for an avatar image.
var _avatar_url
var avatar_url : String:
get:
return "" if not _avatar_url is String else String(_avatar_url)
# The display name of the user.
var _display_name
var display_name : String:
get:
return "" if not _display_name is String else String(_display_name)
# The language expected to be a tag which follows the BCP-47 spec.
var _lang_tag
var lang_tag : String:
get:
return "" if not _lang_tag is String else String(_lang_tag)
# The location set by the user.
var _location
var location : String:
get:
return "" if not _location is String else String(_location)
# The timezone set by the user.
var _timezone
var timezone : String:
get:
return "" if not _timezone is String else String(_timezone)
# The username of the user's account.
var _username
var username : String:
get:
return "" if not _username is String else String(_username)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiUpdateAccountRequest:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiUpdateAccountRequest", p_dict), ApiUpdateAccountRequest) as ApiUpdateAccountRequest
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "avatar_url: %s, " % _avatar_url
output += "display_name: %s, " % _display_name
output += "lang_tag: %s, " % _lang_tag
output += "location: %s, " % _location
output += "timezone: %s, " % _timezone
output += "username: %s, " % _username
return output
# Update fields in a given group.
class ApiUpdateGroupRequest extends NakamaAsyncResult:
const _SCHEMA = {
"avatar_url": {"name": "_avatar_url", "type": TYPE_STRING, "required": false},
"description": {"name": "_description", "type": TYPE_STRING, "required": false},
"group_id": {"name": "_group_id", "type": TYPE_STRING, "required": false},
"lang_tag": {"name": "_lang_tag", "type": TYPE_STRING, "required": false},
"name": {"name": "_name", "type": TYPE_STRING, "required": false},
"open": {"name": "_open", "type": TYPE_BOOL, "required": false},
}
# Avatar URL.
var _avatar_url
var avatar_url : String:
get:
return "" if not _avatar_url is String else String(_avatar_url)
# Description string.
var _description
var description : String:
get:
return "" if not _description is String else String(_description)
# The ID of the group to update.
var _group_id
var group_id : String:
get:
return "" if not _group_id is String else String(_group_id)
# Lang tag.
var _lang_tag
var lang_tag : String:
get:
return "" if not _lang_tag is String else String(_lang_tag)
# Name.
var _name
var name : String:
get:
return "" if not _name is String else String(_name)
# Open is true if anyone should be allowed to join, or false if joins must be approved by a group admin.
var _open
var open : bool:
get:
return false if not _open is bool else bool(_open)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiUpdateGroupRequest:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiUpdateGroupRequest", p_dict), ApiUpdateGroupRequest) as ApiUpdateGroupRequest
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "avatar_url: %s, " % _avatar_url
output += "description: %s, " % _description
output += "group_id: %s, " % _group_id
output += "lang_tag: %s, " % _lang_tag
output += "name: %s, " % _name
output += "open: %s, " % _open
return output
# A user in the server.
class ApiUser extends NakamaAsyncResult:
const _SCHEMA = {
"apple_id": {"name": "_apple_id", "type": TYPE_STRING, "required": false},
"avatar_url": {"name": "_avatar_url", "type": TYPE_STRING, "required": false},
"create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false},
"display_name": {"name": "_display_name", "type": TYPE_STRING, "required": false},
"edge_count": {"name": "_edge_count", "type": TYPE_INT, "required": false},
"facebook_id": {"name": "_facebook_id", "type": TYPE_STRING, "required": false},
"facebook_instant_game_id": {"name": "_facebook_instant_game_id", "type": TYPE_STRING, "required": false},
"gamecenter_id": {"name": "_gamecenter_id", "type": TYPE_STRING, "required": false},
"google_id": {"name": "_google_id", "type": TYPE_STRING, "required": false},
"id": {"name": "_id", "type": TYPE_STRING, "required": false},
"lang_tag": {"name": "_lang_tag", "type": TYPE_STRING, "required": false},
"location": {"name": "_location", "type": TYPE_STRING, "required": false},
"metadata": {"name": "_metadata", "type": TYPE_STRING, "required": false},
"online": {"name": "_online", "type": TYPE_BOOL, "required": false},
"steam_id": {"name": "_steam_id", "type": TYPE_STRING, "required": false},
"timezone": {"name": "_timezone", "type": TYPE_STRING, "required": false},
"update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false},
"username": {"name": "_username", "type": TYPE_STRING, "required": false},
}
# The Apple Sign In ID in the user's account.
var _apple_id
var apple_id : String:
get:
return "" if not _apple_id is String else String(_apple_id)
# A URL for an avatar image.
var _avatar_url
var avatar_url : String:
get:
return "" if not _avatar_url is String else String(_avatar_url)
# The UNIX time when the user was created.
var _create_time
var create_time : String:
get:
return "" if not _create_time is String else String(_create_time)
# The display name of the user.
var _display_name
var display_name : String:
get:
return "" if not _display_name is String else String(_display_name)
# Number of related edges to this user.
var _edge_count
var edge_count : int:
get:
return 0 if not _edge_count is int else int(_edge_count)
# The Facebook id in the user's account.
var _facebook_id
var facebook_id : String:
get:
return "" if not _facebook_id is String else String(_facebook_id)
# The Facebook Instant Game ID in the user's account.
var _facebook_instant_game_id
var facebook_instant_game_id : String:
get:
return "" if not _facebook_instant_game_id is String else String(_facebook_instant_game_id)
# The Apple Game Center in of the user's account.
var _gamecenter_id
var gamecenter_id : String:
get:
return "" if not _gamecenter_id is String else String(_gamecenter_id)
# The Google id in the user's account.
var _google_id
var google_id : String:
get:
return "" if not _google_id is String else String(_google_id)
# The id of the user's account.
var _id
var id : String:
get:
return "" if not _id is String else String(_id)
# The language expected to be a tag which follows the BCP-47 spec.
var _lang_tag
var lang_tag : String:
get:
return "" if not _lang_tag is String else String(_lang_tag)
# The location set by the user.
var _location
var location : String:
get:
return "" if not _location is String else String(_location)
# Additional information stored as a JSON object.
var _metadata
var metadata : String:
get:
return "" if not _metadata is String else String(_metadata)
# Indicates whether the user is currently online.
var _online
var online : bool:
get:
return false if not _online is bool else bool(_online)
# The Steam id in the user's account.
var _steam_id
var steam_id : String:
get:
return "" if not _steam_id is String else String(_steam_id)
# The timezone set by the user.
var _timezone
var timezone : String:
get:
return "" if not _timezone is String else String(_timezone)
# The UNIX time when the user was last updated.
var _update_time
var update_time : String:
get:
return "" if not _update_time is String else String(_update_time)
# The username of the user's account.
var _username
var username : String:
get:
return "" if not _username is String else String(_username)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiUser:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiUser", p_dict), ApiUser) as ApiUser
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "apple_id: %s, " % _apple_id
output += "avatar_url: %s, " % _avatar_url
output += "create_time: %s, " % _create_time
output += "display_name: %s, " % _display_name
output += "edge_count: %s, " % _edge_count
output += "facebook_id: %s, " % _facebook_id
output += "facebook_instant_game_id: %s, " % _facebook_instant_game_id
output += "gamecenter_id: %s, " % _gamecenter_id
output += "google_id: %s, " % _google_id
output += "id: %s, " % _id
output += "lang_tag: %s, " % _lang_tag
output += "location: %s, " % _location
output += "metadata: %s, " % _metadata
output += "online: %s, " % _online
output += "steam_id: %s, " % _steam_id
output += "timezone: %s, " % _timezone
output += "update_time: %s, " % _update_time
output += "username: %s, " % _username
return output
# A list of groups belonging to a user, along with the user's role in each group.
class ApiUserGroupList extends NakamaAsyncResult:
const _SCHEMA = {
"cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false},
"user_groups": {"name": "_user_groups", "type": TYPE_ARRAY, "required": false, "content": "UserGroupListUserGroup"},
}
# Cursor for the next page of results, if any.
var _cursor
var cursor : String:
get:
return "" if not _cursor is String else String(_cursor)
# Group-role pairs for a user.
var _user_groups
var user_groups : Array:
get:
return Array() if not _user_groups is Array else Array(_user_groups)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiUserGroupList:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiUserGroupList", p_dict), ApiUserGroupList) as ApiUserGroupList
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "cursor: %s, " % _cursor
output += "user_groups: %s, " % [_user_groups]
return output
# A collection of zero or more users.
class ApiUsers extends NakamaAsyncResult:
const _SCHEMA = {
"users": {"name": "_users", "type": TYPE_ARRAY, "required": false, "content": "ApiUser"},
}
# The User objects.
var _users
var users : Array:
get:
return Array() if not _users is Array else Array(_users)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiUsers:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiUsers", p_dict), ApiUsers) as ApiUsers
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "users: %s, " % [_users]
return output
#
class ApiValidatePurchaseAppleRequest extends NakamaAsyncResult:
const _SCHEMA = {
"persist": {"name": "_persist", "type": TYPE_BOOL, "required": false},
"receipt": {"name": "_receipt", "type": TYPE_STRING, "required": false},
}
#
var _persist
var persist : bool:
get:
return false if not _persist is bool else bool(_persist)
# Base64 encoded Apple receipt data payload.
var _receipt
var receipt : String:
get:
return "" if not _receipt is String else String(_receipt)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiValidatePurchaseAppleRequest:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiValidatePurchaseAppleRequest", p_dict), ApiValidatePurchaseAppleRequest) as ApiValidatePurchaseAppleRequest
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "persist: %s, " % _persist
output += "receipt: %s, " % _receipt
return output
#
class ApiValidatePurchaseGoogleRequest extends NakamaAsyncResult:
const _SCHEMA = {
"persist": {"name": "_persist", "type": TYPE_BOOL, "required": false},
"purchase": {"name": "_purchase", "type": TYPE_STRING, "required": false},
}
#
var _persist
var persist : bool:
get:
return false if not _persist is bool else bool(_persist)
# JSON encoded Google purchase payload.
var _purchase
var purchase : String:
get:
return "" if not _purchase is String else String(_purchase)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiValidatePurchaseGoogleRequest:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiValidatePurchaseGoogleRequest", p_dict), ApiValidatePurchaseGoogleRequest) as ApiValidatePurchaseGoogleRequest
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "persist: %s, " % _persist
output += "purchase: %s, " % _purchase
return output
#
class ApiValidatePurchaseHuaweiRequest extends NakamaAsyncResult:
const _SCHEMA = {
"persist": {"name": "_persist", "type": TYPE_BOOL, "required": false},
"purchase": {"name": "_purchase", "type": TYPE_STRING, "required": false},
"signature": {"name": "_signature", "type": TYPE_STRING, "required": false},
}
#
var _persist
var persist : bool:
get:
return false if not _persist is bool else bool(_persist)
# JSON encoded Huawei InAppPurchaseData.
var _purchase
var purchase : String:
get:
return "" if not _purchase is String else String(_purchase)
# InAppPurchaseData signature.
var _signature
var signature : String:
get:
return "" if not _signature is String else String(_signature)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiValidatePurchaseHuaweiRequest:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiValidatePurchaseHuaweiRequest", p_dict), ApiValidatePurchaseHuaweiRequest) as ApiValidatePurchaseHuaweiRequest
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "persist: %s, " % _persist
output += "purchase: %s, " % _purchase
output += "signature: %s, " % _signature
return output
# Validate IAP response.
class ApiValidatePurchaseResponse extends NakamaAsyncResult:
const _SCHEMA = {
"validated_purchases": {"name": "_validated_purchases", "type": TYPE_ARRAY, "required": false, "content": "ApiValidatedPurchase"},
}
# Newly seen validated purchases.
var _validated_purchases
var validated_purchases : Array:
get:
return Array() if not _validated_purchases is Array else Array(_validated_purchases)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiValidatePurchaseResponse:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiValidatePurchaseResponse", p_dict), ApiValidatePurchaseResponse) as ApiValidatePurchaseResponse
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "validated_purchases: %s, " % [_validated_purchases]
return output
#
class ApiValidateSubscriptionAppleRequest extends NakamaAsyncResult:
const _SCHEMA = {
"persist": {"name": "_persist", "type": TYPE_BOOL, "required": false},
"receipt": {"name": "_receipt", "type": TYPE_STRING, "required": false},
}
# Persist the subscription.
var _persist
var persist : bool:
get:
return false if not _persist is bool else bool(_persist)
# Base64 encoded Apple receipt data payload.
var _receipt
var receipt : String:
get:
return "" if not _receipt is String else String(_receipt)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiValidateSubscriptionAppleRequest:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiValidateSubscriptionAppleRequest", p_dict), ApiValidateSubscriptionAppleRequest) as ApiValidateSubscriptionAppleRequest
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "persist: %s, " % _persist
output += "receipt: %s, " % _receipt
return output
#
class ApiValidateSubscriptionGoogleRequest extends NakamaAsyncResult:
const _SCHEMA = {
"persist": {"name": "_persist", "type": TYPE_BOOL, "required": false},
"receipt": {"name": "_receipt", "type": TYPE_STRING, "required": false},
}
# Persist the subscription.
var _persist
var persist : bool:
get:
return false if not _persist is bool else bool(_persist)
# JSON encoded Google purchase payload.
var _receipt
var receipt : String:
get:
return "" if not _receipt is String else String(_receipt)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiValidateSubscriptionGoogleRequest:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiValidateSubscriptionGoogleRequest", p_dict), ApiValidateSubscriptionGoogleRequest) as ApiValidateSubscriptionGoogleRequest
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "persist: %s, " % _persist
output += "receipt: %s, " % _receipt
return output
# Validate Subscription response.
class ApiValidateSubscriptionResponse extends NakamaAsyncResult:
const _SCHEMA = {
"validated_subscription": {"name": "_validated_subscription", "type": "ApiValidatedSubscription", "required": false},
}
#
var _validated_subscription
var validated_subscription : ApiValidatedSubscription:
get:
return _validated_subscription as ApiValidatedSubscription
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiValidateSubscriptionResponse:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiValidateSubscriptionResponse", p_dict), ApiValidateSubscriptionResponse) as ApiValidateSubscriptionResponse
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "validated_subscription: %s, " % _validated_subscription
return output
# Validated Purchase stored by Nakama.
class ApiValidatedPurchase extends NakamaAsyncResult:
const _SCHEMA = {
"create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false},
"environment": {"name": "_environment", "type": TYPE_INT, "required": false},
"product_id": {"name": "_product_id", "type": TYPE_STRING, "required": false},
"provider_response": {"name": "_provider_response", "type": TYPE_STRING, "required": false},
"purchase_time": {"name": "_purchase_time", "type": TYPE_STRING, "required": false},
"refund_time": {"name": "_refund_time", "type": TYPE_STRING, "required": false},
"seen_before": {"name": "_seen_before", "type": TYPE_BOOL, "required": false},
"store": {"name": "_store", "type": TYPE_INT, "required": false},
"transaction_id": {"name": "_transaction_id", "type": TYPE_STRING, "required": false},
"update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false},
"user_id": {"name": "_user_id", "type": TYPE_STRING, "required": false},
}
# Timestamp when the receipt validation was stored in DB.
var _create_time
var create_time : String:
get:
return "" if not _create_time is String else String(_create_time)
# Whether the purchase was done in production or sandbox environment.
var _environment
var environment : int:
get:
return ApiStoreEnvironment.values()[0] if not ApiStoreEnvironment.values().has(_environment) else _environment
# Purchase Product ID.
var _product_id
var product_id : String:
get:
return "" if not _product_id is String else String(_product_id)
# Raw provider validation response.
var _provider_response
var provider_response : String:
get:
return "" if not _provider_response is String else String(_provider_response)
# Timestamp when the purchase was done.
var _purchase_time
var purchase_time : String:
get:
return "" if not _purchase_time is String else String(_purchase_time)
#
var _refund_time
var refund_time : String:
get:
return "" if not _refund_time is String else String(_refund_time)
# Whether the purchase had already been validated by Nakama before.
var _seen_before
var seen_before : bool:
get:
return false if not _seen_before is bool else bool(_seen_before)
#
var _store
var store : int:
get:
return ApiStoreProvider.values()[0] if not ApiStoreProvider.values().has(_store) else _store
# Purchase Transaction ID.
var _transaction_id
var transaction_id : String:
get:
return "" if not _transaction_id is String else String(_transaction_id)
# Timestamp when the receipt validation was updated in DB.
var _update_time
var update_time : String:
get:
return "" if not _update_time is String else String(_update_time)
# Purchase User ID.
var _user_id
var user_id : String:
get:
return "" if not _user_id is String else String(_user_id)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiValidatedPurchase:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiValidatedPurchase", p_dict), ApiValidatedPurchase) as ApiValidatedPurchase
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "create_time: %s, " % _create_time
output += "environment: %s, " % _environment
output += "product_id: %s, " % _product_id
output += "provider_response: %s, " % _provider_response
output += "purchase_time: %s, " % _purchase_time
output += "refund_time: %s, " % _refund_time
output += "seen_before: %s, " % _seen_before
output += "store: %s, " % _store
output += "transaction_id: %s, " % _transaction_id
output += "update_time: %s, " % _update_time
output += "user_id: %s, " % _user_id
return output
#
class ApiValidatedSubscription extends NakamaAsyncResult:
const _SCHEMA = {
"active": {"name": "_active", "type": TYPE_BOOL, "required": false},
"create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false},
"environment": {"name": "_environment", "type": TYPE_INT, "required": false},
"expiry_time": {"name": "_expiry_time", "type": TYPE_STRING, "required": false},
"original_transaction_id": {"name": "_original_transaction_id", "type": TYPE_STRING, "required": false},
"product_id": {"name": "_product_id", "type": TYPE_STRING, "required": false},
"provider_notification": {"name": "_provider_notification", "type": TYPE_STRING, "required": false},
"provider_response": {"name": "_provider_response", "type": TYPE_STRING, "required": false},
"purchase_time": {"name": "_purchase_time", "type": TYPE_STRING, "required": false},
"refund_time": {"name": "_refund_time", "type": TYPE_STRING, "required": false},
"store": {"name": "_store", "type": TYPE_INT, "required": false},
"update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false},
"user_id": {"name": "_user_id", "type": TYPE_STRING, "required": false},
}
# Whether the subscription is currently active or not.
var _active
var active : bool:
get:
return false if not _active is bool else bool(_active)
# UNIX Timestamp when the receipt validation was stored in DB.
var _create_time
var create_time : String:
get:
return "" if not _create_time is String else String(_create_time)
# Whether the purchase was done in production or sandbox environment.
var _environment
var environment : int:
get:
return ApiStoreEnvironment.values()[0] if not ApiStoreEnvironment.values().has(_environment) else _environment
# Subscription expiration time. The subscription can still be auto-renewed to extend the expiration time further.
var _expiry_time
var expiry_time : String:
get:
return "" if not _expiry_time is String else String(_expiry_time)
# Purchase Original transaction ID (we only keep track of the original subscription, not subsequent renewals).
var _original_transaction_id
var original_transaction_id : String:
get:
return "" if not _original_transaction_id is String else String(_original_transaction_id)
# Purchase Product ID.
var _product_id
var product_id : String:
get:
return "" if not _product_id is String else String(_product_id)
# Raw provider notification body.
var _provider_notification
var provider_notification : String:
get:
return "" if not _provider_notification is String else String(_provider_notification)
# Raw provider validation response body.
var _provider_response
var provider_response : String:
get:
return "" if not _provider_response is String else String(_provider_response)
# UNIX Timestamp when the purchase was done.
var _purchase_time
var purchase_time : String:
get:
return "" if not _purchase_time is String else String(_purchase_time)
# Subscription refund time. If this time is set, the subscription was refunded.
var _refund_time
var refund_time : String:
get:
return "" if not _refund_time is String else String(_refund_time)
#
var _store
var store : int:
get:
return ApiStoreProvider.values()[0] if not ApiStoreProvider.values().has(_store) else _store
# UNIX Timestamp when the receipt validation was updated in DB.
var _update_time
var update_time : String:
get:
return "" if not _update_time is String else String(_update_time)
# Subscription User ID.
var _user_id
var user_id : String:
get:
return "" if not _user_id is String else String(_user_id)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiValidatedSubscription:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiValidatedSubscription", p_dict), ApiValidatedSubscription) as ApiValidatedSubscription
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "active: %s, " % _active
output += "create_time: %s, " % _create_time
output += "environment: %s, " % _environment
output += "expiry_time: %s, " % _expiry_time
output += "original_transaction_id: %s, " % _original_transaction_id
output += "product_id: %s, " % _product_id
output += "provider_notification: %s, " % _provider_notification
output += "provider_response: %s, " % _provider_response
output += "purchase_time: %s, " % _purchase_time
output += "refund_time: %s, " % _refund_time
output += "store: %s, " % _store
output += "update_time: %s, " % _update_time
output += "user_id: %s, " % _user_id
return output
# The object to store.
class ApiWriteStorageObject extends NakamaAsyncResult:
const _SCHEMA = {
"collection": {"name": "_collection", "type": TYPE_STRING, "required": false},
"key": {"name": "_key", "type": TYPE_STRING, "required": false},
"permission_read": {"name": "_permission_read", "type": TYPE_INT, "required": false},
"permission_write": {"name": "_permission_write", "type": TYPE_INT, "required": false},
"value": {"name": "_value", "type": TYPE_STRING, "required": false},
"version": {"name": "_version", "type": TYPE_STRING, "required": false},
}
# The collection to store the object.
var _collection
var collection : String:
get:
return "" if not _collection is String else String(_collection)
# The key for the object within the collection.
var _key
var key : String:
get:
return "" if not _key is String else String(_key)
# The read access permissions for the object.
var _permission_read
var permission_read : int:
get:
return 0 if not _permission_read is int else int(_permission_read)
# The write access permissions for the object.
var _permission_write
var permission_write : int:
get:
return 0 if not _permission_write is int else int(_permission_write)
# The value of the object.
var _value
var value : String:
get:
return "" if not _value is String else String(_value)
# The version hash of the object to check. Possible values are: ["", "*", "#hash#"].
var _version
var version : String:
get:
return "" if not _version is String else String(_version)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiWriteStorageObject:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiWriteStorageObject", p_dict), ApiWriteStorageObject) as ApiWriteStorageObject
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "collection: %s, " % _collection
output += "key: %s, " % _key
output += "permission_read: %s, " % _permission_read
output += "permission_write: %s, " % _permission_write
output += "value: %s, " % _value
output += "version: %s, " % _version
return output
# Write objects to the storage engine.
class ApiWriteStorageObjectsRequest extends NakamaAsyncResult:
const _SCHEMA = {
"objects": {"name": "_objects", "type": TYPE_ARRAY, "required": false, "content": "ApiWriteStorageObject"},
}
# The objects to store on the server.
var _objects
var objects : Array:
get:
return Array() if not _objects is Array else Array(_objects)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiWriteStorageObjectsRequest:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiWriteStorageObjectsRequest", p_dict), ApiWriteStorageObjectsRequest) as ApiWriteStorageObjectsRequest
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "objects: %s, " % [_objects]
return output
#
class ProtobufAny extends NakamaAsyncResult:
const _SCHEMA = {
"type_url": {"name": "_type_url", "type": TYPE_STRING, "required": false},
"value": {"name": "_value", "type": TYPE_STRING, "required": false},
}
#
var _type_url
var type_url : String:
get:
return "" if not _type_url is String else String(_type_url)
#
var _value
var value : String:
get:
return "" if not _value is String else String(_value)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> ProtobufAny:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ProtobufAny", p_dict), ProtobufAny) as ProtobufAny
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "type_url: %s, " % _type_url
output += "value: %s, " % _value
return output
#
class RpcStatus extends NakamaAsyncResult:
const _SCHEMA = {
"code": {"name": "_code", "type": TYPE_INT, "required": false},
"details": {"name": "_details", "type": TYPE_ARRAY, "required": false, "content": "ProtobufAny"},
"message": {"name": "_message", "type": TYPE_STRING, "required": false},
}
#
var _code
var code : int:
get:
return 0 if not _code is int else int(_code)
#
var _details
var details : Array:
get:
return Array() if not _details is Array else Array(_details)
#
var _message
var message : String:
get:
return "" if not _message is String else String(_message)
func _init(p_exception = null):
super(p_exception)
static func create(p_ns : GDScript, p_dict : Dictionary) -> RpcStatus:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "RpcStatus", p_dict), RpcStatus) as RpcStatus
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string() -> String:
if is_exception():
return get_exception()._to_string()
var output : String = ""
output += "code: %s, " % _code
output += "details: %s, " % [_details]
output += "message: %s, " % _message
return output
# The low level client for the Nakama API.
class ApiClient extends RefCounted:
var _base_uri : String
var _http_adapter
var _namespace : GDScript
var _server_key : String
var auto_refresh := true
var auto_refresh_time := 300
var auto_retry : bool:
set(p_value):
_http_adapter.auto_retry = p_value
get:
return _http_adapter.auto_retry
var auto_retry_count : int:
set(p_value):
_http_adapter.auto_retry_count = p_value
get:
return _http_adapter.auto_retry_count
var auto_retry_backoff_base : int:
set(p_value):
_http_adapter.auto_retry_backoff_base = p_value
get:
return _http_adapter.auto_retry_backoff_base
var last_cancel_token:
get:
return _http_adapter.get_last_token()
func _init(p_base_uri : String, p_http_adapter, p_namespace : GDScript, p_server_key : String, p_timeout : int = 10):
_base_uri = p_base_uri
_http_adapter = p_http_adapter
_http_adapter.timeout = p_timeout
_namespace = p_namespace
_server_key = p_server_key
func _refresh_session(p_session : NakamaSession):
if auto_refresh and p_session.is_valid() and p_session.refresh_token and not p_session.is_refresh_expired() and p_session.would_expire_in(auto_refresh_time):
var request = ApiSessionRefreshRequest.new()
request._token = p_session.refresh_token
return await session_refresh_async(_server_key, "", request)
return null
func cancel_request(p_token):
if p_token:
_http_adapter.cancel_request(p_token)
# A healthcheck which load balancers can use to check the service.
func healthcheck_async(
p_session : NakamaSession
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/healthcheck"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Delete the current user's account.
func delete_account_async(
p_session : NakamaSession
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "DELETE"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Fetch the current user's account.
func get_account_async(
p_session : NakamaSession
) -> ApiAccount:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiAccount.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiAccount.new(result)
var out : ApiAccount = NakamaSerializer.deserialize(_namespace, "ApiAccount", result)
return out
# Update fields in the current user's account.
func update_account_async(
p_session : NakamaSession
, p_body : ApiUpdateAccountRequest
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "PUT"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Authenticate a user with an Apple ID against the server.
func authenticate_apple_async(
p_basic_auth_username : String
, p_basic_auth_password : String
, p_account : ApiAccountApple
, p_create = null # : boolean
, p_username = null # : string
) -> ApiSession:
var urlpath : String = "/v2/account/authenticate/apple"
var query_params = ""
if p_create != null:
query_params += "create=%s&" % str(bool(p_create)).to_lower()
if p_username != null:
query_params += "username=%s&" % NakamaSerializer.escape_http(p_username)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password)
var header = "Basic %s" % credentials
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_account.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiSession.new(result)
var out : ApiSession = NakamaSerializer.deserialize(_namespace, "ApiSession", result)
return out
# Authenticate a user with a custom id against the server.
func authenticate_custom_async(
p_basic_auth_username : String
, p_basic_auth_password : String
, p_account : ApiAccountCustom
, p_create = null # : boolean
, p_username = null # : string
) -> ApiSession:
var urlpath : String = "/v2/account/authenticate/custom"
var query_params = ""
if p_create != null:
query_params += "create=%s&" % str(bool(p_create)).to_lower()
if p_username != null:
query_params += "username=%s&" % NakamaSerializer.escape_http(p_username)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password)
var header = "Basic %s" % credentials
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_account.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiSession.new(result)
var out : ApiSession = NakamaSerializer.deserialize(_namespace, "ApiSession", result)
return out
# Authenticate a user with a device id against the server.
func authenticate_device_async(
p_basic_auth_username : String
, p_basic_auth_password : String
, p_account : ApiAccountDevice
, p_create = null # : boolean
, p_username = null # : string
) -> ApiSession:
var urlpath : String = "/v2/account/authenticate/device"
var query_params = ""
if p_create != null:
query_params += "create=%s&" % str(bool(p_create)).to_lower()
if p_username != null:
query_params += "username=%s&" % NakamaSerializer.escape_http(p_username)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password)
var header = "Basic %s" % credentials
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_account.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiSession.new(result)
var out : ApiSession = NakamaSerializer.deserialize(_namespace, "ApiSession", result)
return out
# Authenticate a user with an email+password against the server.
func authenticate_email_async(
p_basic_auth_username : String
, p_basic_auth_password : String
, p_account : ApiAccountEmail
, p_create = null # : boolean
, p_username = null # : string
) -> ApiSession:
var urlpath : String = "/v2/account/authenticate/email"
var query_params = ""
if p_create != null:
query_params += "create=%s&" % str(bool(p_create)).to_lower()
if p_username != null:
query_params += "username=%s&" % NakamaSerializer.escape_http(p_username)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password)
var header = "Basic %s" % credentials
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_account.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiSession.new(result)
var out : ApiSession = NakamaSerializer.deserialize(_namespace, "ApiSession", result)
return out
# Authenticate a user with a Facebook OAuth token against the server.
func authenticate_facebook_async(
p_basic_auth_username : String
, p_basic_auth_password : String
, p_account : ApiAccountFacebook
, p_create = null # : boolean
, p_username = null # : string
, p_sync = null # : boolean
) -> ApiSession:
var urlpath : String = "/v2/account/authenticate/facebook"
var query_params = ""
if p_create != null:
query_params += "create=%s&" % str(bool(p_create)).to_lower()
if p_username != null:
query_params += "username=%s&" % NakamaSerializer.escape_http(p_username)
if p_sync != null:
query_params += "sync=%s&" % str(bool(p_sync)).to_lower()
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password)
var header = "Basic %s" % credentials
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_account.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiSession.new(result)
var out : ApiSession = NakamaSerializer.deserialize(_namespace, "ApiSession", result)
return out
# Authenticate a user with a Facebook Instant Game token against the server.
func authenticate_facebook_instant_game_async(
p_basic_auth_username : String
, p_basic_auth_password : String
, p_account : ApiAccountFacebookInstantGame
, p_create = null # : boolean
, p_username = null # : string
) -> ApiSession:
var urlpath : String = "/v2/account/authenticate/facebookinstantgame"
var query_params = ""
if p_create != null:
query_params += "create=%s&" % str(bool(p_create)).to_lower()
if p_username != null:
query_params += "username=%s&" % NakamaSerializer.escape_http(p_username)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password)
var header = "Basic %s" % credentials
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_account.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiSession.new(result)
var out : ApiSession = NakamaSerializer.deserialize(_namespace, "ApiSession", result)
return out
# Authenticate a user with Apple's GameCenter against the server.
func authenticate_game_center_async(
p_basic_auth_username : String
, p_basic_auth_password : String
, p_account : ApiAccountGameCenter
, p_create = null # : boolean
, p_username = null # : string
) -> ApiSession:
var urlpath : String = "/v2/account/authenticate/gamecenter"
var query_params = ""
if p_create != null:
query_params += "create=%s&" % str(bool(p_create)).to_lower()
if p_username != null:
query_params += "username=%s&" % NakamaSerializer.escape_http(p_username)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password)
var header = "Basic %s" % credentials
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_account.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiSession.new(result)
var out : ApiSession = NakamaSerializer.deserialize(_namespace, "ApiSession", result)
return out
# Authenticate a user with Google against the server.
func authenticate_google_async(
p_basic_auth_username : String
, p_basic_auth_password : String
, p_account : ApiAccountGoogle
, p_create = null # : boolean
, p_username = null # : string
) -> ApiSession:
var urlpath : String = "/v2/account/authenticate/google"
var query_params = ""
if p_create != null:
query_params += "create=%s&" % str(bool(p_create)).to_lower()
if p_username != null:
query_params += "username=%s&" % NakamaSerializer.escape_http(p_username)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password)
var header = "Basic %s" % credentials
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_account.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiSession.new(result)
var out : ApiSession = NakamaSerializer.deserialize(_namespace, "ApiSession", result)
return out
# Authenticate a user with Steam against the server.
func authenticate_steam_async(
p_basic_auth_username : String
, p_basic_auth_password : String
, p_account : ApiAccountSteam
, p_create = null # : boolean
, p_username = null # : string
, p_sync = null # : boolean
) -> ApiSession:
var urlpath : String = "/v2/account/authenticate/steam"
var query_params = ""
if p_create != null:
query_params += "create=%s&" % str(bool(p_create)).to_lower()
if p_username != null:
query_params += "username=%s&" % NakamaSerializer.escape_http(p_username)
if p_sync != null:
query_params += "sync=%s&" % str(bool(p_sync)).to_lower()
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password)
var header = "Basic %s" % credentials
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_account.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiSession.new(result)
var out : ApiSession = NakamaSerializer.deserialize(_namespace, "ApiSession", result)
return out
# Add an Apple ID to the social profiles on the current user's account.
func link_apple_async(
p_session : NakamaSession
, p_body : ApiAccountApple
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account/link/apple"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Add a custom ID to the social profiles on the current user's account.
func link_custom_async(
p_session : NakamaSession
, p_body : ApiAccountCustom
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account/link/custom"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Add a device ID to the social profiles on the current user's account.
func link_device_async(
p_session : NakamaSession
, p_body : ApiAccountDevice
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account/link/device"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Add an email+password to the social profiles on the current user's account.
func link_email_async(
p_session : NakamaSession
, p_body : ApiAccountEmail
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account/link/email"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Add Facebook to the social profiles on the current user's account.
func link_facebook_async(
p_session : NakamaSession
, p_account : ApiAccountFacebook
, p_sync = null # : boolean
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account/link/facebook"
var query_params = ""
if p_sync != null:
query_params += "sync=%s&" % str(bool(p_sync)).to_lower()
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_account.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Add Facebook Instant Game to the social profiles on the current user's account.
func link_facebook_instant_game_async(
p_session : NakamaSession
, p_body : ApiAccountFacebookInstantGame
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account/link/facebookinstantgame"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Add Apple's GameCenter to the social profiles on the current user's account.
func link_game_center_async(
p_session : NakamaSession
, p_body : ApiAccountGameCenter
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account/link/gamecenter"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Add Google to the social profiles on the current user's account.
func link_google_async(
p_session : NakamaSession
, p_body : ApiAccountGoogle
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account/link/google"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Add Steam to the social profiles on the current user's account.
func link_steam_async(
p_session : NakamaSession
, p_body : ApiLinkSteamRequest
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account/link/steam"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Refresh a user's session using a refresh token retrieved from a previous authentication request.
func session_refresh_async(
p_basic_auth_username : String
, p_basic_auth_password : String
, p_body : ApiSessionRefreshRequest
) -> ApiSession:
var urlpath : String = "/v2/account/session/refresh"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password)
var header = "Basic %s" % credentials
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiSession.new(result)
var out : ApiSession = NakamaSerializer.deserialize(_namespace, "ApiSession", result)
return out
# Remove the Apple ID from the social profiles on the current user's account.
func unlink_apple_async(
p_session : NakamaSession
, p_body : ApiAccountApple
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account/unlink/apple"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Remove the custom ID from the social profiles on the current user's account.
func unlink_custom_async(
p_session : NakamaSession
, p_body : ApiAccountCustom
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account/unlink/custom"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Remove the device ID from the social profiles on the current user's account.
func unlink_device_async(
p_session : NakamaSession
, p_body : ApiAccountDevice
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account/unlink/device"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Remove the email+password from the social profiles on the current user's account.
func unlink_email_async(
p_session : NakamaSession
, p_body : ApiAccountEmail
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account/unlink/email"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Remove Facebook from the social profiles on the current user's account.
func unlink_facebook_async(
p_session : NakamaSession
, p_body : ApiAccountFacebook
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account/unlink/facebook"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Remove Facebook Instant Game profile from the social profiles on the current user's account.
func unlink_facebook_instant_game_async(
p_session : NakamaSession
, p_body : ApiAccountFacebookInstantGame
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account/unlink/facebookinstantgame"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Remove Apple's GameCenter from the social profiles on the current user's account.
func unlink_game_center_async(
p_session : NakamaSession
, p_body : ApiAccountGameCenter
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account/unlink/gamecenter"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Remove Google from the social profiles on the current user's account.
func unlink_google_async(
p_session : NakamaSession
, p_body : ApiAccountGoogle
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account/unlink/google"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Remove Steam from the social profiles on the current user's account.
func unlink_steam_async(
p_session : NakamaSession
, p_body : ApiAccountSteam
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/account/unlink/steam"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# List a channel's message history.
func list_channel_messages_async(
p_session : NakamaSession
, p_channel_id : String
, p_limit = null # : integer
, p_forward = null # : boolean
, p_cursor = null # : string
) -> ApiChannelMessageList:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiChannelMessageList.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/channel/{channelId}"
urlpath = urlpath.replace("{channelId}", NakamaSerializer.escape_http(p_channel_id))
var query_params = ""
if p_limit != null:
query_params += "limit=%d&" % p_limit
if p_forward != null:
query_params += "forward=%s&" % str(bool(p_forward)).to_lower()
if p_cursor != null:
query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiChannelMessageList.new(result)
var out : ApiChannelMessageList = NakamaSerializer.deserialize(_namespace, "ApiChannelMessageList", result)
return out
# Submit an event for processing in the server's registered runtime custom events handler.
func event_async(
p_session : NakamaSession
, p_body : ApiEvent
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/event"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Delete one or more users by ID or username.
func delete_friends_async(
p_session : NakamaSession
, p_ids = null # : array
, p_usernames = null # : array
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/friend"
var query_params = ""
if p_ids != null:
for elem in p_ids:
query_params += "ids=%s&" % elem
if p_usernames != null:
for elem in p_usernames:
query_params += "usernames=%s&" % elem
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "DELETE"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# List all friends for the current user.
func list_friends_async(
p_session : NakamaSession
, p_limit = null # : integer
, p_state = null # : integer
, p_cursor = null # : string
) -> ApiFriendList:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiFriendList.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/friend"
var query_params = ""
if p_limit != null:
query_params += "limit=%d&" % p_limit
if p_state != null:
query_params += "state=%d&" % p_state
if p_cursor != null:
query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiFriendList.new(result)
var out : ApiFriendList = NakamaSerializer.deserialize(_namespace, "ApiFriendList", result)
return out
# Add friends by ID or username to a user's account.
func add_friends_async(
p_session : NakamaSession
, p_ids = null # : array
, p_usernames = null # : array
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/friend"
var query_params = ""
if p_ids != null:
for elem in p_ids:
query_params += "ids=%s&" % elem
if p_usernames != null:
for elem in p_usernames:
query_params += "usernames=%s&" % elem
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Block one or more users by ID or username.
func block_friends_async(
p_session : NakamaSession
, p_ids = null # : array
, p_usernames = null # : array
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/friend/block"
var query_params = ""
if p_ids != null:
for elem in p_ids:
query_params += "ids=%s&" % elem
if p_usernames != null:
for elem in p_usernames:
query_params += "usernames=%s&" % elem
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Import Facebook friends and add them to a user's account.
func import_facebook_friends_async(
p_session : NakamaSession
, p_account : ApiAccountFacebook
, p_reset = null # : boolean
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/friend/facebook"
var query_params = ""
if p_reset != null:
query_params += "reset=%s&" % str(bool(p_reset)).to_lower()
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_account.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Import Steam friends and add them to a user's account.
func import_steam_friends_async(
p_session : NakamaSession
, p_account : ApiAccountSteam
, p_reset = null # : boolean
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/friend/steam"
var query_params = ""
if p_reset != null:
query_params += "reset=%s&" % str(bool(p_reset)).to_lower()
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_account.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# List groups based on given filters.
func list_groups_async(
p_session : NakamaSession
, p_name = null # : string
, p_cursor = null # : string
, p_limit = null # : integer
, p_lang_tag = null # : string
, p_members = null # : integer
, p_open = null # : boolean
) -> ApiGroupList:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiGroupList.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/group"
var query_params = ""
if p_name != null:
query_params += "name=%s&" % NakamaSerializer.escape_http(p_name)
if p_cursor != null:
query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor)
if p_limit != null:
query_params += "limit=%d&" % p_limit
if p_lang_tag != null:
query_params += "lang_tag=%s&" % NakamaSerializer.escape_http(p_lang_tag)
if p_members != null:
query_params += "members=%d&" % p_members
if p_open != null:
query_params += "open=%s&" % str(bool(p_open)).to_lower()
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiGroupList.new(result)
var out : ApiGroupList = NakamaSerializer.deserialize(_namespace, "ApiGroupList", result)
return out
# Create a new group with the current user as the owner.
func create_group_async(
p_session : NakamaSession
, p_body : ApiCreateGroupRequest
) -> ApiGroup:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiGroup.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/group"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiGroup.new(result)
var out : ApiGroup = NakamaSerializer.deserialize(_namespace, "ApiGroup", result)
return out
# Delete a group by ID.
func delete_group_async(
p_session : NakamaSession
, p_group_id : String
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/group/{groupId}"
urlpath = urlpath.replace("{groupId}", NakamaSerializer.escape_http(p_group_id))
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "DELETE"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Update fields in a given group.
func update_group_async(
p_session : NakamaSession
, p_group_id : String
, p_body : ApiUpdateGroupRequest
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/group/{groupId}"
urlpath = urlpath.replace("{groupId}", NakamaSerializer.escape_http(p_group_id))
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "PUT"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Add users to a group.
func add_group_users_async(
p_session : NakamaSession
, p_group_id : String
, p_user_ids = null # : array
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/group/{groupId}/add"
urlpath = urlpath.replace("{groupId}", NakamaSerializer.escape_http(p_group_id))
var query_params = ""
if p_user_ids != null:
for elem in p_user_ids:
query_params += "user_ids=%s&" % elem
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Ban a set of users from a group.
func ban_group_users_async(
p_session : NakamaSession
, p_group_id : String
, p_user_ids = null # : array
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/group/{groupId}/ban"
urlpath = urlpath.replace("{groupId}", NakamaSerializer.escape_http(p_group_id))
var query_params = ""
if p_user_ids != null:
for elem in p_user_ids:
query_params += "user_ids=%s&" % elem
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Demote a set of users in a group to the next role down.
func demote_group_users_async(
p_session : NakamaSession
, p_group_id : String
, p_user_ids = null # : array
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/group/{groupId}/demote"
urlpath = urlpath.replace("{groupId}", NakamaSerializer.escape_http(p_group_id))
var query_params = ""
if p_user_ids != null:
for elem in p_user_ids:
query_params += "user_ids=%s&" % elem
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Immediately join an open group, or request to join a closed one.
func join_group_async(
p_session : NakamaSession
, p_group_id : String
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/group/{groupId}/join"
urlpath = urlpath.replace("{groupId}", NakamaSerializer.escape_http(p_group_id))
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Kick a set of users from a group.
func kick_group_users_async(
p_session : NakamaSession
, p_group_id : String
, p_user_ids = null # : array
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/group/{groupId}/kick"
urlpath = urlpath.replace("{groupId}", NakamaSerializer.escape_http(p_group_id))
var query_params = ""
if p_user_ids != null:
for elem in p_user_ids:
query_params += "user_ids=%s&" % elem
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Leave a group the user is a member of.
func leave_group_async(
p_session : NakamaSession
, p_group_id : String
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/group/{groupId}/leave"
urlpath = urlpath.replace("{groupId}", NakamaSerializer.escape_http(p_group_id))
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Promote a set of users in a group to the next role up.
func promote_group_users_async(
p_session : NakamaSession
, p_group_id : String
, p_user_ids = null # : array
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/group/{groupId}/promote"
urlpath = urlpath.replace("{groupId}", NakamaSerializer.escape_http(p_group_id))
var query_params = ""
if p_user_ids != null:
for elem in p_user_ids:
query_params += "user_ids=%s&" % elem
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# List all users that are part of a group.
func list_group_users_async(
p_session : NakamaSession
, p_group_id : String
, p_limit = null # : integer
, p_state = null # : integer
, p_cursor = null # : string
) -> ApiGroupUserList:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiGroupUserList.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/group/{groupId}/user"
urlpath = urlpath.replace("{groupId}", NakamaSerializer.escape_http(p_group_id))
var query_params = ""
if p_limit != null:
query_params += "limit=%d&" % p_limit
if p_state != null:
query_params += "state=%d&" % p_state
if p_cursor != null:
query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiGroupUserList.new(result)
var out : ApiGroupUserList = NakamaSerializer.deserialize(_namespace, "ApiGroupUserList", result)
return out
# Validate Apple IAP Receipt
func validate_purchase_apple_async(
p_session : NakamaSession
, p_body : ApiValidatePurchaseAppleRequest
) -> ApiValidatePurchaseResponse:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiValidatePurchaseResponse.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/iap/purchase/apple"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiValidatePurchaseResponse.new(result)
var out : ApiValidatePurchaseResponse = NakamaSerializer.deserialize(_namespace, "ApiValidatePurchaseResponse", result)
return out
# Validate Google IAP Receipt
func validate_purchase_google_async(
p_session : NakamaSession
, p_body : ApiValidatePurchaseGoogleRequest
) -> ApiValidatePurchaseResponse:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiValidatePurchaseResponse.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/iap/purchase/google"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiValidatePurchaseResponse.new(result)
var out : ApiValidatePurchaseResponse = NakamaSerializer.deserialize(_namespace, "ApiValidatePurchaseResponse", result)
return out
# Validate Huawei IAP Receipt
func validate_purchase_huawei_async(
p_session : NakamaSession
, p_body : ApiValidatePurchaseHuaweiRequest
) -> ApiValidatePurchaseResponse:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiValidatePurchaseResponse.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/iap/purchase/huawei"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiValidatePurchaseResponse.new(result)
var out : ApiValidatePurchaseResponse = NakamaSerializer.deserialize(_namespace, "ApiValidatePurchaseResponse", result)
return out
# List user's subscriptions.
func list_subscriptions_async(
p_session : NakamaSession
, p_body : ApiListSubscriptionsRequest
) -> ApiSubscriptionList:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiSubscriptionList.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/iap/subscription"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiSubscriptionList.new(result)
var out : ApiSubscriptionList = NakamaSerializer.deserialize(_namespace, "ApiSubscriptionList", result)
return out
# Validate Apple Subscription Receipt
func validate_subscription_apple_async(
p_session : NakamaSession
, p_body : ApiValidateSubscriptionAppleRequest
) -> ApiValidateSubscriptionResponse:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiValidateSubscriptionResponse.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/iap/subscription/apple"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiValidateSubscriptionResponse.new(result)
var out : ApiValidateSubscriptionResponse = NakamaSerializer.deserialize(_namespace, "ApiValidateSubscriptionResponse", result)
return out
# Validate Google Subscription Receipt
func validate_subscription_google_async(
p_session : NakamaSession
, p_body : ApiValidateSubscriptionGoogleRequest
) -> ApiValidateSubscriptionResponse:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiValidateSubscriptionResponse.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/iap/subscription/google"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiValidateSubscriptionResponse.new(result)
var out : ApiValidateSubscriptionResponse = NakamaSerializer.deserialize(_namespace, "ApiValidateSubscriptionResponse", result)
return out
# Get subscription by product id.
func get_subscription_async(
p_session : NakamaSession
, p_product_id : String
) -> ApiValidatedSubscription:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiValidatedSubscription.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/iap/subscription/{productId}"
urlpath = urlpath.replace("{productId}", NakamaSerializer.escape_http(p_product_id))
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiValidatedSubscription.new(result)
var out : ApiValidatedSubscription = NakamaSerializer.deserialize(_namespace, "ApiValidatedSubscription", result)
return out
# Delete a leaderboard record.
func delete_leaderboard_record_async(
p_session : NakamaSession
, p_leaderboard_id : String
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/leaderboard/{leaderboardId}"
urlpath = urlpath.replace("{leaderboardId}", NakamaSerializer.escape_http(p_leaderboard_id))
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "DELETE"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# List leaderboard records.
func list_leaderboard_records_async(
p_session : NakamaSession
, p_leaderboard_id : String
, p_owner_ids = null # : array
, p_limit = null # : integer
, p_cursor = null # : string
, p_expiry = null # : string
) -> ApiLeaderboardRecordList:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiLeaderboardRecordList.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/leaderboard/{leaderboardId}"
urlpath = urlpath.replace("{leaderboardId}", NakamaSerializer.escape_http(p_leaderboard_id))
var query_params = ""
if p_owner_ids != null:
for elem in p_owner_ids:
query_params += "owner_ids=%s&" % elem
if p_limit != null:
query_params += "limit=%d&" % p_limit
if p_cursor != null:
query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor)
if p_expiry != null:
query_params += "expiry=%s&" % NakamaSerializer.escape_http(p_expiry)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiLeaderboardRecordList.new(result)
var out : ApiLeaderboardRecordList = NakamaSerializer.deserialize(_namespace, "ApiLeaderboardRecordList", result)
return out
# Write a record to a leaderboard.
func write_leaderboard_record_async(
p_session : NakamaSession
, p_leaderboard_id : String
, p_record : WriteLeaderboardRecordRequestLeaderboardRecordWrite
) -> ApiLeaderboardRecord:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiLeaderboardRecord.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/leaderboard/{leaderboardId}"
urlpath = urlpath.replace("{leaderboardId}", NakamaSerializer.escape_http(p_leaderboard_id))
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_record.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiLeaderboardRecord.new(result)
var out : ApiLeaderboardRecord = NakamaSerializer.deserialize(_namespace, "ApiLeaderboardRecord", result)
return out
# List leaderboard records that belong to a user.
func list_leaderboard_records_around_owner_async(
p_session : NakamaSession
, p_leaderboard_id : String
, p_owner_id : String
, p_limit = null # : integer
, p_expiry = null # : string
, p_cursor = null # : string
) -> ApiLeaderboardRecordList:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiLeaderboardRecordList.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/leaderboard/{leaderboardId}/owner/{ownerId}"
urlpath = urlpath.replace("{leaderboardId}", NakamaSerializer.escape_http(p_leaderboard_id))
urlpath = urlpath.replace("{ownerId}", NakamaSerializer.escape_http(p_owner_id))
var query_params = ""
if p_limit != null:
query_params += "limit=%d&" % p_limit
if p_expiry != null:
query_params += "expiry=%s&" % NakamaSerializer.escape_http(p_expiry)
if p_cursor != null:
query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiLeaderboardRecordList.new(result)
var out : ApiLeaderboardRecordList = NakamaSerializer.deserialize(_namespace, "ApiLeaderboardRecordList", result)
return out
# Fetch list of running matches.
func list_matches_async(
p_session : NakamaSession
, p_limit = null # : integer
, p_authoritative = null # : boolean
, p_label = null # : string
, p_min_size = null # : integer
, p_max_size = null # : integer
, p_query = null # : string
) -> ApiMatchList:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiMatchList.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/match"
var query_params = ""
if p_limit != null:
query_params += "limit=%d&" % p_limit
if p_authoritative != null:
query_params += "authoritative=%s&" % str(bool(p_authoritative)).to_lower()
if p_label != null:
query_params += "label=%s&" % NakamaSerializer.escape_http(p_label)
if p_min_size != null:
query_params += "min_size=%d&" % p_min_size
if p_max_size != null:
query_params += "max_size=%d&" % p_max_size
if p_query != null:
query_params += "query=%s&" % NakamaSerializer.escape_http(p_query)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiMatchList.new(result)
var out : ApiMatchList = NakamaSerializer.deserialize(_namespace, "ApiMatchList", result)
return out
# Delete one or more notifications for the current user.
func delete_notifications_async(
p_session : NakamaSession
, p_ids = null # : array
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/notification"
var query_params = ""
if p_ids != null:
for elem in p_ids:
query_params += "ids=%s&" % elem
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "DELETE"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Fetch list of notifications.
func list_notifications_async(
p_session : NakamaSession
, p_limit = null # : integer
, p_cacheable_cursor = null # : string
) -> ApiNotificationList:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiNotificationList.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/notification"
var query_params = ""
if p_limit != null:
query_params += "limit=%d&" % p_limit
if p_cacheable_cursor != null:
query_params += "cacheable_cursor=%s&" % NakamaSerializer.escape_http(p_cacheable_cursor)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiNotificationList.new(result)
var out : ApiNotificationList = NakamaSerializer.deserialize(_namespace, "ApiNotificationList", result)
return out
# Execute a Lua function on the server.
func rpc_func2_async(
p_bearer_token : String
, p_id : String
, p_payload = null # : string
, p_http_key = null # : string
) -> ApiRpc:
var urlpath : String = "/v2/rpc/{id}"
urlpath = urlpath.replace("{id}", NakamaSerializer.escape_http(p_id))
var query_params = ""
if p_payload != null:
query_params += "payload=%s&" % NakamaSerializer.escape_http(p_payload)
if p_http_key != null:
query_params += "http_key=%s&" % NakamaSerializer.escape_http(p_http_key)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
if (p_bearer_token):
var header = "Bearer %s" % p_bearer_token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiRpc.new(result)
var out : ApiRpc = NakamaSerializer.deserialize(_namespace, "ApiRpc", result)
return out
# Execute a Lua function on the server.
func rpc_func_async(
p_bearer_token : String
, p_id : String
, p_payload : String
, p_http_key = null # : string
) -> ApiRpc:
var urlpath : String = "/v2/rpc/{id}"
urlpath = urlpath.replace("{id}", NakamaSerializer.escape_http(p_id))
var query_params = ""
if p_http_key != null:
query_params += "http_key=%s&" % NakamaSerializer.escape_http(p_http_key)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
if (p_bearer_token):
var header = "Bearer %s" % p_bearer_token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_payload).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiRpc.new(result)
var out : ApiRpc = NakamaSerializer.deserialize(_namespace, "ApiRpc", result)
return out
# Log out a session, invalidate a refresh token, or log out all sessions/refresh tokens for a user.
func session_logout_async(
p_session : NakamaSession
, p_body : ApiSessionLogoutRequest
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/session/logout"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# Get storage objects.
func read_storage_objects_async(
p_session : NakamaSession
, p_body : ApiReadStorageObjectsRequest
) -> ApiStorageObjects:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiStorageObjects.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/storage"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiStorageObjects.new(result)
var out : ApiStorageObjects = NakamaSerializer.deserialize(_namespace, "ApiStorageObjects", result)
return out
# Write objects into the storage engine.
func write_storage_objects_async(
p_session : NakamaSession
, p_body : ApiWriteStorageObjectsRequest
) -> ApiStorageObjectAcks:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiStorageObjectAcks.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/storage"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "PUT"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiStorageObjectAcks.new(result)
var out : ApiStorageObjectAcks = NakamaSerializer.deserialize(_namespace, "ApiStorageObjectAcks", result)
return out
# Delete one or more objects by ID or username.
func delete_storage_objects_async(
p_session : NakamaSession
, p_body : ApiDeleteStorageObjectsRequest
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/storage/delete"
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "PUT"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_body.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# List publicly readable storage objects in a given collection.
func list_storage_objects_async(
p_session : NakamaSession
, p_collection : String
, p_user_id = null # : string
, p_limit = null # : integer
, p_cursor = null # : string
) -> ApiStorageObjectList:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiStorageObjectList.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/storage/{collection}"
urlpath = urlpath.replace("{collection}", NakamaSerializer.escape_http(p_collection))
var query_params = ""
if p_user_id != null:
query_params += "user_id=%s&" % NakamaSerializer.escape_http(p_user_id)
if p_limit != null:
query_params += "limit=%d&" % p_limit
if p_cursor != null:
query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiStorageObjectList.new(result)
var out : ApiStorageObjectList = NakamaSerializer.deserialize(_namespace, "ApiStorageObjectList", result)
return out
# List publicly readable storage objects in a given collection.
func list_storage_objects2_async(
p_session : NakamaSession
, p_collection : String
, p_user_id : String
, p_limit = null # : integer
, p_cursor = null # : string
) -> ApiStorageObjectList:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiStorageObjectList.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/storage/{collection}/{userId}"
urlpath = urlpath.replace("{collection}", NakamaSerializer.escape_http(p_collection))
urlpath = urlpath.replace("{userId}", NakamaSerializer.escape_http(p_user_id))
var query_params = ""
if p_limit != null:
query_params += "limit=%d&" % p_limit
if p_cursor != null:
query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiStorageObjectList.new(result)
var out : ApiStorageObjectList = NakamaSerializer.deserialize(_namespace, "ApiStorageObjectList", result)
return out
# List current or upcoming tournaments.
func list_tournaments_async(
p_session : NakamaSession
, p_category_start = null # : integer
, p_category_end = null # : integer
, p_start_time = null # : integer
, p_end_time = null # : integer
, p_limit = null # : integer
, p_cursor = null # : string
) -> ApiTournamentList:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiTournamentList.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/tournament"
var query_params = ""
if p_category_start != null:
query_params += "category_start=%d&" % p_category_start
if p_category_end != null:
query_params += "category_end=%d&" % p_category_end
if p_start_time != null:
query_params += "start_time=%d&" % p_start_time
if p_end_time != null:
query_params += "end_time=%d&" % p_end_time
if p_limit != null:
query_params += "limit=%d&" % p_limit
if p_cursor != null:
query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiTournamentList.new(result)
var out : ApiTournamentList = NakamaSerializer.deserialize(_namespace, "ApiTournamentList", result)
return out
# List tournament records.
func list_tournament_records_async(
p_session : NakamaSession
, p_tournament_id : String
, p_owner_ids = null # : array
, p_limit = null # : integer
, p_cursor = null # : string
, p_expiry = null # : string
) -> ApiTournamentRecordList:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiTournamentRecordList.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/tournament/{tournamentId}"
urlpath = urlpath.replace("{tournamentId}", NakamaSerializer.escape_http(p_tournament_id))
var query_params = ""
if p_owner_ids != null:
for elem in p_owner_ids:
query_params += "owner_ids=%s&" % elem
if p_limit != null:
query_params += "limit=%d&" % p_limit
if p_cursor != null:
query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor)
if p_expiry != null:
query_params += "expiry=%s&" % NakamaSerializer.escape_http(p_expiry)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiTournamentRecordList.new(result)
var out : ApiTournamentRecordList = NakamaSerializer.deserialize(_namespace, "ApiTournamentRecordList", result)
return out
# Write a record to a tournament.
func write_tournament_record2_async(
p_session : NakamaSession
, p_tournament_id : String
, p_record : WriteTournamentRecordRequestTournamentRecordWrite
) -> ApiLeaderboardRecord:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiLeaderboardRecord.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/tournament/{tournamentId}"
urlpath = urlpath.replace("{tournamentId}", NakamaSerializer.escape_http(p_tournament_id))
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_record.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiLeaderboardRecord.new(result)
var out : ApiLeaderboardRecord = NakamaSerializer.deserialize(_namespace, "ApiLeaderboardRecord", result)
return out
# Write a record to a tournament.
func write_tournament_record_async(
p_session : NakamaSession
, p_tournament_id : String
, p_record : WriteTournamentRecordRequestTournamentRecordWrite
) -> ApiLeaderboardRecord:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiLeaderboardRecord.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/tournament/{tournamentId}"
urlpath = urlpath.replace("{tournamentId}", NakamaSerializer.escape_http(p_tournament_id))
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "PUT"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
content = JSON.stringify(p_record.serialize()).to_utf8_buffer()
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiLeaderboardRecord.new(result)
var out : ApiLeaderboardRecord = NakamaSerializer.deserialize(_namespace, "ApiLeaderboardRecord", result)
return out
# Attempt to join an open and running tournament.
func join_tournament_async(
p_session : NakamaSession
, p_tournament_id : String
) -> NakamaAsyncResult:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return NakamaAsyncResult.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/tournament/{tournamentId}/join"
urlpath = urlpath.replace("{tournamentId}", NakamaSerializer.escape_http(p_tournament_id))
var query_params = ""
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "POST"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return NakamaAsyncResult.new(result)
return NakamaAsyncResult.new()
# List tournament records for a given owner.
func list_tournament_records_around_owner_async(
p_session : NakamaSession
, p_tournament_id : String
, p_owner_id : String
, p_limit = null # : integer
, p_expiry = null # : string
, p_cursor = null # : string
) -> ApiTournamentRecordList:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiTournamentRecordList.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/tournament/{tournamentId}/owner/{ownerId}"
urlpath = urlpath.replace("{tournamentId}", NakamaSerializer.escape_http(p_tournament_id))
urlpath = urlpath.replace("{ownerId}", NakamaSerializer.escape_http(p_owner_id))
var query_params = ""
if p_limit != null:
query_params += "limit=%d&" % p_limit
if p_expiry != null:
query_params += "expiry=%s&" % NakamaSerializer.escape_http(p_expiry)
if p_cursor != null:
query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiTournamentRecordList.new(result)
var out : ApiTournamentRecordList = NakamaSerializer.deserialize(_namespace, "ApiTournamentRecordList", result)
return out
# Fetch zero or more users by ID and/or username.
func get_users_async(
p_session : NakamaSession
, p_ids = null # : array
, p_usernames = null # : array
, p_facebook_ids = null # : array
) -> ApiUsers:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiUsers.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/user"
var query_params = ""
if p_ids != null:
for elem in p_ids:
query_params += "ids=%s&" % elem
if p_usernames != null:
for elem in p_usernames:
query_params += "usernames=%s&" % elem
if p_facebook_ids != null:
for elem in p_facebook_ids:
query_params += "facebook_ids=%s&" % elem
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiUsers.new(result)
var out : ApiUsers = NakamaSerializer.deserialize(_namespace, "ApiUsers", result)
return out
# List groups the current user belongs to.
func list_user_groups_async(
p_session : NakamaSession
, p_user_id : String
, p_limit = null # : integer
, p_state = null # : integer
, p_cursor = null # : string
) -> ApiUserGroupList:
var try_refresh = await _refresh_session(p_session)
if try_refresh != null:
if try_refresh.is_exception():
return ApiUserGroupList.new(try_refresh.get_exception())
await p_session.refresh(try_refresh)
var urlpath : String = "/v2/user/{userId}/group"
urlpath = urlpath.replace("{userId}", NakamaSerializer.escape_http(p_user_id))
var query_params = ""
if p_limit != null:
query_params += "limit=%d&" % p_limit
if p_state != null:
query_params += "state=%d&" % p_state
if p_cursor != null:
query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor)
var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
var method = "GET"
var headers = {}
var header = "Bearer %s" % p_session.token
headers["Authorization"] = header
var content : PackedByteArray
var result = await _http_adapter.send_async(method, uri, headers, content)
if result is NakamaException:
return ApiUserGroupList.new(result)
var out : ApiUserGroupList = NakamaSerializer.deserialize(_namespace, "ApiUserGroupList", result)
return out
@@ -0,0 +1 @@
uid://duh0d7vmudn4l
@@ -0,0 +1,902 @@
extends NakamaAsyncResult
class_name NakamaRTAPI
# A chat channel on the server.
class Channel extends NakamaAsyncResult:
const _SCHEMA = {
"id": {"name": "id", "type": TYPE_STRING, "required": true},
"presences": {"name": "presences", "type": TYPE_ARRAY, "required": false, "content": "UserPresence"},
"self": {"name": "self_presence", "type": "UserPresence", "required": true},
"room_name": {"name": "room_name", "type": TYPE_STRING, "required": false},
"group_id": {"name": "group_id", "type": TYPE_STRING, "required": false},
"user_id_one": {"name": "user_id_one", "type": TYPE_STRING, "required": false},
"user_id_two": {"name": "user_id_two", "type": TYPE_STRING, "required": false}
}
# The server-assigned channel ID.
var id : String
# The presences visible on the chat channel.
var presences : Array # of objects NakamaUserPresence
# The presence of the current user. i.e. Your self.
var self_presence : NakamaRTAPI.UserPresence
# The name of the chat room, or an empty string if this message was not sent through a chat room.
var room_name : String
# The ID of the group, or an empty string if this message was not sent through a group channel.
var group_id : String
# The ID of the first DM user, or an empty string if this message was not sent through a DM chat.
var user_id_one : String
# The ID of the second DM user, or an empty string if this message was not sent through a DM chat.
var user_id_two : String
func _init(p_ex = null):
super(p_ex)
func _to_string():
if is_exception(): return get_exception()._to_string()
return "Channel<id=%s, presences=%s, self=%s, room_name=%s, group_id=%s, user_id_one=%s, user_id_two=%s>" % [
id, presences, self_presence, room_name, group_id, user_id_one, user_id_two
]
static func create(p_ns : GDScript, p_dict : Dictionary) -> Channel:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "Channel", p_dict), Channel) as Channel
static func get_result_key() -> String:
return "channel"
class ChannelMessageAck extends NakamaAsyncResult:
const _SCHEMA = {
"channel_id": {"name": "channel_id", "type": TYPE_STRING, "required": true},
"code": {"name": "code", "type": TYPE_INT, "required": true},
"create_time": {"name": "create_time", "type": TYPE_STRING, "required": false},
"message_id": {"name": "message_id", "type": TYPE_STRING, "required": true},
"persistent": {"name": "persistent", "type": TYPE_BOOL, "required": false},
"update_time": {"name": "update_time", "type": TYPE_STRING, "required": false},
"username": {"name": "username", "type": TYPE_STRING, "required": false},
"room_name": {"name": "room_name", "type": TYPE_STRING, "required": false},
"group_id": {"name": "group_id", "type": TYPE_STRING, "required": false},
"user_id_one": {"name": "user_id_one", "type": TYPE_STRING, "required": false},
"user_id_two": {"name": "user_id_two", "type": TYPE_STRING, "required": false}
}
# The server-assigned channel ID.
var channel_id : String
# A user-defined code for the chat message.
var code : int
# The UNIX time when the message was created.
var create_time : String
# A unique ID for the chat message.
var message_id : String
# True if the chat message has been stored in history.
var persistent : bool
# The UNIX time when the message was updated.
var update_time : String
# The username of the sender of the message.
var username : String
# The name of the chat room, or an empty string if this message was not sent through a chat room.
var room_name : String
# The ID of the group, or an empty string if this message was not sent through a group channel.
var group_id : String
# The ID of the first DM user, or an empty string if this message was not sent through a DM chat.
var user_id_one : String
# The ID of the second DM user, or an empty string if this message was not sent through a DM chat.
var user_id_two : String
func _init(p_ex = null):
super(p_ex)
func _to_string():
if is_exception(): return get_exception()._to_string()
return "ChannelMessageAck<channel_id=%s, code=%d, create_time=%s, message_id=%s, persistent=%s, update_time=%s, username=%s room_name=%s, group_id=%s, user_id_one=%s, user_id_two=%s>" % [
channel_id, code, create_time, message_id, persistent, update_time, username, room_name, group_id, user_id_one, user_id_two
]
static func create(p_ns : GDScript, p_dict : Dictionary) -> ChannelMessageAck:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ChannelMessageAck", p_dict), ChannelMessageAck) as ChannelMessageAck
static func get_result_key() -> String:
return "channel_message_ack"
# A batch of join and leave presences on a chat channel.
class ChannelPresenceEvent extends NakamaAsyncResult:
const _SCHEMA = {
"channel_id": {"name": "channel_id", "type": TYPE_STRING, "required": true},
"joins": {"name": "joins", "type": TYPE_ARRAY, "required": false, "content" : "UserPresence"},
"leaves": {"name": "leaves", "type": TYPE_ARRAY, "required": false, "content" : "UserPresence"},
"room_name": {"name": "room_name", "type": TYPE_STRING, "required": false},
"group_id": {"name": "group_id", "type": TYPE_STRING, "required": false},
"user_id_one": {"name": "user_id_one", "type": TYPE_STRING, "required": false},
"user_id_two": {"name": "user_id_two", "type": TYPE_STRING, "required": false}
}
# The unique identifier of the chat channel.
var channel_id : String
# Presences of the users who joined the channel.
var joins : Array # UserPresence
# Presences of users who left the channel.
var leaves : Array # UserPresence
# The name of the chat room, or an empty string if this message was not sent through a chat room.
var room_name : String
# The ID of the group, or an empty string if this message was not sent through a group channel.
var group_id : String
# The ID of the first DM user, or an empty string if this message was not sent through a DM chat.
var user_id_one : String
# The ID of the second DM user, or an empty string if this message was not sent through a DM chat.
var user_id_two : String
func _init(p_ex = null):
super(p_ex)
func _to_string():
if is_exception(): return get_exception()._to_string()
return "ChannelPresenceEvent<channel_id=%s, joins=%s, leaves=%s, room_name=%s, group_id=%s, user_id_one=%s, user_id_two=%s>" % [
channel_id, joins, leaves, room_name, group_id, user_id_one, user_id_two
]
static func create(p_ns : GDScript, p_dict : Dictionary) -> ChannelPresenceEvent:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "ChannelPresenceEvent", p_dict), ChannelPresenceEvent) as ChannelPresenceEvent
static func get_result_key() -> String:
return "channel_presence_event"
# Describes an error which occurred on the server.
class Error extends NakamaAsyncResult:
const _SCHEMA = {
"code": {"name": "code", "type": TYPE_INT, "required": true},
"message": {"name": "message", "type": TYPE_STRING, "required": true},
"context": {"name": "context", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
}
# The selection of possible error codes.
enum Code {
# An unexpected result from the server.
RUNTIME_EXCEPTION = 0,
# The server received a message which is not recognised.
UNRECOGNIZED_PAYLOAD = 1,
# A message was expected but contains no content.
MISSING_PAYLOAD = 2,
# Fields in the message have an invalid format.
BAD_INPUT = 3,
# The match id was not found.
MATCH_NOT_FOUND = 4,
# The match join was rejected.
MATCH_JOIN_REJECTED = 5,
# The runtime function does not exist on the server.
RUNTIME_FUNCTION_NOT_FOUND = 6,
#The runtime function executed with an error.
RUNTIME_FUNCTION_EXCEPTION = 7,
}
# The error code which should be one of "Error.Code" enums.
var code : int
# A message in English to help developers debug the response.
var message : String
# Additional error details which may be different for each response.
var context : Dictionary
func _init(p_ex = null):
super(p_ex)
func _to_string():
if is_exception(): return get_exception()._to_string()
return "Error<code=%s, messages=%s, context=%s>" % [code, message, context]
static func create(p_ns : GDScript, p_dict : Dictionary) -> Error:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "Error", p_dict), Error) as Error
static func get_result_key() -> String:
return "error"
# A multiplayer match.
class Match extends NakamaAsyncResult:
const _SCHEMA = {
"authoritative": {"name": "authoritative", "type": TYPE_BOOL, "required": false},
"match_id": {"name": "match_id", "type": TYPE_STRING, "required": true},
"label": {"name": "label", "type": TYPE_STRING, "required": false},
"presences": {"name": "presences", "type": TYPE_ARRAY, "required": false, "content": "UserPresence"},
"size": {"name": "size", "type": TYPE_INT, "required": false},
"self": {"name": "self_user", "type": "UserPresence", "required": true}
}
# If this match has an authoritative handler on the server.
var authoritative : bool
# The unique match identifier.
var match_id : String
# A label for the match which can be filtered on.
var label : String
# The presences already in the match.
var presences : Array # UserPresence
# The number of users currently in the match.
var size : int
# The current user in this match. i.e. Yourself.
var self_user : UserPresence
func _init(p_ex = null):
super(p_ex)
static func create(p_ns : GDScript, p_dict : Dictionary):
return _safe_ret(NakamaSerializer.deserialize(p_ns, "Match", p_dict), Match) as Match
func _to_string():
if is_exception(): return get_exception()._to_string()
return "Match<authoritative=%s, match_id=%s, label=%s, presences=%s, size=%d, self=%s>" % [authoritative, match_id, label, presences, size, self_user]
static func get_result_key() -> String:
return "match"
# Some game state update in a match.
class MatchData extends NakamaAsyncResult:
const _SCHEMA = {
"match_id": {"name": "match_id", "type": TYPE_STRING, "required": true},
"presence": {"name": "presence", "type": "UserPresence", "required": false},
"op_code": {"name": "op_code", "type": TYPE_INT, "required": false},
"data": {"name": "data", "type": TYPE_STRING, "required": false}
}
# The unique match identifier.
var match_id : String
# The operation code for the state change.
# This value can be used to mark the type of the contents of the state.
var op_code : int = 0
# The user that sent this game state update.
var presence : UserPresence
# The raw base64-encoded contents of the state change.
var base64_data : String
# The contents of the state change decoded as a UTF-8 string.
var _data
var data : String:
get:
if _data == null and base64_data != '':
_data = Marshalls.base64_to_utf8(base64_data)
return _data if _data != null else ''
set(v):
_data = v
# The contents of the state change decoded as binary data.
var _binary_data
var binary_data : PackedByteArray:
get:
if _binary_data == null and base64_data != '':
_binary_data = Marshalls.base64_to_raw(base64_data)
return _binary_data
func _init(p_ex = null):
super(p_ex)
func _to_string():
if is_exception(): return get_exception()._to_string()
return "MatchData<match_id=%s, op_code=%s, presence=%s, data=%s>" % [match_id, op_code, presence, data]
static func create(p_ns : GDScript, p_dict : Dictionary) -> MatchData:
var out = _safe_ret(NakamaSerializer.deserialize(p_ns, "MatchData", p_dict), MatchData) as MatchData
# Store the base64 data, ready to be decoded when the developer requests it.
if out._data != null:
out.base64_data = out._data
out._data = null
return out
static func get_result_key() -> String:
return "match_data"
# A batch of join and leave presences for a match.
class MatchPresenceEvent extends NakamaAsyncResult:
const _SCHEMA = {
"match_id": {"name": "match_id", "type": TYPE_STRING, "required": true},
"joins": {"name": "joins", "type": TYPE_ARRAY, "required": false, "content" : "UserPresence"},
"leaves": {"name": "leaves", "type": TYPE_ARRAY, "required": false, "content" : "UserPresence"},
}
# Presences of users who joined the match.
var joins : Array
# Presences of users who left the match.
var leaves : Array
# The unique match identifier.
var match_id : String
func _init(p_ex = null):
super(p_ex)
func _to_string():
if is_exception(): return get_exception()._to_string()
return "MatchPresenceEvent<match_id=%s, joins=%s, leaves=%s>" % [match_id, joins, leaves]
static func create(p_ns : GDScript, p_dict : Dictionary) -> MatchPresenceEvent:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "MatchPresenceEvent", p_dict), MatchPresenceEvent) as MatchPresenceEvent
static func get_result_key() -> String:
return "match_presence_event"
# The result of a successful matchmaker operation sent to the server.
class MatchmakerMatched extends NakamaAsyncResult:
const _SCHEMA = {
"match_id": {"name": "match_id", "type": TYPE_STRING, "required": false},
"ticket": {"name": "ticket", "type": TYPE_STRING, "required": true},
"token": {"name": "token", "type": TYPE_STRING, "required": false},
"users": {"name": "users", "type": TYPE_ARRAY, "required": false, "content": "MatchmakerUser"},
"self": {"name": "self_user", "type": "MatchmakerUser", "required": true}
}
# The id used to join the match.
# A match ID used to join the match.
var match_id : String
# The ticket sent by the server when the user requested to matchmake for other players.
var ticket : String
# The token used to join a match.
var token : String
# The other users matched with this user and the parameters they sent.
var users : Array # MatchmakerUser
# The current user who matched with opponents.
var self_user : MatchmakerUser
func _init(p_ex = null):
super(p_ex)
func _to_string():
if is_exception(): return get_exception()._to_string()
return "<MatchmakerMatched match_id=%s, ticket=%s, token=%s, users=%s, self=%s>" % [
match_id, ticket, token, users, self_user
]
static func create(p_ns : GDScript, p_dict : Dictionary) -> MatchmakerMatched:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "MatchmakerMatched", p_dict), MatchmakerMatched) as MatchmakerMatched
static func get_result_key() -> String:
return "matchmaker_matched"
# The matchmaker ticket received from the server.
class MatchmakerTicket extends NakamaAsyncResult:
const _SCHEMA = {
"ticket": {"name": "ticket", "type": TYPE_STRING, "required": true}
}
# The ticket generated by the matchmaker.
var ticket : String
func _init(p_ex = null):
super(p_ex)
static func create(p_ns : GDScript, p_dict : Dictionary) -> MatchmakerTicket:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "MatchmakerTicket", p_dict), MatchmakerTicket) as MatchmakerTicket
func _to_string():
if is_exception(): return get_exception()._to_string()
return "<MatchmakerTicket ticket=%s>" % ticket
static func get_result_key() -> String:
return "matchmaker_ticket"
# The user with the parameters they sent to the server when asking for opponents.
class MatchmakerUser extends NakamaAsyncResult:
const _SCHEMA = {
"presence": {"name": "presence", "type": "UserPresence", "required": true},
"party_id": {"name": "party_id", "type": TYPE_STRING, "required": false},
"string_properties": {"name": "string_properties", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
"numeric_properties": {"name": "numeric_properties", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_FLOAT},
}
# The presence of the user.
var presence : UserPresence
# Party identifier, if this user was matched as a party member.
var party_id : String
# The numeric properties which this user asked to matchmake with.
var numeric_properties : Dictionary
# The string properties which this user asked to matchmake with.
var string_properties : Dictionary
func _init(p_ex = null):
super(p_ex)
func _to_string():
if is_exception(): return get_exception()._to_string()
return "<MatchmakerUser presence=%s, numeric_properties=%s, string_properties=%s>" % [
presence, numeric_properties, string_properties]
static func create(p_ns : GDScript, p_dict : Dictionary) -> MatchmakerUser:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "MatchmakerUser", p_dict), MatchmakerUser) as MatchmakerUser
static func get_result_key() -> String:
return "matchmaker_user"
# Receive status updates for users.
class Status extends NakamaAsyncResult:
const _SCHEMA = {
"presences": {"name": "presences", "type": TYPE_ARRAY, "required": true, "content": "UserPresence"},
}
# The status events for the users followed.
var presences := Array()
func _init(p_ex = null):
super(p_ex)
static func create(p_ns : GDScript, p_dict : Dictionary) -> Status:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "Status", p_dict), Status) as Status
func _to_string():
if is_exception(): return get_exception()._to_string()
return "<Status presences=%s>" % [presences]
static func get_result_key() -> String:
return "status"
# A status update event about other users who've come online or gone offline.
class StatusPresenceEvent extends NakamaAsyncResult:
const _SCHEMA = {
"joins": {"name": "joins", "type": TYPE_ARRAY, "required": false, "content" : "UserPresence"},
"leaves": {"name": "leaves", "type": TYPE_ARRAY, "required": false, "content" : "UserPresence"},
}
# Presences of users who joined the server.
# This join information is in response to a subscription made to be notified when a user comes online.
var joins : Array
# Presences of users who left the server.
# This leave information is in response to a subscription made to be notified when a user goes offline.
var leaves : Array
func _init(p_ex = null):
super(p_ex)
func _to_string():
if is_exception(): return get_exception()._to_string()
return "StatusPresenceEvent<joins=%s, leaves=%s>" % [joins, leaves]
static func create(p_ns : GDScript, p_dict : Dictionary) -> StatusPresenceEvent:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "StatusPresenceEvent", p_dict), StatusPresenceEvent) as StatusPresenceEvent
static func get_result_key() -> String:
return "status_presence_event"
# A realtime socket stream on the server.
class Stream extends NakamaAsyncResult:
const _SCHEMA = {
"mode": {"name": "mode", "type": TYPE_INT, "required": true},
"subject": {"name": "subject", "type": TYPE_STRING, "required": false},
"subcontext": {"name": "subcontext", "type": TYPE_STRING, "required": false},
"label": {"name": "label", "type": TYPE_STRING, "required": false},
}
# The mode of the stream.
var mode : int
# The subject of the stream. This is usually a user id.
var subject : String
# The descriptor of the stream. Used with direct chat messages and contains a second user id.
var subcontext : String
# Identifies streams which have a context across users like a chat channel room.
var label : String
func _init(p_ex = null):
super(p_ex)
func _to_string():
if is_exception(): return get_exception()._to_string()
return "Stream<mode=%s, subject=%s, subcontext=%s, label=%s>" % [mode, subject, subcontext, label]
static func create(p_ns : GDScript, p_dict : Dictionary) -> Stream:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "Stream", p_dict), Stream) as Stream
static func get_result_key() -> String:
return "stream"
# A batch of joins and leaves on the low level stream.
# Streams are built on to provide abstractions for matches, chat channels, etc. In most cases you'll never need to
# interact with the low level stream itself.
class StreamPresenceEvent extends NakamaAsyncResult:
const _SCHEMA = {
"stream": {"name": "stream", "type": "Stream", "required": true},
"joins": {"name": "joins", "type": TYPE_ARRAY, "required": false, "content" : "UserPresence"},
"leaves": {"name": "leaves", "type": TYPE_ARRAY, "required": false, "content" : "UserPresence"},
}
# Presences of users who left the stream.
var joins : Array
# Presences of users who joined the stream.
var leaves : Array
# The identifier for the stream.
var stream : Stream = null
func _to_string():
if is_exception(): return get_exception()._to_string()
return "StreamPresenceEvent<stream=%s, joins=%s, leaves=%s>" % [stream, joins, leaves]
static func create(p_ns : GDScript, p_dict : Dictionary) -> StreamPresenceEvent:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "StreamPresenceEvent", p_dict), StreamPresenceEvent) as StreamPresenceEvent
static func get_result_key() -> String:
return "stream_presence_event"
# A state change received from a stream.
class StreamData extends NakamaAsyncResult:
const _SCHEMA = {
"stream": {"name": "stream", "type": "Stream", "required": true},
"sender": {"name": "sender", "type": "UserPresence", "required": false},
"data": {"name": "state", "type": TYPE_STRING, "required": false},
"reliable": {"name": "reliable", "type": TYPE_BOOL, "required": false},
}
# The user who sent the state change. May be `null`.
var sender : UserPresence = null
# The contents of the state change.
var state : String
# The identifier for the stream.
var stream : Stream
# True if this data was delivered reliably, false otherwise.
var reliable : bool
func _to_string():
if is_exception(): return get_exception()._to_string()
return "StreamData<sender=%s, state=%s, stream=%s>" % [sender, state, stream]
static func create(p_ns : GDScript, p_dict : Dictionary) -> StreamData:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "StreamData", p_dict), StreamData) as StreamData
static func get_result_key() -> String:
return "stream_data"
# An object which represents a connected user in the server.
# The server allows the same user to be connected with multiple sessions. To uniquely identify them a tuple of
# `{ node_id, user_id, session_id }` is used which is exposed as this object.
class UserPresence extends NakamaAsyncResult:
const _SCHEMA = {
"persistence": {"name": "persistence", "type": TYPE_BOOL, "required": false},
"session_id": {"name": "session_id", "type": TYPE_STRING, "required": true},
"status": {"name": "status", "type": TYPE_STRING, "required": false},
"username": {"name": "username", "type": TYPE_STRING, "required": false},
"user_id": {"name": "user_id", "type": TYPE_STRING, "required": true},
}
# If this presence generates stored events like persistent chat messages or notifications.
var persistence : bool
# The session id of the user.
var session_id : String
# The status of the user with the presence on the server.
var status : String
# The username for the user.
var username : String
# The id of the user.
var user_id : String
func _init(p_ex = null):
super(p_ex)
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string():
if is_exception(): return get_exception()._to_string()
return "UserPresence<persistence=%s, session_id=%s, status=%s, username=%s, user_id=%s>" % [
persistence, session_id, status, username, user_id]
static func create(p_ns : GDScript, p_dict : Dictionary) -> UserPresence:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "UserPresence", p_dict), UserPresence) as UserPresence
static func get_result_key() -> String:
return "user_presence"
class Party extends NakamaAsyncResult:
const _SCHEMA = {
"party_id": {"name": "party_id", "type": TYPE_STRING, "required": true},
"open": {"name": "open", "type": TYPE_BOOL, "required": false},
"max_size": {"name": "max_size", "type": TYPE_INT, "required": true},
"self": {"name": "self_presence", "type": "UserPresence", "required": true},
"leader": {"name": "leader", "type": "UserPresence", "required": true},
"presences": {"name": "presences", "type": TYPE_ARRAY, "required": false, "content": "UserPresence"},
}
# Unique party identifier.
var party_id : String
# Open flag.
var open : bool = false
# Maximum number of party members.
var max_size : int
# The presence of the current user. i.e. Your self.
var self_presence : NakamaRTAPI.UserPresence
# Leader.
var leader : NakamaRTAPI.UserPresence
# All current party members.
var presences : Array # of objects NakamaUserPresence
func _init(p_ex = null):
super(p_ex)
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string():
if is_exception(): return get_exception()._to_string()
return "Party<party_id=%s, open=%s, max_size=%d, self=%s, leader=%s, presences=%s>" % [
party_id, open, max_size, self_presence, leader, presences]
static func create(p_ns : GDScript, p_dict : Dictionary) -> Party:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "Party", p_dict), Party) as Party
static func get_result_key() -> String:
return "party"
# Presence update for a particular party.
class PartyPresenceEvent extends NakamaAsyncResult:
const _SCHEMA = {
"party_id": {"name": "party_id", "type": TYPE_STRING, "required": true},
"joins": {"name": "joins", "type": TYPE_ARRAY, "required": false, "content": "UserPresence"},
"leaves": {"name": "leaves", "type": TYPE_ARRAY, "required": false, "content": "UserPresence"},
}
# The party ID.
var party_id : String
# User presences that have just joined the party.
var joins : Array
# User presences that have just left the party.
var leaves : Array
func _init(p_ex = null):
super(p_ex)
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string():
if is_exception(): return get_exception()._to_string()
return "PartyPresenceEvent<party_id=%s, joins=%s, leaves=%s>" % [party_id, joins, leaves]
static func create(p_ns : GDScript, p_dict : Dictionary) -> PartyPresenceEvent:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "PartyPresenceEvent", p_dict), PartyPresenceEvent) as PartyPresenceEvent
static func get_result_key() -> String:
return "party_presence_event"
# Announcement of a new party leader.
class PartyLeader extends NakamaAsyncResult:
const _SCHEMA = {
"party_id": {"name": "party_id", "type": TYPE_STRING, "required": true},
"presence": {"name": "presence", "type": "UserPresence", "required": true},
}
# Party ID to promote a new leader for.
var party_id : String
# The presence of an existing party member to promote as the new leader.
var presence : NakamaRTAPI.UserPresence
func _init(p_ex = null):
super(p_ex)
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string():
if is_exception(): return get_exception()._to_string()
return "PartyLeader<party_id=%s, presence=%s>" % [party_id, presence]
static func create(p_ns : GDScript, p_dict : Dictionary) -> PartyLeader:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "PartyLeader", p_dict), PartyLeader) as PartyLeader
static func get_result_key() -> String:
return "party_leader"
# Incoming notification for one or more new presences attempting to join the party.
class PartyJoinRequest extends NakamaAsyncResult:
const _SCHEMA = {
"party_id": {"name": "party_id", "type": TYPE_STRING, "required": true},
"presences": {"name": "presences", "type": TYPE_ARRAY, "required": false, "content": "UserPresence"},
}
# Party ID these presences are attempting to join.
var party_id : String
# Presences attempting to join.
var presences : Array
func _init(p_ex = null):
super(p_ex)
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string():
if is_exception(): return get_exception()._to_string()
return "PartyJoinRequest<party_id=%s, presences=%s>" % [party_id, presences]
static func create(p_ns : GDScript, p_dict : Dictionary) -> PartyJoinRequest:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "PartyJoinRequest", p_dict), PartyJoinRequest) as PartyJoinRequest
static func get_result_key() -> String:
return "party_join_request"
# A response from starting a new party matchmaking process.
class PartyMatchmakerTicket extends NakamaAsyncResult:
const _SCHEMA = {
"party_id": {"name": "party_id", "type": TYPE_STRING, "required": true},
"ticket": {"name": "ticket", "type": TYPE_STRING, "required": true},
}
# Party ID.
var party_id : String
# The ticket that can be used to cancel matchmaking.
var ticket : String
func _init(p_ex = null):
super(p_ex)
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string():
if is_exception(): return get_exception()._to_string()
return "PartyMatchmakerTicket<party_id=%s, ticket=%s>" % [party_id, ticket]
static func create(p_ns : GDScript, p_dict : Dictionary) -> PartyMatchmakerTicket:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "PartyMatchmakerTicket", p_dict), PartyMatchmakerTicket) as PartyMatchmakerTicket
static func get_result_key() -> String:
return "party_matchmaker_ticket"
# Incoming party data delivered from the server.
class PartyData extends NakamaAsyncResult:
const _SCHEMA = {
"party_id": {"name": "party_id", "type": TYPE_STRING, "required": true},
"presence": {"name": "presence", "type": "UserPresence", "required": false},
"op_code": {"name": "op_code", "type": TYPE_INT, "required": true},
"data": {"name": "data", "type": TYPE_STRING, "required": false}
}
# The party ID.
var party_id : String
# A reference to the user presence that sent this data, if any.
var presence : NakamaRTAPI.UserPresence
# Op code value.
var op_code : int
# The raw base64-encoded contents of the state change.
var base64_data : String
# The contents of the state change decoded as a UTF-8 string.
var _data
var data : String:
get:
if _data == null and base64_data != '':
_data = Marshalls.base64_to_utf8(base64_data)
return _data if _data != null else ''
set(v):
_data = v
# The contents of the state change decoded as binary data.
var _binary_data
var binary_data : PackedByteArray:
get:
if _binary_data == null and base64_data != '':
_binary_data = Marshalls.base64_to_raw(base64_data)
return _binary_data
func _init(p_ex = null):
super(p_ex)
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func _to_string():
if is_exception(): return get_exception()._to_string()
return "PartyData<party_id=%s, presence=%s, op_code=%d, data%s>" % [party_id, presence, op_code, data]
static func create(p_ns : GDScript, p_dict : Dictionary) -> PartyData:
var out := _safe_ret(NakamaSerializer.deserialize(p_ns, "PartyData", p_dict), PartyData) as PartyData
# Store the base64 data, ready to be decoded when the developer requests it.
if out._data != null:
out.base64_data = out._data
out._data = null
return out
static func get_result_key() -> String:
return "party_data"
# End a party, kicking all party members and closing it. (this is both a message and a result)
class PartyClose extends NakamaAsyncResult:
const _SCHEMA = {
"party_id": {"name": "party_id", "type": TYPE_STRING, "required": true},
}
# Party ID to close.
var party_id : String
func _init(p_ex = null):
super(p_ex)
func serialize():
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "party_close"
func _to_string():
if is_exception(): return get_exception()._to_string()
return "PartyClose<party_id=%s>" % [party_id]
static func create(p_ns : GDScript, p_dict : Dictionary) -> PartyClose:
return _safe_ret(NakamaSerializer.deserialize(p_ns, "PartyClose", p_dict), PartyClose) as PartyClose
static func get_result_key() -> String:
return "party_close"
@@ -0,0 +1 @@
uid://deb6jddlbdxkf
@@ -0,0 +1,635 @@
extends RefCounted
class_name NakamaRTMessage
# Send a channel join message to the server.
class ChannelJoin:
const _SCHEMA = {
"persistence": {"name": "persistence", "type": TYPE_BOOL, "required": true},
"hidden": {"name": "hidden", "type": TYPE_BOOL, "required": true},
"target": {"name": "target", "type": TYPE_STRING, "required": true},
"type": {"name": "type", "type": TYPE_INT, "required": true},
}
enum ChannelType {
# A chat room which can be created dynamically with a name.
Room = 1,
# A private chat between two users.
DirectMessage = 2,
# A chat within a group on the server.
Group = 3
}
var persistence : bool
var hidden : bool
var target : String
var type : int
func _init(p_target : String, p_type : int, p_persistence : bool, p_hidden : bool):
persistence = p_persistence
hidden = p_hidden
target = p_target
type = p_type if p_type >= ChannelType.Room and p_type <= ChannelType.Group else 0 # Will cause error server side
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "channel_join"
func _to_string():
return "ChannelJoin<persistence=%s, hidden=%s, target=%s, type=%d>" % [persistence, hidden, target, type]
# A leave message for a match on the server.
class ChannelLeave extends NakamaAsyncResult:
const _SCHEMA = {
"channel_id": {"name": "channel_id", "type": TYPE_STRING, "required": true}
}
var channel_id : String
func _init(p_channel_id : String):
channel_id = p_channel_id
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "channel_leave"
func _to_string():
return "ChannelLeave<channel_id=%s>" % [channel_id]
class ChannelMessageRemove extends NakamaAsyncResult:
const _SCHEMA = {
"channel_id": {"name": "channel_id", "type": TYPE_STRING, "required": true},
"message_id": {"name": "message_id", "type": TYPE_STRING, "required": true}
}
var channel_id : String
var message_id : String
func _init(p_channel_id : String, p_message_id):
channel_id = p_channel_id
message_id = p_message_id
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "channel_message_remove"
func _to_string():
return "ChannelMessageRemove<channel_id=%s, message_id=%s>" % [channel_id, message_id]
# Send a chat message to a channel on the server.
class ChannelMessageSend extends NakamaAsyncResult:
const _SCHEMA = {
"channel_id": {"name": "channel_id", "type": TYPE_STRING, "required": true},
"content": {"name": "content", "type": TYPE_STRING, "required": true}
}
var channel_id : String
var content : String
func _init(p_channel_id : String, p_content):
channel_id = p_channel_id
content = p_content
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "channel_message_send"
func _to_string():
return "ChannelMessageSend<channel_id=%s, content=%s>" % [channel_id, content]
class ChannelMessageUpdate extends NakamaAsyncResult:
const _SCHEMA = {
"channel_id": {"name": "channel_id", "type": TYPE_STRING, "required": true},
"message_id": {"name": "message_id", "type": TYPE_STRING, "required": true},
"content": {"name": "content", "type": TYPE_STRING, "required": true}
}
var channel_id : String
var message_id : String
var content : String
func _init(p_channel_id : String, p_message_id, p_content : String):
channel_id = p_channel_id
message_id = p_message_id
content = p_content
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "channel_message_update"
func _to_string():
return "ChannelMessageUpdate<channel_id=%s, message_id=%s, content=%s>" % [channel_id, message_id, content]
# A create message for a match on the server.
class MatchCreate extends NakamaAsyncResult:
const _SCHEMA = {
"name": {"name": "name", "type": TYPE_STRING, "required": false},
}
var name = null
func _init(p_name = null):
name = p_name if p_name else null
func serialize():
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "match_create"
func _to_string():
return "MatchCreate<name=%s>" % [name]
# A join message for a match on the server.
class MatchJoin extends NakamaAsyncResult:
const _SCHEMA = {
"match_id": {"name": "match_id", "type": TYPE_STRING, "required": false},
"token": {"name": "token", "type": TYPE_STRING, "required": false},
"metadata": {"name": "metadata", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
}
# These two are mutually exclusive and set manually by socket for now, so use null.
var match_id = null
var token = null
var metadata = null
func _init(p_ex=null):
super(p_ex)
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "match_join"
func _to_string():
return "MatchJoin<match_id=%s, token=%s, metadata=%s>" % [match_id, token, metadata]
# A leave message for a match on the server.
class MatchLeave extends NakamaAsyncResult:
const _SCHEMA = {
"match_id": {"name": "match_id", "type": TYPE_STRING, "required": true}
}
var match_id : String
func _init(p_match_id : String):
match_id = p_match_id
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "match_leave"
func _to_string():
return "MatchLeave<match_id=%s>" % [match_id]
# Send new state to a match on the server.
class MatchDataSend extends NakamaAsyncResult:
const _SCHEMA = {
"match_id": {"name": "match_id", "type": TYPE_STRING, "required": true},
"op_code": {"name": "op_code", "type": TYPE_INT, "required": true},
"presences": {"name": "presences", "type": TYPE_ARRAY, "required": false, "content": "UserPresence"},
"data": {"name": "data", "type": TYPE_STRING, "required": true},
}
var match_id : String
var presences = null
var op_code : int
var data : String
func _init(p_match_id : String, p_op_code : int, p_data : String, p_presences):
match_id = p_match_id
presences = p_presences
op_code = p_op_code
data = p_data
func serialize():
return NakamaSerializer.serialize(self)
func get_msg_key():
return "match_data_send"
func _to_string():
return "MatchDataSend<match_id=%s, op_code=%s, presences=%s, data=%s>" % [match_id, op_code, presences, data]
# Add the user to the matchmaker pool with properties.
class MatchmakerAdd extends NakamaAsyncResult:
const _SCHEMA = {
"query": {"name": "query", "type": TYPE_STRING, "required": true},
"max_count": {"name": "max_count", "type": TYPE_INT, "required": true},
"min_count": {"name": "min_count", "type": TYPE_INT, "required": true},
"numeric_properties": {"name": "numeric_properties", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_FLOAT},
"string_properties": {"name": "string_properties", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
"count_multiple": {"name": "count_multiple", "type": TYPE_INT, "required": false},
}
var query : String = "*"
var max_count : int = 8
var min_count : int = 2
var string_properties : Dictionary
var numeric_properties : Dictionary
var count_multiple
func _init(p_query : String = "*", p_min_count : int = 2, p_max_count : int = 8,
p_string_props : Dictionary = Dictionary(), p_numeric_props : Dictionary = Dictionary(),
p_count_multiple : int = 0):
query = p_query
min_count = p_min_count
max_count = p_max_count
string_properties = p_string_props
numeric_properties = p_numeric_props
count_multiple = p_count_multiple if p_count_multiple > 0 else null
func serialize() -> Dictionary:
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "matchmaker_add"
func _to_string():
return "MatchmakerAdd<query=%s, max_count=%d, min_count=%d, numeric_properties=%s, string_properties=%s, count_multiple=%s>" % [query, max_count, min_count, numeric_properties, string_properties, count_multiple]
# Remove the user from the matchmaker pool by ticket.
class MatchmakerRemove extends NakamaAsyncResult:
const _SCHEMA = {
"ticket": {"name": "ticket", "type": TYPE_STRING, "required": true}
}
var ticket : String
func _init(p_ticket : String):
ticket = p_ticket
func serialize():
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "matchmaker_remove"
func _to_string():
return "MatchmakerRemove<ticket=%s>" % [ticket]
# Follow one or more other users for status updates.
class StatusFollow extends NakamaAsyncResult:
const _SCHEMA = {
"user_ids": {"name": "user_ids", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
"usernames": {"name": "usernames", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
}
var user_ids := PackedStringArray()
var usernames := PackedStringArray()
func _init(p_ids : PackedStringArray, p_usernames : PackedStringArray):
user_ids = p_ids
usernames = p_usernames
func serialize():
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "status_follow"
func _to_string():
return "StatusFollow<user_ids=%s, usernames=%s>" % [user_ids, usernames]
# Unfollow one or more users on the server.
class StatusUnfollow extends NakamaAsyncResult:
const _SCHEMA = {
"user_ids": {"name": "user_ids", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
}
var user_ids := PackedStringArray()
func _init(p_ids : PackedStringArray):
user_ids = p_ids
func serialize():
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "status_unfollow"
func _to_string():
return "StatusUnfollow<user_ids=%s>" % [user_ids]
# Unfollow one or more users on the server.
class StatusUpdate extends NakamaAsyncResult:
const _SCHEMA = {
"status": {"name": "status", "type": TYPE_STRING, "required": true},
}
var status : String
func _init(p_status : String):
status = p_status
func serialize():
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "status_update"
func _to_string():
return "StatusUpdate<status=%s>" % [status]
# Create a party.
class PartyCreate extends NakamaAsyncResult:
const _SCHEMA = {
"open": {"name": "open", "type": TYPE_BOOL, "required": true},
"max_size": {"name": "max_size", "type": TYPE_INT, "required": true},
}
# Whether or not the party will require join requests to be approved by the party leader.
var open : bool
# Maximum number of party members.
var max_size : int
func _init(p_open : bool, p_max_size : int):
open = p_open
max_size = p_max_size
func serialize():
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "party_create"
func _to_string():
return "PartyCreate<open=%s, max_size=%d>" % [open, max_size]
# Join a party, or request to join if the party is not open.
class PartyJoin extends NakamaAsyncResult:
const _SCHEMA = {
"party_id": {"name": "party_id", "type": TYPE_STRING, "required": true},
}
# Party ID to join.
var party_id : String
func _init(p_id : String):
party_id = p_id
func serialize():
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "party_join"
func _to_string():
return "PartyJoin<party_id=%s>" % [party_id]
# Leave a party.
class PartyLeave extends NakamaAsyncResult:
const _SCHEMA = {
"party_id": {"name": "party_id", "type": TYPE_STRING, "required": true},
}
# Party ID to leave.
var party_id : String
func _init(p_id : String):
party_id = p_id
func serialize():
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "party_leave"
func _to_string():
return "PartyLeave<party_id=%s>" % [party_id]
# Promote a new party leader.
class PartyPromote extends NakamaAsyncResult:
const _SCHEMA = {
"party_id": {"name": "party_id", "type": TYPE_STRING, "required": true},
"presence": {"name": "presence", "type": "UserPresence", "required": true},
}
# Party ID to promote a new leader for.
var party_id : String
# The presence of an existing party member to promote as the new leader.
var presence : NakamaRTAPI.UserPresence
func _init(p_id : String, p_presence : NakamaRTAPI.UserPresence):
party_id = p_id
presence = p_presence
func serialize():
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "party_promote"
func _to_string():
return "PartyPromote<party_id=%s, presence=%s>" % [party_id, presence]
# Accept a request to join.
class PartyAccept extends NakamaAsyncResult:
const _SCHEMA = {
"party_id": {"name": "party_id", "type": TYPE_STRING, "required": true},
"presence": {"name": "presence", "type": "UserPresence", "required": true},
}
# Party ID to accept a join request for.
var party_id : String
# The presence to accept as a party member.
var presence : NakamaRTAPI.UserPresence
func _init(p_id : String, p_presence : NakamaRTAPI.UserPresence):
party_id = p_id
presence = p_presence
func serialize():
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "party_accept"
func _to_string():
return "PartyAccept<party_id=%s, presence=%s>" % [party_id, presence]
# Kick a party member, or decline a request to join.
class PartyRemove extends NakamaAsyncResult:
const _SCHEMA = {
"party_id": {"name": "party_id", "type": TYPE_STRING, "required": true},
"presence": {"name": "presence", "type": "UserPresence", "required": true},
}
# Party ID to remove/reject from.
var party_id : String
# The presence to remove or reject.
var presence : NakamaRTAPI.UserPresence
func _init(p_id : String, p_presence : NakamaRTAPI.UserPresence):
party_id = p_id
presence = p_presence
func serialize():
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "party_remove"
func _to_string():
return "PartyRemove<party_id=%s, presence=%s>" % [party_id, presence]
# Request a list of pending join requests for a party.
class PartyJoinRequestList extends NakamaAsyncResult:
const _SCHEMA = {
"party_id": {"name": "party_id", "type": TYPE_STRING, "required": true},
}
# Party ID to get a list of join requests for.
var party_id : String
func _init(p_id : String):
party_id = p_id
func serialize():
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "party_join_request_list"
func _to_string():
return "PartyJoinRequestList<party_id=%s>" % [party_id]
# Begin matchmaking as a party.
class PartyMatchmakerAdd extends NakamaAsyncResult:
const _SCHEMA = {
"party_id": {"name": "party_id", "type": TYPE_STRING, "required": true},
"min_count": {"name": "min_count", "type": TYPE_INT, "required": true},
"max_count": {"name": "max_count", "type": TYPE_INT, "required": true},
"query": {"name": "query", "type": TYPE_STRING, "required": false},
"string_properties": {"name": "string_properties", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
"numeric_properties": {"name": "numeric_properties", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_FLOAT},
}
# Party ID.
var party_id : String
# Minimum total user count to match together.
var min_count : int
# Maximum total user count to match together.
var max_count : int
# Filter query used to identify suitable users.
var query : String
# String properties.
var string_properties : Dictionary
# Numeric properties.
var numeric_properties : Dictionary
# Optional multiple of the count that must be satisfied.
var count_multiple
func _init(p_id : String, p_min_count : int, p_max_count : int, p_query : String, p_string_properties = null, p_numeric_properties = null, p_count_multiple = null):
party_id = p_id
min_count = p_min_count
max_count = p_max_count
query = p_query
string_properties = p_string_properties
numeric_properties = p_numeric_properties
count_multiple = p_count_multiple
func serialize():
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "party_matchmaker_add"
func _to_string():
return "PartyMatchmakerAdd<party_id=%s, min_count=%d, max_count=%d, query=%s, string_properties=%s, numeric_properties=%s, count_multiple=%s>" % [party_id, min_count, max_count, query, string_properties, numeric_properties, count_multiple]
# Cancel a party matchmaking process using a ticket.
class PartyMatchmakerRemove extends NakamaAsyncResult:
const _SCHEMA = {
"party_id": {"name": "party_id", "type": TYPE_STRING, "required": true},
"ticket": {"name": "ticket", "type": TYPE_STRING, "required": true},
}
# Party ID.
var party_id : String
# The ticket to cancel.
var ticket : String
func _init(p_id : String, p_ticket : String):
party_id = p_id
ticket = p_ticket
func serialize():
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "party_matchmaker_remove"
func _to_string():
return "PartyMatchmakerRemove<party_id=%s, ticket=%s>" % [party_id, ticket]
# Send data to a party.
class PartyDataSend extends NakamaAsyncResult:
const _SCHEMA = {
"party_id": {"name": "party_id", "type": TYPE_STRING, "required": true},
"op_code": {"name": "op_code", "type": TYPE_INT, "required": true},
"data": {"name": "data", "type": TYPE_STRING, "required": false}
}
# Party ID to send to.
var party_id : String
# Op code value.
var op_code : int
# Data payload, if any.
var data = null
func _init(p_id : String, p_op_code : int, p_data = null):
party_id = p_id
op_code = p_op_code
data = p_data
func serialize():
return NakamaSerializer.serialize(self)
func get_msg_key() -> String:
return "party_data_send"
func _to_string():
return "PartyDataSend<party_id=%s, op_code=%d, data=%s>" % [party_id, op_code, data]
@@ -0,0 +1 @@
uid://crbt10hwhug0j
@@ -0,0 +1,157 @@
extends NakamaAsyncResult
class_name NakamaSession
var _created : bool = false
var created : bool:
set(v):
pass
get:
return _created
var _token : String = ""
var token : String:
set(v):
pass
get:
return _token
var _create_time : int = 0
var create_time : int:
set(v):
pass
get:
return _create_time
var _expire_time : int = 0
var expire_time : int:
set(v):
pass
get:
return _expire_time
var expired : bool:
set(v):
pass
get:
return is_expired()
var _vars : Dictionary = {}
var vars : Dictionary:
set(v):
pass
get:
return _vars
var _username : String = ""
var username : String:
set(v):
pass
get:
return _username
var _user_id : String = ""
var user_id : String:
set(v):
pass
get:
return _user_id
var _refresh_token : String = ""
var refresh_token : String:
set(v):
pass
get:
return _refresh_token
var _refresh_expire_time : int = 0
var refresh_expire_time : int:
set(v):
pass
get:
return _refresh_expire_time
var _valid : bool = false
var valid : bool:
set(v):
pass
get:
return _valid
func is_expired() -> bool:
return _expire_time < Time.get_unix_time_from_system()
func would_expire_in(p_secs : int) -> bool:
return _expire_time < Time.get_unix_time_from_system() + p_secs
func is_refresh_expired() -> bool:
return _refresh_expire_time < Time.get_unix_time_from_system()
func is_valid():
return _valid
func _init(p_token = null, p_created : bool = false, p_refresh_token = null, p_exception = null):
super(p_exception)
if p_token:
_created = p_created
_parse_token(p_token)
if p_refresh_token:
_parse_refresh_token(p_refresh_token)
func refresh(p_session):
if p_session.token:
_parse_token(p_session.token)
if p_session.refresh_token:
_parse_refresh_token(p_session.refresh_token)
func _parse_token(p_token):
var decoded = _jwt_unpack(p_token)
if decoded.is_empty():
_valid = false
return
_valid = true
_token = p_token
_create_time = Time.get_unix_time_from_system()
_expire_time = int(decoded.get("exp", 0))
_username = str(decoded.get("usn", ""))
_user_id = str(decoded.get("uid", ""))
_vars = {}
if decoded.has("vrs") and typeof(decoded["vrs"]) == TYPE_DICTIONARY:
for k in decoded["vrs"]:
_vars[k] = decoded["vrs"][k]
func _parse_refresh_token(p_refresh_token):
var decoded = _jwt_unpack(p_refresh_token)
if decoded.is_empty():
return
_refresh_expire_time = int(decoded.get("exp", 0))
_refresh_token = p_refresh_token
func _to_string():
if is_exception():
return get_exception()._to_string()
return "Session<created=%s, token=%s, create_time=%d, username=%s, user_id=%s, vars=%s, expire_time=%d, refresh_token=%s refresh_expire_time=%d>" % [
_created, _token, _create_time, _username, _user_id, str(_vars), _expire_time, _refresh_token, _refresh_expire_time]
func _jwt_unpack(p_token : String) -> Dictionary:
# Hack decode JSON payload from JWT.
if p_token.find(".") == -1:
_ex = NakamaException.new("Missing payload: %s" % p_token)
return {}
var payload = p_token.split('.')[1];
var pad_length = ceil(payload.length() / 4.0) * 4;
# Pad base64
for i in range(0, pad_length - payload.length()):
payload += "="
payload = payload.replace("-", "+").replace("_", "/")
var unpacked = Marshalls.base64_to_utf8(payload)
var json = JSON.new()
var error = json.parse(unpacked)
if error == OK:
var decoded = json.get_data()
if typeof(decoded) == TYPE_DICTIONARY:
return decoded
_ex = NakamaException.new("Unable to unpack token: %s" % p_token)
return {}
@@ -0,0 +1 @@
uid://cawl01knvwibs
@@ -0,0 +1,34 @@
extends RefCounted
class_name NakamaStorageObjectId
# The collection which stores the object.
var collection : String
# The key of the object within the collection.
var key : String
# The user owner of the object.
var user_id : String
# The version hash of the object.
var version : String
func _init(p_collection, p_key, p_user_id = "", p_version = ""):
collection = p_collection
key = p_key
user_id = p_user_id
version = p_version
func as_delete():
return NakamaAPI.ApiDeleteStorageObjectId.create(NakamaAPI, {
"collection": collection,
"key": key,
"version": version
})
func as_read():
return NakamaAPI.ApiReadStorageObjectId.create(NakamaAPI, {
"collection": collection,
"key": key,
"user_id": user_id
})
@@ -0,0 +1 @@
uid://d4ethidobucgj
@@ -0,0 +1,28 @@
extends RefCounted
class_name NakamaWriteStorageObject
var collection : String
var key : String
var permission_read : int = 0
var permission_write : int = 0
var value : String
var version : String
func _init(p_collection : String, p_key : String, p_permission_read : int,
p_permission_write : int, p_value : String, p_version : String):
collection = p_collection
key = p_key
permission_read = p_permission_read
permission_write = p_permission_write
value = p_value
version = p_version
func as_write():
return NakamaAPI.ApiWriteStorageObject.create(NakamaAPI, {
"collection": collection,
"key": key,
"permission_read": permission_read,
"permission_write": permission_write,
"value": value,
"version": version
})
@@ -0,0 +1 @@
uid://b1ewkhh82x4ja
@@ -0,0 +1,1084 @@
extends RefCounted
# A client for the API in Nakama server.
class_name NakamaClient
const ChannelType = NakamaRTMessage.ChannelJoin.ChannelType
# The host address of the server. Defaults to "127.0.0.1".
var _host
var host : String:
set(v):
pass
get:
return _host
# The port number of the server. Defaults to 7350.
var _port
var port : int:
set(v):
pass
get:
return _port
# The protocol scheme used to connect with the server. Must be either "http" or "https".
var _scheme
var scheme : String:
set(v):
pass
get:
return _scheme
# The key used to authenticate with the server without a session. Defaults to "defaultkey".
var _server_key : String = "defaultkey"
var server_key:
set(v):
pass
get:
return _server_key
# Set the timeout in seconds on requests sent to the server.
var timeout : int
var logger : NakamaLogger = null
var _api_client : NakamaAPI.ApiClient
var auto_refresh : bool = true:
set(v):
set_auto_refresh(v)
get:
return get_auto_refresh()
var auto_refresh_seconds : int = true:
set(v):
set_auto_refresh_seconds(v)
get:
return get_auto_refresh_seconds()
var auto_retry : bool = true:
set(v):
set_auto_retry(v)
get:
return get_auto_retry()
var auto_retry_count:
set(v):
set_auto_retry_count(v)
get:
return get_auto_retry_count()
var auto_retry_backoff_base:
set(v):
set_auto_retry_backoff_base(v)
get:
return get_auto_retry_backoff_base()
var last_cancel_token:
set(v):
pass
get:
return get_last_cancel_token()
func get_auto_refresh():
return _api_client.auto_refresh
func set_auto_refresh(p_value):
_api_client.auto_refresh = p_value
func get_auto_refresh_seconds():
return _api_client.auto_refresh_time
func set_auto_refresh_seconds(p_value):
_api_client.auto_refresh_time = p_value
func get_last_cancel_token():
return _api_client.last_cancel_token
func get_auto_retry():
return _api_client.auto_retry
func set_auto_retry(p_value):
_api_client.auto_retry = p_value
func get_auto_retry_count():
return _api_client.auto_retry_count
func set_auto_retry_count(p_value):
_api_client.auto_retry_count = p_value
func get_auto_retry_backoff_base():
return _api_client.auto_retry_backoff_base
func set_auto_retry_backoff_base(p_value):
_api_client.auto_retry_backoff_base = p_value
func cancel_request(p_token):
_api_client.cancel_request(p_token)
func _init(p_adapter : NakamaHTTPAdapter,
p_server_key : String,
p_scheme : String,
p_host : String,
p_port : int,
p_timeout : int):
_server_key = p_server_key
_scheme = p_scheme
_host = p_host
_port = p_port
timeout = p_timeout
logger = p_adapter.logger
_api_client = NakamaAPI.ApiClient.new(_scheme + "://" + _host + ":" + str(_port), p_adapter, NakamaAPI, _server_key, p_timeout)
# Restore a session from the auth token.
# A `null` or empty authentication token will return `null`.
# @param authToken - The authentication token to restore as a session.
# Returns a session.
static func restore_session(auth_token : String):
return NakamaSession.new(auth_token, false)
func _to_string():
return "Client(Host='%s', Port=%s, Scheme='%s', ServerKey='%s', Timeout=%s)" % [
host, port, scheme, server_key, timeout
]
func _parse_auth(p_session) -> NakamaSession:
if p_session.is_exception():
return NakamaSession.new(null, false, null, p_session.get_exception())
return NakamaSession.new(p_session.token, p_session.created, p_session.refresh_token)
# Add one or more friends by id or username.
# @param p_session - The session of the user.
# @param p_ids - The ids of the users to add or invite as friends.
# @param p_usernames - The usernames of the users to add as friends.
# Returns a task which represents the asynchronous operation.
func add_friends_async(p_session : NakamaSession, p_ids = null, p_usernames = null) -> NakamaAsyncResult:
return await _api_client.add_friends_async(p_session, p_ids, p_usernames)
# Add one or more users to the group.
# @param p_session - The session of the user.
# @param p_group_id - The id of the group to add users into.
# @param p_ids - The ids of the users to add or invite to the group.
# Returns a task which represents the asynchronous operation.
func add_group_users_async(p_session : NakamaSession, p_group_id : String, p_ids : PackedStringArray) -> NakamaAsyncResult:
return await _api_client.add_group_users_async(p_session, p_group_id, p_ids);
# Authenticate a user with an Apple ID against the server.
# @param p_username - A username used to create the user.</param>
# @param p_token - The ID token received from Apple to validate.</param>
# @param p_vars - Extra information that will be bundled in the session token.</param>
# Returns a task which resolves to a session object.
func authenticate_apple_async(p_token : String, p_username = null, p_create : bool = true, p_vars = null) -> NakamaSession:
return _parse_auth(await _api_client.authenticate_apple_async(server_key, "",
NakamaAPI.ApiAccountApple.create(NakamaAPI, {
"token": p_token,
"vars": p_vars
}), p_create, p_username))
# Authenticate a user with a custom id.
# @param p_id - A custom identifier usually obtained from an external authentication service.
# @param p_username - A username used to create the user. May be `null`.
# @param p_create - If the user should be created when authenticated.
# @param p_vars - Extra information that will be bundled in the session token.
# Returns a task which resolves to a session object.
func authenticate_custom_async(p_id : String, p_username = null, p_create : bool = true, p_vars = null) -> NakamaSession:
return _parse_auth(await _api_client.authenticate_custom_async(server_key, "",
NakamaAPI.ApiAccountCustom.create(NakamaAPI, {
"id": p_id,
"vars": p_vars
}), p_create, p_username))
# Authenticate a user with a device id.
# @param p_id - A device identifier usually obtained from a platform API.
# @param p_username - A username used to create the user. May be `null`.
# @param p_create - If the user should be created when authenticated.
# @param p_vars - Extra information that will be bundled in the session token.
# Returns a task which resolves to a session object.
func authenticate_device_async(p_id : String, p_username = null, p_create : bool = true, p_vars = null) -> NakamaSession:
return _parse_auth(await _api_client.authenticate_device_async(server_key, "",
NakamaAPI.ApiAccountDevice.create(NakamaAPI, {
"id": p_id,
"vars": p_vars
}), p_create, p_username))
# Authenticate a user with an email and password.
# @param p_email - The email address of the user.
# @param p_password - The password for the user.
# @param p_username - A username used to create the user. May be `null`.
# @param p_create - If the user should be created when authenticated.
# @param p_vars - Extra information that will be bundled in the session token.
# Returns a task which resolves to a session object.
func authenticate_email_async(p_email : String, p_password : String, p_username = null, p_create : bool = true, p_vars = null) -> NakamaSession:
return _parse_auth(await _api_client.authenticate_email_async(server_key, "",
NakamaAPI.ApiAccountEmail.create(NakamaAPI, {
"email": p_email,
"password": p_password,
"vars": p_vars
}), p_create, p_username))
# Authenticate a user with a Facebook auth token.
# @param p_token - An OAuth access token from the Facebook SDK.
# @param p_username - A username used to create the user. May be `null`.
# @param p_create - If the user should be created when authenticated.
# @param p_import - If the Facebook friends should be imported.
# @param p_vars - Extra information that will be bundled in the session token.
# Returns a task which resolves to a session object.
func authenticate_facebook_async(p_token : String, p_username = null, p_create : bool = true, p_import : bool = true, p_vars = null) -> NakamaSession:
return _parse_auth(await _api_client.authenticate_facebook_async(server_key, "",
NakamaAPI.ApiAccountFacebook.create(NakamaAPI, {
"token": p_token,
"vars": p_vars
}), p_create, p_username, p_import))
# Authenticate a user with a Facebook Instant Game token against the server.
# @param p_signed_player_info - Facebook Instant Game signed info from Facebook SDK.
# @param p_username - A username used to create the user. May be `null`.
# @param p_create - If the user should be created when authenticated.
# @param p_import - If the Facebook friends should be imported.
# @param p_vars - Extra information that will be bundled in the session token.
# Returns a task which resolves to a session object.
func authenticate_facebook_instant_game_async(p_signed_player_info : String, p_username = null, p_create : bool = true, p_vars = null) -> NakamaSession:
return _parse_auth(await _api_client.authenticate_facebook_instant_game_async(server_key, "",
NakamaAPI.ApiAccountFacebookInstantGame.create(NakamaAPI, {
"signed_player_info": p_signed_player_info,
"vars": p_vars
}), p_create, p_username))
# Authenticate a user with Apple Game Center.
# @param p_bundle_id - The bundle id of the Game Center application.
# @param p_player_id - The player id of the user in Game Center.
# @param p_public_key_url - The URL for the public encryption key.
# @param p_salt - A random `NSString` used to compute the hash and keep it randomized.
# @param p_signature - The verification signature data generated.
# @param p_timestamp_seconds - The date and time that the signature was created.
# @param p_username - A username used to create the user. May be `null`.
# @param p_create - If the user should be created when authenticated.
# @param p_vars - Extra information that will be bundled in the session token.
# Returns a task which resolves to a session object.
func authenticate_game_center_async(p_bundle_id : String, p_player_id : String, p_public_key_url : String,
p_salt : String, p_signature : String, p_timestamp_seconds : String, p_username = null, p_create : bool = true, p_vars = null) -> NakamaSession:
return _parse_auth(await _api_client.authenticate_game_center_async(server_key, "",
NakamaAPI.ApiAccountGameCenter.create(NakamaAPI, {
"bundle_id": p_bundle_id,
"player_id": p_player_id,
"public_key_url": p_public_key_url,
"salt": p_salt,
"signature": p_signature,
"timestamp_seconds": p_timestamp_seconds,
"vars": p_vars
}), p_create, p_username))
# Authenticate a user with a Google auth token.
# @param p_token - An OAuth access token from the Google SDK.
# @param p_username - A username used to create the user. May be `null`.
# @param p_create - If the user should be created when authenticated.
# @param p_vars - Extra information that will be bundled in the session token.
# Returns a task which resolves to a session object.
func authenticate_google_async(p_token : String, p_username = null, p_create : bool = true, p_vars = null) -> NakamaSession:
return _parse_auth(await _api_client.authenticate_google_async(server_key, "",
NakamaAPI.ApiAccountGoogle.create(NakamaAPI, {
"token": p_token,
"vars": p_vars
}), p_create, p_username))
# Authenticate a user with a Steam auth token.
# @param p_token - An authentication token from the Steam network.
# @param p_username - A username used to create the user. May be `null`.
# @param p_create - If the user should be created when authenticated.
# @param p_vars - Extra information that will be bundled in the session token.
# Returns a task which resolves to a session object.
func authenticate_steam_async(p_token : String, p_username = null, p_create : bool = true, p_vars = null, p_sync : bool = false) -> NakamaSession:
return _parse_auth(await _api_client.authenticate_steam_async(server_key, "",
NakamaAPI.ApiAccountSteam.create(NakamaAPI, {
"token": p_token,
"vars": p_vars
}), p_create, p_username, p_sync))
# Block one or more friends by id or username.
# @param p_session - The session of the user.
# @param p_ids - The ids of the users to block.
# @param p_usernames - The usernames of the users to block.
# Returns a task which represents the asynchronous operation.
func block_friends_async(p_session : NakamaSession, p_ids : PackedStringArray, p_usernames = null) -> NakamaAsyncResult:
return await _api_client.block_friends_async(p_session, p_ids, p_usernames);
# Create a group.
# @param p_session - The session of the user.
# @param p_name - The name for the group.
# @param p_description - A description for the group.
# @param p_avatar_url - An avatar url for the group.
# @param p_lang_tag - A language tag in BCP-47 format for the group.
# @param p_open - If the group should have open membership.
# @param p_max_count - The maximum number of members allowed.
# Returns a task which resolves to a new group object.
func create_group_async(p_session : NakamaSession, p_name : String, p_description : String = "",
p_avatar_url = null, p_lang_tag = null, p_open : bool = true, p_max_count : int = 100): # -> NakamaAPI.ApiGroup:
return await _api_client.create_group_async(p_session,
NakamaAPI.ApiCreateGroupRequest.create(NakamaAPI, {
"avatar_url": p_avatar_url,
"description": p_description,
"lang_tag": p_lang_tag,
"max_count": p_max_count,
"name": p_name,
"open": p_open
}))
# Delete the current user's account on the server.
# @param p_session - The session of the user.
# Returns a task which represents the asynchronous operation.
func delete_account_async(p_session : NakamaSession) -> NakamaAsyncResult:
return await _api_client.delete_account_async(p_session)
# Delete one more or users by id or username from friends.
# @param p_session - The session of the user.
# @param p_ids - The user ids to remove as friends.
# @param p_usernames - The usernames to remove as friends.
# Returns a task which represents the asynchronous operation.
func delete_friends_async(p_session : NakamaSession, p_ids : PackedStringArray, p_usernames = null) -> NakamaAsyncResult:
return await _api_client.delete_friends_async(p_session, p_ids, p_usernames)
# Delete a group by id.
# @param p_session - The session of the user.
# @param p_group_id - The group id to to remove.
# Returns a task which represents the asynchronous operation.
func delete_group_async(p_session : NakamaSession, p_group_id : String) -> NakamaAsyncResult:
return await _api_client.delete_group_async(p_session, p_group_id)
# Delete a leaderboard record.
# @param p_session - The session of the user.
# @param p_leaderboard_id - The id of the leaderboard with the record to be deleted.
# Returns a task which represents the asynchronous operation.
func delete_leaderboard_record_async(p_session : NakamaSession, p_leaderboard_id : String) -> NakamaAsyncResult:
return await _api_client.delete_leaderboard_record_async(p_session, p_leaderboard_id)
# Delete one or more notifications by id.
# @param p_session - The session of the user.
# @param p_ids - The notification ids to remove.
# Returns a task which represents the asynchronous operation.
func delete_notifications_async(p_session : NakamaSession, p_ids : PackedStringArray) -> NakamaAsyncResult:
return await _api_client.delete_notifications_async(p_session, p_ids)
# Delete one or more storage objects.
# @param p_session - The session of the user.
# @param p_ids - The ids of the objects to delete.
# Returns a task which represents the asynchronous operation.
func delete_storage_objects_async(p_session : NakamaSession, p_ids : Array) -> NakamaAsyncResult:
var ids : Array = []
for id in p_ids:
if not id is NakamaStorageObjectId:
continue # TODO Exceptions
var obj_id : NakamaStorageObjectId = id
ids.append(obj_id.as_delete().serialize())
return await _api_client.delete_storage_objects_async(p_session,
NakamaAPI.ApiDeleteStorageObjectsRequest.create(NakamaAPI, {
"object_ids": ids
}))
# Demote a set of users in a group to the next role down.
# @param p_session - The session of the user.
# @param p_group_id - The ID of the group to demote users into.
# @param p_ids - The IDs of the users to demote.
# Returns a task which represents the asynchronous operation.
func demote_group_users_async(p_session : NakamaSession, p_group_id : String, p_user_ids : Array):
return await _api_client.demote_group_users_async(p_session, p_group_id, p_user_ids)
# Submit an event for processing in the server's registered runtime custom events handler.
# @param p_session - The session of the user.
# @param p_name - The name of the event.
# @param p_properties - The properties of the event.
# Returns a task which represents the asynchronous operation.
func event_async(p_session : NakamaSession, p_name : String, p_properties : Dictionary = {}) -> NakamaAsyncResult:
return await _api_client.event_async(p_session, NakamaAPI.ApiEvent.create(
NakamaAPI,
{
"name": p_name,
"properties": p_properties,
"external": true,
}
))
# Fetch the user account owned by the session.
# @param p_session - The session of the user.
# Returns a task which resolves to the account object.
func get_account_async(p_session : NakamaSession): # -> NakamaAPI.ApiAccount:
return await _api_client.get_account_async(p_session)
# Get subscription by product id.
# @param p_session - The session of the user.
# @param p_product_id - The product id.
# Returns a task which resolves to the subscription object.
func get_subscription_async(p_session : NakamaSession, p_product_id : String): # -> ApiValidatedSubscription:
return await _api_client.get_subscription_async(p_session, p_product_id)
# Fetch one or more users by id, usernames, and Facebook ids.
# @param p_session - The session of the user.
# @param p_ids - The IDs of the users to retrieve.
# @param p_usernames - The usernames of the users to retrieve.
# @param p_facebook_ids - The facebook IDs of the users to retrieve.
# Returns a task which resolves to a collection of user objects.
func get_users_async(p_session : NakamaSession, p_ids : PackedStringArray, p_usernames = null, p_facebook_ids = null): # -> NakamaAPI.ApiUsers:
return await _api_client.get_users_async(p_session, p_ids, p_usernames, p_facebook_ids)
# Import Facebook friends and add them to the user's account.
# The server will import friends when the user authenticates with Facebook. This function can be used to be
# explicit with the import operation.
# @param p_session - The session of the user.
# @param p_token - An OAuth access token from the Facebook SDK.
# @param p_reset - If the Facebook friend import for the user should be reset.
# Returns a task which represents the asynchronous operation.
func import_facebook_friends_async(p_session : NakamaSession, p_token : String, p_reset = null) -> NakamaAsyncResult:
return await _api_client.import_facebook_friends_async(p_session,
NakamaAPI.ApiAccountFacebook.create(NakamaAPI, {
"token": p_token
}), p_reset)
# Import Steam friends and add them to the user's account.
# The server will import friends when the user authenticates with Steam. This function can be used to be
# explicit with the import operation.
# @param p_session - The session of the user.
# @param p_token - An access token from Steam.
# @param p_reset - If the Steam friend import for the user should be reset.
# Returns a task which represents the asynchronous operation.
func import_steam_friends_async(p_session : NakamaSession, p_token : String, p_reset = null):
return await _api_client.import_steam_friends_async(p_session,
NakamaAPI.ApiAccountSteam.create(NakamaAPI, {
"token": p_token
}), p_reset)
# Join a group if it has open membership or request to join it.
# @param p_session - The session of the user.
# @param p_group_id - The ID of the group to join.
# Returns a task which represents the asynchronous operation.
func join_group_async(p_session : NakamaSession, p_group_id : String) -> NakamaAsyncResult:
return await _api_client.join_group_async(p_session, p_group_id)
# Join a tournament by ID.
# @param p_session - The session of the user.
# @param p_tournament_id - The ID of the tournament to join.
# Returns a task which represents the asynchronous operation.
func join_tournament_async(p_session : NakamaSession, p_tournament_id : String) -> NakamaAsyncResult:
return await _api_client.join_tournament_async(p_session, p_tournament_id)
# Kick one or more users from the group.
# @param p_session - The session of the user.
# @param p_group_id - The ID of the group.
# @param p_ids - The IDs of the users to kick.
# Returns a task which represents the asynchronous operation.
func kick_group_users_async(p_session : NakamaSession, p_group_id : String, p_ids : PackedStringArray) -> NakamaAsyncResult:
return await _api_client.kick_group_users_async(p_session, p_group_id, p_ids)
# Leave a group by ID.
# @param p_session - The session of the user.
# @param p_group_id - The ID of the group to leave.
# Returns a task which represents the asynchronous operation.
func leave_group_async(p_session : NakamaSession, p_group_id : String) -> NakamaAsyncResult:
return await _api_client.leave_group_async(p_session, p_group_id)
# Link an Apple ID to the social profiles on the current user's account.
# @param p_session - The session of the user.
# @param p_token - The ID token received from Apple to validate.
# Returns a task which represents the asynchronous operation.
func link_apple_async(p_session : NakamaSession, p_token : String) -> NakamaAsyncResult:
return await _api_client.link_apple_async(p_session, NakamaAPI.ApiAccountApple.create(NakamaAPI, {
"token": p_token
}))
# Link a custom ID to the user account owned by the session.
# @param p_session - The session of the user.
# @param p_id - A custom identifier usually obtained from an external authentication service.
# Returns a task which represents the asynchronous operation.
func link_custom_async(p_session : NakamaSession, p_id : String) -> NakamaAsyncResult:
return await _api_client.link_custom_async(p_session, NakamaAPI.ApiAccountCustom.create(NakamaAPI, {
"id": p_id
}))
# Link a device ID to the user account owned by the session.
# @param p_session - The session of the user.
# @param p_id - A device identifier usually obtained from a platform API.
# Returns a task which represents the asynchronous operation.
func link_device_async(p_session : NakamaSession, p_id : String) -> NakamaAsyncResult:
return await _api_client.link_device_async(p_session, NakamaAPI.ApiAccountDevice.create(NakamaAPI, {
"id": p_id
}))
# Link an email with password to the user account owned by the session.
# @param p_session - The session of the user.
# @param p_email - The email address of the user.
# @param p_password - The password for the user.
# Returns a task which represents the asynchronous operation.
func link_email_async(p_session : NakamaSession, p_email : String, p_password : String) -> NakamaAsyncResult:
return await _api_client.link_email_async(p_session, NakamaAPI.ApiAccountEmail.create(NakamaAPI, {
"email": p_email,
"password": p_password
}))
# Link a Facebook profile to a user account.
# @param p_session - The session of the user.
# @param p_token - An OAuth access token from the Facebook SDK.
# @param p_import - If the Facebook friends should be imported.
# Returns a task which represents the asynchronous operation.
func link_facebook_async(p_session : NakamaSession, p_token : String) -> NakamaAsyncResult:
return await _api_client.link_facebook_async(p_session, NakamaAPI.ApiAccountFacebook.create(NakamaAPI, {
"token": p_token
}))
# Add Facebook Instant Game to the social profiles on the current user's account.
# @param p_session - The session of the user.
# @param p_token - An OAuth access token from the Facebook SDK.
# @param p_import - If the Facebook friends should be imported.
# Returns a task which represents the asynchronous operation.
func link_facebook_instant_game_async(p_session : NakamaSession, p_signed_player_info : String) -> NakamaAsyncResult:
return await _api_client.link_facebook_instant_game_async(
p_session,
NakamaAPI.ApiAccountFacebookInstantGame.create(
NakamaAPI, {
"signed_player_info": p_signed_player_info
})
)
# Link a Game Center profile to a user account.
# @param p_session - The session of the user.
# @param p_bundle_id - The bundle ID of the Game Center application.
# @param p_player_id - The player ID of the user in Game Center.
# @param p_public_key_url - The URL for the public encryption key.
# @param p_salt - A random `NSString` used to compute the hash and keep it randomized.
# @param p_signature - The verification signature data generated.
# @param p_timestamp_seconds - The date and time that the signature was created.
# Returns a task which represents the asynchronous operation.
func link_game_center_async(p_session : NakamaSession,
p_bundle_id : String, p_player_id : String, p_public_key_url : String, p_salt : String, p_signature : String, p_timestamp_seconds) -> NakamaAsyncResult:
return await _api_client.link_game_center_async(p_session,
NakamaAPI.ApiAccountGameCenter.create(NakamaAPI, {
"bundle_id": p_bundle_id,
"player_id": p_player_id,
"public_key_url": p_public_key_url,
"salt": p_salt,
"signature": p_signature,
"timestamp_seconds": p_timestamp_seconds,
}))
# Link a Google profile to a user account.
# @param p_session - The session of the user.
# @param p_token - An OAuth access token from the Google SDK.
# Returns a task which represents the asynchronous operation.
func link_google_async(p_session : NakamaSession, p_token : String) -> NakamaAsyncResult:
return await _api_client.link_google_async(p_session, NakamaAPI.ApiAccountGoogle.create(NakamaAPI, {
"token": p_token
}))
# Link a Steam profile to a user account.
# @param p_session - The session of the user.
# @param p_token - An authentication token from the Steam network.
# Returns a task which represents the asynchronous operation.
func link_steam_async(p_session : NakamaSession, p_token : String, p_sync : bool = false) -> NakamaAsyncResult:
return await _api_client.link_steam_async(p_session, NakamaAPI.ApiLinkSteamRequest.create(
NakamaAPI,
{
"account": NakamaAPI.ApiAccountSteam.create(NakamaAPI, {
"token": p_token
}).serialize(),
"sync": p_sync
}
))
# List messages from a chat channel.
# @param p_session - The session of the user.
# @param p_channel_id - The id of the chat channel.
# @param p_limit - The number of chat messages to list.
# @param forward - Fetch messages forward from the current cursor (or the start).
# @param p_cursor - A cursor for the current position in the messages history to list.
# Returns a task which resolves to the channel message list object.
func list_channel_messages_async(p_session : NakamaSession, p_channel_id : String, limit : int = 1,
forward : bool = true, cursor = null): # -> NakamaAPI.ApiChannelMessageList:
return await _api_client.list_channel_messages_async(p_session, p_channel_id, limit, forward, cursor)
# List of friends of the current user.
# @param p_session - The session of the user.
# @param p_state - Filter by friendship state.
# @param p_limit - The number of friends to list.
# @param p_cursor - A cursor for the current position in the friends list.
# Returns a task which resolves to the friend objects.
func list_friends_async(p_session : NakamaSession, p_state = null, p_limit = null, p_cursor = null): # -> NakamaAPI.ApiFriendList:
return await _api_client.list_friends_async(p_session, p_limit, p_state, p_cursor)
# List all users part of the group.
# @param p_session - The session of the user.
# @param p_group_id - The ID of the group.
# @param p_state - Filter by group membership state.
# @param p_limit - The number of groups to list.
# @param p_cursor - A cursor for the current position in the group listing.
# Returns a task which resolves to the group user objects.
func list_group_users_async(p_session : NakamaSession, p_group_id : String, p_state = null, p_limit = null, p_cursor = null): # -> NakamaAPI.ApiGroupUserList:
return await _api_client.list_group_users_async(p_session, p_group_id, p_limit, p_state, p_cursor)
# List groups on the server.
# @param p_session - The session of the user.
# @param p_name - The name filter to apply to the group list.
# @param p_limit - The number of groups to list.
# @param p_cursor - A cursor for the current position in the groups to list.
# @param p_lang_tag - The language tag filter.
# @param p_members - The number of group members filter.
# @param p_open - Optional open/closed filter.
# Returns a task to resolve group objects.
func list_groups_async(p_session : NakamaSession, p_name = null, p_limit : int = 10, p_cursor = null, p_lang_tag = null, p_members = null, p_open = null): # -> NakamaAPI.ApiGroupList:
return await _api_client.list_groups_async(p_session, p_name, p_cursor, p_limit, p_lang_tag, p_members, p_open)
# List records from a leaderboard.
# @param p_session - The session of the user.
# @param p_leaderboard_id - The ID of the leaderboard to list.
# @param p_owner_ids - Record owners to fetch with the list of records.
# @param p_expiry - Expiry in seconds (since epoch) to begin fetching records from. Optional. 0 means from current time.
# @param p_limit - The number of records to list.
# @param p_cursor - A cursor for the current position in the leaderboard records to list.
# Returns a task which resolves to the leaderboard record objects.
func list_leaderboard_records_async(p_session : NakamaSession,
p_leaderboard_id : String, p_owner_ids = null, p_expiry = null, p_limit : int = 10, p_cursor = null): # -> NakamaAPI.ApiLeaderboardRecordList:
return await _api_client.list_leaderboard_records_async(p_session,
p_leaderboard_id, p_owner_ids, p_limit, p_cursor, p_expiry)
# List leaderboard records that belong to a user.
# @param p_session - The session for the user.
# @param p_leaderboard_id - The ID of the leaderboard to list.
# @param p_owner_id - The ID of the user to list around.
# @param p_expiry - Expiry in seconds (since epoch) to begin fetching records from. Optional. 0 means from current time.
# @param p_limit - The limit of the listings.
# @param p_cursor - A cursor for the current position in the leaderboard records to list.
# Returns a task which resolves to the leaderboard record objects.
func list_leaderboard_records_around_owner_async(p_session : NakamaSession,
p_leaderboar_id : String, p_owner_id : String, p_expiry = null, p_limit : int = 10, p_cursor = null): # -> NakamaAPI.ApiLeaderboardRecordList:
return await _api_client.list_leaderboard_records_around_owner_async(p_session,
p_leaderboar_id, p_owner_id, p_limit, p_expiry, p_cursor)
# Fetch a list of matches active on the server.
# @param p_session - The session of the user.
# @param p_min - The minimum number of match participants.
# @param p_max - The maximum number of match participants.
# @param p_limit - The number of matches to list.
# @param p_authoritative - If authoritative matches should be included.
# @param p_label - The label to filter the match list on.
# @param p_query - A query for the matches to filter.
# Returns a task which resolves to the match list object.
func list_matches_async(p_session : NakamaSession, p_min : int, p_max : int, p_limit : int, p_authoritative : bool,
p_label : String, p_query : String): # -> NakamaAPI.ApiMatchList:
return await _api_client.list_matches_async(p_session, p_limit, p_authoritative, p_label if p_label else null, p_min, p_max, p_query if p_query else null)
# List notifications for the user with an optional cursor.
# @param p_session - The session of the user.
# @param p_limit - The number of notifications to list.
# @param p_cacheable_cursor - A cursor for the current position in notifications to list.
# Returns a task to resolve notifications objects.
func list_notifications_async(p_session : NakamaSession, p_limit : int = 10, p_cacheable_cursor = null): # -> NakamaAPI.ApiNotificationList:
return await _api_client.list_notifications_async(p_session, p_limit, p_cacheable_cursor)
# List storage objects in a collection which have public read access.
# @param p_session - The session of the user.
# @param p_collection - The collection to list over.
# @param p_user_id - The id of the user that owns the objects.
# @param p_limit - The number of objects to list.
# @param p_cursor - A cursor to paginate over the collection.
# Returns a task which resolves to the storage object list.
func list_storage_objects_async(p_session : NakamaSession, p_collection : String, p_user_id : String = "", p_limit : int = 10, p_cursor = null): # -> NakamaAPI.ApiStorageObjectList:
return await _api_client.list_storage_objects_async(p_session, p_collection, p_user_id, p_limit, p_cursor)
# List user's subscriptions.
# @param p_session - The session of the user.
# @param p_limit - The number of objects to list.
# @param p_cursor - A cursor to paginate over the collection.
# Returns a task which resolves to the subscription list.
func list_subscriptions_async(p_session : NakamaSession, p_limit: int = 10, p_cursor = null): # -> NakamaAPI.ApiSubscriptionList:
return await _api_client.list_subscriptions_async(p_session, NakamaAPI.ApiListSubscriptionsRequest.create(
NakamaAPI,
{
"cursor": p_cursor,
"limit": p_limit,
}
))
# List tournament records around the owner.
# @param p_session - The session of the user.
# @param p_tournament_id - The ID of the tournament.
# @param p_owner_id - The ID of the owner to pivot around.
# @param p_expiry - Expiry in seconds (since epoch) to begin fetching records from.
# @param p_limit - The number of records to list.
# @param p_cursor - An optional cursor for the next page of tournament records.
# Returns a task which resolves to the tournament record list object.
func list_tournament_records_around_owner_async(p_session : NakamaSession,
p_tournament_id : String, p_owner_id : String, p_limit : int = 10, p_cursor = null, p_expiry = null): # -> NakamaAPI.ApiTournamentRecordList:
return await _api_client.list_tournament_records_around_owner_async(p_session, p_tournament_id, p_owner_id, p_limit, p_expiry, p_cursor)
# List records from a tournament.
# @param p_session - The session of the user.
# @param p_tournament_id - The ID of the tournament.
# @param p_owner_ids - The IDs of the record owners to return in the result.
# @param p_expiry - Expiry in seconds (since epoch) to begin fetching records from.
# @param p_limit - The number of records to list.
# @param p_cursor - An optional cursor for the next page of tournament records.
# Returns a task which resolves to the list of tournament records.
func list_tournament_records_async(p_session : NakamaSession, p_tournament_id : String,
p_owner_ids = null, p_limit : int = 10, p_cursor = null, p_expiry = null): # -> NakamaAPI.ApiTournamentRecordList:
return await _api_client.list_tournament_records_async(p_session, p_tournament_id, p_owner_ids, p_limit, p_cursor, p_expiry)
# List current or upcoming tournaments.
# @param p_session - The session of the user.
# @param p_category_start - The start of the category of tournaments to include.
# @param p_category_end - The end of the category of tournaments to include.
# @param p_start_time - The start time of the tournaments. (UNIX timestamp)
# @param p_end_time - The end time of the tournaments. (UNIX timestamp)
# @param p_limit - The number of tournaments to list.
# @param p_cursor - An optional cursor for the next page of tournaments.
# Returns a task which resolves to the list of tournament objects.
func list_tournaments_async(p_session : NakamaSession, p_category_start : int, p_category_end : int,
p_start_time : int, p_end_time : int, p_limit : int = 10, p_cursor = null): # -> NakamaAPI.ApiTournamentList:
return await _api_client.list_tournaments_async(p_session,
p_category_start, p_category_end, p_start_time, p_end_time, p_limit, p_cursor)
# List of groups the current user is a member of.
# @param p_session - The session of the user.
# @param p_user_id - The ID of the user whose groups to list.
# @param p_state - Filter by group membership state.
# @param p_limit - The number of records to list.
# @param p_cursor - A cursor for the current position in the listing.
# Returns a task which resolves to the group list object.
func list_user_groups_async(p_session : NakamaSession, p_user_id : String, p_state = null, p_limit = null, p_cursor = null): # -> NakamaAPI.ApiUserGroupList:
return await _api_client.list_user_groups_async(p_session, p_user_id, p_limit, p_state, p_cursor)
# List storage objects in a collection which belong to a specific user and have public read access.
# @param p_session - The session of the user.
# @param p_collection - The collection to list over.
# @param p_user_id - The user ID of the user to list objects for.
# @param p_limit - The number of objects to list.
# @param p_cursor - A cursor to paginate over the collection.
# Returns a task which resolves to the storage object list.
func list_users_storage_objects_async(p_session : NakamaSession,
p_collection : String, p_user_id : String, p_limit : int, p_cursor : String): # -> NakamaAPI.ApiStorageObjectList:
return await _api_client.list_storage_objects2_async(p_session, p_collection, p_user_id, p_limit, p_cursor)
# Promote one or more users in the group.
# @param p_session - The session of the user.
# @param p_group_id - The ID of the group to promote users into.
# @param p_ids - The IDs of the users to promote.
# Returns a task which represents the asynchronous operation.
func promote_group_users_async(p_session : NakamaSession, p_group_id : String, p_ids : PackedStringArray) -> NakamaAsyncResult:
return await _api_client.promote_group_users_async(p_session, p_group_id, p_ids)
# Read one or more objects from the storage engine.
# @param p_session - The session of the user.
# @param p_ids - The objects to read.
# Returns a task which resolves to the storage batch object.
func read_storage_objects_async(p_session : NakamaSession, p_ids : Array): # -> NakamaAPI.ApiStorageObjects:
var ids = []
for id in p_ids:
if not id is NakamaStorageObjectId:
continue # TODO Exceptions
var obj_id : NakamaStorageObjectId = id
ids.append(obj_id.as_read().serialize())
return await _api_client.read_storage_objects_async(p_session,
NakamaAPI.ApiReadStorageObjectsRequest.create(NakamaAPI, {
"object_ids": ids
}))
# Execute a function with an input payload on the server.
# @param p_session - The session of the user.
# @param p_id - The ID of the function to execute on the server.
# @param p_payload - The payload to send with the function call.
# Returns a task which resolves to the RPC response.
func rpc_async(p_session : NakamaSession, p_id : String, p_payload = null): # -> NakamaAPI.ApiRpc:
if p_payload == null:
return await _api_client.rpc_func2_async(p_session.token, p_id)
return await _api_client.rpc_func_async(p_session.token, p_id, p_payload)
# Execute a function on the server without a session.
# This function is usually used with server side code. DO NOT USE client side.
# @param p_http_key - The secure HTTP key used to authenticate.
# @param p_id - The id of the function to execute on the server.
# @param p_payload - A payload to send with the function call.
# Returns a task to resolve an RPC response.
func rpc_async_with_key(p_http_key : String, p_id : String, p_payload = null): # -> NakamaAPI.ApiRpc:
if p_payload == null:
return await _api_client.rpc_func2_async("", p_id, null, p_http_key)
return await _api_client.rpc_func_async("", p_id, p_payload, p_http_key)
# Log out a session which optionally invalidates the authorization and/or refresh tokens.
# @param p_session - The session of the user.
# Returns a task which represents the asynchronous operation.
func session_logout_async(p_session : NakamaSession) -> NakamaAsyncResult:
return await _api_client.session_logout_async(p_session,
NakamaAPI.ApiSessionLogoutRequest.create(NakamaAPI, {
"refresh_token": p_session.refresh_token,
"token": p_session.token
}))
# Refresh the session unless the current refresh token has expired. If vars are specified they will replace
# what is currently stored inside the session token.
# @param p_session - The session of the user.
# @param p_vars - Extra information which should be bundled inside the session token.
# Returns a task which resolves to a new session object.
func session_refresh_async(p_sesison : NakamaSession, p_vars = null) -> NakamaSession:
return _parse_auth(await _api_client.session_refresh_async(server_key, "",
NakamaAPI.ApiSessionRefreshRequest.create(NakamaAPI, {
"token": p_sesison.refresh_token,
"vars": p_vars
})))
# Remove the Apple ID from the social profiles on the current user's account.
# @param p_session - The session of the user.
# @param p_token - The ID token received from Apple.
# Returns a task which represents the asynchronous operation.
func unlink_apple_async(p_session : NakamaSession, p_token : String) -> NakamaAsyncResult:
return await _api_client.unlink_apple_async(p_session, NakamaAPI.ApiAccountApple.create(NakamaAPI, {
"token": p_token
}))
# Unlink a custom ID from the user account owned by the session.
# @param p_session - The session of the user.
# @param p_id - A custom identifier usually obtained from an external authentication service.
# Returns a task which represents the asynchronous operation.
func unlink_custom_async(p_session : NakamaSession, p_id : String) -> NakamaAsyncResult:
return await _api_client.unlink_custom_async(p_session, NakamaAPI.ApiAccountCustom.create(NakamaAPI, {
"id": p_id
}))
# Unlink a device ID from the user account owned by the session.
# @param p_session - The session of the user.
# @param p_id - A device identifier usually obtained from a platform API.
# Returns a task which represents the asynchronous operation.
func unlink_device_async(p_session : NakamaSession, p_id : String) -> NakamaAsyncResult:
return await _api_client.unlink_device_async(p_session, NakamaAPI.ApiAccountDevice.create(NakamaAPI, {
"id": p_id
}))
# Unlink an email with password from the user account owned by the session.
# @param p_session - The session of the user.
# @param p_email - The email address of the user.
# @param p_password - The password for the user.
# Returns a task which represents the asynchronous operation.
func unlink_email_async(p_session : NakamaSession, p_email : String, p_password : String) -> NakamaAsyncResult:
return await _api_client.unlink_email_async(p_session, NakamaAPI.ApiAccountEmail.create(NakamaAPI, {
"email": p_email,
"password": p_password
}))
# Unlink a Facebook profile from the user account owned by the session.
# @param p_session - The session of the user.
# @param p_token - An OAuth access token from the Facebook SDK.
# Returns a task which represents the asynchronous operation.
func unlink_facebook_async(p_session : NakamaSession, p_token : String) -> NakamaAsyncResult:
return await _api_client.unlink_facebook_async(p_session, NakamaAPI.ApiAccountFacebook.create(NakamaAPI, {
"token": p_token
}))
# Unlink a Facebook profile from the user account owned by the session.
# @param p_session - The session of the user.
# @param p_token - An OAuth access token from the Facebook SDK.
# Returns a task which represents the asynchronous operation.
func unlink_facebook_instant_game_async(p_session : NakamaSession, p_signed_player_info : String) -> NakamaAsyncResult:
return await _api_client.unlink_facebook_instant_game_async(
p_session,
NakamaAPI.ApiAccountFacebookInstantGame.create(NakamaAPI, {
"signed_player_info": p_signed_player_info
})
)
# Unlink a Game Center profile from the user account owned by the session.
# @param p_session - The session of the user.
# @param p_bundle_id - The bundle ID of the Game Center application.
# @param p_player_id - The player ID of the user in Game Center.
# @param p_public_key_url - The URL for the public encryption key.
# @param p_salt - A random `NSString` used to compute the hash and keep it randomized.
# @param p_signature - The verification signature data generated.
# @param p_timestamp_seconds - The date and time that the signature was created.
# Returns a task which represents the asynchronous operation.
func unlink_game_center_async(p_session : NakamaSession,
p_bundle_id : String, p_player_id : String, p_public_key_url : String, p_salt : String, p_signature : String, p_timestamp_seconds) -> NakamaAsyncResult:
return await _api_client.unlink_game_center_async(p_session,
NakamaAPI.ApiAccountGameCenter.create(NakamaAPI, {
"bundle_id": p_bundle_id,
"player_id": p_player_id,
"public_key_url": p_public_key_url,
"salt": p_salt,
"signature": p_signature,
"timestamp_seconds": p_timestamp_seconds,
}))
# Unlink a Google profile from the user account owned by the session.
# @param p_session - The session of the user.
# @param p_token - An OAuth access token from the Google SDK.
# Returns a task which represents the asynchronous operation.
func unlink_google_async(p_session : NakamaSession, p_token : String) -> NakamaAsyncResult:
return await _api_client.unlink_google_async(p_session, NakamaAPI.ApiAccountGoogle.create(NakamaAPI, {
"token": p_token
}))
# Unlink a Steam profile from the user account owned by the session.
# @param p_session - The session of the user.
# @param p_token - An authentication token from the Steam network.
# Returns a task which represents the asynchronous operation.
func unlink_steam_async(p_session : NakamaSession, p_token : String) -> NakamaAsyncResult:
return await _api_client.unlink_steam_async(p_session, NakamaAPI.ApiAccountSteam.create(NakamaAPI, {
"token": p_token
}))
# Update the current user's account on the server.
# @param p_session - The session for the user.
# @param p_username - The new username for the user.
# @param p_display_name - A new display name for the user.
# @param p_avatar_url - A new avatar url for the user.
# @param p_lang_tag - A new language tag in BCP-47 format for the user.
# @param p_location - A new location for the user.
# @param p_timezone - New timezone information for the user.
# Returns a task which represents the asynchronous operation.
func update_account_async(p_session : NakamaSession, p_username = null, p_display_name = null,
p_avatar_url = null, p_lang_tag = null, p_location = null, p_timezone = null) -> NakamaAsyncResult:
return await _api_client.update_account_async(p_session,
NakamaAPI.ApiUpdateAccountRequest.create(NakamaAPI, {
"avatar_url": p_avatar_url,
"display_name": p_display_name,
"lang_tag": p_lang_tag,
"location": p_location,
"timezone": p_timezone,
"username": p_username
}))
# Update a group.
# The user must have the correct access permissions for the group.
# @param p_session - The session of the user.
# @param p_group_id - The ID of the group to update.
# @param p_name - A new name for the group.
# @param p_open - If the group should have open membership.
# @param p_description - A new description for the group.
# @param p_avatar_url - A new avatar url for the group.
# @param p_lang_tag - A new language tag in BCP-47 format for the group.
# Returns a task which represents the asynchronous operation.
func update_group_async(p_session : NakamaSession,
p_group_id : String, p_name = null, p_description = null, p_avatar_url = null, p_lang_tag = null, p_open = null) -> NakamaAsyncResult:
return await _api_client.update_group_async(p_session, p_group_id,
NakamaAPI.ApiUpdateGroupRequest.create(NakamaAPI, {
"name": p_name,
"open": p_open,
"avatar_url": p_avatar_url,
"description": p_description,
"lang_tag": p_lang_tag
}))
# Validate a purchase receipt against the Apple App Store.
# @param p_session - The session of the user.
# @param p_receipt - The purchase receipt to be validated.
# Returns a task which resolves to the validated list of purchase receipts.
func validate_purchase_apple_async(p_session : NakamaSession, p_receipt : String): # -> NakamaAPI.ApiValidatePurchaseResponse
return await _api_client.validate_purchase_apple_async(p_session,
NakamaAPI.ApiValidatePurchaseAppleRequest.create(NakamaAPI, {
"receipt": p_receipt
}))
# Validate a purchase receipt against the Google Play Store.
# @param p_session - The session of the user.
# @param p_receipt - The purchase receipt to be validated.
# Returns a task which resolves to the validated list of purchase receipts.
func validate_purchase_google_async(p_session : NakamaSession, p_receipt : String): # -> NakamaAPI.ApiValidatePurchaseResponse
return await _api_client.validate_purchase_google_async(p_session,
NakamaAPI.ApiValidatePurchaseGoogleRequest.create(NakamaAPI, {
"purchase": p_receipt
}))
# Validate a purchase receipt against the Huawei AppGallery.
# @param p_session - The session of the user.
# @param p_receipt - The purchase receipt to be validated.
# @param p_signature - The signature of the purchase receipt.
# Returns a task which resolves to the validated list of purchase receipts.
func validate_purchase_huawei_async(p_session : NakamaSession, p_receipt : String, p_signature : String): # -> NakamaAPI.ApiValidatePurchaseResponse
return await _api_client.validate_purchase_huawei_async(p_session,
NakamaAPI.ApiValidatePurchaseHuaweiRequest.create(NakamaAPI, {
"purchase": p_receipt,
"signature": p_signature
}))
# Validate Apple Subscription Receipt
# @param p_session - The session of the user.
# @param p_receipt - The purchase receipt to be validated.
# @param p_persist - Whether or not to track the receipt in the Nakama database.
# Returns a task which resolves to the validated subscription response.
func validate_subscription_apple_async(p_session : NakamaSession, p_receipt : String, p_persist : bool = true): # -> NakamaAPI.ApiValidateSubscriptionResponse:
return await _api_client.validate_subscription_apple_async(p_session,
NakamaAPI.ApiValidateSubscriptionAppleRequest.create(NakamaAPI, {
"receipt": p_receipt,
"persist": p_persist,
}))
# Validate Google Subscription Receipt
# @param p_session - The session of the user.
# @param p_receipt - The purchase receipt to be validated.
# @param p_persist - Whether or not to track the receipt in the Nakama database.
# Returns a task which resolves to the validated subscription response.
func validate_subscription_google_async(p_session : NakamaSession, p_receipt : String, p_persist : bool = true): # -> NakamaAPI.ApiValidateSubscriptionResponse:
return await _api_client.validate_subscription_google_async(p_session,
NakamaAPI.ApiValidateSubscriptionGoogleRequest.create(NakamaAPI, {
"receipt": p_receipt,
"persist": p_persist,
}))
# Write a record to a leaderboard.
# @param p_session - The session for the user.
# @param p_leaderboard_id - The ID of the leaderboard to write.
# @param p_score - The score for the leaderboard record.
# @param p_subscore - The subscore for the leaderboard record.
# @param p_metadata - The metadata for the leaderboard record.
# Returns a task which resolves to the leaderboard record object written.
func write_leaderboard_record_async(p_session : NakamaSession,
p_leaderboard_id : String, p_score : int, p_subscore : int = 0, p_metadata = null): # -> NakamaAPI.ApiLeaderboardRecord:
return await _api_client.write_leaderboard_record_async(p_session, p_leaderboard_id,
NakamaAPI.WriteLeaderboardRecordRequestLeaderboardRecordWrite.create(NakamaAPI, {
"metadata": p_metadata,
"score": str(p_score),
"subscore": str(p_subscore)
}))
# Write objects to the storage engine.
# @param p_session - The session of the user.
# @param p_objects - The objects to write.
# Returns a task which resolves to the storage write acknowledgements.
func write_storage_objects_async(p_session : NakamaSession, p_objects : Array): # -> NakamaAPI.ApiStorageObjectAcks:
var writes : Array = []
for obj in p_objects:
if not obj is NakamaWriteStorageObject:
continue # TODO Exceptions
var write_obj : NakamaWriteStorageObject = obj
writes.append(write_obj.as_write().serialize())
return await _api_client.write_storage_objects_async(p_session,
NakamaAPI.ApiWriteStorageObjectsRequest.create(NakamaAPI, {
"objects": writes
}))
# Write a record to a tournament.
# @param p_session - The session of the user.
# @param p_tournament_id - The ID of the tournament to write.
# @param p_score - The score of the tournament record.
# @param p_subscore - The subscore for the tournament record.
# @param p_metadata - The metadata for the tournament record.
# Returns a task which resolves to the tournament record object written.
func write_tournament_record_async(p_session : NakamaSession,
p_tournament_id : String, p_score : int, p_subscore : int = 0, p_metadata = null): # -> NakamaAPI.ApiLeaderboardRecord:
return await _api_client.write_tournament_record_async(p_session, p_tournament_id,
NakamaAPI.WriteTournamentRecordRequestTournamentRecordWrite.create(NakamaAPI, {
"metadata": p_metadata,
"score": str(p_score),
"subscore": str(p_subscore)
}))
# Write a record to a tournament.
# @param p_session - The session of the user.
# @param p_tournament_id - The ID of the tournament to write.
# @param p_score - The score of the tournament record.
# @param p_subscore - The subscore for the tournament record.
# @param p_metadata - The metadata for the tournament record.
# Returns a task which resolves to the tournament record object written.
func write_tournament_record2_async(p_session : NakamaSession,
p_tournament_id : String, p_score : int, p_subscore : int = 0, p_metadata = null): # -> NakamaAPI.ApiLeaderboardRecord:
return await _api_client.write_tournament_record2_async(p_session, p_tournament_id,
NakamaAPI.WriteTournamentRecordRequestTournamentRecordWrite.create(NakamaAPI, {
"metadata": p_metadata,
"score": str(p_score),
"subscore": str(p_subscore)
}))
@@ -0,0 +1 @@
uid://dghnxikdf8a7u
@@ -0,0 +1,208 @@
@tool
extends Node
# An adapter which implements the HTTP protocol.
class_name NakamaHTTPAdapter
# The logger to use with the adapter.
var logger : RefCounted = NakamaLogger.new()
# The timeout for requests
var timeout : int = 3
# If request should be automatically retried when a network error occurs.
var auto_retry : bool = true
# The maximum number of time a request will be retried when auto_retry is true
var auto_retry_count : int = 3
var auto_retry_backoff_base : int = 10
# Whether or not to use threads when making HTTP requests.
var use_threads : bool = true
var _pending = {}
var id : int = 0
class AsyncRequest:
var id : int
var request : HTTPRequest
var uri : String
var method : int
var headers : PackedStringArray
var body : PackedByteArray
var retry_count := 3
var backoff_time := 10
var logger : NakamaLogger
var cancelled = false
var result : int = HTTPRequest.RESULT_NO_RESPONSE
var response_code : int = -1
var response_body : PackedByteArray
var timer : SceneTreeTimer = null
var cur_try : int = 1
var rng = RandomNumberGenerator.new()
func _init(p_id : int, p_request : HTTPRequest, p_uri : String,
p_method : int, p_headers : PackedStringArray, p_body : PackedByteArray,
p_retry_count : int, p_backoff_time : int, p_logger : NakamaLogger):
rng.seed = Time.get_ticks_usec()
id = p_id
request = p_request
uri = p_uri
method = p_method
headers = p_headers
body = p_body
retry_count = p_retry_count
backoff_time = p_backoff_time
logger = p_logger
func should_retry():
return cur_try < retry_count and not cancelled
func retry():
var time = pow(backoff_time, cur_try) * rng.randf_range(0.5, 1)
logger.debug("Retrying request %d. Tries left: %d. Backoff: %d ms" % [
id, retry_count - cur_try, time
])
cur_try += 1
await backoff(time)
if cancelled:
return
return await make_request()
func make_request():
var err = request.request(uri, headers, method, body.get_string_from_utf8())
if err != OK:
await request.get_tree().process_frame
result = HTTPRequest.RESULT_CANT_CONNECT
logger.debug("Request %d failed to start, error: %d" % [id, err])
return
var args = await request.request_completed
result = args[0]
response_code = args[1]
response_body = args[3]
func backoff(p_time : int):
timer = request.get_tree().create_timer(p_time / 1000)
await timer.timeout
timer = null
func cancel():
cancelled = true
request.cancel_request()
if timer:
timer.time_left = 0
else:
request.call_deferred("emit_signal", "request_completed", HTTPRequest.RESULT_REQUEST_FAILED, 0, [], [])
func parse_result():
if cancelled:
return NakamaException.new("Request cancelled", -1, -1, true)
elif result != HTTPRequest.RESULT_SUCCESS:
if result == null:
result = 0
return NakamaException.new("HTTPRequest failed!", result)
var json = JSON.new()
var json_error = json.parse(response_body.get_string_from_utf8())
if json_error != OK:
logger.debug("Unable to parse request %d response. JSON error: %d, JSON error message: %s, response code: %d" % [
id, json_error, json.get_error_message(), response_code
])
return NakamaException.new("Failed to decode JSON response", response_code)
var parsed = json.get_data()
if response_code != HTTPClient.RESPONSE_OK:
var error = ""
var code = -1
if typeof(parsed) == TYPE_DICTIONARY:
if "message" in parsed:
error = parsed["message"]
elif "error" in parsed:
error = parsed["error"]
else:
error = str(parsed)
code = parsed["code"] if "code" in parsed else -1
else:
error = str(parsed)
if typeof(error) == TYPE_DICTIONARY:
error = JSON.stringify(error)
logger.debug("Request %d returned response code: %d, RPC code: %d, error: %s" % [
id, response_code, code, error
])
return NakamaException.new(error, response_code, code)
return parsed
# Send a HTTP request.
# @param method - HTTP method to use for this request.
# @param uri - The fully qualified URI to use.
# @param headers - Request headers to set.
# @param body - Request content body to set.
# @param timeoutSec - Request timeout.
# Returns a task which resolves to the contents of the response.
func send_async(p_method : String, p_uri : String, p_headers : Dictionary, p_body : PackedByteArray):
var req = HTTPRequest.new()
req.timeout = timeout
if use_threads and OS.get_name() != 'Web':
req.use_threads = true # Threads not available nor needed on the web.
# Parse method
var method = HTTPClient.METHOD_GET
if p_method == "POST":
method = HTTPClient.METHOD_POST
elif p_method == "PUT":
method = HTTPClient.METHOD_PUT
elif p_method == "DELETE":
method = HTTPClient.METHOD_DELETE
elif p_method == "HEAD":
method = HTTPClient.METHOD_HEAD
var headers = PackedStringArray()
# Parse headers
headers.append("Accept: application/json")
for k in p_headers:
headers.append("%s: %s" % [k, p_headers[k]])
id += 1
var retry = auto_retry_count if auto_retry else 0
var backoff = auto_retry_backoff_base
_pending[id] = AsyncRequest.new(id, req, p_uri, method, headers, p_body, retry, backoff, logger)
logger.debug("Sending request [ID: %d, Method: %s, Uri: %s, Headers: %s, Body: %s, Timeout: %d, Retries: %d, Backoff base: %d ms]" % [
id, p_method, p_uri, p_headers, p_body.get_string_from_utf8(), timeout, retry, backoff
])
add_child(req)
return await _send_async(id, _pending)
func get_last_token():
return id
func cancel_request(p_token):
if _pending.has(p_token):
_pending[p_token].cancel()
static func _clear_request(p_request : AsyncRequest, p_pending : Dictionary, p_id : int):
if not p_request.request.is_queued_for_deletion():
p_request.logger.debug("Freeing request %d" % p_id)
p_request.request.queue_free()
p_pending.erase(p_id)
static func _send_async(p_id : int, p_pending : Dictionary):
var req : AsyncRequest = p_pending[p_id]
await req.make_request()
while req.result != HTTPRequest.RESULT_SUCCESS:
req.logger.debug("Request %d failed with result: %d, response code: %d" % [
p_id, req.result, req.response_code
])
if not req.should_retry():
break
await req.retry()
_clear_request(req, p_pending, p_id)
return req.parse_result()
@@ -0,0 +1 @@
uid://cgluyw45mnewn
@@ -0,0 +1,112 @@
// Copyright 2022 The Nakama Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Nakama.TinyJson;
using Godot;
namespace Nakama {
/// <summary>
/// An Http adapter which uses Godot's HttpRequest node.
/// </summary>
/// <remarks>
/// Note Content-Type header is always set as 'application/json'.
/// </remarks>
public partial class GodotHttpAdapter : Node, IHttpAdapter {
/// <inheritdoc cref="IHttpAdapter.Logger"/>
public ILogger Logger { get; set; }
/// <inheritdoc cref="IHttpAdapter.TransientExceptionDelegate"/>
public TransientExceptionDelegate TransientExceptionDelegate => IsTransientException;
/// <inheritdoc cref="IHttpAdapter"/>
public async Task<string> SendAsync(string method, Uri uri, IDictionary<string, string> headers,
byte[] body, int timeout, CancellationToken? cancellationToken)
{
var req = new HttpRequest();
req.Timeout = timeout;
if (OS.GetName() != "HTML5") {
req.UseThreads = true;
}
var godot_method = HttpClient.Method.Get;
if (method == "POST") {
godot_method = HttpClient.Method.Post;
}
else if (method == "PUT") {
godot_method = HttpClient.Method.Put;
}
else if (method == "DELETE") {
godot_method = HttpClient.Method.Delete;
}
else if (method == "HEAD") {
godot_method = HttpClient.Method.Head;
}
var headers_array = new String[headers.Count + 1];
headers_array[0] = "Accept: application/json";
int index = 1;
foreach (var item in headers) {
headers_array[index] = item.Key + ": " + item.Value;
index++;
}
string body_string = body != null ? System.Text.Encoding.UTF8.GetString(body) : "";
AddChild(req);
req.Request(uri.ToString(), headers_array, godot_method, body_string);
Logger?.InfoFormat("Send: method='{0}', uri='{1}', body='{2}'", method, uri, body_string);
Variant[] resultObjects = await ToSignal(req, "request_completed");
HttpRequest.Result result = (HttpRequest.Result)(long)resultObjects[0];
long response_code = (long)resultObjects[1];
string response_body = System.Text.Encoding.UTF8.GetString((byte[])resultObjects[3]);
req.QueueFree();
Logger?.InfoFormat("Received: status={0}, contents='{1}'", response_code, response_body);
if (result == HttpRequest.Result.Success && response_code >= 200 && response_code <= 299) {
return response_body;
}
var decoded = response_body.FromJson<Dictionary<string, object>>();
string message = decoded.ContainsKey("message") ? decoded["message"].ToString() : string.Empty;
int grpcCode = decoded.ContainsKey("code") ? (int) decoded["code"] : -1;
var exception = new ApiResponseException(response_code, message, grpcCode);
if (decoded.ContainsKey("error"))
{
IHttpAdapterUtil.CopyResponseError(this, decoded["error"], exception);
}
throw exception;
}
private static bool IsTransientException(Exception e) {
return e is ApiResponseException apiException && (apiException.StatusCode >= 500 || apiException.StatusCode == -1);
}
}
}
@@ -0,0 +1,79 @@
// Copyright 2022 The Nakama Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using Godot;
namespace Nakama {
/// <summary>
/// A logger which prints to the Godot console.
/// </summary>
public class GodotLogger : ILogger {
/// <summary>
/// The log level.
/// </summary>
public enum LogLevel {
NONE,
ERROR,
WARNING,
INFO,
DEBUG,
}
private string module;
private LogLevel level;
/// <summary>
/// Constructs a GodotLogger.
/// </summary>
/// <param name="p_module">The label to use for log entries.</param>
/// <param name="p_level">The log level (or lower) to print to the console.</param>
public GodotLogger(string p_module = "Nakama", LogLevel p_level = LogLevel.ERROR) {
module = p_module;
level = p_level;
}
/// <inheritdoc cref="ILogger"/>
public void ErrorFormat(string format, params object[] args) {
if (level >= LogLevel.ERROR) {
GD.PrintErr("=== " + module + " : ERROR === " + String.Format(format, args));
}
}
/// <inheritdoc cref="ILogger"/>
public void WarnFormat(string format, params object[] args) {
if (level >= LogLevel.WARNING) {
GD.Print("=== " + module + " : WARN === " + String.Format(format, args));
}
}
/// <inheritdoc cref="ILogger"/>
public void InfoFormat(string format, params object[] args) {
if (level >= LogLevel.INFO) {
GD.Print("=== " + module + " : INFO === " + String.Format(format, args));
}
}
/// <inheritdoc cref="ILogger"/>
public void DebugFormat(string format, params object[] args) {
if (level >= LogLevel.DEBUG) {
GD.Print("=== " + module + " : DEBUG === " + String.Format(format, args));
}
}
}
}
@@ -0,0 +1,211 @@
// Copyright 2022 The Nakama Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.Threading;
using System.Threading.Tasks;
using Godot;
namespace Nakama
{
/// <summary>
/// An exception that is thrown when the WebSocket is unable to connect.
/// </summary>
public class GodotWebSocketConnectionException : Exception {
public GodotWebSocketConnectionException(string message = "WebSocket unable to connect")
: base(message) { }
}
/// <summary>
/// An exception that is thrown when the WebSocket is unable to send.
/// </summary>
public class GodotWebSocketSendException : Exception {
public GodotWebSocketSendException() : base("Unable to send over WebSocket") { }
}
/// <summary>
/// A socket adapter which uses Godot's WebSocketPeer.
/// </summary>
public partial class GodotWebSocketAdapter : Node, ISocketAdapter
{
/// <inheritdoc cref="ISocketAdapter.Connected"/>
public event Action Connected;
/// <inheritdoc cref="ISocketAdapter.Closed"/>
public event Action Closed;
/// <inheritdoc cref="ISocketAdapter.ReceivedError"/>
public event Action<Exception> ReceivedError;
/// <inheritdoc cref="ISocketAdapter.Received"/>
public event Action<ArraySegment<byte>> Received;
/// <inheritdoc cref="ISocketAdapter.IsConnected"/>
public new bool IsConnected
{
get
{
return ws.GetReadyState() == WebSocketPeer.State.Open;
}
}
/// <inheritdoc cref="ISocketAdapter.IsConnecting"/>
public bool IsConnecting
{
get
{
return ws.GetReadyState() == WebSocketPeer.State.Connecting;
}
}
private WebSocketPeer ws;
private WebSocketPeer.State wsLastState = WebSocketPeer.State.Closed;
private TaskCompletionSource<bool> connectionSource;
private TaskCompletionSource<bool> closeSource;
private int connectionTimeout;
private double connectionStart;
/// <summary>
/// Constructs a GodotWebSocketAdapter.
/// </summary>
public GodotWebSocketAdapter()
{
ws = new WebSocketPeer();
}
/// <inheritdoc cref="ISocketAdaptor.CloseAsync"/>
public Task CloseAsync()
{
if (closeSource == null)
{
closeSource = new TaskCompletionSource<bool>();
}
ws.Close();
return closeSource.Task;
}
/// <inheritdoc cref="ISocketAdaptor.ConnectAsync"/>
public Task ConnectAsync(Uri uri, int timeout)
{
if (connectionSource != null)
{
connectionSource.SetException(new GodotWebSocketConnectionException("Connection attempt aborted due to new connection attempt"));
connectionSource = null;
}
if (ws.GetReadyState() != WebSocketPeer.State.Closed)
{
return Task.FromException(new GodotWebSocketConnectionException("Cannot connect until current socket is closed"));
}
connectionTimeout = timeout;
connectionStart = Time.GetUnixTimeFromSystem();
connectionSource = new TaskCompletionSource<bool>();
var err = ws.ConnectToUrl(uri.ToString());
if (err != Error.Ok)
{
return Task.FromException(new GodotWebSocketConnectionException(String.Format("Error connecting: {0}", Enum.GetName(typeof(Error), err))));
}
wsLastState = WebSocketPeer.State.Closed;
return connectionSource.Task;
}
/// <inheritdoc cref="ISocketAdaptor.SendAsync"/>
public Task SendAsync(ArraySegment<byte> buffer, bool reliable = true, CancellationToken canceller = default)
{
byte[] temp;
if (buffer.Offset != 0 || buffer.Count != buffer.Array.Length)
{
temp = new byte[buffer.Count];
Array.Copy(buffer.Array, buffer.Offset, temp, 0, buffer.Count);
}
else
{
temp = buffer.Array;
}
var err = ws.Send(temp, WebSocketPeer.WriteMode.Text);
if (err == Error.Ok)
{
return Task.CompletedTask;
}
return Task.FromException(new GodotWebSocketSendException());
}
public override void _Process(double delta)
{
if (ws.GetReadyState() != WebSocketPeer.State.Closed)
{
ws.Poll();
}
var state = ws.GetReadyState();
if (wsLastState != state)
{
wsLastState = state;
if (state == WebSocketPeer.State.Open)
{
Connected?.Invoke();
connectionSource.SetResult(true);
connectionSource = null;
}
else if (state == WebSocketPeer.State.Closed)
{
if (connectionSource != null)
{
Exception e = new GodotWebSocketConnectionException("Failed to connect");
ReceivedError?.Invoke(e);
connectionSource.SetException(e);
connectionSource = null;
}
else
{
Closed?.Invoke();
}
if (closeSource != null)
{
closeSource.SetResult(true);
closeSource = null;
}
}
}
if (ws.GetReadyState() == WebSocketPeer.State.Connecting) {
if (connectionStart + (double)connectionTimeout < Time.GetUnixTimeFromSystem())
{
ws.Close();
Exception e = new GodotWebSocketConnectionException("Connection timed out");
ReceivedError?.Invoke(e);
connectionSource.SetException(e);
connectionSource = null;
}
}
while (ws.GetReadyState() == WebSocketPeer.State.Open && ws.GetAvailablePacketCount() > 0)
{
Received?.Invoke(new ArraySegment<byte>(ws.GetPacket()));
}
}
}
}
@@ -0,0 +1,598 @@
extends RefCounted
# A socket to interact with Nakama server.
class_name NakamaSocket
const ChannelType = NakamaRTMessage.ChannelJoin.ChannelType
# Emitted when a socket is closed.
signal closed()
# Emitted when a socket is connected.
signal connected()
# Emitted when an error occurs while connecting.
signal connection_error(p_error)
# Emitted when a chat channel message is received
signal received_channel_message(p_channel_message) # ApiChannelMessage
# Emitted when receiving a presence change for joins and leaves with users in a chat channel.
signal received_channel_presence(p_channel_presence) # ChannelPresenceEvent
# Emitted when an error is received from the server.
signal received_error(p_error) # Error
# Emitted when receiving a matchmaker matched message.
signal received_matchmaker_matched(p_matchmaker_matched) # MatchmakerMatched
# Emitted when receiving a message from a multiplayer match.
signal received_match_state(p_match_state) # MatchData
# Emitted when receiving a presence change for joins and leaves of users in a multiplayer match.
signal received_match_presence(p_match_presence_event) # MatchPresenceEvent
# Emitted when receiving a notification for the current user.
signal received_notification(p_api_notification) # ApiNotification
# Emitted when receiving a presence change for when a user updated their online status.
signal received_status_presence(p_status_presence_event) # StatusPresenceEvent
# Emitted when receiving a presence change for joins and leaves on a realtime stream.
signal received_stream_presence(p_stream_presence_event) # StreamPresenceEvent
# Emitted when receiving a message from a realtime stream.
signal received_stream_state(p_stream_state) # StreamState
# Received a party event. This will occur when the current user's invitation request is accepted
# the party leader of a closed party.
signal received_party(p_party) # Party
# Received a party close event.
signal received_party_close(p_party_close) # PartyClose
# Received custom party data.
signal received_party_data(p_party_data) # PartyData
# Received a request to join the party.
signal received_party_join_request(p_party_join_request) # PartyJoinRequest
# Received a change in the party leader.
signal received_party_leader(p_party_leader) # PartyLeader
# Received a new matchmaker ticket for the party.
signal received_party_matchmaker_ticket(p_party_matchmaker_ticket) # PartyMatchmakerTicket
# Received a new presence event in the party.
signal received_party_presence(p_party_presence_event) # PartyPresenceEvent
var _adapter : NakamaSocketAdapter
var _free_adapter : bool = false
var _weak_ref : WeakRef
var _base_uri : String
var _requests : Dictionary
var _last_id : int = 1
var _conn = null
var logger : NakamaLogger = null
class AsyncConnection:
signal completed(result)
func resume(result) -> void:
emit_signal("completed", result)
class AsyncRequest:
var id : String
var type
var ns
var result_key : String
signal completed(result)
func _init(p_id : String, p_type, p_ns, p_result_key = null):
id = p_id
type = p_type
ns = p_ns
if type != NakamaAsyncResult:
# Specifically defined key, or default for object.
result_key = p_result_key if p_result_key != null else type.get_result_key()
func resume(data, logger = null) -> void:
var result = _parse_result(data, logger)
emit_signal("completed", result)
func _parse_result(data, logger):
# We got an exception, maybe the task was cancelled?
if data is NakamaException:
return type.new(data as NakamaException)
# Error from server
if data.has("error"):
var err = data["error"]
var code = -1
var msg = str(err)
if typeof(err) == TYPE_DICTIONARY:
msg = err.get("message", "")
code = err.get("code", -1)
if logger:
logger.warning("Error response from server: %s" % err)
return type.new(NakamaException.new(msg, code))
# Simple ack response
elif type == NakamaAsyncResult:
return NakamaAsyncResult.new()
# Missing expected result key
elif not data.has(result_key):
if logger:
logger.warning("Missing expected result key: %s" % result_key)
return type.new(NakamaException.new("Missing expected result key: %s" % result_key))
# All good, proceed with parsing
else:
return type.create(ns, data.get(result_key))
func _resume_conn(p_err : int):
if _conn:
if p_err: # Exception
logger.warning("Connection error: %d" % p_err)
_conn.resume(NakamaAsyncResult.new(NakamaException.new()))
else:
logger.info("Connected!")
_conn.resume(NakamaAsyncResult.new())
_conn = null
func _init(p_adapter : NakamaSocketAdapter,
p_host : String,
p_port : int,
p_scheme : String,
p_free_adapter : bool = false):
logger = p_adapter.logger
_adapter = p_adapter
_weak_ref = weakref(_adapter)
var port = ""
if (p_scheme == "ws" and p_port != 80) or (p_scheme == "wss" and p_port != 443):
port = ":%d" % p_port
_base_uri = "%s://%s%s" % [p_scheme, p_host, port]
_free_adapter = p_free_adapter
_adapter.closed.connect(self._closed)
_adapter.connected.connect(self._connected)
_adapter.received_error.connect(self._connection_error)
_adapter.received.connect(self._received)
func _notification(what):
if what == NOTIFICATION_PREDELETE:
# Is this a bug? Why can't I call a function? self is null...
# _clear_responses()
# _resume_conn(ERR_FILE_EOF)
var keys = _requests.keys()
for k in keys:
_requests[k].resume(NakamaException.new("Cancelled!"))
if _conn != null:
_conn.resume(ERR_FILE_EOF)
_conn = null
if _weak_ref.get_ref() == null:
return
_adapter.close()
if _free_adapter:
_adapter.queue_free()
func _closed(p_error = null):
emit_signal("closed")
_resume_conn(ERR_CANT_CONNECT)
_clear_requests()
func _connection_error(p_error):
emit_signal("connection_error", p_error)
_resume_conn(p_error)
_clear_requests()
func _connected():
emit_signal("connected")
_resume_conn(OK)
func _received(p_bytes : PackedByteArray):
var json = JSON.new()
var json_str = p_bytes.get_string_from_utf8()
var json_error := json.parse(json_str)
if json_error != OK or typeof(json.get_data()) != TYPE_DICTIONARY:
logger.error("Unable to parse response: %s" % json_str)
return
var dict : Dictionary = json.get_data()
var cid = dict.get("cid")
if cid:
if _requests.has(cid):
_resume_request(cid, dict)
else:
logger.error("Invalid call id received %s" % dict)
else:
if dict.has("error"):
var res = NakamaRTAPI.Error.create(NakamaRTAPI, dict["error"])
emit_signal("received_error", res)
elif dict.has("channel_message"):
var res = NakamaAPI.ApiChannelMessage.create(NakamaAPI, dict["channel_message"])
emit_signal("received_channel_message", res)
elif dict.has("channel_presence_event"):
var res = NakamaRTAPI.ChannelPresenceEvent.create(NakamaRTAPI, dict["channel_presence_event"])
emit_signal("received_channel_presence", res)
elif dict.has("match_data"):
var res = NakamaRTAPI.MatchData.create(NakamaRTAPI, dict["match_data"])
emit_signal("received_match_state", res)
elif dict.has("match_presence_event"):
var res = NakamaRTAPI.MatchPresenceEvent.create(NakamaRTAPI, dict["match_presence_event"])
emit_signal("received_match_presence", res)
elif dict.has("matchmaker_matched"):
var res = NakamaRTAPI.MatchmakerMatched.create(NakamaRTAPI, dict["matchmaker_matched"])
emit_signal("received_matchmaker_matched", res)
elif dict.has("notifications"):
var res = NakamaAPI.ApiNotificationList.create(NakamaAPI, dict["notifications"])
for n in res.notifications:
emit_signal("received_notification", n)
elif dict.has("status_presence_event"):
var res = NakamaRTAPI.StatusPresenceEvent.create(NakamaRTAPI, dict["status_presence_event"])
emit_signal("received_status_presence", res)
elif dict.has("stream_presence_event"):
var res = NakamaRTAPI.StreamPresenceEvent.create(NakamaRTAPI, dict["stream_presence_event"])
emit_signal("received_stream_presence", res)
elif dict.has("stream_data"):
var res = NakamaRTAPI.StreamData.create(NakamaRTAPI, dict["stream_data"])
emit_signal("received_stream_state", res)
elif dict.has("party"):
var res = NakamaRTAPI.Party.create(NakamaRTAPI, dict["party"])
emit_signal("received_party", res)
elif dict.has("party_close"):
var res = NakamaRTAPI.PartyClose.create(NakamaRTAPI, dict["party_close"])
emit_signal("received_party_close", res)
elif dict.has("party_data"):
var res = NakamaRTAPI.PartyData.create(NakamaRTAPI, dict["party_data"])
emit_signal("received_party_data", res)
elif dict.has("party_join_request"):
var res = NakamaRTAPI.PartyJoinRequest.create(NakamaRTAPI, dict["party_join_request"])
emit_signal("received_party_join_request", res)
elif dict.has("party_leader"):
var res = NakamaRTAPI.PartyLeader.create(NakamaRTAPI, dict["party_leader"])
emit_signal("received_party_leader", res)
elif dict.has("party_matchmaker_ticket"):
var res = NakamaRTAPI.PartyMatchmakerTicket.create(NakamaRTAPI, dict["party_matchmaker_ticket"])
emit_signal("received_party_matchmaker_ticket", res)
elif dict.has("party_presence_event"):
var res = NakamaRTAPI.PartyPresenceEvent.create(NakamaRTAPI, dict["party_presence_event"])
emit_signal("received_party_presence", res)
else:
logger.warning("Unhandled response: %s" % dict)
func _resume_request(p_id : String, p_data):
if _requests.has(p_id):
logger.debug("Resuming request: %s: %s" % [p_id, p_data])
_requests[p_id].resume(p_data, logger)
_requests.erase(p_id)
else:
logger.warning("Trying to resume missing request: %s: %s" % [p_id, p_data])
func _cancel_request(p_id : String):
logger.debug("Cancelling request: %s" % [p_id])
_resume_request(p_id, NakamaException.new("Request cancelled."))
func _clear_requests():
var ids = _requests.keys()
for id in ids:
_cancel_request(id)
func _send_async(p_message, p_parse_type = NakamaAsyncResult, p_ns = NakamaRTAPI, p_msg_key = null, p_result_key = null) -> AsyncRequest:
logger.debug("Sending async request: %s" % p_message)
# For messages coming from the API which does not have a key defined, so we can override it
var msg = p_msg_key
# For regular RT messages
if msg == null:
msg = p_message.get_msg_key()
var id = str(_last_id)
_last_id += 1
_requests[id] = AsyncRequest.new(id, p_parse_type, p_ns, p_result_key)
var json := JSON.stringify({
"cid": id,
msg: p_message.serialize()
})
var err = _adapter.send(json.to_utf8_buffer())
if err != OK:
call_deferred("_cancel_request", id)
return _requests[id]
# If the socket is connected.
func is_connected_to_host():
return _adapter.is_connected_to_host()
# If the socket is connecting.
func is_connecting_to_host():
return _adapter.is_connecting_to_host()
# Close the socket connection to the server.
func close():
_adapter.close()
# Connect to the server.
# @param p_session - The session of the user.
# @param p_appear_online - If the user who appear online to other users.
# @param p_connect_timeout - The time allowed for the socket connection to be established.
# Returns a task to represent the asynchronous operation.
func connect_async(p_session : NakamaSession, p_appear_online : bool = false, p_connect_timeout : int = 3):
var uri = "%s/ws?lang=en&status=%s&token=%s" % [_base_uri, str(p_appear_online).to_lower(), p_session.token]
logger.debug("Connecting to host: %s" % uri)
_conn = AsyncConnection.new()
_adapter.connect_to_host(uri, p_connect_timeout)
return await _conn.completed
# Join the matchmaker pool and search for opponents on the server.
# @param p_query - The matchmaker query to search for opponents.
# @param p_min_count - The minimum number of players to compete against in a match.
# @param p_max_count - The maximum number of players to compete against in a match.
# @param p_string_properties - A set of key/value properties to provide to searches.
# @param p_numeric_properties - A set of key/value numeric properties to provide to searches.
# @param p_count_multiple - Optional multiple of the count that must be satisfied.
# Returns a task which resolves to a matchmaker ticket object.
func add_matchmaker_async(p_query : String = "*", p_min_count : int = 2, p_max_count : int = 8,
p_string_props : Dictionary = {}, p_numeric_props : Dictionary = {},
p_count_multiple : int = 0) -> NakamaRTAPI.MatchmakerTicket:
return await _send_async(
NakamaRTMessage.MatchmakerAdd.new(p_query, p_min_count, p_max_count, p_string_props, p_numeric_props, p_count_multiple),
NakamaRTAPI.MatchmakerTicket
).completed
# Create a multiplayer match on the server.
# @param p_name - Optional name to use when creating the match.
# Returns a task to represent the asynchronous operation.
func create_match_async(p_name : String = ''):
return await _send_async(NakamaRTMessage.MatchCreate.new(p_name), NakamaRTAPI.Match).completed
# Subscribe to one or more users for their status updates.
# @param p_user_ids - The IDs of users.
# @param p_usernames - The usernames of the users.
# Returns a task which resolves to the current statuses for the users.
func follow_users_async(p_ids : PackedStringArray, p_usernames : PackedStringArray) -> NakamaRTAPI.Status:
return await _send_async(NakamaRTMessage.StatusFollow.new(p_ids, p_usernames), NakamaRTAPI.Status).completed
# Join a chat channel on the server.
# @param p_target - The target channel to join.
# @param p_type - The type of channel to join.
# @param p_persistence - If chat messages should be stored.
# @param p_hidden - If the current user should be hidden on the channel.
# Returns a task which resolves to a chat channel object.
func join_chat_async(p_target : String, p_type : int, p_persistence : bool = false, p_hidden : bool = false) -> NakamaRTAPI.Channel:
return await _send_async(
NakamaRTMessage.ChannelJoin.new(p_target, p_type, p_persistence, p_hidden),
NakamaRTAPI.Channel
).completed
# Join a multiplayer match with the matchmaker matched object.
# @param p_matched - A matchmaker matched object.
# Returns a task which resolves to a multiplayer match.
func join_matched_async(p_matched):
var msg := NakamaRTMessage.MatchJoin.new()
if p_matched.match_id:
msg.match_id = p_matched.match_id
else:
msg.token = p_matched.token
return await _send_async(msg, NakamaRTAPI.Match).completed
# Join a multiplayer match by ID.
# @param p_match_id - The ID of the match to attempt to join.
# @param p_metadata - An optional set of key-value metadata pairs to be passed to the match handler.
# Returns a task which resolves to a multiplayer match.
func join_match_async(p_match_id : String, p_metadata = null):
var msg := NakamaRTMessage.MatchJoin.new()
msg.match_id = p_match_id
msg.metadata = p_metadata
return await _send_async(msg, NakamaRTAPI.Match).completed
# Leave a chat channel on the server.
## @param p_channel_id - The ID of the chat channel to leave.
# Returns a task which represents the asynchronous operation.
func leave_chat_async(p_channel_id : String) -> NakamaAsyncResult:
return await _send_async(NakamaRTMessage.ChannelLeave.new(p_channel_id)).completed
# Leave a multiplayer match on the server.
# @param p_match_id - The multiplayer match to leave.
# Returns a task which represents the asynchronous operation.
func leave_match_async(p_match_id : String) -> NakamaAsyncResult:
return await _send_async(NakamaRTMessage.MatchLeave.new(p_match_id)).completed
# Remove a chat message from a chat channel on the server.
# @param p_channel - The chat channel with the message to remove.
# @param p_message_id - The ID of the chat message to remove.
# Returns a task which resolves to an acknowledgement of the removed message.
func remove_chat_message_async(p_channel_id : String, p_message_id : String):
return await _send_async(
NakamaRTMessage.ChannelMessageRemove.new(p_channel_id, p_message_id),
NakamaRTAPI.ChannelMessageAck
).completed
# Leave the matchmaker pool with the ticket.
# @param p_ticket - The ticket returned by the matchmaker on join.
# Returns a task which represents the asynchronous operation.
func remove_matchmaker_async(p_ticket : String) -> NakamaAsyncResult:
return await _send_async(NakamaRTMessage.MatchmakerRemove.new(p_ticket)).completed
# Execute an RPC function to the server.
# @param p_func_id - The ID of the function to execute.
# @param p_payload - An (optional) String payload to send to the server.
# Returns a task which resolves to the RPC function response object.
func rpc_async(p_func_id : String, p_payload = null) -> NakamaAPI.ApiRpc:
var payload = p_payload
match typeof(p_payload):
TYPE_NIL, TYPE_STRING:
pass
_:
payload = JSON.stringify(p_payload)
return await _send_async(NakamaAPI.ApiRpc.create(NakamaAPI, {
"id": p_func_id,
"payload": payload
}), NakamaAPI.ApiRpc, NakamaAPI, "rpc", "rpc").completed
# Send input to a multiplayer match on the server.
# When no presences are supplied the new match state will be sent to all presences.
# @param p_match_id - The ID of the match.
# @param p_op_code - An operation code for the input.
# @param p_data - The input data to send.
# @param p_presences - The presences in the match who should receive the input.
# Returns a task which represents the asynchronous operation.
func send_match_state_async(p_match_id, p_op_code : int, p_data : String, p_presences = null):
var req = _send_async(NakamaRTMessage.MatchDataSend.new(
p_match_id,
p_op_code,
Marshalls.utf8_to_base64(p_data),
p_presences
))
# This do not return a response from server, you don't really need to wait for it.
req.call_deferred("resume", {})
return req.completed
# Send input to a multiplayer match on the server.
# When no presences are supplied the new match state will be sent to all presences.
# @param p_match_id - The ID of the match.
# @param p_op_code - An operation code for the input.
# @param p_data - The input data to send.
# @param p_presences - The presences in the match who should receive the input.
# Returns a task which represents the asynchronous operation.
func send_match_state_raw_async(p_match_id, p_op_code : int, p_data : PackedByteArray, p_presences = null):
var req = _send_async(NakamaRTMessage.MatchDataSend.new(
p_match_id,
p_op_code,
Marshalls.raw_to_base64(p_data),
p_presences
))
# This do not return a response from server, you don't really need to wait for it.
req.call_deferred("resume", {})
return req.completed
# Unfollow one or more users from their status updates.
# @param p_user_ids - An array of user ids to unfollow.
# Returns a task which represents the asynchronous operation.
func unfollow_users_async(p_ids : PackedStringArray):
return await _send_async(NakamaRTMessage.StatusUnfollow.new(p_ids)).completed
# Update a chat message on a chat channel in the server.
# @param p_channel_id - The ID of the chat channel with the message to update.
# @param p_message_id - The ID of the message to update.
# @param p_content - The new contents of the chat message.
# Returns a task which resolves to an acknowledgement of the updated message.
func update_chat_message_async(p_channel_id : String, p_message_id : String, p_content : Dictionary):
return await _send_async(
NakamaRTMessage.ChannelMessageUpdate.new(p_channel_id, p_message_id, JSON.stringify(p_content)),
NakamaRTAPI.ChannelMessageAck
).completed
# Update the status for the current user online.
# @param p_status - The new status for the user.
# Returns a task which represents the asynchronous operation.
func update_status_async(p_status : String):
return await _send_async(NakamaRTMessage.StatusUpdate.new(p_status)).completed
# Send a chat message to a chat channel on the server.
# @param p_channel_id - The ID of the chat channel to send onto.
# @param p_content - The contents of the message to send.
# Returns a task which resolves to the acknowledgement of the chat message write.
func write_chat_message_async(p_channel_id : String, p_content : Dictionary):
return await _send_async(
NakamaRTMessage.ChannelMessageSend.new(p_channel_id, JSON.stringify(p_content)),
NakamaRTAPI.ChannelMessageAck
).completed
# Accept a party member's request to join the party.
# @param p_party_id - The party ID to accept the join request for.
# @param p_presence - The presence to accept as a party member.
# Returns a task to represent the asynchronous operation.
func accept_party_member_async(p_party_id : String, p_presence : NakamaRTAPI.UserPresence):
return await _send_async(NakamaRTMessage.PartyAccept.new(p_party_id, p_presence)).completed
# Begin matchmaking as a party.
# @param p_party_id - Party ID.
# @param p_query - Filter query used to identify suitable users.
# @param p_min_count - Minimum total user count to match together.
# @param p_max_count - Maximum total user count to match together.
# @param p_string_properties - String properties.
# @param p_numeric_properties - Numeric properties.
# @param p_count_multiple - Optional multiple of the count that must be satisfied.
# Returns a task to represent the asynchronous operation.
func add_matchmaker_party_async(p_party_id : String, p_query : String = "*", p_min_count : int = 2,
p_max_count : int = 8, p_string_properties = {}, p_numeric_properties = {}, p_count_multiple : int = 0):
return await _send_async(
NakamaRTMessage.PartyMatchmakerAdd.new(p_party_id, p_min_count,
p_max_count, p_query, p_string_properties, p_numeric_properties,
p_count_multiple if p_count_multiple > 0 else null),
NakamaRTAPI.PartyMatchmakerTicket).completed
# End a party, kicking all party members and closing it.
# @param p_party_id - The ID of the party.
# Returns a task to represent the asynchronous operation.
func close_party_async(p_party_id : String):
var msg := NakamaRTAPI.PartyClose.new()
msg.party_id = p_party_id
return await _send_async(msg).completed
# Create a party.
# @param p_open - Whether or not the party will require join requests to be approved by the party leader.
# @param p_max_size - Maximum number of party members. This maximum does not include the party leader.
# Returns a task to represent the asynchronous operation.
func create_party_async(p_open : bool, p_max_size : int) -> NakamaRTAPI.Party:
return await _send_async(
NakamaRTMessage.PartyCreate.new(p_open, p_max_size),
NakamaRTAPI.Party
).completed
# Join a party.
# @param p_party_id - Party ID.
# Returns a task to represent the asynchronous operation.
func join_party_async(p_party_id : String):
return await _send_async(NakamaRTMessage.PartyJoin.new(p_party_id)).completed
# Leave the party.
# @param p_party_id - Party ID.
# Returns a task to represent the asynchronous operation.
func leave_party_async(p_party_id : String):
return await _send_async(NakamaRTMessage.PartyLeave.new(p_party_id)).completed
# Request a list of pending join requests for a party.
# @param p_party_id - Party ID.
# Returns a task which resolves to a list of all party join requests.
func list_party_join_requests_async(p_party_id : String) -> NakamaRTAPI.PartyJoinRequest:
return await _send_async(
NakamaRTMessage.PartyJoinRequestList.new(p_party_id),
NakamaRTAPI.PartyJoinRequest).completed
# Promote a new party leader.
# @param p_party_id - Party ID.
# @param p_party_member - The presence of an existing party member to promote as the new leader.
# Returns a which represents the asynchronous operation.
func promote_party_member(p_party_id : String, p_party_member : NakamaRTAPI.UserPresence):
return await _send_async(NakamaRTMessage.PartyPromote.new(p_party_id, p_party_member)).completed
# Cancel a party matchmaking process using a ticket.
# @param p_party_id - Party ID.
# @param p_ticket - The ticket to cancel.
# Returns a task which represents the asynchronous operation.
func remove_matchmaker_party_async(p_party_id : String, p_ticket : String):
return await _send_async(NakamaRTMessage.PartyMatchmakerRemove.new(p_party_id, p_ticket)).completed
# Kick a party member, or decline a request to join.
# @param p_party_id - Party ID to remove/reject from.
# @param p_presence - The presence to remove or reject.
# Returns a task which represents the asynchronous operation.
func remove_party_member_async(p_party_id : String, p_presence : NakamaRTAPI.UserPresence):
return await _send_async(NakamaRTMessage.PartyRemove.new(p_party_id, p_presence)).completed
# Send data to a party.
# @param p_party_id - Party ID to send to.
# @param p_op_code - Op code value.
# @param data - Data payload, if any.
# Returns a task which represents the asynchronous operation.
func send_party_data_async(p_party_id : String, p_op_code : int, p_data:String = ""):
var base64_data = null if p_data.is_empty() else Marshalls.utf8_to_base64(p_data)
return await _send_async(NakamaRTMessage.PartyDataSend.new(p_party_id, p_op_code, base64_data)).completed
# Send data to a party.
# @param p_party_id - Party ID to send to.
# @param p_op_code - Op code value.
# @param data - Data payload, if any.
# Returns a task which represents the asynchronous operation.
func send_party_data_raw_async(p_party_id : String, p_op_code : int, p_data:PackedByteArray):
var base64_data = null if p_data.is_empty() else Marshalls.raw_to_base64(p_data)
return await _send_async(NakamaRTMessage.PartyDataSend.new(p_party_id, p_op_code, base64_data)).completed
@@ -0,0 +1 @@
uid://wfhv0nbv2yfr
@@ -0,0 +1,75 @@
@tool
extends Node
# An adapter which implements a socket with a protocol supported by Nakama.
class_name NakamaSocketAdapter
var _ws := WebSocketPeer.new()
var _ws_last_state := WebSocketPeer.STATE_CLOSED
var _timeout : int = 30
var _start : int = 0
var logger = NakamaLogger.new()
# A signal emitted when the socket is connected.
signal connected()
# A signal emitted when the socket is disconnected.
signal closed()
# A signal emitted when the socket has an error when connecting.
signal received_error(p_exception)
# A signal emitted when the socket receives a message.
signal received(p_bytes) # PackedByteArray
# If the socket is connected.
func is_connected_to_host():
return _ws.get_ready_state() == WebSocketPeer.STATE_OPEN
# If the socket is connecting.
func is_connecting_to_host():
return _ws.get_ready_state() == WebSocketPeer.STATE_CONNECTING
# Close the socket with an asynchronous operation.
func close():
_ws.close()
# Connect to the server with an asynchronous operation.
# @param p_uri - The URI of the server.
# @param p_timeout - The timeout for the connect attempt on the socket.
func connect_to_host(p_uri : String, p_timeout : int):
_timeout = p_timeout
_start = Time.get_unix_time_from_system()
var err = _ws.connect_to_url(p_uri)
if err != OK:
logger.debug("Error connecting to host %s" % p_uri)
call_deferred("emit_signal", "received_error", err)
return
_ws_last_state = WebSocketPeer.STATE_CLOSED
# Send data to the server with an asynchronous operation.
# @param p_buffer - The buffer with the message to send.
# @param p_reliable - If the message should be sent reliably (will be ignored by some protocols).
func send(p_buffer : PackedByteArray, p_reliable : bool = true) -> int:
return _ws.send(p_buffer, WebSocketPeer.WRITE_MODE_TEXT)
func _process(delta):
if _ws.get_ready_state() != WebSocketPeer.STATE_CLOSED:
_ws.poll()
var state = _ws.get_ready_state()
if _ws_last_state != state:
_ws_last_state = state
if state == WebSocketPeer.STATE_OPEN:
connected.emit()
elif state == WebSocketPeer.STATE_CLOSED:
closed.emit()
if state == WebSocketPeer.STATE_CONNECTING:
if _start + _timeout < Time.get_unix_time_from_system():
logger.debug("Timeout when connecting to socket")
received_error.emit(ERR_TIMEOUT)
_ws.close()
while _ws.get_ready_state() == WebSocketPeer.STATE_OPEN and _ws.get_available_packet_count():
received.emit(_ws.get_packet())
@@ -0,0 +1 @@
uid://dsdhcwo4q22gf
@@ -0,0 +1,34 @@
extends RefCounted
class_name NakamaAsyncResult
var exception : NakamaException:
set(v):
pass
get:
return get_exception()
var _ex = null
func _init(p_ex = null):
_ex = p_ex
func is_exception():
return get_exception() != null
func was_cancelled():
return is_exception() and get_exception().cancelled
func get_exception() -> NakamaException:
return _ex as NakamaException
func _to_string():
if is_exception():
return get_exception()._to_string()
return "NakamaAsyncResult<>"
static func _safe_ret(p_obj, p_type : GDScript):
if is_instance_of(p_obj, p_type):
return p_obj # Correct type
elif p_obj is NakamaException:
return p_type.new(p_obj) # It's an exception. Incapsulate it
return p_type.new(NakamaException.new()) # It's something else. generate an exception
@@ -0,0 +1 @@
uid://ckpfmnm3crkgo
@@ -0,0 +1,42 @@
extends RefCounted
# An exception generated during a request.
# Usually contains at least an error message.
class_name NakamaException
var _status_code : int = -1
var status_code : int:
set(v):
pass
get:
return _status_code
var _grpc_status_code : int = -1
var grpc_status_code : int:
set(v):
pass
get:
return _grpc_status_code
var _message : String = ""
var message : String:
set(v):
pass
get:
return _message
var _cancelled : bool = false
var cancelled : bool:
set(v):
pass
get:
return _cancelled
func _init(p_message : String = "", p_status_code : int = -1, p_grpc_status_code : int = -1, p_cancelled : bool = false):
_status_code = p_status_code
_grpc_status_code = p_grpc_status_code
_message = p_message
_cancelled = p_cancelled
func _to_string() -> String:
return "NakamaException(StatusCode={%s}, Message='{%s}', GrpcStatusCode={%s})" % [_status_code, _message, _grpc_status_code]
@@ -0,0 +1 @@
uid://dl5bqgn61sifg
@@ -0,0 +1,38 @@
extends RefCounted
class_name NakamaLogger
enum LOG_LEVEL {NONE, ERROR, WARNING, INFO, VERBOSE, DEBUG}
var _level = LOG_LEVEL.ERROR
var _module = "Nakama"
func _init(p_module : String = "Nakama", p_level : int = LOG_LEVEL.ERROR):
_level = p_level
_module = p_module
func _log(level : int, msg):
if level <= _level:
if level == LOG_LEVEL.ERROR:
printerr("=== %s : ERROR === %s" % [_module, str(msg)])
else:
var what = "=== UNKNOWN === "
for k in LOG_LEVEL:
if level == LOG_LEVEL[k]:
what = "=== %s : %s === " % [_module, k]
break
print(what + str(msg))
func error(msg):
_log(LOG_LEVEL.ERROR, msg)
func warning(msg):
_log(LOG_LEVEL.WARNING, msg)
func info(msg):
_log(LOG_LEVEL.INFO, msg)
func verbose(msg):
_log(LOG_LEVEL.VERBOSE, msg)
func debug(msg):
_log(LOG_LEVEL.DEBUG, msg)
@@ -0,0 +1 @@
uid://bpe0ljoah7ssn
@@ -0,0 +1,363 @@
extends RefCounted
class_name NakamaMultiplayerBridge
enum MatchState {
DISCONNECTED,
JOINING,
CONNECTED,
SOCKET_CLOSED,
}
enum MetaMessageType {
CLAIM_HOST,
ASSIGN_PEER_ID,
}
# Read-only variables.
var _nakama_socket: NakamaSocket
var nakama_socket: NakamaSocket:
get: return _nakama_socket
set(_v): pass
var _match_state: int = MatchState.DISCONNECTED
var match_state: int:
get: return _match_state
set(_v): pass
var _match_id := ''
var match_id: String:
get: return _match_id
set(_v): pass
var _multiplayer_peer: NakamaMultiplayerPeer = NakamaMultiplayerPeer.new()
var multiplayer_peer: NakamaMultiplayerPeer:
get: return _multiplayer_peer
set(_v): pass
# Configuration that can be set by the developer.
var meta_op_code: int = 9001
var rpc_op_code: int = 9002
# Internal variables.
var _my_session_id: String
var _my_peer_id: int = 0
var _id_map := {}
var _users := {}
var _matchmaker_ticket := ''
class User extends RefCounted:
var presence
var peer_id: int = 0
func _init(p_presence) -> void:
presence = p_presence
signal match_join_error (exception)
signal match_joined ()
func _set_readonly(_value) -> void:
pass
func _init(p_nakama_socket: NakamaSocket) -> void:
_nakama_socket = p_nakama_socket
_nakama_socket.received_match_presence.connect(self._on_nakama_socket_received_match_presence)
_nakama_socket.received_matchmaker_matched.connect(self._on_nakama_socket_received_matchmaker_matched)
_nakama_socket.received_match_state.connect(self._on_nakama_socket_received_match_state)
_nakama_socket.closed.connect(self._on_nakama_socket_closed)
_multiplayer_peer.packet_generated.connect(self._on_multiplayer_peer_packet_generated)
_multiplayer_peer.set_connection_status(MultiplayerPeer.CONNECTION_CONNECTING)
func create_match() -> void:
if _match_state != MatchState.DISCONNECTED:
push_error("Cannot create match when state is %s" % MatchState.keys()[_match_state])
return
_match_state = MatchState.JOINING
multiplayer_peer.set_connection_status(MultiplayerPeer.CONNECTION_CONNECTING)
var res = await _nakama_socket.create_match_async()
if res.is_exception():
match_join_error.emit(res.get_exception())
leave()
return
_setup_match(res)
_setup_host()
func join_match(p_match_id: String) -> void:
if _match_state != MatchState.DISCONNECTED:
push_error("Cannot join match when state is %s" % MatchState.keys()[_match_state])
return
_match_state = MatchState.JOINING
multiplayer_peer.set_connection_status(MultiplayerPeer.CONNECTION_CONNECTING)
var res = await _nakama_socket.join_match_async(p_match_id)
if res.is_exception():
match_join_error.emit(res.get_exception())
leave()
return
_setup_match(res)
func join_named_match(_match_name: String) -> void:
if _match_state != MatchState.DISCONNECTED:
push_error("Cannot join match when state is %s" % MatchState.keys()[_match_state])
return
_match_state = MatchState.JOINING
multiplayer_peer.set_connection_status(MultiplayerPeer.CONNECTION_CONNECTING)
var res = await _nakama_socket.create_match_async(_match_name)
if res.is_exception():
match_join_error.emit(res.get_exception())
leave()
return
_setup_match(res)
if res.size == 0 or (res.size == 1 and res.presences.size() == 0):
_setup_host()
func start_matchmaking(ticket) -> void:
if _match_state != MatchState.DISCONNECTED:
push_error("Cannot start matchmaking when state is %s" % MatchState.keys()[_match_state])
return
if ticket.is_exception():
push_error("Ticket with exception passed into start_matchmaking()")
return
_match_state = MatchState.JOINING
multiplayer_peer.set_connection_status(MultiplayerPeer.CONNECTION_CONNECTING)
_matchmaker_ticket = ticket.ticket
func _on_nakama_socket_received_matchmaker_matched(matchmaker_matched) -> void:
if _matchmaker_ticket != matchmaker_matched.ticket:
return
# Get a list of sorted session ids.
var session_ids := []
for matchmaker_user in matchmaker_matched.users:
session_ids.append(matchmaker_user.presence.session_id)
session_ids.sort()
var res = await _nakama_socket.join_matched_async(matchmaker_matched)
if res.is_exception():
match_join_error.emit(res.get_exception())
leave()
return
_setup_match(res)
# If our session is the first alphabetically, then we'll be the host.
if _my_session_id == session_ids[0]:
_setup_host()
# Add all of the existing peers.
for presence in res.presences:
if presence.session_id != _my_session_id:
_host_add_peer(presence)
func _on_nakama_socket_closed() -> void:
match_state = MatchState.SOCKET_CLOSED
_cleanup()
func get_user_presence_for_peer(peer_id: int) -> NakamaRTAPI.UserPresence:
var session_id = _id_map.get(peer_id)
if session_id == null:
return null
var user = _users.get(session_id)
if user == null:
return null
return user.presence
func leave() -> void:
if _match_state == MatchState.DISCONNECTED:
return
_match_state = MatchState.DISCONNECTED
if _match_id:
await _nakama_socket.leave_match_async(_match_id)
if _matchmaker_ticket:
await _nakama_socket.remove_matchmaker_async(_matchmaker_ticket)
_cleanup()
func _cleanup() -> void:
for peer_id in _id_map:
multiplayer_peer.peer_disconnected.emit(peer_id)
_match_id = ''
_matchmaker_ticket = ''
_my_session_id = ''
_my_peer_id = 0
_id_map.clear()
_users.clear()
_multiplayer_peer.set_connection_status(MultiplayerPeer.CONNECTION_DISCONNECTED)
func _setup_match(res) -> void:
_match_id = res.match_id
_my_session_id = res.self_user.session_id
_users[_my_session_id] = User.new(res.self_user)
for presence in res.presences:
if not _users.has(presence.session_id):
_users[presence.session_id] = User.new(presence)
func _setup_host() -> void:
# Claim id 1 and start the match.
_my_peer_id = 1
_map_id_to_session(1, _my_session_id)
_match_state = MatchState.CONNECTED
_multiplayer_peer.initialize(_my_peer_id)
match_joined.emit()
func _generate_id(session_id: String) -> int:
# Peer ids can only be positive 32-bit signed integers.
var peer_id: int = session_id.hash() & 0x7FFFFFFF
# If this peer id is already taken, try to find another.
while peer_id <= 1 or _id_map.has(peer_id):
peer_id += 1
if peer_id > 0x7FFFFFFF or peer_id <= 0:
peer_id = randi() & 0x7FFFFFFF
return peer_id
func _map_id_to_session(peer_id: int, session_id: String) -> void:
_id_map[peer_id] = session_id
_users[session_id].peer_id = peer_id
func _host_add_peer(presence) -> void:
var peer_id = _generate_id(presence.session_id)
_map_id_to_session(peer_id, presence.session_id)
# Tell them we are the host.
_nakama_socket.send_match_state_async(_match_id, meta_op_code, JSON.stringify({
type = MetaMessageType.CLAIM_HOST,
}), [presence])
# Tell them about all the other connected peers.
for other_peer_id in _id_map:
var other_session_id = _id_map[other_peer_id]
if other_session_id == presence.session_id or other_session_id == _my_session_id:
continue
_nakama_socket.send_match_state_async(_match_id, meta_op_code, JSON.stringify({
type = MetaMessageType.ASSIGN_PEER_ID,
session_id = other_session_id,
peer_id = other_peer_id,
}), [presence])
# Assign them a peer_id (tell everyone about it).
_nakama_socket.send_match_state_async(_match_id, meta_op_code, JSON.stringify({
type = MetaMessageType.ASSIGN_PEER_ID,
session_id = presence.session_id,
peer_id = peer_id,
}))
_multiplayer_peer.peer_connected.emit(peer_id)
func _on_nakama_socket_received_match_presence(event) -> void:
if _match_state == MatchState.DISCONNECTED:
return
if event.match_id != _match_id:
return
for presence in event.joins:
if not _users.has(presence.session_id):
_users[presence.session_id] = User.new(presence)
# If we are the host, and they don't yet have a peer id, then let's
# generate a new id for them and send all the necessary messages.
if _my_peer_id == 1 and _users[presence.session_id].peer_id == 0:
_host_add_peer(presence)
for presence in event.leaves:
if not _users.has(presence.session_id):
continue
var peer_id = _users[presence.session_id].peer_id
_multiplayer_peer.peer_disconnected.emit(peer_id)
_users.erase(presence.session_id)
_id_map.erase(peer_id)
func _parse_json(data: String):
var json = JSON.new()
if json.parse(data) != OK:
return null
var content = json.get_data()
if not content is Dictionary:
return null
return content
func _on_nakama_socket_received_match_state(data) -> void:
if _match_state == MatchState.DISCONNECTED:
return
if data.match_id != _match_id:
return
if data.op_code == meta_op_code:
var content = _parse_json(data.data)
if content == null:
return
var type = content['type']
#print ("RECEIVED: ", content)
if type == MetaMessageType.CLAIM_HOST:
if _id_map.has(1):
# @todo Can we mediate this dispute?
push_error("User %s claiming to be host, when user %s has already claimed it" % [data.presence.session_id, _id_map[1]])
else:
_map_id_to_session(1, data.presence.session_id)
return
# Ensure that any meta messages are coming from the host!
if data.presence.session_id != _id_map[1]:
push_error("Received meta message from user %s who isn't the host: %s" % [data.presence.session_id, content])
return
if type == MetaMessageType.ASSIGN_PEER_ID:
var session_id = content['session_id']
var peer_id = content['peer_id']
if _users.has(session_id) and _users[session_id].peer_id != 0:
push_error("Attempting to assign peer id %s to %s which already has id %s" % [
peer_id,
session_id,
_users[session_id].peer_id,
])
return
_map_id_to_session(peer_id, session_id)
if _my_session_id == session_id:
_match_state = MatchState.CONNECTED
_multiplayer_peer.initialize(peer_id)
_multiplayer_peer.set_connection_status(MultiplayerPeer.CONNECTION_CONNECTED)
match_joined.emit()
_multiplayer_peer.peer_connected.emit(1)
else:
_multiplayer_peer.peer_connected.emit(peer_id)
else:
_nakama_socket.logger.error("Received meta message with unknown type: %s" % type)
elif data.op_code == rpc_op_code:
var from_session_id: String = data.presence.session_id
if not _users.has(from_session_id) or _users[from_session_id].peer_id == 0:
push_error("Received RPC from %s which isn't assigned a peer id" % data.presence.session_id)
return
var from_peer_id = _users[from_session_id].peer_id
_multiplayer_peer.deliver_packet(data.binary_data, from_peer_id)
func _on_multiplayer_peer_packet_generated(peer_id: int, buffer: PackedByteArray) -> void:
if match_state == MatchState.CONNECTED:
var target_presences = null
if peer_id > 0:
if not _id_map.has(peer_id):
push_error("Attempting to send RPC to unknown peer id: %s" % peer_id)
return
target_presences = [ _users[_id_map[peer_id]].presence ]
_nakama_socket.send_match_state_raw_async(_match_id, rpc_op_code, buffer, target_presences)
else:
push_error("RPC sent while the NakamaMultiplayerBridge isn't connected!")
@@ -0,0 +1 @@
uid://ntxj8ansnmt
@@ -0,0 +1,97 @@
extends MultiplayerPeerExtension
class_name NakamaMultiplayerPeer
const MAX_PACKET_SIZE := 1 << 24
var _self_id := 0
var _connection_status: ConnectionStatus = CONNECTION_DISCONNECTED
var _refusing_new_connections := false
var _target_id := 0
class Packet extends RefCounted:
var data: PackedByteArray
var from: int
func _init(p_data: PackedByteArray, p_from: int) -> void:
data = p_data
from = p_from
var _incoming_packets := []
signal packet_generated (peer_id, buffer)
func _get_packet_script() -> PackedByteArray:
if _incoming_packets.size() == 0:
return PackedByteArray()
return _incoming_packets.pop_front().data
func _get_packet_mode() -> TransferMode:
return TRANSFER_MODE_RELIABLE
func _get_packet_channel() -> int:
return 0
func _put_packet_script(p_buffer: PackedByteArray) -> Error:
packet_generated.emit(_target_id, p_buffer)
return OK
func _get_available_packet_count() -> int:
return _incoming_packets.size()
func _get_max_packet_size() -> int:
return MAX_PACKET_SIZE
func _set_transfer_channel(p_channel) -> void:
pass
func _get_transfer_channel() -> int:
return 0
func _set_transfer_mode(p_mode: TransferMode) -> void:
pass
func _get_transfer_mode() -> TransferMode:
return TRANSFER_MODE_RELIABLE
func _set_target_peer(p_peer_id: int) -> void:
_target_id = p_peer_id
func _get_packet_peer() -> int:
if _connection_status != CONNECTION_CONNECTED:
return 1
if _incoming_packets.size() == 0:
return 1
return _incoming_packets[0].from
func _is_server() -> bool:
return _self_id == 1
func _poll() -> void:
pass
func _get_unique_id() -> int:
return _self_id
func _set_refuse_new_connections(p_enable: bool) -> void:
_refusing_new_connections = p_enable
func _is_refusing_new_connections() -> bool:
return _refusing_new_connections
func _get_connection_status() -> ConnectionStatus:
return _connection_status
func initialize(p_self_id: int) -> void:
if _connection_status != CONNECTION_CONNECTING:
return
_self_id = p_self_id
if _self_id == 1:
_connection_status = CONNECTION_CONNECTED
func set_connection_status(p_connection_status: int) -> void:
_connection_status = p_connection_status
func deliver_packet(p_data: PackedByteArray, p_from_peer_id: int) -> void:
var packet = Packet.new(p_data, p_from_peer_id);
_incoming_packets.push_back(packet)
@@ -0,0 +1 @@
uid://bqi4fibji5beq
@@ -0,0 +1,160 @@
extends RefCounted
class_name NakamaSerializer
static func serialize(p_obj : Object) -> Dictionary:
var out = {}
var schema = p_obj.get("_SCHEMA")
if schema == null:
return {} # No schema defined
for k in schema:
var prop = schema[k]
var val = p_obj.get(prop["name"])
if val == null:
continue
var type = prop["type"]
var content = prop.get("content", TYPE_NIL)
if typeof(content) == TYPE_STRING:
content = TYPE_OBJECT
var val_type = typeof(val)
match val_type:
TYPE_OBJECT: # Simple objects
out[k] = serialize(val)
TYPE_ARRAY: # Array of objects
var arr = []
for e in val:
if typeof(e) != TYPE_OBJECT:
continue
arr.append(serialize(e))
out[k] = arr
TYPE_PACKED_INT32_ARRAY, TYPE_PACKED_STRING_ARRAY: # Array of ints, bools, or strings
var arr = []
for e in val:
if content == TYPE_BOOL:
e = bool(e)
if typeof(e) != content:
continue
arr.append(e)
out[k] = arr
TYPE_DICTIONARY: # Maps
var dict = {}
if content == TYPE_OBJECT: # Map of objects
for l in val:
if typeof(val[l]) != TYPE_OBJECT:
continue
dict[l] = serialize(val[l])
else: # Map of simple types
for l in val:
var e = val[l]
if content == TYPE_FLOAT:
e = float(e)
elif content == TYPE_INT:
e = int(e)
elif content == TYPE_BOOL:
e = bool(e)
if typeof(e) != content:
continue
dict[l] = e
out[k] = dict
_:
out[k] = val
return out
static func deserialize(p_ns : GDScript, p_cls_name : String, p_dict : Dictionary) -> Object:
var cls : GDScript = p_ns.get(p_cls_name)
var schema = cls.get("_SCHEMA")
if schema == null:
return NakamaException.new() # No schema defined
var obj = cls.new()
for k in schema:
var prop = schema[k]
var pname = prop["name"]
var type = prop["type"]
var required = prop["required"]
var content = prop.get("content", TYPE_NIL)
var type_cmp = type
if typeof(type) == TYPE_STRING: # A class
type_cmp = TYPE_DICTIONARY
if type_cmp == TYPE_PACKED_STRING_ARRAY or type_cmp == TYPE_PACKED_INT32_ARRAY: # A specialized array
type_cmp = TYPE_ARRAY
var content_cmp = content
if typeof(content) == TYPE_STRING: # A dictionary or array of classes
content_cmp = TYPE_DICTIONARY
var val = p_dict.get(k, null)
# Ints might and up being recognized as floats. Change that if needed
if type_cmp == TYPE_INT:
if typeof(val) == TYPE_FLOAT:
val = int(val)
elif typeof(val) == TYPE_STRING and val.is_valid_int():
val = val.to_int()
if typeof(val) == type_cmp:
if typeof(type) == TYPE_STRING:
obj.set(pname, deserialize(p_ns, type, val))
elif type_cmp == TYPE_DICTIONARY:
var v = {}
for l in val:
if typeof(content) == TYPE_STRING:
v[l] = deserialize(p_ns, content, val[l])
elif content == TYPE_FLOAT:
v[l] = float(val[l])
elif content == TYPE_INT:
v[l] = int(val[l])
elif content == TYPE_BOOL:
v[l] = bool(val[l])
else:
v[l] = str(val[l])
obj.set(pname, v)
elif type_cmp == TYPE_ARRAY:
var v
match content:
TYPE_INT, TYPE_BOOL: v = PackedInt32Array()
TYPE_STRING: v = PackedStringArray()
_: v = Array()
for e in val:
if typeof(content) == TYPE_STRING:
v.append(deserialize(p_ns, content, e))
elif content == TYPE_FLOAT:
v.append(float(e))
elif content == TYPE_INT:
v.append(int(e))
elif content == TYPE_BOOL:
v.append(bool(e))
else:
v.append(str(e))
obj.set(pname, v)
else:
obj.set(pname, val)
elif required:
obj._ex = NakamaException.new("ERROR [%s]: Missing or invalid required prop %s = %s:\n\t%s" % [p_cls_name, prop, p_dict.get(k), p_dict])
return obj
return obj
###
# Compatibility with Godot 3.1 which does not expose String.http_escape
###
const HEX = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"]
static func escape_http(p_str : String) -> String:
var out : String = ""
for o in p_str:
if (o == '.' or o == '-' or o == '_' or o == '~' or
(o >= 'a' and o <= 'z') or
(o >= 'A' and o <= 'Z') or
(o >= '0' and o <= '9')):
out += o
else:
for b in o.to_utf8_buffer():
out += "%%%s" % to_hex(b)
return out
static func to_hex(p_val : int) -> String:
var v := p_val
var o := ""
while v != 0:
o = HEX[v % 16] + o
v /= 16
return o
@@ -0,0 +1 @@
uid://bllhuxmb0a5ml