@@ -0,0 +1,33 @@ | |||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/@KeyIndexDefined">True</s:Boolean> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Description/@EntryValue">Module</s:String> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Text/@EntryValue">namespace $namespace$
 | |||
{
 | |||
public class $filename$ : Module
 | |||
{
 | |||
public override void Initialize()
 | |||
{
 | |||
} 
 | |||

 | |||
public override void ParseCommand(CommandMessage command)
 | |||
{
 | |||
}
 | |||
}
 | |||
}</s:String> | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Reformat/@EntryValue">True</s:Boolean> | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/ShortenQualifiedReferences/@EntryValue">True</s:Boolean> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Categories/=Imported_00201_002F29_002F2015/@EntryIndexedValue">Imported 1/29/2015</s:String> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/CustomProperties/=FileName/@EntryIndexedValue">NewModule</s:String> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/CustomProperties/=Extension/@EntryIndexedValue">cs</s:String> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/CustomProperties/=ValidateFileName/@EntryIndexedValue">False</s:String> | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Applicability/=File/@EntryIndexedValue">True</s:Boolean> | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Scope/=E8F0594528C33E45BBFEC6CFE851095D/@KeyIndexDefined">True</s:Boolean> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Scope/=E8F0594528C33E45BBFEC6CFE851095D/Type/@EntryValue">InCSharpProjectFile</s:String> | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/@KeyIndexDefined">True</s:Boolean> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/Expression/@EntryValue">getCurrentNamespace()</s:String> | |||
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/InitialRange/@EntryValue">-1</s:Int64> | |||
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/Order/@EntryValue">0</s:Int64> | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/@KeyIndexDefined">True</s:Boolean> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/Expression/@EntryValue">fileDefaultNamespace()</s:String> | |||
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/InitialRange/@EntryValue">-1</s:Int64> | |||
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/Order/@EntryValue">1</s:Int64></wpf:ResourceDictionary> |
@@ -1,15 +1,12 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Net; | |||
using System.Reflection; | |||
using System.Threading.Tasks; | |||
using System.Threading; | |||
using Combot.IRCServices; | |||
using Combot.Configurations; | |||
using Combot.IRCServices.Messaging; | |||
using Combot.Modules; | |||
using Module = Combot.Modules.Module; | |||
namespace Combot | |||
{ | |||
@@ -19,20 +16,25 @@ namespace Combot | |||
public event Action<BotError> ErrorEvent; | |||
public ServerConfig ServerConfig; | |||
public IRC IRC; | |||
public List<Module> Modules; | |||
public bool Connected = false; | |||
public bool LoggedIn = false; | |||
public static Dictionary<PrivilegeMode, AccessType> AccessTypeMapping = new Dictionary<PrivilegeMode, AccessType>() { { PrivilegeMode.v, AccessType.Voice }, { PrivilegeMode.h, AccessType.HalfOperator }, { PrivilegeMode.o, AccessType.Operator }, { PrivilegeMode.a, AccessType.SuperOperator }, { PrivilegeMode.q, AccessType.Founder } }; | |||
private List<Module> _Modules; | |||
private bool GhostSent; | |||
public Bot(ServerConfig serverConfig) | |||
{ | |||
IRC = new IRC(); | |||
_Modules = new List<Module>(); | |||
Modules = new List<Module>(); | |||
GhostSent = false; | |||
ServerConfig = serverConfig; | |||
IRC.ConnectEvent += HandleConnectEvent; | |||
IRC.DisconnectEvent += HandleDisconnectEvent; | |||
IRC.Message.ServerReplyEvent += HandleReplyEvent; | |||
IRC.Message.ChannelMessageReceivedEvent += HandleChannelMessageReceivedEvent; | |||
IRC.Message.JoinChannelEvent += HandleJoinEvent; | |||
IRC.Message.KickEvent += HandleKickEvent; | |||
LoadModules(); | |||
} | |||
@@ -42,6 +44,7 @@ namespace Combot | |||
/// </summary> | |||
public void Connect() | |||
{ | |||
GhostSent = false; | |||
bool serverConnected = false; | |||
int i = 0; | |||
do | |||
@@ -68,7 +71,13 @@ namespace Combot | |||
if (serverConnected) | |||
{ | |||
IRC.Login(ServerConfig.Name, new Nick() { Nickname = ServerConfig.Nickname, Host = Dns.GetHostName(), Realname = ServerConfig.Realname, Username = ServerConfig.Username }); | |||
IRC.Login(ServerConfig.Name, new Nick() | |||
{ | |||
Nickname = ServerConfig.Nickname, | |||
Host = Dns.GetHostName(), | |||
Realname = ServerConfig.Realname, | |||
Username = ServerConfig.Username | |||
}); | |||
} | |||
} | |||
@@ -79,18 +88,19 @@ namespace Combot | |||
{ | |||
IRC.Disconnect(); | |||
Connected = false; | |||
LoggedIn = false; | |||
} | |||
public void LoadModules() | |||
{ | |||
foreach (Module module in ServerConfig.Modules) | |||
{ | |||
if (module.Enabled && !_Modules.Exists(mod => mod.ClassName == module.ClassName)) | |||
if (module.Enabled && !Modules.Exists(mod => mod.ClassName == module.ClassName)) | |||
{ | |||
Module loadedModule = module.CreateInstance(this); | |||
if (loadedModule.Loaded) | |||
{ | |||
_Modules.Add(loadedModule); | |||
Modules.Add(loadedModule); | |||
} | |||
} | |||
} | |||
@@ -106,18 +116,92 @@ namespace Combot | |||
Connected = false; | |||
} | |||
private void HandleReplyEvent(object sender, IReply e) | |||
private void HandleJoinEvent(object sender, JoinChannelInfo info) | |||
{ | |||
if (info.Nick.Nickname == IRC.Nickname) | |||
{ | |||
if (!ServerConfig.Channels.Exists(chan => chan.Name == info.Channel)) | |||
{ | |||
ChannelConfig chanConfig = new ChannelConfig(); | |||
chanConfig.Name = info.Channel; | |||
ServerConfig.Channels.Add(chanConfig); | |||
ServerConfig.Save(); | |||
} | |||
} | |||
} | |||
private void HandleKickEvent(object sender, KickInfo info) | |||
{ | |||
if (info.KickedNick.Nickname == IRC.Nickname) | |||
{ | |||
ServerConfig.Channels.RemoveAll(chan => chan.Name == info.Channel); | |||
ServerConfig.Save(); | |||
} | |||
} | |||
private async void HandleReplyEvent(object sender, IReply e) | |||
{ | |||
if (e.GetType() == typeof(ServerReplyMessage)) | |||
{ | |||
ServerReplyMessage reply = (ServerReplyMessage)e; | |||
// If the reply is Welcome, that means we are fully connected to the server and can now join the auto-join channels. | |||
if (reply.ReplyCode == IRCReplyCode.RPL_WELCOME && Connected) | |||
switch (reply.ReplyCode) | |||
{ | |||
foreach (ChannelConfig channel in ServerConfig.Channels) | |||
{ | |||
IRC.SendJoin(channel.Name, channel.Key); | |||
} | |||
case IRCReplyCode.RPL_WELCOME: | |||
// If the reply is Welcome, that means we are fully connected to the server. | |||
LoggedIn = true; | |||
if (!GhostSent && IRC.Nickname != ServerConfig.Nickname) | |||
{ | |||
IRC.SendPrivateMessage("NickServ", string.Format("GHOST {0} {1}", ServerConfig.Nickname, ServerConfig.Password)); | |||
Thread.Sleep(1000); | |||
IRC.SendNick(ServerConfig.Nickname); | |||
GhostSent = true; | |||
} | |||
// Identify to NickServ if need be | |||
IRC.SendPrivateMessage("NickServ", string.Format("IDENTIFY {0}", ServerConfig.Password)); | |||
// Join all required channels | |||
// Delay joining channels for configured time | |||
Thread.Sleep(ServerConfig.JoinDelay); | |||
foreach (ChannelConfig channel in ServerConfig.Channels) | |||
{ | |||
IRC.SendJoin(channel.Name, channel.Key); | |||
} | |||
break; | |||
} | |||
} | |||
else if (e.GetType() == typeof(ServerErrorMessage)) | |||
{ | |||
ServerErrorMessage error = (ServerErrorMessage) e; | |||
switch (error.ErrorCode) | |||
{ | |||
case IRCErrorCode.ERR_NOTREGISTERED: | |||
if (ServerConfig.Password != string.Empty && ServerConfig.Email != string.Empty) | |||
{ | |||
IRC.SendPrivateMessage("NickServ", string.Format("REGISTER {0} {1}", ServerConfig.Password, ServerConfig.Email)); | |||
} | |||
break; | |||
case IRCErrorCode.ERR_NICKNAMEINUSE: | |||
if (LoggedIn == false) | |||
{ | |||
string nick = string.Empty; | |||
if (IRC.Nickname == ServerConfig.Nickname && ServerConfig.SecondaryNickname != string.Empty) | |||
{ | |||
nick = ServerConfig.SecondaryNickname; | |||
} | |||
else | |||
{ | |||
Random rand = new Random(); | |||
nick = string.Format("{0}_{1}", ServerConfig.Nickname, rand.Next(100000).ToString()); | |||
} | |||
IRC.Login(ServerConfig.Name, new Nick() | |||
{ | |||
Nickname = nick, | |||
Host = Dns.GetHostName(), | |||
Realname = ServerConfig.Realname, | |||
Username = ServerConfig.Username | |||
}); | |||
} | |||
break; | |||
} | |||
} | |||
} | |||
@@ -144,7 +228,7 @@ namespace Combot | |||
List<string> argsOnly = msgArgs.ToList(); | |||
argsOnly.RemoveAt(0); | |||
Module module = _Modules.Find(mod => mod.Commands.Exists(c => c.Triggers.Contains(command)) && mod.Loaded); | |||
Module module = Modules.Find(mod => mod.Commands.Exists(c => c.Triggers.Contains(command)) && mod.Loaded); | |||
if (module != null) | |||
{ | |||
Command cmd = module.Commands.Find(c => c.Triggers.Contains(command)); | |||
@@ -165,17 +249,18 @@ namespace Combot | |||
newCommand.Command = command; | |||
if (argsOnly.Count > 0) | |||
{ | |||
string[] argSplit = argsOnly.First() | |||
.Split(new[] {' '}, cmd.Arguments.Count + 1, StringSplitOptions.RemoveEmptyEntries); | |||
for (int i = 0; i < cmd.Arguments.Count; i++) | |||
string[] argSplit = argsOnly.First().Split(new[] {' '}, cmd.Arguments.Count + 1, StringSplitOptions.RemoveEmptyEntries); | |||
for (int i = 0; i < cmd.Arguments.Count && i <= argSplit.GetUpperBound(0); i++) | |||
{ | |||
newCommand.Arguments.Add(argSplit[i]); | |||
newCommand.Arguments.Add(cmd.Arguments[i].Name, argSplit[i]); | |||
} | |||
} | |||
if (CommandReceivedEvent != null) | |||
if (cmd.Arguments.FindAll(arg => arg.Required).Count <= newCommand.Arguments.Count) | |||
{ | |||
CommandReceivedEvent(newCommand); | |||
if (CommandReceivedEvent != null) | |||
{ | |||
CommandReceivedEvent(newCommand); | |||
} | |||
} | |||
} | |||
} |
@@ -69,7 +69,9 @@ | |||
<Compile Include="Help.cs" /> | |||
<Compile Include="Modules\CommandArgument.cs" /> | |||
<Compile Include="Modules\CommandMessage.cs" /> | |||
<Compile Include="Modules\ModuleClasses\Invite.cs" /> | |||
<Compile Include="Modules\ModuleClasses\PingMe.cs" /> | |||
<Compile Include="Modules\ModuleClasses\Version.cs" /> | |||
<Compile Include="Modules\Option.cs" /> | |||
<Compile Include="Types.cs" /> | |||
<Compile Include="Methods.cs" /> |
@@ -12,17 +12,21 @@ namespace Combot.Configurations | |||
{ | |||
public event Action ModifyEvent; | |||
public string Name { get; set; } | |||
public bool AutoConnect { get; set; } | |||
public string CommandPrefix { get; set; } | |||
public string Nickname { get; set; } | |||
public string SecondaryNickname { get; set; } | |||
public string Realname { get; set; } | |||
public string Username { get; set; } | |||
public string Password { get; set; } | |||
public string Email { get; set; } | |||
public List<string> Owners { get; set; } | |||
public List<string> ChannelBlacklist { get; set; } | |||
public List<string> NickBlacklist { get; set; } | |||
public List<HostConfig> Hosts { get; set; } | |||
public List<ChannelConfig> Channels { get; set; } | |||
public List<Module> Modules { get; set; } | |||
public bool AutoConnect { get; set; } | |||
public string CommandPrefix { get; set; } | |||
public int JoinDelay { get; set; } | |||
public ServerConfig() | |||
{ | |||
@@ -34,6 +38,7 @@ namespace Combot.Configurations | |||
Name = string.Empty; | |||
AutoConnect = false; | |||
CommandPrefix = string.Empty; | |||
JoinDelay = 0; | |||
Owners = new List<string>(); | |||
ChannelBlacklist = new List<string>(); | |||
NickBlacklist = new List<string>(); | |||
@@ -41,8 +46,11 @@ namespace Combot.Configurations | |||
Modules = new List<Module>(); | |||
Hosts = new List<HostConfig>(); | |||
Nickname = string.Empty; | |||
SecondaryNickname = string.Empty; | |||
Realname = string.Empty; | |||
Username = string.Empty; | |||
Password = string.Empty; | |||
Email = string.Empty; | |||
} | |||
public void Save() |
@@ -6,6 +6,7 @@ namespace Combot.Modules | |||
{ | |||
public string Name { get; set; } | |||
public string Description { get; set; } | |||
public bool Enabled { get; set; } | |||
public List<string> ChannelBlacklist { get; set; } | |||
public List<string> NickBlacklist { get; set; } | |||
public List<string> Triggers { get; set; } | |||
@@ -28,6 +29,7 @@ namespace Combot.Modules | |||
{ | |||
Name = string.Empty; | |||
Description = string.Empty; | |||
Enabled = true; | |||
Triggers = new List<string>(); | |||
ChannelBlacklist = new List<string>(); | |||
NickBlacklist = new List<string>(); | |||
@@ -41,6 +43,7 @@ namespace Combot.Modules | |||
{ | |||
Name = command.Name; | |||
Description = command.Description; | |||
Enabled = command.Enabled; | |||
Triggers = new List<string>(); | |||
foreach (string trigger in command.Triggers) | |||
{ |
@@ -6,7 +6,6 @@ namespace Combot.Modules | |||
{ | |||
public string Name { get; set; } | |||
public string Description { get; set; } | |||
public List<string> Triggers { get; set; } | |||
public bool Required { get; set; } | |||
public CommandArgument() | |||
@@ -18,7 +17,6 @@ namespace Combot.Modules | |||
{ | |||
Name = string.Empty; | |||
Description = string.Empty; | |||
Triggers = new List<string>(); | |||
Required = false; | |||
} | |||
@@ -26,11 +24,6 @@ namespace Combot.Modules | |||
{ | |||
Name = argument.Name; | |||
Description = argument.Description; | |||
Triggers = new List<string>(); | |||
foreach (string trigger in argument.Triggers) | |||
{ | |||
Triggers.Add(trigger); | |||
} | |||
Required = argument.Required; | |||
} | |||
} |
@@ -11,7 +11,7 @@ namespace Combot.Modules | |||
public Nick Nick { get; set; } | |||
public DateTime TimeStamp { get; set; } | |||
public string Command { get; set; } | |||
public List<string> Arguments { get; set; } | |||
public Dictionary<string, dynamic> Arguments { get; set; } | |||
public CommandMessage() | |||
{ | |||
@@ -20,7 +20,7 @@ namespace Combot.Modules | |||
Nick = new Nick(); | |||
TimeStamp = DateTime.Now; | |||
Command = string.Empty; | |||
Arguments = new List<string>(); | |||
Arguments = new Dictionary<string, dynamic>(); | |||
} | |||
} | |||
@@ -38,6 +38,7 @@ namespace Combot.Modules | |||
&& !ChannelBlacklist.Contains(command.Location) | |||
&& !NickBlacklist.Contains(command.Nick.Nickname) | |||
&& Commands.Exists(c => c.Triggers.Contains(command.Command) | |||
&& c.Enabled | |||
&& !c.ChannelBlacklist.Contains(command.Location) | |||
&& !c.NickBlacklist.Contains(command.Nick.Nickname) | |||
) | |||
@@ -132,5 +133,20 @@ namespace Combot.Modules | |||
return newModule; | |||
} | |||
public dynamic GetOptionValue(string name) | |||
{ | |||
dynamic foundValue = null; | |||
Option foundOption = Options.Find(opt => opt.Name == name); | |||
if (foundOption != null) | |||
{ | |||
foundValue = foundOption.Value; | |||
if (foundValue == null) | |||
{ | |||
foundValue = string.Empty; | |||
} | |||
} | |||
return foundValue; | |||
} | |||
} | |||
} |
@@ -0,0 +1,30 @@ | |||
using Combot.IRCServices.Messaging; | |||
namespace Combot.Modules.ModuleClasses | |||
{ | |||
public class Invite : Module | |||
{ | |||
public override void Initialize() | |||
{ | |||
Bot.IRC.Message.InviteChannelEvent += HandleInvite; | |||
} | |||
private void HandleInvite(object sender, InviteChannelInfo inviteInfo) | |||
{ | |||
if (!Bot.ServerConfig.ChannelBlacklist.Contains(inviteInfo.Channel)) | |||
{ | |||
Bot.IRC.SendJoin(inviteInfo.Channel); | |||
string helpMessage = string.Empty; | |||
if (Bot.Modules.Exists(module => module.Commands.Exists(cmd => cmd.Triggers.Contains("help") && cmd.Enabled))) | |||
{ | |||
helpMessage = string.Format(" For more information on what I can do, just type: {0}help", Bot.ServerConfig.CommandPrefix); | |||
} | |||
Bot.IRC.SendPrivateMessage(inviteInfo.Channel, string.Format("{0} has invited me to this channel. If you would like me to leave, just kick me.{1}", inviteInfo.Requester.Nickname, helpMessage)); | |||
} | |||
else | |||
{ | |||
Bot.IRC.SendNotice(inviteInfo.Requester.Nickname, "I am unable to join that channel."); | |||
} | |||
} | |||
} | |||
} |
@@ -37,7 +37,7 @@ namespace Combot.Modules.ModuleClasses | |||
} | |||
pingList.Add(tmpItem); | |||
listLock.ExitWriteLock(); | |||
Bot.IRC.SendCTCP(command.Nick.Nickname, "PING", epoch.ToString()); | |||
Bot.IRC.SendCTCPMessage(command.Nick.Nickname, "PING", epoch.ToString()); | |||
} | |||
} | |||
@@ -0,0 +1,92 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Reflection; | |||
using System.Threading; | |||
using Combot.IRCServices.Messaging; | |||
namespace Combot.Modules.ModuleClasses | |||
{ | |||
public class Version : Module | |||
{ | |||
private List<VersionItem> versionList; | |||
private ReaderWriterLockSlim listLock; | |||
public override void Initialize() | |||
{ | |||
listLock = new ReaderWriterLockSlim(); | |||
versionList = new List<VersionItem>(); | |||
Bot.IRC.Message.CTCPMessageRecievedEvent += HandleVersionQuery; | |||
Bot.IRC.Message.CTCPNoticeRecievedEvent += HandleVersionResponse; | |||
Bot.CommandReceivedEvent += HandleCommandEvent; | |||
} | |||
public override void ParseCommand(CommandMessage command) | |||
{ | |||
if (Commands.Find(cmd => cmd.Name == "Version Check").Triggers.Contains(command.Command)) | |||
{ | |||
VersionItem tmpItem = new VersionItem(); | |||
tmpItem.Location = command.Location; | |||
tmpItem.LocationType = command.LocationType; | |||
tmpItem.Nick = command.Arguments["Nickname"]; | |||
listLock.EnterWriteLock(); | |||
if (versionList.Exists(item => item.Nick == command.Arguments["Nickname"])) | |||
{ | |||
versionList.RemoveAll(item => item.Nick == command.Arguments["Nickname"]); | |||
} | |||
versionList.Add(tmpItem); | |||
listLock.ExitWriteLock(); | |||
Bot.IRC.SendCTCPMessage(command.Arguments["Nickname"], "VERSION"); | |||
} | |||
} | |||
public void HandleVersionQuery(object sender, CTCPMessage message) | |||
{ | |||
if (message.Command.ToLower() == "version") | |||
{ | |||
Bot.IRC.SendCTCPNotice(message.Sender.Nickname, "VERSION", string.Format("Combot v{0} on {1}", Assembly.GetExecutingAssembly().GetName().Version, GetOptionValue("Machine Reply"))); | |||
} | |||
} | |||
public void HandleVersionResponse(object sender, CTCPMessage message) | |||
{ | |||
if (message.Command == "VERSION") | |||
{ | |||
listLock.EnterReadLock(); | |||
VersionItem versionItem = versionList.Find(item => item.Nick == message.Sender.Nickname); | |||
listLock.ExitReadLock(); | |||
if (versionItem != null) | |||
{ | |||
switch (versionItem.LocationType) | |||
{ | |||
case LocationType.Channel: | |||
Bot.IRC.SendPrivateMessage(versionItem.Location, string.Format("[{0}] Using version: {1}", versionItem.Nick, message.Arguments)); | |||
break; | |||
case LocationType.Query: | |||
Bot.IRC.SendPrivateMessage(versionItem.Nick, string.Format("[{0}] Using version: {1}", versionItem.Nick, message.Arguments)); | |||
break; | |||
case LocationType.Notice: | |||
Bot.IRC.SendNotice(versionItem.Nick, string.Format("[{0}] Using version: {1}", versionItem.Nick, message.Arguments)); | |||
break; | |||
} | |||
listLock.EnterWriteLock(); | |||
versionList.RemoveAll(item => item.Nick == versionItem.Nick); | |||
listLock.ExitWriteLock(); | |||
} | |||
} | |||
} | |||
} | |||
public class VersionItem | |||
{ | |||
public string Nick { get; set; } | |||
public string Location { get; set; } | |||
public LocationType LocationType { get; set; } | |||
public VersionItem() | |||
{ | |||
Nick = string.Empty; | |||
Location = string.Empty; | |||
LocationType = LocationType.Channel; | |||
} | |||
} | |||
} |
@@ -57,7 +57,7 @@ namespace Combot.IRCServices | |||
/// <param name="recipient"></param> | |||
/// <param name="command"></param> | |||
/// <param name="message"></param> | |||
public void SendCTCP(string recipient, string command, string message = "") | |||
public void SendCTCPMessage(string recipient, string command, string message = "") | |||
{ | |||
if (message != string.Empty) | |||
{ | |||
@@ -66,7 +66,7 @@ namespace Combot.IRCServices | |||
SendTCPMessage(string.Format("PRIVMSG {0} :\u0001{1}{2}\u0001", recipient, command, message)); | |||
} | |||
public void SendCTCP(List<string> recipients, string command, string message) | |||
public void SendCTCPMessage(List<string> recipients, string command, string message) | |||
{ | |||
string recipient_list = string.Empty; | |||
foreach (string recipient in recipients) | |||
@@ -80,6 +80,35 @@ namespace Combot.IRCServices | |||
SendTCPMessage(string.Format("PRIVMSG {0} :\u0001{1}{2}\u0001", recipient_list.TrimEnd(','), command, message)); | |||
} | |||
/// <summary> | |||
/// Sends a CTCP command and optional message to a nick or channel | |||
/// </summary> | |||
/// <param name="recipient"></param> | |||
/// <param name="command"></param> | |||
/// <param name="message"></param> | |||
public void SendCTCPNotice(string recipient, string command, string message = "") | |||
{ | |||
if (message != string.Empty) | |||
{ | |||
message = " " + message; | |||
} | |||
SendTCPMessage(string.Format("NOTICE {0} :\u0001{1}{2}\u0001", recipient, command, message)); | |||
} | |||
public void SendCTCPNotice(List<string> recipients, string command, string message) | |||
{ | |||
string recipient_list = string.Empty; | |||
foreach (string recipient in recipients) | |||
{ | |||
recipient_list += recipient + ","; | |||
} | |||
if (message != string.Empty) | |||
{ | |||
message = " " + message; | |||
} | |||
SendTCPMessage(string.Format("NOTICE {0} :\u0001{1}{2}\u0001", recipient_list.TrimEnd(','), command, message)); | |||
} | |||
/// <summary> | |||
/// Sends the connection password | |||
/// </summary> |
@@ -42,7 +42,7 @@ namespace Combot.IRCServices.Messaging | |||
/// Parses the raw messages coming from the server and triggers an event based on the type of message. | |||
/// </summary> | |||
/// <param name="tcpMessage">The raw string read from the TCP stream.</param> | |||
internal void ParseTCPMessage(string tcpMessage) | |||
internal async void ParseTCPMessage(string tcpMessage) | |||
{ | |||
DateTime messageTime = DateTime.Now; | |||
Regex messageRegex = new Regex(@"^:(?<Sender>[^\s]+)\s(?<Type>[^\s]+)\s(?<Recipient>[^\s]+)\s?:?(?<Args>.*)", RegexOptions.None); | |||
@@ -80,17 +80,35 @@ namespace Combot.IRCServices.Messaging | |||
// The message was a reply to a command sent | |||
if (Enum.IsDefined(typeof(IRCReplyCode), replyCode)) | |||
{ | |||
if (ServerReplyEvent != null) | |||
await Task.Run(() => | |||
{ | |||
ServerReplyEvent(this, new ServerReplyMessage() { TimeStamp = messageTime, ReplyCode = (IRCReplyCode)replyCode, Message = args }); | |||
} | |||
if (ServerReplyEvent != null) | |||
{ | |||
ServerReplyEvent(this, | |||
new ServerReplyMessage() | |||
{ | |||
TimeStamp = messageTime, | |||
ReplyCode = (IRCReplyCode) replyCode, | |||
Message = args | |||
}); | |||
} | |||
}); | |||
} | |||
else if (Enum.IsDefined(typeof(IRCErrorCode), replyCode)) | |||
{ | |||
if (ServerReplyEvent != null) | |||
await Task.Run(() => | |||
{ | |||
ServerReplyEvent(this, new ServerErrorMessage() { TimeStamp = messageTime, ErrorCode = (IRCErrorCode)replyCode, Message = args }); | |||
} | |||
if (ServerReplyEvent != null) | |||
{ | |||
ServerReplyEvent(this, | |||
new ServerErrorMessage() | |||
{ | |||
TimeStamp = messageTime, | |||
ErrorCode = (IRCErrorCode) replyCode, | |||
Message = args | |||
}); | |||
} | |||
}); | |||
} | |||
} | |||
else | |||
@@ -112,10 +130,13 @@ namespace Combot.IRCServices.Messaging | |||
ctcpMessage.Command = ctcpMatch.Groups["Command"].Value; | |||
ctcpMessage.Arguments = ctcpMatch.Groups["Args"].Value; | |||
if (CTCPMessageRecievedEvent != null) | |||
await Task.Run(() => | |||
{ | |||
CTCPMessageRecievedEvent(this, ctcpMessage); | |||
} | |||
if (CTCPMessageRecievedEvent != null) | |||
{ | |||
CTCPMessageRecievedEvent(this, ctcpMessage); | |||
} | |||
}); | |||
} | |||
else | |||
{ | |||
@@ -131,10 +152,13 @@ namespace Combot.IRCServices.Messaging | |||
}; | |||
msg.Message = args; | |||
if (ChannelMessageReceivedEvent != null) | |||
await Task.Run(() => | |||
{ | |||
ChannelMessageReceivedEvent(this, msg); | |||
} | |||
if (ChannelMessageReceivedEvent != null) | |||
{ | |||
ChannelMessageReceivedEvent(this, msg); | |||
} | |||
}); | |||
} | |||
else | |||
{ | |||
@@ -147,10 +171,13 @@ namespace Combot.IRCServices.Messaging | |||
}; | |||
msg.Message = args; | |||
if (PrivateMessageReceivedEvent != null) | |||
await Task.Run(() => | |||
{ | |||
PrivateMessageReceivedEvent(this, msg); | |||
} | |||
if (PrivateMessageReceivedEvent != null) | |||
{ | |||
PrivateMessageReceivedEvent(this, msg); | |||
} | |||
}); | |||
} | |||
} | |||
break; | |||
@@ -169,10 +196,13 @@ namespace Combot.IRCServices.Messaging | |||
ctcpMessage.Command = ctcpMatch.Groups["Command"].Value; | |||
ctcpMessage.Arguments = ctcpMatch.Groups["Args"].Value; | |||
if (CTCPNoticeRecievedEvent != null) | |||
await Task.Run(() => | |||
{ | |||
CTCPNoticeRecievedEvent(this, ctcpMessage); | |||
} | |||
if (CTCPNoticeRecievedEvent != null) | |||
{ | |||
CTCPNoticeRecievedEvent(this, ctcpMessage); | |||
} | |||
}); | |||
} | |||
if (recipient.StartsWith("&") || recipient.StartsWith("#")) | |||
{ | |||
@@ -181,10 +211,13 @@ namespace Combot.IRCServices.Messaging | |||
msg.Sender = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost }; | |||
msg.Message = args; | |||
if (ChannelNoticeReceivedEvent != null) | |||
await Task.Run(() => | |||
{ | |||
ChannelNoticeReceivedEvent(this, msg); | |||
} | |||
if (ChannelNoticeReceivedEvent != null) | |||
{ | |||
ChannelNoticeReceivedEvent(this, msg); | |||
} | |||
}); | |||
} | |||
else | |||
{ | |||
@@ -192,10 +225,13 @@ namespace Combot.IRCServices.Messaging | |||
msg.Sender = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost }; | |||
msg.Message = args; | |||
if (PrivateNoticeReceivedEvent != null) | |||
await Task.Run(() => | |||
{ | |||
PrivateNoticeReceivedEvent(this, msg); | |||
} | |||
if (PrivateNoticeReceivedEvent != null) | |||
{ | |||
PrivateNoticeReceivedEvent(this, msg); | |||
} | |||
}); | |||
} | |||
break; | |||
// The message was a mode change message for a channel or nick | |||
@@ -256,10 +292,13 @@ namespace Combot.IRCServices.Messaging | |||
} | |||
} | |||
if (ChannelModeChangeEvent != null) | |||
await Task.Run(() => | |||
{ | |||
ChannelModeChangeEvent(this, modeMsg); | |||
} | |||
if (ChannelModeChangeEvent != null) | |||
{ | |||
ChannelModeChangeEvent(this, modeMsg); | |||
} | |||
}); | |||
} | |||
else | |||
{ | |||
@@ -289,10 +328,13 @@ namespace Combot.IRCServices.Messaging | |||
} | |||
} | |||
if (UserModeChangeEvent != null) | |||
await Task.Run(() => | |||
{ | |||
UserModeChangeEvent(this, modeMsg); | |||
} | |||
if (UserModeChangeEvent != null) | |||
{ | |||
UserModeChangeEvent(this, modeMsg); | |||
} | |||
}); | |||
} | |||
break; | |||
// The message was a topic change for a channel | |||
@@ -302,10 +344,13 @@ namespace Combot.IRCServices.Messaging | |||
topicMsg.Nick = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost }; | |||
topicMsg.Topic = args; | |||
if (TopicChangeEvent != null) | |||
await Task.Run(() => | |||
{ | |||
TopicChangeEvent(this, topicMsg); | |||
} | |||
if (TopicChangeEvent != null) | |||
{ | |||
TopicChangeEvent(this, topicMsg); | |||
} | |||
}); | |||
break; | |||
// The message was a nick change | |||
case "NICK": | |||
@@ -313,10 +358,13 @@ namespace Combot.IRCServices.Messaging | |||
nickMsg.OldNick = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost }; | |||
nickMsg.NewNick = new Nick() { Nickname = recipient.Remove(0, 1) }; | |||
if (NickChangeEvent != null) | |||
await Task.Run(() => | |||
{ | |||
NickChangeEvent(this, nickMsg); | |||
} | |||
if (NickChangeEvent != null) | |||
{ | |||
NickChangeEvent(this, nickMsg); | |||
} | |||
}); | |||
break; | |||
// The message was an invite to a channel | |||
case "INVITE": | |||
@@ -325,10 +373,13 @@ namespace Combot.IRCServices.Messaging | |||
inviteMsg.Recipient = new Nick() { Nickname = recipient }; | |||
inviteMsg.Channel = args; | |||
if (InviteChannelEvent != null) | |||
await Task.Run(() => | |||
{ | |||
InviteChannelEvent(this, inviteMsg); | |||
} | |||
if (InviteChannelEvent != null) | |||
{ | |||
InviteChannelEvent(this, inviteMsg); | |||
} | |||
}); | |||
break; | |||
// The message was a nick joining a channel | |||
case "JOIN": | |||
@@ -336,10 +387,13 @@ namespace Combot.IRCServices.Messaging | |||
joinMsg.Channel = recipient.TrimStart(':'); | |||
joinMsg.Nick = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost }; | |||
if (JoinChannelEvent != null) | |||
await Task.Run(() => | |||
{ | |||
JoinChannelEvent(this, joinMsg); | |||
} | |||
if (JoinChannelEvent != null) | |||
{ | |||
JoinChannelEvent(this, joinMsg); | |||
} | |||
}); | |||
break; | |||
// The message was a nick parting a channel | |||
case "PART": | |||
@@ -347,10 +401,13 @@ namespace Combot.IRCServices.Messaging | |||
partMsg.Channel = recipient; | |||
partMsg.Nick = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost }; | |||
if (PartChannelEvent != null) | |||
await Task.Run(() => | |||
{ | |||
PartChannelEvent(this, partMsg); | |||
} | |||
if (PartChannelEvent != null) | |||
{ | |||
PartChannelEvent(this, partMsg); | |||
} | |||
}); | |||
break; | |||
// The message was a nick being kicked from a channel | |||
case "KICK": | |||
@@ -365,10 +422,13 @@ namespace Combot.IRCServices.Messaging | |||
reasonArgs.RemoveAt(0); | |||
kickMsg.Reason = string.Join(" ", reasonArgs.ToArray()).Remove(0, 1); | |||
if (KickEvent != null) | |||
await Task.Run(() => | |||
{ | |||
KickEvent(this, kickMsg); | |||
} | |||
if (KickEvent != null) | |||
{ | |||
KickEvent(this, kickMsg); | |||
} | |||
}); | |||
break; | |||
// The message was a nick quiting the irc network | |||
case "QUIT": | |||
@@ -376,10 +436,13 @@ namespace Combot.IRCServices.Messaging | |||
quitMsg.Nick = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost }; | |||
quitMsg.Message = recipient.Remove(0, 1); | |||
if (QuitEvent != null) | |||
await Task.Run(() => | |||
{ | |||
QuitEvent(this, quitMsg); | |||
} | |||
if (QuitEvent != null) | |||
{ | |||
QuitEvent(this, quitMsg); | |||
} | |||
}); | |||
break; | |||
default: | |||
break; | |||
@@ -392,10 +455,13 @@ namespace Combot.IRCServices.Messaging | |||
PingInfo ping = new PingInfo(); | |||
ping.Message = match.Groups["Message"].Value; | |||
if (PingEvent != null) | |||
await Task.Run(() => | |||
{ | |||
PingEvent(this, ping); | |||
} | |||
if (PingEvent != null) | |||
{ | |||
PingEvent(this, ping); | |||
} | |||
}); | |||
} | |||
else if (pongRegex.IsMatch(message)) // The message was a PONG | |||
{ | |||
@@ -403,10 +469,13 @@ namespace Combot.IRCServices.Messaging | |||
PongInfo pong = new PongInfo(); | |||
pong.Message = match.Groups["Message"].Value; | |||
if (PongEvent != null) | |||
await Task.Run(() => | |||
{ | |||
PongEvent(this, pong); | |||
} | |||
if (PongEvent != null) | |||
{ | |||
PongEvent(this, pong); | |||
} | |||
}); | |||
} | |||
else if (errorRegex.IsMatch(message)) // The message was a server error | |||
{ | |||
@@ -420,14 +489,17 @@ namespace Combot.IRCServices.Messaging | |||
} | |||
} | |||
if (RawMessageEvent != null) | |||
await Task.Run(() => | |||
{ | |||
RawMessageEvent(this, message); | |||
} | |||
if (RawMessageEvent != null) | |||
{ | |||
RawMessageEvent(this, message); | |||
} | |||
}); | |||
} | |||
} | |||
internal bool GetReply(List<IRCReplyCode> ReplyCodes, List<IRCErrorCode> ErrorCodes) | |||
public bool GetReply(List<IRCReplyCode> ReplyCodes, List<IRCErrorCode> ErrorCodes) | |||
{ | |||
GetReply reply = new GetReply(); | |||
reply.Replies = ReplyCodes; |
@@ -43,18 +43,20 @@ namespace Interface.ViewModels | |||
{ | |||
Name = "#testing", | |||
Key = string.Empty | |||
}, | |||
}/*, | |||
new ChannelConfig() | |||
{ | |||
Name = "#/g/technology", | |||
Name = "#rice", | |||
Key = string.Empty | |||
} | |||
}*/ | |||
}; | |||
serverConfig.Name = "Rizon"; | |||
serverConfig.Nickname = "Combot_V3"; | |||
serverConfig.Realname = "Combot_Realname"; | |||
serverConfig.Username = "Combot_Username"; | |||
serverConfig.Password = "24121exe"; | |||
serverConfig.CommandPrefix = "."; | |||
serverConfig.JoinDelay = 1000; | |||
serverConfig.Hosts = new List<HostConfig> { new HostConfig() { Host = "irc.rizon.net", Port = 6667 } }; | |||
serverConfig.Modules = new List<Module> | |||
{ | |||
@@ -69,7 +71,7 @@ namespace Interface.ViewModels | |||
{ | |||
Name = "Ping Me", | |||
Description = "Checks the time it takes for a PING to be returned from a nick.", | |||
AllowedAccess = new List<AccessType>() | |||
AllowedAccess = new List<AccessType> | |||
{ | |||
AccessType.User, | |||
AccessType.Voice, | |||
@@ -79,27 +81,74 @@ namespace Interface.ViewModels | |||
AccessType.Founder, | |||
AccessType.Owner | |||
}, | |||
Triggers = new List<string>() | |||
Triggers = new List<string> | |||
{ | |||
"pingme" | |||
} | |||
} | |||
} | |||
}, | |||
new Module | |||
{ | |||
Name = "Invite", | |||
ClassName = "Invite", | |||
Enabled = true | |||
}, | |||
new Module | |||
{ | |||
Name = "Version", | |||
ClassName = "Version", | |||
Enabled = true, | |||
Commands = new List<Command> | |||
{ | |||
new Command | |||
{ | |||
Name = "Version Check", | |||
Description = "Sends a version CTCP request and displays the response.", | |||
AllowedAccess = new List<AccessType> | |||
{ | |||
AccessType.User, | |||
AccessType.Voice, | |||
AccessType.HalfOperator, | |||
AccessType.Operator, | |||
AccessType.SuperOperator, | |||
AccessType.Founder, | |||
AccessType.Owner | |||
}, | |||
Triggers = new List<string> | |||
{ | |||
"version", | |||
"ver" | |||
}, | |||
Arguments = new List<CommandArgument> | |||
{ | |||
new CommandArgument | |||
{ | |||
Name = "Nickname", | |||
Description = "The nickname you want to query for version information.", | |||
Required = true | |||
} | |||
} | |||
} | |||
} | |||
} | |||
}; | |||
Config.Servers.Add(serverConfig); | |||
Config.SaveServers(); | |||
Config.LoadServers(); | |||
foreach (ServerConfig server in Config.Servers) | |||
{ | |||
Bot Combot = new Bot(server); | |||
/* | |||
Combot.IRC.Message.ErrorMessageEvent += ErrorMessageHandler; | |||
Combot.IRC.Message.ServerReplyEvent += ServerReplyHandler; | |||
Combot.IRC.Message.ChannelMessageReceivedEvent += ChannelMessageReceivedHandler; | |||
Combot.IRC.Message.ChannelNoticeReceivedEvent += ChannelNoticeReceivedHandler; | |||
Combot.IRC.Message.PrivateMessageReceivedEvent += PrivateMessageReceivedHandler; | |||
Combot.IRC.Message.PrivateNoticeReceivedEvent += PrivateNoticeReceivedHandler; | |||
*/ | |||
Combot.IRC.Message.RawMessageEvent += RawMessageHandler; | |||
Combot.IRC.ConnectEvent += ConnectHandler; | |||
Combot.IRC.DisconnectEvent += DisconnectHandler; | |||
@@ -111,6 +160,11 @@ namespace Interface.ViewModels | |||
ToggleConnection = new DelegateCommand(ExecuteToggleConnection, CanToggleConnection); | |||
} | |||
private void RawMessageHandler(object sender, string message) | |||
{ | |||
CurrentBuffer += message + Environment.NewLine; | |||
} | |||
private void TCPErrorHandler(Combot.IRCServices.TCP.TCPError error) | |||
{ | |||
CurrentBuffer += string.Format("[{0}] {1}", error.Code.ToString(), error.Message) + Environment.NewLine; |
@@ -0,0 +1,32 @@ | |||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/@KeyIndexDefined">True</s:Boolean> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Description/@EntryValue">Module</s:String> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Text/@EntryValue">namespace $namespace$
 | |||
{
 | |||
public class $filename$ : Module
 | |||
{
 | |||
public override void Initialize()
 | |||
{
 | |||
} 
 | |||

 | |||
public override void ParseCommand(CommandMessage command)
 | |||
{
 | |||
}
 | |||
}
 | |||
}</s:String> | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Reformat/@EntryValue">True</s:Boolean> | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/ShortenQualifiedReferences/@EntryValue">True</s:Boolean> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/CustomProperties/=FileName/@EntryIndexedValue">NewModule</s:String> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/CustomProperties/=Extension/@EntryIndexedValue">cs</s:String> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/CustomProperties/=ValidateFileName/@EntryIndexedValue">False</s:String> | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Applicability/=File/@EntryIndexedValue">True</s:Boolean> | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Scope/=E8F0594528C33E45BBFEC6CFE851095D/@KeyIndexDefined">True</s:Boolean> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Scope/=E8F0594528C33E45BBFEC6CFE851095D/Type/@EntryValue">InCSharpProjectFile</s:String> | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/@KeyIndexDefined">True</s:Boolean> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/Expression/@EntryValue">getCurrentNamespace()</s:String> | |||
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/InitialRange/@EntryValue">-1</s:Int64> | |||
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/Order/@EntryValue">0</s:Int64> | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/@KeyIndexDefined">True</s:Boolean> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/Expression/@EntryValue">fileDefaultNamespace()</s:String> | |||
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/InitialRange/@EntryValue">-1</s:Int64> | |||
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/Order/@EntryValue">1</s:Int64></wpf:ResourceDictionary> |