/// <summary> /// Connects to Discord and sets up the heartbeat manager and payload manager. /// </summary> public static void Connect() { if (VerboseMode) { NepLogger.Log("Using Discord gateway " + (ConnectionManager.GetGateway()).url, "Setup"); } m = new SocketManager(); s = m.CreateSocket(); HeartbeatTimer.Elapsed += SendHeartbeat; s.OnMessage += HandleSocketMessage; s.OnClose += OnSocketClose; NepLogger.Log("Attempting to connect.", "Setup"); s.Connect(); RemPayload p = new RemPayload(); RIPPContent prop = new RIPPContent(); RIPContent n = new RIPContent(); prop.OS = "win"; n.properties = JObject.FromObject(prop); n.token = tokenx.GetToken(); p.d = JObject.FromObject(n); p.op = 2; s.SendPayload(p, false); if (VerboseMode) { NepLogger.Log("Sending " + OpCodeDetails[OpCodes.Identify] + " to Discord and triggering handshake.", "Setup"); } NepLogger.Log("Connected.", "Setup"); Console.ReadLine(); }
/// <summary> /// Sends the payload. /// </summary> /// <param name="Socket">Socket to send through.</param> /// <param name="payload">Payload to send.</param> public static void SendPayload(this WebSocket Socket, RemPayload payload, bool Log = true) { payload.s = Program.hb_seq; string Data = JsonConvert.SerializeObject(payload); if (payload.op != (int)OpCodes.Heartbeat && Log && Program.VerboseMode) { NepLogger.Log("Sending " + Data + " over the WebSocket."); } Socket.Send(Data); }
/// <summary> /// The entry point of the program, where the program control starts and ends. /// </summary> /// <param name="args">The command-line arguments.</param> public static void Main(string[] args) { try { if (VerboseModeArguments.Contains(args[0])) { VerboseMode = true; NepLogger.Log("Running Remcord 1.3 in verbose mode."); } } catch (IndexOutOfRangeException) { NepLogger.Log("Running Remcord 1.3 with no arguments."); } Connect(); }
/// <summary> /// Sends a heartbeat through the default WebSocket. /// </summary> /// <param name="sender">Sender.</param> /// <param name="e">Event args given by the heartbeat timer (as Discord requires a heartbeat sent every x milliseconds)</param> static void SendHeartbeat(object sender, ElapsedEventArgs e) { RemPayload hbP = new RemPayload(); hbP.op = (int)OpCodes.Heartbeat; hbP.d = hb_seq; s.SendPayload(hbP); StringBuilder b = new StringBuilder(); b.Append("Sending Heartbeat."); if (SentFirstHeartbeat) { b.Append(" " + DateTime.Now.Subtract(LastHeartbeatTime).Seconds + " seconds since the last heartbeat."); } NepLogger.Log(b.ToString(), "Heartbeat"); LastHeartbeatTime = DateTime.Now; SentFirstHeartbeat = true; }
/// <summary> /// Handles an incoming socket message from Discord. /// </summary> /// <param name="sender">Sender.</param> /// <param name="e">The arguments of the socket message.</param> public static void HandleSocketMessage(object sender, MessageEventArgs e) { if (e.IsText) { resp = JsonConvert.DeserializeObject <RemPayload>(e.Data); var respd = JsonConvert.DeserializeObject <Dictionary <string, object> >(JsonConvert.SerializeObject(resp.d)); hb_seq = resp.s; if (resp.op == (int)OpCodes.Hello && HaveRecievedHello == false) { int.TryParse((respd.First(x => x.Key == "heartbeat_interval").Value).ToString(), out result); HeartbeatTimer.Interval = result; HeartbeatTimer.Enabled = true; HaveRecievedHello = true; if (VerboseMode) { NepLogger.Log("Recieved Hello payload. Heartbeat interval: " + result, "Setup"); } } if (resp.op == (int)OpCodes.HeartbeatACK && VerboseMode) { NepLogger.Log("Recieved Heartbeat acknowledgement.", "Heartbeat"); } if (!(resp.op == (int)OpCodes.Dispatch) && !(resp.op == (int)OpCodes.HeartbeatACK) && !(resp.op == (int)OpCodes.Hello) && VerboseMode) { NepLogger.Log($"Recieved message from Discord with OP Code {resp.op} ({OpCodeDetails[(OpCodes)resp.op]}), and data {resp.d}"); } if (resp.op == (int)OpCodes.Dispatch && resp.t == "MESSAGE_CREATE") { //messagecreate var message = JsonConvert.DeserializeObject <DiscordUserMessage>(JsonConvert.SerializeObject(resp.d)); if (message.Content == ".remcord") { StringBuilder sb = new StringBuilder(); sb.AppendLine("**== Remcord - a Discord API for .NET ==**"); sb.AppendLine("Remcord is an upcoming alpha API and bot platform for .NET."); sb.AppendLine("Current version: 0.12 *Drunk Elephant*"); sb.AppendLine("Build info: " + GetBuildInfo()); sb.AppendLine("Current gateway version: **Gateway v5**"); sb.AppendLine("Using WSS or WSX? **WSS**"); sb.AppendLine("Using:"); sb.AppendLine("**WebSocketSharp** as the WebSocket library. [Regrets!]"); sb.AppendLine("**RestSharp** for REST communication with Discord. [More regrets]"); MessageInterface.SendMessage(sb.ToString(), message.ChannelID); } if (message.Content == ".socket") { StringBuilder sb = new StringBuilder(); sb.AppendLine("**Remcord Socket Information**"); sb.AppendLine("Currently using **WebSocketSharp** as our WebSocket library."); sb.AppendLine("Connected to Discord gateway " + ConnectionManager.GetGateway().url); sb.AppendLine("Internal gateway " + ConnectionManager.GetGateway()); sb.AppendLine("Remcord version: 0.12"); var time = DateTime.Now.Subtract(LastHeartbeatTime).Seconds; if (SentFirstHeartbeat) { sb.AppendLine($"The last heartbeat was sent " + time + $" {(time == 1 ? "second" : "seconds")} ago."); } MessageInterface.SendMessage(sb.ToString(), message.ChannelID); } if (message.Content.Contains(".rr ") || message.Content.Contains(".russianroulette ")) { Random gen = new Random(); var args = message.Content.Split(' ')[1]; int ndx; if (int.TryParse(args, out ndx)) { MessageInterface.SendMessage(gen.Next(1, ndx) == 1 ? ":skull_crossbones: You have died!" : ":sunny: You are alive.", message.ChannelID); } else { MessageInterface.SendMessage("invalid argument", message.ChannelID); } } if (message.Content == ".rr" || message.Content == ".russianroulette") { Random gen = new Random(); int nx = gen.Next(1, 6); MessageInterface.SendMessage((nx == 1 ? ":skull_crossbones: You have died!" : ":sunny: You are alive."), message.ChannelID); } } else if (resp.op == (int)OpCodes.Dispatch && VerboseMode) { NepLogger.Log((resp.t).ToTitleCase().Replace('_', ' '), "Incoming Event"); } } else { NepLogger.Log(e.RawData + e.Data, "Unknown Event Data"); } }
/// <summary> /// Called when the Discord socket is closed. /// </summary> /// <param name="sender">Sender.</param> /// <param name="args">Event arguments.</param> public static void OnSocketClose(object sender, CloseEventArgs args) { NepLogger.Log("CRITICAL - Discord socket closed."); NepLogger.Log("Reason: " + args.Reason); NepLogger.Log("Code: " + args.Code); }