Иконка ресурса

FREE CronLibrary : 1.0.2 1.0.2

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
/*
// Cron Library - Cron Library for Oxide Mod ()
// Copyright (c) 2008 Münir Ozan TOPCU.All rights reserved.//
//  Author(s):
//
//      Münir Ozan TOPCU, feramor@computer.org
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and
// limitations under the License.*/
/*NCrontab
    Copyright 2008 Atif Aziz 

    This product includes software developed by
    Atif Aziz (https://github.com/atifaziz/NCrontab).*/
/* Cron Job Syntax

 # ââââââââââââââ min (0 - 59) 
 # â âââââââââââââââ hour (0 - 23)
 # â â ââââââââââââââââ day of month (1 - 31)
 # â â â âââââââââââââââââ month (1 - 12)
 # â â â â ââââââââââââââââââ day of week (0 - 6) (0 to 6 are Sunday to Saturday, or use names; 7 is Sunday, the same as 0)
 # â â â â â
 # â â â â â
 # * * * * *

*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
//Oxide
using Oxide.Core;
using Oxide.Core.Logging;
using Oxide.Core.Plugins;
using Oxide.Game.Rust;
using Oxide.Game.Rust.Cui;
using Oxide.Core.Libraries;
//UnityEngine
using UnityEngine;
//Others
using Newtonsoft.Json;
namespace Oxide.Plugins {
    [Info("Cron Library", "Feramor", "1.0.2", ResourceId = 1754)]
    [Description("Cron Job Library for Oxide.")]
    public class CronLibrary : RustPlugin {
        public static class NCrontab {
            /*
            // NCrontab - Crontab for.NET
            // Copyright (c) 2008 Atif Aziz.All rights reserved.//
            //  Author(s):
            //
            //      Atif Aziz, http://www.raboof.com
            //
            // Licensed under the Apache License, Version 2.0 (the "License");
            // you may not use this file except in compliance with the License.// You may obtain a copy of the License at
            //
            //     http://www.apache.org/licenses/LICENSE-2.0
            //
            // Unless required by applicable law or agreed to in writing, software
            // distributed under the License is distributed on an "AS IS" BASIS,
            // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and
            // limitations under the License.*/
            public delegate ExceptionProvider CrontabFieldAccumulator(int start, int end, int interval, ExceptionHandler onError);
            public delegate void ExceptionHandler(Exception e);
            public delegate Exception ExceptionProvider();
            [Serializable]
            public class CrontabException : Exception {
                public CrontabException() : base("Crontab error.") {
                }
                // TODO: Fix message and add it to resource.public CrontabException(string message) :
                base(message) {
                }
                public CrontabException(string message, Exception innerException) : base(message, innerException) {
                }
                protected CrontabException(SerializationInfo info, StreamingContext context) : base(info, context) {
                }
            }
            [Serializable]
            public sealed class CrontabField : ICrontabField {
                private readonly BitArray _bits;
                private  /* readonly */
                int _minValueSet;
                private  /* readonly */
                int _maxValueSet;
                private readonly CrontabFieldImpl _impl;
                /// <summary>
                /// Parses a crontab field expression given its kind./// </summary>
                public static CrontabField Parse(CrontabFieldKind kind, string expression) {
                    return TryParse(kind, expression, ErrorHandling.Throw).Value;
                }
                public static ValueOrError<CrontabField> TryParse(CrontabFieldKind kind, string expression) {
                    return TryParse(kind, expression, null);
                }
                public static ValueOrError<CrontabField> TryParse(CrontabFieldKind kind, string expression, ExceptionHandler onError) {
                    var field = new CrontabField(CrontabFieldImpl.FromKind(kind));
                    var error = field._impl.TryParse(expression, field.Accumulate, onError);
                    return error == null ? field : (ValueOrError<CrontabField>)error;
                }
                /// <summary>
                /// Parses a crontab field expression representing minutes./// </summary>
                public static CrontabField Minutes(string expression) {
                    return Parse(CrontabFieldKind.Minute, expression);
                }
                /// <summary>
                /// Parses a crontab field expression representing hours./// </summary>
                public static CrontabField Hours(string expression) {
                    return Parse(CrontabFieldKind.Hour, expression);
                }
                /// <summary>
                /// Parses a crontab field expression representing days in any given month./// </summary>
                public static CrontabField Days(string expression) {
                    return Parse(CrontabFieldKind.Day, expression);
                }
                /// <summary>
                /// Parses a crontab field expression representing months./// </summary>
                public static CrontabField Months(string expression) {
                    return Parse(CrontabFieldKind.Month, expression);
                }
                /// <summary>
                /// Parses a crontab field expression representing days of a week./// </summary>
                public static CrontabField DaysOfWeek(string expression) {
                    return Parse(CrontabFieldKind.DayOfWeek, expression);
                }
                private CrontabField(CrontabFieldImpl impl) {
                    if (impl == null) throw new ArgumentNullException("impl");
                    _impl = impl;
                    _bits = new BitArray(impl.ValueCount);
                    _bits.SetAll(false);
                    _minValueSet = int.MaxValue;
                    _maxValueSet = -1;
                }
                /// <summary>
                /// Gets the first value of the field or -1./// </summary>
                public int GetFirst() {
                    return _minValueSet < int.MaxValue ? _minValueSet : -1;
                }
                /// <summary>
                /// Gets the next value of the field that occurs after the given
                /// start value or -1 if there is no next value available./// </summary>
                public int Next(int start) {
                    if (start < _minValueSet) return _minValueSet;
                    var startIndex = ValueToIndex(start);
                    var lastIndex = ValueToIndex(_maxValueSet);
                    for (var i = startIndex; i <= lastIndex; i++) {
                        if (_bits[i]) return IndexToValue(i);
                    }
                    return -1;
                }
                private int IndexToValue(int index) {
                    return index + _impl.MinValue;
                }
                private int ValueToIndex(int value) {
                    return value - _impl.MinValue;
                }
                /// <summary>
                /// Determines if the given value occurs in the field./// </summary>
                public bool Contains(int value) {
                    return _bits[ValueToIndex(value)];
                }
                /// <summary>
                /// Accumulates the given range (start to end) and interval of values
                /// into the current set of the field./// </summary>
                /// <remarks>
                /// To set the entire range of values representable by the field,
                /// set <param name="start" /> and <param name="end" /> to -1 and
                /// <param name="interval" /> to 1./// </remarks>
                private ExceptionProvider Accumulate(int start, int end, int interval, ExceptionHandler onError) {
                    var minValue = _impl.MinValue;
                    var maxValue = _impl.MaxValue;
                    if (start == end) {
                        if (start < 0) {
                            //
                            // We're setting the entire range of values.//
                            if (interval <= 1) {
                                _minValueSet = minValue;
                                _maxValueSet = maxValue;
                                _bits.SetAll(true);
                                return null;
                            }
                            start = minValue;
                            end = maxValue;
                        }
                        else {
                            //
                            // We're only setting a single value - check that it is in range.//
                            if (start < minValue) return OnValueBelowMinError(start, onError);
                            if (start > maxValue) return OnValueAboveMaxError(start, onError);
                        }
                    }
                    else {
                        //
                        // For ranges, if the start is bigger than the end value then
                        // swap them over.//
                        if (start > end) {
                            end ^= start;
                            start ^= end;
                            end ^= start;
                        }
                        if (start < 0) start = minValue;
                        else if (start < minValue) return OnValueBelowMinError(start, onError);
                        if (end < 0) end = maxValue;
                        else if (end > maxValue) return OnValueAboveMaxError(end, onError);
                    }
                    if (interval < 1) interval = 1;
                    int i;
                    //
                    // Populate the _bits table by setting all the bits corresponding to
                    // the valid field values.//
                    for (i = start - minValue; i <= (end - minValue);
                    i += interval) _bits[i] = true;
                    //
                    // Make sure we remember the minimum value set so far Keep track of
                    // the highest and lowest values that have been added to this field
                    // so far.//
                    if (_minValueSet > start) _minValueSet = start;
                    i += (minValue - interval);
                    if (_maxValueSet < i) _maxValueSet = i;
                    return null;
                }
                private ExceptionProvider OnValueAboveMaxError(int value, ExceptionHandler onError) {
                    return ErrorHandling.OnError(() => new CrontabException(string.Format("{0} is higher than the maximum allowable value for the [{3}] field.Value must be between {1} and {2} (all inclusive).", value, _impl.MinValue, _impl.MaxValue, _impl.Kind)), onError);
                }
                private ExceptionProvider OnValueBelowMinError(int value, ExceptionHandler onError) {
                    return ErrorHandling.OnError(() => new CrontabException(string.Format("{0} is lower than the minimum allowable value for the [{3}] field.Value must be between {1} and {2} (all inclusive).", value, _impl.MinValue, _impl.MaxValue, _impl.Kind)), onError);
                }
                public override string ToString() {
                    return ToString(null);
                }
                public string ToString(string format) {
                    var writer = new StringWriter(CultureInfo.InvariantCulture);
                    switch (format) {
                        case "G" : case null : Format(writer, true);
                        break;
                        case "N" : Format(writer);
                        break;
                        default : throw new FormatException();
                    }
                    return writer.ToString();
                }
                public void Format(TextWriter writer) {
                    Format(writer, false);
                }
                public void Format(TextWriter writer, bool noNames) {
                    _impl.Format(this, writer, noNames);
                }
            }
            [Serializable]
            public sealed class CrontabFieldImpl : IObjectReference {
                public static readonly CrontabFieldImpl Minute = new CrontabFieldImpl(CrontabFieldKind.Minute, 0, 59, null);
                public static readonly CrontabFieldImpl Hour = new CrontabFieldImpl(CrontabFieldKind.Hour, 0, 23, null);
                public static readonly CrontabFieldImpl Day = new CrontabFieldImpl(CrontabFieldKind.Day, 1, 31, null);
                public static readonly CrontabFieldImpl Month = new CrontabFieldImpl(CrontabFieldKind.Month, 1, 12, new[] {
                    "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
                }
                );
                public static readonly CrontabFieldImpl DayOfWeek = new CrontabFieldImpl(CrontabFieldKind.DayOfWeek, 0, 6, new[] {
                    "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
                }
                );
                private static readonly CrontabFieldImpl[] _fieldByKind = new[] {
                    Minute, Hour, Day, Month, DayOfWeek
                }
                ;
                private static readonly CompareInfo _comparer = CultureInfo.InvariantCulture.CompareInfo;
                private static readonly char[] _comma = new[] {
                    ','
                }
                ;
                private readonly CrontabFieldKind _kind;
                private readonly int _minValue;
                private readonly int _maxValue;
                private readonly string[] _names;
                public static CrontabFieldImpl FromKind(CrontabFieldKind kind) {
                    if (!Enum.IsDefined(typeof(CrontabFieldKind), kind)) {
                        throw new ArgumentException(string.Format("Invalid crontab field kind.Valid values are {0}.", string.Join(", ", Enum.GetNames(typeof(CrontabFieldKind)))), "kind");
                    }
                    return _fieldByKind[(int)kind];
                }
                private CrontabFieldImpl(CrontabFieldKind kind, int minValue, int maxValue, string[] names) {
                    UnityEngine.Debug.Assert(Enum.IsDefined(typeof(CrontabFieldKind), kind));
                    UnityEngine.Debug.Assert(minValue >= 0);
                    UnityEngine.Debug.Assert(maxValue >= minValue);
                    UnityEngine.Debug.Assert(names == null || names.Length == (maxValue - minValue + 1));
                    _kind = kind;
                    _minValue = minValue;
                    _maxValue = maxValue;
                    _names = names;
                }
                public CrontabFieldKind Kind {
                    get {
                        return _kind;
                    }
                }
                public int MinValue {
                    get {
                        return _minValue;
                    }
                }
                public int MaxValue {
                    get {
                        return _maxValue;
                    }
                }
                public int ValueCount {
                    get {
                        return _maxValue - _minValue + 1;
                    }
                }
                public void Format(ICrontabField field, TextWriter writer) {
                    Format(field, writer, false);
                }
                public void Format(ICrontabField field, TextWriter writer, bool noNames) {
                    if (field == null) throw new ArgumentNullException("field");
                    if (writer == null) throw new ArgumentNullException("writer");
                    var next = field.GetFirst();
                    var count = 0;
                    while (next != -1) {
                        var first = next;
                        int last;
                        do {
                            last = next;
                            next = field.Next(last + 1);
                        }
                        while (next - last == 1);
                        if (count == 0 && first == _minValue && last == _maxValue) {
                            writer.Write('*');
                            return;
                        }
                        if (count > 0) writer.Write(',');
                        if (first == last) {
                            FormatValue(first, writer, noNames);
                        }
                        else {
                            FormatValue(first, writer, noNames);
                            writer.Write('-');
                            FormatValue(last, writer, noNames);
                        }
                        count++;
                    }
                }
                private void FormatValue(int value, TextWriter writer, bool noNames) {
                    UnityEngine.Debug.Assert(writer != null);
                    if (noNames || _names == null) {
                        if (value >= 0 && value < 100) {
                            FastFormatNumericValue(value, writer);
                        }
                        else {
                            writer.Write(value.ToString(CultureInfo.InvariantCulture));
                        }
                    }
                    else {
                        var index = value - _minValue;
                        writer.Write(_names[index]);
                    }
                }
                private static void FastFormatNumericValue(int value, TextWriter writer) {
                    UnityEngine.Debug.Assert(value >= 0 && value < 100);
                    UnityEngine.Debug.Assert(writer != null);
                    if (value >= 10) {
                        writer.Write((char)('0' + (value / 10)));
                        writer.Write((char)('0' + (value % 10)));
                    }
                    else {
                        writer.Write((char)('0' + value));
                    }
                }
                public void Parse(string str, CrontabFieldAccumulator acc) {
                    TryParse(str, acc, ErrorHandling.Throw);
                }
                public ExceptionProvider TryParse(string str, CrontabFieldAccumulator acc, ExceptionHandler onError) {
                    if (acc == null) throw new ArgumentNullException("acc");
                    if (string.IsNullOrEmpty(str)) return null;
                    try {
                        return InternalParse(str, acc, onError);
                    }
                    catch (FormatException e) {
                        return OnParseException(e, str, onError);
                    }
                    catch (CrontabException e) {
                        return OnParseException(e, str, onError);
                    }
                }
                private ExceptionProvider OnParseException(Exception innerException, string str, ExceptionHandler onError) {
                    UnityEngine.Debug.Assert(str != null);
                    UnityEngine.Debug.Assert(innerException != null);
                    return ErrorHandling.OnError(() => new CrontabException(string.Format("'{0}' is not a valid [{1}] crontab field expression.", str, Kind), innerException), onError);
                }
                private ExceptionProvider InternalParse(string str, CrontabFieldAccumulator acc, ExceptionHandler onError) {
                    UnityEngine.Debug.Assert(str != null);
                    UnityEngine.Debug.Assert(acc != null);
                    if (str.Length == 0) return ErrorHandling.OnError(() => new CrontabException("A crontab field value cannot be empty."), onError);
                    //
                    // Next, look for a list of values (e.g.1,2,3).//
                    var commaIndex = str.IndexOf(",");
                    if (commaIndex > 0) {
                        ExceptionProvider e = null;
                        var token = ((IEnumerable<string>)str.Split(_comma)).GetEnumerator();
                        while (token.MoveNext() && e == null) e = InternalParse(token.Current, acc, onError);
                        return e;
                    }
                    var every = 1;
                    //
                    // Look for stepping first (e.g.*/2 = every 2nd).//
                    var slashIndex = str.IndexOf("/");
                    if (slashIndex > 0) {
                        every = int.Parse(str.Substring(slashIndex + 1), CultureInfo.InvariantCulture);
                        str = str.Substring(0, slashIndex);
                    }
                    //
                    // Next, look for wildcard (*).//
                    if (str.Length == 1 && str[0] == '*') {
                        return acc(-1, -1, every, onError);
                    }
                    //
                    // Next, look for a range of values (e.g.2-10).//
                    var dashIndex = str.IndexOf("-");
                    if (dashIndex > 0) {
                        var first = ParseValue(str.Substring(0, dashIndex));
                        var last = ParseValue(str.Substring(dashIndex + 1));
                        return acc(first, last, every, onError);
                    }
                    //
                    // Finally, handle the case where there is only one number.//
                    var value = ParseValue(str);
                    if (every == 1) return acc(value, value, 1, onError);
                    UnityEngine.Debug.Assert(every != 0);
                    return acc(value, _maxValue, every, onError);
                }
                private int ParseValue(string str) {
                    UnityEngine.Debug.Assert(str != null);
                    if (str.Length == 0) throw new CrontabException("A crontab field value cannot be empty.");
                    var firstChar = str[0];
                    if (firstChar >= '0' && firstChar <= '9') return int.Parse(str, CultureInfo.InvariantCulture);
                    if (_names == null) {
                        throw new CrontabException(string.Format("'{0}' is not a valid [{3}] crontab field value.It must be a numeric value between {1} and {2} (all inclusive).", str, _minValue.ToString(), _maxValue.ToString(), _kind.ToString()));
                    }
                    for (var i = 0; i < _names.Length; i++) {
                        if (_comparer.IsPrefix(_names[i], str, CompareOptions.IgnoreCase)) return i + _minValue;
                    }
                    throw new CrontabException(string.Format("'{0}' is not a known value name.Use one of the following: {1}.", str, string.Join(", ", _names)));
                }
                object IObjectReference.GetRealObject(StreamingContext context) {
                    return FromKind(Kind);
                }
            }
            [Serializable]
            public enum CrontabFieldKind {
                Minute = 0,  // Keep in order of appearance in expression
                Hour, Day, Month, DayOfWeek
            }
            [Serializable]
            public sealed class CrontabSchedule {
                private readonly CrontabField _minutes;
                private readonly CrontabField _hours;
                private readonly CrontabField _days;
                private readonly CrontabField _months;
                private readonly CrontabField _daysOfWeek;
                private static readonly char[] _separators = new[] {
                    ' '
                }
                ;
                //
                // Crontab expression format:
                //
                // * * * * *
                // - - - - -
                // | | | | |
                // | | | | +----- day of week (0 - 6) (Sunday=0)
                // | | | +------- month (1 - 12)
                // | | +--------- day of month (1 - 31)
                // | +----------- hour (0 - 23)
                // +------------- min (0 - 59)
                //
                // Star (*) in the value field above means all legal values as in
                // braces for that column.The value column can have a * or a list
                // of elements separated by commas.An element is either a number in
                // the ranges shown above or two numbers in the range separated by a
                // hyphen (meaning an inclusive range).//
                // Source: http://www.adminschoice.com/docs/crontab.htm
                //
                public static CrontabSchedule Parse(string expression) {
                    return TryParse(expression, ErrorHandling.Throw).Value;
                }
                public static ValueOrError<CrontabSchedule> TryParse(string expression) {
                    return TryParse(expression, null);
                }
                private static ValueOrError<CrontabSchedule> TryParse(string expression, ExceptionHandler onError) {
                    if (expression == null) throw new ArgumentNullException("expression");
                    var tokens = expression.Split(_separators, StringSplitOptions.RemoveEmptyEntries);
                    if (tokens.Length != 5) {
                        return ErrorHandling.OnError(() => new CrontabException(string.Format("'{0}' is not a valid crontab expression.It must contain at least 5 components of a schedule " + "(in the sequence of minutes, hours, days, months, days of week).", expression)), onError);
                    }
                    var fields = new CrontabField[5];
                    for (var i = 0; i < fields.Length; i++) {
                        var field = CrontabField.TryParse((CrontabFieldKind)i, tokens[i], onError);
                        if (field.IsError) return field.ErrorProvider;
                        fields[i] = field.Value;
                    }
                    return new CrontabSchedule(fields[0], fields[1], fields[2], fields[3], fields[4]);
                }
                private CrontabSchedule(CrontabField minutes, CrontabField hours, CrontabField days, CrontabField months, CrontabField daysOfWeek) {
                    UnityEngine.Debug.Assert(minutes != null);
                    UnityEngine.Debug.Assert(hours != null);
                    UnityEngine.Debug.Assert(days != null);
                    UnityEngine.Debug.Assert(months != null);
                    UnityEngine.Debug.Assert(daysOfWeek != null);
                    _minutes = minutes;
                    _hours = hours;
                    _days = days;
                    _months = months;
                    _daysOfWeek = daysOfWeek;
                }
                /// <summary>
                /// Enumerates all the occurrences of this schedule starting with a
                /// base time and up to an end time limit.This method uses deferred
                /// execution such that the occurrences are only calculated as they
                /// are enumerated./// </summary>
                /// <remarks>
                /// This method does not return the value of <paramref name="baseTime"/>
                /// itself if it falls on the schedule.For example, if <paramref name="baseTime" />
                /// is midnight and the schedule was created from the expression <c>* * * * *</c>
                /// (meaning every minute) then the next occurrence of the schedule
                /// will be at one minute past midnight and not midnight itself./// The method returns the <em>next</em> occurrence <em>after</em>
                /// <paramref name="baseTime"/>.Also, <param name="endTime" /> is
                /// exclusive./// </remarks>
                public IEnumerable<DateTime> GetNextOccurrences(DateTime baseTime, DateTime endTime) {
                    for (var occurrence = GetNextOccurrence(baseTime, endTime);
                    occurrence < endTime;
                    occurrence = GetNextOccurrence(occurrence, endTime)) {
                        yield return occurrence;
                    }
                }
                /// <summary>
                /// Gets the next occurrence of this schedule starting with a base time./// </summary>
                public DateTime GetNextOccurrence(DateTime baseTime) {
                    return GetNextOccurrence(baseTime, DateTime.MaxValue);
                }
                /// <summary>
                /// Gets the next occurrence of this schedule starting with a base
                /// time and up to an end time limit./// </summary>
                /// <remarks>
                /// This method does not return the value of <paramref name="baseTime"/>
                /// itself if it falls on the schedule.For example, if <paramref name="baseTime" />
                /// is midnight and the schedule was created from the expression <c>* * * * *</c>
                /// (meaning every minute) then the next occurrence of the schedule
                /// will be at one minute past midnight and not midnight itself./// The method returns the <em>next</em> occurrence <em>after</em>
                /// <paramref name="baseTime"/>.Also, <param name="endTime" /> is
                /// exclusive./// </remarks>
                public DateTime GetNextOccurrence(DateTime baseTime, DateTime endTime) {
                    const int nil = -1;
                    var baseYear = baseTime.Year;
                    var baseMonth = baseTime.Month;
                    var baseDay = baseTime.Day;
                    var baseHour = baseTime.Hour;
                    var baseMinute = baseTime.Minute;
                    var endYear = endTime.Year;
                    var endMonth = endTime.Month;
                    var endDay = endTime.Day;
                    var year = baseYear;
                    var month = baseMonth;
                    var day = baseDay;
                    var hour = baseHour;
                    var minute = baseMinute + 1;
                    //
                    // Minute
                    //
                    minute = _minutes.Next(minute);
                    if (minute == nil) {
                        minute = _minutes.GetFirst();
                        hour++;
                    }
                    //
                    // Hour
                    //
                    hour = _hours.Next(hour);
                    if (hour == nil) {
                        minute = _minutes.GetFirst();
                        hour = _hours.GetFirst();
                        day++;
                    }
                    else if (hour > baseHour) {
                        minute = _minutes.GetFirst();
                    }
                    //
                    // Day
                    //
                    day = _days.Next(day);
                    RetryDayMonth : if (day == nil) {
                        minute = _minutes.GetFirst();
                        hour = _hours.GetFirst();
                        day = _days.GetFirst();
                        month++;
                    }
                    else if (day > baseDay) {
                        minute = _minutes.GetFirst();
                        hour = _hours.GetFirst();
                    }
                    //
                    // Month
                    //
                    month = _months.Next(month);
                    if (month == nil) {
                        minute = _minutes.GetFirst();
                        hour = _hours.GetFirst();
                        day = _days.GetFirst();
                        month = _months.GetFirst();
                        year++;
                    }
                    else if (month > baseMonth) {
                        minute = _minutes.GetFirst();
                        hour = _hours.GetFirst();
                        day = _days.GetFirst();
                    }
                    //
                    // The day field in a cron expression spans the entire range of days
                    // in a month, which is from 1 to 31.However, the number of days in
                    // a month tend to be variable depending on the month (and the year
                    // in case of February).So a check is needed here to see if the
                    // date is a border case.If the day happens to be beyond 28
                    // (meaning that we're dealing with the suspicious range of 29-31)
                    // and the date part has changed then we need to determine whether
                    // the day still makes sense for the given year and month.If the
                    // day is beyond the last possible value, then the day/month part
                    // for the schedule is re-evaluated.So an expression like "0 0
                    // 15,31 * *" will yield the following sequence starting on midnight
                    // of Jan 1, 2000:
                    //
                    //  Jan 15, Jan 31, Feb 15, Mar 15, Apr 15, Apr 31,...//
                    var dateChanged = day != baseDay || month != baseMonth || year != baseYear;
                    if (day > 28 && dateChanged && day > Calendar.GetDaysInMonth(year, month)) {
                        if (year >= endYear && month >= endMonth && day >= endDay) return endTime;
                        day = nil;
                        goto RetryDayMonth;
                    }
                    var nextTime = new DateTime(year, month, day, hour, minute, 0, 0, baseTime.Kind);
                    if (nextTime >= endTime) return endTime;
                    //
                    // Day of week
                    //
                    if (_daysOfWeek.Contains((int)nextTime.DayOfWeek)) return nextTime;
                    return GetNextOccurrence(new DateTime(year, month, day, 23, 59, 0, 0, baseTime.Kind), endTime);
                }
                /// <summary>
                /// Returns a string in crontab expression (expanded) that represents
                /// this schedule./// </summary>
                public override string ToString() {
                    var writer = new StringWriter(CultureInfo.InvariantCulture);
                    _minutes.Format(writer, true);
                    writer.Write(' ');
                    _hours.Format(writer, true);
                    writer.Write(' ');
                    _days.Format(writer, true);
                    writer.Write(' ');
                    _months.Format(writer, true);
                    writer.Write(' ');
                    _daysOfWeek.Format(writer, true);
                    return writer.ToString();
                }
                private static Calendar Calendar {
                    get {
                        return CultureInfo.InvariantCulture.Calendar;
                    }
                }
            }
            internal static class ErrorHandling {
                /// <summary>
                /// A stock <see cref="ExceptionHandler"/> that throws./// </summary>
                public static readonly ExceptionHandler Throw = e => {
                    throw e;
                }
                ;
                internal static ExceptionProvider OnError(ExceptionProvider provider, ExceptionHandler handler) {
                    UnityEngine.Debug.Assert(provider != null);
                    if (handler != null) handler(provider());
                    return provider;
                }
            }
            public interface ICrontabField {
                int GetFirst();
                int Next(int start);
                bool Contains(int value);
            }
            [Serializable]
            public struct ValueOrError<T> {
                private readonly bool _hasValue;
                private readonly T _value;
                private readonly ExceptionProvider _ep;
                private static readonly ExceptionProvider _dep = () => new Exception("Value is undefined.");
                /// <summary>
                /// Initializes the object with a defined value./// </summary>
                public ValueOrError(T value) : this() {
                    _hasValue = true;
                    _value = value;
                }
                /// <summary>
                /// Initializes the object with an error./// </summary>
                public ValueOrError(Exception error) : this(CheckError(error)) {
                }
                private static ExceptionProvider CheckError(Exception error) {
                    if (error == null) throw new ArgumentNullException("error");
                    return () => error;
                }
                /// <summary>
                /// Initializes the object with a handler that will provide
                /// the error result when needed./// </summary>
                public ValueOrError(ExceptionProvider provider) : this() {
                    if (provider == null) throw new ArgumentNullException("provider");
                    _ep = provider;
                }
                /// <summary>
                /// Determines if object holds a defined value or not./// </summary>
                public bool HasValue {
                    get {
                        return _hasValue;
                    }
                }
                /// <summary>
                /// Gets the value otherwise throws an error if undefined./// </summary>
                public T Value {
                    get {
                        if (!HasValue) throw ErrorProvider();
                        return _value;
                    }
                }
                /// <summary>
                /// Determines if object identifies an error condition or not./// </summary>
                public bool IsError {
                    get {
                        return ErrorProvider != null;
                    }
                }
                /// <summary>
                /// Gets the <see cref="Exception"/> object if this object
                /// represents an error condition otherwise it returns <c>null</c>./// </summary>
                public Exception Error {
                    get {
                        return IsError ? ErrorProvider() : null;
                    }
                }
                /// <summary>
                /// Gets the <see cref="ExceptionProvider"/> object if this
                /// object represents an error condition otherwise it returns <c>null</c>./// </summary>
                public ExceptionProvider ErrorProvider {
                    get {
                        return HasValue ? null : _ep ?? _dep;
                    }
                }
                /// <summary>
                /// Attempts to get the defined value or another in case
                /// of an error./// </summary>
                public T TryGetValue(T errorValue) {
                    return IsError ? errorValue : Value;
                }
                /// <summary>
                /// Implicitly converts a <typeparamref name="T"/> value to
                /// an object of this type./// </summary>
                public static implicit operator ValueOrError<T>(T value) {
                    return new ValueOrError<T>(value);
                }
                /// <summary>
                /// Implicitly converts an <see cref="Exception"/> object to
                /// an object of this type that represents the error condition./// </summary>
                public static implicit operator ValueOrError<T>(Exception error) {
                    return new ValueOrError<T>(error);
                }
                /// <summary>
                /// Implicitly converts an <see cref="ExceptionProvider"/> object to
                /// an object of this type that represents the error condition./// </summary>
                public static implicit operator ValueOrError<T>(ExceptionProvider provider) {
                    return new ValueOrError<T>(provider);
                }
                /// <summary>
                /// Explicits converts this object to a <typeparamref name="T"/> value./// </summary>
                public static explicit operator T(ValueOrError<T> ve) {
                    return ve.Value;
                }
                /// <summary>
                /// Explicits converts this object to an <see cref="Exception"/> object
                /// if it represents an error condition.The conversion yields <c>null</c>
                /// if this object does not represent an error condition./// </summary>
                public static explicit operator Exception(ValueOrError<T> ve) {
                    return ve.Error;
                }
                /// <summary>
                /// Explicits converts this object to an <see cref="ExceptionProvider"/> object
                /// if it represents an error condition.The conversion yields <c>null</c>
                /// if this object does not represent an error condition./// </summary>
                public static explicit operator ExceptionProvider(ValueOrError<T> ve) {
                    return ve.ErrorProvider;
                }
                public override string ToString() {
                    var error = Error;
                    return IsError ? error.GetType().FullName + ": " + error.Message : _value != null ? _value.ToString() : string.Empty;
                }
            }
        }
        private static Core.Logging.Logger RootLogger = Interface.GetMod().RootLogger;
        private Dictionary<Plugin, List<Timer>> TimerList = new Dictionary<Plugin, List<Timer>>();
        void Loaded() {
            Manager.OnPluginRemoved += OnPluginRemovedControlCrons;
            TimerList.Add(this, new List<Timer> {
                timer.Repeat(60, 0, new Action(() => {
                    foreach (KeyValuePair<Plugin, List<Timer>> Current in TimerList) {
                        if ((Current.Key == null) || (!Current.Key.IsLoaded)) {
                            Current.Value.FindAll(e => e.Destroyed == false).ForEach(e => e.Destroy());
                        }
                        Current.Value.RemoveAll(e => e.Destroyed);
                    }
                }
                ))
            }
            );
        }
        void Unload() {
            Manager.OnPluginRemoved -= OnPluginRemovedControlCrons;
        }
        bool RegisterCron(Plugin Owner, bool UseUTC, string CronSyntax, Action Function) {
            Action RunAction = new Action(() => {
                try {
                    if ((Owner != null) && (Owner.IsLoaded)) {
                        Function();
                        RegisterCron(Owner, UseUTC, CronSyntax, Function);
                    }
                }
                catch (Exception Ex) {
                    RootLogger.Write(Core.Logging.LogType.Error, "[Cron Library] {0}", Ex.Message);
                }
            }
            );
            try {
                if (!TimerList.ContainsKey(Owner)) TimerList.Add(Owner, new List<Timer>());
                List<Timer> Current;
                if (TimerList.TryGetValue(Owner, out Current)) {
                    DateTime BaseTime = (UseUTC) ? DateTime.UtcNow : DateTime.Now;
                    DateTime NextRun = NCrontab.CrontabSchedule.Parse(CronSyntax).GetNextOccurrence(BaseTime);
                    DateTime UTCTime = (UseUTC) ? NextRun : TimeZone.CurrentTimeZone.ToUniversalTime(NextRun);
                    DateTime UserTime = (UseUTC) ? TimeZone.CurrentTimeZone.ToLocalTime(NextRun) : NextRun;
                    RootLogger.Write(Core.Logging.LogType.Debug, "[Cron Library] {0} added new cron with {1}\n\t***Next Run***\n\tUTC\t: {2} UTC\n\tLocal\t: {3} {4}", Owner.Name, CronSyntax, UTCTime.ToString("ddd, dd MMM yyyy HH':'mm':'ss"), UserTime.ToString("ddd, dd MMM yyyy HH':'mm':'ss"), (TimeZone.CurrentTimeZone.IsDaylightSavingTime(UserTime) ? TimeZone.CurrentTimeZone.DaylightName : TimeZone.CurrentTimeZone.StandardName));
                    TimeSpan NextTimeSpan = NextRun - ((UseUTC) ? DateTime.UtcNow : DateTime.Now);
                    double TimeLeft = NextTimeSpan.TotalSeconds;
                    if (TimeLeft - Math.Round(TimeLeft) != 0) TimeLeft++;
                    Current.Add((timer.Once((int)TimeLeft, RunAction)));
                    return true;
                }
                else return false;
            }
            catch (Exception Ex) {
                RootLogger.Write(Core.Logging.LogType.Error, "[Cron Library] {0}", Ex.Message);
                return false;
            }
        }
        object GetNextOccurrence(bool UseUTC, string CronSyntax, bool IsString = true) {
            DateTime BaseTime = (UseUTC) ? DateTime.UtcNow : DateTime.Now;
            if (IsString) return NCrontab.CrontabSchedule.Parse(CronSyntax).GetNextOccurrence(BaseTime).ToString("ddd, dd MMM yyyy HH':'mm':'ss");
            else return NCrontab.CrontabSchedule.Parse(CronSyntax).GetNextOccurrence(BaseTime);
        }
        private void OnPluginRemovedControlCrons(Plugin plugin) {
            if (TimerList.ContainsKey(plugin)) {
                int RemovedCrons = 0;
                foreach (KeyValuePair<Plugin, List<Timer>> Current in TimerList) {
                    Current.Value.FindAll(e => e.Destroyed == false).ForEach(e => e.Destroy());
                    RemovedCrons += Current.Value.RemoveAll(e => e.Destroyed);
                }
                TimerList.Remove(plugin);
                RootLogger.Write(Core.Logging.LogType.Warning, "[Cron Library] Plugin {0} unloaded.Removed {1} cron jobs.", plugin.Name, RemovedCrons);
            }
        }
    }
}

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху