Гемблинг на запросах | Разваливаем "Мир слотов"

Dmitriy Ka

Client
Регистрация
03.05.2016
Сообщения
733
Благодарностей
485
Баллы
63
111383


Всем привет! Как насчёт выиграть парочку миллиардов в слоты? :di:
Жалко конечно, что пару миллиардов фантиков, но тоже весело! :D
111381

Так как мы супер-пупер автоматизаторы, нам кликать по кнопочкам не интересно, мы сделаем все на запросах, чтобы уровень проходить не за 5-10 минут, а меньше чем за минуту:bd:

Играть мы будим в приложение ВК казино на фантики
Приложение: https://vk.com/mir_slotov
Группа ВК: https://vk.com/slotworld

Чтобы шайтан коробка завилась, нужно получить sid приложения!
К сожалению, чтобы получить sid на запросах, пришлось бы убить кучу времени, а оно того не стоило. Поэтому его мы быстренько получим через DevTools.

Для этого делаем 3 простых действия:
1) Заходим в приложение. Важно, если заходите в первый раз в игру соберите монеты по подсказкам, которые дает игра!
2) Открываем DevTools (ctrl+shift+i) => Вкладка Network и обновляем страницу с игрой
3) Фильтруем выдачу по index и ищем 3 строчку.
В ней переходим во вкладку Responce и забираем нужный нам sid
111390

Заходим во входные настройки шаблона и закидываем туда Sid. Все шаблон готов к фарму фантиков8-)

Коротко по Входным настройкам:
Sid - обязательно, чтобы все заработало.
Биг вин!!! Х от - указываем кокой Х выигрыша подсвечивать в логе.
Например выигрыш от Х 1000 будет выведен в лог Зеленым и шаблон сделает паузу 5 секунд.
Количество Квестов - Указываем сколько уровней хотим пройти, шаблон будет ходит по циклу, пока не пройдет нужное количество уровней.
Сколько нужно денег - указываем сколько нужно нафармить денег с помощью бага.
А чтобы фантики точно не закончились, я для вас нашел баг на 10 уровне.
Поставь сразу лайк за Баг:ah:
С помощью него можно фармить сколько угодно денег, но есть одно но, так как уровень маленький, ставки тоже, бабосики фармятся долго.
Советую нафармить 10 000 000 000.

А если серьезно шаблон относительно полезный, однако реализация интересная, поэтому советую разобрать подход.
Все самое интересное лежит в Общем Коде!
А для тех кому лень скачать шаблон, выкладываю код сюда, за это тоже можно лайкосик влепить:df:

В работе задействованы 3 класса, 2 вспомогательных, 1 рабочий.
C#:
public class SlotData
{
    public string Id { get; set; }
    public string Slot { get; set; }
    public string Level { get; set; }
    public string Quest { get; set; }
}
C#:
public class SpinData
{
    public int Bet { get; set; }
    public int Xbet { get; set; }
    public long Money { get; set; }
    public long Reward { get; set; }
    public bool IsFreeSpins { get; set; }
    public bool IsFinished { get; set; }
    public string Goal { get; set; }
    public string Progress { get; set; }
}
C#:
public class Slots
{
    public string Error { get; private set; }

    private SlotData SlotData { get; set; }
    private SpinData SpinData { get; set; }
    private SlotData[] ArrSlotData { get; set; }
    private string DataLevel { get; set; }
    private string Token { get; set; }
    private string Bet { get; set; }

    private int _spinId;
    private string _sid;

    public Slots(string sid)
    {
        _sid = sid;
        _spinId = new Random().Next(1000, 2000);
        SpinData = new SpinData();
    }

