Перейти к содержанию
Форум шарда Middle-Earth

nepret

nepret
  • Публикаций

    274
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные nepret


  1. stealth version 9.6.1  (<- делался на версии)

    Блок (класс) для работы с рунбукой

    Как запустить:  читать тут

    Что делает:

    • Все действия что можно сделать с рунбукой (телепорт по регам\скролам, открытия портов и т.д.)

    Инструкция по применению:

    • дока в теле скрипта, в низу все доступные методы.
    from datetime import datetime
    from py_stealth import *
    
    
    class Runebook:
        def __init__(self, runebook_id: int):
            self._runebook_id = runebook_id  # ID рунбуки
            self.info_runebook = {}
    
        def __call__(self, *args, **kwargs):
            pass
    
        @staticmethod
        def _check_connected() -> bool:
            if Connected():
                return True
            print("Ошибка: нет соединения с сервером.")
            return False
    
        def _open_backpack(self, pack=None) -> bool:
            if pack is None:
                pack = Backpack()
            if self._check_connected():
                for i in range(5):
                    UseObject(pack)
                    if LastContainer() == pack:
                        return True
                    Wait(1000)
                print("Ошибка: не смог открыть бэкпак.")
            return False
    
        def _check_runebook(self, runebook_id: int) -> bool:
            if self._open_backpack():
                if GetParent(runebook_id) == Backpack():
                    return True
                print(f"Ошибка: рунбука {hex(runebook_id)} не в бэкпаке.")
            return False
    
        def _open_runebook(self, runebook_id: int) -> bool:
            if self._check_runebook(runebook_id=runebook_id):
                while GetGumpsCount():
                    CloseSimpleGump(GetGumpsCount() - 1)
                temp = GetGumpsCount()
                for i in range(10):
                    UseObject(runebook_id)
                    if temp < GetGumpsCount():
                        return True
                    Wait(500)
                print("Ошибка: не смог открыть рунбуку.")
            return False
    
        def _check_reagents(self, pack=None, gate=False) -> bool:
            '''
            :param pack: если реги в бекпаке, то вызываем пустым, если в мешке, шкатулке, передаём id контейнера
            '''
            if pack is not None:
                self._open_backpack(pack=pack)
            if not gate:
                if any(i < 1 for i in [BPCount(), MRCount(), BMCount()]):
                    print(f'Недостаточно реагентов (BP:{BPCount()}, MR:{MRCount()}, BM:{BMCount()})')
                    return False
            else:
                if any(i < 1 for i in [BPCount(), MRCount(), SACount()]):
                    print(f'Недостаточно реагентов (BP:{BPCount()}, MR:{MRCount()}, SA:{SACount()})')
                    return False
            return True
    
        @staticmethod
        def _check_mana(gate=False) -> bool:
            if not gate:
                if Mana() < 11:
                    print(f"Мало маны! <11 ({Mana()}/{MaxMana()})")
                    return False
            else:
                if Mana() < 40:
                    print(f"Мало маны! <40 ({Mana()}/{MaxMana()})")
                    return False
            return True
    
        def _find_rune(self, rune, runebook_id=None) -> dict | bool:
            '''
            :param runebook_id: если вызывается пустым, присваивается id рунбуки из конструктора, или указать id
            интересующей рунбуки.
            :param rune: принимает номер руны(НЕ индекс) в рунбуке с 1 по 16
            :return: возвращает словарь с номерами гампов
            {"name": "sortir","set_def": 501, "scroll": 601,"drop": 81,"reagent": 2,"gate": 3}
            '''
            if runebook_id is None:
                runebook_id = self._runebook_id
            if _pull := self.get_info_runebook(runebook_id=runebook_id):
                if isinstance(rune, int):
                    if _pull['info']['count_rune'] >= rune - 1:
                        return _pull['gumps'][rune - 1]
                else:
                    for i in _pull['gumps']:
                        if i["name"] in rune:
                            return i
            print(f"Ошибка: руна не найдена")
            return False
    
        def get_info_runebook(self, runebook_id=None) -> dict | bool:
            '''
            :param runebook_id:  если вызывается пустым, присваивается id рунбуки из конструктора, или указать id
            интересующей рунбуки.
            :return: возвращает словарь с общей информацие о рунбуке и гампами.
            {
                "gumps": [{"name": "sortir","set_def": 501, "scroll": 601,"drop": 81,"reagent": 2,"gate": 3}, [...], ...n],
                "info": {'name': Basyan, 'charge': 2, 'charge_max': 10, 'count_rune': 7}
            }
            '''
            if runebook_id is None:
                runebook_id = self._runebook_id
            if self._open_runebook(runebook_id=runebook_id):
                info_gumps = GetGumpInfo(GetGumpsCount() - 1)
                count_rune = int((info_gumps['GumpButtons'][len(info_gumps['GumpButtons']) - 2]['ReturnValue']) / 2)
    
                temp_pull_gump = {'gumps': []}
                for n, i, r in zip(range(7, count_rune + 7), range(1, count_rune + 1), range(2, 99, 2)):
                    temp_pull_gump['gumps'].append({
                        "name": info_gumps['Text'][n][0],
                        "set_def": 500 + i,
                        "scroll": 600 + i,
                        "drop": 80 + i,
                        "reagent": r,
                        "gate": r + 1
                    })
    
                temp_pull_gump.update({"info": {'name': GetTooltip(runebook_id),
                                                'charge': int(info_gumps['Text'][3][0]),
                                                'charge_max': int(info_gumps['Text'][4][0]),
                                                'count_rune': int(count_rune)}})
    
                if runebook_id == self._runebook_id:
                    self.info_runebook = temp_pull_gump
                return temp_pull_gump
            return False
    
        def recall(self, rune, pack=None, reagents=False) -> bool:
            '''
            :param pack: если реги в бекпаке, то вызываем пустым, если в мешке, шкатулке, передаём id контейнера
            :param rune: номер руны в рунбуке (с 1 до 16), 0 - последняя руна или имя руны "sortir" (чувствителен к регистру)
            :param reagents: устой и false рекол по скроллам, если true, рекол по регам
            :return: boolean
            '''
            if _rune := self._find_rune(rune=rune):
                if not reagents:
                    if self.info_runebook['info']['charge'] <= 0:
                        print(f"АХТУНГ: заправь рунбуку. charge "
                              f"{self.info_runebook['info']['charge']}/{self.info_runebook['info']['charge_max']}")
                        return False
                    NumGumpButton(GetGumpsCount() - 1, _rune["scroll"])
                    return True
                else:
                    if self._check_reagents(pack=pack) and self._check_mana():
                        NumGumpButton(GetGumpsCount() - 1, _rune["reagent"])
                        return True
            return False
    
        def gate(self, rune, pack=None) -> bool:
            '''
            :param pack: если реги в бекпаке, то вызываем пустым, если в мешке, шкатулке, передаём id контейнера
            :param rune: номер руны в рунбуке (с 1 до 16), 0 - последняя руна или имя руны "sortir" (чувствителен к регистру)
            :return: boolean
            '''
            if _rune := self._find_rune(rune=rune):
                if self._check_reagents(gate=True, pack=pack) and self._check_mana(gate=True):
                    NumGumpButton(GetGumpsCount() - 1, _rune["gate"])
                    return True
            return False
    
        def recharge(self, scrolls=None) -> bool:
            '''
            :param scrolls: если пустой, то вызовет таргет речерджа или указать ID стопки с рекалами
            :return: boolean
            '''
            if _rune := self.get_info_runebook():
                if self.info_runebook['info']['charge'] < self.info_runebook['info']['charge_max']:
                    if TargetPresent():
                        CancelTarget()
                    NumGumpButton(GetGumpsCount() - 1, 800)
                    for i in range(5):
                        if TargetPresent():
                            if isinstance(scrolls, int):
                                WaitTargetObject(scrolls)
                            break
                        Wait(500)
                return True
            return False
    
        def set_def_rune(self, rune) -> bool:
            '''
            :param rune: номер руны в рунбуке (с 1 до 16), 0 - последняя руна или имя руны "sortir" (чувствителен к регистру)
            :return: boolean
            '''
            if _rune := self._find_rune(rune=rune):
                NumGumpButton(GetGumpsCount() - 1, _rune["set_def"])
                return True
            return False
    
        def drop_rune(self, rune, runebook_id=None) -> int | bool:
            '''
            :param runebook_id: если вызывается пустым, присваивается id рунбуки из конструктора, или указать id
            интересующей рунбуки.
            :param rune: номер руны в рунбуке (с 1 до 16), 0 - последняя руна или имя руны "sortir" (чувствителен к регистру)
            :return: boolean
            '''
            if _rune := self._find_rune(rune=rune, runebook_id=runebook_id):
                while f := FindTypeEx(0x1F14, 0xFFFF, Backpack(), False):
                    Ignore(f)
                NumGumpButton(GetGumpsCount() - 1, _rune["drop"])
                drop_rune = FindTypeEx(0x1F14, 0xFFFF, Backpack(), False)
                IgnoreReset()
                return drop_rune
            return False
    
        def add_rune(self, rune_id: int, runebook_id=None):
            '''
            :param rune_id: id пустой руны
            :param runebook_id: если вызывается пустым, присваивается id рунбуки из конструктора, или указать id
            интересующей рунбуки.
            :return:
            '''
            if self.get_info_runebook(runebook_id=runebook_id):
                if TargetPresent():
                    CancelTarget()
                NumGumpButton(GetGumpsCount() - 1, 1)
                for i in range(5):
                    if TargetPresent():
                        WaitTargetObject(rune_id)
                        break
                    Wait(500)
                return True
            return False
    
    
    if __name__ == '__main__':
        _runebook = Runebook()
    
        _runebook.recall()
        _runebook.gate()
        _runebook.recharge()
        _runebook.drop_rune()
        _runebook.add_rune()
        _runebook.get_info_runebook()
        _runebook.info_runebook

     

     

    runebook.py


  2. stealth version 9.6.1  (<- делался на версии)

    Копирования рунбуки и ... не только...

    Как запустить:  читать тут

    Что делает:

    • Летает по рунам из первой рунбуки, маркает на точках прилёта руны, переименовывает их и запихивает во вторую.
    • Если чара убили или упал сервак, после повторного запуска продолжит с руны на которой остановился. (смотрит по числу рун, а не по названию, мешать их не советую)
    • Может летать как по регам так и по скролам, есть в настройках.
    • По завершению, можно отправить домой. с.м. настройки.

    Инструкция по применению:

    1. Руны в пак.
    2. Заправить рунбуку скролами и бекпак регами. (для рекола и для Марка)
    3. Подправить настройки под себя.
    4. Запустить скрипт.

    "и ... не только... " будет ниже.

     

    from datetime import datetime
    from py_stealth import *
    
    
    class Runebook:
        def __init__(self, runebook_id: int):
            self._runebook_id = runebook_id
            self.info_runebook = {}
    
        def __call__(self, *args, **kwargs):
            pass
    
        @staticmethod
        def _check_connected() -> bool:
            if Connected():
                return True
            print("Ошибка: нет соединения с сервером.")
            return False
    
        def _open_backpack(self, pack=None) -> bool:
            if pack is None:
                pack = Backpack()
            if self._check_connected():
                for i in range(5):
                    UseObject(pack)
                    if LastContainer() == pack:
                        return True
                    Wait(1000)
                print("Ошибка: не смог открыть бэкпак.")
            return False
    
        def _check_runebook(self, runebook_id: int) -> bool:
            if self._open_backpack():
                if GetParent(runebook_id) == Backpack():
                    return True
                print(f"Ошибка: рунбука {hex(runebook_id)} не в бэкпаке.")
            return False
    
        def _open_runebook(self, runebook_id: int) -> bool:
            if self._check_runebook(runebook_id=runebook_id):
                while GetGumpsCount():
                    CloseSimpleGump(GetGumpsCount() - 1)
                temp = GetGumpsCount()
                for i in range(10):
                    UseObject(runebook_id)
                    if temp < GetGumpsCount():
                        return True
                    Wait(500)
                print("Ошибка: не смог открыть рунбуку.")
            return False
    
        def _check_reagents(self, pack=None, gate=False) -> bool:
            '''
            :param pack: если реги в бекпаке, то вызываем пустым, если в мешке, шкатулке, передаём id контейнера
            '''
            if pack is not None:
                self._open_backpack(pack=pack)
            if not gate:
                if any(i < 1 for i in [BPCount(), MRCount(), BMCount()]):
                    print(f'Недостаточно реагентов (BP:{BPCount()}, MR:{MRCount()}, BM:{BMCount()})')
                    return False
            else:
                if any(i < 1 for i in [BPCount(), MRCount(), SACount()]):
                    print(f'Недостаточно реагентов (BP:{BPCount()}, MR:{MRCount()}, SA:{SACount()})')
                    return False
            return True
    
        @staticmethod
        def _check_mana(gate=False) -> bool:
            if not gate:
                if Mana() < 11:
                    print(f"Мало маны! <11 ({Mana()}/{MaxMana()})")
                    return False
            else:
                if Mana() < 40:
                    print(f"Мало маны! <40 ({Mana()}/{MaxMana()})")
                    return False
            return True
    
        def _find_rune(self, rune, runebook_id=None) -> dict | bool:
            '''
            :param runebook_id: если вызывается пустым, присваивается id рунбуки из конструктора, или указать id
            интересующей рунбуки.
            :param rune: принимает номер руны(НЕ индекс) в рунбуке с 1 по 16
            :return: возвращает словарь с номерами гампов
            {"name": "sortir","set_def": 501, "scroll": 601,"drop": 81,"reagent": 2,"gate": 3}
            '''
            if runebook_id is None:
                runebook_id = self._runebook_id
            if _pull := self.get_info_runebook(runebook_id=runebook_id):
                if isinstance(rune, int):
                    if _pull['info']['count_rune'] >= rune - 1:
                        return _pull['gumps'][rune - 1]
                else:
                    for i in _pull['gumps']:
                        if i["name"] in rune:
                            return i
            print(f"Ошибка: руна не найдена")
            return False
    
        def get_info_runebook(self, runebook_id=None) -> dict | bool:
            '''
            :param runebook_id:  если вызывается пустым, присваивается id рунбуки из конструктора, или указать id
            интересующей рунбуки.
            :return: возвращает словарь с общей информацие о рунбуке и гампами.
            {
                "gumps": [{"name": "sortir","set_def": 501, "scroll": 601,"drop": 81,"reagent": 2,"gate": 3}, [...], ...n],
                "info": {'name': Basyan, 'charge': 2, 'charge_max': 10, 'count_rune': 7}
            }
            '''
            if runebook_id is None:
                runebook_id = self._runebook_id
            if self._open_runebook(runebook_id=runebook_id):
                info_gumps = GetGumpInfo(GetGumpsCount() - 1)
                count_rune = int((info_gumps['GumpButtons'][len(info_gumps['GumpButtons']) - 2]['ReturnValue']) / 2)
    
                temp_pull_gump = {'gumps': []}
                for n, i, r in zip(range(7, count_rune + 7), range(1, count_rune + 1), range(2, 99, 2)):
                    temp_pull_gump['gumps'].append({
                        "name": info_gumps['Text'][n][0],
                        "set_def": 500 + i,
                        "scroll": 600 + i,
                        "drop": 80 + i,
                        "reagent": r,
                        "gate": r + 1
                    })
    
                temp_pull_gump.update({"info": {'name': GetTooltip(runebook_id),
                                                'charge': int(info_gumps['Text'][3][0]),
                                                'charge_max': int(info_gumps['Text'][4][0]),
                                                'count_rune': int(count_rune)}})
    
                if runebook_id == self._runebook_id:
                    self.info_runebook = temp_pull_gump
                return temp_pull_gump
            return False
    
        def recall(self, rune, pack=None, reagents=False) -> bool:
            '''
            :param pack: если реги в бекпаке, то вызываем пустым, если в мешке, шкатулке, передаём id контейнера
            :param rune: номер руны в рунбуке (с 1 до 16), 0 - последняя руна или имя руны "sortir" (чувствителен к регистру)
            :param reagents: устой и false рекол по скроллам, если true, рекол по регам
            :return: boolean
            '''
            if _rune := self._find_rune(rune=rune):
                if not reagents:
                    if self.info_runebook['info']['charge'] <= 0:
                        print(f"АХТУНГ: заправь рунбуку. charge "
                              f"{self.info_runebook['info']['charge']}/{self.info_runebook['info']['charge_max']}")
                        return False
                    NumGumpButton(GetGumpsCount() - 1, _rune["scroll"])
                    return True
                else:
                    if self._check_reagents(pack=pack) and self._check_mana():
                        NumGumpButton(GetGumpsCount() - 1, _rune["reagent"])
                        return True
            return False
    
        def gate(self, rune, pack=None) -> bool:
            '''
            :param pack: если реги в бекпаке, то вызываем пустым, если в мешке, шкатулке, передаём id контейнера
            :param rune: номер руны в рунбуке (с 1 до 16), 0 - последняя руна или имя руны "sortir" (чувствителен к регистру)
            :return: boolean
            '''
            if _rune := self._find_rune(rune=rune):
                if self._check_reagents(gate=True, pack=pack) and self._check_mana(gate=True):
                    NumGumpButton(GetGumpsCount() - 1, _rune["gate"])
                    return True
            return False
    
        def recharge(self, scrolls=None) -> bool:
            '''
            :param scrolls: если пустой, то вызовет таргет речерджа или указать ID стопки с рекалами
            :return: boolean
            '''
            if _rune := self.get_info_runebook():
                if self.info_runebook['info']['charge'] < self.info_runebook['info']['charge_max']:
                    if TargetPresent():
                        CancelTarget()
                    NumGumpButton(GetGumpsCount() - 1, 800)
                    for i in range(5):
                        if TargetPresent():
                            if isinstance(scrolls, int):
                                WaitTargetObject(scrolls)
                            break
                        Wait(500)
                return True
            return False
    
        def set_def_rune(self, rune) -> bool:
            '''
            :param rune: номер руны в рунбуке (с 1 до 16), 0 - последняя руна или имя руны "sortir" (чувствителен к регистру)
            :return: boolean
            '''
            if _rune := self._find_rune(rune=rune):
                NumGumpButton(GetGumpsCount() - 1, _rune["set_def"])
                return True
            return False
    
        def drop_rune(self, rune, runebook_id=None) -> int | bool:
            '''
            :param runebook_id: если вызывается пустым, присваивается id рунбуки из конструктора, или указать id
            интересующей рунбуки.
            :param rune: номер руны в рунбуке (с 1 до 16), 0 - последняя руна или имя руны "sortir" (чувствителен к регистру)
            :return: boolean
            '''
            if _rune := self._find_rune(rune=rune, runebook_id=runebook_id):
                while f := FindTypeEx(0x1F14, 0xFFFF, Backpack(), False):
                    Ignore(f)
                NumGumpButton(GetGumpsCount() - 1, _rune["drop"])
                drop_rune = FindTypeEx(0x1F14, 0xFFFF, Backpack(), False)
                IgnoreReset()
                return drop_rune
            return False
    
        def add_rune(self, rune_id: int, runebook_id=None):
            '''
            :param rune_id: id пустой руны
            :param runebook_id: если вызывается пустым, присваивается id рунбуки из конструктора, или указать id
            интересующей рунбуки.
            :return:
            '''
            if self.get_info_runebook(runebook_id=runebook_id):
                if TargetPresent():
                    CancelTarget()
                NumGumpButton(GetGumpsCount() - 1, 1)
                for i in range(5):
                    if TargetPresent():
                        WaitTargetObject(rune_id)
                        break
                    Wait(500)
                return True
            return False
    
    
    def meditation():
        if Mana() < 20:
            while Mana() < MaxMana():
                ct = datetime.now()
                if TargetPresent():
                    CancelTarget()
                UseSkill('Meditation')
                if WaitJournalLine(ct, "You begin to meditate|"
                                       "Вы уже медитируете|"
                                       "You are already meditating|"
                                       "You must wait to perform another action", 10000):
                    while InJournalBetweenTimes("You are unable to concentrate|"
                                                "You stop meditating|"
                                                "I am already performing|", ct, datetime.now()) == -1:
                        Wait(1000)
    
    
    def cast_mark():
        if Connected() and not Dead():
            if TargetPresent():
                CancelTarget()
            if Mana() >= 20:
                meditation()
            Cast('Mark')
            for i in range(8):
                if TargetPresent():
                    return True
                Wait(1000)
        return False
    
    
    def check_blank_rune(count):
        if Connected() and not Dead():
            FindType(0x1F14, Backpack())
            if FindCount() >= count:
                return True
            print(f"В паке рун меньше чем нужно скопировать. Докинь ещё {count - FindCount()}")
        return False
    
    
    def main():
        if Connected() and not Dead():
            _runebook = Runebook(runebook_id=ID_RUNEBOOK)
    
            pull_rune = _runebook.get_info_runebook()
            pull_copy_rune = _runebook.get_info_runebook(ID_CLEAR_RUNEBOOK)
    
            if check_blank_rune(pull_rune['info']['count_rune'] - pull_copy_rune['info']['count_rune']):
                for i in range(pull_copy_rune['info']['count_rune'], pull_rune['info']['count_rune']):
                    if not Connected() or Dead():
                        return
                    if not _runebook.recall(rune=i, reagents=REAGENTS):
                        return
                    Wait(8000)
                    if cast_mark():
                        FindType(0x1F14, Backpack())
                        WaitTargetObject(FindItem())
                        Wait(1000)
                        UseObject(FindItem())
                        UOSay(pull_rune['gumps'][i]['name'])
                        _runebook.add_rune(rune_id=FindItem(), runebook_id=ID_CLEAR_RUNEBOOK)
                    else:
                        return
                if RETURN:
                    _runebook.recall(rune=RETURN, reagents=REAGENTS)
                print('Скопировано.')
    
    
    if __name__ == '__main__':
        # settings
        ID_RUNEBOOK = 0x13D07FEC            # id рунбуки которую хотим скопировать
        ID_CLEAR_RUNEBOOK = 0x13D07FDD      # id пустой рунбуки
        REAGENTS = False                    # если телепорт по скроллам в рунбуке, то оставляйте False, если телепорт по регам, то True
        RETURN = "place1"                   # если надо вернуться домой, то укажите имя руны, или её номер (без ковычек) в рунбуке. Если нет, то False (RETURN = False)
    
        main()

     

    CopyRuneBook.py


  3. stealth version 8.12.7

    Копка песка и глины

    Как запустить:  читать тут

    Что делает:

    • копает песок
    • копает глину\торф
    • жрёт фиш стейки (можно поменять)
    • реконектит

    Инструкция по применению:

    • одеваем чара и даём в лапы ствол, так как есть шанс выкопать элементаля или слизня
    • отводим на место копки
    • кидаем в пак лопату (Shovel)
    • кидаем в пак еду
    FOOD = 0x097B  # Type еды, сейчас фишстейки
    
    • запускаем скрипт

     

    from datetime import datetime, timedelta
    from time import sleep
    from py_stealth import *
    
    ############################## info ################################
    #
    #   Скрипт для копки песка или глины\торфа
    #   Устанавливаем радиус поиска тайлов - RADIUS
    #   Ставим чара на место добычи
    #   * еду в пак - FOOD
    #   * в бекпак кидаем лопату - Shovel
    #   Одеваем чара и даём в руки какой нибудь ствол,
    #   так как есть шанс выкопать элементаля или слизняка
    #
    ###################################################################
    ############################ settings ##############################
    #
    RADIUS = 4
    #
    FOOD = 0x097B  # тип еды, сейчас фишь-стейки \ type food, now fish steaks
    #
    ###################################################################
    
    
    def msg(args):
        print(args)
        ClientPrintEx(0, 60, 2, args)
    
    
    def CheckConnect(waitTimeReconnected=5):
        """
        waitTimeReconnected: wait reconnected time, int >= 1
        """
        if int(waitTimeReconnected) <= 0:
            waitTimeReconnected = 5
        waitTimeReconnected *= 1000
    
        if GetARStatus():
            SetARStatus(False)
    
        if Connected() and not Hidden() and not CheckLag():
            Disconnect()
            Wait(5000)
    
        if not Connected():
            print('# Not connected to server!')
            print('# Reconnected...')
            while not Connected():
                Connect()
                Wait(3000)
                if Connected() and Hidden():
                    UOSay(" ")
                if Connected() and not CheckLag(5000):
                    Disconnect()
                    Wait(waitTimeReconnected)
            Wait(5000)
            print('# Server connection restored.')
    
    
    def WaitTarget(sec=5):
        for i in range(sec):
            if not Connected() or Dead() or TargetPresent():
                break
            Wait(1000)
        if not Connected() or Dead() or not TargetPresent():
            return False
        return True
    
    
    def evSpeech(_text, _senderName, _senderID):
        # Check Save World
        if _senderID == 16843009 and _text == 'Saving World State':
            eventTime = datetime.now()
            msg(f"{_senderName}: {_text}")
            for i in range(15):
                if InJournalBetweenTimes('Saving World State complete.', eventTime, datetime.now()) != 1:
                    break
                sleep(1)
    
    
    class Hungry:
        def __init__(self, food=0x097B, timer=10):
            """
            Ищем еду в бекпаке, если не нашли, ищем в банке, потом на полу
            (при поиске в банке, бонк должен быть предварительно открыт)
            food: сейчас фишстейки или указать тип еды
            timer: через сколько докармливать чара
            """
            self._food = food
            self._nextTime = datetime.now()
            self._timer = timer
    
        def __call__(self):
            if datetime.now() >= self._nextTime:
                place = [Backpack(), ObjAtLayer(BankLayer()), Ground()]
                ct = datetime.now()
                f = False
                while InJournalBetweenTimes("Я объелся|You are full", ct, datetime.now()) == -1:
                    if Connected() and not Dead():
                        for i in place:
                            if f := FindType(self._food, i):
                                if TargetPresent():
                                    CancelTarget()
                                ct = datetime.now()
                                UseObject(f)
                                Wait(300)
                                break
                        if not f:
                            msg("Attention!: Food not found!")
                            break
                    else:
                        return
                self._nextTime = datetime.now() + timedelta(minutes=self._timer)
    
    
    class Processed:
        def __init__(self, _range=4):
            self._range = _range
            self._sand = [22, 23, 24, 25, 26, 27, 28, 35, 39, 52, 53, 54, 56,
                          57, 58, 59, 60, 61, 88, 92, 95, 96, 100]
            self._peat = [15810, 15811, 15825, 15832, 15835, 15836, 15837, 15838, 15839, 15840, 15841, 15842, 15843,
                          15844, 15845, 15846, 15848, 15849, 15850, 15851, 15852, 15853, 15854, 15855, 15856]
            self._arrWorkTile = []  # dict {'x': x, 'y': y, 'z': z}
            self._shovel = None
            self._lastIndex = None
    
        def __call__(self):
            CheckConnect()
            if not Hidden() and not CheckLag():
                Disconnect()
                Wait(5000)
            if Connected():
                if Dead():
                    msg('Character is dead!')
                    return False
                if LastContainer() != Backpack():
                    for i in range(5):
                        UseObject(Backpack())
                        if LastContainer() == Backpack():
                            break
                        Wait(1000)
                    if LastContainer() != Backpack():
                        msg("I can't open my backpack")
                        return False
                if not self.__CheckShovel():
                    msg('Not found tool (SHovel)!')
                    return False
                if not len(self._arrWorkTile):
                    if not self.__GetTile():
                        print(f'Not found tiles!')
                        return False
                    msg(f'Found {len(self._arrWorkTile)} tiles.')
            if not WarMode():
                SetWarMode(True)
            return True
    
        def __CheckShovel(self):
            if f := FindType(0x0F39, Backpack()):
                self._shovel = f
                return True
            return False
    
        def __GetTile(self):
            _allTypeTile = self._sand + self._peat
            for x in range(GetX(Self()) - self._range, GetX(Self()) + self._range + 1):
                for y in range(GetY(Self()) - self._range, GetY(Self()) + self._range + 1):
                    if cell := GetCell(x, y, WorldNum()):
                        try:
                            if _allTypeTile.index(cell['Tile']):
                                cell['x'] = x
                                cell['y'] = y
                                self._arrWorkTile.append({'x': cell['x'], 'y': cell['y'],
                                                          'z': cell['Z'], 't': cell['Tile']})
                                pass
                        except ValueError:
                            pass
            if len(self._arrWorkTile):
                return True
            return False
    
        def Mining(self):
            if Connected() and not Dead():
                ct = datetime.now()
                if not TargetPresent():
                    UseObject(self._shovel)
                if WaitTarget():
                    if self._lastIndex is None:
                        self._lastIndex = 0
                    _i = self._lastIndex
                    x, y, z = self._arrWorkTile[_i]['x'], self._arrWorkTile[_i]['y'], self._arrWorkTile[_i]['z']
                    if not newMoveXY(x, y, False, 2, True):
                        self._arrWorkTile.pop(_i)
                        return
                    TargetToXYZ(x, y, z)
                    for i in range(15):
                        Wait(2000)
                        UseObject(self._shovel)
                        if not Connected() or Dead() or TargetPresent():
                            break
                    if InJournalBetweenTimes('There is nothing to dig here|'
                                             'You fail to|'
                                             'There is no brimstone', ct, datetime.now()) != -1:
                        if FoundedParamID() == 0:
                            msg(f'DELETE type "{self._arrWorkTile[_i]["t"]} in script! 118 or 120 line!"')
                        if self._lastIndex >= len(self._arrWorkTile) - 1:
                            self._lastIndex = 0
                        else:
                            self._lastIndex += 1
    
    
    if __name__ == '__main__':
        SetMoveCheckStamina(0)
        SetMoveThroughNPC(0)
        SetEventProc('evSpeech', evSpeech)
        _p = Processed(RADIUS)
        _hungry = Hungry(FOOD)
        while _p():
            _p.Mining()
            _hungry()
        msg("End script")
        Disconnect()

     

    Mining_SAND_or_PEAT.py


  4. Как запустить скрипты написанные на языке Python?
    файлы с расширением .py например fishing.py

    FAQ ориентирован на пользователей Windows, Линуксоводы и так в курсе что и как :)


    !!! АХТУНГ !!! Все параметры в Python связанные с серийником(ID), типом(type) или цветом(color) и т.п, вводятся через 0x (в hex формате)
    то есть: в Stealth вся инфа выглядит так: $097B, $73A3DA2E
    просто убираем знак доллара($) и вставляем на его место 0x, получаем 0x097B, 0x73A3DA2E

    Ссылки:
    Сайт Python: https://www.python.org/
    Скачать: https://www.python.org/downloads/windows/
    v 3.9.x для Windows 8.1 и выше
    v 3.8.x для Windows 7
    v 3.4.x и старше для Windows XP

    1. Определяем какая у Вас винда и разрядность
      правый клик мышки на "Мой компьютер" ---> "Свойства":
      в окне "Просмотр основных сведений о вашем компьютере"

      Screenshot_3.png.556311d43924cf11b7a1e88526c2838f.png
    2. Качаем соответствующую версию питончика тЫк
      Screenshot_1.png.651a819e88534acbcb6ac1f2b0dd847a.png

       
    3. Устанавливаем
      windows-setup-run-the-python-installer.jpg.242c5d27db1a69271df3141a370a59d2.jpg
      1. Ставим галочку на Add Python 3.5 to PATH
      2. Указываем дерикторию установки (можно оставить как есть)
       
    4. Проверяем правильно ли установился питон:
      Ctrl+R ---> cmd
      В появившемся окне Командной строки вводим команду: pip
      Если выводи что то на подобии этого:
      Screenshot_2.png.58bb6cc8c7b9d5eaee74ad34665a2b2e.png

      Значит установка прошла успешна!

      Если посыпались ошибки, попробуйте удалить питон и переустановить с правами Администратора:
      правый клик на экзешник -> запустить от имени администратора

    Собственно на этом процесс установки и настройки закончен, теперь у Вас будут работать скрипты на языке Python


  5. Ссылки:

     

    Инструкция по настройке Stealth под наш шард:

    Запускаем Stealth.exe

    В основном окне стелса нажимаем на иконку «

    1.png.7f18e1cdd5078239a26725c12ab2a4b4.png

     

    В появившемся окне «Profiles setup» жмём на иконку «2»

    2.png.1841febc15e3e6dd67fd05e0d23d4598.png

     

    В появившемся окне «Shards setup» жмём на иконку «3»

    Screenshot_1.png.5d1cf65732286c989ad90fc45e8e1c05.png

     

    В появившемся окне «4»:

    1. В «Name» вводим имя настройки(на свой выбор)
    2. Жмём на иконку папки и указываем клиент в директории  UO
      на сегодня это client403.exe
    3. Выставляем галочки в чек-боксах как на скрине
    4. Жмём большой, зелёный плюс
    5. Жмём «OK(+Save)» потом «Closed»

    Screenshot_2.png.fd611bd54bc820b8875383319b92c754.png

     

    В окне «Shards setup»:

    1. В «Name» вводим имя сервера: middle-earth
    2. В «Address» IP сервера или доменное имя: middle-earth.ru
    3. В «Port» соответственно порт сервера: 5005
    4. В «Client version» вводим версию клиента. Cтавим то, что выставляли в предыдущем окне, если 403, то и ставим 4 0 3 0
    5. Жмём на иконку папки и указываем директории  UO
    6. В «Select Client» выбираем нужный Вам клиент
    7. Жмём кнопку «Add»
    8. Жмём «Save» и «Close»

    Screenshot_3.png.221f844164362693747d20f0226ad1d1.png

     

    В окне «Profiles setup» :

    1. «Name» имя профиля
    2. «Login» логин аккаунта
    3. «Pass» пароль аккаунта
    4. «Shard» выбираем шард
    5. Жмём большой, зелёный плюсик
    6. Жмём «Save» и «Close»

    Screenshot_4.png.c3fc8b220c30b66e949272b12e82c582.png

     

    В основном окне стелса:

    1. Добавляет активный профиль в бар чаров ниже
      правее можно:
      сохранить, выбрать, загрузить или удалить набор профилей
      поменять местами профили(выше-ниже)
       
    2. Собственно сам бар чаров
      что бы что то делать с чаром (залогиниться, дисконектнуться, посмотреть инфу по закладкам, запустить скрипт на чаре),
      нужно выделить профиль в баре чаров(тупо кликнуть по профилю)
       
    3. Выбор профиля чара
       
    4. «Connect» - залогиться на сервер
      «Disconnect» - дисконектнуться с сервера
      «Auto» - авто реконект на сервер
      «120» - тайм аут релогина (сколько ждать в секунда до начала авто реконекта)
       
    5. Загрузить  скрипт (у скриптов на паскале расширение файла .sc, у питона .py)
    6. Запустить, поставить на паузу или остановить скрипт
    7. Настройки стелса

    Screenshot_5.png.3d570794b821c4a1d86e370a560c39af.png

     

    Жмём на шестерёнку  в главном окне «7»
    Закладки:

    • Commo
      Use Art.mul для отображения изображений объектов на вкладке World в основном окне стела
      unknown.png.f039c24e50ece92140d797c956d92d62.png


      Enable Map включить отображение карты (вкладка «Map»)
      Messages from Move r in Sysjournal в системный журнал(System Journal) будет приходить информация вида:
      Screenshot_10.png.38e91a136bf50e1c84c948dac41dcbfc.png

      Minimize to tray при сворачивании, стелс будет ходить в трей (с права, в низу, там где часы)
      Always On Top стелс всегда по верх окон
      Группа CharItem Height высота элементов Char в CharsList (левая часть окна Stealth, бар-чаров) - нормальная или маленькая
      Группа Tray Icon изменяет иконку по умолчанию в трее на другой
      Check update проверка обновлений в ручную (по умолчанию проверяется один раз в день при запуске стелса)
      Hide Stealth скрыть иконку стеклса в системном трее (что бы иконка появилась, нажмите сочетание клавиш клавиш Ctrl + Alt + Shift + S).
      Screenshot_6.png.4b8375e6595e6456e95ddd0e3e8cbd88.png
    • Journal
      Show Cliloc text in journal отображать текст из файла cliloc.
      Если отключено - сообщения будут отображаться в формате «cliloc # XXXXXXXX, где XXXXXXXX - идентификатор Cliloc.
      Color in Journal окрашивает сообщения чата в цвет который отсылает сервер (в закладке UOJournal)
       если отключено, все сообщения будут одним цветом(пм, общий чат, .f и т.д.)
      Save journal background color сохранять пользовательский цвет журнала (в закладке UOJournal)
      Группа Show in Journal по моему у нас не работает (я не проверял)
      Screenshot_9.png.6c53b3116ce8025e2dc7a11e8e6fa735.png
       
    • Server

      Port порт для сервера (Вы можете сами запустить клиент и подключиться к этому порту)
      Log Client-Stealth packets сохранять всю связь между клиентом и Stealth
      Send Extended Messages To Client отправлять клиенту сообщения типа «Target \ Menu \ Gump»
      Allow to connect only from LocalHost разрешить подключение к серверу только с вашего ПК.
      Если отключено - для удаленного подключения необходимо установить логин и пароль.
      Если Включено - логин и пароль могут быть ЛЮБЫМИ.

      Full Mode включить все настройки группы Setup mode
      Setup mode 
      Moving On разрешить движение от клиента
      Gumps&Menus On разрешить отправку гампов и меню клиенту
      Target On разрешить отправку целей клиенту
      Other packets On все остальные пакеты

      Client Dll Settings group группа параметров, влияющая только на клиента
      Use DLL включить стелсовский assistant
      Fast Login быстрый старт (без окна логин-пароль, выбор сервера, выбор чара)
      Show Dll Window показывать окно assistanta
      Draw custom caption разрешить изменять заголовок окна
      Fix caption in client исправление заголовка окна

      Use original assistant для корректной работы assistanta на ClassicUO

    Screenshot_7.png.9feddc257ec43daee43a55f221a72403.png

     

    • Logs

      Save packets log записывать сетевые пакеты Stealth-сервера в файл с именем% profilename% _packets.log в папке журналов

      Save debug log записать в файл всю отладочную информацию

      Logs Path путь к папке куда сохранять лог файлы
      !!!  АХТУНГ !!! лучше сделать отдельную папку LOGS в папке стелса, что бы все логи чаров уходили туда
      логов там на каждого чара по 3 файла(они тупо зафлудят корневой каталог):
      _sysjournal.log
      _packets.log
      _journal.log
      по дефолту, логи сохраняются в корневой папке стелса, если у Вас куча чаров, то папка будет ВСЯ в текстовых файлах...
      а так, будут лежать отдельной кучкой

      Log compressed packets включать в журналы пакетов сжатые (необработанные) пакеты.
      Должен быть включен только в целях отладки.

    Screenshot_8.png.dd297c8098c70923323a767b8403c59c.png

     


  6. stealth version 8.12.7

    Прокачка Meditation с dragon шмотками. Новый!

    Как запустить:  читать тут

    Что делает:

    • снимает-одевает dragon шмот (кнут в том числе)
    • медитирует
    • жрёт фиш стейки (можно поменять)
    • реконектит

    Инструкция по применению:

    • кидаем в пак еду
    FOOD = 0x097B  # Type еды, сейчас фишстейки
    • одеваем в dragon вещи + кнут(если есть)
    • запускаем скрипт
    from py_stealth import *
    from datetime import datetime, timedelta
    """
    Устанавливаем настройки ниже, одеваем чара в драгон, запускаем скрипт
    """
    SKILL = 100  # Предел прокачки скила
    FOOD = 0x097B  # Type еды, сейчас фишстейки
    DELAY = 150  # Задерка после снятия\одевания вещи (в мс)
    
    
    # include start
    def msg(Message):
        print(Message)
        ClientPrintEx(0, 60, 2, Message)
    
    
    def CheckConnect(WaitTime=15000):
        if Connected() and Hidden():
            for i in range(0, 10):
                if Hidden():
                    UOSay(' ')
                    Wait(500)
                else:
                    break
        if Connected() and not Hidden() and not CheckLag(WaitTime):
            Disconnect()
            Wait(5000)
        if not Connected():
            print('CheckConnect.py : Not connected to server!')
            print('CheckConnect.py : Reconnected...')
            while not Connected():
                Connect()
                for i in range(0, 10):
                    if Hidden():
                        UOSay(' ')
                        Wait(500)
                    else:
                        break
                CheckLag(5000)
                if Connected() and not Hidden() and not CheckLag(8000):
                    Disconnect()
            print('CheckConnect.py : Server connection restored.')
            return False
        return True
    
    
    def CheckSave():
        Time = datetime.now() - timedelta(0, 30)
        if InJournalBetweenTimes('Saving World State', Time, datetime.now()) >= 0:
            Wait(30000)
    
    
    def OpenPack(Container=None):
        """
        :param Container: if "None": Backpack self, or set ID Container
        :return: if open True, else not False
        """
        if Container is None:
            Container = Backpack()
        while LastContainer() != Container:
            if not Connected() or Dead():
                msg("#ERROR: {OpenPack} not connected or you dead")
                return False
            CheckSave()
            UseObject(Container)
            for i in range(5):
                if LastContainer() == Container:
                    break
                Wait(1000)
        return True
    
    
    class Hungry:
        def __init__(self, food=0x097B, place=None, timer=10):
            """
            food: сейчас фишстейки или указать тип еды
            place: место поиска еды
            timer: через сколько докармливать чара
            """
            if place is None:
                self._place = Backpack()
            else:
                self._place = place
            self._food = food
            self._nextTime = datetime.now()
            self._timer = timer
    
        def Hungry(self):
            if datetime.now() >= self._nextTime:
                OpenPack()
                while f := FindType(self._food, self._place):
                    CheckConnect()
                    CheckSave()
                    td = datetime.now()
                    UseObject(f)
                    if WaitJournalLineSystem(td, "Я объелся|You are full, and can't eat nothing more.", 750):
                        self._nextTime = datetime.now() + timedelta(minutes=self._timer)
                        break
                else:
                    msg("Warning: Food not found!")
    
    
    # include finish
    
    class Layer:
        def __init__(self):
            self._layer = [1, 5, 23, 4, 19, 10, 6, 7, 13, 3]
            self.__CheckEquip()
    
        @property
        def Equip(self):
            return len(self._layer)
    
        def __CheckEquip(self):
            CheckConnect()
            for i in self._layer.copy():
                if f := ObjAtLayer(i):
                    if "Dragon" not in GetTooltip(f):
                        self._layer.remove(i)
                else:
                    self._layer.remove(i)
            if len(self._layer):
                SetDress()
            else:
                msg("На чаре нет одежды...")
    
    
    def CheckSkill():
        CheckConnect()
        if GetSkillValue("Meditation") >= SKILL:
            msg(f"Стоп-отметка! Скилл 'Meditation' прокачен до: {SKILL}")
            return True
        return False
    
    
    def Meditation():
        while Mana() < MaxMana():
            CheckConnect()
            CheckSave()
            ct = datetime.now()
            UseSkill("Meditation")
            if WaitJournalLineSystem(ct, "You begin to meditate|Вы уже медитируете|You are already meditating", 5000):
                WaitJournalLineSystem(ct, "You are unable to concentrate.|You stop meditating", 30000)
    
    
    def Main():
        while not Dead() and not CheckSkill():
            h.Hungry()
            Meditation()
            if not Undress():
                Disconnect()
            CheckConnect()
            CheckSave()
            EquipDressSet()
    
    
    if __name__ == '__main__':
        SetARStatus(False)
        SetPauseScriptOnDisconnectStatus(False)
        SetDressSpeed(DELAY)
        SKILL_VALUE = 100
        h = Hungry(food=FOOD)
        l = Layer()
        if l.Equip:
            Main()
        msg("End script.")
        Disconnect()

     

     

    Meditation.py


  7. stealth version 8.11.4

    Фишинг с берега. Новый!

    Как запустить:  читать тут

    Что делает:

    • ловит рыбу удочкой
    • ничего не скидываем (карты, соски, обувь остаётся в паке)
    • жрёт
    • авто реконект (советую не включать встроенный столсовский реконектор, так как он имеет неприятную особенность зависать при длительных падениях сервака, да и на скрипты это влияет так себе...)

     

    Инструкция по применению:

    • кидаем чару в пак удочки и еду(если надо, меняем на свой тип)
    FOOD = 0x097B  # Type еды, сейчас фишстейки
    • ставим возле берега
    • запускаем скрипт
    • следим за появлением капчи и появлением красно\серых упырей
    from datetime import datetime, timedelta
    from py_stealth import *
    """
    в бекпак еду, удочки
    встаём возле берега и запускаем скрипт
    """
    POLE = 0x0DBF
    RANGE = 6
    FOOD = 0x097B  # Type еды, сейчас фишстейки
    
    
    def msg(Message):
        print(Message)
        ClientPrintEx(0, 60, 2, Message)
    
    
    def DCC(message, TimeWait=15000):
        if Dead() or not Connected() or not CheckLag(TimeWait):
            print(f"{message}: You dead, or something else!")
            return False
        return True
    
    
    def CheckConnect(WaitTime=15000):
        if Connected() and Hidden():
            for i in range(0, 10):
                if Hidden():
                    UOSay(' ')
                    Wait(500)
                else:
                    break
        if Connected() and not Hidden() and not CheckLag(WaitTime):
            Disconnect()
            Wait(5000)
        if not Connected():
            print('CheckConnect.py : Not connected to server!')
            print('CheckConnect.py : Reconnected...')
            while not Connected():
                Connect()
                for i in range(0, 10):
                    if Hidden():
                        UOSay(' ')
                        Wait(500)
                    else:
                        break
                CheckLag(5000)
                if Connected() and not Hidden() and not CheckLag(8000):
                    Disconnect()
            print('CheckConnect.py : Server connection restored.')
            return False
        return True
    
    
    def CheckSave():
        Time = datetime.now() - timedelta(0, 30)
        if InJournalBetweenTimes('Saving World State', Time, datetime.now()) >= 0:
            Wait(30000)
    
    
    def OpenPack(Container=Backpack()):
        while LastContainer() != Container:
            if DCC(OpenPack):
                break
            CheckSave()
            UseObject(Container)
            end = 0
            while end >= 5:
                if LastContainer() == Backpack():
                    break
                Wait(1000)
                end += 1
    
    
    def Hungry(food=0x097B, place=Backpack()):  # food default "fish steaks", search in you backpack
        while True:
            if Dead() or not Connected() or not CheckLag():
                print("Hungry: You dead, or not connected or hard lags!")
                return False
            if f := FindType(food, place):
                ct = datetime.now()
                UseObject(f)
                Wait(1000)
                if WaitJournalLine(ct, 'Я объелся', 700):
                    return True
            else:
                print("Hungry: not found food!")
                return False
    
    
    def CheckPole():
        if not CheckConnect() or Dead():
            return False
        CheckSave()
        if LastContainer() != Backpack():
            OpenPack()
        if GetType(ObjAtLayer(RhandLayer())):
            Disarm()
        if GetType(ObjAtLayer(LhandLayer())) == POLE:
            return ObjAtLayer(LhandLayer())
        if FindType(POLE, Backpack()):
            return FindItem()
        else:
            print('ERROR: у меня нет инструмента')
            return False
    
    
    def CheckTile(x, y):
        tile = [0, 6038, 6039, 6040, 6041, 6042, 6043, 13422, 13423, 13424, 13425, 13426, 13427, 13428,
                13429, 13430, 13431, 13432, 13433, 13434, 13435, 13436, 13437, 13438, 13439, 13440,
                13441, 13442, 13443, 13444, 13456, 13457, 13458, 13459, 13460, 13461, 13462, 13463,
                13464, 13465, 13466, 13467, 13468, 13469, 13470, 13471, 13472, 13473, 13474, 13475,
                13476, 13477, 13478, 13479, 13480, 13481, 13482, 13493, 13494, 13495, 13496, 13497,
                13498, 13499, 13500, 13501, 13502, 13503, 13504, 13505, 13506, 13507, 13508, 13509,
                13510, 13511, 13512, 13513, 13514, 13515, 13516, 13517, 13518, 13519, 13520, 13521,
                13522, 13523, 13524, 168, 169, 170, 310, 16368, 16369, 16370, 168, 169, 170, 171, 310, 311]
        r = ReadStaticsXY(x, y, WorldNum())
        for i in tile:
            if len(r) <= 0:
                return False
            if r[len(r) - 1].get('Tile') == i:
                return r[len(r)-1]
        return False
    
    
    def CheckCaptcha(pole):
        while IsGump():
            g = GetGumpInfo(GetGumpsCount() - 1)
            if g.get('Text')[0][0].find("капча"):
                msg(">>>>>>>> Нужно ввести капчу!\n"
                    "если клиент был закрыт и при заходе клиентом капчи нет, просто юзани удочку...")
                while IsGump():
                    Wait(1000)
                msg(">>>>>>>> отлично продолжаем...")
            if not TargetPresent():
                UseObject(pole)
                Wait(1000)
    
    
    def Fishing(x, y, z, tile):
        while True:
            CheckConnect()
            if Dead():
                msg('Чар мёртв')
                return False
            if pole := CheckPole():
                Hungry()
                if TargetPresent():
                    CancelTarget()
                ct = datetime.now()
                while not TargetPresent():
                    CheckSave()
                    CheckLag()
                    UseObject(pole)
                    CheckCaptcha(pole)
                    WaitForTarget(2500)
                if WaitForTarget(2500):
                    WaitTargetTile(tile, x, y, z)
                    if WaitJournalLineSystem(ct, "Fishing шанс на успех|There doesn't", 15000):
                        if InJournalBetweenTimes("There doesn't", ct, datetime.now()) != -1:
                            return True
            else:
                return False
    
    
    def main():
        while True:
            CheckConnect()
            if Dead():
                msg('Чар мёртв')
                return
            ct = 0
            for x in range(GetX(Self())-RANGE, GetX(Self())+RANGE):
                for y in range(GetY(Self())-RANGE, GetY(Self())+RANGE):
                    if CheckTile(x, y):
                        ct += 1
            if ct <= 0:
                msg(f'ERROR: Не вижи тайлов для ловли в радиусе: {RANGE}')
                return
            for x in range(GetX(Self())-RANGE, GetX(Self())+RANGE):
                for y in range(GetY(Self())-RANGE, GetY(Self())+RANGE):
                    if coord := CheckTile(x, y):
                        if not Fishing(coord.get('X'), coord.get('Y'), coord.get('Z'), coord.get('Tile')):
                            return False
    
    
    if __name__ == '__main__':
        main()
        if Connected():
            Disconnect()
        msg('END SCRIPT!')

     


  8. stealth version 8.11.4

    Фишинг с лодки. Новый!

    Как запустить:  читать тут

    Чем богат?:

    • ловит рыбу удочкой
    • скидывает на пол всю пойманную обувь
    • жрёт
    • авто реконект (советую не включать встроенный столсовский реконектор, так как он имеет неприятную особенность зависать при длительных падениях сервака, да и на скрипты это влияет так себе...)
    • бегает к трешбочке что бы утилизировать по всем канонам гринписа: сос бутылки, карты, старые сети... моё время
    • после похода к бочке, понуро плетётся к трюму за новой удочкой
    • ну и самостоятельно (как взрослый мальчик) возвращается на своё место и продолжает рыбачить

     

    Инструкция по применению:

    • отплываем на лодке от берега на 1-2 экрана (30-40 тайлов)
    • забиваем трюм лодки удочками
    • ставим треш бочку на лодке
    • в рыбаков суём жареные фишстейки(если что то другое, указываем в скрипте)
    FOOD = 0x097B  # Type еды, сейчас фишстейки
    • запускаем скрипт
    • ???
    • profit

    АХТУНГ! При появлении капчи действие скрипта я не проверял, но запилил реакцию, так что при нахождении бага, пишите да поможет вам бог.

    from datetime import datetime, timedelta
    from py_stealth import *
    
    FOOD = 0x097B  # Type еды, сейчас фишстейки
    
    
    def msg(Message):
        print(Message)
        ClientPrintEx(0, 60, 2, Message)
    
    
    def DCC(message, TimeWait=15000):
        if Dead() or not Connected() or not CheckLag(TimeWait):
            print(f"{message}: You dead, or something else!")
            return False
        return True
    
    
    def CheckConnect(WaitTime=15000):
        if Connected() and Hidden():
            for i in range(0, 10):
                if Hidden():
                    UOSay(' ')
                    Wait(500)
                else:
                    break
        if Connected() and not Hidden() and not CheckLag(WaitTime):
            Disconnect()
            Wait(5000)
        if not Connected():
            print('CheckConnect.py : Not connected to server!')
            print('CheckConnect.py : Reconnected...')
            while not Connected():
                Connect()
                for i in range(0, 10):
                    if Hidden():
                        UOSay(' ')
                        Wait(500)
                    else:
                        break
                CheckLag(5000)
                if Connected() and not Hidden() and not CheckLag(8000):
                    Disconnect()
            print('CheckConnect.py : Server connection restored.')
            return False
        return True
    
    
    def CheckSave():
        Time = datetime.now() - timedelta(0, 30)
        if InJournalBetweenTimes('Saving World State', Time, datetime.now()) >= 0:
            Wait(30000)
    
    
    def OpenPack(Container=Backpack()):
        while LastContainer() != Container:
            if DCC(OpenPack):
                break
            CheckSave()
            UseObject(Container)
            end = 0
            while end >= 5:
                if LastContainer() == Backpack():
                    break
                Wait(1000)
                end += 1
    
    
    def Hungry():  # food default "fish steaks", search in you backpack
        while True:
            if Dead() or not Connected() or not CheckLag(15000):
                print("Hungry: You dead, or not connected or hard lags!")
                return False
            OpenPack()
            FindType(FOOD, Backpack())
            if FindCount() <= 0:
                print("Hungry: not food!")
                return
            ct = datetime.now()
            if TargetPresent():
                CancelTarget()
            UseObject(FindItem())
            if not WaitJournalLine(ct, 'Я объелся', 5000):
                Wait(100)
            else:
                return True
    
    
    def DropTrash(board):
        # Drop boots
        boot = [0x170A, 0x170B, 0x170C, 0x170D, 0x170E, 0x170F, 0x1710, 0x1711]
        for i in boot:
            CheckConnect()
            while f := FindType(i, Backpack()):
                if not CheckLag():
                    break
                DropHere(f)
    
        # Drop trash
        trash = [0x0DC8,  # сети
                 0x14ED,  # карты
                 0x099F]  # бутылки
        while trashBarrel := FindType(0x0E77, Ground()):
            x, y = GetX(trashBarrel), GetY(trashBarrel)
            if board[0]['XMin'] <= x <= board[0]['XMax'] and board[0]['YMin'] <= y <= board[0]['YMax']:
                if newMoveXY(x, y, False, 1, True):
                    break
                else:
                    Ignore(trashBarrel)
        if trashBarrel <= 0:
            msg("ERROR: не вижу или не могу добраться до Trash barrel!")
            return False
        for i in trash:
            CheckConnect()
            while f := FindType(i, Backpack()):
                if not CheckLag():
                    break
                MoveItem(f, 1, trashBarrel, 0, 0, 0)
    
    
    def GetPole():
        CheckConnect()
        CheckSave()
        board = GetMultis()
        fX, fY = GetX(Self()), GetY(Self())
        DropTrash(board)
        while hold := FindType(0x3E65, Ground()):
            x, y = GetX(hold), GetY(hold)
            if board[0]['XMin'] <= x <= board[0]['XMax'] and board[0]['YMin'] <= y <= board[0]['YMax']:
                if not newMoveXY(x, y, False, 1, True):
                    msg(f"ERROR: не могу добраться до трюма x:{x}, y{y}")
                    return False
                else:
                    break
        if LastContainer() != hold:
            UseObject(hold)
            for i in range(5):
                Wait(1000)
                if LastContainer() == hold:
                    break
            if i >= 5 and LastContainer() != hold:
                msg(f"ERROR: не могу открыть трюм x:{GetX(hold)}, y:{GetY(hold)}")
                return False
        if FindType(0x0DBF, hold):
            MoveItem(FindItem(), 1, Backpack(), 0, 0, 0)
            newMoveXY(fX, fY, False, 0, True)
            return FindItem()
        else:
            print('ERROR: в трюме нет удочек, мне нечем ловить!')
            return False
    
    
    def CheckPole():
        if not CheckConnect() or Dead():
            return False
        CheckSave()
        if LastContainer() != Backpack():
            OpenPack()
        if GetType(ObjAtLayer(RhandLayer())):
            Disarm()
        if GetType(ObjAtLayer(LhandLayer())) == 0x0DBF:
            return ObjAtLayer(LhandLayer())
        if FindType(0x0DBF, Backpack()):
            return FindItem()
        if pole := GetPole():
            return pole
        return False
    
    
    def CheckCaptcha(pole):
        while IsGump():
            g = GetGumpInfo(GetGumpsCount() - 1)
            if g.get('Text')[0][0].find("капча"):
                msg(">>>>>>>> Нужно ввести капчу!\n"
                    "если клиент был закрыт и при заходе клиентом капчи нет, просто юзани удочку...")
                while IsGump():
                    Wait(1000)
                msg(">>>>>>>> отлично продолжаем...")
            if not TargetPresent():
                UseObject(pole)
                Wait(1000)
    
    
    def Fishing(x, y, z):
        while True:
            CheckConnect()
            if Dead():
                msg('Чар мёртв')
                return False
            if pole := CheckPole():
                Hungry()
                if TargetPresent():
                    CancelTarget()
                while not TargetPresent():
                    CheckSave()
                    CheckLag()
                    while IsGump():
                        CloseSimpleGump(GetGumpsCount()-1)
                    UseObject(pole)
                    CheckCaptcha(pole)
                    WaitForTarget(2500)
                ct = datetime.now()
                if WaitForTarget(2500):
                    WaitTargetXYZ(x, y, z)
                    if WaitJournalLine(ct, "Fishing шанс на успех|There doesn't", 60000):
                        if InJournalBetweenTimes("There doesn't", ct, datetime.now()) != -1:
                            return True
            else:
                return False
    
    
    def GetTiles():
        typeTile = [168, 169, 170, 171, 310, 311]
        array = []
        board = GetMultis()
        for x in range(GetX(Self()) - 6, GetX(Self()) + 6):
            for y in range(GetY(Self()) - 6, GetY(Self()) + 6):
                if (x > board[0]['XMax'] or x < board[0]['XMin']) and (y > board[0]['YMax'] or y < board[0]['YMin']):
                    tile = GetCell(x, y, WorldNum())
                    for t in typeTile:
                        if tile['Tile'] == t:
                            array.append({'X': x, 'Y': y, 'Z': tile['Z']})
                            break
        return array if len(array) else False
    
    
    def main():
        while True:
            CheckConnect()
            if Dead():
                msg('Чар мёртв')
                return
            arrayTile = GetTiles()
            if not len(arrayTile):
                msg(f'ERROR: Не вижи тайлов для ловли в радиусе: 6 тайлов')
                return
            for tile in arrayTile:
                if not Fishing(tile['X'], tile['Y'], tile['Z']):
                    return False
    
    
    if __name__ == '__main__':
        SetFindDistance(10)
        SetFindVertical(10)
        SetMoveOpenDoor(True)
        SetMoveCheckStamina(0)
        SetMoveThroughNPC(0)
        main()
        if Connected():
            Disconnect()
        msg('END SCRIPT!')
        SetARStatus(False)
        Disconnect()

     


  9. stealts v. 8.11.4

    Как запустить:  читать тут

     

    Собственно сабж

    Чар берёт из банка нужное кол-во логов для 1 крафта - крафтит вещь, если не получилось, добирает логов, если получилось скидывает удочку\ки в банк
    сам жрёт, сам реконектится

    Никаких счётчиков на кол-во скрафченных вещей нет! Будет пилить эти палки пока есть из чего!


    Оставить чара в Ньюби Городе, в пак ему кинуть щипцы тинкертулса, в банк закинуть жареной рыбки
    если хотите что бы чар с начало кидал удочки в контейнер в банке, указать ID контейнера в:

    CONTAINER = 0x69F8D06A  # указать ID контейнера в банке иначе будет кидать в банк

    После того как контейнер заполнится, будет складывать всё в банк под завязку, ну или пока не кончатся логи.

    Логи должны быть ПРОСТЫЕ!

     

    from py_stealth import *
    from datetime import datetime as dt
    from datetime import timedelta
    
    CONTAINER = 0x69F8D06A  # указать ID контейнера в банке иначе будет кидать в банк
    
    
    def CheckSave():
        Time = dt.now() - timedelta(0, 30)
        if InJournalBetweenTimes('Saving World State', Time, dt.now()) >= 0:
            Wait(30000)
            return False
        return True
    
    
    def Hungry(food=0x097B, place=Backpack()):  # food default "fish steaks", search in you backpack
        while True:
            if Dead() or not Connected() or not CheckLag(15000):
                print("Hungry: You dead, or not connected or hard lags!")
                return False
            FindType(food, place)
            if FindCount() <= 0:
                print("Hungry: not food!")
                return
            ct = dt.now()
            UseObject(FindItem())
            Wait(1000)
            if InJournalBetweenTimes('Я объелся', ct, dt.now()) != -1:
                return True
    
    
    def OpenPack(Container=Backpack()):
        while LastContainer() != Container:
            if Dead() or not Connected() or not CheckLag():
                print("OpenPack: You dead, or something else!")
                break
            CheckSave()
            UseObject(Container)
            end = 0
            while end >= 5:
                if LastContainer() == Backpack():
                    break
                Wait(1000)
                end += 1
    
    
    def msg(Message):
        print(Message)
        ClientPrintEx(0, 60, 2, Message)
    
    
    def CheckConnect(WaitTime=15000):
        for i in range(0, 10):
            if Hidden():
                UOSay(' ')
                Wait(500)
            else:
                break
        if Connected() and not CheckLag(WaitTime):
            Disconnect()
            Wait(5000)
        if not Connected():
            print('CheckConnect.py : Not connected to server!')
            print('CheckConnect.py : Reconnected...')
            while not Connected():
                Connect()
                CheckLag(5000)
                if Connected() and not CheckLag(8000):
                    Disconnect()
            print('CheckConnect.py : Server connection restored.')
            return False
        return True
    
    
    def GetTool():
        if f := FindType(0x1EBC, Backpack()):
            return f
        else:
            msg("ERROR: в бекпаке нет tinker's tools")
            return False
    
    
    def GetWood():
        FindTypeEx(0x1BDD, 0xffff, Backpack(), False)
        if FindQuantity() >= 5:
            return True
        count = abs(5 - FindQuantity())
        if count == 0:
            return True
        FindTypeEx(0x1BDD, 0xffff, ObjAtLayer(BankLayer()), False)
        if FindQuantity() >= count:
            MoveItem(FindItem(), count, Backpack(), 0, 0, 0)
            return True
        return False
    
    
    def CraftPole(tool):
        AutoMenu("Select", "Tools")
        AutoMenu("Select", "Pole")
        cTime = dt.now()
        if TargetPresent():
            CancelTarget()
        UseObject(tool)
        if WaitForTarget(5000):
            if f := FindType(0x1BDD, Backpack()):
                WaitTargetObject(f)
                msg1 = "You don't have enough material to make this!"
                msg2 = "You destroy some material."
                msg3 = "You create"
                if WaitJournalLine(cTime, f"{msg1}|{msg2}|{msg3}", 15000):
                    if InJournalBetweenTimes(msg3, cTime, dt.now()) != -1:
                        return True
        Wait(100)
        return False
    
    
    def MovePoleInBank():
        if GetType(CONTAINER) > 0:
            cont = CONTAINER
        else:
            cont = ObjAtLayer(BankLayer())
        while f := FindType(0x0DBF, Backpack()):
            bTime = dt.now()
            MoveItem(f, 1, cont, 0, 0, 0)
            Wait(100)
            if InJournalBetweenTimes("full", bTime, dt.now()) != -1:
                if cont == ObjAtLayer(BankLayer()):
                    msg("Все контейнеры заполнены!")
                    return False
                cont = ObjAtLayer(BankLayer())
        return True
    
    
    def main():
        while True:
            if not CheckConnect():
                OpenPack()
            if Dead():
                msg('ERROR: Я мёртв')
                return False
            if Dist(GetX(Self()), GetY(Self()), 3031, 3370) < 1:
                if not newMoveXY(3031, 3370, 0, 1, True):
                    msg('ERROR: не могу дойти до банка')
                    return False
            t = 0
            while LastContainer() != ObjAtLayer(BankLayer()):
                if t > 4:
                    msg('ERROR: Не могу открыть банк')
                    return False
                t += 1
                UOSay('bank')
                Wait(5000)
            Hungry(place=ObjAtLayer(BankLayer()))
            tool = GetTool()
            if not GetWood():
                return False
            if CraftPole(tool):
                if not MovePoleInBank():
                    return False
    
    
    if __name__ == '__main__':
        main()
        SetARStatus(False)
        Disconnect()
        msg('END SCRIPT')

     


  10. скрипт жрёт из банка (жареное мясо), в банк кидает логи
    на 158 строчке можно поменять тип еды
    топор нубайный
    при достижении максимального веса, бежит на разгрузку

     

    Program Lumber_in_Minoc;
    const
    xMin = 2391;
    xMax = 2534;
    yMin = 378;
    yMax = 655;
    //
    axe = $0F43; //Type топора
    
    type
        TreeRecord = Record
        t,x,y,z : Word;
    end;
    var
    Tree : array of TreeRecord;
    ct, t : Integer;
    ftime : TDateTime;
    txtR, txtF : String;
    
    procedure GetPoint;
    var
    tt, i : Integer;
    a : Word;
    b : TFoundTilesArray;
    TreeTile : array[0..39] of Word;
    begin
        if not Connected then exit;
        TreeTile[0]:=3274;
        TreeTile[1]:=3275;
        TreeTile[2]:=3277;
        TreeTile[3]:=3280;
        TreeTile[4]:=3283;
        TreeTile[5]:=3286;
        TreeTile[6]:=3288;
        TreeTile[7]:=3290;
        TreeTile[8]:=3293;
        TreeTile[9]:=3296;
        TreeTile[10]:=3299;
        TreeTile[11]:=3302;
        TreeTile[12]:=3320;
        TreeTile[13]:=3323;
        TreeTile[14]:=3326;
        TreeTile[15]:=3329;
        TreeTile[16]:=3393;
        TreeTile[17]:=3394;
        TreeTile[18]:=3395;
        TreeTile[19]:=3396;
        TreeTile[20]:=3415;
        TreeTile[21]:=3416;
        TreeTile[22]:=3417;
        TreeTile[23]:=3418;
        TreeTile[24]:=3419;
        TreeTile[25]:=3438;
        TreeTile[26]:=3439;
        TreeTile[27]:=3440;
        TreeTile[28]:=3441;
        TreeTile[29]:=3442;
        TreeTile[30]:=3460;
        TreeTile[31]:=3461;
        TreeTile[32]:=3462;
        TreeTile[33]:=3476;
        TreeTile[34]:=3478;
        TreeTile[35]:=3480;
        TreeTile[36]:=3482;
        TreeTile[37]:=3484;
        TreeTile[38]:=3492;
        TreeTile[39]:=3496; 
        for tt := 0 to 39 do
        begin
            a := GetStaticTilesArray(xMin,yMin,xMax,yMax, WorldNum,TreeTile[tt], b);
            if a > 0 then
            begin 
                for i := 0 to a - 1 do
                begin 
                    SetLength(Tree, Length(Tree)+1);
                    Tree[High(Tree)].x := b[i].x;
                    Tree[High(Tree)].y := b[i].y;
                    Tree[High(Tree)].z := b[i].z;
                    Tree[High(Tree)].t := b[i].tile;
                end;   
            end;
        end;
    end;
    
    function CheckAxe : Boolean;
    begin
        if not Connected then exit;
        result := True;
        if (GetType(ObjAtLayer(LhandLayer)) = Axe) then exit;
        FindTypeEx(Axe, $FFFF, Backpack, False);
        if FindCount > 0 then
        begin
            CheckLag(60000);
            Equip(RhandLayer,FindItem);
            wait(500); 
            exit;  
        end;
        result := False;
        AddToSystemJournal('>>>>>ERROR: нет топора!');
    end;
    
    function CheckWeight : Boolean;
    begin
        if not Connected then exit;
        if Weight < MaxWeight then Result := True; 
        if Weight >= MaxWeight then Result := False;
    end;
    
    procedure DropResource;
    var
    t : integer;
    bank : Cardinal;
    ctime : TDateTime;
    begin
        if not Connected then exit;
        if not CheckWeight then 
        begin                                          
            while (GetX(Self) <> 2498) or (GetY(Self) <> 560) do
                newMoveXY(2498, 560, True, 0, CheckWeight); 
            repeat
                if not Connected then exit;
                CheckLag(60000);
                repeat
                    if not Connected then exit;
                    t := 0;
                    CheckLag(60000);
                    UseObject(Backpack);
                    repeat
                        if not Connected then exit;
                        wait(100);
                        t := t + 1;
                    until (LastContainer = Backpack) or (t >= 100);
                until LastContainer = Backpack;
                CheckLag(60000);
                repeat
                    if not Connected then exit;
                    t := 0;
                    CheckLag(60000);
                    UOSay('bank');
                    repeat    
                        if not Connected then exit;
                        wait(100);
                        t := t + 1;
                    until (LastContainer = ObjAtLayer(BankLayer)) or (t >= 100);
                until LastContainer = ObjAtLayer(BankLayer);
            until LastContainer = ObjAtLayer(BankLayer); 
            if not Connected then exit;
            bank := ObjAtLayer(BankLayer); 
            FindTypeEx($1BDD, $FFFF, Backpack, False);
            if FindCount > 0 then 
            begin                                           
                CheckLag(60000);
                MoveItem(FindItem, FindQuantity, bank, 0,0,0);
                wait(500);                
            end;
            repeat
                if not Connected then exit;
                FindTypeEx($09F2,$FFFF, bank, False);//$09F2 тип еды
                if FindCount > 0 then
                begin  
                    ctime := Now; 
                    CheckLag(60000);
                    UseObject(FindItem);
                    wait(500);    
                end;
            until (FindCount <= 0) or (InJournalBetweenTimes('Я объелся', ctime, Now) <> -1);    
        end;  
    end;
    
    procedure CheckAttak;
    begin
        if not Connected then exit;
        if not WarMode then SetWarMode(True); 
        if HP < MaxHP then 
        begin
            UOSay('.guards');
            if TargetPresent then CancelTarget;
            UOSay('.bandage');
            CheckLag(60000);
            WaitForTarget(5000);
            WaitTargetSelf;
        end;
    end;
                     
    begin
        SetARStatus(True);
        moveThroughNPC := 0;
        MoveOpenDoor := True;
        GetPoint;
        txtR := 'You have found some deadwood|Forest guardians are angry on you|not enough wood here to chop|Circle of Transparency|That is too far away';
        txtF := 'not enough wood here to chop|Circle of Transparency|That is too far away';
        repeat 
            while not Connected do
            begin
                wait(1000);
            end;
            for ct := 0 to High(Tree) do
            begin
                if not Connected then break;
                if not CheckAxe then exit;
                DropResource;    
                if newMoveXY(Tree[ct].x, Tree[ct].y, True, 2, CheckWeight) then
                begin
                    repeat 
                        if not Connected then break;
                        repeat
                            if not Connected then break;
                            if TargetPresent then CancelTarget; 
                            CheckLag(60000);
                            UseObject(ObjAtLayer(LhandLayer));
                            WaitForTarget(5000);
                        until TargetPresent;
                        ftime := Now;
                        TargetToTile(Tree[ct].t, Tree[ct].x, Tree[ct].y, Tree[ct].z); 
                        CheckAttak;
                        t := 0;
                        repeat 
                            if not Connected then break;  
                            t := t + 1;
                            CheckLag(60000);
                            wait(100);
                        until (InJournalBetweenTimes(txtR, ftime, Now) <> -1) or (t >= 600);
                    until (InJournalBetweenTimes(txtF, ftime, Now) <> -1);    
                end;
            end;    
        until false;      
    end.

     


  11. не забывайте о том что в теле уохаммера содержится ворм, что точно делает он не известно, но лично видел что посылает запросы на отправку к адресам, не являющимся и близко адресом уо. что именно делает вирус не понятно, может и расчитан под старые ОС а в новых бессилен, но все же не приятно осознавать это все.

    он отправляет логин с паролем на сторонний адресс


  12. Вы бы хоть прочитали какой блок ковыряете... Вы ковыряете блок (Recharge) заправку спеллбуки реколлами, а непосредстенно за телепорт отвечает блок Recall.

     

    А эта строка:

    WaitGump(IntToStr(500+HomeRune));

    отвечает за добавление руны в SetDefault рунбуки

     

    Координаты в шахте это точка к которой чар идет по прилету, на возможность телепортироваться они никак не влияют.

     

    координаты шахты и дома играют роль контролера на краш скрипта, если чар оказывается в не предела шахты или дома на определённом расстояние, скрипт завершается с ошибкой


  13. procedure OpenBackpack;
    begin
      if (LastContainer <> Backpack) and (dead = false) then
        begin
          repeat
            if not Connected then exit;
            Checksave;
            UseObject(Backpack);
            wait(1000);
          until LastContainer = Backpack;
        end;
    end;

     

    procedure WaitConnection(WaitTime : Integer);
    begin
        if Connected then Exit;
            while not Connected do Wait(1000);
            {WaitTime - Waiting After Connected}
            wait(WaitTime);
    end;

×
×
  • Создать...