示例#1
0
        static private void GetEvents(Journal.OptionsRow or, ILJServer iLJ, ref SyncItemCollection sic,
                                      ref SyncItemCollection deletedsic, ref EventCollection ec)
        {
            // for an explanation of this algorithm, see
            // http://www.livejournal.com/community/lj_clients/143312.html
            // note that this is a very painful algorithm.  it will loop an extra time for each
            // deleted syncitem that getevents doesn't return an event for.  if LJ decides to revise
            // how they return syncitems, this algorithm can be made more efficient.
            int total = sic.Count;

            while (sic.Count > 0)
            {
                SyncItem             oldest     = sic.GetOldest();
                DateTime             oldestTime = DateTime.Parse(oldest.time, CultureInfo.InvariantCulture).AddSeconds(-1);
                GetChallengeResponse gcr        = iLJ.GetChallenge();
                string          auth_response   = MD5Hasher.Compute(gcr.challenge + or.HPassword);
                GetEventsParams gep             = new GetEventsParams(or.UserName, "challenge", gcr.challenge,
                                                                      auth_response, 1, 0, 0, 0, "syncitems", oldestTime.ToString(_datetimeformat), 0, 0, 0, 0,
                                                                      string.Empty, 0, "unix", (or.IsUseJournalNull() ? string.Empty : or.UseJournal));
                GetEventsResponse ger;
                socb(new SyncOperationEventArgs(SyncOperation.GetEvents, total - sic.Count, total));
                ger = iLJ.GetEvents(gep);
                // remove this item in case it isn't returned by getevents
                // this signifies that the item has been deleted
                // this also ensures we don't get stuck in an endless loop
                sic.Remove(oldest);
                sic.RemoveDownloaded(ger.events);
                deletedsic.RemoveDownloaded(ger.events);
                ec.AddRange(ger.events);
            }
        }
示例#2
0
        static private void SyncItems(Journal.OptionsRow or, ILJServer iLJ, ref SyncItemCollection sic,
                                      ref SyncItemCollection deletedsic, ref DateTime lastSync)
        {
            // syncitems returns a "meta" list of what events have changed since the last time we called syncitems
            // note that syncitems may be called more than once
            GetChallengeResponse gcr;
            string            auth_response;
            SyncItemsParams   sip;
            SyncItemsResponse sir;
            int total = -1, count = 0;

            lastSync = (or.IsLastSyncNull() ? DateTime.MinValue : or.LastSync);
            do
            {
                string lastSyncString = (lastSync == DateTime.MinValue ? string.Empty :
                                         lastSync.ToString(_datetimeformat));
                gcr           = iLJ.GetChallenge();
                auth_response = MD5Hasher.Compute(gcr.challenge + or.HPassword);
                sip           = new SyncItemsParams(or.UserName, "challenge", gcr.challenge, auth_response, 1,
                                                    lastSyncString, (or.IsUseJournalNull() ? string.Empty : or.UseJournal));
                sir    = iLJ.SyncItems(sip);
                total  = (total == -1 ? sir.total : total);
                count += sir.count;
                sic.AddRangeLog(sir.syncitems);
                deletedsic.AddRangeLog(sir.syncitems);
                if (sic.GetMostRecentTime() > lastSync)
                {
                    lastSync = sic.GetMostRecentTime();
                }
                socb(new SyncOperationEventArgs(SyncOperation.SyncItems, count, total));
            } while (sir.count < sir.total);
        }
示例#3
0
 static Globals()
 {
     SyncItems = new SyncItemCollection();
 }
示例#4
0
        static private void Merge(Journal j, EventCollection ec, CommentCollection ccMeta,
                                  CommentCollection ccBody, UserMapCollection umc, SyncItemCollection deletedsic, LoginResponse lr,
                                  string communityPicURL, DateTime lastSync)
        {
            j.AcceptChanges();             // row states must be set to unchanged for loaddatarow to merge properly

            // update moods
            j.Moods.BeginLoadData();
            foreach (Mood m in lr.moods)
            {
                j.Moods.LoadDataRow(new object[] { m.id, m.name, m.parent }, false);
            }
            j.Moods.EndLoadData();

            // update userpics
            j.UserPics.Clear();
            j.UserPics.BeginLoadData();
            for (int i = 0; i < lr.pickws.Length; ++i)
            {
                j.UserPics.AddUserPicsRow(lr.pickws[i], lr.pickwurls[i]);
            }
            j.UserPics.EndLoadData();

            // update users
            j.Users.BeginLoadData();
            foreach (UserMap u in umc)
            {
                j.Users.LoadDataRow(new object[] { u.id, u.user }, false);
            }
            j.Users.LoadDataRow(new object[] { 0, "anonymous" }, false);
            j.Users.EndLoadData();

            // update new/updated journal events
            j.Events.BeginLoadData();
            foreach (Event e in ec)
            {
                j.Events.LoadDataRow(new object[] {
                    e.itemid,
                    DateTime.Parse(e.eventtime, CultureInfo.InvariantCulture),
                    e.security,
                    e.allowmask,
                    e.subject,
                    e.eventText,
                    e.poster,
                    e.anum,
                    e.props.current_mood,
                    e.props.current_moodid,
                    e.props.current_music,
                    e.props.opt_preformatted == 1,
                    e.props.opt_nocomments == 1,
                    e.props.picture_keyword,
                    e.props.opt_backdated == 1,
                    e.props.opt_noemail == 1,
                    e.props.unknown8bit == 1,
                    e.props.hasscreened == 1,
                    e.props.revnum,
                    e.props.commentalter,
                    e.props.syn_link,
                    e.props.syn_id,
                    new DateTime(1970, 1, 1).AddSeconds(e.props.revtime),
                    e.props.taglist
                }, false);
            }
            j.Events.EndLoadData();

            // update comment meta (posterid and state can change)
            j.Comments.BeginLoadData();
            foreach (Comment c in ccMeta)
            {
                Journal.CommentsRow cr = j.Comments.FindByID(c.id);
                if (cr != null)
                {
                    cr.PosterID = c.posterid;
                    cr.State    = c.state;
                }
            }
            j.Comments.EndLoadData();

            // update comment bodies
            j.Comments.BeginLoadData();
            foreach (Comment c in ccBody)
            {
                j.Comments.LoadDataRow(new object[] {
                    c.id,
                    c.posterid,
                    c.state,
                    c.jitemid,
                    c.parentid,
                    c.body,
                    c.subject,
                    c.date
                }, false);
            }
            j.Comments.EndLoadData();

            // update deleted journal events
            if (deletedsic != null)
            {
                foreach (SyncItem s in deletedsic)
                {
                    Common.Journal.EventsRow er =
                        j.Events.FindByID(int.Parse(s.item.Substring(_syncitemtypelogprefix.Length)));
                    if (er != null)
                    {
                        j.Events.RemoveEventsRow(er);
                    }
                }
            }

            // update options
            j.Options.DefaultPicURL = (lr.defaultpicurl != null && lr.defaultpicurl.Length > 0 ?
                                       lr.defaultpicurl : null);
            j.Options.CommunityPicURL = communityPicURL;
            j.Options.FullName        = (lr.fullname != null && lr.fullname.Length > 0 ? lr.fullname : null);
            j.Options.LastSync        = lastSync;
        }