    /// <summary>
    /// Получаем Уровень.
    /// </summary>
    /// <returns></returns>
    public bool GetLevel()
    {
        string time = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ");

        var url = "https://sandmanslots-api.candygrill.com/api/v1_0_0/call/index?sid=" + _sid;

        var content = "{\"time\":\"" + time + "\",\"commands\":[" +
            "{\"id\":1,\"cmd\":\"eventSocial.get\",\"data\":{\"social_net\":\"vkig\"},\"time\":\"" + time + "\"}," +
            "{\"id\":3,\"cmd\":\"systemCommands.gameLoading.start\",\"data\":" +
            "{\"deviceId\":\"vkig:\",\"deviceModel\":\"cocos\",\"graphicsDeviceName\":\"\",\"graphicsDeviceVendor\":\"WebKit\"," +
            "\"graphicsDeviceVersion\":\"\",\"operatingSystem\":\"\",\"platform\":\"vkig_WEB\",\"unityVersion\":\"2.1.0\"," +
            "\"graphicsMemorySize\":0,\"graphicsShaderLevel\":0,\"maxTextureSize\":16384,\"npotSupport\":false,\"processorCount\":0," +
            "\"processorType\":\"cocos\",\"supportedRenderTargetCount\":0,\"supports3DTextures\":false,\"systemMemorySize\":8192," +
            "\"api_version\":1},\"time\":\"" + time + "\"}," +
            "{\"id\":5,\"cmd\":\"user.profile\",\"data\":{},\"time\":\"" + time + "\"}," +
            "{\"id\":6,\"cmd\":\"user.getOptions\",\"data\":{},\"time\":\"" + time + "\"}," +
            "{\"id\":7,\"cmd\":\"x_slots.fortuneWheel.configuration\",\"data\":{},\"time\":\"" + time + "\"}," +
            "{\"id\":8,\"cmd\":\"moneybox.configuration\",\"data\":{},\"time\":\"" + time + "\"}," +
            "{\"id\":9,\"cmd\":\"eventGatcha.configuration\",\"data\":{\"systemRequest\":false},\"time\":\"" + time + "\"}," +
            "{\"id\":10,\"cmd\":\"cashBack.config\",\"data\":{},\"time\":\"" + time + "\"}," +
            "{\"id\":11,\"cmd\":\"eventOpenSlot.configuration\",\"data\":{\"systemRequest\":false},\"time\":\"" + time + "\"}," +
            "{\"id\":12,\"cmd\":\"vipSubscription.configuration\",\"data\":{},\"time\":\"" + time + "\"}," +
            "{\"id\":13,\"cmd\":\"news.update\",\"data\":{},\"time\":\"" + time + "\"}," +
            "{\"id\":14,\"cmd\":\"event.configuration\",\"data\":{\"systemRequest\":false},\"time\":\"" + time + "\"}," +
            "{\"id\":15,\"cmd\":\"eventSale.configuration\",\"data\":{\"systemRequest\":false},\"time\":\"" + time + "\"}," +
            "{\"id\":16,\"cmd\":\"adminBonus.configuration\",\"data\":{},\"time\":\"" + time + "\"}," +
            "{\"id\":17,\"cmd\":\"eventScratch.config\",\"data\":{\"systemRequest\":false},\"time\":\"" + time + "\"}," +
            "{\"id\":18,\"cmd\":\"x_slots.dailyMission.configuration\",\"data\":{\"systemRequest\":false},\"time\":\"" + time + "\"}," +
            "{\"id\":19,\"cmd\":\"x_slots.map\",\"data\":{},\"time\":\"" + time + "\"}]}";

        string[] headers = {
            "accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
            "accept-encoding: gzip, deflate",
            "cache-control: max-age=0",
            "sec-fetch-dest: document",
            "sec-fetch-mode: navigate",
            "sec-fetch-site: same-origin",
            "sec-fetch-user: ?1",
            "upgrade-insecure-requests: 1",
        };

        var result = Post(url, content, headers);

        var status = JObject.Parse(result)["commands"][0].SelectToken("status").ToString();

        if (status == "ok")
        {
            DataLevel = result;
            return true;
        }
        else
        {
            Error = result;
            return false;
        }
    }

    /// <summary>
    /// Парсим данные уровня(Id, Slot, Quest).
    /// </summary>
    public void ParseLevel()
    {
        var arrSlots = JObject.Parse(DataLevel)["commands"][16]["data"]["quests"].ToArray();
        var countSlots = arrSlots.Length;
        ArrSlotData = new SlotData[countSlots];

        for (int i = 0; i < countSlots; i++)
        {
            ArrSlotData[i] = new SlotData();
            ArrSlotData[i].Level = JObject.Parse(DataLevel)["commands"][2]["data"].SelectToken("level").ToString();
            ArrSlotData[i].Id = arrSlots[i].SelectToken("id").ToString();
            ArrSlotData[i].Slot = arrSlots[i].SelectToken("slot").ToString();
            ArrSlotData[i].Quest = arrSlots[i].SelectToken("type").ToString();
        }

    }

