[转].net仿传奇机器人配置文件

调用方法:

 /*
假设有以下配置内容:

;机器人配置文件
;重要文件
;SEC:按秒运行
;MIN:按分运行
;HOUR:按小时运行
;DAY:按天运行
;RunOnDay:按每天什么时候运行
;RunOnWeek:按星期几及时间运行
;Name RunOnWeek 5:15:55:59 Method Class,DLL
;星期五15点55分59秒运行 method 方法

;aaa每天10点事件
aaa_10_hour_event RunOnDay 10:00:00 静态方法名 类名,程序集名
;bbb服务每天10点事件
aaa_10_hour_event RunOnDay 10:00:00 静态方法名 类名,程序集名
;ccc服务每天10点事件
aaa_10_hour_event RunOnDay 10:00:00 静态方法名 类名,所在程序集名

;定时运行某程序集下某类的某静态方法

*/

public void init() {
    Robot robot = new Robot(@"c:\robot.txt");
    robot.Error += this.robot_OnError;
    robot.Start();
}

public void robot_OnError(object sender, RobotErrorEventArgs e) {
    _log.Fatal(e.Def, e.Exception);
}

 

此功能很早就完成了,现在放出来,其实作用不是太大,感觉好玩,呵呵!
注:此代码应用在几个项目中稳定运行了两年有余。
完整源代码如下: 
 

 

 using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Timers;
using System.Xml;

/// <summary>
/// 机器人,自动运行库
/// </summary>
public class Robot : IDisposable {

    
private string _def_path;
    
private List<RobotDef> _robots;
    
private object _robots_lock = new object();
    
private FileSystemWatcher _defWatcher;
    
public event RobotErrorHandler Error;

    
public Robot()
        : 
this(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"robot.txt")) {
    }
    
public Robot(string path) {
        _def_path 
= path;
    }

    
public void Start() {
        Stop();
        
if (!File.Exists(_def_path)) return;
        
lock (_robots_lock) {
            _robots 
= LoadDef();
            
foreach (RobotDef bot in _robots) {
                bot.RunNow();
            }
        }
        
if (_defWatcher == null) {
            _defWatcher 
= new FileSystemWatcher(Path.GetDirectoryName(_def_path), Path.GetFileName(_def_path));
            _defWatcher.Changed 
+= delegate(object sender, FileSystemEventArgs e) {
                _defWatcher.EnableRaisingEvents 
= false;
                
if (_robots.Count > 0) {
                    Start();
                }
                _defWatcher.EnableRaisingEvents 
= true;
            };
            _defWatcher.EnableRaisingEvents 
= true;
        }
    }
    
public void Stop() {
        
lock (_robots_lock) {
            
if (_robots != null) {
                
for (int a = 0; a < _robots.Count; a++) {
                    _robots[a].Dispose();
                }
                _robots.Clear();
            }
        }
    }

    
#region IDisposable 成员

    
public void Dispose() {
        
if (_defWatcher != null) {
            _defWatcher.Dispose();
        }
        Stop();
    }

    
#endregion

    
public List<RobotDef> LoadDef() {
        
string defDoc = Encoding.Default.GetString(readFile(_def_path));
        
return LoadDef(defDoc);
    }
    
