CELua[RU]
    • Категории
    • Последние
    • Метки
    • Популярные
    • Пользователи
    • Группы
    • Зарегистрироваться
    • Войти
    1. Главная
    2. MasterGH
    3. Сообщения
    Не в сети
    • Профиль
    • Подписки 1
    • Подписчики 1
    • Темы 129
    • Сообщения 252
    • Группы 4

    Сообщения

    Последние Лучшие сообщения Спорные
    • [The Escapists 2 + Unity + dnSpy] Спавн итемов

      Спавн итемов удалось сделать через dnSpy

      При клике на любой предмет на меню крафта он создается в инвентаре, а если там занято, то выкидывается на карту.

      Я переписал метод клика на рецепт, вот он оригинальный

      // Token: 0x060069FA RID: 27130 RVA: 0x00254874 File Offset: 0x00252A74
      	private void OnRecipeSlotClicked(int recipeSlotID)
      	{
      		if (recipeSlotID == this.m_CurrentClickedRecipeID)
      		{
      			if (!T17RewiredStandaloneInputModule.IsCurrentActiveModuleUsingController())
      			{
      				this.m_CurrentClickedRecipeID = -1;
      			}
      			return;
      		}
      		if (!this.CheckHasItemsForRecipe(recipeSlotID))
      		{
      			this.m_CurrentClickedRecipeID = -1;
      			return;
      		}
      		CraftManager.Recipe recipeByID = CraftManager.GetInstance().GetRecipeByID(recipeSlotID);
      		if (recipeByID != null && (!recipeByID.m_bHidden || recipeByID.m_bDiscovered))
      		{
      			this.FillSlots(recipeSlotID);
      			this.m_CurrentClickedRecipeID = recipeSlotID;
      			return;
      		}
      		this.m_CurrentClickedRecipeID = -1;
      	}
      

      На этот

      private void OnRecipeSlotClicked(int recipeSlotID)
      	{
      		int itemDataID = CraftManager.GetInstance().GetCurrentRecipes()[recipeSlotID].m_Product.m_ItemDataID;
      		Character character = base.CurrentGamePlayer.GetComponent();
      		ItemManager.GetInstance().AssignItemRPC(character.m_NetView.ownerId, itemDataID, new ItemManager.ItemManagerEvent(this.OnStandingAnimItemSpawn), ref character.m_StandingStillEquipID, -1);
      	}
      
      	private void OnStandingAnimItemSpawn(Item item, int eventID)
      	{
      		if (base.CurrentGamePlayer.GetComponent().m_StandingStillEquipID == eventID)
      		{
      			Player player = base.CurrentGamePlayer;
      			bool flag = false;
      			if (player.GetEquippedItem() == null)
      			{
      				flag = player.SetEquippedItem(item, true, false, RPC_CallContexts.Master);
      			}
      			if (!flag)
      			{
      				item.DropItemInLevel(player, player.transform.position);
      			}
      		}
      	}
      

      7c8381aa-0c85-466d-9743-42edabd7eb9c-изображение.png
      ac1cd6a8-5078-48ea-9f4a-3d605db0971c-изображение.png
      Для спавна заменить Assembly-CSharp.dll из архива, сделав копию предварительно
      Assembly-CSharp.rar

      написал в Статьи unity cheats dnspy csharp блог
      MasterGHM
      MasterGH
    • [dnSpy + Unity ] Пошаговая отладка

      Эта статья позволит отлаживать игры на Unity в Runtime и при этом видеть декомпилированный код.
      Это, конечно, не для всех игр на Unity. Пошаговая отладка в dnSpy позволяет ставить брейкпоинты на C# код во время работы игры, перемещаться по коду, просматривать значения переменных. Сэкономит кучу времени при поиске и отладке игрового кода,

      1. Страница загрузки dnSpy

      2. Скачиваем dnSpy и все архивы с mono.dll файлами
        Unity-debugging-4.x-win32.zip
        Unity-debugging-4.x-win64.zip
        Unity-debugging-win32.zip
        Unity-debugging-win64.zip

      3. Смотрим свойства exe файла игры и определяем по нему версию Unity. Например, "Версия продукта 5.5.0.3120186" или версия "файла 5.50.39994" может указывать на версию Unity 5.5.

      4. Определяем разрядность приложения через Process Explorer

      5. Т.к. версия Unity 5.5 и приложение 32 разрядное, то открываем Unity-debugging-win32.zip ищем там версию Unity и заменяем mono.dll в директории игры

      6. Запускаем игру и dnSpy x86 (игра 32 разрядная поэтому x86). Открываем файл "...\Managed\Assembly-CSharp.dll" Запускаем отладку нажав F5 или кнопку Play

      7. Настраиваем соединение и жмем ок
        f3bfd701-f39d-407e-88a4-7d055be62dd8-изображение.png

      8. Ставим брейкпоинты, смотрим перемененные, перемещаемся по коду, пишем свой код и так далее
        02ae6479-60bb-46ff-8a4a-29d49a3d338e-изображение.png

      9. После изменения кода, нужно перезаписать модуль предварительно сохранив его
        46ca3c49-4ed6-4dd4-8ab5-c76dd2c24810-изображение.png
        68919380-783a-4497-860a-ff2ef1809f64-изображение.png
        О других способах подключения пошаговой отладки есть на английском руководство.

      Как работать в пошаговой отладке

      Работать можно почти также как и в Cheat Engine в пошаговой отладке или в среде разработки программ.

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

      Стоит обратить внимание на такие названия как "IsPlayer, Player, Character, CharacterController, MainCharacter, Health, Inventory, Craft" и другие. Чтобы не искать вручную можно задействовать поиск сборкам. Поиск стандартного тега "Player" в виде в строки кода (в Unity выше версии 5.0) или свойства "IsPlayer" может помочь найти игрока или отличить от чужих.

      Важно представлять иерархию игровых объектов, которую мы не видим в dnSpy. Программист работая в Unity видит это окошко много лет и эту иерархию всегда представляет смотря на скрипты в dnSpy
      c4838eb6-f93c-4b24-aeda-c733de7ffb51-изображение.png
      Скрипты наследники от MonoBehavior могут находиться на игровом объекте и могут работать как с ним так и с другими объектами. Получается такая штука, что игровой объект всегда имеет Transform компонент с полями позиций, углами и scale. Классы Transform и GameObject самые основные. Методами этих классов можно разместить объект в мире, создать или удалить его. В идеале удалив объект со сцены не должно быть никаких ошибок связанных с пустыми ссылками, потерей объекта. Также и клонировав объект, тоже не должно быть ошибок. Но не всегда так просто отспавнить игровой объект. Если это сделать методами UnityEngine, то другие классы ничего не будут знать о появлении игрового объекта. Нужно ставить брейкпоинт в функции Start или Awake в классе и трейсить по Shift+11 чтобы выйти на функцию разработчиков спавна этого GameObject. Функции Start или Awake (в классе наследника от MonoBehavior) срабатывают один раз при включении скрипта и инициализации. По ним можно выйти на строку кода, которая создает объекты в мире.

      Отдельно стоит сказать про количество скриптов. Практически в любой игре, которая мне попадалась в dnSpy много скриптов или очень много. Иногда и не будет понятных названий у типов (из-за обфускации). В любом случае при пошаговой отладке можно найти требующиеся участки кода для создания чита и использовать их по другой логике.

      Основные приемы

      В Update можно обновлять параметры только своего игрока. Например, в Character классе сделать сравнения в Update по IsPlayer свойству (если оно там есть) и у тебя за каждый кадр рендеринга будет максимум характеристик.

      В Update с классом Input можно считывать хоткеи.

      В Start и Awake можно подгружать свои ассеты с внутриигровым user interface. Код скриптов перед загрузкой ассетов должен быть внедрен через dnSpy

      Иерархию игровых объектов и инспектор, если очень нужно, то можно отрисовать в user interface. Обычно не требуется. (поищите по форуму в игрострое)

      В заключении

      Пока нет времени делать трейнер или таблицу на CE для включения опций в играх Unity. Для меня пока подходит способ через перезапись модуля в dnSpy вручную.

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

      написал в Статьи unity dnspy decompile debug блог
      MasterGHM
      MasterGH
    • RE: Настройка частного DNS

      Ого 😃 Ну, спасибо

      написал в Linux
      MasterGHM
      MasterGH
    • RE: Защита Трейнера

      Пользовательские метки должны здесь появится.

      изображение.png
      изображение.png

      Если их там нет, значит они не зарегистрировались. Чтобы они зарегистрировались нужно использовать reinitializeSymbolhandler(true) до autoassemble(...)

      написал в Вопросы
      MasterGHM
      MasterGH
    • Настройка частного DNS

      Статья "Настройка частного DNS"
      ссылка en
      перевод ru

      написал в Linux linux dns server ubuntu
      MasterGHM
      MasterGH
    • CE Script Editor [Notepad+]

      Расширение для Notepad+
      Там все файлы и ссылки: перейти
      Пару картинок запосчу, чтобы иметь представление что это

      Описание
      Описание

      Не хватает изменения размеров картинок.
      Не хватает спойлеров (добавил в todo)
      Не хватает цвета для текста

      написал в Плагин-строй todo ce plugin notepad++
      MasterGHM
      MasterGH
    • Собираем ссылки на разные источники

      В этой теме собираем все, что понравилось и плюс небольшой комментарий. Можно по CE, можно не по CE. Как угодно. Потом сгруппируем, как больше накопится

      1. Базовые основы CE Auto Assembler Basics
        Auto Assembler Basics

      2. Вся справка по CE

        Cheat Engine
      3. Статья из блога по шаблонам CE (сложно, для понимания надо хорошо знать CE Lua)

        Ну, а сам блог можно полистать там. Там есть например настройка DNS
        И сам движок прикольный блога с тегами
        c0a3a943-0e68-4eaa-90f3-bf3fc8c98a15-изображение.png Надо будет такой же поставить (записил в todo). Шаблоны на CE Lua того же автора (альтернатива AAMaker)

      4. Сам форум CE (там куча всего). Наиболее интересный для меня раздел по CE Lua плагинам.

      5. Отличный форум "FearLess Cheat Engine"
        Лучшие авторы. Можно найти их сообщения. Перейти

      6. Книга программиста из Electronic Arts. Создание игр на C++. Офиц. версия

      7. Семантическое Версионирование 2.0.0. Всегда хотел узнать что означают точки в названии версии? Тогда сюда

      Продолжение следует...

      написал в Статьи todo источники
      MasterGHM
      MasterGH
    • RE: Защита Трейнера

      Мой вариант был не рабочий. Я толком не проверил, потому что мой бинарник тоториала не подходил.

      Рабочий вариант. Если хочешь, то попробуй запустить мой вариант (если нужен, то мой exe туториала там же). А потом из моего примера сделать твой, который заработает на двух бинарниках.

      написал в Вопросы
      MasterGHM
      MasterGH
    • RE: Рубрика "Lua код сегодня" №5 (активирующий скрипт)

      Update:
      Если скрипт не запускается, то вызывать reinitializeSymbolhandler(true)
      Пример здесь

      написал в Обучающие примеры
      MasterGHM
      MasterGH
    • Запустить активирющий скрипт CE 7.5

      Tutorial-i386.CT

      Бинарник тутораала(шаг1):Tutorial-i386.zip

      Смысл в следующем. Нужно активирующий скрипт перенести в Lua. Как оказалось для корректности нужно использовать reinitializeSymbolhandler(true)

      aa_script = [[
      { Game   : Tutorial-i386.exe
        Version:
        Date   : 2023-04-08
        Author : 79777
      
        This script does blah blah blah
      }
      
      [ENABLE]
      aobscanmodule(INJECT_tut1,Tutorial-i386.exe,81 BB B0 04 00 00 E8 03 00 00)
      
      alloc(newmem,$1000)
      alloc(newmem2,$1000)
      label(code)
      label(return)
      label(pointer_ebx)
      registersymbol(pointer_ebx)
      
      newmem2:
      pointer_ebx:
       dd 00
      
      newmem:
        mov [pointer_ebx],ebx
      code:
        cmp [ebx+000004B0],000003E8
        jmp return
      
      INJECT_tut1:
        jmp newmem
        nop 5
      return:
      registersymbol(INJECT_tut1)
      
      [DISABLE]
      //code from here till the end of the code will be used to disable the cheat
      INJECT_tut1:
        db 81 BB B0 04 00 00 E8 03 00 00
      
      unregistersymbol(INJECT_tut1)
      dealloc(newmem)
      dealloc(newmem2)
      
      {
      // ORIGINAL CODE - INJECTION POINT: Tutorial-i386.exe+25DD3
      
      Tutorial-i386.exe+25DC1: 85 C0                          - test eax,eax
      Tutorial-i386.exe+25DC3: 74 05                          - je Tutorial-i386.exe+25DCA
      Tutorial-i386.exe+25DC5: E8 B6 7D FE FF                 - call Tutorial-i386.exe+DB80
      Tutorial-i386.exe+25DCA: 5E                             - pop esi
      Tutorial-i386.exe+25DCB: 5B                             - pop ebx
      Tutorial-i386.exe+25DCC: 89 EC                          - mov esp,ebp
      Tutorial-i386.exe+25DCE: 5D                             - pop ebp
      Tutorial-i386.exe+25DCF: C3                             - ret
      Tutorial-i386.exe+25DD0: 53                             - push ebx
      Tutorial-i386.exe+25DD1: 89 C3                          - mov ebx,eax
      // ---------- INJECTING HERE ----------
      Tutorial-i386.exe+25DD3: 81 BB B0 04 00 00 E8 03 00 00  - cmp [ebx+000004B0],000003E8
      // ---------- DONE INJECTING  ----------
      Tutorial-i386.exe+25DDD: 75 2D                          - jne Tutorial-i386.exe+25E0C
      Tutorial-i386.exe+25DDF: 8B 83 9C 04 00 00              - mov eax,[ebx+0000049C]
      Tutorial-i386.exe+25DE5: B2 01                          - mov dl,01
      Tutorial-i386.exe+25DE7: 8B 8B 9C 04 00 00              - mov ecx,[ebx+0000049C]
      Tutorial-i386.exe+25DED: 8B 09                          - mov ecx,[ecx]
      Tutorial-i386.exe+25DEF: FF 91 20 02 00 00              - call dword ptr [ecx+00000220]
      Tutorial-i386.exe+25DF5: 8B 83 A8 04 00 00              - mov eax,[ebx+000004A8]
      Tutorial-i386.exe+25DFB: 30 D2                          - xor dl,dl
      Tutorial-i386.exe+25DFD: 8B 8B A8 04 00 00              - mov ecx,[ebx+000004A8]
      Tutorial-i386.exe+25E03: 8B 09                          - mov ecx,[ecx]
      }
      ]]
      
      
      function onOpenProcess()
        reinitializeSymbolhandler(true)
        local checkOk, errMsg = autoAssembleCheck(aa_script, true, false)
        if not checkOk then
           print('Ошибка в активирующем скрипте')
           print(errMsg)
           return
        end
      
        is_enabled, disabled_info = autoAssemble(aa_script)
      
        if not is_enabled then
           print('Ошибка. Не запущен активирующий скрипт')
        end
      end
      
      getAutoAttachList().add("Tutorial-i386.exe")
      
      написал в Управление ce aa active rec ce lua важно
      MasterGHM
      MasterGH
    • Заполнение разделов старыми постами

      Перенос старых тем, постов, блогов, видео по разделам

      написал в Новости todo
      MasterGHM
      MasterGH
    • RE: Ваши группы пользователей

      В ступать и выходить из групп можно самому без админа? (Проверить)

      написал в Новости
      MasterGHM
      MasterGH
    • RE: CE Lua чистка памяти от утечек

      Оптимизация CE Lua кода по сборке мусора

      Есть инструкции, которые добавляют мусора больше чем другие.
      Показываем объем памяти мусора

      print(string.format('Lua memory usage %.1f MiB',collectgarbage('count')/1024))
      

      Ниже код того как попробовать узнать сколько мусора добавил код при парсинге ассемблерной строки двумя способами

      local s = " 0045464A - FF 05 A4B54500        - inc [0045B5A4] { [000003EA] }"
      
      function GetDebugString(address)
        return splitDisassembledString(s)
      end
      
      \-- address, bytes, opcode
      function GetDebugString2(address)
        local clearString = string.gsub(s, '%s','')
        return string.match(clearString, '^(.-)%-(.-)%-(.-)$')
      end
      
      function NoOptimizeCode()
        GetDebugString2()
      end
      
      function OptimizeCode()
        GetDebugString()
      end
      
      local countRepeat = 500000 -- add more cycle
      local x1 = 0
      local x2 = 0
      
      x1 = getTickCount()
      print(string.format('Lua memory usage %.1f MiB',collectgarbage('count')/1024))
      for i = 1, countRepeat do NoOptimizeCode() end
      print(string.format('Lua memory usage %.1f MiB',collectgarbage('count')/1024))
      x2 = getTickCount()
      for i = 1, countRepeat do OptimizeCode() end
      print(string.format('Lua memory usage %.1f MiB',collectgarbage('count')/1024))
      
      print(string.format("%.2f", (x2 - x1)/(getTickCount() - x2)) )
      

      Пример результатов могут отличаться. Фиг его знает почему. Возможно работает сборщик мусора в разные моменты времени

      Lua memory usage 1.8 MiB
      Lua memory usage 1.8 MiB
      Lua memory usage 1.8 MiB
      1.49

      Lua memory usage 1.8 MiB
      Lua memory usage 2.3 MiB
      Lua memory usage 2.3 MiB
      1.47

      Lua memory usage 2.3 MiB
      Lua memory usage 2.8 MiB
      Lua memory usage 2.8 MiB
      1.49

      написал в Плагин-строй
      MasterGHM
      MasterGH
    • Работа с системой контроля версий в команде разработчиков

      Инфа по совместной работе с гитом. Может быть пригодится кому, а может и нет. Такую систему я использую на работе недавно.

      Можно совместно работать над одним большим проектом через git-flow. Возможно, кто-то из форумчан тоже использует git flow на работе.

      git-flow — это набор расширений git предоставляющий высокоуровневые операции над репозиторием для поддержки модели ветвления Vincent Driessen.

      Кратко. Модель контроля версии построена на 4 ветках

      master - релизы
      develop - разработка
      feature - фичи
      hotfix - исравления

      С develop начинается разработка через копирования в ветку feature.
      Над фичей идет работа, а после завершения feature мержится с develop и feature сразу удаляется.
      После запланированных изменений develop мержится с master уходя в релиз.
      Если возникли баги, то от master создается ветвь на hotfix . После фиксов hotfix мержится с master.

      Доступ к мастер ветки может иметь один человек или его доверенные лица. Ветка Develop открыта для разработчиков. Это значит, что множество разработчиков колдуют в Develop ветке, а мержит изменения с master уже главный разработчик или несколько главных разработчиков.

      В мастере создаются теги с обозначением версии.

      Учитывая номер версии МАЖОРНАЯ.МИНОРНАЯ.ПАТЧ, следует увеличивать:

      МАЖОРНУЮ версию, когда сделаны обратно несовместимые изменения API.
      МИНОРНУЮ версию, когда вы добавляете новый функционал, не нарушая обратной совместимости.
      ПАТЧ-версию, когда вы делаете обратно совместимые исправления.
      Дополнительные обозначения для предрелизных и билд-метаданных возможны как дополнения к МАЖОРНАЯ.МИНОРНАЯ.ПАТЧ формату.

      git-flow заметки
      Семантическое версионирование

      написал в Справочники git-flow версионирование
      MasterGHM
      MasterGH
    • RE: CE вывод списка записей и вывод свойств компонентов

      Ищем свойства userData.

      UserData в Lua это пользовательский тип. Точно не знаю, но я думаю в документации в CE Lua (celua.txt или здесь на офф. сайте) тип userData у всех классов или большинства классов. Например, проверим, что главная форма CE это userData тип

      local mainFormCE = getMainForm()
      print(type(mainFormCE))
      
       > userdata (вывод из консоли)
      

      Выводим список свойств следующим образом через getmetatable функцию. Метатаблица — это особая таблица свойств Lua-переменной

      local mainForm = getMainForm()
      local listUserData = createStringlist()
      
      for k,_ in pairs(getmetatable(mainForm)) do
        listUserData.add(k)
      end
      
      local allowCustomInput = false
      local id, name = showSelectionList("Title", "Caption", listUserData, allowCustomInput)
      print ('Index: '..id..", Name: "..name)
      
      listUserData.destroy()
      

      Результат в виде списка свойство переменной mainForm
      1a800863-fb55-46e7-a2b0-b3daed1613af-изображение.png
      Чтобы наглядно было. Свойства эти похожи на свойства из Дельфи. Можно загуглить, они поддробно описываются.

      Берем например свойство цвет. Прочитаем оригинальное и запишем свое любое

      local mainFormCE = getMainForm()
      print(mainFormCE.getColor())
      
      > 536870912 -- в hex-е это 0x20000000. Можно перевести в калькуляторе или через print(string.format("%08X", 536870912))
      

      Случайное свое впишем ради наглядного примера
      mainFormCE.setColor(546484)

      72d5c265-f388-4d4f-b24c-f3dcb46d8f39-изображение.png

      написал в Плагин-строй
      MasterGHM
      MasterGH
    • Lua ООП конспект

      Пригодится для создания больших плагинов в Cheat Engine. Более ~500 строк

      Наследование

      ClassX = {}
      
      	function ClassX:New(_argument1, _argument2)
      
      		local obj = {}
      		obj.argument1 = _argument1
      		obj.argument2 = _argument2
      
      		-- Через "self"
      		function obj:GetValue1() return obj.argument1 end
      		function obj:GetValue2() return obj.argument2 end
      
      		setmetatable(obj, self)
      		obj.__index = ClassX
      		return obj
      	end
      
      	someObject = ClassX:New("A", "B")
      	print(someObject.GetValue1())
      	print(someObject.GetValue2())
      
      
         	Woman = {}
      	--наследуемся
      	setmetatable(Woman ,{__index = ClassX})
      	--проверяем
      	masha = Woman:New("Марья","Ивановна")
      	print(masha:GetValue1())  --->результат: Марья
      

      Инкапсуляция

      Person = {}
      	function Person:new(name)
      		--приватное свойство
      		local private = {}
      		private.age = 18
      
      		local obj = {}
      		--публичное свойство
      		obj.name = name or "Вася"   -- "Вася" - это значение по умолчанию
      
      		function obj:getAge() return private.age end
      
      		setmetatable(obj,self)
      		self.__index = self
      		return obj
      	end
      
      	vasya = Person:new()
      	print(vasya.name)          --> результат: Вася
      	print(vasya.age)           --> результат: nil
      	print(vasya:getAge())     --> результат: 18
      

      Полиморфизм

      Person = {}
      	function Person:New(name)
      		local private = {}
      		private.age = 18
      
      		local obj = {}
      		obj.name = name or "Вася"
      		-- Защищенный от переорпеделения
      		function obj:GetName() return "Person protected "..self.name end
      		-- Переопределяемый
      		function Person:GetName2() return "Person "..self.name	end
      
      		setmetatable(obj, self)
      		self.__index = self
      		return obj
      	end
      
      	--создадим класс, унаследованный от Person
      	Woman = {}
      	setmetatable(Woman,{__index = Person})
      	function Woman:GetName() return "Woman protected "..self.name end
      	function Woman:GetName2() return "Woman "..self.name end
      
      	--проверим
      	masha = Woman:New()
      	print(masha:GetName())   --> Person protected Вася
      	print(masha:GetName2())  --> Woman Вася
      

      ref

      написал в Справочники ce lua oop
      MasterGHM
      MasterGH
    • FPU инструкция FINCSTP. Очистка ST(0)

      Команда FINCSTP добавляет единицу (без переноса) к трехбитному полю TOP слова состояния FPU.

      Эффект действия команды FINCSTP заключается во вращении стека. Она не изменяет регистров тэгов и не перемещает данные. Она не эквивалентна операции выталкивания из стека, потому что, она не устанавливает тэг старой вершины стека в значение пустой.

      Флаги C0, C2, C3 регистра SW после выполнения команды не определены, флаг C1 устанавливается равным 0.

      Похожа на FSTP, также вращает стек регистров FPU (я кстати не знал, увидел при тестах в CE), но только не перемещает значение по адресу.

      FSTP [здесь указывается адрес или регистр]
      FINCSTP
      

      Если нужно вытолкнуть значение из ST(0), а адрес куда его выталкивать не нужен, то можно сделать так FINCSTP Или аналог FSTP ST(0)

      При использовании стоит обратить внимание на флаги, возможно их состояние будет влиять на исполнение кода.
      6260cbac-426b-48f3-bbb1-159a31ee36f6-изображение.png
      *Вообще не помню почему я пишу "выталкивать значение" через fstp, когда оно появляется снизу в ST(8). Т.е. не выталкивается по сути.

      написал в Справочники ce aa fincstp
      MasterGHM
      MasterGH
    • RE: Сравнение времени выполнения двух функций

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

      local x = os.clock()
      local s = 0
      for i=1,100000 do s = s + i end
      print(string.format("elapsed time: %.3f\n", os.clock() - x))
      

      После выполнения, показывает 2 тысячных секунды или 2 мс

      elapsed time: 0.002
      

      Можно посчитать прошедшее время для другой цели. Например, если цикл в отладке выполняется более 3 секунд, то это вероятно корневой цикл, а если менее, то это вложенный цикл. На корневом цикле можно остановить трейслог. Об этом может быть потом напишу.

      написал в Обучающие примеры
      MasterGHM
      MasterGH
    • Функция autoAssemble

      Функция autoAssemble это Lua функция, которая позволяет скопилировать ассемблерный код активации и деактивации. Пример ниже

      \-- Скрипт похожий на таблицу АА
      InfiniteHealthScript = [[
      [ENABLE]
      alloc(InfiniteHealth,2048,BlackOps3.exe)
      aobscanmodule(InfiniteHealthAOB,BlackOps3.exe,8B 83 C8 02 00 00 48 8B)
      registersymbol(InfiniteHealthAOB)
      label(return)
      
      InfiniteHealth:
        mov [rbx+000002C8],#999
        jmp return
      
      InfiniteHealthAOB:
        jmp InfiniteHealth
        nop
      return:
      
      [DISABLE]
      InfiniteHealthAOB:
        db 8B 83 C8 02 00 00
      
      unregistersymbol(InfiniteHealthAOB)
      
      dealloc(InfiniteHealth)
      ]]
      
      \-- Функция активации
      function enableInfiniteHealthCheat()
        -- Если чит был выключен, то только тогда сработает деактивация
        if not InfiniteHealthCheatIsEnabled then
          InfiniteHealthCheatIsEnabled,InfiniteHealthCheatDisableinfo = autoAssemble(InfiniteHealthScript)
        end
      end
      
      \-- Функция деактивации
      function disableInfiniteHealthCheat()
        -- Если чит был включен, то только тогда сработает активация
        if InfiniteHealthCheatIsEnabled then
          if autoAssemble(InfiniteHealthScript,InfiniteHealthCheatDisableinfo) then
            InfiniteHealthCheatIsEnabled = false
          end
        end
      end
      
      написал в Приёмы ce aa ce lua autoassemble
      MasterGHM
      MasterGH
    • CE Lua чистка памяти от утечек

      Хотя в последних версиях CE включили чистку памяти (надеюсь, что эта функция была и есть). Но может пригодится очистка памяти. Вдруг?

      ИМХО отказываться от CE Lua скриптов из-за утечек памяти не стоит, если такая происходит. Т.е. оперативная память забивается каким-то мусором. Это бывает редко, когда пилишь плагины.

      Можно чистить память следующим образом

      function startCollectgarbageProcess(interval, showStatus)
        local timer1 = createTimer(true)  
        timer1.Interval = interval  
        timer1.onTimer = function ()  
          if (showStatus) then
            print(string.format('Lua memory usage %.1f MiB',collectgarbage('count')/1024))
          end 
          collectgarbage("restart")
          collectgarbage("collect")    
          if (showStatus) then
            print(string.format('Lua memory usage %.1f MiB',collectgarbage('count')/1024))
          end    
        end
      end
      
      \-- Собирать каждую 1 минуту и показать результат
      startCollectgarbageProcess(60000, true)
      
      написал в Плагин-строй ce lua ce plugin memory leak
      MasterGHM
      MasterGH
    • 1
    • 2
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 9 / 13