    /// <summary>
    /// Выбираем самый легикий слот для игры.
    /// </summary>
    /// <returns></returns>
    public SlotData SelectSlot()
    {
        var quests = new[] {
            "make_n_spins_for_free",
            "make_n_spins_on_max_bet",
            "make_n_spins",
            "get_icon_n_times",
            "win_n_coins_in_freespins",
            "win_n_coins_in_bonus_game",
            "win_n_coins_in_freespin_game",
            "win_n_coins",
            "break_n_chains"
            };

        var ignorSlots = new[] {
            "Jungle",
            "Gangsters",
            "Indiana",
            "BookOfRa"
            };

        for (int i = 0; i < quests.Length; i++)
        {
            for (int s = 0; s < ArrSlotData.Length; s++)
            {
                if (ignorSlots.Contains(ArrSlotData[s].Slot))
                {
                    continue;
                }
                if (quests[i] == ArrSlotData[s].Quest)
                {
                    SlotData = ArrSlotData[s];
                    return ArrSlotData[s];
                }
            }
        }

        return null;
    }

    /// <summary>
    /// Получаем токен Слота.
    /// </summary>
    /// <param name="slotData"></param>
    /// <returns></returns>
    public bool GetTokenAndBetSlot()
    {
        var time = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ");
        var url = "https://sandmanslots-api.candygrill.com/api/v1_0_0/call/index?sid=" + _sid;

        var content = "{\"time\":\"" + time + "\",\"commands\":[" +
            "{\"id\":38,\"cmd\":\"systemCommands.trackWindowAction\",\"data\":{\"window\":\"PromosWindow\",\"action\":\"open\"},\"time\":\"" + time + "\"}," +
            "{\"id\":39,\"cmd\":\"systemCommands.trackWindowAction\",\"data\":{\"window\":\"PromosWindow\",\"action\":\"close\"},\"time\":\"" + time + "\"}," +
            "{\"id\":40,\"cmd\":\"systemCommands.trackWindowAction\",\"data\":{\"window\":\"XMissionChooseWindow\",\"action\":\"open\"},\"time\":\"" + time + "\"}," +
            "{\"id\":41,\"cmd\":\"systemCommands.trackWindowAction\",\"data\":{\"window\":\"XMissionChooseWindow\",\"action\":\"close\"},\"time\":\"" + time + "\"}," +
            "{\"id\":42,\"cmd\":\"x_slots.configuration\",\"data\":{\"slot\":\"" + SlotData.Slot + "\",\"quest_id\":" + SlotData.Id + "},\"time\":\"" + time + "\"}]}";

        var headers = new[] {
            "Connection: keep-alive",
            "Content-Type: application/json",
            "Accept: */*",
            "Origin: https://sandmanslots-api.candygrill.com",
            "Sec-Fetch-Site: same-origin",
            "Sec-Fetch-Mode: cors",
            "Sec-Fetch-Dest: empty",
            "Referer: https://sandmanslots-api.candygrill.com/unity-assets/ig-vk-release-app/current/indexVk.html?&hash=",
            "Accept-Encoding: gzip, deflate, br",
            "Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7",
        };

        var result = Post(url, content, headers);
        var status = JObject.Parse(result)["commands"][0].SelectToken("status").ToString();

        if (status == "ok")
        {
            var json = JObject.Parse(result)["commands"][4]["data"];
            Token = json.SelectToken("token").ToString();
            var arrBet = json["configuration"].SelectToken("availableBets").ToArray();

            if (SlotData.Quest == "make_n_spins_for_free" || SlotData.Quest == "make_n_spins_on_max_bet")
            {
                Bet = arrBet[arrBet.Length-1].ToString();
            }
            else if (SlotData.Quest == "win_n_coins_in_bonus_game" || SlotData.Quest == "win_n_coins_in_freespin_game" || SlotData.Quest == "win_n_coins")
            {
                if (arrBet.Length > 3)
                {
                    Bet = arrBet[arrBet.Length - 3].ToString();
                }
            }
            else Bet = arrBet[0].ToString();

            return true;
        }
        else
        {
            Error = result;
            return false;
        }
    }

