Ejemplo n.º 1
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 successCallback, ErrorCallback errorCallback)
        {
            if (!Client.IsConnected)
            {
                errorCallback.Invoke("Not connected");
                return;
            }

            Client.SendMessage((ushort)OpCodes.ServerProfileRequest, profile.Username, (status, response) =>
            {
                if (status != ResponseStatus.Success)
                {
                    errorCallback.Invoke(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);
                };

                profile.Disposed += OnProfileDisposed;

                successCallback.Invoke();
            });
        }
Ejemplo n.º 2
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 async void SendUpdatesToClient(ObservableServerProfile profile, float delay)
        {
            // Wait for the delay
            if (delay > 0.01f)
            {
                await Task.Delay(TimeSpan.FromSeconds(delay));
            }

            // 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();
                return;
            }

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

                profile.ClientPeer.SendMessage(MessageHelper.Create((short)OpCodes.UpdateClientProfile, ms.ToArray()),
                                               DeliveryMethod.ReliableOrdered);
            }
        }
    private IEnumerator ImitateGameServer()
    {
        var connection = Msf.Advanced.ClientSocketFactory();

        connection.Connect("127.0.0.1", 5000);

        // Wait until connected to master
        while (!connection.IsConnected)
        {
            yield return(null);
        }

        // Construct the profile
        var profile = new ObservableServerProfile(_username)
        {
            new ObservableInt(MyProfileKeys.Coins, 5),
            new ObservableString(MyProfileKeys.Title, "DefaultTitle"),
        };

        // Fill profile values
        Msf.Server.Profiles.FillProfileValues(profile, (successful, error) =>
        {
            if (!successful)
            {
                Logs.Error(error);
                return;
            }

            // Modify the profile (changes will automatically be sent to the master server)
            profile.GetProperty <ObservableInt>(MyProfileKeys.Coins).Add(4);
            profile.GetProperty <ObservableString>(MyProfileKeys.Title).Set("DifferentTitle");
        }, connection);
    }
Ejemplo n.º 4
0
        /// <summary>
        /// Update profile info in database
        /// </summary>
        /// <param name="profile"></param>
        public void UpdateProfile(ObservableServerProfile profile)
        {
            var data = FindOrCreateData(profile);

            data.Data = profile.ToBytes();
            profiles.Update(data);
        }
Ejemplo n.º 5
0
    private IEnumerator ImitateGameServer()
    {
        var connection = Msf.Advanced.ClientSocketFactory();

        connection.Connect("127.0.0.1", 5000);

        // Wait until connected to master
        while (!connection.IsConnected)
        {
            yield return(null);
        }

        var profile = new ObservableServerProfile(_username)
        {
            new ObservableInt(0, 5),
            new ObservableString(1, "TEE")
        };

        Msf.Server.Profiles.FillProfileValues(profile, (successful, error) =>
        {
            if (!successful)
            {
                Logs.Error(error);
                return;
            }

            profile.GetProperty <ObservableInt>(0).Add(4);
            profile.GetProperty <ObservableString>(1).Set("Medis");
        }, connection);
    }
