Пример #1
0
        public void SetNearestNode(SupernodeStructures.Location location)
        {
            var client = new SupernodeClient();

            if (location.numNodes > 25)
            {
                throw new ArgumentException("invalid number of nodes");
            }

            client.BeginGetNearestNodesInfo(ar =>
            {
                for (var i = 0; i < ar.Content.data.Count; i++)
                {
                    if (ar.Content.data[i].status != 1)
                    {
                        continue;
                    }
                    SetHost(ar.Content.data[i].ip);
                    break;
                }
            }, location).AsyncWaitHandle.WaitOne();
        }
Пример #2
0
        internal async Task ScanTests(SuperNode n)
        {
            try
            {
                var testTypes = new List <string>()
                {
                    "node version test",
                    "chain height test",
                    "chain part test",
                    "responsiveness test",
                    "bandwidth test",
                    "computing power test",
                    "ping test",
                    "node balance test"
                };

                var superClient = new SupernodeClient();

                superClient.BeginGetTestResults(ar =>
                {
                    try
                    {
                        if (ar.Content.data[0].round != n.LastTest)
                        {
                            var bitArray = new BitArray(new[] { ar.Content.data[0].testResult });

                            var passed = new bool[32];

                            bitArray.CopyTo(passed, 0);

                            var passedBits = ToBitInts(bitArray);

                            if (passedBits.Contains(0))
                            {
                                var msg = "Node: " + n.Alias +
                                          "\nWith IP: " + n.IP +
                                          " \nfailed tests on " + "\nDate: " +
                                          ar.Content.data[0].dateAndTime.Substring(startIndex: 0, length: 10) +
                                          "\nTime: " + ar.Content.data[0].dateAndTime.Substring(startIndex: 11, length: 8) +
                                          "\n";

                                for (var index = 0; index < 8; index++)
                                {
                                    var pass = passedBits[index];

                                    if (pass == 0)
                                    {
                                        msg += pass == 0 ? testTypes[index] + ": failed\n" : testTypes[index] + ": passed\n";
                                    }
                                }

                                try
                                {
                                    msg       += "https://supernodes.nem.io/details/" + n.SNodeID + "\n";
                                    n.LastTest = ar.Content.data[0].round;
                                    NodeUtils.UpdateNode(snode: n, chatId: n.OwnedByUser);

                                    Console.WriteLine(msg);

                                    Nofity(node: n, msg: msg);
                                }
                                catch (Exception e)
                                {
                                    Console.WriteLine("node scanner line 199: " + e.StackTrace);

                                    if (e.Message.Contains("blocked"))
                                    {
                                        UserUtils.DeleteUser(n.OwnedByUser);
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("node scanner line 214: " + ex.Message);
                    }
                }, new SupernodeStructures.TestResultRequestData
                {
                    alias     = n.Alias,
                    numRounds = 1,
                    roundFrom = -1
                });
            }
            catch (Exception e)
            {
                Console.WriteLine("node scanner line 225" + e.StackTrace);
            }
        }
Пример #3
0
        internal void ManageNodes(Chat chat, string text)
        {
            var Bot = new TelegramBot(accessToken: ConfigurationManager.AppSettings[name: "accessKey"]);

            // if the user is not known, add the user to the database
            if (UserUtils.GetUser(chatId: chat.Id)?.ChatId == null)
            {
                // add user based on their chat ID
                UserUtils.AddUser(userName: chat.Username, chatId: chat.Id);

                // declare message
                var msg1 = "You have been automatically registered, one moment please";

                // send message notifying they have been registered
                var reqAction1 = new SendMessage(chatId: chat.Id, text: msg1);

                // send message
                Bot.MakeRequestAsync(request: reqAction1);
            }

            // set up regex pattern matching sequences.
            var ip  = new Regex(pattern: @"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b");
            var ip2 = new Regex(pattern: @"[a-zA-Z0-9]{1,20}\.[a-zA-Z0-9]{1,20}\.[a-zA-Z0-9]{1,20}");
            var ip3 = new Regex(pattern: @"[a-zA-Z0-9]{1,20}\.[a-zA-Z0-9]{1,20}");

            // scan list of submitted ip's for any valid sequences
            var result = ip.Matches(input: text).Cast <Match>().Select(selector: m => m.Value)
                         .Concat(second: ip2.Matches(input: text).Cast <Match>().Select(selector: m => m.Value))
                         .Concat(second: ip3.Matches(input: text).Cast <Match>().Select(selector: m => m.Value)).ToArray();



            // declare a nodeClient to retrieve node data.
            var snodeClient = new SupernodeClient();

            // get a list of all supernodes
            snodeClient.BeginGetSupernodes(ar =>
            {
                try
                {
                    // check submitted list against the list of all supernodes
                    var validNodes = new SupernodeResponseData.Supernodes()
                    {
                        data = new List <SupernodeResponseData.Nodes>()
                    };

                    foreach (string userIp in result)
                    {
                        foreach (var node in ar.Content.data)
                        {
                            if (userIp != node.ip)
                            {
                                continue;
                            }

                            if (node.payoutAddress == null)
                            {
                                var bot = new TelegramBot(accessToken: ConfigurationManager.AppSettings[name: "accessKey"]);
                                var req = new SendMessage(chatId: chat.Id, text: "One of the nodes you have submitted is invalid, or has not been accepted into the supernode program yet, or it has not recieved its first payment. The invalid node was node registered. Please check your nodes and try again");

                                bot.MakeRequestAsync(request: req);

                                continue;
                            }

                            validNodes.data.Add(item: node);
                        }
                    }

                    // if the user wants to register a node
                    if (text.StartsWith(value: "/registerNode:") && text != "/registerNode:")
                    {
                        // automatically add the deposit account of each registered node as a monitored account
                        // nodes must be cross referenced with total supernode list to acquire the deposit address
                        // as the supernode API doesnt contain this information
                        string msg1;
                        try
                        {
                            AccountUtils.AddAccount(
                                chatId: chat.Id,
                                accounts: ar.Content.data.Where(predicate: x => validNodes.data.Any(predicate: y => y.ip == x.ip)).ToList()
                                .Select(selector: node => node.payoutAddress).ToList());

                            var nodesAdded = NodeUtils.AddNode(chatId: chat.Id, nodes: validNodes);


                            // return a message showing which accounts were registered
                            msg1 = ar.Content.data.Count > 0
                                ? nodesAdded.data.Aggregate(seed: "Nodes registered: \n \n", func: (current, n) => current + n.ip + "\n")
                                : "No nodes were added. It/they may be offline or have an invalid IP. Check your node ip's and try again";

                            // send message
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(value: e);
                            msg1 = "Something went wrong, please try again.";
                        }

                        var reqAction1 = new SendMessage(chatId: chat.Id, text: msg1);

                        Bot.MakeRequestAsync(request: reqAction1);
                    }

                    // if a user wants to unregister an account
                    if (text.StartsWith(value: "/unregisterNode:") && text != "/unregisterNode:")
                    {
                        string msg2;
                        try
                        {
                            // declare message assuming nothing goes wrong
                            msg2 = result.Length > 1 ? "Your nodes were removed" : "Your node was removed";

                            // make sure the user is registered
                            if (UserUtils.GetUser(chatId: chat.Id)?.ChatId != chat.Id)
                            {
                                // if not, tell them
                                var reqAction3 = new SendMessage(chatId: chat.Id, text: "You are not registered");
                                Bot.MakeRequestAsync(request: reqAction3);
                                return;
                            }

                            // get all user nodes
                            var userNodes = NodeUtils.GetNodeByUser(chatId: chat.Id);

                            // delete any nodes submitted
                            NodeUtils.DeleteNode(chatId: chat.Id, nodes: result.ToList());

                            // delete any associated deposit accounts that would have been automatically registered

                            AccountUtils.DeleteAccount(chatId: chat.Id,
                                                       accounts: userNodes.Where(predicate: y => AccountUtils.GetAccountByUser(chatId: chat.Id)
                                                                                 .Any(predicate: x => x.EncodedAddress == y.DepositAddress))
                                                       .Where(predicate: y => result.Any(predicate: x => x == y.IP))
                                                       .Select(selector: acc => acc.DepositAddress).ToList());
                        }
                        catch (Exception)
                        {
                            msg2 = "Something went wrong. Please try again. If the problem persists, please notify kodtycoon";
                        }

                        // send a message to notify user of any changes
                        var reqAction2 = new SendMessage(chatId: chat.Id, text: msg2);
                        Bot.MakeRequestAsync(request: reqAction2);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.StackTrace);
                }
            }, 1);
        }
Пример #4
0
        internal async void RunBot()
        {
            var snodeClient = new SupernodeClient();

            try
            {
                // get access key from congif
                var Bot = new TelegramBot(accessToken: ConfigurationManager.AppSettings[name: "accessKey"]);
                // insert access token

                // get "me"
                var me = Bot.MakeRequestAsync(request: new GetMe()).Result;

                // if me is null, connection failed, maybe incorrect access token
                if (me == null)
                {
                    Console.WriteLine(value: "GetMe() FAILED. Do you forget to add your AccessToken to App.config?");
                    Console.WriteLine(value: "(Press ENTER to quit)");
                    Console.ReadLine();
                    return;
                }

                // print out that connection worked
                Console.WriteLine(format: "{0} (@{1}) connected!", arg0: me.FirstName, arg1: me.Username);

                Console.WriteLine();
                Console.WriteLine(format: "Find @{0} in Telegram and send him a message - it will be displayed here",
                                  arg0: me.Username);
                Console.WriteLine(value: "(Press ENTER to stop listening and quit)");

                // set message update offset
                long offset = 0;

                // run continuously
                while (!stopMe)
                {
                    Update[] updates;

                    try
                    {
                        updates = Bot.MakeRequestAsync(request: new GetUpdates()
                        {
                            Offset = offset
                        }).Result;
                    }
                    catch (Exception)
                    {
                        Bot = new TelegramBot(accessToken: ConfigurationManager.AppSettings[name: "accessKey"]);
                        continue;
                    }

                    // if none, start next iteration of the loop
                    if (updates == null)
                    {
                        continue;
                    }

                    // repeat following for each update
                    foreach (var update in updates)
                    {
                        // declare the first update as checked
                        offset = update.UpdateId + 1;

                        // get the message text
                        var text = update.Message?.Text;

                        // if empty or null, reiterate loop
                        if (string.IsNullOrEmpty(value: text))
                        {
                            continue;
                        }

                        // if message is to register or unregister a node do the following
                        if (text.StartsWith(value: "/registerNode:") && text != "/registerNode:" ||
                            text.StartsWith(value: "/unregisterNode:") && text != "/unregisterNode:")
                        {
                            // send message to let the user know the bot is working
                            var reqAction = new SendMessage(chatId: update.Message.Chat.Id, text: "One moment please..");

                            await Bot.MakeRequestAsync(request : reqAction);

                            var t =
                                Task.Run(
                                    action:
                                    () => new NodeManagement().ManageNodes(chat: update.Message.Chat, text: text));
                            continue;
                        }

                        if (text == "/dailySummary" || text == "/sevenDaySummary" || text == "/thirtyOneDaySummary" ||
                            text.StartsWith(value: "/customSummary:"))
                        {
                            var t =
                                Task.Run(
                                    action: () => SummaryCreator.GetSummary(text: text, chat: update.Message.Chat));

                            continue;
                        }

                        // if a user wants to register an account, not linked to a supernode
                        if (text.StartsWith(value: "/registerAccount:") && text != "/registerAccount:")
                        {
                            var t = Task.Run(action: () => new AccountTask().RegisterAccounts(message: update.Message));
                            continue;
                        }

                        // if a user wants to unregister an account
                        if (text.StartsWith(value: "/unregisterAccount:") && text != "/unregisterAccount:")
                        {
                            var t =
                                Task.Run(
                                    action:
                                    () => new AccountTask().UnregisterAccount(message: update.Message, text: text));
                            continue;
                        }

                        if (text.StartsWith(value: "/optInTxsAcc:") && text != "/optInTxsAcc:")
                        {
                            OptIOAccountUtils.OptInTx(message: update.Message);

                            continue;
                        }
                        if (text.StartsWith(value: "/optOutTxsAcc:") && text != "/optOutTxsAcc:")
                        {
                            OptIOAccountUtils.OptOutTx(message: update.Message);

                            continue;
                        }

                        if (text.StartsWith(value: "/optInHarvestingAcc:") && text != "/optInHarvestingAcc:")
                        {
                            OptIOAccountUtils.OptInHarvesting(message: update.Message);

                            continue;
                        }
                        if (text.StartsWith(value: "/optOutHarvestingAcc:") && text != "/optOutHarvestingAcc:")
                        {
                            OptIOAccountUtils.OptOutHarvesting(message: update.Message);

                            continue;
                        }

                        switch (text)
                        {
                        case "/registerAccount:":
                        {
                            var reqAction = new SendMessage(chatId: update.Message.Chat.Id,
                                                            text:
                                                            "To register an account, use the command \"/registerAccount:\" followed by a comma delimited list of accounts");

                            Bot.MakeRequestAsync(request: reqAction);

                            continue;
                        }

                        case "/unregisterAccount:":
                        {
                            var reqAction = new SendMessage(chatId: update.Message.Chat.Id,
                                                            text:
                                                            "To unregister an account, use the commmand \"/unregisterAccount:\" followed by a comma delimited list of accounts");

                            Bot.MakeRequestAsync(request: reqAction);

                            continue;
                        }

                        case "/registerNode:":
                        {
                            var reqAction = new SendMessage(chatId: update.Message.Chat.Id,
                                                            text:
                                                            "To register a node, use the command \"/registerNode:\" followed by a comma delimited list of IP addresses. Addresses consisting of characters are also supported. eg. bob.nem.ninja");

                            Bot.MakeRequestAsync(request: reqAction);

                            continue;
                        }

                        case "/unregisterNode:":
                        {
                            var reqAction = new SendMessage(chatId: update.Message.Chat.Id,
                                                            text:
                                                            "To unregister a node, use the commmand \"/unregisterNode:\" followed by a comma delimited list of IP addresses");

                            Bot.MakeRequestAsync(request: reqAction);

                            continue;
                        }

                        case "/deleteAccount":
                        {
                            UserUtils.DeleteUser(update.Message.Chat.Id);

                            var reqAction = new SendMessage(chatId: update.Message.Chat.Id,
                                                            text: "You Account has been removed");

                            Bot.MakeRequestAsync(request: reqAction);

                            continue;
                        }

                        case "/start":
                        {
                            UserUtils.AddUser(userName: update.Message.From.Username, chatId: update.Message.Chat.Id);

                            var reqAction = new SendMessage(chatId: update.Message.Chat.Id,
                                                            text: "Hello. \n\n" +
                                                            "Please start by registering a supernode or NEM acccount. \n" +
                                                            "When you register a supernode, the deposit account of the supernode is" +
                                                            " automatically registered under your username and you will start to " +
                                                            "recieve notifications about failed supernode tests, any transactions " +
                                                            "associated with the deposit account as well as any blocks the deposit account of each node harvests\n\n" +
                                                            "If you dont want to get notifications about the supernode depsoit account, simply unregister the " +
                                                            "account by using the \"/unregisterAccount:\" command followed by the account address you wish to unregister." +
                                                            "This does not unregister your supernode, rather, only the deposit account associated with it\n\n" +
                                                            "You can also in opt out of specific notification types for each node or NEM account you have registered. " +
                                                            "Check out the \"/optIO\" command for more details. You are automatically opted in for all notifications when you register a node or nem account.\n\n" +
                                                            "Use the \"/myDetails\" command to see the nodes and accounts you have registered, what notifications they are signed up for and some additional information. \n\n"
                                                            )
                            {
                                ReplyMarkup = KeyBoards.MainMenu
                            };

                            Bot.MakeRequestAsync(request: reqAction);

                            continue;
                        }

                        case "/myDetails":
                        {
                            var req = new SendMessage(chatId: update.Message.Chat.Id, text: "One moment please..");

                            Bot.MakeRequestAsync(request: req);

                            var t =
                                Task.Run(action: () => new MyDetailsTask().ReturnMyDetails(message: update.Message));

                            continue;
                        }

                        case "/summary":
                        {
                            var req = new SendMessage(chatId: update.Message.Chat.Id,
                                                      text: "Use the commands below to generate a summary for your accounts. " +
                                                      "Include a number after custom summary to get a summary of any given" +
                                                      " days up to the current day")
                            {
                                ReplyMarkup = KeyBoards.SummaryMenu
                            };

                            Bot.MakeRequestAsync(request: req);

                            continue;
                        }

                        case "/help":
                        {
                            var req = new SendMessage(chatId: update.Message.Chat.Id,
                                                      text: "https://blog.nem.io/nem-chain-supernode-notifications-telegram-bot/")
                            {
                                ReplyMarkup = KeyBoards.MainMenu
                            };

                            Bot.MakeRequestAsync(request: req);

                            continue;
                        }

                        case "/back":
                        {
                            var req = new SendMessage(chatId: update.Message.Chat.Id, text: "Main menu")
                            {
                                ReplyMarkup = KeyBoards.MainMenu
                            };

                            Bot.MakeRequestAsync(request: req);

                            continue;
                        }

                        case "/optIO":
                        {
                            var req = new SendMessage(chatId: update.Message.Chat.Id,
                                                      text:
                                                      "Use any of the commands below to opt in or out of any particular notification types. " +
                                                      "You can either opt in or out of notification types globally for all accounts registered to you" +
                                                      " or selectively per account.")
                            {
                                ReplyMarkup = KeyBoards.OptMenu
                            };

                            Bot.MakeRequestAsync(request: req);

                            continue;
                        }

                        case "/optInTxsAcc:":
                        {
                            var req = new SendMessage(chatId: update.Message.Chat.Id,
                                                      text:
                                                      "To opt into transaction notifications for a given account or accounts, use the \"/optInTxsAcc:\" command, " +
                                                      "followed by a list of comma delimeted addresses ");

                            Bot.MakeRequestAsync(request: req);

                            continue;
                        }

                        case "/optOutTxsAcc:":
                        {
                            var req = new SendMessage(chatId: update.Message.Chat.Id,
                                                      text: "To opt out of transaction notifications for a given account or accounts, " +
                                                      "use the \"/optOutTxsAcc:\" command, followed by a list of comma delimeted addresses ");

                            Bot.MakeRequestAsync(request: req);

                            continue;
                        }

                        case "/optInHarvestingAcc:":
                        {
                            var req = new SendMessage(chatId: update.Message.Chat.Id,
                                                      text: "To opt into harvesting notifications for a given account or accounts, " +
                                                      "use the \"/optInHarvestingAcc:\" command, followed by a list of comma delimeted addresses ");

                            Bot.MakeRequestAsync(request: req);

                            continue;
                        }

                        case "/optOutHarvestingAcc:":
                        {
                            var req = new SendMessage(chatId: update.Message.Chat.Id,
                                                      text: "To opt out of harvesting notifications for a given account or accounts, " +
                                                      "use the \"/optOutHarvestingAcc:\" command, followed by a list of comma delimeted addresses ");

                            Bot.MakeRequestAsync(request: req);

                            continue;
                        }

                        case "/optInTxsGlobal":
                        {
                            var accs = AccountUtils.GetAccountByUser(chatId: update.Message.Chat.Id);

                            foreach (var acc in accs)
                            {
                                acc.CheckTxs = true;
                            }

                            AccountUtils.UpdateAccount(accs: accs, user: update.Message.Chat.Id);

                            var req = new SendMessage(chatId: update.Message.Chat.Id,
                                                      text: "You have opted into transaction notifications");

                            Bot.MakeRequestAsync(request: req);

                            continue;
                        }

                        case "/optOutTxsGlobal":
                        {
                            var accs = AccountUtils.GetAccountByUser(chatId: update.Message.Chat.Id);

                            foreach (var acc in accs)
                            {
                                acc.CheckTxs = false;
                            }

                            AccountUtils.UpdateAccount(accs: accs, user: update.Message.Chat.Id);

                            var req = new SendMessage(chatId: update.Message.Chat.Id,
                                                      text: "You have opted out of transaction notifications");

                            Bot.MakeRequestAsync(request: req);

                            continue;
                        }

                        case "/optInHarvestingGlobal":
                        {
                            var accs = AccountUtils.GetAccountByUser(chatId: update.Message.Chat.Id);

                            foreach (var acc in accs)
                            {
                                acc.CheckBlocks = true;
                            }

                            AccountUtils.UpdateAccount(accs: accs, user: update.Message.Chat.Id);

                            var req = new SendMessage(chatId: update.Message.Chat.Id,
                                                      text: "You have opted into harvesting notifications");

                            Bot.MakeRequestAsync(request: req);

                            continue;
                        }

                        case "/optOutHarvestingGlobal":
                        {
                            var accs = AccountUtils.GetAccountByUser(chatId: update.Message.Chat.Id);

                            foreach (var acc in accs)
                            {
                                acc.CheckBlocks = false;
                            }

                            AccountUtils.UpdateAccount(accs: accs, user: update.Message.Chat.Id);

                            var req = new SendMessage(chatId: update.Message.Chat.Id,
                                                      text: "You have opted out of harvesting notifications");

                            Bot.MakeRequestAsync(request: req);

                            continue;
                        }

                        case "/harvestingSpace":
                        {
                            var reqAction = new SendMessage(chatId: update.Message.Chat.Id,
                                                            text: "One moment please..");

                            Bot.MakeRequestAsync(request: reqAction);

                            var freeNodes = new List <string>();

                            var nodeClient = new NodeClient();

                            snodeClient.BeginGetSupernodes(ar =>
                                {
                                    var r = new Random();

                                    for (var index = r.Next(minValue: 0, maxValue: 320); index < 400; index++)
                                    {
                                        var node = ar.Content.data[index: index];

                                        nodeClient.Connection.SetHost(host: node.ip);

                                        nodeClient.BeginGetUnlockedInfo(ar2 =>
                                        {
                                            if (ar2.Content.NumUnlocked < ar2.Content.MaxUnlocked)
                                            {
                                                freeNodes.Add(item: node.ip);
                                            }
                                        }).AsyncWaitHandle.WaitOne();

                                        if (freeNodes.Count == 3)
                                        {
                                            break;
                                        }
                                    }

                                    var message = string.Join(separator: "\n", values: freeNodes);

                                    var req = new SendMessage(chatId: update.Message.Chat.Id, text: message);

                                    Bot.MakeRequestAsync(request: req);
                                }, 1);

                            continue;
                        }

                        default:
                        {
                            var req = new SendMessage(chatId: update.Message.Chat.Id, text: "Main menu")
                            {
                                ReplyMarkup = KeyBoards.MainMenu
                            };

                            Bot.MakeRequestAsync(request: req);

                            continue;
                        }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("tele scanner line 478 " + e.StackTrace);
            }
        }