Перейти к содержанию

MasterGH

Ветераны
  • Постов

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

  • Победитель дней

    129

Весь контент MasterGH

  1. 1. Какой именно чит (читы) ты хочешь сделать? 2. В какой игре или играх (название)? 3. Каким образом способ "разбора игры по классам" может помочь?
  2. Добавлена 32-разрядная версия.
  3. Только поставил игру и немного прошел... [ENABLE]alloc(newmem,2048,"gamedll_x64_rwdi.dll"+5BB33C)label(returnhere)label(originalcode)label(exit)newmem: mov [rdi+04],(float)35.0 originalcode: movss xmm6,[rdi+04]exit: jmp returnhere"gamedll_x64_rwdi.dll"+5BB33C: jmp newmem returnhere: [DISABLE]"gamedll_x64_rwdi.dll"+5BB33C: movss xmm6,[rdi+04] //Alt: db F3 0F 10 77 04dealloc(newmem)gamedll_x64_rwdi.dll+5BB316 - 48 83 EC 30 - sub rsp,30gamedll_x64_rwdi.dll+5BB31A - 48 8B 41 18 - mov rax,[rcx+18]gamedll_x64_rwdi.dll+5BB31E - 48 8B F9 - mov rdi,rcxgamedll_x64_rwdi.dll+5BB321 - 48 83 C1 18 - add rcx,18gamedll_x64_rwdi.dll+5BB325 - FF 90 58080000 - call qword ptr [rax+00000858]gamedll_x64_rwdi.dll+5BB32B - 84 C0 - test al,algamedll_x64_rwdi.dll+5BB32D - 74 2F - je gamedll_x64_rwdi.dll+5BB35Egamedll_x64_rwdi.dll+5BB32F - 48 8B 47 18 - mov rax,[rdi+18]gamedll_x64_rwdi.dll+5BB333 - 48 8D 4F 18 - lea rcx,[rdi+18]gamedll_x64_rwdi.dll+5BB337 - 0F29 74 24 20 - movaps [rsp+20],xmm6gamedll_x64_rwdi.dll+5BB33C - F3 0F10 77 04 - movss xmm6,[rdi+04]gamedll_x64_rwdi.dll+5BB341 - FF 90 18090000 - call qword ptr [rax+00000918]gamedll_x64_rwdi.dll+5BB347 - 0F2F F0 - comiss xmm6,xmm0gamedll_x64_rwdi.dll+5BB34A - 0F28 74 24 20 - movaps xmm6,[rsp+20]gamedll_x64_rwdi.dll+5BB34F - 77 0D - ja gamedll_x64_rwdi.dll+5BB35Egamedll_x64_rwdi.dll+5BB351 - B0 01 - mov al,01gamedll_x64_rwdi.dll+5BB353 - 48 8B 5C 24 40 - mov rbx,[rsp+40]gamedll_x64_rwdi.dll+5BB358 - 48 83 C4 30 - add rsp,30gamedll_x64_rwdi.dll+5BB35C - 5F - pop rdigamedll_x64_rwdi.dll+5BB35D - C3 - ret gamedll_x64_rwdi.dll+5BB35E - 32 C0 - xor al,algamedll_x64_rwdi.dll+5BB360 - 48 8B 5C 24 40 - mov rbx,[rsp+40]gamedll_x64_rwdi.dll+5BB365 - 48 83 C4 30 - add rsp,30gamedll_x64_rwdi.dll+5BB369 - 5F - pop rdigamedll_x64_rwdi.dll+5BB36A - C3 - ret gamedll_x64_rwdi.dll+5BB36B - CC - int 3
  4. У меня нет ошибок. Win7 64 Pro CE 6.4 "cheatengine-x86_64.exe" Поиск адресов и установка бряков работает. Проверено. Подсказка. Значение зашифровано по принципу кодирования Chicken Invaders 4. Этот принцип я разбирал в одной из тем на форуме. Это значит, что рабочий адрес таймера невозможно найти через сканер памяти. Могут быть лишь зацепки. Поиск адреса текста и реверс до места шифрования или поиск/отсев call-ов через Ultimap, которые показывают диалоги, но придется ждать каждый раз 30 секунд.
  5. MasterGH

    Trainme. Взлом таймера

    Цель. В течении 30 секунд нужно заморозить время или сделать его больше текущего. Если сделали все правильно, то по истечении 30 секунд будет проверка и появится сообщение о выигрыше или проигрыше. Примените все свои знания и опыт, чтобы добиться этой цели как можно быстрее. Можно использовать отладчик, а можно и другие способы. Любые способы.
  6. Вот набросал перевод документации API { init: function(elevators, floors) { var elevator = elevators[0]; // Использовать первый лифт (на 1-ой стадии он один) elevator.on("idle", function() { // Лифт встал на этаже и ничего не делает elevator.goToFloor(0); // добавить в очередь движение на этаж 0 elevator.goToFloor(1); // добавить в очередь движение на этаж 1 }); }, update: function(dt, elevators, floors) { // Функция обновления где // DT (deltaTime) - разница игровых секунд (прим. от MasterGH тип не знаю сами проверите), прошедших с предыдущего вызова update-функции }}elevator.destinationQueue = [];elevator.checkDestinationQueue();if(elevator.getPressedFloors().length > 0) {// Может быть лифту отправиться на некоторый этаж?}elevator.on("idle", function() { ... });elevator.on("floor_button_pressed", function(floorNum) {// Нужно ли лифту отправлятся на этаж floorNum?})elevator.on("passing_floor", function(floorNum, direction) { ... });elevator.on("stopped_at_floor", function(floorNum) {// Нужно решить куда идти лифту дальше?})if(floor.floorNum() > 3) { ... }floor.on("up_button_pressed", function() {// Может быть послать лифт на этот этаж floor ?})floor.on("down_button_pressed", function() {// Может быть послать лифт на этот этаж floor ?}){ init: function(elevators, floors) { var reorder = true; //reorder floor order to minimize moves. Keep on true var minimalfilled = 0; //set to 0.6 for minimal move challenges var backtozero = false; //make elevators go back to floor zero if idle or not. var uppressed = []; //keep track of up button presses var downpressed = []; //keep track of down button presses // loop over floors _.each(floors, function(floor) { // if an up button is pressed, add it to the list of up presses floor.on("up_button_pressed", function() { uppressed.push(floor.level); }); // if a down button is pressed, add it to the list of down presses floor.on("down_button_pressed", function() { downpressed.push(floor.level); }); }); // loop over elevators _.each(elevators, function(elevator) { // if a button is pressed in the elevator, go to that floor (order can be changed when a floor is passed) elevator.on("floor_button_pressed", function(floorNum) { elevator.goToFloor(floorNum); }); // if idle, determine the next floor to go to elevator.on("idle", function() { // compute the center floor - unused //var middle = Math.floor(floors.length/2); var floor; // if a down button is pressed, go to the floor where a button is pressed if (downpressed.length > 0) { floor = downpressed.pop(); //inProcessDown.push(floor); // if an up button is pressed, go to the floor where an up button is pressed // this comes after the down presses, because up presses mostly occur at ground floor, where plenty of elevators pass anyway } else if (uppressed.length > 0){ floor = uppressed.pop(); //inProcessUp.push(floor); // if the variable is set to true, and no buttons are pressed, go to ground floor } else if (backtozero){ floor = 0; // stay on the current floor } else { floor = elevator.currentFloor(); } // go to the floor chosen above elevator.goToFloor(floor); }); // when stopping on a floor elevator.on("stopped_at_floor", function() { // if the elevator is not sufficiently filled, stay on the current floor // can be used for the minimal move challenges if (elevator.loadFactor()<minimalfilled){ elevator.goToFloor(elevator.currentFloor(),true); } }); // when passing a floor, rearrange the queue elevator.on("passing_floor", function(floorNum, direction) { var arr = elevator.destinationQueue; var uppressedIndex=uppressed.indexOf(floorNum); var downPressedIndex=downpressed.indexOf(floorNum); // see if someone pressed a floor button, if you're not full and you're going in the right direction add the floor to the queue if(elevator.loadFactor()<=0.5 && (((uppressedIndex > -1) && direction == "up") || ((downPressedIndex > -1) && direction == "down"))){ if (uppressedIndex > -1) uppressed.splice(uppressedIndex,1); if (downPressedIndex > -1) downpressed.splice(downPressedIndex,1); arr.push(floorNum); } // remove potential duplicate values from the queue var i, len=arr.length, out=[], obj={}; for (i=0;i<len;i++) { obj[arr[i]]=0; } for (i in obj) { out.push(i); } // duplicates removed // reorder the queue so floors on the path are first in the queue if(reorder){ out=out.sort(); var out2=[]; var out3=[]; if(direction == "up"){ for(i in out){ if(out[i]>=floorNum){ out2.push(out[i]); } else { out3.push(out[i]); } } } else { out = out.reverse(); for(i in out){ if(out[i]<=floorNum){ out2.push(out[i]); } else { out3.push(out[i]); } } } out = out2.concat(out3); } elevator.destinationQueue = out; elevator.checkDestinationQueue(); }); }); }, update: function(dt, elevators, floors) { }}{ init: function(elevators, floors) { var rotator = 0; _.each(floors, function(floor) { floor.on("up_button_pressed down_button_pressed", function() { var elevator = elevators[(rotator++) % elevators.length]; elevator.goToFloor(floor.level); }); }); _.each(elevators, function(elevator) { elevator.on("floor_button_pressed", function(floorNum) { elevator.goToFloor(floorNum); }); elevator.on("idle", function() { elevator.goToFloor(0); }); }); }, update: function(dt, elevators, floors) { }}
  7. И сколько ты стадий прошел? Я на 7-ой застрял
  8. Впервые я задумался, что очень жаль, что ни в этой игре и не в реальной жизни нельзя избирательно пропускать в лифт определенных пассажиров, а также нельзя определенных пассажиров принудительно (даже если они очень не хотят) высаживать на "этажах с ожиданием пока их не заберут", или высаживать в другие лифты. Если мы будем пропускать в лифт определенных пассажиров и выпускать даже там где они не хотели бы, то другие могли бы в бОльшем количестве доехать до места назначения. В этой игре возможно идеальным решением будет взвешивание вариантов из всех возможных найденных за единицу времени. Но можно попробовать обобщить только некоторые варианты, чтобы это было достаточным решением 1) лифт должен немного подождать пока пассажиров наберется в нем, а не сразу ехать с одним человеком 2) лифт едет вверх или вниз, и по пути собирает и высаживает людей, но лифт не должен менять направление пока не отвезет всех пассажиров по текущему направлению до самого верхнего или до самого нижнего этажа 3) если лифт пустой, то он должен выбрать с какого этажа и в каком направлении начать движение, чтобы собрать как можно больше людей 4) когда лифтов много, то можно распределять для них задачи по маршрутам так, чтобы пункт 1, пункт 2, пункт 3 выполнялись наиболее выгодно с меньшим количеством лифтов Вы слышали что-нибудь про инфузорию туфельку и движения ресничками по всему телу? Нигде не описывается как именно реснички выбирают направление, но я могу предположить, что окружающая среда (источники раздражения) и направляет эти реснички. По аналогии и с лифтами. Пассажиры это еда. Реснички это лифты. Если создать сесть из узлов оценивающих в единицу времени сумму весов случайных вариантов и запомненных вариантов, то можно запомнить новые варианты и эффективно перевозить пассажиров. Такая система вряд ли делается жесткими условиями "если А, то Б". Эти условия должны сами формироваться... Короче ну нафиг, я пошел работать...
  9. MasterGH

    Чат

    Уже скучаете без чата?
  10. Xipho, я очень благодарен за помощь. С минуты на минуту будет новый плагин.
  11. Спасибо. Как найду время исправлю описания плагинов и скрины.
  12. Репозиторий Появились продвижения по вызову функций. Я готовлю новый плагин "Repeater", который позволит вызывать если не любые функции, то большинство из них. Если найти адрес в Ultimap, то сделать повтор действия в игре будет очень просто через плагин. При тестах удалось вызывать пока функцию дельфи, которую нажимала кнопка На скрине видно окно плагина и две кнопки. Обе они визуально увеличивают число на 1 ед. Плагин тем не менее не доделан. Подмена ESP на другой регион памяти с копией стека вызывает вылет приложения ибо регион памяти не имеет нужных прав. Здесь два выхода не менять esp и заполнить его или же менять esp и менять права региона памяти. Технология следующая. Читер находит верхний call из Ultimap Открывает плагин. Вводит адрес этого call и называет Событие каким-нибудь именем. Создает событие и появляется кнопка. Событий можно сделать не больше 10. Т.е. 10 кнопок может появиться. Кликая на них в игре будет повторяться действие. Что происходит за кулисами? За кулисами происходит установка бряка на call и создается кнопка отключенная. Игрок идет в игру, совершает действие. Происходит бряк Затем Луа код плагина бряк снимает Снятие дампа стека Немного дизаасемблирования, ассемблирования и прочая хренотень для вызова функции по копии дампа стека и по копии данных регистров Кнопка становится активной Процесс игры отпускается Все... теперь нажимая на кнопку в окне Repeater действие в игре повторяется по копии данных стека и регистров снятых от предыдущего действия Пока копия стека не используется из-за ошибки, т.к. нарушение прав региона памяти при подмене esp. Как решу проблему с ESP, как проверю работу на игре, то будет плагин. Пока код такой без формы, для интересующихся (форму не даю, т.к. плагин не рабочий пока): --Author: MasterGH, 26.01.2015, Gamehacklab[RU] (http://gamehacklab.ru)frmRepeater = createFormFromFile(getCheatEngineDir().."\\autorun\\frmRepeater.xml")if(frmRepeater == nil) then messageDialog('Can not find frmRepeater', mtError, mbOK) returnendfunction OnClickMenuItemRepeater() frmRepeater.Show()endfunction DEC_HEX( IN ) return string.format( '%x', IN )end function HEX_DEC( IN ) return tonumber(IN, 16)end local menuItems = getMemoryViewForm().findComponentByName('MainMenu1').Itemslocal count = menuItems.Count - 1for i = 0, count-1 do local item = menuItems.getItem(i) if(item.Caption == 'Tools') then local mi = createMenuItem(popupmenu) menuItem_setCaption(mi, '*Repeater [Plugin]') menuItem_onClick(mi, OnClickMenuItemRepeater) item.add(mi) break endendlocal countLine = 1tableBtn = {}frmRepeater.CEEdit1.Text = 'Action1'frmRepeater.CEEdit2.Text = '00454690' --'00000000'frmRepeater.Caption = 'Repeater [CE Lua Plugin, ver 1.0]'function OnClickBtnCaller(sender) for i,v in ipairs(tableBtn) do if(tableBtn[i].btnCall == sender) then autoAssemble(tableBtn[i].AACallThread) end endendfunction OnClickCreateLine(sender) if (countLine > 10) then print('Records > 15') return end local labelName = frmRepeater.CEEdit1.Text local addressCode = frmRepeater.CEEdit2.Text if (labelName == '') then messageDialog('Label is empty', mtError, mbOK) return end if (addressCode == '') then messageDialog('AddressCode is empty', mtError, mbOK) return end for i,v in ipairs(tableBtn) do if(tableBtn[i].userLabel == labelName) then print('Name "'..labelName..'" is not unical') return end if(tableBtn[i].addressCall == addressCode) then print('AddressCode "'..addressCode..'" is not unical') return end end local btnCall = createButton(frmRepeater) btnCall.Caption = labelName..' (Do action in the game!)' btnCall.Top = (countLine - 1) * 50 + 10 btnCall.Width = 300 btnCall.Left = 80 btnCall.OnClick = OnClickBtnCaller btnCall.Enabled = false tableBtn[countLine] = {} tableBtn[countLine].btnCall = btnCall tableBtn[countLine].userLabel = labelName tableBtn[countLine].addressCall = addressCode tableBtn[countLine].addressCallNumber = HEX_DEC(addressCode) tableBtn[countLine].StackDump = false tableBtn[countLine].addressStack = 'StackMemRepeatCall'..countLine tableBtn[countLine].addressMemThread = 'ThreadMemRepeatCall'..countLine tableBtn[countLine].AACallThread = '' debug_setBreakpoint(addressCode, 1, bptExecute) frmRepeater.CEEdit1.Text = 'Action1' frmRepeater.CEEdit2.Text = '00000000' frmRepeater.CEPanel1.Top = countLine * 50 countLine = countLine + 1endfunction CallAction(itemTable) debug_removeBreakpoint(itemTable.addressCall) if (getOpenedProcessID() == 0) then messageDialog('No target any process', mtError, mbOK) return end autoAssemble([[ alloc(]]..itemTable.addressStack..[[,4096)registersymbol(]]..itemTable.addressStack..[[)]]..itemTable.addressStack..[[:readmem(]]..DEC_HEX(ESP)..[[, 3000)]]) itemTable.StackDump = true--EFLAGS--32-bit: EAX, EBX, ECX, EDX, EDI, ESP, EBP, ESP, EIP--64-bit: RAX, EBX, RBX, RDX, RDI, RSP, RBP, RSP, RIP, R8, R9, R10, R11, R12, R13, R14, R15 : The value of the register local lineDissassemble = disassemble(itemTable.addressCall) extrafield, opcode, bytes, adressReturnHere = splitDisassembledString(lineDissassemble) local _ebp = DEC_HEX(getAddress(DEC_HEX(EBP)..'-'..DEC_HEX(ESP)..'+'..itemTable.addressStack, false)) local _esp = DEC_HEX(getAddress(itemTable.addressStack)) local scriptAA0 = string.format([[alloc(%s,1024)registersymbol(%s)%s:mov eax,%xmov ebx,%xmov ecx,%xmov edx,%xmov esi,%xmov edi,%xmov esp,%smov ebp,%s%sret]], itemTable.addressMemThread, itemTable.addressMemThread, itemTable.addressMemThread, EAX, EBX, ECX, EDX, ESI, EDI, _esp, _ebp, opcode) autoAssemble(scriptAA0) itemTable.AACallThread = [[createthread(]]..itemTable.addressMemThread..[[)]] itemTable.btnCall.Enabled = trueendfunction debugger_onBreakpoint() for i,v in ipairs(tableBtn) do if(tableBtn[i].addressCallNumber == EIP) then CallAction(tableBtn[i]) return 1 end end return 0endfrmRepeater.CEButton2.OnClick = OnClickCreateLine
  13. Можно все время ковырять чужие игры в отладочном коде и понятия не иметь как это бы выглядело на современных игровых движках, которые можно скачать в сети. Сry Engine UDK Unity 3D И даже валяется в сети Gamebryo Хорошо ковырять игры в отладке, хорошо пытаться написать подобие игры на C++ и на каких-то библиотеках. Однако, лучше всего увидеть как твоя игра или демо выглядит на игровом движке, на котором сделаны другие игры.
  14. MasterGH

    Ultimap

    Эксперименты с Ultimap переносятся на другое время. Функции находятся и дампы со стека снимаются, и видны возможные аргументы функций как в стеке так и в регистрах, но происходят ошибки и вылеты при вызове функций... В ближайшее время лень ковыряться в рутине отладочного кода, когда можно провести время более весело. Тем не менее, мы когда-нибудь научимся вызывать любую функцию. Это обязательно произойдет. Если общими усилиями искать решение, то это произойдет еще быстрее. Подпишитесь на тему. Как будет что-то новое, то придет уведомление.
  15. У меня все нормально. Не замечал сегодня.
  16. Abraham08, на вопрос администрации нужно отвечать. "В сингле также читал о подобном..." - это не ответ. Ответ невнятный. То что Вы читали, это не ответ. pvp - нельзя pwe - можно (Xipho иногда разрешает в обход правилам) pvp + pwe - явно нельзя pvp + pwe - нельзя, т.е. если помимо всех монстров в мультиплеер будут в кучу собираться и персонажи живых игроков, то автору может быть бан, а "помогающие" могут быть наказаны.
  17. Здесь обсуждение. Я не думаю, что в сингле кто-то это сделал, а вот в мультиплеере очень даже вероятно. Судя по видео, читак отправляет сетевой пакет нанесения удара с id персонажа, которому наносится удар на мастре-сервер или через сервер на мастер-клиент. Мастер-сервер, если он там есть даже не проверяет расстояние нанесения удара, не проверяет препятствия... и отправляет в "обратку" всем в сети, что такой-то перс нанес бекспаб удар. Все остальные клиенты подчиняются как безвольные. Устанавливают и разворачивают персонажа, по которому ударили, рядом с тем кто ударил его. В связи с чем вопрос. Автор, Вам для сетевой игры в пвп или для одиночной надо? Боюсь, что если сделать для одиночной, то и для сетевой будет работать, а Вы наверно этого и хотите проверить. Поглумиться над глупцами, которые дуб-дубом в читах.
  18. Добавлены пункты: 4 - сохранение списка адресов из колонки Ultimap в файл *.address через диалог сохранения 5 - установка бряков "на выполнение" из файла-списка*.address Пункт 4 позволит сохранить найденные адреса в файл во время зависания игры. У меня игра частенько виснет, если что-то долго искать. Чтобы результат не пропадал очень пригодится, чтобы не делать повторный поиск. В файле *.address можно удалить или добавить адреса, а затем поставить махом на них бряки "на выполнение". Когда в игре бряки выполняются, а желаемое действие мы еще не делали, то эти бряки не подходят. Их надо удалять, а бряки которые срабатывают во время желаемого действия нужно сохранять. Хотя, если сканировали Ultimap правильно фильтруя не десвующие и действующие адреса, то бряки вручную удалять из файла не надо будет. Кстати это и пример того как сохранять и загружать текст используя диалоги. Может пригодиться, если нужно сохранять логи. Анализировать их например сторонней программой на любимом языке программирования. ----- К сожалению не работает функция: debug_getBreakpointList(): Returns a lua table containing all the breakpoint addresses Она должна будет работать в новых версиях CE судя по логам исправлений на офиц. сайте CE. Надо будет сделать кнопку в окне бряков, которая удалит все брейкпоинты. Уже запарило чистить.
  19. MasterGH

    Ultimap

    Привет. Ну, один пример уже был. Эта статья, которую ты переводил. Я просто не видел, что ты её переводил. Там я Ultimap-ом нашел зашифрованное значение. Можешь скачать эту игру и прогнать на практике. Т.е. ты на практике найдешь зашифрованное значение и место откуда оно вызывается DBVM у меня работает прекрасно. Не разу не было, чтобы он у меня не грузился. Win7 64 Pro лицензия. Проц интеловский E7500 (2 ядра 2,9Гц), GTX 560 Ti видюха. Я думаю Ultimap хорошо работает на мощном процессоре с быстрой памятью. Есть второй комп на котором я мог бы потестить Ultimap, он помощнее (i5-4670K 4 ядра 3,4Гц, GTX 980, твердотельный накопитель, памяти 16 Гб уже не помню какой-то быстрой памяти) , но этот комп занят под игрушки. За ним постоянно играют в arch age и он занят.
  20. Лучше сюды писать, ultimap-тема там Ultimap парой слов можно попробовать объяснить. Если ты взял с земли шесть раз предмет, то можно найти call-ы, которые ровно 6 раз вызывались. Если поставить все бряки на адреса второй колонки, то первый бряк и предположительно нужно исследовать. Это будет первый call, от которого начинается ветвь кода, в которой начинается поднятие оружия. Остальные бряки желательно сразу отключить. Чтобы это сделать разом я напишут еще скрипт. Где-то выше этого call-а есть условие, которое как спусковой крючок запускает поднятие оружия по горячей клавише. Надо либо это условие менять, либо вызывать call-ы потоком игры.... ...В теории можно получить оружие, которого у тебя не было. Пока на практике это не удалось сделать. Ну, времени мало... куча работы. На выходных скорее всего. Ну, если образно выразиться. Скорее части ветвей отладочного кода. Трейс лог более полно может показать ветвь кода как раз при установке на "верхний call" На все, которые находятся в определенной колонке. Проверено. Потом задолбаешся их снимать удерживая Del
  21. Название формы: "frmUltimap" Название поля: "ListView1" Цели: 1. Вывести текст всей таблицы в консоль 2. Вывести текст определенной колонки 3. Поставить брейкпоинты на все адреса первой или второй колонки 4. Сохранить выбранную колонку с адресами в файл *.address 5. Установить брейкпоинты из файла *.adresses
  22. Да, вторая и третья картинка (под первым спойлером) ни в опере 12.17 и не в фаерфоксе 33,1,1 не открываются
  23. Я условно определил появление бага, когда невозможно посмотреть картинку. Вот одна из тем Первое знакомство с движком Unity3D В этой теме нельзя открыть некоторые одинаковые картинки. Так вот причина в том, что картинки повторяются в сообщение поста. Если к посту прикрепить например одну картинку, а в разметке сообщения текстом вставить эту картинку более одного раза, то эту картинку невозможно посмотреть. Эта ошибка произошла после какого-то обновления форума.
  24. Это не совсем плагин, а скорее то, что могло быть плагином, но просто лень делать форму с одной кнопкой. Предлагаю это сделать желающим. Допустим в таблице сохранено около сотни инструкций собранных из Ultimap, смотрим ниже Название формы: "AdvancedOptions" Название поля: "Codelist2" Нам нужно разом поставить на них брейкпоинт (после случайного вылета из игры) для исследований... Для этого нужно выполнить CE Lua скрипт предварительно открыв Code List function FindFrom(formName) local formCount = getFormCount() for i=0, formCount-1 do if(getForm(i).Name == formName) then return getForm(i) end end end function SetBreakPoints(argListView) local items1 = argListView.Items local linesCount = items1.getCount() for i=0, linesCount-1 do debug_setBreakpoint(items1.getItem(i).Caption, 1, bptExecute) end end local frmFindFrom = FindFrom('AdvancedOptions') local codeList = frmFindFrom.findComponentByName('Codelist2') SetBreakPoints(codeList) Как открыть Code List? Ответ на первом скрине Как добавить инструкцию в Code List? Ответ на скрине Как открыть окно бряков? Ответ на скрине
×
×
  • Создать...

Важная информация

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