public List<RobotDef> LoadDef(string defDoc) {
        Dictionary
<string, RobotDef> dic = new Dictionary<string, RobotDef>();
        
string[] defs = defDoc.Split(new string[] { "\r\n" }, StringSplitOptions.None);
        
int row = 1;
        
foreach (string def in defs) {
            
string loc1 = def.Trim();
            
if (string.IsNullOrEmpty(loc1) || loc1[0== ';'continue;
            
string pattern = @"([^\s]+)\s+(NONE|SEC|MIN|HOUR|DAY|RunOnDay|RunOnWeek)\s+([^\s]+)\s+([^\s]+)\s+([^\s,]+),\s*([^\s]+)";
            Match m 
= Regex.Match(loc1, pattern, RegexOptions.IgnoreCase);
            
if (!m.Success) {
                onError(
new Exception("Robot配置错误“" + loc1 + "”, 第" + row + ""));
                
continue;
            }
            RobotDef rd 
= new RobotDef(this);
            rd._name 
= m.Groups[1].Value;
            rd._mode 
= getMode(m.Groups[2].Value);
            rd._parm 
= m.Groups[3].Value;
            rd._method 
= m.Groups[4].Value;
            rd._assemblyName 
= m.Groups[5].Value + "," + m.Groups[6].Value;
            
if (rd.Mode == RobotRunMode.NONE) continue;
            
if (dic.ContainsKey(rd._name)) {
                onError(
new Exception("Robot配置存在重复的名字“" + rd._name + "”, 第" + row + ""));
                
continue;
            }
            
if (rd.Interval < 0) {
                onError(
new Exception("Robot配置参数错误“" + def + "”, 第" + row + ""));
                
continue;
            }
            dic.Add(rd.Name, rd);
            row
++;
        }
        List
<RobotDef> rds = new List<RobotDef>();
        
foreach (RobotDef rd in dic.Values) {
            rds.Add(rd);
        }
        
return rds;
    }

    
private void onError(Exception ex) {
        onError(ex, 
null);
    }
    
internal void onError(Exception ex, RobotDef def) {
        
if (Error != null) {
            RobotErrorEventArgs e 
= new RobotErrorEventArgs(ex, def);
            Error(
this, e);
        }
    }
    
private byte[] readFile(string path) {
        
if (File.Exists(path)) {
            
string destFileName = Path.GetTempFileName();
            File.Copy(path, destFileName, 
true);
            
int read = 0;
            
byte[] data = new byte[1024];
            MemoryStream ms 
= new MemoryStream();
            
using (FileStream fs = new FileStream(destFileName, FileMode.OpenOrCreate, FileAccess.Read)) {
                
do {
                    read 
= fs.Read(data, 0, data.Length);
                    
if (read <= 0break;
                    ms.Write(data, 
0, read);
                } 
while (true);
                fs.Close();
            }
            File.Delete(destFileName);
            data 
= ms.ToArray();
            ms.Close();
            
return data;
        }
        
return new byte[] { };
    }
    
private RobotRunMode getMode(string mode) {
        mode 
= string.Concat(mode).ToUpper().Trim();
        
switch (mode) {
            
case "SEC"return RobotRunMode.SEC;
            
case "MIN"return RobotRunMode.MIN;
            
case "HOUR"return RobotRunMode.HOUR;
            
case "DAY"return RobotRunMode.DAY;
            
case "RUNONDAY"return RobotRunMode.RunOnDay;
            
case "RUNONWEEK"return RobotRunMode.RunOnWeek;
            
defaultreturn RobotRunMode.NONE;
        }
    }
}

public class RobotDef : IDisposable {
    
internal string _name;
    
internal RobotRunMode _mode = RobotRunMode.NONE;
    
internal string _parm;
    
internal string _method;
    
internal string _assemblyName;

    
private Robot _onwer;
    
private Timer _timer;

    
public RobotDef(Robot onwer) {
        _onwer 
= onwer;
    }

    
public void RunNow() {
        
if (_timer == null) {
            _timer 
= new Timer();
            _timer.AutoReset 
= false;
            _timer.Elapsed 
+= delegate(object sender, System.Timers.ElapsedEventArgs e) {
                
try {
                    Type type 
= Type.GetType(_assemblyName, true);
                    
if (type != null) {
                        type.InvokeMember(_method, BindingFlags.InvokeMethod, 
nullnullnew object[] { this });
                        RunNow();
                    }
                } 
catch (Exception ex) {
                    _onwer.onError(ex, 
this);
                }
            };
        }
        
if (_timer != null) {
            _timer.Stop();
            _timer.Interval 
= Interval;
            _timer.Start();
        }
    }

    
public override string ToString() {
        
return Name + "" + Mode + "" + Parm + "" + Method + "" + AssemblyName + "" + Interval;
    }

    
#region IDisposable 成员

    
public void Dispose() {
        
if (_timer != null) {
            _timer.Stop();
            _timer.Close();
            _timer.Dispose();
        }
    }

    
#endregion

    
public string Name {
        
get { return _name; }
    }
    
public RobotRunMode Mode {
        
get { return _mode; }
    }
    
public string Parm {
        
get { return _parm; }
    }
    
public string Method {
        
get { return _method; }
    }
    
public string AssemblyName {
        
get { return _assemblyName; }
    }
    
public double Interval {
        
get {
            DateTime now 
= DateTime.Now;
            
double interval = -1;
            
switch (_mode) {
                
case RobotRunMode.SEC:
                    
double.TryParse(_parm, out interval);
                    interval 
*= 1000;
                    
break;
                
case RobotRunMode.MIN:
                    
double.TryParse(_parm, out interval);
                    interval 
*= 60 * 1000;
                    
break;
                
case RobotRunMode.HOUR:
                    
double.TryParse(_parm, out interval);
                    interval 
*= 60 * 60 * 1000;
                    
break;
                
case RobotRunMode.DAY:
                    
double.TryParse(_parm, out interval);
                    interval 
*= 24 * 60 * 60 * 1000;
                    
break;
                
case RobotRunMode.RunOnDay:
                    
string[] hhmmss = string.Concat(_parm).Split(':');
                    
if (hhmmss.Length == 3) {
                        
int hh, mm, ss;
                        
if (int.TryParse(hhmmss[0], out hh) && hh >= 0 && hh < 24 &&
                            
int.TryParse(hhmmss[1], out mm) && mm >= 0 && mm < 60 &&
                            
int.TryParse(hhmmss[2], out ss) && ss >= 0 && ss < 60) {
                            DateTime curt 
= now.Date.AddHours(hh).AddMinutes(mm).AddSeconds(ss);
                            TimeSpan ts 
= curt - now;
                            
if (ts.TotalSeconds > 0) {
                                interval 
= ts.TotalSeconds * 1000;
                            } 
else {
                                curt 
= curt.AddDays(1);
                                ts 
= curt - now;
                                interval 
= ts.TotalSeconds * 1000;
                            }
                        }
                    }
                    
break;
                
case RobotRunMode.RunOnWeek:
                    
string[] wwhhmmss = string.Concat(_parm).Split(':');
                    
if (wwhhmmss.Length == 4) {
                        
int ww, hh, mm, ss;
                        
if (int.TryParse(wwhhmmss[0], out ww) && ww >= 0 && ww < 7 &&
                            
int.TryParse(wwhhmmss[1], out hh) && hh >= 0 && hh < 24 &&
                            
int.TryParse(wwhhmmss[2], out mm) && mm >= 0 && mm < 60 &&
                            
int.TryParse(wwhhmmss[3], out ss) && ss >= 0 && ss < 60) {
                            DateTime curt 
= now.Date.AddHours(hh).AddMinutes(mm).AddSeconds(ss);
                            TimeSpan ts 
= curt - now;
                            
if (ts.TotalSeconds > 0) {
                                interval 
= ts.TotalSeconds * 1000;
                            } 
else {
                                
do {
                                    curt 
= curt.AddDays(1);
                                } 
while ((int)curt.DayOfWeek != ww);
                                ts 
= curt - now;
                                interval 
= ts.TotalSeconds * 1000;
                            }
                        }
                    }
                    
break;
            }
            
if (interval == 0) interval = 1;
            
return interval;
        }
    }
}
/*
;SEC:按秒运行
;MIN:按分运行
;HOUR:按小时运行
;DAY:按天运行
;RunOnDay:按每天什么时候运行
;RUNONWEEK:按星期几及时间运行
Name RunOnWeek 5:15:55:59 Run10Hour Asian,Server.Common
;星期五15点55分59秒运行 method 方法
*/
public enum RobotRunMode {
    
/// <summary>
    
/// 无
    
/// </summary>
    NONE = 0,
    
/// <summary>
    
/// 按秒运行 
    
/// </summary>
    SEC = 1,
    
/// <summary>
    
/// 按分运行
    
/// </summary>
    MIN = 2,
    
/// <summary>
    
/// 按小时运行
    
/// </summary>
    HOUR = 3,
    
/// <summary>
    
/// 按天运行
    
/// </summary>
    DAY = 4,
    
/// <summary>
    
/// 按每天什么时候运行
    
/// </summary>
    RunOnDay = 10,
    
/// <summary>
    
/// 按星期几及时间运行
    
/// </summary>
    RunOnWeek = 11
}

public delegate void RobotErrorHandler(object sender, RobotErrorEventArgs e);
public class RobotErrorEventArgs : EventArgs {

    
private Exception _exception;
    
private RobotDef _def;

    
public RobotErrorEventArgs(Exception exception, RobotDef def) {
        _exception 
= exception;
        _def 
= def;
    }

    
public Exception Exception {
        
get { return _exception; }
    }
    
public RobotDef Def {
        
get { return _def; }
    }
}
posted @ 2012-09-05 23:09  安度  阅读(440)  评论(0编辑  收藏  举报