You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

343 lines
15 KiB
C#

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Discord;
using Discord.WebSocket;
using Newtonsoft.Json.Linq;
using SysBot.Base;
namespace DiscordPlaySwitch
{
class Program
{
private DiscordSocketClient _client;
private SwitchConnectionAsync _connection;
private static readonly JObject Config = JObject.Parse(File.ReadAllText("config.json"));
private readonly JObject _nSwitch = JObject.Parse(Config.GetValue("nSwitch").ToString());
private readonly string[] _control =
{
"DLEFT", "DRIGHT", "DUP", "DDOWN", "A", "B", "X", "Y", "+", "-", "ZL", "ZR", "L", "R", "LSP", "RSP", "LSU",
"LSUR", "LSUL", "LSDR", "LSDL", "LSD", "LSL", "LSR", "RSU", "RSD", "RSL", "RSR", "SCREENSHOT"
};
private readonly string _prefix = ((string) Config.GetValue("prefix")).ToUpper();
public static void Main(string[] args)
=> new Program().MainAsync().GetAwaiter().GetResult();
private async Task MainAsync()
{
_client = new DiscordSocketClient();
_client.Log += Log;
await _client.LoginAsync(TokenType.Bot, (string) Config.GetValue("token"));
await _client.StartAsync();
_client.Ready += () =>
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("==================================================================================");
Console.WriteLine($"Connected to discord as {_client.CurrentUser.Username}#{_client.CurrentUser.DiscriminatorValue} ({_client.CurrentUser.Id})");
Console.WriteLine($"Discord bot prefix is set as: {_prefix}");
Console.WriteLine("Attempting to connect to the Nintendo switch");
try
{
_connection = new SwitchConnectionAsync((string) _nSwitch.GetValue("IP"),
int.Parse((string) _nSwitch.GetValue("sysbotPORT")));
_connection.Connect();
}
catch (Exception e)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(e);
Console.ResetColor();
}
if (_connection.Connected)
{
Console.WriteLine($"Connected to nintendo switch on {_connection.IP}:{_connection.Port}!");
Console.WriteLine($"Say \"{_prefix}exit\" in discord to quit the application!");
}
else
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Failed to connect to the console!");
Console.WriteLine("Press any key to exit the app.");
Console.ResetColor();
Console.ReadKey();
Environment.Exit(1);
}
Console.WriteLine("==================================================================================");
Console.ResetColor();
return Task.CompletedTask;
};
_client.MessageReceived += async message =>
{
if (message.Author.IsBot) return;
if (message.Author.Id == 595703186816499772) return;
if (_connection.Connected)
if (message.Content.Length > _prefix.Length)
await HandleInput(message);
};
await Task.Delay(-1);
}
private async Task HandleInput(SocketMessage message)
{
string msg = message.Content;
string args = msg.ToUpper().Substring(_prefix.Length, msg.Length - _prefix.Length);
string[] words = args.Split(' ');
if (msg.ToUpper().StartsWith(_prefix))
{
switch (args)
{
case "HELP":
await message.Channel.SendMessageAsync(
$"You can input one of those command and they will execute on my nintendo switch ( please don't destroy it ):\n{string.Join(" ", _control)}");
break;
case "EXIT GAME":
{
break;
if (message.Author.Id == 267065637183029248)
{
CancellationTokenSource cancellationToken = new CancellationTokenSource();
await _connection.SendAsync(SwitchCommand.Click(SwitchButton.HOME),
cancellationToken.Token);
cancellationToken.Cancel();
Thread.Sleep(500);
cancellationToken = new CancellationTokenSource();
await _connection.SendAsync(SwitchCommand.Click(SwitchButton.X),
cancellationToken.Token);
cancellationToken.Cancel();
Thread.Sleep(500);
cancellationToken = new CancellationTokenSource();
await _connection.SendAsync(SwitchCommand.Click(SwitchButton.A),
cancellationToken.Token);
cancellationToken.Cancel();
Console.WriteLine("Game exited");
await message.Channel.SendMessageAsync("Game exited");
}
else
{
await message.Channel.SendMessageAsync("Only for supositware");
}
break;
}
case "EXIT":
{
break;
if (message.Author.Id == 267065637183029248)
{
_connection.Disconnect();
Console.WriteLine("Bye bye!");
await message.Channel.SendMessageAsync("Bye bye!");
Environment.Exit(1);
}
else
{
await message.Channel.SendMessageAsync("Only for supositware");
}
break;
}
case "SCREENSHOT":
SendScreenshot(message);
break;
}
if (_control.Any(args.Contains))
{
short speed = short.MaxValue;
if (args.Contains("SLOWER"))
{
speed = 8000;
//i++;
}
else if (args.Contains("SLOW"))
{
speed = 10000;
//i++;
}
else if (args.Contains("MEDIUM"))
{
speed = 16382;
//i++;
}
foreach (var word in words)
{
if (Array.Exists(_control, e => e == word))
{
switch (word)
{
case "DLEFT":
PressButton(SwitchButton.DLEFT);
break;
case "DRIGHT":
PressButton(SwitchButton.DRIGHT);
break;
case "DUP":
PressButton(SwitchButton.DUP);
break;
case "DDOWN":
PressButton(SwitchButton.DDOWN);
break;
case "A":
PressButton(SwitchButton.A);
break;
case "B":
PressButton(SwitchButton.B);
break;
case "X":
PressButton(SwitchButton.X);
break;
case "Y":
PressButton(SwitchButton.Y);
break;
case "+":
PressButton(SwitchButton.PLUS);
break;
case "-":
PressButton(SwitchButton.MINUS);
break;
case "ZL":
PressButton(SwitchButton.ZL);
break;
case "ZR":
PressButton(SwitchButton.ZR);
break;
case "L":
PressButton(SwitchButton.L);
break;
case "R":
PressButton(SwitchButton.R);
break;
case "LSP":
PressButton(SwitchButton.LSTICK);
break;
case "RSP":
PressButton(SwitchButton.RSTICK);
break;
case "LSU":
MoveStick(SwitchStick.LEFT, 0, speed);
break;
case "LSUL":
MoveStick(SwitchStick.LEFT, short.Parse((speed * -1).ToString()), speed);
break;
case "LSUR":
MoveStick(SwitchStick.LEFT, speed, speed);
break;
case "LSD":
MoveStick(SwitchStick.LEFT, 0, short.Parse((speed * -1).ToString()));
break;
case "LSDL":
MoveStick(SwitchStick.LEFT, speed, short.Parse((speed * -1).ToString()));
break;
case "LSDR":
MoveStick(SwitchStick.LEFT, short.Parse((speed * -1).ToString()), short.Parse((speed * -1).ToString()));
break;
case "LSL":
MoveStick(SwitchStick.LEFT, short.Parse((speed * -1).ToString()), 0);
break;
case "LSR":
MoveStick(SwitchStick.LEFT, speed, 0);
break;
case "RSU":
MoveStick(SwitchStick.RIGHT, 0, speed);
break;
case "RSD":
MoveStick(SwitchStick.RIGHT, 0, short.Parse((speed * -1).ToString()));
break;
case "RSL":
MoveStick(SwitchStick.RIGHT, short.Parse((speed * -1).ToString()), 0);
break;
case "RSR":
MoveStick(SwitchStick.RIGHT, speed, 0);
break;
}
SendScreenshot(message);
}
}
}
}
}
private Task Log(LogMessage msg)
{
Console.WriteLine(msg.ToString());
return Task.CompletedTask;
}
private async void PressButton(SwitchButton button)
{
CancellationTokenSource cancellationToken = new CancellationTokenSource();
if (button == SwitchButton.ZL || button == SwitchButton.ZR)
{
await _connection.SendAsync(SwitchCommand.Hold(button), cancellationToken.Token);
Thread.Sleep(2000);
//SendScreenshot(message);
await _connection.SendAsync(SwitchCommand.Release(button), cancellationToken.Token);
}
else
{
await _connection.SendAsync(SwitchCommand.Click(button), cancellationToken.Token);
//SendScreenshot(message);
}
cancellationToken.Cancel();
}
private async void MoveStick(SwitchStick stick, short x, short y)
{
CancellationTokenSource cancellationToken = new CancellationTokenSource();
await _connection.SendAsync(SwitchCommand.SetStick(stick, x, y), cancellationToken.Token);
Thread.Sleep(stick == SwitchStick.RIGHT ? 500 : 1000);
await _connection.SendAsync(SwitchCommand.ResetStick(stick), cancellationToken.Token);
//SendScreenshot(message);
cancellationToken.Cancel();
}
private void SendScreenshot(SocketMessage message)
{
using (Process pProcess = new Process())
{
pProcess.StartInfo.FileName = "ffmpeg";
pProcess.StartInfo.Arguments =
$"-hide_banner -loglevel panic -y -i rtsp://{(string) _nSwitch.GetValue("IP")}:{(string) _nSwitch.GetValue("sysDVRPORT")} -vframes 1 NintendoSwitch.jpg"; //argument
//pProcess.StartInfo.Arguments = $"-hide_banner -loglevel panic -y -i rtsp://127.0.0.1:6666 -vframes 1 NintendoSwitch.jpg"; //argument
pProcess.StartInfo.UseShellExecute = false;
pProcess.StartInfo.RedirectStandardOutput = true;
pProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
pProcess.StartInfo.CreateNoWindow = true; //not diplay a windows
pProcess.Start();
pProcess.WaitForExit();
}
message.Channel.SendFileAsync("NintendoSwitch.jpg");
}
}
}