예제 #1
0
        /// <summary>
        /// Should restore all values of the given profile,
        /// or not change them, if there's no entry in the database
        /// </summary>
        /// <returns></returns>
        public void RestoreProfile(ObservableServerProfile profile, Action doneCallback)
        {
            var data = FindOrCreateData(profile);

            profile.FromBytes(data.Data);
            doneCallback.Invoke();
        }
예제 #2
0
        /// <summary>
        ///     Sends a request to server, retrieves all profile values, and applies them to a provided
        ///     profile
        /// </summary>
        public void FillProfileValues(ObservableServerProfile profile, SuccessCallback callback,
                                      IClientSocket connection)
        {
            if (!connection.IsConnected)
            {
                callback.Invoke(false, "Not connected");
                return;
            }

            connection.SendMessage((short)MsfOpCodes.ServerProfileRequest, profile.Username, (status, response) => {
                if (status != ResponseStatus.Success)
                {
                    callback.Invoke(false, response.AsString("Unknown error"));
                    return;
                }

                // Use the bytes received, to replicate the profile
                profile.FromBytes(response.AsBytes());

                profile.ClearUpdates();

                _profiles[profile.Username] = profile;

                profile.ModifiedInServer += serverProfile => { OnProfileModified(profile, connection); };

                profile.Disposed += OnProfileDisposed;

                callback.Invoke(true, null);
            });
        }
예제 #3
0
        /// <summary>
        /// Should save updated profile into database
        /// </summary>
        /// <param name="profile"></param>
        public void UpdateProfile(ObservableServerProfile profile)
        {
            var data = FindOrCreateData(profile);

            data.Data = profile.ToBytes();
            _profiles.Update(data);
        }
예제 #4
0
        /// <summary>
        ///     Collets changes in the profile, and sends them to client after delay
        /// </summary>
        /// <param name="profile"></param>
        /// <param name="delay"></param>
        /// <returns></returns>
        private IEnumerator SendUpdatesToClient(ObservableServerProfile profile, float delay)
        {
            // Wait for the delay
            if (delay > 0.01f)
            {
                yield return(new WaitForSecondsRealtime(delay));
            }
            else
            {
                yield return(null);
            }

            // Remove value from debounced updates
            _debouncedClientUpdates.Remove(profile.Username);

            if (profile.ClientPeer == null || !profile.ClientPeer.IsConnected)
            {
                // If client is not connected, and we don't need to send him profile updates
                profile.ClearUpdates();
                yield break;
            }

            using (var ms = new MemoryStream()) {
                using (var writer = new EndianBinaryWriter(EndianBitConverter.Big, ms)) {
                    profile.GetUpdates(writer);
                    profile.ClearUpdates();
                }

                profile.ClientPeer.SendMessage(
                    MessageHelper.Create((short)MsfOpCodes.UpdateClientProfile, ms.ToArray()),
                    DeliveryMethod.ReliableSequenced);
            }
        }
예제 #5
0
        /// <summary>
        /// Should save updated profile into database
        /// </summary>
        public void UpdateProfile(ObservableServerProfile profile, Action doneCallback)
        {
            var data = FindOrCreateData(profile);

            data.Data = profile.ToBytes();
            _profiles.Update(data);

            doneCallback.Invoke();
        }
예제 #6
0
        private void OnProfileModified(ObservableServerProfile profile, IClientSocket connection)
        {
            _modifiedProfiles.Add(profile);

            if (_sendUpdatesCoroutine != null)
            {
                return;
            }

            _sendUpdatesCoroutine = BTimer.Instance.StartCoroutine(KeepSendingUpdates(connection));
        }
예제 #7
0
        /// <summary>
        /// Saves a profile into database after delay
        /// </summary>
        /// <param name="profile"></param>
        /// <param name="delay"></param>
        /// <returns></returns>
        private IEnumerator SaveProfile(ObservableServerProfile profile, float delay)
        {
            // Wait for the delay
            yield return(new WaitForSecondsRealtime(delay));

            // Remove value from debounced updates
            debouncedSaves.Remove(profile.Username);

            profileDatabaseAccessor.UpdateProfile(profile);

            profile.UnsavedProperties.Clear();
        }
예제 #8
0
        private ProfileDataLdb FindOrCreateData(ObservableServerProfile profile)
        {
            var data = _profiles.FindOne(a => a.Username == profile.Username);

            if (data == null)
            {
                data = new ProfileDataLdb()
                {
                    Username = profile.Username,
                    Data     = profile.ToBytes()
                };

                // Why did I do this?
                _profiles.Insert(data);
            }
            return(data);
        }
예제 #9
0
        /// <summary>
        /// Invoked, when profile is changed
        /// </summary>
        /// <param name="profile"></param>
        private void OnProfileChangedEventHandler(ObservableServerProfile profile)
        {
            // Debouncing is used to reduce a number of updates per interval to one
            // TODO make debounce lookup more efficient than using string hashet

            if (!debouncedSaves.Contains(profile.Username) && profile.ShouldBeSavedToDatabase)
            {
                // If profile is not already waiting to be saved
                debouncedSaves.Add(profile.Username);
                StartCoroutine(SaveProfile(profile, saveProfileInterval));
            }

            if (!debouncedClientUpdates.Contains(profile.Username))
            {
                // If it's a master server
                debouncedClientUpdates.Add(profile.Username);
                StartCoroutine(SendUpdatesToClient(profile, clientUpdateInterval));
            }
        }
예제 #10
0
 public ProfileExtension(ObservableServerProfile profile, IPeer peer)
 {
     Username = profile.Username;
     Profile  = profile;
     Peer     = peer;
 }
예제 #11
0
        /// <summary>
        /// Should restore all values of the given profile,
        /// or not change them, if there's no entry in the database
        /// </summary>
        /// <param name="profile"></param>
        /// <returns></returns>
        public void RestoreProfile(ObservableServerProfile profile)
        {
            var data = FindOrCreateData(profile);

            profile.FromBytes(data.Data);
        }
예제 #12
0
        private void OnProfileDisposed(ObservableServerProfile profile)
        {
            profile.Disposed -= OnProfileDisposed;

            _profiles.Remove(profile.Username);
        }
예제 #13
0
 /// <summary>
 ///     Sends a request to server, retrieves all profile values, and applies them to a provided
 ///     profile
 /// </summary>
 public void FillProfileValues(ObservableServerProfile profile, SuccessCallback callback)
 {
     FillProfileValues(profile, callback, Connection);
 }