    /// <summary>
    /// Делаем спин.
    /// </summary>
    /// <returns></returns>
    public SpinData Spin()
    {
        _spinId++;

        var time = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ");
        var url = "https://sandmanslots-api.candygrill.com/api/v1_0_0/call/index?sid=" + _sid;

        var content = "{\"time\":\"" + time + "\",\"commands\":[" +
            "{\"id\":" + _spinId + ",\"cmd\":\"x_slots.spin\",\"data\":" +
            "{\"quest_id\":" + SlotData.Id + ",\"slot\":\"" + SlotData.Slot + "\",\"bet\":" + Bet + ",\"token\":\"" + Token + "\"}," +
            "\"time\":\"" + time + "\"}]}";

        var headers = new[] {
            "Accept: */*",
            "Origin: https://sandmanslots-api.candygrill.com",
            "Sec-Fetch-Site: same-origin",
            "Sec-Fetch-Mode: cors",
            "Sec-Fetch-Dest: empty",
            "Referer: https://sandmanslots-api.candygrill.com/unity-assets/ig-vk-release-app/current/indexVk.html?&hash=",
            "Accept-Encoding: gzip, deflate, br",
            "Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7",
        };

        var result = Post(url, content, headers);

        var status = JObject.Parse(result)["commands"][0].SelectToken("status").ToString();

        if (status == "ok")
        {
            var json = JObject.Parse(result)["commands"][0]["data"];

            SpinData.IsFreeSpins = json.SelectToken("isFreeSpinResult").Value<bool>();
            SpinData.IsFinished = json["questProgress"].SelectToken("finished").Value<bool>();
            SpinData.Reward = json.SelectToken("totalReward").Value<long>();
            SpinData.Money = json["user"].SelectToken("money").Value<long>();
            SpinData.Goal = json["questProgress"].SelectToken("goal").ToString();
            SpinData.Progress = json["questProgress"]["progress"][0].SelectToken("").ToString();
            SpinData.Bet = int.Parse(Bet);
            SpinData.Xbet = (int)SpinData.Reward / SpinData.Bet;

            return SpinData;
        }
        else
        {
            Error = result;
            return null;
        }
    }

    /// <summary>
    /// Фармим баланс через Баг 10-го уровня.
    /// </summary>
    /// <param name="countMoney"></param>
    /// <returns></returns>
    public long FarmMoney()
    {
        Bet = "20000";
        Spin();

        return SpinData.Money;
    }

    /// <summary>
    /// Установить ставку вручную.
    /// </summary>
    /// <param name="bet"></param>
    public void SetBet(string bet)
    {
        Bet = bet;
    }

    //Get запрос
    private string Get(string url, string[] headers = null)
    {
        return Request(HttpMethod.GET, url, "", headers);
    }

    //Post запрос
    private string Post(string url, string content, string[] headers = null)
    {
        return Request(HttpMethod.POST, url, content, headers);
    }

    //Http запрос
    private string Request(HttpMethod method, string url, string content, string[] headers = null)
    {
        return ZennoPoster.HTTP.Request(
            method: method,
            url: url,
            content: content,
            AdditionalHeaders: headers,
            respType: ResponceType.BodyOnly
        );
    }
}
На этом у меня все.
Можете подписаться на мой ТГ канал: https://t.me/streamzp
Канал был заброшен, но возможно запущу стрим по разбору данного шаблона, подпишитесь, чтобы не пропустить.

 
Номер конкурса шаблонов
Одиннадцатый конкурс шаблонов

Вложения

Для запуска проектов требуется программа ZennoPoster или ZennoDroid.
Это основное приложение, предназначенное для выполнения автоматизированных шаблонов действий (ботов).
Подробнее...

Для того чтобы запустить шаблон, откройте нужную программу. Нажмите кнопку «Добавить», и выберите файл проекта, который хотите запустить.
Подробнее о том, где и как выполняется проект.

Последнее редактирование модератором:

radv