Ejemplo n.º 6
0
 public MirrorRoomPlayer(int msfPeerId, NetworkConnection mirrorPeer, string username, MstProperties customOptions)
 {
     MasterPeerId  = msfPeerId;
     MirrorPeer    = mirrorPeer ?? throw new ArgumentNullException(nameof(mirrorPeer));
     Username      = username ?? throw new ArgumentNullException(nameof(username));
     CustomOptions = customOptions ?? throw new ArgumentNullException(nameof(customOptions));
     Profile       = new ObservableServerProfile(username);
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Update profile info in database
        /// </summary>
        /// <param name="profile"></param>
        public async Task UpdateProfileAsync(ObservableServerProfile profile)
        {
            var data = await FindOrCreateData(profile);
            data.Data = profile.ToBytes();

            await Task.Run(() =>
            {
                profiles.Update(data);
            });
        }
Ejemplo n.º 8
0
        private void OnProfileModified(ObservableServerProfile profile)
        {
            _modifiedProfiles.Add(profile);

            if (_sendUpdatesCoroutine != null)
            {
                return;
            }

            _sendUpdatesCoroutine = Task.Factory.StartNew(() => KeepSendingUpdates(), TaskCreationOptions.LongRunning);
        }
Ejemplo n.º 9
0
        private void OnProfileModified(ObservableServerProfile profile)
        {
            _modifiedProfiles.Add(profile);

            if (_updateTask != null)
            {
                return;
            }

            _updateTask = KeepSendingUpdates();
        }
Ejemplo n.º 10
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();
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Saves a profile into database after delay
        /// </summary>
        /// <param name="profile"></param>
        /// <param name="delay"></param>
        /// <returns></returns>
        private async void SaveProfile(ObservableServerProfile profile, float delay)
        {
            // Wait for the delay
            await Task.Delay(TimeSpan.FromSeconds(delay));

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

            database.ProfilesDatabase.UpdateProfile(profile);

            profile.UnsavedProperties.Clear();
        }
Ejemplo n.º 12
0
        public void UpdateProfile(ObservableServerProfile profile)
        {
            if (!profile.ShouldBeSavedToDatabase)
            {
                return;
            }

            using (var con = new NpgsqlConnection(_connectionString))
                using (var cmd = new NpgsqlCommand())
                {
                    con.Open();

                    cmd.Connection  = con;
                    cmd.CommandText = "SELECT account_id FROM accounts " +
                                      "WHERE username = @username";
                    cmd.Parameters.AddWithValue("@username", profile.Username);

                    var reader = cmd.ExecuteReader();

                    if (!reader.HasRows)
                    {
                        Logs.Error("Tried to save a profile of a user who has no account: " + profile.Username);
                        return;
                    }

                    reader.Read();

                    //var accountId = reader.GetInt32("account_id");
                    var accountId = int.Parse(reader["account_id"].ToString());

                    reader.Close();
                    cmd.Parameters.Clear();

                    cmd.Connection = con;

                    foreach (var unsavedProp in profile.UnsavedProperties)
                    {
                        cmd.CommandText = "INSERT INTO profile_values (account_id, value_key, value_value) " +
                                          "VALUES (@account_id, @value_key, @value_value)" +
                                          "ON CONFLICT (account_id, value_key) DO UPDATE SET value_value = @value_value";

                        cmd.Parameters.AddWithValue("@account_id", accountId);
                        cmd.Parameters.AddWithValue("@value_key", unsavedProp.Key);
                        cmd.Parameters.AddWithValue("@value_value", unsavedProp.SerializeToString());

                        cmd.ExecuteNonQuery();

                        cmd.Parameters.Clear();
                    }
                }

            profile.UnsavedProperties.Clear();
        }
Ejemplo n.º 13
0
 /// <summary>
 /// Get profile info from database
 /// </summary>
 /// <param name="profile"></param>
 public async Task RestoreProfileAsync(ObservableServerProfile profile)
 {
     try
     {
         var data = await FindOrCreateData(profile);
         profile.FromBytes(data.Data);
     }
     catch (Exception e)
     {
         UnityEngine.Debug.LogError(e);
     }
 }
Ejemplo n.º 14
0
        /// <summary>
        /// Update profile info in database
        /// </summary>
        /// <param name="profile"></param>
        /// <param name="callback"></param>
        public async void UpdateProfileAsync(ObservableServerProfile profile, SuccessCallback callback)
        {
            try
            {
                await Task.Run(() => UpdateProfile(profile));

                callback?.Invoke(true, string.Empty);
            }
            catch (Exception e)
            {
                callback?.Invoke(false, e.Message);
            }
        }
Ejemplo n.º 15
0
        public async Task UpdateProfileAsync(ObservableServerProfile profile)
        {
            var data = await FindOrCreateData(profile);

            data.Data = profile.ToBytes();

            var filter = Builders <ProfileInfoDataMongoDB> .Filter.Eq(e => e.UserId, profile.UserId);

            await Task.Run(() =>
            {
                _profiles.ReplaceOne(filter, data);
            });
        }
Ejemplo n.º 16
0
        //Find profile in database or create new data and insert into database
        private ProfileInfoData FindOrCreateData(ObservableServerProfile profile)
        {
            var data = profiles.FindOne(a => a.Username == profile.Username);

            if (data == null)
            {
                data = new ProfileInfoData()
                {
                    Username = profile.Username,
                    Data     = profile.ToBytes()
                };
                profiles.Insert(data);
            }
            return(data);
        }
Ejemplo n.º 17
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));
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Find profile data in database or create new data and insert them to database
        /// </summary>
        /// <param name="profile"></param>
        /// <returns></returns>
        private async Task <ProfileInfoData> FindOrCreateData(ObservableServerProfile profile)
        {
            string username = profile.Username;

            var data = await Task.Run(() => {
                return(profiles.FindOne(a => a.Username == username));
            });

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

                await Task.Run(() => {
                    profiles.Insert(data);
                });
            }

            return(data);
        }
