Смотрите видео ниже, чтобы узнать, как установить наш сайт в качестве веб-приложения на домашнем экране.
Примечание: Эта возможность может быть недоступна в некоторых браузерах.
Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нём некорректно. Вам необходимо обновить браузер или попробовать использовать другой.
Может кто-нибудь подкинуть готовый код вывода трафика дискорда не в лог, а в переменную. К сожалению, своих скиллов не хвататет адаптировать приведенный код.
Может кто-нибудь подкинуть готовый код вывода трафика дискорда не в лог, а в переменную. К сожалению, своих скиллов не хвататет адаптировать приведенный код.
Взял шаб из топика. Чуть подправил, сделал по образу и подобию. Нужно отправить по адресу wss://ws.dream-singles.com/ws
вот эти данные: {"type":"auth","connection":"invite","subscribe_to":["auth-response","chat-invites-response","user-matches-response","presence-change","system-message"],"payload":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ3d3cuZHJlYW0tc2luZ2xlcy5jb20iLCJhdWQiOiJkbV9jaGF0IiwiaWF0IjoxNjExNjU5ODYwLCJleHAiOjE2MTI3NzE4NjAsInN1YiI6IjU1NTE3ODgiLCJnZW5kZXIiOiJtIn0.WNcSP7VFacYdj1D9qnGCsovjaw1oJA7-FMhKVLXtuJg"}
В результате должно получиться следующее:
Исправленный код:
C#:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using System.Text.RegularExpressions;
using ZennoLab.CommandCenter;
using ZennoLab.InterfacesLibrary;
using ZennoLab.InterfacesLibrary.ProjectModel;
using ZennoLab.InterfacesLibrary.ProjectModel.Collections;
using ZennoLab.InterfacesLibrary.ProjectModel.Enums;
using ZennoLab.Macros;
using Global.ZennoExtensions;
using ZennoLab.Emulation;
using WebSocketSharp;
using WebSocketSharp.Server;
using WebSocketSharp.Net;
using System.Threading.Tasks;
namespace ZennoLab.OwnCode
{
public class CommonCode
{
public static void Wss(IZennoPosterProjectModel project) //определяем метод Wss
{
string data = project.Variables["wss_data"].Value; //загружаем тело запроса из переменной
//подключаем прокси, если необходимо
//string ip = project.Variables["proxy_ip"].Value;
//string login = project.Variables["proxy_login"].Value;
//string pass = project.Variables["proxy_pass"].Value;
using (var ws = new WebSocket("wss://ws.dream-singles.com/ws")) //определяем ссылку запроса
{
try
{
//ws.SetProxy (ip, login, pass); //устанавливаем прокси, если необходимо
//ws.SetCookie (new Cookie("__cfduid", project.Variables["cookies_value"].Value)); //устанавливаем куки, если необходимо
ws.Origin = "https://www.dream-singles.com";
ws.OnMessage += (sender, e) => //объявляем, что будем получать сообщение
project.SendInfoToLog(e.Data); //пишем инфу в лог для наглядности
ws.Connect(); //подключаемся по wss
System.Threading.Thread.Sleep(1000); //небольшая пауза
ws.Send (data); //отправляем тело запроса
while (Convert.ToBoolean(project.Variables["wss_lock"].Value)) //пока переменная = true, цикл будет выполняться
{
Thread.Sleep(2000);
};
project.SendInfoToLog("Закрытие соединения", true);
ws.Close();
}
catch (Exception ex)
{ project.SendInfoToLog(ex.Message, true); }
}
}
public static async Task WssAsync(IZennoPosterProjectModel project) //определяем асинхронный метод
{
await Task.Run(() => Wss(project)); //запуск метода Wss
}
}
}
Никакого положительного ответа от сервера нет (( Как бы мне развязать ему язык? ))
Может быть нужно еще какие-то данные прописать для настройки соединения? Ниже скрин снифинга:
а что за лаги то? За соединениями через библиотеку надо тщательно следить, особенно при некорректных завершениях работы шаблона - соединение так и останется открытым и будет работать асинхронно дальше! В логике работы в таких случаях надо не забыть закрыть соединение! Может таких незакрытых соединений накапливается куча и начинает что-то лагать?
Добрый день. А как поступить если после авторизации нужно отправлять запросы до/после определенного события. Например в срм при открытии карточки заказа происходит обмен сообщениями в сокете, и при сохранении также. Понял что это можно отслеживая значения переменных, но как это реализовать общем коде?
Добрый день. А как поступить если после авторизации нужно отправлять запросы до/после определенного события. Например в срм при открытии карточки заказа происходит обмен сообщениями в сокете, и при сохранении также. Понял что это можно отслеживая значения переменных, но как это реализовать общем коде?
Я так вдохновился вашими положительными отзывами на предыдущую статью, что решил поделиться ещё одной.
Предисловие.
В ноябре прошлого года у меня была одна удалённая работёнка, в которой мне потребовался ZennoPoster. Задача состояла в продвижении криптопроекта на ресурсах, где может находиться целевая аудитория. Одним из таких ресурсов был Discord, автоматизацию которого я стал реализовывать на стандартных кубиках. По сути с этого момента и началось моё изучение ZP.
Прошло несколько месяцев и от работы не осталось и следа, зато остался ZennoPoster с уже написанным Discord. Нужен был новый источник дохода, и после нескольких профитных тестов я решил реализовать регистратор и рассыльщик на запросах, дабы запустить больше потоков на паре моих ПК оставшихся после майнинга. Спустя некоторое время задача была реализована и трафик полился, а с ним и профит, но затем Discord стал запрашивать авторизацию, тут и началось моё изучение Websocket.
WS в основном используется на ресурсах, где необходим активный обмен данными. Это могут быть мессенджеры, онлайн-игры, форексы и различные приложения, где важно обмениваться большим объёмом данных в режиме реального времени.
Клиент (браузер или приложение) с помощью WS подключается к серверу только один раз и внутри этого подключения обменивается данными.
За счет этого уменьшается объём передаваемого трафика, и тем самым WS имеет огромное преимущество перед обычными POST/GET запросами, где нужно постоянно устанавливать новые подключения и передавать заголовки.
По сути WS похож на обычный POST запрос, но чтобы его выполнить на ZP нам понадобится библиотека. В моём случае это была websocket-sharp.
О том как ей пользоваться я и опишу в этой статье.
Sniffаем.
Проанализировать трафик WS можно разными способами, но самый простой и доступный это использование браузера на базе Chromium. В моём случае это SWIron.
Разберёмся что здесь к чему.
В колонке Name при наведении отобразится ссылка для запроса, её можно скопировать к себе нажав на пр. кн. мыши и соответствующее меню: wss://gateway.discord.gg/?encoding=json&v=6&compress=zlib-stream
В колонке Data можно увидеть исходящие и поступающие запросы. Копируем себе первый исходящий запрос (это запрос, который мы должны отправить серверу для авторизации): {"op":2,"d":{"token":"NjMwMTU2ODYzNDcxNjE2MDMw.Xe9SFw.GLgMR8R7vQPnHOmaD5KmHqU4vmk","properties":{"os":"Windows","browser":"Chrome","device":"","browser_user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3650.0 Iron Safari/537.36","browser_version":"","os_version":"10","referrer":"","referring_domain":"","referrer_current":"","referring_domain_current":"","release_channel":"stable","client_build_number":50980,"client_event_source":null},"presence":{"status":"online","since":0,"activities":[],"afk":false},"compress":false}}
Теперь мы можем проверить будет ли работать наш WS на отдельном клиенте. Для этого можно использовать расширение Simple WebSocket Client.
Прописываем URL
Открываем Websocket нажатием на Open (в логах должно появиться первое сообщение с heartbeat_interval)
Вставляем тело исходящего запроса в поле Request и нажимаем Send. В логах мы получим ответ, что всё прошло успешно.
Супер! Всё работает как надо, дело осталось за малым - реализовать тоже самое на ZennoPoster.
Realизуем.
Для начала нам нужен сам websocket-sharp.dll. Качаем и вытаскиваем его с помощью WinRAR. Закидываем библиотеку в папку ExternalAssemblies. Добавляем его в наш проект с помощью блока "Ссылки из GAC" и прописываем using:
Директивы using и общий код:
using WebSocketSharp;
using WebSocketSharp.Server;
using WebSocketSharp.Net;
Кстати, в тестовом шаблоне я использовал тело запроса от десктопной версии, поэтому просто можете закинуть свой токен в переменную для теста. (build number - версия клиента)
Если взглянуть на трафик в браузере, то можно заметить, что сокет не закрывается и принимает/отправляет периодично новые запросы, поэтому в коде мы должны будем использовать асинхронный метод, чтобы сам шаблон выполнялся, а сокет работал в фоновом режиме и не закрывался, пока мы его об этом не попросим.
В общем коде дописываем using:
using System.Threading.Tasks;
В общем коде в классе CommonCode пишем наш код:
Описываем методы для WSS:
public static void Wss(IZennoPosterProjectModel project) //определяем метод Wss
{
Random rnd = new Random(); //инициализация Random
string data = project.Variables["wss_data"].Value; //загружаем тело запроса из переменной
//подключаем прокси, если необходимо
//string ip = project.Variables["proxy_ip"].Value;
//string login = project.Variables["proxy_login"].Value;
//string pass = project.Variables["proxy_pass"].Value;
using (var ws = new WebSocket("wss://gateway.discord.gg/")) //определяем ссылку запроса
{
//ws.SetProxy (ip, login, pass); //устанавливаем прокси, если необходимо
//ws.SetCookie (new Cookie("__cfduid", project.Variables["cookies_value"].Value)); //устанавливаем куки, если необходимо
ws.Origin = "https://discordapp.com";
ws.OnMessage += (sender, e) => //объявляем, что будем получать сообщение
project.SendInfoToLog(e.Data); //пишем инфу в лог для наглядности
ws.Connect(); //подключаемся по wss
ws.Send (data); //отправляем тело запроса
System.Threading.Thread.Sleep(1000); //небольшая пауза
ws.Send ("{\"op\":4,\"d\":{\"guild_id\":null,\"channel_id\":null,\"self_mute\":true,\"self_deaf\":true,\"self_video\":false}}"); //отправляем тело второго запроса
int q = 0;
while (Convert.ToBoolean(project.Variables["wss_lock"].Value)) //пока переменная = true, цикл будет выполняться
{
Thread.Sleep(rnd.Next(40000, 43000));
q = q + rnd.Next(4, 40);
ws.Send ("{\"op\":1,\"d\":" + q + "}"); //отправляем тело запроса
};
}
}
public static async Task WssAsync(IZennoPosterProjectModel project) //определяем асинхронный метод
{
await Task.Run(() => Wss(project)); //запуск метода Wss
}
Если упрощенно, то сначала вы пишете в методе Wss код, который вы хотите выполнить, а потом в WssAsync указываете, что Wss нужно запустить асинхронно.
Вызвать асинхронный Wss можно с помощью C# кубика.
После того как мы присвоим переменной wss_lock значение false через кубик "Обработка переменных", код успешно завершится и websocket закроется. А в Discord ваш аккаунт уйдёт в оффлайн.
Также завершить поток можно другими интересными и, возможно, более "правильными" способами, но я не сильно углублялся в эту тему.
Summary
В конечном итоге всё оказалось не так уж и сложно, но пришлось разбираться и потратить какое-то время. После чего я успешно возобновил трафик, а позже реализовал рассыльщик по чату в Reddit, там также используется wss. Вообще Websocket часто используют в авторизациях и мессенджерах, поэтому, думаю, эти знания вам пригодятся.
P.S. Асинхронный WSS гарантированно работает в версии 5.28. Если нужно заменить какие-то заголовки, то можно подредактировать некоторые файлы с Github (например User-Agent) и скомпилировать в VS измененный websocket-sharp.dll.
Приветствую! Отличная статья... Используя данный метод для своих целей, а именно делаю вебхук дискорда для получения сигналов определенных с трейдинг вью. Сигнал получается приходят в чат дискорда и уже в шаблоне я передаю это дело в переменную.
Столкнулся с проблемой, что вебсокет каждые пару минут вырубается или соединение теряется или что-то.... не подскажешь что изменить надо, что соединения было постоянным?
У всех так ребят? Вроде как вебсокет должен как раз постоянно быть на готове принять и отдать или не?))
А Вы в течении этих 2х минут какой-то Ping/Pong отправляете/получаете?
Просто чтобы это работало нужно как-бы дать серверу знать, что я мол ещё живой...
А Вы в течении этих 2х минут какой-то Ping/Pong отправляете/получаете?
Просто чтобы это работало нужно как-бы дать серверу знать, что я мол ещё живой...
Приветствую! Отличная статья... Используя данный метод для своих целей, а именно делаю вебхук дискорда для получения сигналов определенных с трейдинг вью. Сигнал получается приходят в чат дискорда и уже в шаблоне я передаю это дело в переменную.
Столкнулся с проблемой, что вебсокет каждые пару минут вырубается или соединение теряется или что-то.... не подскажешь что изменить надо, что соединения было постоянным?
У всех так ребят? Вроде как вебсокет должен как раз постоянно быть на готове принять и отдать или не?))
У меня на одном сайте соединение закрывается через минуту после открытия, каждую минуту необходимо отправлять специальный рефреш запрос, чтобы поддерживать активность соединения. Тут скорее всего такой же случай.
Приветствую, спасибо за статью. Сейчас пытаюсь разобраться в работе с одним сайтом, использующим вебсокет, но никак не выходит. Нужно отправить три сообщения. Первое содержит токен, второе и третье его уже не содержит. При попытке отправки второго или третьего сообщение выкидывает ошибку: 4003 Error: Not authenticated.
Cookies запрос не использует. В headers есть только параметр Sec-WebSocket-Key. Однако, как я понял в этой библиотеке не предусмотрена установка пользовательских заголовков. Как отправить всю цепочку сообщений без сбоя коннекта и возвратом нужных мне данных пока въехать не могу. Если кто-то сталкивался с этим - напишите, пожалуйста, хотя бы в какую сторону смотреть.
Всем привет подскажите если каждые 30 сек поток останавливается и нужно отправлять "primus::pong:: куда прописать что бы отправка шла каждые 30 сек или нужно все перезапускать постоянно
А как можно понять, как аккаунт в онлайне держится, где найти этот запрос, который за это отвечает?
это не про дискорд, я вот бразуер как только закрываю, через пару минут акк уже оф, но в браузере запрос wss есть только на уведомления