├── .gitignore ├── README.md ├── WebMatBot ├── AutomaticMessages │ ├── AutomaticMessages.cs │ └── ScheduledMessage.cs ├── Config │ ├── Parameters.cs │ └── StreamerDefault.cs ├── Core │ ├── IrcEngine.cs │ ├── PubSubEngine.cs │ └── TasksQueueOutput.cs ├── Games │ ├── Cannon.cs │ └── Cannon_Store.cs ├── General │ ├── Cache.cs │ ├── Commands.cs │ ├── Screens.cs │ └── Sounds.cs ├── LedArt │ └── Test.cs ├── Lights │ ├── AudioVisual.cs │ └── Light.cs ├── Program.cs ├── Sounds │ ├── General │ │ ├── aplausos.mp3 │ │ ├── rimshot.mp3 │ │ └── xandao.mp3 │ ├── Party │ │ ├── baby-shark.mp3 │ │ ├── naruto-trap.mp3 │ │ ├── sbtrapvinebycarb0n.mp3 │ │ ├── trap_android.mp3 │ │ └── yoshi_gets_lit_trap_remixgrabfrom.mp3 │ └── Troll │ │ ├── ajuda-o-maluco.mp3 │ │ ├── batida-de-porta-troll.mp3 │ │ ├── birl.mp3 │ │ ├── cavalo.mp3 │ │ ├── choque-da-uva.mp3 │ │ ├── eoq.mp3 │ │ ├── failhorn.mp3 │ │ ├── faustao-errou.mp3 │ │ ├── hadouken.mp3 │ │ ├── kasino.mp3 │ │ ├── metalgearsolid.swf.mp3 │ │ ├── olha_a_pedra.mp3 │ │ ├── quack.mp3 │ │ ├── que-ota.mp3 │ │ ├── tafareeel.mp3 │ │ ├── vergonha.mp3 │ │ ├── xandao.mp3 │ │ ├── xaropinho.mp3 │ │ └── zach.mp3 ├── Speakers │ ├── AzureSpeakers.cs │ ├── GoogleSpeakers.cs │ ├── SSML.xml │ ├── Speaker.cs │ └── SpeakerCore.cs ├── Subtitles │ └── Subtitle.cs ├── Translator │ ├── AutomaticTranslator.cs │ └── Translate.cs └── WebMatBot.csproj ├── WebMatBotV3 ├── Client │ ├── App.razor │ ├── Pages │ │ ├── Index.razor │ │ └── Subtitle.razor │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Shared │ │ ├── MainLayout.razor │ │ ├── MainLayout.razor.css │ │ ├── NavMenu.razor │ │ ├── NavMenu.razor.css │ │ └── SurveyPrompt.razor │ ├── WebMatBotV3.Client.csproj │ ├── _Imports.razor │ └── wwwroot │ │ ├── css │ │ ├── app.css │ │ ├── bootstrap │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ └── open-iconic │ │ │ ├── FONT-LICENSE │ │ │ ├── ICON-LICENSE │ │ │ └── font │ │ │ ├── css │ │ │ └── open-iconic-bootstrap.min.css │ │ │ └── fonts │ │ │ ├── open-iconic.eot │ │ │ ├── open-iconic.otf │ │ │ ├── open-iconic.svg │ │ │ ├── open-iconic.ttf │ │ │ └── open-iconic.woff │ │ ├── favicon.ico │ │ └── index.html ├── Server │ ├── .config │ │ └── dotnet-tools.json │ ├── Controllers │ │ └── CommandController.cs │ ├── Hubs │ │ ├── CannonHub.cs │ │ └── SubtitleHub.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Services │ │ ├── CannonService.cs │ │ ├── ContextCache.cs │ │ └── WebMatBotService.cs │ ├── Startup.cs │ ├── WebMatBotV3.Server.csproj │ ├── appsettings.Development.json │ └── appsettings.json └── Shared │ ├── Command.cs │ ├── DataContext.cs │ ├── Entity │ ├── Balls.cs │ ├── IRankItem.cs │ ├── Inventories.cs │ ├── Invitations.cs │ ├── Points.cs │ ├── Records.cs │ ├── Resources.cs │ ├── Scores.cs │ ├── Seasons.cs │ ├── SubscribersResources.cs │ └── Usernames.cs │ ├── Extensions │ └── Extension.cs │ ├── ICannonClient.cs │ ├── UserTitle.cs │ └── WebMatBotV3.Shared.csproj └── WebMatTwitchBot.sln /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | [Ll]ogs/ 33 | 34 | # Visual Studio 2015/2017 cache/options directory 35 | .vs/ 36 | # Uncomment if you have tasks that create the project's static files in wwwroot 37 | #wwwroot/ 38 | 39 | # Visual Studio 2017 auto generated files 40 | Generated\ Files/ 41 | 42 | # MSTest test Results 43 | [Tt]est[Rr]esult*/ 44 | [Bb]uild[Ll]og.* 45 | 46 | # NUnit 47 | *.VisualState.xml 48 | TestResult.xml 49 | nunit-*.xml 50 | 51 | # Build Results of an ATL Project 52 | [Dd]ebugPS/ 53 | [Rr]eleasePS/ 54 | dlldata.c 55 | 56 | # Benchmark Results 57 | BenchmarkDotNet.Artifacts/ 58 | 59 | # .NET Core 60 | project.lock.json 61 | project.fragment.lock.json 62 | artifacts/ 63 | 64 | # StyleCop 65 | StyleCopReport.xml 66 | 67 | # Files built by Visual Studio 68 | *_i.c 69 | *_p.c 70 | *_h.h 71 | *.ilk 72 | *.meta 73 | *.obj 74 | *.iobj 75 | *.pch 76 | *.pdb 77 | *.ipdb 78 | *.pgc 79 | *.pgd 80 | *.rsp 81 | *.sbr 82 | *.tlb 83 | *.tli 84 | *.tlh 85 | *.tmp 86 | *.tmp_proj 87 | *_wpftmp.csproj 88 | *.log 89 | *.vspscc 90 | *.vssscc 91 | .builds 92 | *.pidb 93 | *.svclog 94 | *.scc 95 | 96 | # Chutzpah Test files 97 | _Chutzpah* 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opendb 104 | *.opensdf 105 | *.sdf 106 | *.cachefile 107 | *.VC.db 108 | *.VC.VC.opendb 109 | 110 | # Visual Studio profiler 111 | *.psess 112 | *.vsp 113 | *.vspx 114 | *.sap 115 | 116 | # Visual Studio Trace Files 117 | *.e2e 118 | 119 | # TFS 2012 Local Workspace 120 | $tf/ 121 | 122 | # Guidance Automation Toolkit 123 | *.gpState 124 | 125 | # ReSharper is a .NET coding add-in 126 | _ReSharper*/ 127 | *.[Rr]e[Ss]harper 128 | *.DotSettings.user 129 | 130 | # TeamCity is a build add-in 131 | _TeamCity* 132 | 133 | # DotCover is a Code Coverage Tool 134 | *.dotCover 135 | 136 | # AxoCover is a Code Coverage Tool 137 | .axoCover/* 138 | !.axoCover/settings.json 139 | 140 | # Visual Studio code coverage results 141 | *.coverage 142 | *.coveragexml 143 | 144 | # NCrunch 145 | _NCrunch_* 146 | .*crunch*.local.xml 147 | nCrunchTemp_* 148 | 149 | # MightyMoose 150 | *.mm.* 151 | AutoTest.Net/ 152 | 153 | # Web workbench (sass) 154 | .sass-cache/ 155 | 156 | # Installshield output folder 157 | [Ee]xpress/ 158 | 159 | # DocProject is a documentation generator add-in 160 | DocProject/buildhelp/ 161 | DocProject/Help/*.HxT 162 | DocProject/Help/*.HxC 163 | DocProject/Help/*.hhc 164 | DocProject/Help/*.hhk 165 | DocProject/Help/*.hhp 166 | DocProject/Help/Html2 167 | DocProject/Help/html 168 | 169 | # Click-Once directory 170 | publish/ 171 | 172 | # Publish Web Output 173 | *.[Pp]ublish.xml 174 | *.azurePubxml 175 | # Note: Comment the next line if you want to checkin your web deploy settings, 176 | # but database connection strings (with potential passwords) will be unencrypted 177 | *.pubxml 178 | *.publishproj 179 | 180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 181 | # checkin your Azure Web App publish settings, but sensitive information contained 182 | # in these scripts will be unencrypted 183 | PublishScripts/ 184 | 185 | # NuGet Packages 186 | *.nupkg 187 | # NuGet Symbol Packages 188 | *.snupkg 189 | # The packages folder can be ignored because of Package Restore 190 | **/[Pp]ackages/* 191 | # except build/, which is used as an MSBuild target. 192 | !**/[Pp]ackages/build/ 193 | # Uncomment if necessary however generally it will be regenerated when needed 194 | #!**/[Pp]ackages/repositories.config 195 | # NuGet v3's project.json files produces more ignorable files 196 | *.nuget.props 197 | *.nuget.targets 198 | 199 | # Microsoft Azure Build Output 200 | csx/ 201 | *.build.csdef 202 | 203 | # Microsoft Azure Emulator 204 | ecf/ 205 | rcf/ 206 | 207 | # Windows Store app package directories and files 208 | AppPackages/ 209 | BundleArtifacts/ 210 | Package.StoreAssociation.xml 211 | _pkginfo.txt 212 | *.appx 213 | *.appxbundle 214 | *.appxupload 215 | 216 | # Visual Studio cache files 217 | # files ending in .cache can be ignored 218 | *.[Cc]ache 219 | # but keep track of directories ending in .cache 220 | !?*.[Cc]ache/ 221 | 222 | # Others 223 | ClientBin/ 224 | ~$* 225 | *~ 226 | *.dbmdl 227 | *.dbproj.schemaview 228 | *.jfm 229 | *.pfx 230 | *.publishsettings 231 | orleans.codegen.cs 232 | 233 | # Including strong name files can present a security risk 234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 235 | #*.snk 236 | 237 | # Since there are multiple workflows, uncomment next line to ignore bower_components 238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 239 | #bower_components/ 240 | 241 | # RIA/Silverlight projects 242 | Generated_Code/ 243 | 244 | # Backup & report files from converting an old project file 245 | # to a newer Visual Studio version. Backup files are not needed, 246 | # because we have git ;-) 247 | _UpgradeReport_Files/ 248 | Backup*/ 249 | UpgradeLog*.XML 250 | UpgradeLog*.htm 251 | ServiceFabricBackup/ 252 | *.rptproj.bak 253 | 254 | # SQL Server files 255 | *.mdf 256 | *.ldf 257 | *.ndf 258 | 259 | # Business Intelligence projects 260 | *.rdl.data 261 | *.bim.layout 262 | *.bim_*.settings 263 | *.rptproj.rsuser 264 | *- [Bb]ackup.rdl 265 | *- [Bb]ackup ([0-9]).rdl 266 | *- [Bb]ackup ([0-9][0-9]).rdl 267 | 268 | # Microsoft Fakes 269 | FakesAssemblies/ 270 | 271 | # GhostDoc plugin setting file 272 | *.GhostDoc.xml 273 | 274 | # Node.js Tools for Visual Studio 275 | .ntvs_analysis.dat 276 | node_modules/ 277 | 278 | # Visual Studio 6 build log 279 | *.plg 280 | 281 | # Visual Studio 6 workspace options file 282 | *.opt 283 | 284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 285 | *.vbw 286 | 287 | # Visual Studio LightSwitch build output 288 | **/*.HTMLClient/GeneratedArtifacts 289 | **/*.DesktopClient/GeneratedArtifacts 290 | **/*.DesktopClient/ModelManifest.xml 291 | **/*.Server/GeneratedArtifacts 292 | **/*.Server/ModelManifest.xml 293 | _Pvt_Extensions 294 | 295 | # Paket dependency manager 296 | .paket/paket.exe 297 | paket-files/ 298 | 299 | # FAKE - F# Make 300 | .fake/ 301 | 302 | # CodeRush personal settings 303 | .cr/personal 304 | 305 | # Python Tools for Visual Studio (PTVS) 306 | __pycache__/ 307 | *.pyc 308 | 309 | # Cake - Uncomment if you are using it 310 | # tools/** 311 | # !tools/packages.config 312 | 313 | # Tabs Studio 314 | *.tss 315 | 316 | # Telerik's JustMock configuration file 317 | *.jmconfig 318 | 319 | # BizTalk build output 320 | *.btp.cs 321 | *.btm.cs 322 | *.odx.cs 323 | *.xsd.cs 324 | 325 | # OpenCover UI analysis results 326 | OpenCover/ 327 | 328 | # Azure Stream Analytics local run output 329 | ASALocalRun/ 330 | 331 | # MSBuild Binary and Structured Log 332 | *.binlog 333 | 334 | # NVidia Nsight GPU debugger configuration file 335 | *.nvuser 336 | 337 | # MFractors (Xamarin productivity tool) working folder 338 | .mfractor/ 339 | 340 | # Local History for Visual Studio 341 | .localhistory/ 342 | 343 | # BeatPulse healthcheck temp database 344 | healthchecksdb 345 | 346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 347 | MigrationBackup/ 348 | 349 | # Ionide (cross platform F# VS Code tools) working folder 350 | .ionide/ 351 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WebMatTwitchBot 2 | Um simples bot para automatizar o chat do seu canal na twitch. 3 | 4 | ## Considerações: 5 | A finalidade deste bot é trazer uma maior proximidade entre o público da twitch e a linguagem de programação C#
6 | O bot, por padrão, é o mesmo usuário do canal que se deseja o bot.
7 | Existem dois modelos de Text to Speech (TTS) (texto para fala):
8 | A - Comando !Speak chama o power shell e utiliza o idioma padrão do seu windows para reproduzir a fala.
9 | B - (removido do código princial) - Comando !SpeakPt ou !SpeakEn chama o azure serviços cognitivos para reproduzir a fala (necessita configuração)
10 | C - Comando !SpeakPt ou !SpeakEn chama o google cloud api text-to-speech para reproduzir a fala (necessita configuração)
11 | 12 | ## Primeiro run 13 | Por segurança, o arquivo Parameters.cs vem com seus campos em branco. É necessário fazer o preenchimento antes de rodar o bot. 14 | 15 | 1 - Para receber o valor da propriedade oauth, acesse https://twitchapps.com/tmi/ e conecte-se utilizando a conta que deseja ter o botchat.
16 | 2 - Copie o codigo mostrado no item anterior e cole no campo oauth, no campo user preencha com o mesmo usuario utilizado anteriormente.
17 | B - (removido do código princial) - Caso você deseja utilizar o !speakPt !speakEn entre outros (azure serviços cognitivos) é necessário ir em : www.portal.azure.com, cadastrar-se, e instalar Serviço Cognitivo.
18 | C - Caso você deseja utilizar o !speakPt !speakEn (google cloud api text-to-speech) é necessário ir em : https://googleapis.dev/dotnet/Google.Cloud.TextToSpeech.V1/2.0.0/index.html, cadastrar-se, e instalar siga os passos recomendados pelo próprio google.
19 | 20 | ## Customização 21 | Você pode customizar os comandos e respostas do bot indo até Commands.cs adicionando um novo item no campo List. (Se você sentir alguma dificuldade consulte itens já inseridos)
22 | Você pode customizar os registros em cache indo até Cache.cs. (Vide exemplo entre Cache.cs e Commands.cs)
23 | Por padrão o Text-to-Speech vem desabilitado, para habilita-lo digite no console !setspeaker true 24 | 25 | ## Considerações finais 26 | O processo de criação do bot foi todo produzido em live no canal www.twitch.tv/webmat1. Qualquer dúvida, sugestão e/ou reclamação, pode ser encaminhado pela twitch também.
27 | Agradaço a todos que participaram do processo de criação e tiveram compreensão da não complexidade deste bot, pois a finalidade maior é torná-lo um caminho acessivel ao C#.
28 | 29 | 30 | 31 | Just a bot to respond your twitch chat. 32 | 33 | ## Firstly 34 | The main idea is turning people on twitch next to programmming language c#.
35 | By default, our bot uses the same userbot and channel target.
36 | There are two ways to use Text-to-Speech (TTS):
37 | A - Command !Speak, this uses the power shell to call all librarys. So its works fine on windows
38 | B - (depreciated) - Command !SpeakPt or !SpeakEn, this uses azure cognitive services to do a machine speak
39 | C - Command !SpeakPt or !SpeakEn (etc.), this uses google cloud api text-to-speech to do a machine speak
40 | 41 | ## First run 42 | For security, Parameters.cs file has your fields empty. Its necessary fill it before first run. 43 | 44 | 1 - To get the value to fill oauth field, access https://twitchapps.com/tmi/ and click on Connect button.
45 | 2 - Copy the code on before step and fill oauth field. user field must be filled with the same user used before.
46 | B - (depreciated) - If you are going to use !SpeakPt or !SpeakEn (google cloud api text-to-speech) you need follow all steps in https://googleapis.dev/dotnet/Google.Cloud.TextToSpeech.V1/2.0.0/index.html; Maybe you should sign-in and install the google cloud api.
47 | 48 | ## Customization 49 | You can change all commands in Commands.cs, List field. (You can see examples there)
50 | You can change all cached items in Chache.cs. (Its good to insert a command in Commands.cs as well)
51 | By default TTS is disabled, to enable you must type "!setspeaker true" on console.
52 | 53 | ## Final Considerations 54 | This bot was built on stream in www.twitch.tv/webmat1. Feel free to send your suggestion there.
55 | Thank's to all people no stream who gave me feedback, suggestions and fixes.
56 | -------------------------------------------------------------------------------- /WebMatBot/AutomaticMessages/AutomaticMessages.cs: -------------------------------------------------------------------------------- 1 | using Google.Api; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Runtime.CompilerServices; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using static WebMatBot.ScheduledMessage; 10 | 11 | namespace WebMatBot 12 | { 13 | public class AutomaticMessages 14 | { 15 | public static DateTime LastMessage { get; set; } = DateTime.Now.AddMinutes(-5); 16 | private static TimeSpan SpaceBetweenMessages = new TimeSpan(0,30,0); 17 | 18 | private static List ScheduledQueue = new List(); 19 | private static List LiquidQueue = new List(); 20 | 21 | 22 | public static async Task StartScheduled() 23 | { 24 | //inicialização tempo 25 | await Task.Delay(new TimeSpan(0, 1, 0)); 26 | 27 | lock (ScheduledQueue) 28 | { 29 | ScheduledQueue.Add(DrinkWater(DateTime.Now)); 30 | ScheduledQueue.Add(Discord(DateTime.Now)); 31 | ScheduledQueue.Add(Youtube(DateTime.Now)); 32 | ScheduledQueue.Add(GitHub(DateTime.Now)); 33 | ScheduledQueue.Add(Donate(DateTime.Now)); 34 | //Queue.Add(Form(DateTime.Now)); 35 | } 36 | 37 | 38 | do 39 | { 40 | ScheduledMessage Item; 41 | 42 | lock (ScheduledQueue) 43 | Item = ScheduledQueue.OrderBy(q => q.DateSchedule).FirstOrDefault(item => item.DateSchedule <= DateTime.Now && DateTime.Now >= LastMessage.Add(SpaceBetweenMessages)); 44 | 45 | if (Item != null) 46 | Item.Action.Invoke(Item); 47 | 48 | await Task.Delay(20000); 49 | } 50 | while (true); 51 | } 52 | 53 | public static async Task StartLiquid() 54 | { 55 | //inicialização tempo 56 | await Task.Delay(new TimeSpan(0, 45, 0)); 57 | 58 | lock (LiquidQueue) 59 | { 60 | LiquidQueue.Add(Commercial(DateTime.Now)); 61 | } 62 | 63 | 64 | do 65 | { 66 | ScheduledMessage Item; 67 | 68 | lock (LiquidQueue) 69 | Item = LiquidQueue.OrderBy(q => q.DateSchedule).FirstOrDefault(item => item.DateSchedule <= DateTime.Now); 70 | 71 | if (Item != null) 72 | Item.Action.Invoke(Item); 73 | 74 | await Task.Delay(20000); 75 | } 76 | while (true); 77 | } 78 | 79 | public static void AddScheduledQueue(ScheduledMessage Item) 80 | { 81 | lock (ScheduledQueue) 82 | ScheduledQueue.Add(Item); 83 | } 84 | 85 | public static void RemoveScheduledQueue(MessageType type) 86 | { 87 | ScheduledMessage item; 88 | lock (ScheduledQueue) 89 | item = ScheduledQueue.FirstOrDefault(q => q.TypeInfo == type); 90 | 91 | if (item != null) 92 | ScheduledQueue.Remove(item); 93 | } 94 | 95 | public static void AddLiquidQueue(ScheduledMessage Item) 96 | { 97 | lock (ScheduledQueue) 98 | LiquidQueue.Add(Item); 99 | } 100 | 101 | public static void RemoveLiquidQueue(MessageType type) 102 | { 103 | ScheduledMessage item; 104 | lock (LiquidQueue) 105 | item = LiquidQueue.FirstOrDefault(q => q.TypeInfo == type); 106 | 107 | if (item != null) 108 | LiquidQueue.Remove(item); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /WebMatBot/AutomaticMessages/ScheduledMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.CompilerServices; 4 | using System.Text; 5 | using System.Threading; 6 | using WebMatBot.Core; 7 | 8 | namespace WebMatBot 9 | { 10 | public class ScheduledMessage 11 | { 12 | public DateTime DateSchedule { get; set; } 13 | public Action Action { get; set; } 14 | public TimeSpan WaitingTime { get; set; } 15 | public string Message { get; set; } 16 | public MessageType TypeInfo { get; set; } 17 | 18 | public ScheduledMessage(DateTime dateSche, Action act, TimeSpan waitTime, string message, MessageType type) 19 | { 20 | DateSchedule = dateSche; 21 | Action = act; 22 | WaitingTime = waitTime; 23 | Message = message; 24 | TypeInfo = type; 25 | } 26 | 27 | public static ScheduledMessage Discord(DateTime date) => 28 | new ScheduledMessage(date, async (ScheduledMessage schM) => 29 | { 30 | if (DateTime.Now >= AutomaticMessages.LastMessage) 31 | { 32 | //envia a mensagem 33 | await IrcEngine.Respond(schM.Message); 34 | 35 | AutomaticMessages.LastMessage = DateTime.Now; 36 | 37 | AutomaticMessages.RemoveScheduledQueue(schM.TypeInfo); 38 | AutomaticMessages.AddScheduledQueue(Discord(DateTime.Now.AddMinutes(schM.WaitingTime.TotalMinutes))); 39 | } 40 | 41 | }, 42 | new TimeSpan(0, 45, 0), // 43 | "Você também pode participar do nosso discord... // "+ 44 | " Join us on Discord... " + StreamerDefault.Discord, 45 | MessageType.Discord); 46 | 47 | public static ScheduledMessage Youtube(DateTime date) => 48 | new ScheduledMessage(date,async (ScheduledMessage schM) => 49 | { 50 | if (DateTime.Now >= AutomaticMessages.LastMessage) 51 | { 52 | //envia a mensagem 53 | await IrcEngine.Respond(schM.Message); 54 | 55 | AutomaticMessages.LastMessage = DateTime.Now; 56 | 57 | AutomaticMessages.RemoveScheduledQueue(schM.TypeInfo); 58 | AutomaticMessages.AddScheduledQueue(Youtube(DateTime.Now.AddMinutes(schM.WaitingTime.TotalMinutes))); 59 | } 60 | 61 | }, 62 | new TimeSpan(0, 45, 0), 63 | "Confira o nosso canal no Youtube... // " + 64 | " We are also on YouTube... " + StreamerDefault.Youtube, 65 | MessageType.YouTube); 66 | 67 | public static ScheduledMessage GitHub(DateTime date) => 68 | new ScheduledMessage(date, async (ScheduledMessage schM) => 69 | { 70 | if (DateTime.Now >= AutomaticMessages.LastMessage) 71 | { 72 | //envia a mensagem 73 | await IrcEngine.Respond(schM.Message); 74 | 75 | AutomaticMessages.LastMessage = DateTime.Now; 76 | 77 | AutomaticMessages.RemoveScheduledQueue(schM.TypeInfo); 78 | AutomaticMessages.AddScheduledQueue(GitHub(DateTime.Now.AddMinutes(schM.WaitingTime.TotalMinutes))); 79 | } 80 | 81 | }, 82 | new TimeSpan(0, 45, 0), 83 | "O nosso bot, todo em C#, está disponível no GitHub... // " + 84 | " Check our chat bot on GitHub... " + StreamerDefault.GitHub, 85 | MessageType.GitHub); 86 | 87 | public static ScheduledMessage Donate(DateTime date) => 88 | new ScheduledMessage(date, async (ScheduledMessage schM) => 89 | { 90 | if (DateTime.Now >= AutomaticMessages.LastMessage) 91 | { 92 | //envia a mensagem 93 | await IrcEngine.Respond(schM.Message); 94 | 95 | AutomaticMessages.LastMessage = DateTime.Now; 96 | 97 | AutomaticMessages.RemoveScheduledQueue(schM.TypeInfo); 98 | AutomaticMessages.AddScheduledQueue(Donate(DateTime.Now.AddMinutes(schM.WaitingTime.TotalMinutes))); 99 | } 100 | 101 | }, 102 | new TimeSpan(0, 45, 0), 103 | "Sinta-se livre para nos apoiar financeiramente... // " + 104 | " Feel free helping us... " + StreamerDefault.PayPal + " " + StreamerDefault.PicPay, 105 | MessageType.Donate); 106 | 107 | public static ScheduledMessage Form(DateTime date) => 108 | new ScheduledMessage(date, async (ScheduledMessage schM) => 109 | { 110 | if (DateTime.Now >= AutomaticMessages.LastMessage) 111 | { 112 | //envia a mensagem 113 | await IrcEngine.Respond(schM.Message); 114 | 115 | AutomaticMessages.LastMessage = DateTime.Now; 116 | 117 | AutomaticMessages.RemoveScheduledQueue(schM.TypeInfo); 118 | AutomaticMessages.AddScheduledQueue(Form(DateTime.Now.AddMinutes(schM.WaitingTime.TotalMinutes))); 119 | } 120 | 121 | }, 122 | new TimeSpan(0, 45, 0), 123 | "Temos uma pesquisa para conhecer mais o nosso chat... // " + 124 | " Let me know more about you... " + StreamerDefault.Form, 125 | MessageType.Form); 126 | 127 | public static ScheduledMessage DrinkWater(DateTime date) => 128 | new ScheduledMessage(date, async (ScheduledMessage schM) => 129 | { 130 | if (DateTime.Now >= AutomaticMessages.LastMessage) 131 | { 132 | //envia a mensagem 133 | await IrcEngine.Respond(schM.Message); 134 | 135 | AutomaticMessages.LastMessage = DateTime.Now; 136 | 137 | AutomaticMessages.RemoveScheduledQueue(schM.TypeInfo); 138 | AutomaticMessages.AddScheduledQueue(DrinkWater(DateTime.Now.AddMinutes(schM.WaitingTime.TotalMinutes))); 139 | } 140 | 141 | }, 142 | new TimeSpan(0, 7, 30), 143 | "Não se esqueça de beber Vodka/Água... // " + 144 | " Remember to drink Vodka/Water... ", 145 | MessageType.Water); 146 | 147 | 148 | public static ScheduledMessage Commercial(DateTime date) => 149 | new ScheduledMessage(date, async (ScheduledMessage schM) => 150 | { 151 | //if (DateTime.Now >= AutomaticMessages.LastMessage) 152 | //{ 153 | //envia a mensagem 154 | await IrcEngine.Send(schM.Message, CancellationToken.None); 155 | 156 | AutomaticMessages.LastMessage = DateTime.Now; 157 | 158 | AutomaticMessages.RemoveLiquidQueue(schM.TypeInfo); 159 | AutomaticMessages.AddLiquidQueue(Commercial(DateTime.Now.AddMinutes(schM.WaitingTime.TotalMinutes))); 160 | //} 161 | 162 | }, 163 | new TimeSpan(1, 0, 0), 164 | @"PRIVMSG #" + Parameters.User + " :/commercial 30 ", 165 | MessageType.Commercial); 166 | 167 | public enum MessageType 168 | { 169 | Discord, 170 | YouTube, 171 | Donate, 172 | GitHub, 173 | Form, 174 | Water, 175 | Commercial, 176 | } 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /WebMatBot/Config/Parameters.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace WebMatBot 6 | { 7 | public static class Parameters 8 | { 9 | public static string OAuth = ""; //https://twitchtokengenerator.com/ 10 | public static string User = ""; 11 | public static string ChannelID = ""; //its the same user id on authentiaction twitch 12 | 13 | public static string AzureCognitiveKey = "";//https://portal.azure.com/ 14 | public static string AzureCognitiveRegion = ""; 15 | 16 | public static string GoogleTranslateApiKey = ""; 17 | } 18 | } -------------------------------------------------------------------------------- /WebMatBot/Config/StreamerDefault.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace WebMatBot.Core 6 | { 7 | public class StreamerDefault 8 | { 9 | public static string Discord = "https://discord.gg/ZyBWR6y"; 10 | public static string Youtube = "https://www.youtube.com/channel/UChrqLllkeISeCNiucSeq-IQ/videos"; 11 | public static string GitHub = "https://github.com/WebMat1/WebMatBotTwitch"; 12 | public static string StreamElements_Store = "https://streamelements.com/webmat1/store"; 13 | public static string PicPay = "https://app.picpay.com/user/WebMat"; 14 | public static string PayPal = "https://streamlabs.com/webmat1/tip"; 15 | public static string Form = "https://forms.gle/nzF1M8DaH1c38Pce6"; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /WebMatBot/Core/IrcEngine.cs: -------------------------------------------------------------------------------- 1 | using F23.StringSimilarity; 2 | using Microsoft.CognitiveServices.Speech.Transcription; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Net.WebSockets; 8 | using System.Text; 9 | using System.Threading; 10 | using System.Threading.Tasks; 11 | using WebMatBot.Core; 12 | using WebMatBot.Lights; 13 | using WebMatBotV3.Shared; 14 | 15 | namespace WebMatBot 16 | { 17 | public static class IrcEngine 18 | { 19 | public static Func UserInteraction; 20 | 21 | private static ClientWebSocket webSocket { get; set; } 22 | 23 | //all words in lowercase 24 | private static List badWords = new List { "mongoloide", "mongolóide", "mongol", "pinto", "buceta", "toma no cu", "tomar no cu" }; 25 | 26 | public static async Task Start() 27 | { 28 | do 29 | { 30 | using (var socket = new ClientWebSocket()) 31 | try 32 | { 33 | await socket.ConnectAsync(new Uri("wss://irc-ws.chat.twitch.tv:443"), CancellationToken.None); 34 | 35 | webSocket = socket; 36 | 37 | await Send("PASS " + Parameters.OAuth, CancellationToken.None); 38 | await Send("NICK " + Parameters.User, CancellationToken.None); 39 | await Send("CAP REQ :twitch.tv/tags", CancellationToken.None); 40 | await Send("CAP REQ :twitch.tv/commands", CancellationToken.None); 41 | 42 | await Send("JOIN #" + Parameters.User, CancellationToken.None); 43 | 44 | 45 | await Respond("Estou conectado... Muito bom estar aqui com vcs..."); 46 | 47 | await Receive(CancellationToken.None); 48 | 49 | } 50 | catch (Exception ex) 51 | { 52 | Console.WriteLine($"ERROR - {ex.Message}"); 53 | } 54 | } while (true); 55 | } 56 | 57 | public static async Task Send(string data, CancellationToken stoppingToken) => 58 | await webSocket.SendAsync(Encoding.UTF8.GetBytes(data), WebSocketMessageType.Text, true, stoppingToken); 59 | 60 | public static async Task Receive(CancellationToken stoppingToken) 61 | { 62 | var buffer = new ArraySegment(new byte[2048]); 63 | while (!stoppingToken.IsCancellationRequested) 64 | { 65 | WebSocketReceiveResult result; 66 | using (var ms = new MemoryStream()) 67 | { 68 | do 69 | { 70 | result = await webSocket.ReceiveAsync(buffer, stoppingToken); 71 | ms.Write(buffer.Array, buffer.Offset, result.Count); 72 | } while (!result.EndOfMessage); 73 | 74 | if (result.MessageType == WebSocketMessageType.Close) 75 | break; 76 | 77 | ms.Seek(0, SeekOrigin.Begin); 78 | using (var reader = new StreamReader(ms, Encoding.UTF8)) 79 | { 80 | var input = await reader.ReadToEndAsync(); 81 | Console.WriteLine(input); 82 | if (await Analizer(input)) 83 | { 84 | Cache.AddToCacheMessage(input); 85 | } 86 | } 87 | } 88 | }; 89 | } 90 | 91 | public static async Task Respond(string msg, string user = "") 92 | { 93 | try 94 | { 95 | await Send("PRIVMSG #" + Parameters.User + " : MrDestructoid " + "@" + user + "... " + msg, CancellationToken.None); 96 | } 97 | catch (Exception except) 98 | { 99 | Console.WriteLine(except.Message); 100 | } 101 | } 102 | 103 | public static async Task Whisper(string user, string msg) 104 | { 105 | await Send(@"PRIVMSG #" + Parameters.User + " :/w " + user + " " + msg, CancellationToken.None); 106 | } 107 | 108 | public static async Task Analizer(string input) 109 | { 110 | //must responde ping pong 111 | if (input.Contains("PING")) 112 | { 113 | await Send("PONG", CancellationToken.None); 114 | return false; 115 | } 116 | 117 | var u_ID = GetUserId(input); 118 | 119 | //grava no banco toda interação (user id) de quem escreve no chat 120 | if (u_ID != null) 121 | if (UserInteraction != null) await UserInteraction(input.Split(" ")[1].Split("!")[0].Replace(":", ""), u_ID.Value); 122 | 123 | //filtro de palavrões 124 | var filter = input.ToLower(); 125 | if (badWords.Any(s => filter.Contains(s))) 126 | { 127 | await Respond("Sua Mensagem contém palavras impróprias e não será repassada ao nosso bot!", input.Split(" ")[1].Split("!")[0].Replace(":", "")); 128 | await Send(@"PRIVMSG #" + Parameters.User + " :/timeout " + input.Split(" ")[1].Split("!")[0].Replace(":", "") + " 1m", CancellationToken.None); 129 | return false; 130 | } 131 | 132 | //pode receber commando para USERNOTICE ou PRIVMSG, direciona-los 133 | if (input.Contains(" PRIVMSG ")) 134 | await CheckCommand(input.Contains("user-type=") ? input.ToLower().Split("user-type=")[1].Trim() : input, new UserTitle(input)); 135 | else if (input.Contains(" USERNOTICE ")) 136 | await CheckNotice(input); 137 | 138 | return true; 139 | } 140 | 141 | private static async Task CheckCommand(string input, UserTitle userTitle) 142 | { 143 | //gambi da boa hahahhah 144 | input = input.Replace("mod ", ""); 145 | 146 | var words = input.ToLower().Split(" "); 147 | Command command = null; 148 | bool isDone = false; 149 | 150 | // verifica comandos 151 | for (int i = 0; i < Commands.List.Count() && !isDone; i++) 152 | { 153 | if (words.Any(q => q.Trim().Replace(":", "").Equals(Commands.List[i].Key.ToLower()))) 154 | { 155 | command = Commands.List[i]; 156 | isDone = true; 157 | } 158 | } 159 | 160 | if (isDone) 161 | { 162 | //limite de caracteres 300 163 | if (input.Length > 400) 164 | { 165 | await Respond("Sua Mensagem contém muitos caracteres e não será repassada ao nosso bot!", input.Split("!")[0].Replace(":", "")); 166 | return; 167 | } 168 | else 169 | { 170 | //verificar se tem permissões suficientes para executar o comando 171 | if (await Commands.CheckPermissions(command, userTitle)) 172 | command.Action.Invoke(input.ToLower().Split(command.Key.ToLower())[1], input.Split("!")[0].Replace(":", ""), userTitle); 173 | } 174 | } 175 | else if (words.Length >= 4 && words[3].StartsWith(":!")) 176 | { 177 | await CommandCorrector(input, words[3].Replace(":", ""), userTitle); 178 | } 179 | 180 | } 181 | 182 | public static async Task CommandCorrector(string input, string command, UserTitle userTitle = null, string user = null,bool shouldBeExact = false) 183 | { 184 | // def variables 185 | IDictionary MatchRate = new Dictionary(); 186 | var Match = new NormalizedLevenshtein(); 187 | 188 | // filling array with matching rate 189 | for (int i = 0; i < Commands.List.Count; i++) 190 | MatchRate.Add(Commands.List[i], Match.Distance(command, Commands.List[i].Key)); 191 | 192 | //is there some rate lower than 35% 193 | if (!MatchRate.Any(q => q.Value <= 0.51d)) 194 | { 195 | await Respond("Não entendi o seu comando, tente !Exclamação para obter a lista de todos os comandos...", input.ToLower().Split("!")[0].Replace(":", "")); 196 | return; 197 | } 198 | else 199 | { 200 | //get the minimum match rate (closest command) 201 | var minimum = MatchRate.Min(q => q.Value); 202 | 203 | var arrayMinimum = MatchRate.Where(q => q.Value == minimum); 204 | 205 | if (arrayMinimum.Count() == 1) 206 | { 207 | if (shouldBeExact) 208 | { 209 | await Respond("O comando " + command + " está incorreto; " + arrayMinimum.ElementAt(0).Key.Description, user); 210 | } 211 | else 212 | { 213 | var Tinput = input.ToLower().Split(command)[1]; 214 | var Tuser = input.ToLower().Split("!")[0].Replace(":", ""); 215 | 216 | await Respond("Seu commando foi corrigido para " + arrayMinimum.ElementAt(0).Key.Key + ", tente !Exclamação para obter a lista de todos os comandos...", Tuser); 217 | 218 | //verificar se tem permissões suficientes para executar o comando 219 | if (userTitle == null || await Commands.CheckPermissions(arrayMinimum.ElementAt(0).Key, userTitle)) 220 | arrayMinimum.ElementAt(0).Key.Action.Invoke(Tinput, Tuser, userTitle); 221 | } 222 | 223 | } 224 | else 225 | { 226 | string text = "Não entendi o seu comando, não seria "; 227 | foreach (var item in arrayMinimum) 228 | { 229 | text += item.Key.Key + " ou "; 230 | } 231 | 232 | text += "tente !Exclamação para ver todos os comandos..."; 233 | 234 | await Respond(text, input.ToLower().Split("!")[0].Replace(":", "")); 235 | } 236 | } 237 | } 238 | 239 | public static async Task CheckNotice(string input) 240 | { 241 | string[] properties = input.Split(";"); 242 | var loginPropert = properties.First(q => q.StartsWith("login=")); 243 | var raider = loginPropert.Split("=")[1]; 244 | 245 | //raider é o cidadão q está enviando a raid pra vc 246 | 247 | if (input.Contains("msg-id=raid;")) 248 | await TasksQueueOutput.QueueAddSpeech(async () => 249 | { 250 | await AudioVisual.Party("", Parameters.User); 251 | await SpeakerCore.Speak("Muito obrigado, " + raider, Parameters.User); 252 | }, ""); 253 | 254 | } 255 | 256 | private static int? GetUserId(string input) 257 | { 258 | string inputc = input.ToLower(); 259 | 260 | //@badge-info=; 261 | //badges=vip/1; 262 | //client-nonce=9fee50a50257c84bfb54c82f52f890b5; 263 | //color=#FF0000;display-name=victorzonta; 264 | //emotes=;flags=; 265 | //id=eb659c5e-e906-4291-85d6-8b2a0bade681; 266 | //mod=0; 267 | //room-id=45168403; 268 | //subscriber=0; 269 | //tmi-sent-ts=1609121503057; 270 | //turbo=0; 271 | //user-id=600718807; 272 | //user-type= :victorzonta!victorzonta@victorzonta.tmi.twitch.tv PRIVMSG #webmat1 :!spray 55 90 273 | var semiCommaSplit = inputc.Split(" ")[0].Split(";"); 274 | var item = semiCommaSplit.FirstOrDefault(q => q.StartsWith("user-id")); 275 | 276 | if (item != null) 277 | { 278 | var strValue = item.Split("=")[1]; 279 | 280 | return int.Parse(strValue); 281 | } 282 | else 283 | return null; 284 | } 285 | } 286 | } 287 | -------------------------------------------------------------------------------- /WebMatBot/Core/PubSubEngine.cs: -------------------------------------------------------------------------------- 1 | using Grpc.Core; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Net.WebSockets; 6 | using System.Text; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | using Newtonsoft.Json; 10 | using WebMatBot.Lights; 11 | using System.Linq; 12 | using System.Net.Mail; 13 | 14 | namespace WebMatBot.Core 15 | { 16 | public static class PubSubEngine 17 | { 18 | private static ClientWebSocket webSocket { get; set; } 19 | 20 | private readonly static IDictionary>> Topics = new Dictionary>> 21 | { 22 | { $"channel-bits-events-v1.{Parameters.ChannelID}", async (line) => { await BitsEnter(line); await TasksQueueOutput.QueueAddSpeech( async() => await AudioVisual.Party("", Parameters.User), ""); } }, 23 | { $"channel-bits-badge-unlocks.{Parameters.ChannelID}" ,async (line) => await TasksQueueOutput.QueueAddSpeech( async() => await AudioVisual.Party("", Parameters.User), "") } , 24 | { $"channel-points-channel-v1.{Parameters.ChannelID}", async (line) => await ChannelPoints(line) }, 25 | { $"channel-subscribe-events-v1.{Parameters.ChannelID}",async (line) => { await SubEnter(line); await TasksQueueOutput.QueueAddSpeech( async() => await AudioVisual.Party("", Parameters.User), ""); } }, 26 | }; 27 | private readonly static string Auth = Parameters.OAuth.Split(":")[1]; //https://twitchtokengenerator.com/ 28 | 29 | public static async Task Start() 30 | { 31 | Task.Run(() => PingPong()); 32 | 33 | do 34 | { 35 | using (var socket = new ClientWebSocket()) 36 | try 37 | { 38 | await socket.ConnectAsync(new Uri("wss://pubsub-edge.twitch.tv"), CancellationToken.None); 39 | 40 | webSocket = socket; 41 | 42 | 43 | 44 | var obj = new 45 | { 46 | type = "LISTEN", 47 | data = new 48 | { 49 | topics = Topics.Keys, 50 | auth_token = Auth, 51 | }, 52 | }; 53 | 54 | await Send(Newtonsoft.Json.JsonConvert.SerializeObject(obj), CancellationToken.None); 55 | 56 | //reponde para o chat 57 | //await Engine.Respond("Ouvindo PubSub... Começando a SkyNet..."); 58 | 59 | await Receive(CancellationToken.None); 60 | 61 | } 62 | catch (Exception ex) 63 | { 64 | //Console.WriteLine($"ERROR - {ex.Message}"); 65 | } 66 | } while (true); 67 | } 68 | 69 | public static async Task Receive(CancellationToken stoppingToken) 70 | { 71 | var buffer = new ArraySegment(new byte[2048]); 72 | while (!stoppingToken.IsCancellationRequested) 73 | { 74 | WebSocketReceiveResult result; 75 | using (var ms = new MemoryStream()) 76 | { 77 | do 78 | { 79 | result = await webSocket.ReceiveAsync(buffer, stoppingToken); 80 | ms.Write(buffer.Array, buffer.Offset, result.Count); 81 | } while (!result.EndOfMessage); 82 | 83 | if (result.MessageType == WebSocketMessageType.Close) 84 | break; 85 | 86 | ms.Seek(0, SeekOrigin.Begin); 87 | using (var reader = new StreamReader(ms, Encoding.UTF8)) 88 | { 89 | var input = await reader.ReadToEndAsync(); 90 | 91 | await Analizer(input); 92 | } 93 | } 94 | }; 95 | } 96 | 97 | private static Task Analizer(string JsonInput) 98 | { 99 | var Obj = new { type = "", data = new { topic = "", message = ""} }; 100 | Obj = JsonConvert.DeserializeAnonymousType(JsonInput, Obj); 101 | if (Obj.type == "MESSAGE") 102 | { 103 | IDictionary message = JsonConvert.DeserializeObject>(Obj.data.message); 104 | 105 | return CheckCommand(message, Obj.data.topic); 106 | } 107 | 108 | return Task.CompletedTask; 109 | 110 | } 111 | private static async Task CheckCommand(IDictionary message, string topic) 112 | { 113 | Action> command = null; 114 | bool isDone = false; 115 | 116 | // verifica comandos 117 | for (int i = 0; i < Topics.Count && !isDone; i++) 118 | { 119 | if (topic == Topics.ElementAt(i).Key) 120 | { 121 | command = Topics.ElementAt(i).Value; 122 | isDone = true; 123 | } 124 | } 125 | 126 | if (isDone) 127 | command.Invoke(message); 128 | } 129 | 130 | public static async Task Send(string data, CancellationToken stoppingToken) => 131 | await webSocket.SendAsync(Encoding.UTF8.GetBytes(data), WebSocketMessageType.Text, true, stoppingToken); 132 | 133 | public static async void PingPong() 134 | { 135 | while (true) 136 | { 137 | await Task.Delay(new TimeSpan(0,3,0)); 138 | if (webSocket.State == WebSocketState.Open) 139 | await Send("PING", CancellationToken.None); 140 | } 141 | } 142 | 143 | public static async Task SubEnter(IDictionary json) 144 | { 145 | try 146 | { 147 | var user = json["user_name"].ToString(); 148 | //var data = json["data"]; 149 | 150 | 151 | await Games.Cannon_Store.SubEnterResource(user); 152 | }catch(Exception excpt) 153 | { 154 | Console.WriteLine(excpt.Message); 155 | 156 | //var data = json["data"]; 157 | 158 | var user = ((Newtonsoft.Json.Linq.JObject)json).GetValue("user_name").ToString(); 159 | await Games.Cannon_Store.SubEnterResource(user); 160 | 161 | 162 | 163 | } 164 | } 165 | 166 | private static async Task BitsEnter(IDictionary json) 167 | { 168 | var data = json["data"]; 169 | var user = ((Newtonsoft.Json.Linq.JObject)data).GetValue("user_name").ToString(); 170 | var bits = int.Parse(((Newtonsoft.Json.Linq.JObject)data).GetValue("bits_used").ToString()); 171 | 172 | await Games.Cannon_Store.BuyBallCommand(user, bits, Games.Cannon_Store.TypePayment.bits); 173 | } 174 | 175 | private static async Task ChannelPoints(IDictionary message) 176 | { 177 | 178 | var data = message["data"]; 179 | var redemption = ((Newtonsoft.Json.Linq.JObject)data)["redemption"]; 180 | var userInfo = ((Newtonsoft.Json.Linq.JObject)redemption)["user"]; 181 | var user = ((Newtonsoft.Json.Linq.JObject)userInfo).GetValue("login").ToString(); 182 | var reward = ((Newtonsoft.Json.Linq.JObject)redemption)["reward"]; 183 | var title = ((Newtonsoft.Json.Linq.JObject)reward).GetValue("title").ToString(); 184 | 185 | if (title.ToLower().Contains("xandão")) 186 | { 187 | await TasksQueueOutput.QueueAddSpeech(async () => await AudioVisual.Xandao("", Parameters.User),""); 188 | } 189 | 190 | //to do -> pegar quantidade comprada em cada redemption 191 | if (title.ToLower().Contains("cannongame")) 192 | { 193 | await Games.Cannon.NewRedemptionGame(user, "100 0"); 194 | } 195 | } 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /WebMatBot/Core/TasksQueueOutput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading.Tasks; 5 | 6 | namespace WebMatBot.Core 7 | { 8 | public class TasksQueueOutput 9 | { 10 | public static int TimeSleeping { get; set; } = 0; // em segundos 11 | 12 | private static IList> Queue = new List>(); 13 | 14 | public static async Task QueueAddSpeech(Func action, string user) 15 | { 16 | if (await SpeakerCore.CheckStatus(user)) 17 | lock (Queue) 18 | Queue.Add(action); 19 | } 20 | 21 | public static async Task QueueAddLight(Func action, string user) 22 | { 23 | if (await Lights.Light.CheckStatus(user)) 24 | lock (Queue) 25 | Queue.Add(action); 26 | } 27 | 28 | public static async Task Start() 29 | { 30 | do 31 | { 32 | try 33 | { 34 | if (SpeakerCore.State == SpeakerCore.Status.Disabled || SpeakerCore.State == SpeakerCore.Status.Paused) 35 | await Task.Delay(2000); 36 | else 37 | { 38 | Func scoped = null; 39 | 40 | //get from list 41 | lock (Queue) 42 | { 43 | if (Queue.Count > 0) 44 | { 45 | scoped = Queue[0]; 46 | } 47 | } 48 | 49 | //execute and wait 50 | if (scoped != null) 51 | { 52 | await scoped(); 53 | 54 | //update list 55 | lock (Queue) 56 | Queue.Remove(Queue[0]); 57 | } 58 | 59 | await Task.Delay(TimeSleeping * 1000); 60 | } 61 | } 62 | catch (Exception excpt) 63 | { 64 | Console.WriteLine(excpt.Message); 65 | } 66 | } while (true); 67 | } 68 | 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /WebMatBot/Games/Cannon.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WebMatBotV3.Shared; 7 | using WebMatBotV3.Shared.Entity; 8 | 9 | namespace WebMatBot.Games 10 | { 11 | public class Cannon 12 | { 13 | private static double TimeCoolDownShot = 4; 14 | private static Status _State = Status.Enabled; 15 | public static Status State 16 | { 17 | get => _State; 18 | set 19 | { 20 | _State = value; 21 | NewGame(); 22 | } 23 | } 24 | 25 | //private static List UsersCanShot = new List(); 26 | private static Dictionary CoolDownShot = new Dictionary(); 27 | 28 | public static Func Shot; 29 | public static Func Spray; 30 | public static Func MoveTarget; 31 | public static Func NewGame; 32 | public static Func CheckMyBallsFromServer; 33 | public static Func SaveRecord; 34 | public static Func CanShot; 35 | public static Func> CanSubRedemption; 36 | public static Func> AddInvitation; 37 | public static Func>> Rank; 38 | public static Func GenerateList; 39 | public static Func TransferName; 40 | 41 | public static async Task SendMessageToWinner(string user, int points, string args) 42 | { 43 | await IrcEngine.Whisper(user, "Parabéns... @" + user + "... Você acertou o alvo, com o comando (" + args + ") e agora está com " + points.ToString("00#") + " pontos..."); 44 | } 45 | 46 | public static async Task ShotCommand(string cmd,string user) 47 | { 48 | if (!await CheckStatus(user)) 49 | return; 50 | 51 | #region verifica se o usuario tem balas para atirar 52 | //verificar se está apto a atirar 53 | if (!CanShot(user)) 54 | { 55 | await IrcEngine.Respond("Ops... Me Desculpe... Se você quiser brincar com o canhão, primeiro deve se eleger; Eleções são feitas Por pontos do canal ou donations (verifique com o streamer)!!!", user); 56 | return; 57 | } 58 | #endregion 59 | 60 | #region verifica parametros passados 61 | //paremetros passados 62 | float angle, power; 63 | if (!GetShotParameters(cmd, out angle, out power)) 64 | { 65 | await IrcEngine.CommandCorrector(cmd, "!Shot", user: user, shouldBeExact: true); 66 | return; 67 | } 68 | #endregion 69 | 70 | #region Verificar frequencia de tiro por usuario 71 | //verificar se está atirando com muita frequencia 72 | if (CoolDownShot.ContainsKey(user)) 73 | { 74 | if (CoolDownShot[user].AddSeconds(TimeCoolDownShot) >= DateTime.Now) 75 | { 76 | await IrcEngine.Respond("Ops... Rápido demais... Dê uma respirada, coleguinha!!!", user); 77 | return; 78 | } 79 | //atualiza lista de cooldown 80 | else 81 | CoolDownShot[user] = DateTime.Now; 82 | } 83 | else 84 | { 85 | //adiciona na lista de coolDown 86 | CoolDownShot.Add(user, DateTime.Now); 87 | } 88 | #endregion 89 | 90 | if (Shot != null) await Shot(angle, power, user, cmd); 91 | 92 | } 93 | public static async Task SprayCommand(string cmd, string user) 94 | { 95 | if (!await CheckStatus(user)) 96 | return; 97 | 98 | #region verifica se o usuario tem balas para atirar 99 | //verificar se está apto a atirar 100 | if (!CanShot(user)) 101 | { 102 | await IrcEngine.Respond("Ops... Me Desculpe... Se você quiser brincar com o canhão, primeiro deve se eleger; Eleções são feitas Por pontos do canal ou donations (verifique com o streamer)!!!", user); 103 | return; 104 | } 105 | #endregion 106 | 107 | #region verifica parametros passados 108 | //paremetros passados 109 | float angle, power; 110 | if (!GetShotParameters(cmd, out angle, out power)) 111 | { 112 | await IrcEngine.CommandCorrector(cmd, "!Shot", user: user, shouldBeExact: true); 113 | return; 114 | } 115 | #endregion 116 | 117 | #region Verificar frequencia de tiro por usuario 118 | //verificar se está atirando com muita frequencia 119 | if (CoolDownShot.ContainsKey(user)) 120 | { 121 | if (CoolDownShot[user].AddSeconds(TimeCoolDownShot*2.5) >= DateTime.Now) 122 | { 123 | await IrcEngine.Respond("Ops... Rápido demais... Quando se usa !Spray o tempo de coolDown é um pouquinho maior... Sorry... marcob3Like marcob3Like ", user); 124 | return; 125 | } 126 | //atualiza lista de cooldown 127 | else 128 | CoolDownShot[user] = DateTime.Now; 129 | } 130 | else 131 | { 132 | //adiciona na lista de coolDown 133 | CoolDownShot.Add(user, DateTime.Now); 134 | } 135 | #endregion 136 | 137 | if (Spray != null) await Spray(angle, power, user, cmd); 138 | 139 | } 140 | public static async Task SubRedemptionCommand(string cmd, string user, UserTitle title) 141 | { 142 | #region Verifica se é sub 143 | if (!title.Permissions.Contains(Permissions.Subscriber)) 144 | { 145 | await IrcEngine.Respond("Desculpe o resgate é apenas permitido por quem está inscrito no canal... TehePelo", user); 146 | return; 147 | } 148 | #endregion 149 | 150 | #region verifica se o usuario já não resgatou o comando 151 | //verificar se está apto a atirar 152 | if (!await CanSubRedemption(user)) 153 | { 154 | await IrcEngine.Respond("Ops... Me Desculpe... Seu resgate de Subscriber já foi efetuado nessa Season. Tente na Proxima season...", user); 155 | return; 156 | } 157 | #endregion 158 | 159 | //save os records 160 | await SaveRecord( 161 | new Records() 162 | { 163 | Action = Records.ActionType.SubRedemption, 164 | Arguments = "20 0", 165 | Date = DateTime.Now, 166 | Username = user, 167 | }); 168 | 169 | } 170 | public static async Task GenerateListCommand() 171 | { 172 | await GenerateList(); 173 | } 174 | 175 | public static async Task RankCommand(string args, string user) 176 | { 177 | var result = Rank(user); 178 | if (result != null) 179 | await IrcEngine.Whisper(user, "@" + user + "... Você está na posição " + result.Value.Key + ", com " + result.Value.Value.Points+" pontos e sendo destes " + result.Value.Value.PointIntraDay + " somente hoje... Parabéns continue acertando o alvo..."); 180 | else 181 | await IrcEngine.Whisper(user, "@" + user + "... Você ainda não está no nosso Ranking... Continue tentando acertar o alvo para começarmos a contagem de seus pontos..."); 182 | } 183 | 184 | private static bool GetShotParameters(string stringRaw, out float angle, out float power) 185 | { 186 | stringRaw = stringRaw.ToLower().Trim(); 187 | var parts = stringRaw.Split(" "); 188 | 189 | angle = -1; 190 | power = -1; 191 | 192 | 193 | if (parts.Length != 2) 194 | return false; 195 | 196 | if (!float.TryParse(parts[0].Replace(".",","),out angle) || angle < 0 || angle > 90) 197 | return false; 198 | 199 | if (!float.TryParse(parts[1].Replace(".", ","), out power) || power < 0 || power > 100) 200 | return false; 201 | 202 | 203 | return true; 204 | 205 | 206 | } 207 | 208 | public static async Task MoveTargetCommand(string stringRaw, string user) 209 | { 210 | stringRaw = stringRaw.ToLower().Trim(); 211 | bool done = false; 212 | 213 | switch (stringRaw.ToLower()) 214 | { 215 | case "up": 216 | await UpdateAxisY(1); 217 | done = true; 218 | break; 219 | 220 | case "down": 221 | await UpdateAxisY(-1); 222 | done = true; 223 | break; 224 | 225 | case "left": 226 | await UpdateAxisX(-1); 227 | done = true; 228 | break; 229 | 230 | case "right": 231 | await UpdateAxisX(1); 232 | done = true; 233 | break; 234 | } 235 | 236 | 237 | if (!done) 238 | { 239 | await IrcEngine.CommandCorrector(stringRaw, "!Target", user: user, shouldBeExact: true); 240 | } 241 | 242 | } 243 | 244 | private static async Task UpdateAxisX(int x) 245 | { 246 | await MoveTarget(x, 0); 247 | } 248 | private static async Task UpdateAxisY(int y) 249 | { 250 | await MoveTarget(0,y); 251 | } 252 | 253 | public static async Task CheckStatus(string user) 254 | { 255 | if (State == Status.Disabled) 256 | { 257 | await IrcEngine.Respond("O Cannon Game está off... peça o streamer para acioná-lo...", user); 258 | return false; 259 | } 260 | else if(State == Status.Paused) 261 | { 262 | await IrcEngine.Respond("O Cannon Game está pausado... Provavelmente o nosso Skins Store esteja rolando... Confira as promoções de Skins e divirta-se...", user); 263 | return false; 264 | } 265 | else 266 | return true; 267 | } 268 | 269 | public static async Task NewRedemptionGame(string user, string args) //args = balls jackpot 270 | { 271 | var newRecordBuy = new Records() 272 | { 273 | Action = Records.ActionType.Buy, 274 | Arguments = args, 275 | Date = DateTime.Now, 276 | Username = user, 277 | }; 278 | 279 | await SaveRecord(newRecordBuy); 280 | 281 | await CheckMyBalls(user); 282 | } 283 | public static async Task CheckMyBalls(string user) 284 | { 285 | //responder para o usuario quantas balas ele pode atirar, até o momento 286 | await IrcEngine.Whisper(user,user + "... Você tem um total de " + CheckMyBallsFromServer(user) + " bolas de canhão para atirar... divirta-se usando o !Shot"); 287 | } 288 | 289 | public static async Task InvitedBy(string args, string user) 290 | { 291 | string result = null; 292 | 293 | args = args.Trim().Replace("@",""); 294 | 295 | //checar se o username (args) existe 296 | if (args == null || args.ToLower() == user.Trim().ToLower()) 297 | result = "@"+ user +"... Erro ao processar comando de indicação..."; 298 | else 299 | result = await AddInvitation(args, user); //mandar comando para o server para adicionar no bd 300 | 301 | if (result == null) // result == null é que deu tudo certo 302 | { 303 | //manda whisper tanto para quem indicou, quanto pra quem foi indicado, avisando como será dado os pontos 304 | await IrcEngine.Whisper(user, "Parabéns, você efetivou sua indicação... Acerte o alvo com !Shot [Angulo] [Força] para ganhar pontos extras para você e quem te indicou..."); 305 | 306 | //envia mensagem pra o host 307 | await IrcEngine.Whisper(args, "Parabéns, "+ user +" efetivou sua indicação... Incentive-o a acertar o alvo com !Shot [Angulo] [Força] para ganhar pontos extras para você e sua indicação..."); 308 | } 309 | else 310 | { 311 | await IrcEngine.Respond(result, user); 312 | } 313 | } 314 | 315 | public static async Task AddBallsStreamLabs(string user, string cmd) 316 | { 317 | if ((user.ToLower() == "streamlabs" || user.ToLower() == Parameters.User.ToLower()) && Cannon.State == Status.Enabled) 318 | { 319 | cmd = cmd.Trim(); 320 | var parameters = cmd.Split(" "); 321 | var userDonate = parameters[0]; 322 | var valueDonate = parameters[1].Replace("r$","").Replace(".",","); 323 | 324 | double doubleValue = 0; 325 | 326 | //calculos de jackpot e bolas a disponibilizar 327 | if (double.TryParse(valueDonate, out doubleValue)) 328 | { 329 | var jackPotAdd = (doubleValue * 0.7d) / 2d; 330 | var ballsAdd = (int)(doubleValue / 0.20d); 331 | string args = ballsAdd.ToString()+ " " + jackPotAdd.ToString().Replace(".", ","); 332 | await Games.Cannon.NewRedemptionGame(userDonate, args); 333 | } 334 | } 335 | } 336 | 337 | public enum Status 338 | { 339 | Disabled, 340 | Enabled, 341 | Paused, 342 | } 343 | } 344 | } 345 | -------------------------------------------------------------------------------- /WebMatBot/Games/Cannon_Store.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WebMatBotV3.Shared; 7 | using WebMatBotV3.Shared.Entity; 8 | using static WebMatBotV3.Shared.Entity.Balls; 9 | 10 | namespace WebMatBot.Games 11 | { 12 | public class Cannon_Store 13 | { 14 | private static double StoreDurationSeconds = (new TimeSpan(0, 5, 0)).TotalSeconds; 15 | private static IEnumerable BallsOnSale { get; set; } 16 | public static Cannon.Status State { get; set; } = Cannon.Status.Disabled; 17 | 18 | public static Func,Task> OpenMarket; 19 | public static Func>> GetBallsToSale; 20 | public static Func, TypePayment,Task> BuyBall; 21 | public static Func GetUserSkins; 22 | public static Func> EquipUserBall; 23 | public static Func> CanSubGift; 24 | public static Func SubEnter; 25 | 26 | public static async Task Start() 27 | { 28 | await Task.Delay(10000); 29 | 30 | do 31 | { 32 | if (State == Cannon.Status.Paused) 33 | await OpenMarketCommand(); 34 | 35 | await Task.Delay(5000); 36 | 37 | } while (true); 38 | } 39 | 40 | public static async Task OpenMarketCommand() 41 | { 42 | //Cannon.State = Cannon.Status.Paused; 43 | State = Cannon.Status.Enabled; 44 | 45 | //pergunta pro servidor quais 4 bolas vão pra leilão 46 | BallsOnSale = await GetBallsToSale(); 47 | 48 | await OpenMarket(StoreDurationSeconds, BallsOnSale.OrderBy(q=>q.BitValue)) ; 49 | } 50 | 51 | public static async Task CloseMarketCommand() 52 | { 53 | //compensar delay da twitch de transmissao 54 | await Task.Delay(5000); 55 | 56 | //Cannon.State = Cannon.Status.Enabled; 57 | State = Cannon.Status.Paused; 58 | BallsOnSale = new List(); 59 | //await Task.Delay(500); 60 | } 61 | 62 | public static async Task SubGiftCommand(string user, UserTitle userTitle) 63 | { 64 | //significa que mercado ta fechado... 65 | if (State != Cannon.Status.Enabled) 66 | await IrcEngine.Respond("O mercado de Balas de Canhão está fechado =/, mesmo assim, muito obrigado por ser Sub =) ... VoHiYo VoHiYo ", user); 67 | else 68 | { 69 | if (!await CanSubGift(user)) 70 | {//confere e salva a baixa de recurso 71 | await IrcEngine.Whisper(user, "@" + user + "... Você não tem recursos para solicitar essa chamada... Provavelmente você já o resgatou... Resubs são uma boa opção para lhe disponibizar novos recursos..."); 72 | return; 73 | } 74 | 75 | //pega todos os valores de bolas ofertadas 76 | var values = BallsOnSale.Select(q => q.BitValue).ToList(); 77 | 78 | //mistura a lista 79 | values.Shuffle(); 80 | 81 | //seleciona um valor dentre os valores anteriores 82 | int RandomIndex = new Random().Next(0, BallsOnSale.Count()); 83 | 84 | //envia o buyball com o valor selecionado e metodo bits 85 | 86 | var result = await BuyBall(user, values[RandomIndex], BallsOnSale.ToList(), TypePayment.bits); 87 | 88 | if (result != null) //tudo certo, adiquiriu a bala 89 | { 90 | await IrcEngine.Respond(result, user); 91 | } 92 | 93 | } 94 | 95 | 96 | } 97 | 98 | public static async Task BuyBallCommand(string user, float bits, TypePayment payment) 99 | { 100 | //significa que mercado ta fechado... 101 | if (State != Cannon.Status.Enabled) 102 | await IrcEngine.Respond("O mercado de Balas de Canhão está fechado =/, mesmo assim, muito obrigado pelos Bits =) ... VoHiYo VoHiYo ",user); 103 | else 104 | { 105 | 106 | var result = await BuyBall(user, bits, BallsOnSale.ToList(), payment); 107 | 108 | if (result != null) //tudo certo, adiquiriu a bala 109 | { 110 | await IrcEngine.Respond(result,user); 111 | } 112 | } 113 | } 114 | 115 | public static async Task EquipCommand(string cmd,string user) 116 | { 117 | cmd = cmd.ToLower().Trim(); //retira os espaços 118 | 119 | var type = Enum.GetNames(typeof(TypeBalls)).FirstOrDefault(q=>q.ToLower() == cmd); 120 | 121 | //sem skin com esse nome 122 | if (type == null) 123 | { 124 | await IrcEngine.Whisper(user, "@" + user + "... Não encontrei nenhuma skin com este nome..."); 125 | await GetUserSkinsCommand(user); 126 | } 127 | else 128 | { 129 | var Typeball = Enum.Parse(type); 130 | 131 | // tentar setar no banco dados que a skin selecionada é a isUsing 132 | string result; 133 | 134 | //manda para o servidor atualizar a bola 135 | result = await EquipUserBall(user, Typeball); 136 | 137 | 138 | if (string.IsNullOrEmpty(result)) 139 | await IrcEngine.Whisper(user, "@" + user + "... Parabéns, você equipou a sua " + type + " Ball... Divirta-se usando o !Shot"); //sucesso 140 | else 141 | { 142 | await IrcEngine.Whisper(user, result); //erro 143 | await Task.Delay(5000); 144 | await GetUserSkinsCommand(user); 145 | } 146 | 147 | } 148 | 149 | return; 150 | } 151 | 152 | public static async Task GetUserSkinsCommand(string user) 153 | { 154 | var myTypes = GetUserSkins(user); 155 | 156 | if (myTypes == null || myTypes.Length == 0) 157 | await IrcEngine.Whisper(user, "Você não possui nenhuma Skin... Aguarde ou Invoque a abertura do Ball Store para comprar alguma... e divirta-se..."); 158 | else 159 | await IrcEngine.Whisper(user, "@" + user + "... Você possui as skins: " + String.Join(" ", myTypes.Select(q => q.ToString()))+"... Use o !Equip [nome da skin] para ativá-la..."); 160 | } 161 | 162 | public static async Task SubEnterResource(string user) => await SubEnter(user); 163 | 164 | public enum TypePayment 165 | { 166 | bits, 167 | donation 168 | } 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /WebMatBot/General/Cache.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace WebMatBot 8 | { 9 | public static class Cache 10 | { 11 | public static IList Messages = new List(); 12 | 13 | public static void AddToCacheMessage(string input) 14 | { 15 | //:webmat1!webmat1@webmat1.tmi.twitch.tv PRIVMSG #{user} :Teste 16 | 17 | //get the owner of message e save this 18 | var arrayInput = input.Split("PRIVMSG"); 19 | 20 | if (arrayInput.Length >= 2) 21 | { 22 | var msg = arrayInput[0].Split("!")[0] + " "+arrayInput[1].Split("#"+ Parameters.User)[1]; 23 | Messages.Add(msg + ";"); 24 | 25 | if (Messages.Count > 10) Messages.RemoveAt(0); 26 | } 27 | 28 | } 29 | 30 | public static async Task Respond(string user) 31 | { 32 | foreach (var item in Messages) 33 | { 34 | await IrcEngine.Whisper( user ,item); 35 | //await Core.Respond(item); // maximo de 500 caracteres por mensagem na twitch 36 | } 37 | 38 | await IrcEngine.Respond("Por favor, confira a aba de sussurros...", user); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /WebMatBot/General/Screens.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading.Tasks; 5 | using WindowsInput; 6 | 7 | namespace WebMatBot 8 | { 9 | public class Screens 10 | { 11 | public static bool isActive { get; set; } = false; //inactivated 12 | 13 | public static async Task VSCode(string user) 14 | { 15 | if (!await CheckStatus(user)) 16 | return; 17 | 18 | InputSimulator input = new InputSimulator(); 19 | input.Keyboard.KeyDown(WindowsInput.Native.VirtualKeyCode.CONTROL); 20 | input.Keyboard.KeyPress(WindowsInput.Native.VirtualKeyCode.F1); 21 | input.Keyboard.KeyUp(WindowsInput.Native.VirtualKeyCode.CONTROL); 22 | 23 | return ; 24 | } 25 | public static async Task Browser(string user) 26 | { 27 | 28 | if (!await CheckStatus(user)) 29 | return; 30 | 31 | InputSimulator input = new InputSimulator(); 32 | input.Keyboard.KeyDown(WindowsInput.Native.VirtualKeyCode.CONTROL); 33 | input.Keyboard.KeyPress(WindowsInput.Native.VirtualKeyCode.F3); 34 | input.Keyboard.KeyUp(WindowsInput.Native.VirtualKeyCode.CONTROL); 35 | 36 | return ; 37 | } 38 | public static async Task VS(string user) 39 | { 40 | 41 | if (!await CheckStatus(user)) 42 | return; 43 | 44 | InputSimulator input = new InputSimulator(); 45 | input.Keyboard.KeyDown(WindowsInput.Native.VirtualKeyCode.CONTROL); 46 | input.Keyboard.KeyPress(WindowsInput.Native.VirtualKeyCode.F2); 47 | input.Keyboard.KeyUp(WindowsInput.Native.VirtualKeyCode.CONTROL); 48 | 49 | return ; 50 | } 51 | public static async Task Kitchen(string user) 52 | { 53 | 54 | if (!await CheckStatus(user)) 55 | return; 56 | 57 | InputSimulator input = new InputSimulator(); 58 | input.Keyboard.KeyDown(WindowsInput.Native.VirtualKeyCode.CONTROL); 59 | input.Keyboard.KeyPress(WindowsInput.Native.VirtualKeyCode.F6); 60 | input.Keyboard.KeyUp(WindowsInput.Native.VirtualKeyCode.CONTROL); 61 | 62 | return; 63 | } 64 | public static async Task Chat(string user) 65 | { 66 | 67 | if (!await CheckStatus(user)) 68 | return; 69 | 70 | InputSimulator input = new InputSimulator(); 71 | input.Keyboard.KeyDown(WindowsInput.Native.VirtualKeyCode.CONTROL); 72 | input.Keyboard.KeyPress(WindowsInput.Native.VirtualKeyCode.F7); 73 | input.Keyboard.KeyUp(WindowsInput.Native.VirtualKeyCode.CONTROL); 74 | 75 | return; 76 | } 77 | public static async Task Cannon() 78 | { 79 | InputSimulator input = new InputSimulator(); 80 | input.Keyboard.KeyDown(WindowsInput.Native.VirtualKeyCode.MENU); 81 | input.Keyboard.KeyPress(WindowsInput.Native.VirtualKeyCode.F12); 82 | input.Keyboard.KeyUp(WindowsInput.Native.VirtualKeyCode.MENU); 83 | } 84 | 85 | private static async Task CheckStatus(string user) 86 | { 87 | if (!isActive) 88 | await IrcEngine.Respond("A mudança de tela está desativada, peça o streamer para ativá-la.", user); 89 | 90 | return isActive; 91 | } 92 | 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /WebMatBot/General/Sounds.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace WebMatBot 9 | { 10 | public class Sounds 11 | { 12 | public static bool TrollisActive { get; set; } = false; 13 | 14 | public static void RandomTrollSound() 15 | { 16 | if (!CheckStatus()) 17 | return; 18 | 19 | Random rdm = new Random(); 20 | var files = GetTrollFiles(); 21 | 22 | var index = rdm.Next(files.Length); 23 | 24 | SpeakerCore.ExecuteMP3File(files[index]); 25 | //Task.Delay(500); 26 | } 27 | 28 | private static bool CheckStatus() 29 | { 30 | return TrollisActive; 31 | } 32 | 33 | private static string[] GetTrollFiles() 34 | { 35 | var targetDirectory = @Directory.GetCurrentDirectory() + @"\Sounds\Troll"; 36 | 37 | // Process the list of files found in the directory. 38 | string[] fileEntries = Directory.GetFiles(targetDirectory); 39 | return fileEntries; 40 | } 41 | 42 | private static string[] GetGeneralFiles() 43 | { 44 | var targetDirectory = @Directory.GetCurrentDirectory() + @"\Sounds\General"; 45 | 46 | // Process the list of files found in the directory. 47 | string[] fileEntries = Directory.GetFiles(targetDirectory); 48 | return fileEntries; 49 | } 50 | 51 | private static string[] GetPartyFiles() 52 | { 53 | var targetDirectory = @Directory.GetCurrentDirectory() + @"\Sounds\Party"; 54 | 55 | // Process the list of files found in the directory. 56 | string[] fileEntries = Directory.GetFiles(targetDirectory); 57 | return fileEntries; 58 | } 59 | 60 | 61 | public static void Piada() 62 | { 63 | var files = GetGeneralFiles(); 64 | var piada = files.Where(q=>q.Contains("rimshot.mp3")).FirstOrDefault(); 65 | if (piada != null) SpeakerCore.ExecuteMP3File(piada); 66 | } 67 | 68 | public static void Clap() 69 | { 70 | var files = GetGeneralFiles(); 71 | var piada = files.Where(q => q.Contains("aplausos.mp3")).FirstOrDefault(); 72 | if (piada != null) SpeakerCore.ExecuteMP3File(piada); 73 | } 74 | 75 | public static void Xandao() 76 | { 77 | var files = GetGeneralFiles(); 78 | var piada = files.Where(q => q.Contains("xandao.mp3")).FirstOrDefault(); 79 | if (piada != null) SpeakerCore.ExecuteMP3File(piada); 80 | } 81 | 82 | public static void RandomPartySound() 83 | { 84 | Random rdm = new Random(); 85 | var files = GetPartyFiles(); 86 | 87 | var index = rdm.Next(files.Length); 88 | 89 | SpeakerCore.ExecuteMP3File(files[index]); 90 | } 91 | 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /WebMatBot/LedArt/Test.cs: -------------------------------------------------------------------------------- 1 | //using InTheHand.Net.Bluetooth; 2 | //using InTheHand.Net.Sockets; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace WebMatBot.LedArt 10 | { 11 | public class Test 12 | { 13 | public static async Task Start() 14 | { 15 | try 16 | { 17 | 18 | //BluetoothRadio.PrimaryRadio.Mode = RadioMode.Connectable; 19 | //using (BluetoothClient client = new BluetoothClient()) 20 | //{ 21 | // BluetoothDeviceInfo[] devices = client.DiscoverDevices(); 22 | 23 | // var PixelDevice = devices.FirstOrDefault(q => q.DeviceName.Contains("PIXEL")); 24 | // var installedService = PixelDevice.InstalledServices[0]; 25 | // var ep = new InTheHand.Net.BluetoothEndPoint(PixelDevice.DeviceAddress, installedService); 26 | // client.Connect(ep); 27 | // var bluetoothStream = client.GetStream(); 28 | 29 | // if (client.Connected && bluetoothStream != null) 30 | // { 31 | // bluetoothStream.WriteByte(0x1F); 32 | // await bluetoothStream.WriteAsync(Encoding.ASCII.GetBytes("Teste Teste Teste Teste")); 33 | // await bluetoothStream.FlushAsync(); 34 | // bluetoothStream.Close(); 35 | // } 36 | 37 | // #region Teste 38 | // //String authenticated; 39 | // //String classOfDevice; 40 | // //String connected; 41 | // //String deviceAddress; 42 | // //String deviceName; 43 | // //String installedServices; 44 | // //String lastSeen; 45 | // //String lastUsed; 46 | // //String remembered; 47 | // //String rssi; 48 | 49 | 50 | // //foreach (BluetoothDeviceInfo device in devices) 51 | // //{ 52 | // // authenticated = device.Authenticated.ToString(); 53 | // // classOfDevice = device.ClassOfDevice.ToString(); 54 | // // connected = device.Connected.ToString(); 55 | // // deviceAddress = device.DeviceAddress.ToString(); 56 | // // deviceName = device.DeviceName.ToString(); 57 | // // installedServices = device.InstalledServices.ToString(); 58 | // // lastSeen = device.LastSeen.ToString(); 59 | // // lastUsed = device.LastUsed.ToString(); 60 | // // remembered = device.Remembered.ToString(); 61 | // // rssi = device.Rssi.ToString(); 62 | // // string[] row = new string[] { authenticated, classOfDevice, connected, deviceAddress, deviceName, installedServices, lastSeen, lastUsed, remembered, rssi }; 63 | // // Console.WriteLine(string.Join(',',row)); 64 | // //} 65 | 66 | // #endregion 67 | 68 | //} //BluetoothRadio.PrimaryRadio.Mode = RadioMode.Connectable; 69 | //using (BluetoothClient client = new BluetoothClient()) 70 | //{ 71 | // BluetoothDeviceInfo[] devices = client.DiscoverDevices(); 72 | 73 | // var PixelDevice = devices.FirstOrDefault(q => q.DeviceName.Contains("PIXEL")); 74 | // var installedService = PixelDevice.InstalledServices[0]; 75 | // var ep = new InTheHand.Net.BluetoothEndPoint(PixelDevice.DeviceAddress, installedService); 76 | // client.Connect(ep); 77 | // var bluetoothStream = client.GetStream(); 78 | 79 | // if (client.Connected && bluetoothStream != null) 80 | // { 81 | // bluetoothStream.WriteByte(0x1F); 82 | // await bluetoothStream.WriteAsync(Encoding.ASCII.GetBytes("Teste Teste Teste Teste")); 83 | // await bluetoothStream.FlushAsync(); 84 | // bluetoothStream.Close(); 85 | // } 86 | 87 | // #region Teste 88 | // //String authenticated; 89 | // //String classOfDevice; 90 | // //String connected; 91 | // //String deviceAddress; 92 | // //String deviceName; 93 | // //String installedServices; 94 | // //String lastSeen; 95 | // //String lastUsed; 96 | // //String remembered; 97 | // //String rssi; 98 | 99 | 100 | // //foreach (BluetoothDeviceInfo device in devices) 101 | // //{ 102 | // // authenticated = device.Authenticated.ToString(); 103 | // // classOfDevice = device.ClassOfDevice.ToString(); 104 | // // connected = device.Connected.ToString(); 105 | // // deviceAddress = device.DeviceAddress.ToString(); 106 | // // deviceName = device.DeviceName.ToString(); 107 | // // installedServices = device.InstalledServices.ToString(); 108 | // // lastSeen = device.LastSeen.ToString(); 109 | // // lastUsed = device.LastUsed.ToString(); 110 | // // remembered = device.Remembered.ToString(); 111 | // // rssi = device.Rssi.ToString(); 112 | // // string[] row = new string[] { authenticated, classOfDevice, connected, deviceAddress, deviceName, installedServices, lastSeen, lastUsed, remembered, rssi }; 113 | // // Console.WriteLine(string.Join(',',row)); 114 | // //} 115 | 116 | // #endregion 117 | 118 | //} 119 | 120 | } 121 | catch(Exception exp) 122 | { 123 | Console.WriteLine(exp.Message); 124 | } 125 | } 126 | 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /WebMatBot/Lights/AudioVisual.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading.Tasks; 5 | using YeelightAPI.Models.ColorFlow; 6 | 7 | namespace WebMatBot.Lights 8 | { 9 | public class AudioVisual 10 | { 11 | public static async Task Party(string txt, string user) 12 | { 13 | try 14 | { 15 | //sem await para não ter q parar as luzes e depois falar o texto 16 | Light.StartLightFlow(user); 17 | 18 | Sounds.RandomPartySound(); 19 | 20 | await Light.StopLightFlow(); 21 | 22 | } 23 | catch (Exception ex) 24 | { 25 | await IrcEngine.CommandCorrector(txt, "!Light",user:user, shouldBeExact:true); 26 | } 27 | } 28 | 29 | public static async Task Anthem(string txt, string user) 30 | { 31 | //sem await para não ter q parar as luzes e depois falar o texto 32 | Light.StartLightFlowAnthem(user); 33 | 34 | Random random = new Random(); 35 | var index = random.Next(Enum.GetValues(typeof(Translate.Languages)).Length); 36 | 37 | //colocar o speaker pra falar em uma lingua randomicamente 38 | GoogleSpeakers.Speak("golira, tevelisão, abdominável, estrepe, pobrema, mortandela, entertido, carda?o, salchicha, meia cansada, asterístico, " + 39 | "ciclo vicioso, bicabornato, beneficiente, metereologia, triologia, conhecidência, célebro, entertido, madastra, imbigo, cocrante, padastro, " + 40 | "iorgurte, trabisseiro, bassoura, menas, seje, provalecer, esteje, guspe, chuva de granito... Salve todos os BOTES dos DEVES...", "OBOT", (Translate.Languages)Enum.GetValues(typeof(Translate.Languages)).GetValue(index)); 41 | 42 | await Light.StopLightFlow(); 43 | } 44 | 45 | public static async Task Xandao(string txt, string user) 46 | { 47 | try 48 | { 49 | //sem await para não ter q parar as luzes e depois falar o texto 50 | Light.StartLightFlow(user); 51 | 52 | Sounds.Xandao(); 53 | 54 | await Light.StopLightFlow(); 55 | 56 | } 57 | catch (Exception ex) 58 | { 59 | await IrcEngine.CommandCorrector(txt, "!AudioVisual",user:user, shouldBeExact:true); 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /WebMatBot/Lights/Light.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.Design; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using YeelightAPI; 7 | using YeelightAPI.Models.ColorFlow; 8 | 9 | namespace WebMatBot.Lights 10 | { 11 | public class Light 12 | { 13 | public enum Status 14 | { 15 | Enabled, 16 | Disabled 17 | } 18 | 19 | private static Status _State = Status.Disabled; 20 | public static Status State { get => _State; 21 | set 22 | { 23 | _State = value; 24 | if (_State == Status.Enabled) 25 | Start(); 26 | } 27 | } 28 | 29 | public static string ipLight = "192.168.0.14"; 30 | private static Device device { get; set; } 31 | 32 | public static async Task Start() 33 | { 34 | try 35 | { 36 | if (State == Status.Enabled) 37 | { 38 | device = new Device(ipLight, autoConnect: false); 39 | Console.WriteLine(device.FirmwareVersion); 40 | if (device.IsConnected) 41 | { 42 | await device.TurnOn(); 43 | await Random(""); 44 | } 45 | else 46 | await device.Connect(); 47 | } 48 | } 49 | catch (Exception excpt) 50 | { 51 | Console.WriteLine(excpt.Message); 52 | } 53 | } 54 | 55 | private static async Task Random(string user) 56 | { 57 | if (!await CheckStatus(user)) 58 | return; 59 | 60 | int r = 0, g = 0, b = 0; 61 | 62 | while (r == 0 && b == 0 && g == 0) 63 | { 64 | Random random = new Random(); 65 | r = random.Next(0, 255); 66 | g = random.Next(0, 255); 67 | b = random.Next(0, 255); 68 | } 69 | 70 | await SetRGBColor($"rgb({r},{g},{b})", user); 71 | } 72 | 73 | public static async Task Command(string cmd, string user) 74 | { 75 | if (!await CheckStatus(user)) 76 | return; 77 | 78 | bool founded = false; 79 | 80 | cmd = cmd.Trim().Replace("\r\n", ""); 81 | if (cmd.StartsWith("rgb")) 82 | { 83 | await SetRGBColor(cmd, user); 84 | founded = true; 85 | } 86 | 87 | 88 | switch (cmd) 89 | { 90 | case "blue": 91 | await SetRGBColor("rgb(0,0,255)", user); 92 | founded = true; 93 | break; 94 | case "red": 95 | await SetRGBColor("rgb(255,0,0)", user); 96 | founded = true; 97 | break; 98 | case "green": 99 | await SetRGBColor("rgb(0,255,0)", user); 100 | founded = true; 101 | break; 102 | case "yellow": 103 | await SetRGBColor("rgb(255,255,0)", user); 104 | founded = true; 105 | break; 106 | case "white": 107 | await SetRGBColor("rgb(255,255,255)", user); 108 | founded = true; 109 | break; 110 | case "pink": 111 | await SetRGBColor("rgb(255,0,155)", user); 112 | founded = true; 113 | break; 114 | case "orange": 115 | await SetRGBColor("rgb(255,155,0)", user); 116 | founded = true; 117 | break; 118 | case "purple": 119 | await SetRGBColor("rgb(127,0,255)", user); 120 | founded = true; 121 | break; 122 | case "random": 123 | await Random(user); 124 | founded = true; 125 | break; 126 | } 127 | 128 | //não encontrou nenhum comando 129 | if (!founded) 130 | { 131 | await IrcEngine.CommandCorrector(cmd, "!Light",user:user, shouldBeExact: true); 132 | } 133 | } 134 | 135 | private static async Task SetRGBColor(string rawSTR, string user) 136 | { 137 | try 138 | { 139 | if (!device.IsConnected) 140 | return; 141 | 142 | //trabalhar a string para remover dados 143 | string[] rgb = rawSTR.Split("rgb")[1].Replace("(", "").Replace(")", "").Split(","); 144 | int r = int.Parse(rgb[0]); 145 | int g = int.Parse(rgb[1]); 146 | int b = int.Parse(rgb[2]); 147 | 148 | if (r > 255 || r < 0 || g > 255 || g < 0 || b > 255 || b < 0 || (r == 0 && g == 0 && b == 0)) 149 | throw new Exception("Parametro(s) inválido(s)"); 150 | 151 | await device.SetRGBColor(r, g, b); 152 | } 153 | catch (Exception ex) 154 | { 155 | await IrcEngine.CommandCorrector(rawSTR, "!Light",user: user, shouldBeExact: true); 156 | } 157 | } 158 | 159 | public static async Task StartLightFlow(string user) 160 | { 161 | if (!await CheckStatus(user)) 162 | return; 163 | 164 | if (device.IsConnected) 165 | { 166 | Random rand = new Random(); 167 | ColorFlow flow = new ColorFlow(0, ColorFlowEndAction.Restore); 168 | flow.Add(new ColorFlowRGBExpression(27, 149, 211, 100, rand.Next(200, 450))); // color : red / brightness : 1% / duration : 500 169 | flow.Add(new ColorFlowRGBExpression(206, 95, 26, 100, rand.Next(200, 450))); // color : green / brightness : 100% / duration : 500 170 | flow.Add(new ColorFlowRGBExpression(31, 88, 162, 100, rand.Next(200, 450))); // color : blue / brightness : 50% / duration : 500 171 | flow.Add(new ColorFlowRGBExpression(213, 122, 25, 100, rand.Next(200, 450))); 172 | flow.Add(new ColorFlowRGBExpression(104, 62, 139, 100, rand.Next(200, 450))); 173 | flow.Add(new ColorFlowRGBExpression(232, 178, 20, 100, rand.Next(200, 450))); 174 | flow.Add(new ColorFlowRGBExpression(163, 65, 141, 100, rand.Next(200, 450))); 175 | flow.Add(new ColorFlowRGBExpression(253, 236, 16, 100, rand.Next(200, 450))); 176 | flow.Add(new ColorFlowRGBExpression(200, 46, 129, 100, rand.Next(200, 450))); 177 | flow.Add(new ColorFlowRGBExpression(129, 178, 61, 100, rand.Next(200, 450))); 178 | 179 | await device.StartColorFlow(flow); // start 180 | } 181 | } 182 | 183 | public static async Task StartLightFlowAnthem(string user) 184 | { 185 | if (!await CheckStatus(user)) 186 | return; 187 | 188 | if (device.IsConnected) 189 | { 190 | Random rand = new Random(); 191 | ColorFlow flow = new ColorFlow(0, ColorFlowEndAction.Restore); 192 | flow.Add(new ColorFlowRGBExpression(1, 0, 173, 100, rand.Next(1300, 5000))); // blue screen of death 193 | flow.Add(new ColorFlowRGBExpression(118, 185, 0, 100, rand.Next(200, 450))); // nvidia's green 194 | flow.Add(new ColorFlowRGBExpression(222, 0, 49, 100, rand.Next(200, 450))); // amd's red 195 | await device.StartColorFlow(flow); // start 196 | } 197 | } 198 | 199 | public static async Task StopLightFlow() 200 | { 201 | if (device.IsConnected) 202 | { 203 | await Light.device.StopColorFlow(); 204 | } 205 | } 206 | 207 | public static async Task Stop() 208 | { 209 | if (device.IsConnected) 210 | await device.TurnOff(); 211 | } 212 | 213 | public static async Task CheckStatus(string user) 214 | { 215 | if (State == Status.Enabled) 216 | return true; 217 | else 218 | await IrcEngine.Respond("As alterações de luzes estão desabilitadas, por favor peça o streamer para ativa-las...", user); 219 | 220 | return false; 221 | } 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /WebMatBot/Program.cs: -------------------------------------------------------------------------------- 1 | using F23.StringSimilarity; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Net.WebSockets; 6 | using System.Text; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | using WebMatBot.Core; 10 | using WindowsInput; 11 | using static WebMatBotV3.Shared.Entity.Balls; 12 | 13 | namespace WebMatBot 14 | { 15 | public class Program 16 | { 17 | static async Task Main(string[] args) 18 | { 19 | await Start(); 20 | 21 | // to set new parameters while running 22 | await ListeningNewSettings(); 23 | } 24 | 25 | public static async Task Start() 26 | { 27 | Task.Run(() => IrcEngine.Start()); // run the core of twitch connection in a new thread 28 | Task.Run(() => TasksQueueOutput.Start()); 29 | Task.Run(() => AutomaticMessages.StartScheduled()); 30 | Task.Run(() => AutomaticMessages.StartLiquid()); 31 | Task.Run(() => Lights.Light.Start()); 32 | Task.Run(() => PubSubEngine.Start()); 33 | Task.Run(() => Games.Cannon_Store.Start()); 34 | } 35 | 36 | private static async Task ListeningNewSettings() 37 | { 38 | do 39 | { 40 | try 41 | { 42 | var line = Console.ReadLine(); 43 | await SendCommand(line); 44 | } 45 | catch (Exception except) 46 | { 47 | Console.WriteLine(except.Message); 48 | } 49 | } while (true); 50 | } 51 | 52 | public static async Task SendCommand(string line) 53 | { 54 | 55 | string result = "Fail"; 56 | if (line.ToLower().Contains("!setproject")) 57 | { 58 | Commands.ProjectLink = line.Split(" ")[1]; 59 | result = "Projet link is :" + Commands.ProjectLink; 60 | } 61 | 62 | if (line.ToLower().Contains("!settetris")) 63 | { 64 | Commands.TetrisLink = line.Split(" ")[1]; 65 | result = "Tetris link is: " + Commands.TetrisLink; 66 | } 67 | 68 | if (line.ToLower().Contains("!setspeaker")) 69 | { 70 | line = line.ToLower(); 71 | switch (line.Split(" ")[1]) 72 | { 73 | case "pause": 74 | SpeakerCore.State = SpeakerCore.Status.Paused; 75 | break; 76 | case "play": 77 | case "true": 78 | SpeakerCore.State = SpeakerCore.Status.Enabled; 79 | break; 80 | case "false": 81 | SpeakerCore.State = SpeakerCore.Status.Disabled; 82 | break; 83 | } 84 | 85 | result = "Speaker now is: " + SpeakerCore.State.ToString(); 86 | } 87 | 88 | if (line.ToLower().Contains("!setscreen")) 89 | { 90 | switch (line.Split(" ")[1]) 91 | { 92 | case "true": 93 | Screens.isActive = true; 94 | break; 95 | case "false": 96 | Screens.isActive = false; 97 | break; 98 | } 99 | result = "Screen Changer now is: " + (Screens.isActive ? "Active" : "Deactivated"); 100 | } 101 | 102 | if (line.ToLower().Contains("!settroll")) 103 | { 104 | switch (line.Split(" ")[1]) 105 | { 106 | case "true": 107 | Sounds.TrollisActive = true; 108 | break; 109 | case "false": 110 | Sounds.TrollisActive = false; 111 | break; 112 | } 113 | 114 | result = "Speaker Troll now is: " + (Sounds.TrollisActive ? "Active" : "Deactivated"); 115 | } 116 | 117 | if (line.ToLower().Contains("!setspeaktime")) 118 | { 119 | line = line.ToLower(); 120 | int newTime = TasksQueueOutput.TimeSleeping; 121 | 122 | int.TryParse(line.Split(" ")[1], out newTime); 123 | 124 | TasksQueueOutput.TimeSleeping = newTime; 125 | 126 | result = "Speaker now has time delay: " + TasksQueueOutput.TimeSleeping.ToString() + " seconds"; 127 | } 128 | 129 | if (line.ToLower().Contains("!setcannon")) 130 | { 131 | switch (line.Split(" ")[1]) 132 | { 133 | case "true": 134 | Games.Cannon.State = Games.Cannon.Status.Enabled; 135 | break; 136 | case "false": 137 | Games.Cannon.State = Games.Cannon.Status.Disabled; 138 | break; 139 | } 140 | 141 | result = "Cannon now is: " + (Games.Cannon.State == Games.Cannon.Status.Enabled ? "Active" : "Deactivated"); 142 | } 143 | 144 | if (line.ToLower().Contains("!setlight")) 145 | { 146 | switch (line.Split(" ")[1]) 147 | { 148 | case "true": 149 | Lights.Light.State = Lights.Light.Status.Enabled; 150 | break; 151 | case "false": 152 | Lights.Light.State = Lights.Light.Status.Disabled; 153 | break; 154 | } 155 | 156 | result = "Lights now are: " + (Lights.Light.State == Lights.Light.Status.Enabled ? "Active" : "Deactivated"); 157 | } 158 | 159 | if (line.ToLower().Contains("!setiplight")) 160 | { 161 | Lights.Light.ipLight = (line.Split(" ")[1]); 162 | 163 | result = "Ip Light now is: " + Lights.Light.ipLight; 164 | } 165 | 166 | if (line.ToLower().Contains("!addcannon")) 167 | { 168 | var parameters = line.Split("!AddCannon")[0].Trim().Split(" "); 169 | 170 | if (parameters.Length == 4) 171 | { 172 | var user = parameters[1]; 173 | var args = parameters[2] + " " + parameters[3]; 174 | 175 | await Games.Cannon.NewRedemptionGame(user, args); 176 | 177 | result = "Added [" + user + "] Balls:" + parameters[2] + " and JackPot:" + parameters[3]; 178 | } 179 | else result = "Fail"; 180 | } 181 | 182 | if (line.ToLower().Contains("!cannonlist")) 183 | { 184 | await Games.Cannon.GenerateList(); 185 | } 186 | 187 | if (line.ToLower().Contains("!cannonstore")) 188 | { 189 | Task.Run(() => Games.Cannon_Store.OpenMarketCommand()); 190 | } 191 | 192 | if (line.ToLower().Contains("!cannonstopstore")) 193 | { 194 | Games.Cannon_Store.CloseMarketCommand(); 195 | } 196 | 197 | if (line.ToLower().Contains("!addskin")) 198 | { 199 | var parameters = line.Split("!addskin")[1].Trim().Split(" "); 200 | 201 | if (parameters.Length == 2) 202 | { 203 | var user = parameters[0]; 204 | var value = int.Parse(parameters[1]); 205 | 206 | await Games.Cannon_Store.BuyBallCommand(user, value, Games.Cannon_Store.TypePayment.bits); 207 | } 208 | else result = "Fail parameters"; 209 | } 210 | 211 | await WebMatBot.IrcEngine.Analizer("badges=broadcaster;user-type= :" + Parameters.User + "!" + Parameters.User + "@" + Parameters.User + ".tmi.twitch.tv PRIVMSG " + line); 212 | 213 | //Console.WriteLine(result); 214 | return result; 215 | } 216 | } 217 | } -------------------------------------------------------------------------------- /WebMatBot/Sounds/General/aplausos.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/General/aplausos.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/General/rimshot.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/General/rimshot.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/General/xandao.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/General/xandao.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Party/baby-shark.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Party/baby-shark.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Party/naruto-trap.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Party/naruto-trap.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Party/sbtrapvinebycarb0n.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Party/sbtrapvinebycarb0n.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Party/trap_android.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Party/trap_android.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Party/yoshi_gets_lit_trap_remixgrabfrom.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Party/yoshi_gets_lit_trap_remixgrabfrom.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Troll/ajuda-o-maluco.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Troll/ajuda-o-maluco.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Troll/batida-de-porta-troll.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Troll/batida-de-porta-troll.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Troll/birl.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Troll/birl.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Troll/cavalo.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Troll/cavalo.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Troll/choque-da-uva.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Troll/choque-da-uva.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Troll/eoq.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Troll/eoq.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Troll/failhorn.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Troll/failhorn.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Troll/faustao-errou.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Troll/faustao-errou.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Troll/hadouken.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Troll/hadouken.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Troll/kasino.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Troll/kasino.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Troll/metalgearsolid.swf.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Troll/metalgearsolid.swf.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Troll/olha_a_pedra.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Troll/olha_a_pedra.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Troll/quack.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Troll/quack.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Troll/que-ota.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Troll/que-ota.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Troll/tafareeel.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Troll/tafareeel.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Troll/vergonha.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Troll/vergonha.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Troll/xandao.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Troll/xandao.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Troll/xaropinho.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Troll/xaropinho.mp3 -------------------------------------------------------------------------------- /WebMatBot/Sounds/Troll/zach.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBot/Sounds/Troll/zach.mp3 -------------------------------------------------------------------------------- /WebMatBot/Speakers/AzureSpeakers.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CognitiveServices.Speech; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using WebMatBot.Core; 9 | using static WebMatBot.Translate; 10 | 11 | namespace WebMatBot 12 | { 13 | public class AzureSpeakers 14 | { 15 | private static SpeechConfig config = (string.IsNullOrEmpty(Parameters.AzureCognitiveKey)||string.IsNullOrEmpty(Parameters.AzureCognitiveRegion)) ? null : SpeechConfig.FromSubscription(Parameters.AzureCognitiveKey, Parameters.AzureCognitiveRegion);//https://portal.azure.com/ 16 | private static IList Speakers = new List() 17 | { 18 | new Speaker(){ Alert = "Insha'Allah", Voice = "ar-EG-Hoda", Diction = "", Language=Languages.ar, Accent = "ar-XA" }, 19 | new Speaker(){ Alert = "Schweinsteiger", Voice = "de-DE-Stefan", Diction = "", Language=Languages.de , Accent ="de-DE" }, 20 | new Speaker(){ Alert = "Malaká", Voice = "el-GR-Stefanos", Diction = "", Language=Languages.el, Accent = "el-GR"}, 21 | new Speaker(){ Alert = "Heyyy.", Voice = "en-AU-Catherine", Diction = "", Language=Languages.en, Accent = "en-AU" }, 22 | new Speaker(){ Alert = "A buenas horas mangas verdes", Voice = "es-MX-Raul", Diction = "", Language=Languages.es, Accent = "es-ES"}, 23 | new Speaker(){ Alert = "Thierry Henry", Voice = "fr-FR-Julie", Diction = "" , Language=Languages.fr, Accent = "fr-FR"}, 24 | new Speaker(){ Alert = "Mama mia Marcello.", Voice = "it-IT-Cosimo", Diction = "", Language=Languages.it, Accent = "it-IT"}, 25 | new Speaker(){ Alert = "Nani", Voice = "ja-JP-Ichiro", Diction = "", Language=Languages.ja, Accent = "ja-JP"}, 26 | new Speaker(){ Alert = "Ora Pois", Voice = "pt-PT-HeliaRUS", Diction = "", Language=Languages.pt , Accent = "pt-PT"}, 27 | new Speaker(){ Alert = "Sputinik", Voice = "ru-RU-Irina", Diction = "", Language=Languages.ru, Accent = "ru-RU"}, 28 | new Speaker(){ Alert = "wǒ shì bā xī rén", Voice = "zh-CN-Yaoyao", Diction = "", Language=Languages.zh, Accent = "cmn-CN"}, 29 | }; 30 | 31 | public static async Task Speak(string textToSpeech, string user,Languages lang) 32 | { 33 | if (!await SpeakerCore.CheckStatus(user) || config == null) return; 34 | 35 | Speaker spk = Speakers.FirstOrDefault(q => q.Language == lang); 36 | 37 | if (spk != null) await SpeakAzure(spk, textToSpeech, user); 38 | } 39 | 40 | 41 | private static async Task SpeakAzure(ISpeaker speaker, string textToSpeech, string user) 42 | { 43 | textToSpeech = textToSpeech.Replace("\"", "\"\""); 44 | 45 | config.SpeechSynthesisVoiceName = speaker.Voice; 46 | using var synthesizer = new SpeechSynthesizer(config); 47 | 48 | var ssml = File.ReadAllText("Speakers/SSML.xml").Replace("{text}", textToSpeech).Replace("{voice}", speaker.Voice).Replace("{posmsg}", speaker.Diction).Replace("{alert}", speaker.Alert); 49 | 50 | SpeakerCore.PreSpeech(user); 51 | 52 | var result = await synthesizer.SpeakSsmlAsync(ssml); 53 | 54 | await AutomaticTranslator.Translate(textToSpeech, user); 55 | } 56 | 57 | public static async Task SpeakTranslate(string cmd, string user) 58 | { 59 | string msg; 60 | Languages? src, trg; 61 | if (GetLanguages(cmd, out src, out trg, out msg)) 62 | { 63 | var Target = trg.Value; 64 | 65 | msg = await TranslateCore(msg, false, Target, user); 66 | 67 | await TasksQueueOutput.QueueAddSpeech(async () => await Speak(msg, user,Target), user); 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /WebMatBot/Speakers/GoogleSpeakers.cs: -------------------------------------------------------------------------------- 1 | using Google.Apis.Http; 2 | using Google.Cloud.TextToSpeech.V1; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Diagnostics; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using WebMatBot.Core; 11 | using static WebMatBot.Translate; 12 | 13 | namespace WebMatBot 14 | { 15 | public class GoogleSpeakers 16 | { 17 | 18 | private static IList Speakers = new List() 19 | { 20 | new Speaker(){ Alert = "Insha'Allah?", Voice = "ar-XA-Standard-D", Diction = "", Language=Languages.ar , Accent = "ar-XA" }, 21 | new Speaker(){ Alert = "Schweinsteiger?", Voice = "de-DE-Standard-F", Diction = "", Language=Languages.de , Accent ="de-DE"}, 22 | new Speaker(){ Alert = "Malaká?", Voice = "el-GR-Standard-A", Diction = "", Language=Languages.el , Accent = "el-GR"}, 23 | new Speaker(){ Alert = "Hey?", Voice = "en-US-Standard-C", Diction = "", Language=Languages.en , Accent = "en-AU"}, 24 | new Speaker(){ Alert = "¿A buenas horas mangas verdes?", Voice = "es-ES-Standard-A", Diction = "", Language=Languages.es , Accent = "es-ES"}, 25 | new Speaker(){ Alert = "Thierry Henry?", Voice = "fr-FR-Standard-E", Diction = "" , Language=Languages.fr , Accent = "fr-FR"}, 26 | new Speaker(){ Alert = "Mama mia Marcello?", Voice = "it-IT-Standard-D", Diction = "", Language=Languages.it, Accent = "it-IT" }, 27 | new Speaker(){ Alert = "Nani?", Voice = "ja-JP-Standard-A", Diction = "", Language=Languages.ja, Accent = "ja-JP" }, 28 | new Speaker(){ Alert = "Ora Pois?", Voice = "pt-PT-Standard-C", Diction = "", Language=Languages.pt, Accent = "pt-PT" }, 29 | new Speaker(){ Alert = "Sputinik?", Voice = "ru-RU-Standard-E", Diction = "", Language=Languages.ru , Accent = "ru-RU"}, 30 | new Speaker(){ Alert = "wǒ shì bā xī rén?", Voice = "cmn-CN-Standard-D", Diction = "", Language=Languages.zh , Accent = "cmn-CN"}, 31 | }; 32 | 33 | 34 | public static async Task Speak(string textToSpeech, string user,Languages lang) 35 | { 36 | if (!await SpeakerCore.CheckStatus(user) || Parameters.GoogleTranslateApiKey == null) return; 37 | 38 | Speaker spk = Speakers.FirstOrDefault(q => q.Language == lang); 39 | 40 | if (spk != null) await SpeakGoogle(spk, textToSpeech, user); 41 | } 42 | 43 | private static async Task SpeakGoogle(ISpeaker speaker, string textToSpeech, string user) 44 | { 45 | textToSpeech = textToSpeech.Replace("\"", "\"\""); 46 | 47 | // Instantiate a client 48 | TextToSpeechClient client = TextToSpeechClient.Create(); 49 | 50 | // Set the text input to be synthesized. 51 | SynthesisInput input = new SynthesisInput 52 | { 53 | //Text = textToSpeech, 54 | Ssml = File.ReadAllText("Speakers/SSML.xml").Replace("{text}", textToSpeech).Replace("{voice}", speaker.Voice).Replace("{posmsg}", speaker.Diction).Replace("{alert}", speaker.Alert), 55 | }; 56 | 57 | // Build the voice request, select the language code ("en-US"), 58 | // and the SSML voice gender ("neutral"). 59 | VoiceSelectionParams voice = new VoiceSelectionParams 60 | { 61 | LanguageCode = speaker.Accent.ToString(), 62 | //SsmlGender = SsmlVoiceGender.Neutral 63 | }; 64 | 65 | // Select the type of audio file you want returned. 66 | AudioConfig config = new AudioConfig 67 | { 68 | AudioEncoding = AudioEncoding.Mp3 69 | }; 70 | 71 | // Perform the Text-to-Speech request, passing the text input 72 | // with the selected voice parameters and audio file type 73 | var response = await client.SynthesizeSpeechAsync(new SynthesizeSpeechRequest 74 | { 75 | Input = input, 76 | Voice = voice, 77 | AudioConfig = config 78 | }); 79 | 80 | // create a temp file with .ps1 extension 81 | var cFile = System.IO.Path.GetTempPath() + Guid.NewGuid() + ".mp3"; 82 | 83 | // Write the binary AudioContent of the response to an MP3 file. 84 | using (Stream output = File.Create(cFile)) 85 | response.AudioContent.WriteTo(output); 86 | 87 | Sounds.RandomTrollSound(); 88 | 89 | SpeakerCore.PreSpeech(user); 90 | 91 | SpeakerCore.ExecuteMP3File(cFile); 92 | 93 | await AutomaticTranslator.Translate(textToSpeech, user); 94 | 95 | } 96 | 97 | public static async Task SpeakTranslate(string cmd, string user) 98 | { 99 | string msg; 100 | Languages? src, trg; 101 | if (GetLanguages(cmd, out src, out trg, out msg)) 102 | { 103 | var Target = trg.Value; 104 | 105 | msg = await TranslateCore(msg, false, Target, user); 106 | 107 | await TasksQueueOutput.QueueAddSpeech(async () => await Speak(msg, user,Target), user); 108 | } 109 | else 110 | { 111 | await IrcEngine.CommandCorrector(cmd,"!SpeakTranslate",user: user, shouldBeExact:true); 112 | } 113 | } 114 | 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /WebMatBot/Speakers/SSML.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | {alert}{text} {posmsg} 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WebMatBot/Speakers/Speaker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using static WebMatBot.Translate; 5 | 6 | namespace WebMatBot 7 | { 8 | public class Speaker : ISpeaker 9 | { 10 | public Languages Language { get; set; } 11 | 12 | public string Voice { get; set; } 13 | 14 | public string Alert { get; set; } 15 | 16 | public string Diction { get; set; } 17 | 18 | public string Accent { get; set; } 19 | } 20 | 21 | public interface ISpeaker 22 | { 23 | Languages Language { get; set; } 24 | 25 | string Voice { get; set; } 26 | 27 | string Alert { get; set; } 28 | 29 | string Diction { get; set; } 30 | 31 | string Accent { get; set; } 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /WebMatBot/Speakers/SpeakerCore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using static WebMatBot.Translate; 9 | 10 | namespace WebMatBot 11 | { 12 | public class SpeakerCore 13 | { 14 | //public static bool Speaker { get; set; } = false; 15 | public static Status State { get; set; } = Status.Enabled; 16 | 17 | public static async Task Speak(string textToSpeech, string user,bool wait = true, string speakRate = "0") 18 | { 19 | if (!await CheckStatus(user)) return; 20 | 21 | Sounds.RandomTrollSound(); 22 | 23 | PreSpeech(user); 24 | 25 | textToSpeech = textToSpeech.Replace("\"", "\"\""); 26 | 27 | // Command to execute PS 28 | ExecutePowerShell($@"Add-Type -AssemblyName System.speech; 29 | $speak = New-Object System.Speech.Synthesis.SpeechSynthesizer; 30 | $speak.Rate = {speakRate}; 31 | $speak.Speak(""{textToSpeech}"");"); // Embedd text 32 | 33 | await AutomaticTranslator.Translate(textToSpeech, user); 34 | } 35 | 36 | public static void ExecutePowerShell(string command) 37 | { 38 | // create a temp file with .ps1 extension 39 | var cFile = System.IO.Path.GetTempPath() + Guid.NewGuid() + ".ps1"; 40 | 41 | //Write the .ps1 42 | using (var tw = new System.IO.StreamWriter(cFile, false, Encoding.UTF8)) 43 | tw.Write(command); 44 | 45 | 46 | // Setup the PS 47 | var start = 48 | new System.Diagnostics.ProcessStartInfo() 49 | { 50 | FileName = "C:\\windows\\system32\\windowspowershell\\v1.0\\powershell.exe", 51 | LoadUserProfile = false, 52 | UseShellExecute = false, 53 | CreateNoWindow = true, 54 | Arguments = $"-executionpolicy bypass -File {cFile}", 55 | WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal 56 | }; 57 | var p = System.Diagnostics.Process.Start(start); 58 | p.StartInfo.RedirectStandardOutput = true; 59 | var copyProcess = Process.GetCurrentProcess(); 60 | p.WaitForExit(); 61 | } 62 | 63 | public static void ExecuteMP3File(string path) 64 | { 65 | ExecutePowerShell($@"Add-Type -AssemblyName PresentationCore; 66 | $mediaPlayer = New-Object System.Windows.Media.MediaPlayer; 67 | do{{ 68 | $mediaPlayer.Open(""{path}""); 69 | $musicaDuracao = $mediaPlayer.NaturalDuration.TimeSpan.TotalMilliseconds; 70 | }} 71 | until($musicaDuracao) 72 | $mediaPlayer.Play(); 73 | Start-Sleep -Milliseconds $musicaDuracao;"); 74 | } 75 | 76 | public static void PreSpeech(string user) 77 | { 78 | string text = user + " diz: "; 79 | 80 | // Command to execute PS 81 | ExecutePowerShell($@"Add-Type -AssemblyName System.speech; 82 | $speak = New-Object System.Speech.Synthesis.SpeechSynthesizer; 83 | $speak.Speak(""{text}"");"); // Embedd text 84 | } 85 | 86 | public static async Task CheckStatus(string user) 87 | { 88 | if (State == Status.Disabled) 89 | { 90 | await IrcEngine.Respond("O Speaker está off... peça o streamer para acioná-lo...", user); 91 | return false; 92 | } 93 | else 94 | return true; 95 | } 96 | public enum Status 97 | { 98 | Disabled, 99 | Enabled, 100 | Paused, 101 | } 102 | } 103 | 104 | 105 | } 106 | -------------------------------------------------------------------------------- /WebMatBot/Subtitles/Subtitle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using static WebMatBot.Translate; 7 | 8 | namespace WebMatBot 9 | { 10 | public class Subtitle 11 | { 12 | public static bool IsActive { get; set; } = false; 13 | 14 | public static Translate.Languages TargetLanguage { get; set; } = Translate.Languages.en; 15 | 16 | public static void TurnOn() 17 | { 18 | IsActive = false; 19 | } 20 | 21 | public static void TurnOff() 22 | { 23 | IsActive = false; 24 | } 25 | 26 | public static async Task Command(string cmd, string user) 27 | { 28 | cmd = cmd.ToLower().Trim(); 29 | 30 | if (cmd == "false" || cmd== "true") 31 | { 32 | IsActive = bool.Parse(cmd); 33 | } 34 | else 35 | { 36 | string msg; 37 | Languages? src, trg; 38 | if (GetLanguages(cmd, out src, out trg, out msg)) 39 | { 40 | IsActive = true; 41 | TargetLanguage = trg.Value; 42 | 43 | await IrcEngine.Respond("A Legenda está traduzindo para " + TargetLanguage.ToString() + "...", user); 44 | } 45 | } 46 | 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /WebMatBot/Translator/AutomaticTranslator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Linq; 5 | using static WebMatBot.Translate; 6 | using System.Threading.Tasks; 7 | 8 | namespace WebMatBot 9 | { 10 | public class AutomaticTranslator 11 | { 12 | public static Languages Target { get; set; } 13 | 14 | public static Status status { get; set; } = Status.Disabled; 15 | 16 | public enum Status 17 | { 18 | Enabled, 19 | Disabled 20 | } 21 | 22 | public static async Task Command (string cmd, string user) 23 | { 24 | cmd = cmd.ToLower().Trim(); 25 | 26 | if (cmd == "false") 27 | { 28 | status = Status.Disabled; 29 | } 30 | else 31 | { 32 | string msg; 33 | Languages? src, trg; 34 | if (GetLanguages(cmd,out src,out trg, out msg)) 35 | { 36 | status = Status.Enabled; 37 | Target = trg.Value; 38 | 39 | await IrcEngine.Respond("O tradutor está automatico para " + Target.ToString() + "...", user); 40 | } 41 | } 42 | } 43 | 44 | public static async Task Translate(string text, string user) 45 | { 46 | if (status == Status.Disabled) 47 | return; 48 | 49 | await TranslateCore(text, true, Target, user); 50 | 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /WebMatBot/Translator/Translate.cs: -------------------------------------------------------------------------------- 1 | using Google.Apis.Auth.OAuth2; 2 | using Google.Apis.Services; 3 | using Google.Cloud.Translation.V2; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace WebMatBot 10 | { 11 | public class Translate 12 | { 13 | public static int CharacterCounter { get; set; } 14 | private static int LimitCharacters = 16000; //limite de caracteres diarios. 15 | private static TranslationClient client = TranslationClient.CreateFromApiKey(Parameters.GoogleTranslateApiKey); 16 | 17 | public static async Task TranslateText(string stringRaw, bool respond, string user) 18 | { 19 | string stringToTranslate; 20 | Languages? src, trg; 21 | if (!GetLanguages(stringRaw, out src, out trg, out stringToTranslate)) 22 | return stringRaw; 23 | 24 | return await TranslateCore(stringToTranslate, respond, trg.Value, user ,src); 25 | 26 | } 27 | 28 | public static async Task TranslateCore(string textToTranslate,bool respond, Languages Trg, string user, Languages? Src = null) 29 | { 30 | //checagem de limites 31 | if (!CheckLimits(textToTranslate)) return "Limite de tradução gratuita diária estourado."; 32 | 33 | var response = await client.TranslateTextAsync( 34 | text: textToTranslate, 35 | targetLanguage: Trg.ToString(), 36 | sourceLanguage: (Src == null) ? null : Src.ToString()); 37 | 38 | //Console.WriteLine(response.TranslatedText); 39 | 40 | if (respond) await IrcEngine.Respond(response.TranslatedText, user); 41 | 42 | return response.TranslatedText; 43 | } 44 | 45 | private static bool CheckLimits(string str) 46 | { 47 | CharacterCounter += str.Length; 48 | 49 | return (CharacterCounter <= LimitCharacters); 50 | } 51 | 52 | public enum Languages 53 | { 54 | pt, 55 | en, 56 | ru, 57 | de, 58 | fr, 59 | it, 60 | ar, 61 | el, 62 | ja, 63 | zh, 64 | es, 65 | } 66 | 67 | public static bool GetLanguages(string stringRaw, out Languages? Source, out Languages? Target, out string Message) 68 | { 69 | stringRaw = stringRaw.ToLower().Trim(); 70 | var parts = stringRaw.Split(" "); 71 | var partsin = parts[0].Split("-"); 72 | 73 | string src, trg; 74 | 75 | if (partsin.Length > 1) 76 | { 77 | src = partsin[0]; 78 | trg = partsin[1]; 79 | } 80 | else 81 | { 82 | src = null; 83 | trg = partsin[0]; 84 | } 85 | 86 | Message = ""; 87 | object Src; 88 | object Trg; 89 | 90 | Enum.TryParse(typeof(Languages), src, out Src); 91 | Enum.TryParse(typeof(Languages), trg, out Trg); 92 | 93 | if (Trg != null) 94 | { 95 | Source = (Languages?)Src; 96 | Target = (Languages)Trg; 97 | 98 | parts[0] = ""; 99 | Message = string.Join(" ",parts); 100 | return true; 101 | 102 | } 103 | else 104 | { 105 | Source = null; 106 | Target = null; 107 | return false; 108 | } 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /WebMatBot/WebMatBot.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net5.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Always 23 | 24 | 25 | Always 26 | 27 | 28 | Always 29 | 30 | 31 | Always 32 | 33 | 34 | Always 35 | 36 | 37 | Always 38 | 39 | 40 | Always 41 | 42 | 43 | Always 44 | 45 | 46 | Always 47 | 48 | 49 | Always 50 | 51 | 52 | Always 53 | 54 | 55 | Always 56 | 57 | 58 | Always 59 | 60 | 61 | Always 62 | 63 | 64 | Always 65 | 66 | 67 | Always 68 | 69 | 70 | Always 71 | 72 | 73 | Always 74 | 75 | 76 | Always 77 | 78 | 79 | Always 80 | 81 | 82 | Always 83 | 84 | 85 | Always 86 | 87 | 88 | Always 89 | 90 | 91 | Always 92 | 93 | 94 | Always 95 | 96 | 97 | Always 98 | 99 | 100 | Always 101 | 102 | 103 | Always 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /WebMatBotV3/Client/App.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

Sorry, there's nothing at this address.

8 |
9 |
10 |
11 | -------------------------------------------------------------------------------- /WebMatBotV3/Client/Pages/Index.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @inject HttpClient http 3 | @inject NavigationManager nav 4 | 5 |

Hello, world!

6 | 7 | 8 | 9 | 10 | 11 |
12 |

@Iresult

13 |
14 | 15 | @code{ 16 | string Icommand { get; set; } 17 | string Iresult { get; set; } 18 | 19 | List recentCommands = new List(); 20 | int recentIndex { get; set; } 21 | 22 | async void SendCommand() 23 | { 24 | var response = await http.GetAsync($"Command/{Icommand}"); 25 | if (response.IsSuccessStatusCode) 26 | { 27 | Iresult = await response.Content.ReadAsStringAsync(); 28 | 29 | recentCommands.Add(Icommand); 30 | recentIndex = recentCommands.Count; 31 | 32 | Icommand = ""; 33 | StateHasChanged(); 34 | } 35 | 36 | } 37 | 38 | void checkCommand(KeyboardEventArgs eventArgs) 39 | { 40 | if (!(recentCommands.Count <= 0)) 41 | { 42 | bool pressed = false; 43 | 44 | if (eventArgs.Key == "ArrowUp") 45 | { 46 | recentIndex -= 1; 47 | pressed = true; 48 | } 49 | 50 | if (eventArgs.Key == "ArrowDown") 51 | { 52 | recentIndex += 1; 53 | pressed = true; 54 | } 55 | 56 | if (recentIndex < 0 && pressed) 57 | recentIndex = recentCommands.Count - 1; 58 | 59 | if (recentIndex >= recentCommands.Count && pressed) 60 | recentIndex = 0; 61 | 62 | if (pressed) Icommand = recentCommands[recentIndex]; 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /WebMatBotV3/Client/Pages/Subtitle.razor: -------------------------------------------------------------------------------- 1 | @page "/subtitle" 2 | @inject IJSRuntime jsRuntime; 3 | @inject NavigationManager NavigationManager 4 | @using Microsoft.AspNetCore.SignalR.Client; 5 | 6 |
7 | @if (running) 8 | { 9 |

@SubtitleMessage

10 | } 11 |
12 | 13 | @code{ 14 | bool running { get; set; } = false; 15 | 16 | public HubConnection connection; 17 | 18 | public string SubtitleMessage { get; set; } = ""; 19 | public DateTime LastUpdateSubTitleMessage { get; set; } = DateTime.Now; 20 | 21 | protected override async Task OnAfterRenderAsync(bool firstRender) 22 | { 23 | if (firstRender) 24 | { 25 | running = true; 26 | 27 | var dotNetReference = DotNetObjectReference.Create(this); 28 | await jsRuntime.InvokeVoidAsync("TurnOnRecognition", dotNetReference); 29 | 30 | connection = new HubConnectionBuilder() 31 | .WithUrl(NavigationManager.ToAbsoluteUri("/HubConnection")) 32 | .WithAutomaticReconnect() 33 | .Build(); 34 | 35 | connection.On("receiveTranslated", (msg) => receiveTranslated(msg)); 36 | 37 | await connection.StartAsync(); 38 | 39 | await base.OnAfterRenderAsync(firstRender); 40 | } 41 | } 42 | 43 | [JSInvokable("receiveTalk")] 44 | public async Task receiveTalk(string captured) 45 | { 46 | await connection.InvokeAsync("ToTranslate", captured); 47 | } 48 | 49 | public async Task receiveTranslated(string translated) 50 | { 51 | SubtitleMessage = translated; 52 | LastUpdateSubTitleMessage = DateTime.Now; 53 | 54 | StateHasChanged(); 55 | 56 | await InvokeAsync(async () => 57 | { 58 | await Task.Delay(5000); 59 | if (DateTime.Now > LastUpdateSubTitleMessage.AddSeconds(5)) 60 | SubtitleMessage = ""; 61 | StateHasChanged(); 62 | }); 63 | 64 | 65 | 66 | //await jsRuntime.InvokeVoidAsync("console.log", translated); 67 | } 68 | } -------------------------------------------------------------------------------- /WebMatBotV3/Client/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Net.Http; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace WebMatBotV3.Client 12 | { 13 | public class Program 14 | { 15 | public static async Task Main(string[] args) 16 | { 17 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 18 | builder.RootComponents.Add("#app"); 19 | 20 | builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); 21 | 22 | await builder.Build().RunAsync(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /WebMatBotV3/Client/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:56464", 7 | "sslPort": 44333 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "WebMatBotV3": { 20 | "commandName": "Project", 21 | "dotnetRunMessages": "true", 22 | "launchBrowser": true, 23 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 24 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /WebMatBotV3/Client/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 |
4 | @**@ 7 | 8 |
9 | @*
10 | About 11 |
*@ 12 | 13 |
14 | @Body 15 |
16 |
17 |
18 | -------------------------------------------------------------------------------- /WebMatBotV3/Client/Shared/MainLayout.razor.css: -------------------------------------------------------------------------------- 1 | .page { 2 | position: relative; 3 | display: flex; 4 | flex-direction: column; 5 | } 6 | 7 | .main { 8 | flex: 1; 9 | } 10 | 11 | .sidebar { 12 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); 13 | } 14 | 15 | .top-row { 16 | background-color: #f7f7f7; 17 | border-bottom: 1px solid #d6d5d5; 18 | justify-content: flex-end; 19 | height: 3.5rem; 20 | display: flex; 21 | align-items: center; 22 | } 23 | 24 | .top-row ::deep a, .top-row .btn-link { 25 | white-space: nowrap; 26 | margin-left: 1.5rem; 27 | } 28 | 29 | .top-row a:first-child { 30 | overflow: hidden; 31 | text-overflow: ellipsis; 32 | } 33 | 34 | @media (max-width: 640.98px) { 35 | .top-row:not(.auth) { 36 | display: none; 37 | } 38 | 39 | .top-row.auth { 40 | justify-content: space-between; 41 | } 42 | 43 | .top-row a, .top-row .btn-link { 44 | margin-left: 0; 45 | } 46 | } 47 | 48 | @media (min-width: 641px) { 49 | .page { 50 | flex-direction: row; 51 | } 52 | 53 | .sidebar { 54 | width: 250px; 55 | height: 100vh; 56 | position: sticky; 57 | top: 0; 58 | } 59 | 60 | .top-row { 61 | position: sticky; 62 | top: 0; 63 | z-index: 1; 64 | } 65 | 66 | .main > div { 67 | padding-left: 2rem !important; 68 | padding-right: 1.5rem !important; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /WebMatBotV3/Client/Shared/NavMenu.razor: -------------------------------------------------------------------------------- 1 |  7 | 8 |
9 | 21 |
22 | 23 | @code { 24 | private bool collapseNavMenu = true; 25 | 26 | private string NavMenuCssClass => collapseNavMenu ? "collapse" : null; 27 | 28 | private void ToggleNavMenu() 29 | { 30 | collapseNavMenu = !collapseNavMenu; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /WebMatBotV3/Client/Shared/NavMenu.razor.css: -------------------------------------------------------------------------------- 1 | .navbar-toggler { 2 | background-color: rgba(255, 255, 255, 0.1); 3 | } 4 | 5 | .top-row { 6 | height: 3.5rem; 7 | background-color: rgba(0,0,0,0.4); 8 | } 9 | 10 | .navbar-brand { 11 | font-size: 1.1rem; 12 | } 13 | 14 | .oi { 15 | width: 2rem; 16 | font-size: 1.1rem; 17 | vertical-align: text-top; 18 | top: -2px; 19 | } 20 | 21 | .nav-item { 22 | font-size: 0.9rem; 23 | padding-bottom: 0.5rem; 24 | } 25 | 26 | .nav-item:first-of-type { 27 | padding-top: 1rem; 28 | } 29 | 30 | .nav-item:last-of-type { 31 | padding-bottom: 1rem; 32 | } 33 | 34 | .nav-item ::deep a { 35 | color: #d7d7d7; 36 | border-radius: 4px; 37 | height: 3rem; 38 | display: flex; 39 | align-items: center; 40 | line-height: 3rem; 41 | } 42 | 43 | .nav-item ::deep a.active { 44 | background-color: rgba(255,255,255,0.25); 45 | color: white; 46 | } 47 | 48 | .nav-item ::deep a:hover { 49 | background-color: rgba(255,255,255,0.1); 50 | color: white; 51 | } 52 | 53 | @media (min-width: 641px) { 54 | .navbar-toggler { 55 | display: none; 56 | } 57 | 58 | .collapse { 59 | /* Never collapse the sidebar for wide screens */ 60 | display: block; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /WebMatBotV3/Client/Shared/SurveyPrompt.razor: -------------------------------------------------------------------------------- 1 |  11 | 12 | @code { 13 | // Demonstrates how a parent component can supply parameters 14 | [Parameter] 15 | public string Title { get; set; } 16 | } 17 | -------------------------------------------------------------------------------- /WebMatBotV3/Client/WebMatBotV3.Client.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /WebMatBotV3/Client/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using Microsoft.AspNetCore.Components.Web.Virtualization 7 | @using Microsoft.AspNetCore.Components.WebAssembly.Http 8 | @using Microsoft.JSInterop 9 | @using WebMatBotV3.Client 10 | @using WebMatBotV3.Client.Shared 11 | -------------------------------------------------------------------------------- /WebMatBotV3/Client/wwwroot/css/app.css: -------------------------------------------------------------------------------- 1 | @import url('open-iconic/font/css/open-iconic-bootstrap.min.css'); 2 | 3 | html, body { 4 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 5 | } 6 | 7 | a, .btn-link { 8 | color: #0366d6; 9 | } 10 | 11 | .btn-primary { 12 | color: #fff; 13 | background-color: #1b6ec2; 14 | border-color: #1861ac; 15 | } 16 | 17 | .content { 18 | padding-top: 1.1rem; 19 | } 20 | 21 | .valid.modified:not([type=checkbox]) { 22 | outline: 1px solid #26b050; 23 | } 24 | 25 | .invalid { 26 | outline: 1px solid red; 27 | } 28 | 29 | .validation-message { 30 | color: red; 31 | } 32 | 33 | #blazor-error-ui { 34 | background: lightyellow; 35 | bottom: 0; 36 | box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); 37 | display: none; 38 | left: 0; 39 | padding: 0.6rem 1.25rem 0.7rem 1.25rem; 40 | position: fixed; 41 | width: 100%; 42 | z-index: 1000; 43 | } 44 | 45 | #blazor-error-ui .dismiss { 46 | cursor: pointer; 47 | position: absolute; 48 | right: 0.75rem; 49 | top: 0.5rem; 50 | } 51 | -------------------------------------------------------------------------------- /WebMatBotV3/Client/wwwroot/css/open-iconic/FONT-LICENSE: -------------------------------------------------------------------------------- 1 | SIL OPEN FONT LICENSE Version 1.1 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | PREAMBLE 6 | The goals of the Open Font License (OFL) are to stimulate worldwide 7 | development of collaborative font projects, to support the font creation 8 | efforts of academic and linguistic communities, and to provide a free and 9 | open framework in which fonts may be shared and improved in partnership 10 | with others. 11 | 12 | The OFL allows the licensed fonts to be used, studied, modified and 13 | redistributed freely as long as they are not sold by themselves. The 14 | fonts, including any derivative works, can be bundled, embedded, 15 | redistributed and/or sold with any software provided that any reserved 16 | names are not used by derivative works. The fonts and derivatives, 17 | however, cannot be released under any other type of license. The 18 | requirement for fonts to remain under this license does not apply 19 | to any document created using the fonts or their derivatives. 20 | 21 | DEFINITIONS 22 | "Font Software" refers to the set of files released by the Copyright 23 | Holder(s) under this license and clearly marked as such. This may 24 | include source files, build scripts and documentation. 25 | 26 | "Reserved Font Name" refers to any names specified as such after the 27 | copyright statement(s). 28 | 29 | "Original Version" refers to the collection of Font Software components as 30 | distributed by the Copyright Holder(s). 31 | 32 | "Modified Version" refers to any derivative made by adding to, deleting, 33 | or substituting -- in part or in whole -- any of the components of the 34 | Original Version, by changing formats or by porting the Font Software to a 35 | new environment. 36 | 37 | "Author" refers to any designer, engineer, programmer, technical 38 | writer or other person who contributed to the Font Software. 39 | 40 | PERMISSION & CONDITIONS 41 | Permission is hereby granted, free of charge, to any person obtaining 42 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 43 | redistribute, and sell modified and unmodified copies of the Font 44 | Software, subject to the following conditions: 45 | 46 | 1) Neither the Font Software nor any of its individual components, 47 | in Original or Modified Versions, may be sold by itself. 48 | 49 | 2) Original or Modified Versions of the Font Software may be bundled, 50 | redistributed and/or sold with any software, provided that each copy 51 | contains the above copyright notice and this license. These can be 52 | included either as stand-alone text files, human-readable headers or 53 | in the appropriate machine-readable metadata fields within text or 54 | binary files as long as those fields can be easily viewed by the user. 55 | 56 | 3) No Modified Version of the Font Software may use the Reserved Font 57 | Name(s) unless explicit written permission is granted by the corresponding 58 | Copyright Holder. This restriction only applies to the primary font name as 59 | presented to the users. 60 | 61 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 62 | Software shall not be used to promote, endorse or advertise any 63 | Modified Version, except to acknowledge the contribution(s) of the 64 | Copyright Holder(s) and the Author(s) or with their explicit written 65 | permission. 66 | 67 | 5) The Font Software, modified or unmodified, in part or in whole, 68 | must be distributed entirely under this license, and must not be 69 | distributed under any other license. The requirement for fonts to 70 | remain under this license does not apply to any document created 71 | using the Font Software. 72 | 73 | TERMINATION 74 | This license becomes null and void if any of the above conditions are 75 | not met. 76 | 77 | DISCLAIMER 78 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 79 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 80 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 81 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 82 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 83 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 84 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 85 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 86 | OTHER DEALINGS IN THE FONT SOFTWARE. 87 | -------------------------------------------------------------------------------- /WebMatBotV3/Client/wwwroot/css/open-iconic/ICON-LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /WebMatBotV3/Client/wwwroot/css/open-iconic/font/css/open-iconic-bootstrap.min.css: -------------------------------------------------------------------------------- 1 | @font-face{font-family:Icons;src:url(../fonts/open-iconic.eot);src:url(../fonts/open-iconic.eot?#iconic-sm) format('embedded-opentype'),url(../fonts/open-iconic.woff) format('woff'),url(../fonts/open-iconic.ttf) format('truetype'),url(../fonts/open-iconic.otf) format('opentype'),url(../fonts/open-iconic.svg#iconic-sm) format('svg');font-weight:400;font-style:normal}.oi{position:relative;top:1px;display:inline-block;speak:none;font-family:Icons;font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.oi:empty:before{width:1em;text-align:center;box-sizing:content-box}.oi.oi-align-center:before{text-align:center}.oi.oi-align-left:before{text-align:left}.oi.oi-align-right:before{text-align:right}.oi.oi-flip-horizontal:before{-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.oi.oi-flip-vertical:before{-webkit-transform:scale(1,-1);-ms-transform:scale(-1,1);transform:scale(1,-1)}.oi.oi-flip-horizontal-vertical:before{-webkit-transform:scale(-1,-1);-ms-transform:scale(-1,1);transform:scale(-1,-1)}.oi-account-login:before{content:'\e000'}.oi-account-logout:before{content:'\e001'}.oi-action-redo:before{content:'\e002'}.oi-action-undo:before{content:'\e003'}.oi-align-center:before{content:'\e004'}.oi-align-left:before{content:'\e005'}.oi-align-right:before{content:'\e006'}.oi-aperture:before{content:'\e007'}.oi-arrow-bottom:before{content:'\e008'}.oi-arrow-circle-bottom:before{content:'\e009'}.oi-arrow-circle-left:before{content:'\e00a'}.oi-arrow-circle-right:before{content:'\e00b'}.oi-arrow-circle-top:before{content:'\e00c'}.oi-arrow-left:before{content:'\e00d'}.oi-arrow-right:before{content:'\e00e'}.oi-arrow-thick-bottom:before{content:'\e00f'}.oi-arrow-thick-left:before{content:'\e010'}.oi-arrow-thick-right:before{content:'\e011'}.oi-arrow-thick-top:before{content:'\e012'}.oi-arrow-top:before{content:'\e013'}.oi-audio-spectrum:before{content:'\e014'}.oi-audio:before{content:'\e015'}.oi-badge:before{content:'\e016'}.oi-ban:before{content:'\e017'}.oi-bar-chart:before{content:'\e018'}.oi-basket:before{content:'\e019'}.oi-battery-empty:before{content:'\e01a'}.oi-battery-full:before{content:'\e01b'}.oi-beaker:before{content:'\e01c'}.oi-bell:before{content:'\e01d'}.oi-bluetooth:before{content:'\e01e'}.oi-bold:before{content:'\e01f'}.oi-bolt:before{content:'\e020'}.oi-book:before{content:'\e021'}.oi-bookmark:before{content:'\e022'}.oi-box:before{content:'\e023'}.oi-briefcase:before{content:'\e024'}.oi-british-pound:before{content:'\e025'}.oi-browser:before{content:'\e026'}.oi-brush:before{content:'\e027'}.oi-bug:before{content:'\e028'}.oi-bullhorn:before{content:'\e029'}.oi-calculator:before{content:'\e02a'}.oi-calendar:before{content:'\e02b'}.oi-camera-slr:before{content:'\e02c'}.oi-caret-bottom:before{content:'\e02d'}.oi-caret-left:before{content:'\e02e'}.oi-caret-right:before{content:'\e02f'}.oi-caret-top:before{content:'\e030'}.oi-cart:before{content:'\e031'}.oi-chat:before{content:'\e032'}.oi-check:before{content:'\e033'}.oi-chevron-bottom:before{content:'\e034'}.oi-chevron-left:before{content:'\e035'}.oi-chevron-right:before{content:'\e036'}.oi-chevron-top:before{content:'\e037'}.oi-circle-check:before{content:'\e038'}.oi-circle-x:before{content:'\e039'}.oi-clipboard:before{content:'\e03a'}.oi-clock:before{content:'\e03b'}.oi-cloud-download:before{content:'\e03c'}.oi-cloud-upload:before{content:'\e03d'}.oi-cloud:before{content:'\e03e'}.oi-cloudy:before{content:'\e03f'}.oi-code:before{content:'\e040'}.oi-cog:before{content:'\e041'}.oi-collapse-down:before{content:'\e042'}.oi-collapse-left:before{content:'\e043'}.oi-collapse-right:before{content:'\e044'}.oi-collapse-up:before{content:'\e045'}.oi-command:before{content:'\e046'}.oi-comment-square:before{content:'\e047'}.oi-compass:before{content:'\e048'}.oi-contrast:before{content:'\e049'}.oi-copywriting:before{content:'\e04a'}.oi-credit-card:before{content:'\e04b'}.oi-crop:before{content:'\e04c'}.oi-dashboard:before{content:'\e04d'}.oi-data-transfer-download:before{content:'\e04e'}.oi-data-transfer-upload:before{content:'\e04f'}.oi-delete:before{content:'\e050'}.oi-dial:before{content:'\e051'}.oi-document:before{content:'\e052'}.oi-dollar:before{content:'\e053'}.oi-double-quote-sans-left:before{content:'\e054'}.oi-double-quote-sans-right:before{content:'\e055'}.oi-double-quote-serif-left:before{content:'\e056'}.oi-double-quote-serif-right:before{content:'\e057'}.oi-droplet:before{content:'\e058'}.oi-eject:before{content:'\e059'}.oi-elevator:before{content:'\e05a'}.oi-ellipses:before{content:'\e05b'}.oi-envelope-closed:before{content:'\e05c'}.oi-envelope-open:before{content:'\e05d'}.oi-euro:before{content:'\e05e'}.oi-excerpt:before{content:'\e05f'}.oi-expand-down:before{content:'\e060'}.oi-expand-left:before{content:'\e061'}.oi-expand-right:before{content:'\e062'}.oi-expand-up:before{content:'\e063'}.oi-external-link:before{content:'\e064'}.oi-eye:before{content:'\e065'}.oi-eyedropper:before{content:'\e066'}.oi-file:before{content:'\e067'}.oi-fire:before{content:'\e068'}.oi-flag:before{content:'\e069'}.oi-flash:before{content:'\e06a'}.oi-folder:before{content:'\e06b'}.oi-fork:before{content:'\e06c'}.oi-fullscreen-enter:before{content:'\e06d'}.oi-fullscreen-exit:before{content:'\e06e'}.oi-globe:before{content:'\e06f'}.oi-graph:before{content:'\e070'}.oi-grid-four-up:before{content:'\e071'}.oi-grid-three-up:before{content:'\e072'}.oi-grid-two-up:before{content:'\e073'}.oi-hard-drive:before{content:'\e074'}.oi-header:before{content:'\e075'}.oi-headphones:before{content:'\e076'}.oi-heart:before{content:'\e077'}.oi-home:before{content:'\e078'}.oi-image:before{content:'\e079'}.oi-inbox:before{content:'\e07a'}.oi-infinity:before{content:'\e07b'}.oi-info:before{content:'\e07c'}.oi-italic:before{content:'\e07d'}.oi-justify-center:before{content:'\e07e'}.oi-justify-left:before{content:'\e07f'}.oi-justify-right:before{content:'\e080'}.oi-key:before{content:'\e081'}.oi-laptop:before{content:'\e082'}.oi-layers:before{content:'\e083'}.oi-lightbulb:before{content:'\e084'}.oi-link-broken:before{content:'\e085'}.oi-link-intact:before{content:'\e086'}.oi-list-rich:before{content:'\e087'}.oi-list:before{content:'\e088'}.oi-location:before{content:'\e089'}.oi-lock-locked:before{content:'\e08a'}.oi-lock-unlocked:before{content:'\e08b'}.oi-loop-circular:before{content:'\e08c'}.oi-loop-square:before{content:'\e08d'}.oi-loop:before{content:'\e08e'}.oi-magnifying-glass:before{content:'\e08f'}.oi-map-marker:before{content:'\e090'}.oi-map:before{content:'\e091'}.oi-media-pause:before{content:'\e092'}.oi-media-play:before{content:'\e093'}.oi-media-record:before{content:'\e094'}.oi-media-skip-backward:before{content:'\e095'}.oi-media-skip-forward:before{content:'\e096'}.oi-media-step-backward:before{content:'\e097'}.oi-media-step-forward:before{content:'\e098'}.oi-media-stop:before{content:'\e099'}.oi-medical-cross:before{content:'\e09a'}.oi-menu:before{content:'\e09b'}.oi-microphone:before{content:'\e09c'}.oi-minus:before{content:'\e09d'}.oi-monitor:before{content:'\e09e'}.oi-moon:before{content:'\e09f'}.oi-move:before{content:'\e0a0'}.oi-musical-note:before{content:'\e0a1'}.oi-paperclip:before{content:'\e0a2'}.oi-pencil:before{content:'\e0a3'}.oi-people:before{content:'\e0a4'}.oi-person:before{content:'\e0a5'}.oi-phone:before{content:'\e0a6'}.oi-pie-chart:before{content:'\e0a7'}.oi-pin:before{content:'\e0a8'}.oi-play-circle:before{content:'\e0a9'}.oi-plus:before{content:'\e0aa'}.oi-power-standby:before{content:'\e0ab'}.oi-print:before{content:'\e0ac'}.oi-project:before{content:'\e0ad'}.oi-pulse:before{content:'\e0ae'}.oi-puzzle-piece:before{content:'\e0af'}.oi-question-mark:before{content:'\e0b0'}.oi-rain:before{content:'\e0b1'}.oi-random:before{content:'\e0b2'}.oi-reload:before{content:'\e0b3'}.oi-resize-both:before{content:'\e0b4'}.oi-resize-height:before{content:'\e0b5'}.oi-resize-width:before{content:'\e0b6'}.oi-rss-alt:before{content:'\e0b7'}.oi-rss:before{content:'\e0b8'}.oi-script:before{content:'\e0b9'}.oi-share-boxed:before{content:'\e0ba'}.oi-share:before{content:'\e0bb'}.oi-shield:before{content:'\e0bc'}.oi-signal:before{content:'\e0bd'}.oi-signpost:before{content:'\e0be'}.oi-sort-ascending:before{content:'\e0bf'}.oi-sort-descending:before{content:'\e0c0'}.oi-spreadsheet:before{content:'\e0c1'}.oi-star:before{content:'\e0c2'}.oi-sun:before{content:'\e0c3'}.oi-tablet:before{content:'\e0c4'}.oi-tag:before{content:'\e0c5'}.oi-tags:before{content:'\e0c6'}.oi-target:before{content:'\e0c7'}.oi-task:before{content:'\e0c8'}.oi-terminal:before{content:'\e0c9'}.oi-text:before{content:'\e0ca'}.oi-thumb-down:before{content:'\e0cb'}.oi-thumb-up:before{content:'\e0cc'}.oi-timer:before{content:'\e0cd'}.oi-transfer:before{content:'\e0ce'}.oi-trash:before{content:'\e0cf'}.oi-underline:before{content:'\e0d0'}.oi-vertical-align-bottom:before{content:'\e0d1'}.oi-vertical-align-center:before{content:'\e0d2'}.oi-vertical-align-top:before{content:'\e0d3'}.oi-video:before{content:'\e0d4'}.oi-volume-high:before{content:'\e0d5'}.oi-volume-low:before{content:'\e0d6'}.oi-volume-off:before{content:'\e0d7'}.oi-warning:before{content:'\e0d8'}.oi-wifi:before{content:'\e0d9'}.oi-wrench:before{content:'\e0da'}.oi-x:before{content:'\e0db'}.oi-yen:before{content:'\e0dc'}.oi-zoom-in:before{content:'\e0dd'}.oi-zoom-out:before{content:'\e0de'} -------------------------------------------------------------------------------- /WebMatBotV3/Client/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBotV3/Client/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /WebMatBotV3/Client/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBotV3/Client/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /WebMatBotV3/Client/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBotV3/Client/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /WebMatBotV3/Client/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBotV3/Client/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /WebMatBotV3/Client/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebMat1/WebMatBotTwitch/3338e7a27ff364ce0b3753f154524658e4337754/WebMatBotV3/Client/wwwroot/favicon.ico -------------------------------------------------------------------------------- /WebMatBotV3/Client/wwwroot/index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | WebMatBotV3 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
Loading...
16 | 17 |
18 | An unhandled error has occurred. 19 | Reload 20 | 🗙 21 |
22 | 23 | 24 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /WebMatBotV3/Server/.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-ef": { 6 | "version": "5.0.1", 7 | "commands": [ 8 | "dotnet-ef" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /WebMatBotV3/Server/Controllers/CommandController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.Extensions.Logging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using WebMatBotV3.Shared; 8 | 9 | namespace WebMatBotV3.Server.Controllers 10 | { 11 | [ApiController] 12 | [Route("[controller]")] 13 | public class CommandController : ControllerBase 14 | { 15 | private readonly DataContext dataContext; 16 | 17 | [HttpGet("{command}")] 18 | public async Task Get(string command) 19 | { 20 | return await WebMatBot.Program.SendCommand(command); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /WebMatBotV3/Server/Hubs/CannonHub.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.SignalR; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using WebMatBotV3.Server.Services; 7 | using WebMatBotV3.Shared; 8 | 9 | namespace WebMatBotV3.Server.Hubs 10 | { 11 | public class CannonHub : Hub 12 | { 13 | private readonly CannonService cService; 14 | private IList connectedIds { get; set; } = new List(); 15 | 16 | public CannonHub(CannonService _cService) 17 | { 18 | cService = _cService; 19 | } 20 | 21 | public async Task Winner(string user, string args) 22 | { 23 | //avisa que o cidadão acertou e recebe os pontos que ele possui 24 | await cService.AddPoint(user, args); 25 | 26 | await cService.BonusInvitations(user); 27 | 28 | await cService.SendRanking(); 29 | } 30 | public async Task CloseStore() => 31 | await WebMatBot.Games.Cannon_Store.CloseMarketCommand(); 32 | 33 | public async Task Init() 34 | { 35 | await WebMatBot.Games.Cannon_Store.OpenMarketCommand(); 36 | await cService.SendRanking(); 37 | await cService.SendJackPot(); 38 | } 39 | 40 | public override Task OnConnectedAsync() 41 | { 42 | Console.WriteLine("Connected " + Context.ConnectionId); 43 | connectedIds.Add(Context.ConnectionId); 44 | 45 | return base.OnConnectedAsync(); 46 | } 47 | 48 | public override Task OnDisconnectedAsync(Exception exception) 49 | { 50 | 51 | Console.WriteLine("Disconnected " + Context.ConnectionId); 52 | connectedIds.Remove(Context.ConnectionId); 53 | 54 | return base.OnDisconnectedAsync(exception); 55 | } 56 | 57 | public bool alala() => true; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /WebMatBotV3/Server/Hubs/SubtitleHub.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.SignalR; 6 | 7 | namespace WebMatBotV3.Server.Hubs 8 | { 9 | public class SubtitleHub : Hub 10 | { 11 | public async Task ToTranslate(string text,string user) 12 | { 13 | 14 | //subtitle está ativo 15 | if (WebMatBot.Subtitle.IsActive) 16 | { 17 | //traduz 18 | var textTranslated = await WebMatBot.Translate.TranslateCore(text, false, WebMatBot.Subtitle.TargetLanguage, user); 19 | 20 | //envia para os clientes 21 | await Clients.All.SendAsync("receiveTranslated", textTranslated); 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /WebMatBotV3/Server/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace WebMatBotV3.Server 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /WebMatBotV3/Server/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:56464", 7 | "sslPort": 44333 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "WebMatBotV3.Server": { 20 | "commandName": "Project", 21 | "dotnetRunMessages": "true", 22 | "launchBrowser": true, 23 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 24 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /WebMatBotV3/Server/Services/ContextCache.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using WebMatBotV3.Shared.Entity; 7 | 8 | namespace WebMatBotV3.Server.Services 9 | { 10 | public class ContextCache : BaseCache 11 | { 12 | private IList LastRanking { get; set; } = new List(); 13 | 14 | public bool IsSameRanking(IList newList) 15 | { 16 | if (newList.Count != LastRanking.Count) 17 | { 18 | //copia a lista pra memoria do singleton 19 | LastRanking = newList.ToList(); 20 | 21 | //retorna resultado; 22 | return false; 23 | } 24 | else 25 | { 26 | bool flagNegative = false; 27 | 28 | for(int i = 0; i < newList.Count && flagNegative == false; i++) 29 | { 30 | if (newList[i].Score.Username != LastRanking[i].Score.Username) 31 | flagNegative = true; 32 | } 33 | 34 | if (flagNegative) 35 | LastRanking = newList.ToList(); 36 | 37 | return !flagNegative; 38 | } 39 | } 40 | } 41 | 42 | public class BaseCache 43 | { 44 | private Seasons Season { get; set; } 45 | 46 | private IList Inventories { get; set; } 47 | 48 | private IList Usernames { get; set; } 49 | 50 | public async Task Init(Shared.DataContext dataContext) 51 | { 52 | var _season = await dataContext.Seasons.Include(e => e.Scores).ThenInclude(e => e.RecordPoints).Include(e => e.Resources).FirstAsync(q => q.EndDate == null && q.Game == "Cannon"); 53 | var _inventories = await dataContext.Inventories.Include(q => q.Ball).ToListAsync(); 54 | var _usernames = await dataContext.Usernames.ToListAsync(); 55 | lock (this) 56 | { 57 | Season = _season; 58 | Inventories = _inventories; 59 | Usernames = _usernames; 60 | } 61 | } 62 | 63 | public Seasons GetSeason() 64 | { 65 | //cloca o objeto da memoria e disponibiliza o necessario 66 | lock (this) 67 | return ((BaseCache)this.MemberwiseClone()).Season; 68 | } 69 | public IList GetInventories() 70 | { 71 | //cloca o objeto da memoria e disponibiliza o necessario 72 | lock (this) 73 | return ((BaseCache)this.MemberwiseClone()).Inventories; 74 | } 75 | public IList GetUsernames() 76 | { 77 | //cloca o objeto da memoria e disponibiliza o necessario 78 | lock (this) 79 | return ((BaseCache)this.MemberwiseClone()).Usernames; 80 | 81 | } 82 | 83 | public void UpdateSeason(Seasons _season) 84 | { 85 | lock (Season) 86 | Season = _season; 87 | } 88 | public void UpdateInventories(IList _inv) 89 | { 90 | lock (Inventories) 91 | Inventories = _inv; 92 | } 93 | public void UpdateUsernames(IList _usernames) 94 | { 95 | lock (Usernames) 96 | Usernames = _usernames; 97 | } 98 | 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /WebMatBotV3/Server/Services/WebMatBotService.cs: -------------------------------------------------------------------------------- 1 | using F23.StringSimilarity; 2 | using Microsoft.AspNetCore.SignalR; 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Microsoft.Extensions.Hosting; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.IO; 9 | using System.Linq; 10 | using System.Net.WebSockets; 11 | using System.Text; 12 | using System.Threading; 13 | using System.Threading.Tasks; 14 | using WebMatBot; 15 | using WebMatBot.Core; 16 | using WebMatBot.Lights; 17 | using WebMatBotV3.Server.Hubs; 18 | using WebMatBotV3.Shared; 19 | using WebMatBotV3.Shared.Entity; 20 | using static WebMatBot.Games.Cannon_Store; 21 | using static WebMatBotV3.Shared.Entity.Balls; 22 | 23 | namespace WebMatBotV3.Server.Services 24 | { 25 | public class WebMatBotService : BackgroundService 26 | { 27 | private readonly IHubContext cannonHub; 28 | private readonly IServiceProvider providerService; 29 | private readonly ContextCache contextCache; 30 | 31 | public WebMatBotService(IHubContext _cannonHub, IServiceProvider _providerService, ContextCache _contextCache) 32 | { 33 | cannonHub = _cannonHub; 34 | providerService = _providerService; 35 | contextCache = _contextCache; 36 | } 37 | 38 | protected override async Task ExecuteAsync(CancellationToken stoppingToken) 39 | { 40 | await InitializeCache(); 41 | await WebMatBot.Program.Start(); 42 | WebMatBot.Games.Cannon.Shot = Shot; 43 | WebMatBot.Games.Cannon.Spray = Spray; 44 | WebMatBot.Games.Cannon.MoveTarget = cannonHub.Clients.All.MoveTarget; 45 | WebMatBot.Games.Cannon.CheckMyBallsFromServer = GetPlayerBalls; 46 | WebMatBot.Games.Cannon.NewGame = InitClient; 47 | WebMatBot.Games.Cannon.SaveRecord = SaveRecord; 48 | WebMatBot.Games.Cannon.CanShot = CanShot; 49 | WebMatBot.Games.Cannon.CanSubRedemption = CanSubRedemption; 50 | WebMatBot.Games.Cannon.AddInvitation = AddInvitation; 51 | WebMatBot.Games.Cannon.Rank = Rank; 52 | WebMatBot.Games.Cannon.GenerateList = GenerateList; 53 | WebMatBot.Games.Cannon.TransferName = TransferName; 54 | WebMatBot.Games.Cannon_Store.OpenMarket = cannonHub.Clients.All.OpenMarket; 55 | WebMatBot.Games.Cannon_Store.BuyBall = BuyBall; 56 | WebMatBot.Games.Cannon_Store.EquipUserBall = EquipUserBall; 57 | WebMatBot.Games.Cannon_Store.GetUserSkins = GetUserSkins; 58 | WebMatBot.Games.Cannon_Store.GetBallsToSale = GetBallsToSale; 59 | WebMatBot.Games.Cannon_Store.CanSubGift = CanSubGift; 60 | WebMatBot.Games.Cannon_Store.SubEnter = SubEnter; 61 | WebMatBot.IrcEngine.UserInteraction = UserInteraction; 62 | 63 | 64 | 65 | //auto update cache by time 66 | while (true) 67 | { 68 | await Task.Delay(new TimeSpan(0, 1, 0)); //atualiza o bd a cada 1 minuto 69 | await InitializeCache(); 70 | } 71 | 72 | 73 | 74 | } 75 | 76 | public static async Task StopAsync() => await WebMatBot.Lights.Light.Stop(); 77 | 78 | public async Task InitClient() 79 | { 80 | //maneira de instanciar um serviço scoped dentro de um singleton 81 | using (var scope = providerService.CreateScope()) 82 | { 83 | using (var cannonService = scope.ServiceProvider.GetRequiredService()) 84 | { 85 | await cannonService.SendRanking(); 86 | await cannonService.SendJackPot(); 87 | } 88 | } 89 | } 90 | 91 | public async Task Shot(float angle, float power, string user, string cmd) 92 | { 93 | TypeBalls ball; 94 | using (var scope = providerService.CreateScope()) 95 | { 96 | using (var cannonService = scope.ServiceProvider.GetRequiredService()) 97 | ball = cannonService.GetUserEquipedBall(user); 98 | } 99 | 100 | await cannonHub.Clients.All.Shot(angle, power, user, ball); 101 | 102 | //save os records 103 | await SaveRecord( 104 | new Records() 105 | { 106 | Action = Records.ActionType.Shot, 107 | Arguments = cmd, 108 | Date = DateTime.Now, 109 | Username = user, 110 | }); 111 | } 112 | public async Task Spray(float angle, float power, string user, string cmd) 113 | { 114 | TypeBalls ball; 115 | int qtdBalls; 116 | using (var scope = providerService.CreateScope()) 117 | { 118 | using (var cannonService = scope.ServiceProvider.GetRequiredService()) 119 | { 120 | ball = cannonService.GetUserEquipedBall(user); 121 | qtdBalls = cannonService.GetPlayerBalls(user); 122 | } 123 | } 124 | 125 | await cannonHub.Clients.All.Spray(angle, power, user, ball, (qtdBalls < 5) ? qtdBalls : 5); 126 | 127 | await SaveRecord( 128 | new Records() 129 | { 130 | Action = Records.ActionType.Spray, 131 | Arguments = cmd, 132 | Date = DateTime.Now, 133 | Username = user, 134 | }); 135 | } 136 | 137 | public int GetPlayerBalls(string user) 138 | { 139 | int Result = 0; 140 | //maneira de instanciar um serviço scoped dentro de um singleton 141 | using (var scope = providerService.CreateScope()) 142 | { 143 | using (var cannonService = scope.ServiceProvider.GetRequiredService()) 144 | Result = cannonService.GetPlayerBalls(user); 145 | } 146 | 147 | return Result; 148 | } 149 | 150 | public async Task SaveRecord(Records record) 151 | { 152 | //maneira de instanciar um serviço scoped dentro de um singleton 153 | using (var scope = providerService.CreateScope()) 154 | { 155 | using (var cannonService = scope.ServiceProvider.GetRequiredService()) 156 | await cannonService.SaveRecord(record); 157 | } 158 | } 159 | 160 | public bool CanShot(string user) 161 | { 162 | //verificar aqui se há clientes conectados no hub do signal R 163 | 164 | bool result = false; 165 | //maneira de instanciar um serviço scoped dentro de um singleton 166 | using (var scope = providerService.CreateScope()) 167 | { 168 | using (var cannonService = scope.ServiceProvider.GetRequiredService()) 169 | result = cannonService.CanShot(user); 170 | } 171 | 172 | return result; 173 | } 174 | public Nullable> Rank(string user) 175 | { 176 | //verificar aqui se há clientes conectados no hub do signal R 177 | 178 | Nullable> result; 179 | 180 | //maneira de instanciar um serviço scoped dentro de um singleton 181 | using (var scope = providerService.CreateScope()) 182 | { 183 | using (var cannonService = scope.ServiceProvider.GetRequiredService()) 184 | result = cannonService.GetUserRank(user); 185 | } 186 | 187 | return result; 188 | } 189 | 190 | public async Task CanSubRedemption(string user) 191 | { 192 | bool result = false; 193 | //maneira de instanciar um serviço scoped dentro de um singleton 194 | using (var scope = providerService.CreateScope()) 195 | { 196 | using (var cannonService = scope.ServiceProvider.GetRequiredService()) 197 | result = await cannonService.CanSubRedemption(user); 198 | } 199 | 200 | return result; 201 | } 202 | 203 | public async Task CanSubGift(string user) 204 | { 205 | bool result = false; 206 | //maneira de instanciar um serviço scoped dentro de um singleton 207 | using (var scope = providerService.CreateScope()) 208 | { 209 | using (var cannonService = scope.ServiceProvider.GetRequiredService()) 210 | result = await cannonService.CanSubGift(user); 211 | } 212 | 213 | return result; 214 | } 215 | 216 | public async Task SubEnter(string user) 217 | { 218 | //maneira de instanciar um serviço scoped dentro de um singleton 219 | using (var scope = providerService.CreateScope()) 220 | { 221 | using (var cannonService = scope.ServiceProvider.GetRequiredService()) 222 | await cannonService.SubEnter(user); 223 | } 224 | } 225 | 226 | public async Task AddInvitation(string host, string invited) 227 | { 228 | string result = null; 229 | //maneira de instanciar um serviço scoped dentro de um singleton 230 | using (var scope = providerService.CreateScope()) 231 | { 232 | using (var cannonService = scope.ServiceProvider.GetRequiredService()) 233 | result = await cannonService.AddInvitation(host, invited); 234 | } 235 | 236 | return result; 237 | } 238 | 239 | public async Task GenerateList() 240 | { 241 | using (var scope = providerService.CreateScope()) 242 | { 243 | using (var cannonService = scope.ServiceProvider.GetRequiredService()) 244 | await cannonService.GenerateList(); 245 | } 246 | } 247 | 248 | public async Task> GetBallsToSale() 249 | { 250 | IEnumerable list = null; 251 | using (var scope = providerService.CreateScope()) 252 | { 253 | using (var cannonService = scope.ServiceProvider.GetRequiredService()) 254 | list = await cannonService.GetBallsToSale(); 255 | } 256 | 257 | return list; 258 | } 259 | 260 | public async Task BuyBall(string user, float bits, List ballsOnSale, TypePayment payment) 261 | { 262 | string result = "Erro..."; 263 | using (var scope = providerService.CreateScope()) 264 | { 265 | using (var cannonService = scope.ServiceProvider.GetRequiredService()) 266 | result = await cannonService.BuyBall(user, bits, ballsOnSale, payment); 267 | } 268 | 269 | return result; 270 | } 271 | 272 | public TypeBalls[] GetUserSkins(string user) 273 | { 274 | TypeBalls[] result = null; 275 | using (var scope = providerService.CreateScope()) 276 | { 277 | using (var cannonService = scope.ServiceProvider.GetRequiredService()) 278 | result = cannonService.GetUserSkins(user); 279 | } 280 | 281 | return result; 282 | } 283 | 284 | public async Task EquipUserBall(string user, TypeBalls type) 285 | { 286 | string result = "Erro..."; 287 | using (var scope = providerService.CreateScope()) 288 | { 289 | using (var cannonService = scope.ServiceProvider.GetRequiredService()) 290 | result = await cannonService.EquipUserBall(user, type); 291 | } 292 | 293 | return result; 294 | } 295 | 296 | public async Task TransferName(string user) 297 | { 298 | using (var scope = providerService.CreateScope()) 299 | { 300 | using (var cannonService = scope.ServiceProvider.GetRequiredService()) 301 | await cannonService.TransferName(user); 302 | } 303 | } 304 | 305 | public async Task UserInteraction(string user, int id) 306 | { 307 | var cachedList = contextCache.GetUsernames(); 308 | var userCached = cachedList.FirstOrDefault(q => q.Username == user && q.User_id == id); 309 | 310 | if (userCached == null) 311 | { 312 | using (var scope = providerService.CreateScope()) 313 | { 314 | using (var dataContext = scope.ServiceProvider.GetRequiredService()) 315 | { 316 | var newUserInteration = new Usernames() 317 | { 318 | User_id = id, 319 | Username = user 320 | }; 321 | 322 | dataContext.Usernames.Add(newUserInteration); 323 | await dataContext.SaveChangesAsync(); 324 | 325 | //atualiza o cache 326 | contextCache.UpdateUsernames(await dataContext.Usernames.ToListAsync()); 327 | 328 | } 329 | } 330 | } 331 | 332 | } 333 | 334 | public async Task InitializeCache() 335 | { 336 | using (var scope = providerService.CreateScope()) 337 | { 338 | using (var dataService = scope.ServiceProvider.GetRequiredService()) 339 | await contextCache.Init(dataService); 340 | } 341 | } 342 | } 343 | } 344 | -------------------------------------------------------------------------------- /WebMatBotV3/Server/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.AspNetCore.HttpsPolicy; 4 | using Microsoft.AspNetCore.ResponseCompression; 5 | using Microsoft.EntityFrameworkCore; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.DependencyInjection; 8 | using Microsoft.Extensions.Hosting; 9 | using System.Linq; 10 | using System.Threading.Tasks; 11 | using WebMatBotV3.Shared; 12 | 13 | namespace WebMatBotV3.Server 14 | { 15 | public class Startup 16 | { 17 | public Startup(IConfiguration configuration) 18 | { 19 | Configuration = configuration; 20 | } 21 | 22 | public IConfiguration Configuration { get; } 23 | 24 | // This method gets called by the runtime. Use this method to add services to the container. 25 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 26 | public void ConfigureServices(IServiceCollection services) 27 | { 28 | // services.AddDbContext(option => { option.UseMySql(Configuration.GetConnectionString("MainDataBase"), mysqlOptions => mysqlOptions.EnableRetryOnFailure());}); 29 | 30 | services.AddControllersWithViews(); 31 | services.AddRazorPages(); 32 | services.AddSignalR(); 33 | // services.AddSingleton(); 34 | // services.AddScoped(); 35 | // services.AddHostedService(); 36 | } 37 | 38 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 39 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime hostApp) 40 | { 41 | if (env.IsDevelopment()) 42 | { 43 | app.UseDeveloperExceptionPage(); 44 | app.UseWebAssemblyDebugging(); 45 | } 46 | else 47 | { 48 | app.UseExceptionHandler("/Error"); 49 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 50 | app.UseHsts(); 51 | } 52 | 53 | //app.UseHttpsRedirection(); 54 | app.UseBlazorFrameworkFiles(); 55 | app.UseStaticFiles(); 56 | 57 | app.UseRouting(); 58 | 59 | app.UseEndpoints(endpoints => 60 | { 61 | endpoints.MapRazorPages(); 62 | endpoints.MapControllers(); 63 | endpoints.MapFallbackToFile("index.html"); 64 | endpoints.MapHub("/HubConnection"); 65 | endpoints.MapHub("/HubCannon"); 66 | }); 67 | 68 | WebMatBot.Program.Start(); 69 | 70 | //hostApp.ApplicationStopping.Register(async () => { 71 | // await Services.WebMatBotService.StopAsync(); 72 | // await Task.Delay(5000); 73 | //}); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /WebMatBotV3/Server/WebMatBotV3.Server.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 93cc1a07-05ec-46e5-8bba-876721db3316 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /WebMatBotV3/Server/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /WebMatBotV3/Server/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*", 10 | "ConnectionStrings": { 11 | "MainDataBase":"" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /WebMatBotV3/Shared/Command.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace WebMatBotV3.Shared 6 | { 7 | public class Command 8 | { 9 | public string Key { get; set; } 10 | public Action Action { get; set; } 11 | public Permissions[] Permissions { get; set; } 12 | public string Description { get; set; } 13 | public Command(string _Key, Action _Action, string _Description,params Permissions[] _permissions ) 14 | { 15 | Key = _Key; 16 | Action = _Action; 17 | Description = _Description; 18 | Permissions = _permissions == null || _permissions.Length == 0 ? new Permissions[1] { Shared.Permissions.Viewer} : _permissions; 19 | } 20 | 21 | } 22 | public enum Permissions 23 | { 24 | Viewer, 25 | Subscriber, 26 | Bits, 27 | Moderator, 28 | VIP, 29 | Broadcaster, 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /WebMatBotV3/Shared/DataContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using WebMatBotV3.Shared.Entity; 7 | 8 | namespace WebMatBotV3.Shared 9 | { 10 | public class DataContext : DbContext 11 | { 12 | public DataContext(DbContextOptions options) : base(options) { } 13 | 14 | public DbSet Scores {get;set;} 15 | public DbSet Points {get;set;} 16 | public DbSet Seasons {get;set;} 17 | public DbSet Records {get;set;} 18 | public DbSet Resources {get;set;} 19 | public DbSet Invitations {get;set;} 20 | public DbSet Balls { get; set; } 21 | public DbSet Inventories { get; set; } 22 | public DbSet SubscribersResources { get; set; } 23 | public DbSet Usernames { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /WebMatBotV3/Shared/Entity/Balls.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Text.Json.Serialization; 8 | using System.Threading.Tasks; 9 | 10 | namespace WebMatBotV3.Shared.Entity 11 | { 12 | [Table("Balls")] 13 | public class Balls 14 | { 15 | [Key] 16 | [JsonIgnore] 17 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 18 | public int BallsID { get; set; } 19 | 20 | [Required] 21 | public TypeBalls Type { get; set; } 22 | 23 | [Required] 24 | public float BitValue { get; set; } 25 | 26 | [Required] 27 | public float DonationValue { get; set; } 28 | 29 | [Required] 30 | public decimal MarketProbability { get; set; } 31 | 32 | [Required] 33 | public int SoldAmount { get; set; } 34 | 35 | [Required] 36 | [JsonIgnore] 37 | public bool IsActive { get; set; } 38 | 39 | [Required] 40 | public TypeLegacy Legacy { get; set; } 41 | 42 | public enum TypeLegacy 43 | { 44 | normal, 45 | rare, 46 | legendary, 47 | mythical 48 | } 49 | 50 | public enum TypeBalls 51 | { 52 | none, 53 | baseball, // 1 54 | basketball, // 2 55 | football, // 3 56 | golf, // 4 57 | pokeball, // 5 58 | soccer, // 6 59 | tennis, // 7 60 | volleyball, // 8 61 | captain, // 9 62 | mercurio, // 10 63 | thanos, // 11 64 | woman, // 12 65 | fireball, // 13 66 | eight, // 14 67 | moon, // 15 68 | 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /WebMatBotV3/Shared/Entity/IRankItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using static WebMatBotV3.Shared.Entity.Balls; 7 | 8 | namespace WebMatBotV3.Shared.Entity 9 | { 10 | public class IRankItem 11 | { 12 | public Scores Score { get; set; } 13 | public TypeBalls TypeBall { get; set; } 14 | 15 | public IRankItem(TypeBalls _t, Scores _s) 16 | { 17 | Score = _s; 18 | TypeBall = _t; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /WebMatBotV3/Shared/Entity/Inventories.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Text.Json.Serialization; 8 | using System.Threading.Tasks; 9 | 10 | namespace WebMatBotV3.Shared.Entity 11 | { 12 | [Table("Inventories")] 13 | public class Inventories 14 | { 15 | [Key] 16 | [JsonIgnore] 17 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 18 | public int InventoriesID { get; set; } 19 | 20 | [Required] 21 | public string Username { get; set; } 22 | 23 | [Required] 24 | public DateTime Date { get; set; } 25 | 26 | [Required] 27 | public bool IsUsing { get; set; } 28 | 29 | 30 | [JsonIgnore] 31 | [Required] 32 | public int BallID { get; set; } 33 | 34 | [JsonIgnore] 35 | [ForeignKey("BallID")] 36 | public Balls Ball { get; set; } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /WebMatBotV3/Shared/Entity/Invitations.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Text.Json.Serialization; 8 | using System.Threading.Tasks; 9 | 10 | namespace WebMatBotV3.Shared.Entity 11 | { 12 | [Table("Invitations")] 13 | public class Invitations 14 | { 15 | [Key] 16 | [JsonIgnore] 17 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 18 | public int InvitationsID { get; set; } 19 | 20 | [Required] 21 | public string Host { get; set; } 22 | 23 | [Required] 24 | public string Invited { get; set; } 25 | 26 | [JsonIgnore] 27 | public int? ScoreID { get; set; } 28 | [JsonIgnore] 29 | [ForeignKey("ScoreID")] 30 | public Scores Score { get; set; } 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /WebMatBotV3/Shared/Entity/Points.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Text.Json.Serialization; 8 | using System.Threading.Tasks; 9 | 10 | namespace WebMatBotV3.Shared.Entity 11 | { 12 | [Table("Points")] 13 | public class Points 14 | { 15 | [Key] 16 | [JsonIgnore] 17 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 18 | public int PointsID { get; set; } 19 | 20 | public DateTime Date { get; set; } 21 | 22 | 23 | [JsonIgnore] 24 | [Required] 25 | public int ScoreID { get; set; } 26 | [JsonIgnore] 27 | [ForeignKey("ScoreID")] 28 | public Scores Score { get; set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /WebMatBotV3/Shared/Entity/Records.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Text.Json.Serialization; 8 | using System.Threading.Tasks; 9 | 10 | namespace WebMatBotV3.Shared.Entity 11 | { 12 | [Table("Records")] 13 | public class Records 14 | { 15 | public enum ActionType 16 | { 17 | Shot, 18 | Buy, 19 | SubRedemption, 20 | Spray, 21 | } 22 | 23 | 24 | [Key] 25 | [JsonIgnore] 26 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 27 | public int RecordsID { get; set; } 28 | 29 | [Required] 30 | public string Username { get; set; } 31 | 32 | [Required] 33 | public ActionType Action { get; set; } 34 | 35 | public string Arguments { get; set; } 36 | 37 | [Required] 38 | public DateTime Date { get; set; } 39 | 40 | [JsonIgnore] 41 | public int? ResourceID { get; set; } 42 | [JsonIgnore] 43 | [ForeignKey("ResourceID")] 44 | public Resources Resource { get; set; } 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /WebMatBotV3/Shared/Entity/Resources.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Text.Json.Serialization; 8 | using System.Threading.Tasks; 9 | 10 | namespace WebMatBotV3.Shared.Entity 11 | { 12 | [Table("Resources")] 13 | public class Resources 14 | { 15 | [JsonIgnore] 16 | [Key] 17 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 18 | public int ResourcesID { get; set; } 19 | 20 | public string Username { get; set; } 21 | 22 | public int Balls { get; set; } 23 | 24 | [JsonIgnore] 25 | [Required] 26 | public int SeasonID { get; set; } 27 | 28 | [JsonIgnore] 29 | [ForeignKey("SeasonID")] 30 | public Seasons Season { get; set; } 31 | 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /WebMatBotV3/Shared/Entity/Scores.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Text.Json.Serialization; 8 | using System.Threading.Tasks; 9 | 10 | namespace WebMatBotV3.Shared.Entity 11 | { 12 | [Table("Scores")] 13 | public class Scores 14 | { 15 | [JsonIgnore] 16 | [Key] 17 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 18 | public int ScoresID { get; set; } 19 | 20 | public string Username { get; set; } 21 | 22 | public int Points { get; set; } 23 | 24 | public int PointIntraDay { 25 | get 26 | { 27 | var count = RecordPoints?.Where(q => q.Date.Date == DateTime.Today).Count(); 28 | return (count == null) ? 0 : count.Value; 29 | } 30 | } 31 | 32 | public int Tries { get; set; } 33 | 34 | [JsonIgnore] 35 | [Required] 36 | public int SeasonID { get; set; } 37 | [JsonIgnore] 38 | [ForeignKey("SeasonID")] 39 | public Seasons Season { get; set; } 40 | 41 | [JsonIgnore] 42 | public ICollection RecordPoints { get; set; } 43 | 44 | [JsonIgnore] 45 | public float HitRate 46 | { 47 | get 48 | { 49 | return ((float)Points / (float)Tries) * 100f; 50 | } 51 | } 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /WebMatBotV3/Shared/Entity/Seasons.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Text.Json.Serialization; 8 | using System.Threading.Tasks; 9 | 10 | namespace WebMatBotV3.Shared.Entity 11 | { 12 | [Table("Seasons")] 13 | public class Seasons 14 | { 15 | [Key] 16 | [JsonIgnore] 17 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 18 | public int SeasonsID { get; set; } 19 | 20 | public string Game { get; set; } 21 | 22 | public DateTime? EndDate { get; set; } 23 | 24 | public string VersionName { get; set; } 25 | 26 | public float JackPot { get; set; } 27 | public ICollection Scores { get; set; } 28 | public ICollection Resources { get; set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /WebMatBotV3/Shared/Entity/SubscribersResources.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Text.Json.Serialization; 8 | using System.Threading.Tasks; 9 | 10 | namespace WebMatBotV3.Shared.Entity 11 | { 12 | [Table("SubscribersResources")] 13 | public class SubscribersResources 14 | { 15 | [Key] 16 | [JsonIgnore] 17 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 18 | public int SubscribersResourcesID { get; set; } 19 | 20 | [Required] 21 | public string Username { get; set; } 22 | 23 | [Required] 24 | public bool SubGiftEnable { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /WebMatBotV3/Shared/Entity/Usernames.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Text.Json.Serialization; 8 | using System.Threading.Tasks; 9 | 10 | namespace WebMatBotV3.Shared.Entity 11 | { 12 | [Table("Usernames")] 13 | public class Usernames 14 | { 15 | [Key] 16 | [JsonIgnore] 17 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 18 | public int UsernamesID { get; set; } 19 | 20 | [Required] 21 | public string Username { get; set; } 22 | 23 | [Required] 24 | public int User_id {get;set;} 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /WebMatBotV3/Shared/Extensions/Extension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WebMatBotV3.Shared 8 | { 9 | public static class Extension 10 | { 11 | private static Random rng = new Random(); 12 | 13 | public static void Shuffle(this IList list) 14 | { 15 | int n = list.Count; 16 | while (n > 1) 17 | { 18 | n--; 19 | int k = rng.Next(n + 1); 20 | T value = list[k]; 21 | list[k] = list[n]; 22 | list[n] = value; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /WebMatBotV3/Shared/ICannonClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WebMatBotV3.Shared.Entity; 7 | using static WebMatBotV3.Shared.Entity.Balls; 8 | 9 | namespace WebMatBotV3.Shared 10 | { 11 | public interface ICannonClient 12 | { 13 | Task Shot(float angle, float power, string user, TypeBalls skin); 14 | Task Spray(float angle, float power, string user, TypeBalls skin, int qtdballs); 15 | Task MoveTarget(int x, int y); 16 | Task Ranking(IEnumerable scores, bool shouldUpdateList); 17 | Task JackPot(float newJackPot); 18 | Task OpenMarket(double time, IEnumerable balls); 19 | Task OnBuy(string user, Balls ball); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /WebMatBotV3/Shared/UserTitle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WebMatBotV3.Shared 8 | { 9 | public class UserTitle 10 | { 11 | 12 | public List Permissions { get; set; } 13 | 14 | 15 | public UserTitle(string badges) { 16 | 17 | //decodificar a string da twitch 18 | 19 | // @badge-info=subscriber/1;badges=subscriber/0,premium/1,moderator/1,bits/1;client-nonce=3c7925c70412b0b55144227f60764baf;color=;display-name=allexx3x;emotes=;flags=;id=61742c2b-5ea1-4d40-9b35-c971b12c8812;mod=0;room-id=45168403;subscriber=1;tmi-sent-ts=1606745430489;turbo=0;user-id=55290495;user-type= :allexx3x!allexx3x@allexx3x.tmi.twitch.tv PRIVMSG #webmat1 :dotnet -version 20 | 21 | #region Pegando string Badges 22 | string[] parameters = badges.Split(";"); 23 | string userBadge = null; 24 | 25 | for (int i = 0; i < parameters.Length && userBadge == null; i++) 26 | userBadge = (parameters[i].StartsWith("badges=") ? parameters[i] : null); 27 | 28 | if (userBadge == null) 29 | throw new Exception("Informações de usuário não carregadas"); 30 | 31 | #endregion 32 | 33 | Permissions = new List() { WebMatBotV3.Shared.Permissions.Viewer}; 34 | 35 | #region Populando instancia 36 | 37 | if (userBadge.Contains("subscriber") || userBadge.Contains("founder")) 38 | Permissions.Add(WebMatBotV3.Shared.Permissions.Subscriber); 39 | 40 | if (userBadge.Contains("moderator")) 41 | Permissions.Add(WebMatBotV3.Shared.Permissions.Moderator); 42 | 43 | 44 | if (userBadge.Contains("bits")) 45 | Permissions.Add(WebMatBotV3.Shared.Permissions.Bits); 46 | 47 | if (userBadge.Contains("vip")) 48 | Permissions.Add(WebMatBotV3.Shared.Permissions.VIP); 49 | 50 | if (userBadge.Contains("broadcaster")) 51 | Permissions.Add(WebMatBotV3.Shared.Permissions.Broadcaster); 52 | #endregion 53 | 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /WebMatBotV3/Shared/WebMatBotV3.Shared.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /WebMatTwitchBot.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30320.27 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebMatBot", "WebMatBot\WebMatBot.csproj", "{939FAEC2-F6BA-4AA7-B487-A4933F17ACCB}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebMatBotV3.Server", "WebMatBotV3\Server\WebMatBotV3.Server.csproj", "{FC1722BA-B96A-4C86-9285-F3730AAEE74C}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebMatBotV3.Client", "WebMatBotV3\Client\WebMatBotV3.Client.csproj", "{B0E1A020-B615-4555-84D5-19CE3EEDC142}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebMatBotV3.Shared", "WebMatBotV3\Shared\WebMatBotV3.Shared.csproj", "{52BF0221-4E9C-4A49-9581-2CB317C85C14}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Release|Any CPU = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {939FAEC2-F6BA-4AA7-B487-A4933F17ACCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {939FAEC2-F6BA-4AA7-B487-A4933F17ACCB}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {939FAEC2-F6BA-4AA7-B487-A4933F17ACCB}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {939FAEC2-F6BA-4AA7-B487-A4933F17ACCB}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {FC1722BA-B96A-4C86-9285-F3730AAEE74C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {FC1722BA-B96A-4C86-9285-F3730AAEE74C}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {FC1722BA-B96A-4C86-9285-F3730AAEE74C}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {FC1722BA-B96A-4C86-9285-F3730AAEE74C}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {B0E1A020-B615-4555-84D5-19CE3EEDC142}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {B0E1A020-B615-4555-84D5-19CE3EEDC142}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {B0E1A020-B615-4555-84D5-19CE3EEDC142}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {B0E1A020-B615-4555-84D5-19CE3EEDC142}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {52BF0221-4E9C-4A49-9581-2CB317C85C14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {52BF0221-4E9C-4A49-9581-2CB317C85C14}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {52BF0221-4E9C-4A49-9581-2CB317C85C14}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {52BF0221-4E9C-4A49-9581-2CB317C85C14}.Release|Any CPU.Build.0 = Release|Any CPU 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | GlobalSection(ExtensibilityGlobals) = postSolution 41 | SolutionGuid = {40D16D0D-F5EA-48B0-B0F4-96BB9CE489DB} 42 | EndGlobalSection 43 | EndGlobal 44 | --------------------------------------------------------------------------------