Changeset 347
- Timestamp:
- 10/30/07 10:29:55 (13 months ago)
- Location:
- TwitterIrcGateway/TwitterIrcGatewayCore
- Files:
-
- 3 modified
Legend:
- Unmodified
- Added
- Removed
-
TwitterIrcGateway/TwitterIrcGatewayCore/Filter.cs
r343 r347 10 10 { 11 11 [XmlInclude(typeof(Drop))] 12 [XmlInclude(typeof(Re route))]12 [XmlInclude(typeof(Redirect))] 13 13 [XmlInclude(typeof(RewriteContent))] 14 14 public class Filters … … 204 204 } 205 205 206 public class Re route: FilterItem206 public class Redirect : FilterItem 207 207 { 208 208 private String _matchPattern = ""; … … 236 236 public override void Execute(FilterArgs args) 237 237 { 238 if (String.IsNullOrEmpty(_channelName)) 239 return; 240 238 241 if (!String.IsNullOrEmpty(_matchPattern)) 239 242 { … … 266 269 public override string ToString() 267 270 { 268 return "Re route:"271 return "Redirect:" 269 272 + ((Enabled) ? "" : "[DISABLED]") 270 273 + ((String.IsNullOrEmpty(_userMatchPattern)) ? "" : String.Format(" UserMatchPattern={0}", _userMatchPattern)) 271 274 + ((String.IsNullOrEmpty(_matchPattern)) ? "" : String.Format(" MatchPattern={0}", _matchPattern)) 275 + ((String.IsNullOrEmpty(_channelName)) ? "" : String.Format(" ChannelName={0}", _channelName)) 272 276 + ((_duplicate) ? " Duplicate" : "") 273 277 ; -
TwitterIrcGateway/TwitterIrcGatewayCore/Server.cs
r319 r347 23 23 /// </summary> 24 24 public Int32 IntervalDirectMessage = 60 * 5; 25 26 /// <summary> 27 /// Replies��F�b�N���邩�ǂ��� 28 /// </summary> 29 public Boolean EnableRepliesCheck = false; 30 31 /// <summary> 32 /// Replies�`�F�b�N�����u 33 /// </summary> 34 public Int32 IntervalReplies = 60 * 5; 25 35 26 36 /// <summary> -
TwitterIrcGateway/TwitterIrcGatewayCore/Session.cs
r341 r347 1 1 using System; 2 2 using System.Collections.Generic; 3 using System.Text; 3 using System.Diagnostics; 4 using System.Globalization; 5 using System.IO; 4 6 using System.Net.Sockets; 5 7 using System.Net; 6 using System.IO; 8 using System.Reflection; 9 using System.Text; 10 using System.Text.RegularExpressions; 11 using System.Threading; 7 12 using System.Web; 8 using System.Threading; 13 using System.Xml; 14 9 15 using Misuzilla.Net.Irc; 10 using System.Xml;11 using System.Diagnostics;12 using System.Globalization;13 using System.Text.RegularExpressions;14 16 using Misuzilla.Applications.TwitterIrcGateway.Filter; 15 using System.Reflection;16 17 17 18 namespace Misuzilla.Applications.TwitterIrcGateway … … 29 30 private Timer _timer; 30 31 private Timer _timerDirectMessage; 32 private Timer _timerReplies; 31 33 private Groups _groups; 32 34 private Filters _filter; … … 37 39 private DateTime _lastAccessDirectMessage = DateTime.Now; 38 40 private LinkedList<Status> _statusBuffer; 39 private Boolean _isCallbackRunning = false; 40 private Boolean _isCallbackDirectMessageRunning = false; 41 private LinkedList<Status> _repliesBuffer; 41 42 private TraceListener _traceListeneer; 42 43 … … 69 70 _tcpClient = tcpClient; 70 71 _statusBuffer = new LinkedList<Status>(); 72 _repliesBuffer = new LinkedList<Status>(); 71 73 _lastStatusIdsFromGateway = new LinkedList<int>(); 72 74 _timer = new Timer(new TimerCallback(OnTimerCallback), null, Timeout.Infinite, Timeout.Infinite); 73 75 _timerDirectMessage = new Timer(new TimerCallback(OnTimerCallbackDirectMessage), null, Timeout.Infinite, Timeout.Infinite); 76 _timerReplies = new Timer(new TimerCallback(OnTimerCallbackReplies), null, Timeout.Infinite, Timeout.Infinite); 74 77 } 75 78 … … 109 112 } 110 113 } 111 114 112 115 /// <summary> 113 116 /// … … 116 119 private void OnTimerCallback(Object stateObject) 117 120 { 118 // あまりに処理が遅れると二重になる可能性がある 119 lock (_timer) 120 { 121 if (_isCallbackRunning) 122 return; 123 _isCallbackRunning = true; 124 } 125 126 try 121 RunCallback(_timer, delegate 127 122 { 128 123 SendPing(); … … 140 135 CheckFriends(); 141 136 } 142 } 143 finally 144 { 145 _isCallbackRunning = false; 146 } 137 }); 147 138 } 148 139 … … 153 144 private void OnTimerCallbackDirectMessage(Object stateObject) 154 145 { 146 RunCallback(_timerDirectMessage, delegate 147 { 148 CheckDirectMessage(); 149 }); 150 } 151 152 /// <summary> 153 /// 154 /// </summary> 155 /// <param name="stateObject"></param> 156 private void OnTimerCallbackReplies(Object stateObject) 157 { 158 RunCallback(_timerReplies, delegate 159 { 160 CheckDirectMessage(); 161 }); 162 } 163 164 /// <summary> 165 /// 166 /// </summary> 167 private delegate void CallbackProcedure(); 168 169 /// <summary> 170 /// タイマーコールバックの処理を実行します。 171 /// </summary> 172 /// <param name="timer"></param> 173 /// <param name="callbackProcedure"></param> 174 private void RunCallback(Timer timer, CallbackProcedure callbackProcedure) 175 { 155 176 // あまりに処理が遅れると二重になる可能性がある 156 lock (_timer) 157 { 158 if (_isCallbackDirectMessageRunning) 159 return; 160 _isCallbackDirectMessageRunning = true; 161 } 162 163 try 164 { 165 CheckDirectMessage(); 166 } 167 finally 168 { 169 _isCallbackDirectMessageRunning = false; 177 if (Monitor.TryEnter(timer)) 178 { 179 try 180 { 181 callbackProcedure(); 182 } 183 finally 184 { 185 Monitor.Exit(timer); 186 } 170 187 } 171 188 } … … 190 207 try 191 208 { 192 //Console.WriteLine(line);193 line = line.Replace('〜', '~'); // FIXME:194 209 IRCMessage msg = IRCMessage.CreateMessage(line); 195 210 OnMessageRecieved(msg); 196 211 } 197 212 catch (IRCException) 198 { 199 } 213 {} 200 214 } 201 215 } 202 216 } 203 217 catch (IOException ie) 204 { 205 } 218 {} 206 219 catch (NullReferenceException ne) 207 { 208 } 220 {} 209 221 finally 210 222 { … … 611 623 _timer.Change(0, _server.Interval * 1000); 612 624 _timerDirectMessage.Change(0, _server.IntervalDirectMessage * 1000); 625 _timerReplies.Change(0, _server.IntervalReplies * 1000); 613 626 } 614 627 … … 870 883 void GetFriendNames() 871 884 { 872 try885 RunCheck(delegate 873 886 { 874 887 User[] friends = _twitter.GetFriends(); 875 _nickNames = new List<string>(Array.ConvertAll<User, String>(friends, delegate(User u) { 888 _nickNames = new List<string>(Array.ConvertAll<User, String>(friends, delegate(User u) 889 { 876 890 return u.ScreenName; 877 891 })); … … 879 893 SendNumericReply(NumericReply.RPL_NAMREPLY, "=", _server.ChannelName, String.Join(" ", _nickNames.ToArray())); 880 894 SendNumericReply(NumericReply.RPL_ENDOFNAMES, _server.ChannelName, "End of NAMES list"); 881 } 882 catch (WebException ex) 883 { 884 if (ex.Response == null || (ex.Response is HttpWebResponse) && ((HttpWebResponse)(ex.Response)).StatusCode != HttpStatusCode.NotModified) 885 { 886 // not-modified 以外 887 SendTwitterGatewayServerMessage(ex.Message); 888 } 889 } 890 catch (TwitterServiceException ex2) 891 { 892 SendTwitterGatewayServerMessage(ex2.Message); 893 } 895 }); 894 896 } 895 897 … … 913 915 } 914 916 915 try917 RunCheck(delegate 916 918 { 917 919 User[] friends = _twitter.GetFriends(); … … 947 949 _nickNames = screenNames; 948 950 949 } 950 catch (WebException ex) 951 { 952 if (ex.Response == null || !(ex.Response is HttpWebResponse) || ((HttpWebResponse)(ex.Response)).StatusCode != HttpStatusCode.NotModified) 953 { 954 // not-modified 以外 955 SendServerErrorMessage(ex.Message); 956 } 957 } 958 catch (TwitterServiceException ex2) 959 { 960 SendServerErrorMessage(ex2.Message); 961 } 951 }); 962 952 } 963 953 964 954 private Boolean CheckNewTimeLine(out Boolean friendsCheckRequired) 965 955 { 966 friendsCheckRequired = false; 967 968 try 956 Boolean friendsCheckRequiredAnon = false; 957 Boolean returnValue = RunCheck(delegate 969 958 { 970 959 Statuses statuses = _twitter.GetTimeline(_lastAccessTimeline); … … 972 961 foreach (Status status in statuses.Status) 973 962 { 974 ProcessTimelineStatus (status, ref friendsCheckRequired); 975 } 976 statuses = _twitter.GetReplies(); 963 // 差分チェック 964 if (ProcessDropProtection(_statusBuffer, status)) 965 { 966 ProcessTimelineStatus(status, ref friendsCheckRequiredAnon); 967 } 968 } 969 970 if (_isFirstTime && _server.EnableDropProtection) 971 { 972 _lastAccessTimeline = DateTime.Now; 973 } 974 _isFirstTime = false; 975 }); 976 977 friendsCheckRequired = friendsCheckRequiredAnon; 978 return returnValue; 979 } 980 981 private Boolean CheckNewReplies(out Boolean friendsCheckRequired) 982 { 983 friendsCheckRequired = false; 984 return RunCheck(delegate 985 { 986 Statuses statuses = _twitter.GetReplies(); 977 987 Array.Reverse(statuses.Status); 978 988 bool dummy = false; … … 981 991 if (status.CreatedAt < _lastAccessTimeline) 982 992 continue; 983 // Here I pass dummy, because no matter how the replier flags 984 // friendsCheckRequired, we cannot receive his or her info 985 // through get_friends. 986 ProcessTimelineStatus (status, ref dummy); 993 // 差分チェック 994 if (ProcessDropProtection(_statusBuffer, status) && ProcessDropProtection(_repliesBuffer, status)) 995 { 996 // Here I pass dummy, because no matter how the replier flags 997 // friendsCheckRequired, we cannot receive his or her info 998 // through get_friends. 999 ProcessTimelineStatus(status, ref dummy); 1000 } 987 1001 } 988 1002 … … 992 1006 } 993 1007 _isFirstTime = false; 994 } 995 catch (WebException ex) 996 { 997 if (ex.Response == null || !(ex.Response is HttpWebResponse) || ((HttpWebResponse)(ex.Response)).StatusCode != HttpStatusCode.NotModified) 998 { 999 // not-modified 以外 1000 SendServerErrorMessage(ex.Message); 1001 } 1002 return false; 1003 } 1004 catch (TwitterServiceException ex2) 1005 { 1006 SendServerErrorMessage(ex2.Message); 1007 return false; 1008 } 1009 1010 return true; 1011 } 1012 1013 private void ProcessTimelineStatus (Status status, ref Boolean friendsCheckRequired) 1008 }); 1009 } 1010 1011 /// <summary> 1012 /// 既に受信したstatusかどうかをチェックします。既に送信済みの場合falseを返します。 1013 /// </summary> 1014 /// <param name="statusBuffer"></param> 1015 /// <param name="status"></param> 1016 /// <returns></returns> 1017 private Boolean ProcessDropProtection(LinkedList<Status> statusBuffer, Status status) 1014 1018 { 1015 1019 // 差分チェック 1016 1020 if (_server.EnableDropProtection) 1017 1021 { 1018 if ( _statusBuffer.Contains(status))1019 return ;1020 1021 _statusBuffer.AddLast(status);1022 if ( _statusBuffer.Count > 100)1022 if (statusBuffer.Contains(status)) 1023 return false; 1024 1025 statusBuffer.AddLast(status); 1026 if (statusBuffer.Count > 100) 1023 1027 { 1024 1028 // 一番古いのを消す … … 1032 1036 //} 1033 1037 //_statusBuffer.Remove(oldStatus); 1034 _statusBuffer.RemoveFirst(); 1035 } 1036 } 1038 statusBuffer.RemoveFirst(); 1039 } 1040 } 1041 1042 return true; 1043 } 1044 1045 private void ProcessTimelineStatus (Status status, ref Boolean friendsCheckRequired) 1046 { 1037 1047 1038 1048 // チェック … … 1140 1150 private void CheckDirectMessage() 1141 1151 { 1142 try1152 RunCheck(delegate 1143 1153 { 1144 1154 DirectMessages directMessages = _twitter.GetDirectMessages(_lastAccessDirectMessage); … … 1152 1162 } 1153 1163 1154 String text = (_server.ResolveTinyUrl) ? Utility.ResolveTinyUrlInMessage(message.Text) : message.Text; 1164 String text = (_server.ResolveTinyUrl) ? Utility.ResolveTinyUrlInMessage(message.Text) : message.Text; 1155 1165 String[] lines = text.Split(new Char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); 1156 1166 … … 1171 1181 } 1172 1182 } 1183 }); 1184 } 1185 1186 private delegate void CheckProcedure(); 1187 /// <summary> 1188 /// チェックを実行します。例外が発生した場合には自動的にメッセージを送信します。 1189 /// </summary> 1190 /// <param name="proc">実行するチェック処理</param> 1191 /// <returns></returns> 1192 private Boolean RunCheck(CheckProcedure proc) 1193 { 1194 try 1195 { 1196 proc(); 1173 1197 } 1174 1198 catch (WebException ex) … … 1178 1202 // not-modified 以外 1179 1203 SendServerErrorMessage(ex.Message); 1204 return false; 1180 1205 } 1181 1206 } … … 1183 1208 { 1184 1209 SendServerErrorMessage(ex2.Message); 1185 } 1186 } 1210 return false; 1211 } 1212 1213 return true; 1214 } 1215 1187 1216 1188 1217 /// <summary> … … 1225 1254 _timerDirectMessage = null; 1226 1255 } 1227 1228 // 一応待つ 1229 while (_isCallbackRunning || _isCallbackDirectMessageRunning) 1230 Thread.Sleep(100); 1256 if (_timerReplies != null) 1257 { 1258 _timerReplies.Dispose(); 1259 _timerReplies = null; 1260 } 1231 1261 1232 1262 if (_twitter != null)