Client
Регистрация
11.05.2015
Сообщения
3 788
Благодарностей
1 952
Баллы
113
Как тренировочная база, для работы с подобными играми подойдет. :az: Потом и на что то похожее можно применить:ay:
 

Fedman09

Client
Регистрация
25.02.2020
Сообщения
95
Благодарностей
40
Баллы
28
Интересная тема, у меня появился повод подумать о монетизации кастомной версии:bf:
 
  • Спасибо
Реакции: Dmitriy Ka

SlipDez

Client
Регистрация
18.07.2018
Сообщения
375
Благодарностей
70
Баллы
28
Для обучения работы на запросах самое то)
 
  • Спасибо
Реакции: Dmitriy Ka

Dmitriy Ka

Client
Регистрация
03.05.2016
Сообщения
733
Благодарностей
485
Баллы
63
Для обучения работы на запросах самое то)
Советую обратить внимание на код для работы с запросами, как можно удобно схлопывать код и потом вызывать через короткий метод :df:
C#:
//Get запрос
private string Get(string url, string[] headers = null)
{
    return Request(HttpMethod.GET, url, "", headers);
}

//Post запрос
private string Post(string url, string content, string[] headers = null)
{
    return Request(HttpMethod.POST, url, content, headers);
}

//Http запрос
private string Request(HttpMethod method, string url, string content, string[] headers = null)
{
    return ZennoPoster.HTTP.Request(
        method: method,
        url: url,
        content: content,
        AdditionalHeaders: headers,
        respType: ResponceType.BodyOnly
    );
}
 
  • Спасибо
Реакции: SHILY и SlipDez

SlipDez

Client
Регистрация
18.07.2018
Сообщения
375
Благодарностей
70
Баллы
28
Vamp1k

Обратил внимание, очень удобно сделал) Ранее сталкивался с проблемой что из за куки контейнера иногда в запросы попадали лишние данные из за чего запрос не проходил. Не сталкивался с таким?

Есть ли смысл хранить куки в отдельном листе и вытаскивать нужные данные через contains? Либо ZP подтягивает сам нужные данные, возможно у меня просто был баг
 

oleg21621

Client
Регистрация
20.04.2016
Сообщения
973
Благодарностей
172
Баллы
43
шаблон написать бы такой ,чтобы отмывать бездепозитный бонус в казино
 

Dmitriy Ka

Client
Регистрация
03.05.2016
Сообщения
733
Благодарностей
485
Баллы
63
Ранее сталкивался с проблемой что из за куки контейнера иногда в запросы попадали лишние данные из за чего запрос не проходил.
С таким не сталкивался.
Есть ли смысл хранить куки в отдельном листе и вытаскивать нужные данные через contains? Либо ZP подтягивает сам нужные данные, возможно у меня просто был баг
Зависит от задачи, возможно где-то и надо хранить куки отдельно.
А вот вытаскивать данные куки из контейнера, с таким сталкивался. В куки лежали данные, которые надо было отправлять в теле запроса.
 
  • Спасибо
Реакции: SlipDez

Dmitriy Ka

Client
Регистрация
03.05.2016
Сообщения
733
Благодарностей
485
Баллы
63

Dmitriy Ka

Client
Регистрация
03.05.2016
Сообщения
733
Благодарностей
485
Баллы
63
15 лайков и 5 голосов, хорошо идем :D
 
  • Спасибо
Реакции: SlipDez

GreenWay

Client
Регистрация
11.05.2012
Сообщения
432
Благодарностей
139
Баллы
43
шаблон написать бы такой ,чтобы отмывать бездепозитный бонус в казино
Бонусхантинг - заводиться 2 акка и в рулетке весь бонус с 1 акка на красное, со второго на черное - полюбому 1 пройдет. Если ты об этом... старо как мир :-)
 

oleg21621

Client
Регистрация
20.04.2016
Сообщения
973
Благодарностей
172
Баллы
43
Бонусхантинг - заводиться 2 акка и в рулетке весь бонус с 1 акка на красное, со второго на черное - полюбому 1 пройдет. Если ты об этом... старо как мир :-)
это я в 1 классе уже знал .Я про другое . Я про казино три топора
 
  • Спасибо
Реакции: GreenWay

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)