Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- 【 LICENCE 】
- --------------------------------------------------------------------------------
- -- The MIT License (MIT)
- --
- -- Copyright (c) mece from opencheattables.org
- --
- -- Permission is hereby granted, free of charge, to any person obtaining a
- -- copy of this software and associated documentation files (the "Software"),
- -- to deal in the Software without restriction, including without limitation
- -- the rights to use, copy, modify, merge, publish, distribute, sublicense,
- -- and/or sell copies of the Software, and to permit persons to whom the
- -- Software is furnished to do so, subject to the following conditions:
- --
- -- The above copyright notice and this permission notice shall be included in
- -- all copies or substantial portions of the Software.
- --
- -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- -- DEALINGS IN THE SOFTWARE.
- --------------------------------------------------------------------------------
- -- 【 FILE INFO 】
- -- ㅤ❖ This is an extention for Cheat Engine 7.4 (https://cheatengine.org)
- --
- -- 【 FEATURES 】
- -- ㅤ❖ Adds 'Structure picker' menu item into the 'Structures' menu
- -- ㅤㅤ of 'Structure dissect' window (default shortcut Ctrl+D)
- -- ㅤ❖ New menu opens 'Structure picker' window with all global structures
- -- ㅤ❖ 'Structure picker' automatically selects the main structure of
- -- ㅤㅤ the 'Structure dissect' foreground window
- -- ㅤ❖ Selecting structure from the 'Structure picker' replaces the main
- -- ㅤㅤ structure of the 'Structure dissect' foreground window
- -- ㅤ❖ 'Structure picker' contains a text filter which helps to find
- -- ㅤㅤ a structure in a long list
- -- ㅤ❖ 'Up' and 'Down' arrow keys transfer focus from the filter to
- -- ㅤㅤ the list and used to navigate
- -- ㅤ❖ 'Ctrl+F' transfers focus from the list to the filter
- -- 【 HOW TO INSTALL 】
- -- ㅤ❖ Place the .lua file in CE autorun folder. Could be:
- -- ㅤㅤ C:\Program Files\Cheat Engine 7.4\autorun
- -- ㅤ❖ Place the .frm file in CE autorun\forms folder. Could be:
- -- ㅤㅤ C:\Program Files\Cheat Engine 7.4\autorun\forms
- --
- -- 【 CHANGE LOG 】
- -- ㅤ⋯ 2022-06-09 ⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯
- -- ㅤ❖ initial version
- --
- -- 【 CONTACT THE AUTHOR 】
- -- ㅤ❖ https://forum.cheatengine.org/profile.php?mode=viewprofile&u=388402
- -- ㅤ❖ https://opencheattables.org/memberlist.php?mode=viewprofile&u=239
- --
- --------------------------------------------------------------------------------
- local sp = {}
- --------------------------------------------------------------------------------
- local function isValidStructureFrm(frm)
- return frm and (frm.ClassName=='TfrmStructures2')
- end
- --------------------------------------------------------------------------------
- local function updateGlobalStructureList()
- local needUpdate = getStructureCount() ~= #sp.globalStructureList
- if needUpdate then sp.globalStructureList = {} end
- for i=0,getStructureCount()-1 do
- local s = getStructure(i)
- needUpdate = needUpdate or (sp.globalStructureList[i+1] ~= s) or (sp.globalStructureList[i+1].OldName ~= s.Name)
- sp.globalStructureList[i+1] = s
- sp.globalStructureList[i+1].OldName = s.Name
- end
- return needUpdate
- end
- --------------------------------------------------------------------------------
- local function lookupListBoxData(listBox, needle)
- local index = -1
- for i=0,listBox.Items.Count-1 do
- if integerToUserData(listBox.Items.Data[i]) == needle then
- index = i
- break
- end
- end
- return index
- end
- --------------------------------------------------------------------------------
- local function filtered(haystack)
- local result = nil
- local needle = sp.picker.CEEditFilter.Text
- if needle and needle ~= '' then
- result = not string.find(string.upper(haystack), string.upper(needle),1,true)
- end
- return result
- end
- --------------------------------------------------------------------------------
- local function changeSelection(listBox, newIndex)
- listBox.clearSelection()
- listBox.ItemIndex = newIndex
- if newIndex >= 0 then
- listBox.Selected[newIndex] = true
- end
- end
- --------------------------------------------------------------------------------
- local function clearSelection(listBox)
- listBox.clearSelection()
- listBox.ItemIndex = -1
- end
- --------------------------------------------------------------------------------
- local function selectedData(listBox)
- local data = nil
- local idx = listBox.itemIndex
- if idx >= 0 and listBox.Selected[idx] then
- data = integerToUserData(listBox.Items.Data[idx])
- end
- return data
- end
- --------------------------------------------------------------------------------
- local function selectMainStructure(form)
- local listBox = sp.picker.CEListBoxStructures
- if form.MainStruct and listBox.Items.Count > 0 then
- if form.MainStruct ~= selectedData(listBox) then
- changeSelection(listBox, lookupListBoxData(listBox, form.MainStruct))
- end
- else
- clearSelection(listBox)
- end
- end
- --------------------------------------------------------------------------------
- local function updateCEListBoxStructures()
- local items = sp.picker.CEListBoxStructures.Items
- items.beginUpdate()
- items.clear()
- for i=0,getStructureCount()-1 do
- local structure = getStructure(i)
- if not filtered(structure.Name) then
- items.add(structure.Name, userDataToInteger(structure))
- end
- end
- items.endUpdate()
- if isValidStructureFrm(sp.focused) then
- selectMainStructure(sp.focused)
- end
- end
- --------------------------------------------------------------------------------
- local function setMainStruct(form, struct)
- form.MainStruct = nil
- form.MainStruct = struct
- form.structChange()
- end
- --------------------------------------------------------------------------------
- function CEFormStructurePicker_CEListBoxStructuresSelectionChange(listBox, user)
- if user and listBox.Selected[listBox.ItemIndex] then
- local selected = selectedData(listBox)
- local form = sp.focused
- if isValidStructureFrm(form) and form.MainStruct ~= selected then
- setMainStruct(form, selected)
- end
- end
- end
- --------------------------------------------------------------------------------
- function CEFormStructurePicker_CETimerStructurePickerTimer(thisTimer)
- if sp.picker.Visible then
- if updateGlobalStructureList() then
- updateCEListBoxStructures()
- end
- local form = sp.focused
- if isValidStructureFrm(form) and form.oldMainStruct ~= form.MainStruct then
- selectMainStructure(form)
- form.oldMainStruct = form.MainStruct
- end
- end
- end
- --------------------------------------------------------------------------------
- function CEFormStructurePicker_CEEditFilterChange(editBox)
- updateCEListBoxStructures()
- if isValidStructureFrm(sp.focused) then
- selectMainStructure(sp.focused)
- end
- end
- --------------------------------------------------------------------------------
- function CEFormStructurePicker_CEEditFilterKeyDown(sender, key)
- if key == VK_DOWN or key == VK_UP then
- sp.picker.CEListBoxStructures.setFocus()
- doKeyPress(key)
- end
- return key
- end
- --------------------------------------------------------------------------------
- function CEFormStructurePicker_CEListBoxStructuresKeyPress(sender, key)
- -- https://www.windmill.co.uk/ascii-control-codes.html
- if string.byte(key) == 6 then -- Ctrl+F
- sp.picker.CEEditFilter.setFocus()
- return nil
- end
- return key
- end
- --------------------------------------------------------------------------------
- local function file_exists(file_path)
- local f = io.open(file_path, "r")
- return f ~= nil and io.close(f)
- end
- --------------------------------------------------------------------------------
- if sp_structureFrmAddNotification then
- unregisterFormAddNotification(sp_structureFrmAddNotification)
- end
- sp_structureFrmAddNotification = registerFormAddNotification(function(form)
- if isValidStructureFrm(form) then
- local callback = form.registerCreateCallback(function(form)
- form.OnActivate = function(form)
- sp.focused = form
- if sp.picker.Visible then
- if isValidStructureFrm(form) then
- selectMainStructure(form)
- end
- end
- end
- form.unregisterCreateCallback(callback)
- local ownermenu = form.Structures1
- local mi = createMenuItem(ownermenu)
- ownermenu.insert(2, mi)
- mi.Caption = "Structure picker"
- mi.ImageIndex = 15
- mi.Shortcut = "Shift+D"
- mi.OnClick = function()
- updateCEListBoxStructures()
- sp.picker.Left = form.Left + form.Width
- sp.picker.Top = form.Top
- sp.picker.show()
- end
- end)
- end
- end)
- --------------------------------------------------------------------------------
- local pathsep = getOperatingSystem() and [[\]] or [[/]]
- local forms_path = getAutoRunPath()..'forms'..pathsep
- local file_path = forms_path .. 'StructurePicker.FRM'
- local CEFormWindowSwitcher = nil
- if file_exists(file_path) then
- CEFormWindowSwitcher = createFormFromFile(file_path)
- sp.picker = CEFormWindowSwitcher
- sp.picker.CEEditFilter.Text = ''
- sp.focused = nil
- sp.globalStructureList = {}
- else
- print(file_path .. " not found!")
- end
- --------------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement