public static void AutoCycle( Interactor intr, int startDelaySec) { if (intr.CancelSource.IsCancellationRequested) { return; } var queue = new TaskQueue(); int charsTotal = intr.AccountSettings.GetSettingValOr("characterCount", "general", 0); if (queue.IsEmpty) { intr.Log("Populating task queue: (0 -> " + (charsTotal).ToString() + ")"); queue.Populate(intr, charsTotal, RESET_DAY); intr.UpdateQueueList(queue.ListClone(intr)); } intr.Log("Starting AutoCycle in " + startDelaySec.ToString() + " seconds..."); intr.Wait(startDelaySec * 1000); if (intr.CancelSource.IsCancellationRequested) { return; } intr.Log("Beginning AutoCycle."); // ##### BEGIN AUTOCYCLE LOOP ##### while (!queue.IsEmpty && !intr.CancelSource.IsCancellationRequested) { if (IsCurfew()) { int sleepTime = intr.WaitRand(300000, 1800000); intr.Log("Curfew time. Sleeping for " + (sleepTime / 60000).ToString() + " minutes."); } intr.Log(LogEntryType.Debug, "AutoCycle(): Loop iteration starting."); TimeSpan nextTaskMatureDelay = queue.NextTaskMatureDelay(); intr.Log(LogEntryType.Debug, "AutoCycle(): Next task mature delay: " + nextTaskMatureDelay); if (nextTaskMatureDelay.Ticks <= 0) { // TASK TIMER HAS MATURED -> CONTINUE // ##### ENTRY POINT -- INVOKING & PROCESSING CHARACTER ##### ProcessCharacter(intr, queue); } else { // TASK TIMER NOT MATURE YET -> WAIT intr.Wait(1000); intr.Log("Next task matures in " + nextTaskMatureDelay.TotalMinutes.ToString("F0") + " minutes."); TimeSpan waitDelay = nextTaskMatureDelay; if (nextTaskMatureDelay.TotalMinutes > 8) { if (queue.NextTask.Kind == TaskKind.Profession) { waitDelay = nextTaskMatureDelay + intr.RandomDelay(9, 25); } else { waitDelay = nextTaskMatureDelay + intr.RandomDelay(9, 15); } ProduceClientState(intr, ClientState.None, 0); } else if (nextTaskMatureDelay.TotalSeconds > 1) { // Delay more than 1 sec, let the train catch up... ProduceClientState(intr, ClientState.Inactive, 0); waitDelay = nextTaskMatureDelay + intr.RandomDelay(5, 11); intr.Log("Minimizing client and waiting " + waitDelay.TotalMinutes.ToString("F0") + " minutes."); } if (waitDelay.TotalSeconds > 1) { intr.Log("Sleeping for " + waitDelay.TotalMinutes.ToString("F0") + " minutes before continuing..."); intr.Wait(waitDelay); Screen.Wake(intr); } } intr.Wait(100); } intr.Log(LogEntryType.Info, "Autocycle complete."); }
// QUEUESUBSEQUENTPROFESSIONTASK(): QUEUE FOLLOW UP TASK private void QueueSubsequentProfessionTask(Interactor intr, uint charIdx, int taskId, float bonusFactor) { var now = DateTime.Now; var mostRecentProfTime = intr.AccountStates.GetCharStateOr(charIdx, "MostRecentProfTime_" + taskId, Global.Default.SomeOldDate); var taskMatureTime = now; if (mostRecentProfTime.AddMinutes(ProfessionTasksRef.ProfessionTaskDurationMinutes[taskId]) < now) { taskMatureTime = CalculateTaskMatureTime(now, charIdx, TaskKind.Profession, taskId, bonusFactor); } else { taskMatureTime = CalculateTaskMatureTime(mostRecentProfTime, charIdx, TaskKind.Profession, taskId, bonusFactor); } intr.Log("Next profession task (" + ProfessionTasksRef.ProfessionTaskNames[taskId] + ") for " + intr.AccountSettings.CharNames[(int)charIdx] + " at: " + taskMatureTime.ToString() + "."); var newTask = this.Add(new GameTask(now, taskMatureTime, charIdx, TaskKind.Profession, taskId, bonusFactor)); //intr.AccountStates.SaveCharState(now, charIdx, "MostRecentProfTime_" + taskId); intr.AccountStates.SaveCharTask(newTask); intr.UpdateQueueList(this.ListClone(intr)); }
// QUEUESUBSEQUENTINVOCATIONTASK(): QUEUE FOLLOW UP TASK // // If `invokesToday` is 0 it can be assumed that things are out of sync. // - `invokesToday` defaults to 1 initially (see `AdvanceTask()` near the bottom). // - There are no other known reasons why it would be 0, therefore an extra 15 minutes of delay is added. private void QueueSubsequentInvocationTask(Interactor intr, uint charIdx, int invokesToday) { var now = DateTime.Now; DateTime taskMatureTime = now; DateTime nextThreeThirty = NextThreeAmPst; DateTime todaysInvokeDate = TodaysGameDate; //string charLabel = intr.AccountSettings.GetCharSetting(charIdx, "CharacterName"); string charLabel = intr.AccountSettings.CharNode(charIdx).GetAttribute("name"); if (invokesToday < 6) { // QUEUE FOR LATER TimeSpan extraDelay = TimeSpan.FromMinutes(0); if (invokesToday == 0) { extraDelay = TimeSpan.FromMinutes(15); } taskMatureTime = CalculateTaskMatureTime(now + extraDelay, charIdx, TaskKind.Invocation, invokesToday, 0.0f); // IF NEXT SCHEDULED TASK IS BEYOND THE 3:30 CURFEW, RESET FOR NEXT DAY if (taskMatureTime > nextThreeThirty) { invokesToday = 6; taskMatureTime = nextThreeThirty; } } else { // (INVOKES >= 6) QUEUE FOR TOMORROW try { intr.Log(LogEntryType.Debug, "Interactions::Sequences::AutoCycle(): All daily invocation complete for character [" + charIdx + "] on: " + todaysInvokeDate); intr.AccountStates.SaveCharState(todaysInvokeDate, charIdx, "invokesCompleteFor"); intr.AccountStates.SaveCharState(invokesToday, charIdx, "invokesToday"); taskMatureTime = nextThreeThirty; } catch (Exception ex) { intr.Log(LogEntryType.Error, "Error saving InvokesCompleteFor" + ex.ToString()); } } try { intr.AccountStates.SaveCharState(invokesToday, charIdx, "invokesToday"); intr.AccountStates.SaveCharState(now, charIdx, "mostRecentInvocationTime"); intr.Log(LogEntryType.Debug, "Settings saved to ini for: " + charLabel + "."); } catch (Exception ex) { intr.Log(LogEntryType.Error, "Interactions::Sequences::AutoCycle(): Problem saving settings: " + ex.ToString()); } intr.Log("Next invocation task for " + intr.AccountSettings.CharNames[(int)charIdx] + " at: " + taskMatureTime.ToString() + "."); var newTask = this.Add(new GameTask(now, taskMatureTime, charIdx, TaskKind.Invocation, invokesToday, 0.0f)); intr.AccountStates.SaveCharTask(newTask); intr.UpdateQueueList(this.ListClone(intr)); }