示例#5
0
        static private void ThreadStart()
        {
            // The main threaded execution body for performing a sync.
            // This method is chopped up into smaller methods for clarity and structure.
            ILJServer iLJ;

            Journal.OptionsRow      or = null;
            SyncItemCollection      sic = null, deletedsic = null;
            EventCollection         ec = null;
            CommentCollection       ccbody = null, ccmeta = null;
            UserMapCollection       umc             = null;
            LoginResponse           lr              = new LoginResponse();
            string                  communityPicURL = null;
            DateTime                lastSync        = DateTime.MinValue;
            SessionGenerateResponse sgr;
            int serverMaxID, localMaxID;

            try
            {
                // STEP 1: Initialize
                socb(new SyncOperationEventArgs(SyncOperation.Initialize, 0, 0));
                syncException = null;
                or            = j.Options;
                iLJ           = LJServerFactory.Create(or.ServerURL);
                sic           = new SyncItemCollection();
                deletedsic    = new SyncItemCollection();
                ec            = new EventCollection();
                ccmeta        = new CommentCollection();
                ccbody        = new CommentCollection();
                umc           = new UserMapCollection();

                // STEP 2: Login
                socb(new SyncOperationEventArgs(SyncOperation.Login, 0, 0));
                lr = new LoginResponse();
                Login(or, iLJ, ref lr, ref communityPicURL);

                // STEP 3: SyncItems
                socb(new SyncOperationEventArgs(SyncOperation.SyncItems, 0, 0));
                lastSync = DateTime.MinValue;
                SyncItems(or, iLJ, ref sic, ref deletedsic, ref lastSync);

                // STEP 4: GetEvents
                socb(new SyncOperationEventArgs(SyncOperation.GetEvents, 0, 0));
                GetEvents(or, iLJ, ref sic, ref deletedsic, ref ec);

                if (or.GetComments)
                {
                    // STEP 5: SessionGenerate
                    socb(new SyncOperationEventArgs(SyncOperation.SessionGenerate, 0, 0));
                    sgr = new SessionGenerateResponse();
                    SessionGenerate(or, iLJ, ref sgr);

                    // STEP 6: ExportCommentsMeta
                    socb(new SyncOperationEventArgs(SyncOperation.ExportCommentsMeta, 0, 0));
                    localMaxID = serverMaxID = j.GetMaxCommentID();
                    ExportCommentsMeta(or, iLJ, sgr, ref serverMaxID, localMaxID, umc, ccmeta);

                    // STEP 7: ExportCommentsBody
                    socb(new SyncOperationEventArgs(SyncOperation.ExportCommentsBody, 0, 0));
                    ExportCommentsBody(or, iLJ, sgr, serverMaxID, localMaxID, ccbody);
                }
            }
            catch (Exception ex)
            {
                ParseException(ex, ref syncException);
                if (ex.GetType() == typeof(ThreadAbortException))
                {
                    socb(new SyncOperationEventArgs(SyncOperation.Failure, 0, 0));                     // do this before thread terminates
                    return;
                }
            }

            // STEP 8: Merge
            try
            {
                if (syncException == null)
                {
                    socb(new SyncOperationEventArgs(SyncOperation.Merge, 0, 0));
                    Merge(j, ec, ccmeta, ccbody, umc, deletedsic, lr, communityPicURL, lastSync);
                    socb(new SyncOperationEventArgs(SyncOperation.Success, ec.Count, ccbody.Count));
                }
                else if (syncException.GetType() == typeof(ExpectedSyncException) &&
                         (((ExpectedSyncException)syncException).ExpectedError == ExpectedError.ServerNotResponding ||
                          ((ExpectedSyncException)syncException).ExpectedError ==
                          ExpectedError.ExportCommentsNotSupported ||
                          ((ExpectedSyncException)syncException).ExpectedError ==
                          ExpectedError.CommunityAccessDenied) &&
                         lr.moods != null)
                {
                    socb(new SyncOperationEventArgs(SyncOperation.Merge, 0, 0));
                    if (sic.Count > 0)
                    {
                        lastSync = DateTime.Parse(sic.GetOldest().time, CultureInfo.InvariantCulture).AddSeconds(-1);
                    }
                    Merge(j, ec, ccmeta, ccbody, umc, deletedsic, lr, communityPicURL, lastSync);
                    socb(new SyncOperationEventArgs(SyncOperation.PartialSync, ec.Count, ccbody.Count));
                }
                else
                {
                    socb(new SyncOperationEventArgs(SyncOperation.Failure, 0, 0));
                }
            }
            catch (Exception ex)
            {
                syncException = ex;
                socb(new SyncOperationEventArgs(SyncOperation.Failure, 0, 0));
            }
        }
        public override void OnInspectorGUI()
        {
            #region Core
            base.OnInspectorGUI();
            SyncItemCollection sic = (SyncItemCollection)target;
            DrawTitleBar(
                "Sync Item Collection",
                "Used to sync events from collecting this item across the network. \n\n" +
                "Required Setup Actions:\n" +
                "1. Copy the settings on the following fields from \"vItemCollection\" to this component:\n" +
                " * \"OnPressActionDelay\"\n" +
                " * \"OnPressActionInput\"\n" +
                " * \"OnPressActionInputWithTarget\"\n\n" +
                "2. On \"vItemCollection\" do the following:\n" +
                " * Set \"OnPressActionDelay\" to zero\n" +
                " * Remove all events from \"OnPressActionInput\"\n" +
                " * Remove all events from \"OnPressActionInputWithTarget\"\n",
                E_Core.h_genericIcon
                );
            #endregion

            #region Properties
            GUILayout.BeginHorizontal(GUI.skin.box, GUILayout.ExpandHeight(false));
            GUILayout.BeginVertical(GUILayout.ExpandHeight(false));
            EditorGUILayout.PropertyField(syncCrossScenes);
            if (syncCrossScenes.boolValue == true)
            {
                EditorGUILayout.PropertyField(holder, new GUIContent("Track Position"));
                EditorGUILayout.PropertyField(syncCreateDestroy, new GUIContent("Is Dynamic Obj"));
                if (syncCreateDestroy.boolValue == true)
                {
                    EditorGUILayout.PropertyField(resourcesPrefab);
                }
            }
            EditorGUILayout.PropertyField(skipStartCheck, new GUIContent("Items In ItemCollection"));
            GUILayout.EndHorizontal();
            GUILayout.EndVertical();

            GUILayout.BeginHorizontal(GUI.skin.box, GUILayout.ExpandHeight(false));
            GUILayout.BeginVertical(GUILayout.ExpandHeight(false));
            EditorGUILayout.PropertyField(onPressActionDelay);
            GUILayout.EndHorizontal();
            GUILayout.EndVertical();

            GUILayout.BeginHorizontal(GUI.skin.box, GUILayout.ExpandHeight(false));
            GUILayout.BeginVertical(GUILayout.ExpandHeight(false));
            GUI.skin = _original;
            CBEditor.SetColorToEditorStyle(_originalHolder, _originalFoldout);
            EditorGUILayout.HelpBox("These should be copied exactly from the vItemColletion component.", MessageType.None);
            EditorGUILayout.PropertyField(OnPressActionInput);
            EditorGUILayout.PropertyField(onPressActionInputWithTarget);

            EditorGUILayout.HelpBox("This is called when this object was actived by another player " +
                                    "when previously in another scene. When you enter this scene this is called.", MessageType.None);
            EditorGUILayout.PropertyField(OnSceneEnterUpdate);

            GUI.skin = _skin;
            CBEditor.SetColorToEditorStyle(_skinHolder, _skinHolder);
            GUILayout.EndHorizontal();
            GUILayout.EndVertical();
            #endregion

            EndInspectorGUI(typeof(SyncItemCollection));
        }