예제 #1
0
 internal Realm(Realm parent, long id)
 {
     Parent = parent;
     ID     = id;
 }
예제 #2
0
        private void ChangeRealm(User user, long targetRealmID, bool createChildRealm)
        {
            // Don't do anything if the user is staying in the same realm
            if ((user.Realm == null && targetRealmID == -1) ||
                (user.Realm != null && user.Realm.ID == targetRealmID))
            {
                return;
            }

            // Child realms can only be created if user is currently in a realm
            var oldRealm = user.Realm;

            if (oldRealm == null && createChildRealm)
            {
                createChildRealm = false;
            }

            // Remove user from the old realm, informing everyone that the user has left it
            if (oldRealm != null)
            {
                oldRealm.Users.Remove(user);
                user.Realm = null;
                foreach (var realmUser in oldRealm.Users)
                {
                    Send(realmUser.EndPoint, "-" + user.ID);
                }
            }

            // Get the target realm, creating it if necessary
            var newRealm = (Realm)null;

            if (targetRealmID != -1)
            {
                if (!realmsByID.TryGetValue(targetRealmID, out newRealm))
                {
                    var parentRealm = createChildRealm ? oldRealm : null;
                    newRealm = new Realm(parentRealm, targetRealmID);
                    realmsByID.Add(targetRealmID, newRealm);
                    if (parentRealm != null)
                    {
                        parentRealm.ChildRealms.Add(newRealm);
                    }
                }

                // Add the user to the new realm
                newRealm.Users.Add(user);
                user.Realm = newRealm;

                // Advise user that the new realm has been joined successfully
                Send(user.EndPoint, (createChildRealm ? "&" : "^") + targetRealmID);

                // Advise user of all child realms already existing in the new realm
                foreach (var realm in newRealm.ChildRealms)
                {
                    Send(user.EndPoint, "{" + realm.ID);
                }

                // Advise user of all other users already connected to that realm
                var otherRealmUsers = newRealm.Users.Where(u => u != user).ToArray();
                Send(user.EndPoint, "=" + string.Join(",", otherRealmUsers.Select(u => u.ID)));

                // Advise everyone in the target realm that user has joined
                foreach (var realmUser in otherRealmUsers)
                {
                    Send(realmUser.EndPoint, "+" + user.ID);
                }
            }

            // Advise everyone in the old realm that there is a new child realm
            if (createChildRealm)
            {
                foreach (var realmUser in oldRealm.Users)
                {
                    Send(realmUser.EndPoint, "{" + newRealm.ID);
                }
            }

            // If there aren't any more users or child realms in the old realm then recursively destroy the old realm(s)
            var currentRealm = oldRealm;

            while (!createChildRealm && currentRealm != null && currentRealm.Users.Count == 0 && currentRealm.ChildRealms.Count == 0)
            {
                // Remove the realm from the parent's child list
                if (currentRealm.Parent != null)
                {
                    currentRealm.Parent.ChildRealms.Remove(currentRealm);

                    // Advise users of the parent realm that the child realm has been destroyed
                    foreach (var realmUser in currentRealm.Parent.Users)
                    {
                        Send(realmUser.EndPoint, "}" + currentRealm.ID);
                    }
                }

                // Remove realm data
                if (currentRealm.ID >= Settings.Default.PublicRealmCount)
                {
                    foreach (var fileName in Directory.GetFiles(".", "realm." + currentRealm.ID + ".*.entity"))
                    {
                        File.Delete(fileName);
                    }
                }

                // Remove the realm from the list
                if (currentRealm.ID >= Settings.Default.PublicRealmCount)
                {
                    reclaimableRealmIDs.Enqueue(currentRealm.ID);
                }
                realmsByID.Remove(currentRealm.ID);

                // Move on to checking parent realm
                currentRealm = currentRealm.Parent;
            }
        }