Ejemplo n.º 19
0
        private async Task <ProfileInfoDataMongoDB> FindOrCreateData(ObservableServerProfile profile)
        {
            string userId = profile.UserId;

            var data = await Task.Run(() => {
                return(_profiles.Find(a => a.UserId == userId).FirstOrDefault());
            });

            if (data == null)
            {
                data = new ProfileInfoDataMongoDB()
                {
                    UserId = profile.UserId,
                    Data   = profile.ToBytes()
                };

                await Task.Run(() => {
                    _profiles.InsertOne(data);
                });
            }

            return(data);
        }
Ejemplo n.º 20
0
        public void RestoreProfile(ObservableServerProfile profile)
        {
            using (var con = new NpgsqlConnection(_connectionString))
                using (var cmd = new NpgsqlCommand())
                {
                    con.Open();

                    cmd.Connection  = con;
                    cmd.CommandText = "SELECT profile_values.* " +
                                      "FROM profile_values " +
                                      "INNER JOIN accounts " +
                                      "ON accounts.account_id = profile_values.account_id " +
                                      "WHERE username = @username;";
                    cmd.Parameters.AddWithValue("@username", profile.Username);

                    var reader = cmd.ExecuteReader();

                    // There's no such data
                    if (!reader.HasRows)
                    {
                        return;
                    }

                    var data = new Dictionary <short, string>();

                    while (reader.Read())
                    {
                        //var key = reader.GetInt16("value_key");
                        var key = short.Parse(reader["value_key"].ToString());

                        var value = reader["value_value"] as string ?? "";
                        data.Add(key, value);
                    }

                    profile.FromStrings(data);
                }
        }
Ejemplo n.º 21
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
            {
                // Wait one frame, so that we don't send multiple packets
                // in case we update multiple values
                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)MsfMessageCodes.UpdateClientProfile, ms.ToArray()),
                                               DeliveryMethod.ReliableSequenced);
            }
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Get profile info from database
        /// </summary>
        /// <param name="profile"></param>
        public void RestoreProfile(ObservableServerProfile profile)
        {
            var data = FindOrCreateData(profile);

            profile.FromBytes(data.Data);
        }
Ejemplo n.º 23
0
        private void OnProfileDisposed(ObservableServerProfile profile)
        {
            profile.Disposed -= OnProfileDisposed;

            _profiles.Remove(profile.Username);
        }
Ejemplo n.º 24
0
 public void RestoreProfile(ObservableServerProfile profile)
 {
     _concreteDbAccess.RestoreProfile(profile);
 }
Ejemplo n.º 25
0
 public void UpdateProfile(ObservableServerProfile profile)
 {
     _concreteDbAccess.UpdateProfile(profile);
 }
Ejemplo n.º 26
0
 public ProfileExtension(ObservableServerProfile profile, IPeer peer)
 {
     Username = profile.Username;
     Profile  = profile;
     Peer     = peer;
 }