commit 46ae523127624ffd9780fe954231d462e70a9e93 Author: Nicola Zangrandi Date: Thu Feb 8 09:21:36 2024 +0100 Split from monorepo diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b8cecca --- /dev/null +++ b/.gitignore @@ -0,0 +1,186 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ + +# Roslyn cache directories +*.ide/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +#NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding addin-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# If using the old MSBuild-Integrated Package Restore, uncomment this: +#!**/packages/repositories.config + +# Windows Azure Build Output +csx/ +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# config file containing private api keys +[Cc]onfig.json diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..1bf2d31 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,17 @@ +variables: + SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache + GIT_DEPTH: "0" # Tells git to fetch all the branches of the project, required by the analysis task +sonarcloud-check: + image: + name: sonarsource/sonar-scanner-cli:latest + entrypoint: [""] + cache: + key: "${CI_JOB_NAME}" + paths: + - .sonar/cache + script: + - sonar-scanner + only: + - x + - 2.0 + - 1.0 diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..a0833a9 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,10 @@ +language: csharp +solution: csbot.sln +mono: + - latest +install: + - nuget restore csbot.sln + - nuget install xunit.runners -Version 1.9.2 -OutputDirectory testrunner +script: + - xbuild /p:Configuration=Release csbot.sln + - mono ./testrunner/xunit.runners.1.9.2/tools/xunit.console.clr4.exe ./csbotTests/bin/Release/csbotTests.dll diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e87a115 --- /dev/null +++ b/LICENSE @@ -0,0 +1,363 @@ +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. "Contributor" + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. "Contributor Version" + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the terms of + a Secondary License. + +1.6. "Executable Form" + + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + + means a work that combines Covered Software with other material, in a + separate file or files, that is not Covered Software. + +1.8. "License" + + means this document. + +1.9. "Licensable" + + means having the right to grant, to the maximum extent possible, whether + at the time of the initial grant or subsequently, any and all of the + rights conveyed by this License. + +1.10. "Modifications" + + means any of the following: + + a. any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. "Patent Claims" of a Contributor + + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the License, + by the making, using, selling, offering for sale, having made, import, + or transfer of either its Contributions or its Contributor Version. + +1.12. "Secondary License" + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. "Source Code Form" + + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, "control" means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution + become effective for each Contribution on the date the Contributor first + distributes such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under + this License. No additional rights or licenses will be implied from the + distribution or licensing of Covered Software under this License. + Notwithstanding Section 2.1(b) above, no patent license is granted by a + Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of + its Contributions. + + This License does not grant any rights in the trademarks, service marks, + or logos of any Contributor (except as may be necessary to comply with + the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this + License (see Section 10.2) or under the terms of a Secondary License (if + permitted under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its + Contributions are its original creation(s) or it has sufficient rights to + grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under + applicable copyright doctrines of fair use, fair dealing, or other + equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under + the terms of this License. You must inform recipients that the Source + Code Form of the Covered Software is governed by the terms of this + License, and how they can obtain a copy of this License. You may not + attempt to alter or restrict the recipients' rights in the Source Code + Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter the + recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for + the Covered Software. If the Larger Work is a combination of Covered + Software with a work governed by one or more Secondary Licenses, and the + Covered Software is not Incompatible With Secondary Licenses, this + License permits You to additionally distribute such Covered Software + under the terms of such Secondary License(s), so that the recipient of + the Larger Work may, at their option, further distribute the Covered + Software under the terms of either this License or such Secondary + License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices + (including copyright notices, patent notices, disclaimers of warranty, or + limitations of liability) contained within the Source Code Form of the + Covered Software, except that You may alter any license notices to the + extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on + behalf of any Contributor. You must make it absolutely clear that any + such warranty, support, indemnity, or liability obligation is offered by + You alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, + judicial order, or regulation then You must: (a) comply with the terms of + this License to the maximum extent possible; and (b) describe the + limitations and the code they affect. Such description must be placed in a + text file included with all distributions of the Covered Software under + this License. Except to the extent prohibited by statute or regulation, + such description must be sufficiently detailed for a recipient of ordinary + skill to be able to understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing + basis, if such Contributor fails to notify You of the non-compliance by + some reasonable means prior to 60 days after You have come back into + compliance. Moreover, Your grants from a particular Contributor are + reinstated on an ongoing basis if such Contributor notifies You of the + non-compliance by some reasonable means, this is the first time You have + received notice of non-compliance with this License from such + Contributor, and You become compliant prior to 30 days after Your receipt + of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, + counter-claims, and cross-claims) alleging that a Contributor Version + directly or indirectly infringes any patent, then the rights granted to + You by any and all Contributors for the Covered Software under Section + 2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an "as is" basis, + without warranty of any kind, either expressed, implied, or statutory, + including, without limitation, warranties that the Covered Software is free + of defects, merchantable, fit for a particular purpose or non-infringing. + The entire risk as to the quality and performance of the Covered Software + is with You. Should any Covered Software prove defective in any respect, + You (not any Contributor) assume the cost of any necessary servicing, + repair, or correction. This disclaimer of warranty constitutes an essential + part of this License. No use of any Covered Software is authorized under + this License except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from + such party's negligence to the extent applicable law prohibits such + limitation. Some jurisdictions do not allow the exclusion or limitation of + incidental or consequential damages, so this exclusion and limitation may + not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts + of a jurisdiction where the defendant maintains its principal place of + business and such litigation shall be governed by laws of that + jurisdiction, without reference to its conflict-of-law provisions. Nothing + in this Section shall prevent a party's ability to bring cross-claims or + counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. Any law or regulation which provides that + the language of a contract shall be construed against the drafter shall not + be used to construe this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version + of the License under which You originally received the Covered Software, + or under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a + modified version of this License if you rename the license and remove + any references to the name of the license steward (except to note that + such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary + Licenses If You choose to distribute Source Code Form that is + Incompatible With Secondary Licenses under the terms of this version of + the License, the notice described in Exhibit B of this License must be + attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, +then You may include the notice in a location (such as a LICENSE file in a +relevant directory) where a recipient would be likely to look for such a +notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice + + This Source Code Form is "Incompatible + With Secondary Licenses", as defined by + the Mozilla Public License, v. 2.0. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..0db8851 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +csbot [![Build Status](https://travis-ci.org/nicolapcweek94/csbot.svg?branch=master)](https://travis-ci.org/nicolapcweek94/csbot) +===== + +Fuck Java. Fuck Perl. C# is where it's at. \ No newline at end of file diff --git a/csbot.sln b/csbot.sln new file mode 100644 index 0000000..a15b09d --- /dev/null +++ b/csbot.sln @@ -0,0 +1,36 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.22823.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "csbot", "csbot\csbot.csproj", "{67BB8FD9-E727-4F24-935E-E923531BF200}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{34648371-F0D9-44E5-B8B6-F7838945CA5F}" + ProjectSection(SolutionItems) = preProject + .gitignore = .gitignore + .travis.yml = .travis.yml + LICENSE = LICENSE + README.md = README.md + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "csbotTests", "csbotTests\csbotTests.csproj", "{619F047D-984A-4AD8-BCD8-6F37F03FE26E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {67BB8FD9-E727-4F24-935E-E923531BF200}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {67BB8FD9-E727-4F24-935E-E923531BF200}.Debug|Any CPU.Build.0 = Debug|Any CPU + {67BB8FD9-E727-4F24-935E-E923531BF200}.Release|Any CPU.ActiveCfg = Release|Any CPU + {67BB8FD9-E727-4F24-935E-E923531BF200}.Release|Any CPU.Build.0 = Release|Any CPU + {619F047D-984A-4AD8-BCD8-6F37F03FE26E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {619F047D-984A-4AD8-BCD8-6F37F03FE26E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {619F047D-984A-4AD8-BCD8-6F37F03FE26E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {619F047D-984A-4AD8-BCD8-6F37F03FE26E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/csbot/App.config b/csbot/App.config new file mode 100644 index 0000000..8e15646 --- /dev/null +++ b/csbot/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/csbot/Core/Config.cs b/csbot/Core/Config.cs new file mode 100644 index 0000000..04f3c05 --- /dev/null +++ b/csbot/Core/Config.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; + +namespace Csbot.Core +{ + /// + /// This class is used as a config file deserializer. Add any configuration parameter you need and make sure the JSON file has all of these. + /// + class Config + { + public User csbot { get; set; } + public String nick { get; set; } + public String password { get; set; } + public List channels { get; set; } + public List masters { get; set; } + public String server { get; set; } + public int port { get; set; } + public Char commandStart { get; set; } + public String lastFmApiKey { get; set; } + public String traktClientID { get; set; } + public bool debug { get; set; } + } +} diff --git a/csbot/Core/Core.cs b/csbot/Core/Core.cs new file mode 100644 index 0000000..7ff6c7c --- /dev/null +++ b/csbot/Core/Core.cs @@ -0,0 +1,74 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Sockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Csbot.Core +{ + /// + /// This class contains the core of csbot, including (and mostly limited to) the IRC communication handling. + /// + class Core + { + static void Main(string[] args) + { + Config config = JsonConvert.DeserializeObject(new StreamReader("config.json").ReadToEnd()); + config.csbot = new User(config.nick, "Csbot, the original.", ""); + TcpClient irc = new TcpClient(config.server, config.port); + NetworkStream ircStream = irc.GetStream(); + StreamReader ircIn = new StreamReader(ircStream); + StreamWriter ircOut = new StreamWriter(ircStream); + ircOut.AutoFlush = true; + + String line; + Message received; + + while ((line = ircIn.ReadLine()) != null) + { + if (config.debug) + { + Console.WriteLine(line); + } + + received = new Message(line, config.commandStart); + + if ("PING".Equals(received.action)) + { + Message pong = new Message(); + pong.line = "PONG :" + received.text; + pong.Send(ircOut, config.debug); + } + + if ("NOTICE".Equals(received.action) && (received.text.Contains("Found your hostname") || received.text.Contains("Your hostname does not match up"))) + { + config.csbot.getUserLine().Send(ircOut, config.debug); + config.csbot.getNickLine().Send(ircOut, config.debug); + } + + if ("422".Equals(received.action) || "376".Equals(received.action)) + { + Message nickServAuth = new Message("PRIVMSG NickServ :identify " + config.password); + nickServAuth.Send(ircOut, config.debug); + + foreach (String chan in config.channels) + { + Message join = new Message(); + join.line = "JOIN " + chan; + join.Send(ircOut, config.debug); + } + } + + if (received.isCommand) + { + Thread parser = new Thread(Parser.Run); + parser.Start(new ParserParameters(received, config, ircOut)); + } + } + } + } +} diff --git a/csbot/Core/Host.cs b/csbot/Core/Host.cs new file mode 100644 index 0000000..2f91ba3 --- /dev/null +++ b/csbot/Core/Host.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Csbot.Core +{ + /// + /// This class implements the ISender interface and represents a host sending messages on IRC (such as the IRCd itself). + /// + class Host : ISender + { + public String host { get; set; } + public String nick { get; set; } + public String realname { get; set; } + + /// + /// Public constructor for the class. + /// + /// The hostname of the host. + public Host(String host) + { + this.host = host; + this.nick = null; + this.realname = null; + } + } +} diff --git a/csbot/Core/ISender.cs b/csbot/Core/ISender.cs new file mode 100644 index 0000000..327ed58 --- /dev/null +++ b/csbot/Core/ISender.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Csbot.Core +{ + /// + /// This interface represents every "entity" that could be sending a message on an IRCd. + /// Implemented in the User and Host classes. + /// + public interface ISender + { + String host { get; set; } + String nick { get; set; } + String realname { get; set; } + } +} diff --git a/csbot/Core/Message.cs b/csbot/Core/Message.cs new file mode 100644 index 0000000..3a222a1 --- /dev/null +++ b/csbot/Core/Message.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Csbot.Core +{ + /// + /// The Message class is used to store any message sent to/received from the IRCd. + /// This class makes message parsing look easy, but it really isn't. + /// + public class Message + { + public String line { get; set; } + public String action { get; set; } + public String text { get; set; } + public String channel { get; set; } + public String command { get; set; } + public ISender author; + public bool isCommand; + + /// + /// Public constructor for the Message class. + /// Please call this to parse received messages, don't just simply assign values to the properties. + /// + /// The message from start to newline, as received from the server. + /// A Char indicating the start character for bot commands, as defined in the config file. + public Message(String line, Char commandStart) + { + this.line = line; + String[] parts = this.line.Split(' '); + + if ("PING".Equals(parts[0])) + { + this.action = "PING"; + this.text = parts[1]; + this.channel = null; + this.author = new Host(parts[1].Substring(1)); + this.isCommand = false; + this.command = null; + return; + } + + if (parts[0].Contains("!") && parts[0].Contains("@")) + { + this.author = new User(parts[0].Substring(1, parts[0].IndexOf("!") - 1), + parts[0].Substring(parts[0].IndexOf("!"), (parts[0].IndexOf("@") - parts[0].IndexOf("!"))), + parts[0].Substring(parts[0].IndexOf("@"), (parts[0].Length - parts[0].IndexOf("@")))); + } + else + { + this.author = new Host(parts[0].Substring(1)); + } + + if ("NOTICE".Equals(parts[1])) + { + this.action = "NOTICE"; + this.text = this.line.Substring(this.line.IndexOf(" :") + 2); + this.channel = parts[2]; + return; + } + + if ("PRIVMSG".Equals(parts[1])) + { + this.action = "PRIVMSG"; + this.text = this.line.Substring(this.line.IndexOf(" :") + 2); + this.channel = parts[2]; + + if (commandStart == this.text[0]) + { + this.isCommand = true; + this.command = this.text.Contains(" ") ? this.text.Substring(1, this.text.IndexOf(" ") - 1) : this.text.Substring(1, this.text.Length - 1); + } + else + { + this.isCommand = false; + this.command = null; + } + return; + } + else + { + //TODO pls add parsing here + this.action = parts[1]; + this.text = null; + this.channel = null; + this.isCommand = false; + this.command = null; + } + } + + /// + /// Please please please only use this constructor for outgoing PRIVMSGs. + /// + /// The message to be sent to the server. + public Message(String line) + { + this.line = line; + this.action = "PRIVMSG"; + this.channel = this.line.Split(' ')[1]; + this.text = this.line.Substring(this.line.IndexOf(" :") + 2); + } + + /// + /// Empty constructor, pls do not use. Only used to build messages sent during startup. + /// + public Message() + { + this.line = null; + this.action = null; + this.text = null; + this.channel = null; + this.command = null; + this.author = null; + this.isCommand = false; + } + + /// + /// This function splits messages (PRIVMSGs only) over 512 chars in two or more lines, as required by the RFC. + /// + /// The list of messages ready to be sent. + protected List Split() + { + List ret = new List { }; + + if (this.line.Length > 510 && "PRIVMSG".Equals(this.action)) + { + for (int i = 0; i <= this.line.Length / 510; i++) + { + ret.Add(this.action + " " + this.channel + " :" + this.text.Substring(i * 510, 510)); //yay, math. But no, really, twy it, it works. + } + } + else + { + ret.Add(this.line); + } + + return ret; + } + + /// + /// This functions takes care of sending the message, splitting it in more than one lines if necessary. + /// + /// The StreamWriter to write the message(s) to. + public void Send(StreamWriter sock, bool debug) + { + foreach (String line in this.Split()) + { + if (debug) + Console.WriteLine(line); + sock.WriteLine(line); + } + } + } +} diff --git a/csbot/Core/Parser.cs b/csbot/Core/Parser.cs new file mode 100644 index 0000000..aab7bce --- /dev/null +++ b/csbot/Core/Parser.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Csbot.Core +{ + /// + /// This class does all the parsing for actual bot commands. + /// + class Parser + { + public static void Run(object param) + { + ParserParameters vars = (ParserParameters)param; + + if (vars.config.masters.Contains(vars.received.author.nick)) //no need to check for stuff to be not null, a command can only be issued by a User. + { + // %quit + if ("quit".Equals(vars.received.command)) + { + vars.ircOut.Close(); + Environment.Exit(0); + } + + // %join #channel + if ("join".Equals(vars.received.command)) + { + vars.config.channels.Add(vars.received.text.Split(' ')[1]); + Message join = new Message(); + join.line = "JOIN " + vars.received.text.Split(' ')[1]; + join.Send(vars.ircOut, vars.config.debug); + } + + // %part #channel + if ("part".Equals(vars.received.command)) + { + vars.config.channels.Remove(vars.received.text.Split(' ')[1]); + Message part = new Message(); + part.line = "PART " + vars.received.text.Split(' ')[1]; + part.Send(vars.ircOut, vars.config.debug); + } + + // %masteradd nick + if ("masteradd".Equals(vars.received.command)) + { + vars.config.masters.Add(vars.received.text.Split(' ')[1]); + } + + // %masterdel nick + if ("masterdel".Equals(vars.received.command)) + { + vars.config.masters.Remove(vars.received.text.Split(' ')[1]); + } + } + + // %roll ndn + if ("roll".Equals(vars.received.command)) + { + int dice = Convert.ToInt32(vars.received.text.Split(' ')[1].Split('d')[0]); + int num = Convert.ToInt32(vars.received.text.Split(' ')[1].Split('d')[1]); + Random r = new Random(); + int result = r.Next(dice * num); + Message res = new Message(); + res.line = "PRIVMSG " + vars.received.channel + " :" + result.ToString(); + res.Send(vars.ircOut, vars.config.debug); + } + + // %lastfm + } + } +} diff --git a/csbot/Core/ParserParameters.cs b/csbot/Core/ParserParameters.cs new file mode 100644 index 0000000..e96478e --- /dev/null +++ b/csbot/Core/ParserParameters.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Csbot.Core +{ + /// + /// Helper class used to pass parameters to the Parser.Run function. + /// + class ParserParameters + { + public Message received { get; set; } + public Config config { get; set; } + public StreamWriter ircOut { get; set; } + + public ParserParameters(Message recv, Config conf, StreamWriter irc) + { + this.received = recv; + this.config = conf; + this.ircOut = irc; + } + } +} diff --git a/csbot/Core/User.cs b/csbot/Core/User.cs new file mode 100644 index 0000000..b0264e1 --- /dev/null +++ b/csbot/Core/User.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Csbot.Core +{ + /// + /// This class implements the ISender interface and represents a "huamn" user (or a bot, or anything pretending to be human on IRC). + /// + class User : ISender + { + public String host { get; set; } + public String nick { get; set; } + public String realname { get; set; } + + /// + /// Public constructor for the class. + /// + /// The user's nickname. + /// The user's realname. + /// The user's hostname. + public User(String nick, String realname, String host) + { + this.nick = nick; + this.realname = realname; + this.host = host; + } + + /// + /// This function returns a Message ready to be sent as a USER command. + /// + /// The USER command. + public Message getUserLine() + { + Message ret = new Message(); + ret.line = "USER " + this.nick + " 0 * :" + realname; + return ret; + } + + /// + /// This functions returns a Message ready to be sent as a NICK command. + /// + /// The NICK command. + public Message getNickLine() + { + Message ret = new Message(); + ret.line = "NICK " + this.nick; + return ret; + } + } +} diff --git a/csbot/Properties/AssemblyInfo.cs b/csbot/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..6ffd4ba --- /dev/null +++ b/csbot/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("csbot")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("csbot")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("0395e1b8-cc1a-40fe-b4a7-f8885694ff42")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/csbot/csbot.csproj b/csbot/csbot.csproj new file mode 100644 index 0000000..a4beb77 --- /dev/null +++ b/csbot/csbot.csproj @@ -0,0 +1,76 @@ + + + + + Debug + AnyCPU + {67BB8FD9-E727-4F24-935E-E923531BF200} + Exe + Properties + Csbot + csbot + v4.5 + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll + + + + + + + + + + + + + + + + + + + + + + + + + Designer + + + + + + + + \ No newline at end of file diff --git a/csbot/packages.config b/csbot/packages.config new file mode 100644 index 0000000..747efc5 --- /dev/null +++ b/csbot/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/csbotTests/MessageTests.cs b/csbotTests/MessageTests.cs new file mode 100644 index 0000000..7649e75 --- /dev/null +++ b/csbotTests/MessageTests.cs @@ -0,0 +1,16 @@ +using System; +using Xunit; +using Csbot.Core; + +namespace CsbotTests +{ + public class MessageTests + { + [Fact] + public void NewMessage_StandardScenario_PRIVMSG() + { + Message msg = new Message(":nicolapcweek94!test@lol PRIVMSG #test :test lol", '%'); + Assert.Equal("PRIVMSG", msg.action); + } + } +} diff --git a/csbotTests/Properties/AssemblyInfo.cs b/csbotTests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..d61f494 --- /dev/null +++ b/csbotTests/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("csbotTests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("csbotTests")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("619f047d-984a-4ad8-bcd8-6f37f03fe26e")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/csbotTests/csbotTests.csproj b/csbotTests/csbotTests.csproj new file mode 100644 index 0000000..1d46945 --- /dev/null +++ b/csbotTests/csbotTests.csproj @@ -0,0 +1,84 @@ + + + + + + Debug + AnyCPU + {619F047D-984A-4AD8-BCD8-6F37F03FE26E} + Library + Properties + csbotTests + csbotTests + v4.5.2 + 512 + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + ..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll + True + + + ..\packages\xunit.assert.2.1.0-beta1-build2945\lib\portable-net45+aspnetcore50+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.assert.dll + True + + + ..\packages\xunit.extensibility.core.2.1.0-beta1-build2945\lib\portable-net45+aspnetcore50+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.dll + True + + + + + + + + + + + + {67bb8fd9-e727-4f24-935e-e923531bf200} + csbot + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/csbotTests/packages.config b/csbotTests/packages.config new file mode 100644 index 0000000..f7f57aa --- /dev/null +++ b/csbotTests/packages.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file