/// <summary>
        /// Send the reverse metadata from game server to the agent. This should be called when the game wants to update the metadata. Thread-safe.
        /// </summary>
        /// <param name="map">Current map.</param>
        /// <param name="mode">Current mode.</param>
        /// <param name="type">Current type.</param>
        public void SendReverseMetadata(string map,
                                        string mode,
                                        string type)
        {
            int code;

            using (var data = new OneArray())
                using (var mapObject = new OneObject())
                    using (var modeObject = new OneObject())
                        using (var typeObject = new OneObject())
                            using (var map1 = new Utf8ByteArray(map))
                                using (var mode1 = new Utf8ByteArray(mode))
                                    using (var type1 = new Utf8ByteArray(type))
                                    {
                                        mapObject.SetString("key", "map");
                                        mapObject.SetString("value", map1.ToString());
                                        modeObject.SetString("key", "mode");
                                        modeObject.SetString("value", mode1.ToString());
                                        typeObject.SetString("key", "type");
                                        typeObject.SetString("value", type1.ToString());
                                        data.PushObject(mapObject);
                                        data.PushObject(modeObject);
                                        data.PushObject(typeObject);
                                        code = one_server_send_reverse_metadata(_ptr, data.Ptr);
                                    }

            OneErrorValidator.Validate(code);
        }
        /// <summary>
        /// Retrieves the <see cref="int"/> value from the array.
        /// </summary>
        public int GetInt(uint position)
        {
            int value;
            int code = one_array_val_int(_ptr, position, out value);

            OneErrorValidator.Validate(code);

            return(value);
        }
        /// <summary>
        /// Retrieves the <see cref="OneArray"/> value from the array. Should be disposed.
        /// </summary>
        public OneArray GetArray(uint position)
        {
            var array = new OneArray();
            int code  = one_array_val_array(_ptr, position, array.Ptr);

            OneErrorValidator.Validate(code);

            return(array);
        }
        /// <summary>
        /// Retrieves the <see cref="bool"/> value from the array.
        /// </summary>
        public bool GetBool(uint position)
        {
            bool value;
            int  code = one_array_val_bool(_ptr, position, out value);

            OneErrorValidator.Validate(code);

            return(value);
        }
        /// <summary>
        /// Retrieves the <see cref="OneObject"/> value from the array. Should be disposed.
        /// </summary>
        public OneObject GetObject(uint position)
        {
            var obj  = new OneObject();
            int code = one_array_val_object(_ptr, position, obj.Ptr);

            OneErrorValidator.Validate(code);

            return(obj);
        }
        /// <summary>
        /// Checks whether the given key is <see cref="OneObject"/>.
        /// </summary>
        public bool IsObject(uint position)
        {
            bool result;
            int  code = one_array_is_val_object(_ptr, position, out result);

            OneErrorValidator.Validate(code);

            return(result);
        }
        private int GetStringSize(uint position)
        {
            int size;

            int code = one_array_val_string_size(_ptr, position, out size);

            OneErrorValidator.Validate(code);

            return(size);
        }
        /// <summary>
        /// Sets a <see cref="string"/> value into a position of the array.
        /// </summary>
        public void SetString(uint position, string value)
        {
            int code;

            using (var value8 = new Utf8ByteArray(value))
            {
                code = one_array_set_val_string(_ptr, position, value8);
            }

            OneErrorValidator.Validate(code);
        }
        /// <summary>
        /// Sets a <see cref="bool"/> key/value pair on the object.
        /// </summary>
        public void SetBool(string key, bool value)
        {
            int code;

            using (var key8 = new Utf8ByteArray(key))
            {
                code = one_object_set_val_bool(_ptr, key8, value);
            }

            OneErrorValidator.Validate(code);
        }
        /// <summary>
        /// Sets a <see cref="OneObject"/> key/value pair on the object.
        /// </summary>
        public void SetObject(string key, OneObject value)
        {
            int code;

            using (var key8 = new Utf8ByteArray(key))
            {
                code = one_object_set_val_object(_ptr, key8, value._ptr);
            }

            OneErrorValidator.Validate(code);
        }
        /// <summary>
        /// Adds a <see cref="string"/> element value to the back of the array. The array
        /// must have sufficient free space, that is the capacity must be greater than
        /// the size.
        /// </summary>
        public void PushString(string value)
        {
            int code;

            using (var value8 = new Utf8ByteArray(value))
            {
                code = one_array_push_back_string(_ptr, value8);
            }

            OneErrorValidator.Validate(code);
        }
        /// <summary>
        /// Sets a <see cref="string"/> key/value pair on the object.
        /// </summary>
        public void SetString(string key, string value)
        {
            int code;

            using (var key8 = new Utf8ByteArray(key))
                using (var value8 = new Utf8ByteArray(value))
                {
                    code = one_object_set_val_string(_ptr, key8, value8);
                }

            OneErrorValidator.Validate(code);
        }
        /// <summary>
        /// Retrieves the <see cref="string"/> value from the array.
        /// </summary>
        public string GetString(uint position)
        {
            int size = GetStringSize(position);

            using (var result8 = new Utf8ByteArray(size))
            {
                int code = one_array_val_string(_ptr, position, result8, size);
                OneErrorValidator.Validate(code);

                result8.ReadPtr();
                return(result8.ToString());
            }
        }
        /// <summary>
        /// Retrieves the <see cref="OneArray"/> value from the object. Should be disposed.
        /// </summary>
        public OneArray GetArray(string key)
        {
            var array = new OneArray();
            int code;

            using (var key8 = new Utf8ByteArray(key))
            {
                code = one_object_val_array(_ptr, key8, array.Ptr);
            }

            OneErrorValidator.Validate(code);

            return(array);
        }
        private int GetStringSize(string key)
        {
            int size;
            int code;

            using (var key8 = new Utf8ByteArray(key))
            {
                code = one_object_val_string_size(_ptr, key8, out size);
            }

            OneErrorValidator.Validate(code);

            return(size);
        }
        /// <summary>
        /// Retrieves the <see cref="OneObject"/> value from the object. Should be disposed.
        /// </summary>
        public OneObject GetObject(string key)
        {
            var obj = new OneObject();
            int code;

            using (var key8 = new Utf8ByteArray(key))
            {
                code = one_object_val_object(_ptr, key8, obj.Ptr);
            }

            OneErrorValidator.Validate(code);

            return(obj);
        }
        /// <summary>
        /// Retrieves the <see cref="int"/> value from the object.
        /// </summary>
        public int GetInt(string key)
        {
            int value;
            int code;

            using (var key8 = new Utf8ByteArray(key))
            {
                code = one_object_val_int(_ptr, key8, out value);
            }

            OneErrorValidator.Validate(code);

            return(value);
        }
        /// <summary>
        /// Retrieves the <see cref="bool"/> value from the object.
        /// </summary>
        public bool GetBool(string key)
        {
            bool value;
            int  code;

            using (var key8 = new Utf8ByteArray(key))
            {
                code = one_object_val_bool(_ptr, key8, out value);
            }

            OneErrorValidator.Validate(code);

            return(value);
        }
        /// <summary>
        /// Checks whether the given key is <see cref="string"/>.
        /// </summary>
        public bool IsString(string key)
        {
            bool result;
            int  code;

            using (var key8 = new Utf8ByteArray(key))
            {
                code = one_object_is_val_string(_ptr, key8, out result);
            }

            OneErrorValidator.Validate(code);

            return(result);
        }
        /// <summary>
        /// Retrieves the <see cref="string"/> value from the object.
        /// </summary>
        public string GetString(string key)
        {
            int size = GetStringSize(key);

            using (var result8 = new Utf8ByteArray(size))
            {
                int code;

                using (var key8 = new Utf8ByteArray(key))
                {
                    code = one_object_val_string(_ptr, key8, result8, size);
                }

                OneErrorValidator.Validate(code);

                result8.ReadPtr();
                return(result8.ToString());
            }
        }
        /// <summary>
        /// Set the live game state information about the game server. This should be called at the least when
        /// the state changes, but it is safe to call more often if it is more convenient to do so -
        /// data is only sent out if there are changes from the previous call. Thread-safe.
        /// </summary>
        /// <param name="players">Current player count.</param>
        /// <param name="maxPlayers">Max player count allowed in current match.</param>
        /// <param name="name">Friendly server name.</param>
        /// <param name="map">Actively hosted map.</param>
        /// <param name="mode">Actively hosted game mode.</param>
        /// <param name="version">The version of the game software.</param>
        /// <param name="additionalData">Any key/value pairs set on this object will be added.</param>
        public void SetLiveState(int players,
                                 int maxPlayers,
                                 string name,
                                 string map,
                                 string mode,
                                 string version,
                                 OneObject additionalData)
        {
            int code;

            using (var name8 = new Utf8ByteArray(name))
                using (var map8 = new Utf8ByteArray(map))
                    using (var mode8 = new Utf8ByteArray(mode))
                        using (var version8 = new Utf8ByteArray(version))
                        {
                            code = one_server_set_live_state(_ptr, players, maxPlayers, name8, map8, mode8, version8,
                                                             additionalData != null ? additionalData.Ptr : IntPtr.Zero);
                        }

            OneErrorValidator.Validate(code);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="OneServerWrapper"/> class and starts listening to the specified port.
        /// Should be disposed.
        /// </summary>
        /// <param name="logCallback">The logging callback.</param>
        /// <param name="port">The port to listen to.</param>
        public OneServerWrapper(Action <OneLogLevel, string> logCallback, ushort port)
        {
            _logCallback = logCallback;
            _port        = port;

            int code = one_server_create(port, out _ptr);

            OneErrorValidator.Validate(code);

            code = one_server_set_logger(_ptr, LogCallback, _ptr);
            OneErrorValidator.Validate(code);

            lock (Servers)
            {
                Servers.Add(_ptr, this);
            }

            code = one_server_set_soft_stop_callback(_ptr, SoftStopCallback, _ptr);
            OneErrorValidator.Validate(code);

            code = one_server_set_allocated_callback(_ptr, AllocatedCallback, _ptr);
            OneErrorValidator.Validate(code);

            code = one_server_set_metadata_callback(_ptr, MetadataCallback, _ptr);
            OneErrorValidator.Validate(code);

            code = one_server_set_host_information_callback(_ptr, HostInformationCallback, _ptr);
            OneErrorValidator.Validate(code);

            code = one_server_set_application_instance_information_callback(
                _ptr, ApplicationInstanceInformationCallback, _ptr);
            OneErrorValidator.Validate(code);

            code = one_server_set_custom_command_callback(_ptr, CustomCommandCallback, _ptr);
            OneErrorValidator.Validate(code);
        }
        /// <summary>
        /// Sets a <see cref="OneArray"/> value into a position of the array.
        /// </summary>
        public void SetArray(uint position, OneArray value)
        {
            int code = one_array_set_val_array(_ptr, position, value._ptr);

            OneErrorValidator.Validate(code);
        }
        /// <summary>
        /// Removes last element of the array, if any.
        /// </summary>
        public void Pop()
        {
            int code = one_array_pop_back(_ptr);

            OneErrorValidator.Validate(code);
        }
        /// <summary>
        /// Adds a <see cref="OneObject"/> element value to the back of the array. The array
        /// must have sufficient free space, that is the capacity must be greater than
        /// the size.
        /// </summary>
        public void PushObject(OneObject value)
        {
            int code = one_array_push_back_object(_ptr, value.Ptr);

            OneErrorValidator.Validate(code);
        }
        /// <summary>
        /// Sets a <see cref="bool"/> value into a position of the array.
        /// </summary>
        public void SetBool(uint position, bool value)
        {
            int code = one_array_set_val_bool(_ptr, position, value);

            OneErrorValidator.Validate(code);
        }
        /// <summary>
        /// Sets an <see cref="int"/> value into a position of the array.
        /// </summary>
        public void SetInt(uint position, int value)
        {
            int code = one_array_set_val_int(_ptr, position, value);

            OneErrorValidator.Validate(code);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="OneObject"/>. Should be disposed.
        /// </summary>
        public OneObject()
        {
            int code = one_object_create(out _ptr);

            OneErrorValidator.Validate(code);
        }
        /// <summary>
        /// Sets a <see cref="OneObject"/> value into a position of the array.
        /// </summary>
        public void SetObject(uint position, OneObject value)
        {
            int code = one_array_set_val_object(_ptr, position, value.Ptr);

            OneErrorValidator.Validate(code);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="OneArray"/>. Should be disposed.
        /// </summary>
        public OneArray()
        {
            int code = one_array_create(out _ptr);

            OneErrorValidator.Validate(code);
        }