diff --git a/addons/com.heroiclabs.nakama/Nakama.gd b/addons/com.heroiclabs.nakama/Nakama.gd new file mode 100644 index 0000000..37781d4 --- /dev/null +++ b/addons/com.heroiclabs.nakama/Nakama.gd @@ -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) diff --git a/addons/com.heroiclabs.nakama/Nakama.gd.uid b/addons/com.heroiclabs.nakama/Nakama.gd.uid new file mode 100644 index 0000000..1e86055 --- /dev/null +++ b/addons/com.heroiclabs.nakama/Nakama.gd.uid @@ -0,0 +1 @@ +uid://bueyqhhvxe0tx diff --git a/addons/com.heroiclabs.nakama/Satori.gd b/addons/com.heroiclabs.nakama/Satori.gd new file mode 100644 index 0000000..423cfb5 --- /dev/null +++ b/addons/com.heroiclabs.nakama/Satori.gd @@ -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) diff --git a/addons/com.heroiclabs.nakama/Satori.gd.uid b/addons/com.heroiclabs.nakama/Satori.gd.uid new file mode 100644 index 0000000..0d344ce --- /dev/null +++ b/addons/com.heroiclabs.nakama/Satori.gd.uid @@ -0,0 +1 @@ +uid://b8vev00s34b7 diff --git a/addons/com.heroiclabs.nakama/Satori/Event.gd b/addons/com.heroiclabs.nakama/Satori/Event.gd new file mode 100644 index 0000000..445013d --- /dev/null +++ b/addons/com.heroiclabs.nakama/Satori/Event.gd @@ -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 \ No newline at end of file diff --git a/addons/com.heroiclabs.nakama/Satori/Event.gd.uid b/addons/com.heroiclabs.nakama/Satori/Event.gd.uid new file mode 100644 index 0000000..ffb8028 --- /dev/null +++ b/addons/com.heroiclabs.nakama/Satori/Event.gd.uid @@ -0,0 +1 @@ +uid://ccldwb3ljqre2 diff --git a/addons/com.heroiclabs.nakama/Satori/SatoriAPI.gd b/addons/com.heroiclabs.nakama/Satori/SatoriAPI.gd new file mode 100644 index 0000000..21aee34 --- /dev/null +++ b/addons/com.heroiclabs.nakama/Satori/SatoriAPI.gd @@ -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() diff --git a/addons/com.heroiclabs.nakama/Satori/SatoriAPI.gd.uid b/addons/com.heroiclabs.nakama/Satori/SatoriAPI.gd.uid new file mode 100644 index 0000000..db97e0f --- /dev/null +++ b/addons/com.heroiclabs.nakama/Satori/SatoriAPI.gd.uid @@ -0,0 +1 @@ +uid://bjc75keigk02r diff --git a/addons/com.heroiclabs.nakama/Satori/SatoriClient.gd b/addons/com.heroiclabs.nakama/Satori/SatoriClient.gd new file mode 100644 index 0000000..f67f8d7 --- /dev/null +++ b/addons/com.heroiclabs.nakama/Satori/SatoriClient.gd @@ -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 diff --git a/addons/com.heroiclabs.nakama/Satori/SatoriClient.gd.uid b/addons/com.heroiclabs.nakama/Satori/SatoriClient.gd.uid new file mode 100644 index 0000000..51f7d75 --- /dev/null +++ b/addons/com.heroiclabs.nakama/Satori/SatoriClient.gd.uid @@ -0,0 +1 @@ +uid://dp2dpam3ffqar diff --git a/addons/com.heroiclabs.nakama/Satori/SatoriHttpAdapter.gd b/addons/com.heroiclabs.nakama/Satori/SatoriHttpAdapter.gd new file mode 100644 index 0000000..9aac03e --- /dev/null +++ b/addons/com.heroiclabs.nakama/Satori/SatoriHttpAdapter.gd @@ -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() diff --git a/addons/com.heroiclabs.nakama/Satori/SatoriHttpAdapter.gd.uid b/addons/com.heroiclabs.nakama/Satori/SatoriHttpAdapter.gd.uid new file mode 100644 index 0000000..508bc0d --- /dev/null +++ b/addons/com.heroiclabs.nakama/Satori/SatoriHttpAdapter.gd.uid @@ -0,0 +1 @@ +uid://b7i4l7xvmg5qe diff --git a/addons/com.heroiclabs.nakama/Satori/SatoriSession.gd b/addons/com.heroiclabs.nakama/Satori/SatoriSession.gd new file mode 100644 index 0000000..09052c4 --- /dev/null +++ b/addons/com.heroiclabs.nakama/Satori/SatoriSession.gd @@ -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" % [ + _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 {} \ No newline at end of file diff --git a/addons/com.heroiclabs.nakama/Satori/SatoriSession.gd.uid b/addons/com.heroiclabs.nakama/Satori/SatoriSession.gd.uid new file mode 100644 index 0000000..4c5dfa6 --- /dev/null +++ b/addons/com.heroiclabs.nakama/Satori/SatoriSession.gd.uid @@ -0,0 +1 @@ +uid://yreiavija6v4 diff --git a/addons/com.heroiclabs.nakama/Satori/utils/SatoriAsyncResult.gd b/addons/com.heroiclabs.nakama/Satori/utils/SatoriAsyncResult.gd new file mode 100644 index 0000000..bf43a90 --- /dev/null +++ b/addons/com.heroiclabs.nakama/Satori/utils/SatoriAsyncResult.gd @@ -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()) diff --git a/addons/com.heroiclabs.nakama/Satori/utils/SatoriAsyncResult.gd.uid b/addons/com.heroiclabs.nakama/Satori/utils/SatoriAsyncResult.gd.uid new file mode 100644 index 0000000..170dddb --- /dev/null +++ b/addons/com.heroiclabs.nakama/Satori/utils/SatoriAsyncResult.gd.uid @@ -0,0 +1 @@ +uid://dhrty7nqady0k diff --git a/addons/com.heroiclabs.nakama/Satori/utils/SatoriException.gd b/addons/com.heroiclabs.nakama/Satori/utils/SatoriException.gd new file mode 100644 index 0000000..ed5452a --- /dev/null +++ b/addons/com.heroiclabs.nakama/Satori/utils/SatoriException.gd @@ -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] diff --git a/addons/com.heroiclabs.nakama/Satori/utils/SatoriException.gd.uid b/addons/com.heroiclabs.nakama/Satori/utils/SatoriException.gd.uid new file mode 100644 index 0000000..3db061b --- /dev/null +++ b/addons/com.heroiclabs.nakama/Satori/utils/SatoriException.gd.uid @@ -0,0 +1 @@ +uid://ds56ldehv1e2i diff --git a/addons/com.heroiclabs.nakama/Satori/utils/SatoriLogger.gd b/addons/com.heroiclabs.nakama/Satori/utils/SatoriLogger.gd new file mode 100644 index 0000000..172ea07 --- /dev/null +++ b/addons/com.heroiclabs.nakama/Satori/utils/SatoriLogger.gd @@ -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) diff --git a/addons/com.heroiclabs.nakama/Satori/utils/SatoriLogger.gd.uid b/addons/com.heroiclabs.nakama/Satori/utils/SatoriLogger.gd.uid new file mode 100644 index 0000000..88ecf14 --- /dev/null +++ b/addons/com.heroiclabs.nakama/Satori/utils/SatoriLogger.gd.uid @@ -0,0 +1 @@ +uid://dk3qpgkfd74x0 diff --git a/addons/com.heroiclabs.nakama/Satori/utils/SatoriSerializer.gd b/addons/com.heroiclabs.nakama/Satori/utils/SatoriSerializer.gd new file mode 100644 index 0000000..fa28fba --- /dev/null +++ b/addons/com.heroiclabs.nakama/Satori/utils/SatoriSerializer.gd @@ -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 diff --git a/addons/com.heroiclabs.nakama/Satori/utils/SatoriSerializer.gd.uid b/addons/com.heroiclabs.nakama/Satori/utils/SatoriSerializer.gd.uid new file mode 100644 index 0000000..60bf590 --- /dev/null +++ b/addons/com.heroiclabs.nakama/Satori/utils/SatoriSerializer.gd.uid @@ -0,0 +1 @@ +uid://dcgodt1wuq4ei diff --git a/addons/com.heroiclabs.nakama/api/NakamaAPI.gd b/addons/com.heroiclabs.nakama/api/NakamaAPI.gd new file mode 100644 index 0000000..fc680bd --- /dev/null +++ b/addons/com.heroiclabs.nakama/api/NakamaAPI.gd @@ -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 diff --git a/addons/com.heroiclabs.nakama/api/NakamaAPI.gd.uid b/addons/com.heroiclabs.nakama/api/NakamaAPI.gd.uid new file mode 100644 index 0000000..a403b94 --- /dev/null +++ b/addons/com.heroiclabs.nakama/api/NakamaAPI.gd.uid @@ -0,0 +1 @@ +uid://duh0d7vmudn4l diff --git a/addons/com.heroiclabs.nakama/api/NakamaRTAPI.gd b/addons/com.heroiclabs.nakama/api/NakamaRTAPI.gd new file mode 100644 index 0000000..05fc5ae --- /dev/null +++ b/addons/com.heroiclabs.nakama/api/NakamaRTAPI.gd @@ -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, 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, 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, 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, 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, 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, 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, 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 "" % [ + 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 "" % 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 "" % [ + 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 "" % [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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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] + + 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" diff --git a/addons/com.heroiclabs.nakama/api/NakamaRTAPI.gd.uid b/addons/com.heroiclabs.nakama/api/NakamaRTAPI.gd.uid new file mode 100644 index 0000000..8dc7fb8 --- /dev/null +++ b/addons/com.heroiclabs.nakama/api/NakamaRTAPI.gd.uid @@ -0,0 +1 @@ +uid://deb6jddlbdxkf diff --git a/addons/com.heroiclabs.nakama/api/NakamaRTMessage.gd b/addons/com.heroiclabs.nakama/api/NakamaRTMessage.gd new file mode 100644 index 0000000..d3bedd6 --- /dev/null +++ b/addons/com.heroiclabs.nakama/api/NakamaRTMessage.gd @@ -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