SQLite with Python: Introduction and triggers
Python is pretty great, and SQLite is pretty great too. Can they be pretty great together? Yes!
This will be a short tutorial on how to do it with sqlite3 , which is part of the Python Standard Library. I’ll provide a lightning introduction to general usage, and how to create a trigger that will do automatic logging for you.
Let’s get started by importing sqlite3 :
One nice thing is that if you try to connect to a database that doesn’t exist, sqlite3 will create it.
If this is not a nice thing to you – perhaps because you want to rely on Python throwing an error if it doesn’t find the file – you could first check if the database file exists using os :
import os.path if not os.path.isfile('mydb.sqlite'): print('Where is it?')
Let’s create a new database file by trying to connect to it:
connection = sqlite3.connect('mydb.sqlite') c = connection.cursor()
I didn’t know what a cursor was until I started working with sqlite3 . You can read a simple explanation at the Wikipedia page.
sqlite3 created the database file for us. Now let’s create two tables:
c.execute('CREATE TABLE bikes (id INTEGER PRIMARY KEY, brand TEXT, model TEXT, size INTEGER)') c.execute('CREATE TABLE bike_logs (bike_id INTEGER, time_added TIMESTAMP)')
We created two tables. bikes is a table that will store bike id, brand, model, and frame size, and bike_logs is a logging table that we will use to record timestamps of when each bike was added.
The second table is an excuse to demonstrate how to create a trigger with sqlite3 . The trigger is executed whenever a row is added to the bikes table, and its job is to add a row of the bike id and timestamp to the bike_logs table.
c.execute('''CREATE TRIGGER bike_logger AFTER INSERT ON bikes BEGIN INSERT INTO bike_logs (bike_id, time_added) VALUES (new.id, strftime('%s', 'now')); END ; ''')
Learning how to create the trigger using sqlite3 took me a long time. I think SQLite is particular about the placement of the semicolons ; . Based on my trial and error, the ; at the end of INSERT INTO. as well as the ; after END is crucial.
Now let’s add a couple of bikes:
c.execute("INSERT INTO bikes (brand, model, size) VALUES ('State Bicycle', 'Contender', 52 )") c.execute("INSERT INTO bikes (brand, model, size) VALUES ('Ritte', 'Vlaandren', 51)") connection.commit()
… and check to see if everything worked:
c.execute('SELECT * FROM bikes') for bike in c.fetchall(): print(bike)
(1, 'State Bicycle', 'Contender', 52) (2, 'Ritte', 'Vlaandren', 51)
Good. The Contender and Vlaandren are there in the bikes table, and they were automatically given ids 1 and 2 .
c.execute('SELECT * FROM bike_logs') for log in c.fetchall(): print(log)
(1, 1468376023) (2, 1468376023)
Nice! The bike ids are there, along with the unix epoch timestamp of when the rows were added.
Before we leave, we’ll close the connection.
Closing note
I’m pretty new to SQL. If you find any mistakes or bad practices in my code, please leave a comment.
See also:
- A thorough guide to SQLite database operations in Python. This is a great introductory post to using sqlite3 . It covers a lot of ground. The only missing point is creating triggers, which is why I wrote my post.
Take no one’s word for it · © 2012–2023 Sherif Soliman
Subscribe to the posts, album notes, and book notes feeds.
Гайд Гайд по написанию триггер-бота на Python
Этот гайд для тех кто только осваивает мир читов и все что с ними связано. Я постарался расписать все подробно чтобы было понятно и наглядно.
Дисклеймер: данный гайд написан мой(новичком в этом деле), если у вас есть улучшения данного кода пишите, хорошо отношусь к критике!
И так разберем каждую строчку кода
- «import keyboard» импортирует модуль keyboard для работы с клавиатурой.
- «import pymem» и «import pymem.process» импортируют модули pymem и pymem.process для работы с памятью процесса.
- «dwEntityList = (0x4DFFF14)» и следующие строки определяют константы с адресами в памяти, используемыми далее в коде.
- «pm = pymem.Pymem(«csgo.exe»)» создает экземпляр класса Pymem для работы с процессом csgo.exe.
- «client = pymem.process.module_from_name(pm.process_handle, «client.dll»).lpBaseOfDll» получает базовый адрес модуля client.dll в памяти процесса.
- «trigger_key = «shift»» определяет, что клавишей-триггером будет шифт.
- «def main():» определяет функцию main, которая будет запущена при запуске скрипта.
- «print(«TriggerBot enabled!»)» выводит сообщение о том, что триггербот включен.
- «shooting = False» инициализирует переменную shooting как False.
- «while True:» запускает бесконечный цикл.
- «player = pm.read_int(client + dwLocalPlayer)» получает адрес локального игрока из памяти процесса.
- «if keyboard.is_pressed(trigger_key):» проверяет, нажата ли клавиша-триггер. Если нажата, то выполняется следующий код.
- «if player is not None:» проверяет, найден ли локальный игрок. Если найден, то выполняется следующий код.
- «if pm.read_int(player + m_iCrosshairId) > 0 and pm.read_int(player + m_iCrosshairId)
- «if pm.read_int(player + m_fFlags) & 0x1:» проверяет, что бит флага «движения» в памяти установлен в 1.
- «for i in range(64):» запускает цикл, в котором перебираются все сущности в списке.
- «entity = pm.read_int(client + dwEntityList + i * 0x10)» получает адрес сущности из памяти процесса.
Умножение на 0x10 в этой строке необходимо для того, чтобы перебрать все сущности в списке. Список сущностей в игре хранится в памяти процесса как массив и каждая сущность имеет свой адрес в памяти. Адреса соседних сущностей в массиве расположены на определенном расстоянии друг от друга, которое и задается умножением на 0x10. Это значит, что каждый следующий элемент списка имеет адрес, который на 0x10 больше предыдущего. - «entity_team = pm.read_int(entity + m_iTeamNum)» получает идентификатор команды сущности из памяти процесса.
- «player_team = pm.read_int(player + m_iTeamNum)» получает идентификатор команды локального игрока из памяти и процесса.
- «if player_team != entity_team:» проверяет, что команда сущности не совпадает с командой локального игрока.
- «shooting = True» устанавливает значение переменной shooting в True.
- «pm.write_int(client + dwForceAttack, 5)» записывает значение 5 в память процесса для выстрела.
- «break» прерывает цикл.
- «if not keyboard.is_pressed(trigger_key) and shooting == True:» проверяет, что клавиша-триггер не нажата и shooting имеет значение True.
- «pm.write_int(client + dwForceAttack, 4)» записывает значение 4 в память процесса для отпускания кнопки мыши.
- «shooting = False» устанавливает значение переменной shooting в False.
- «if name == ‘main‘:» проверяет, что скрипт запущен как главный.
- «main()» запускает функцию main.
Использовать данный код только в ознакомительных целях, использования данного кода в игре приведет к блокировки вашего игрового аккаунта!
import keyboard import pymem import pymem.process dwEntityList = (0x4DFFF14) dwForceAttack = (0x322DD10) dwLocalPlayer = (0xDEA964) m_fFlags = (0x104) m_iCrosshairId = (0x11838) m_iTeamNum = (0xF4) pm = pymem.Pymem("csgo.exe") client = pymem.process.module_from_name(pm.process_handle, "client.dll").lpBaseOfDll trigger_key = "shift" def main(): print("TriggerBot enabled!") shooting = False while True: player = pm.read_int(client + dwLocalPlayer) if keyboard.is_pressed(trigger_key): # проверяем наличие игрока if player is not None: # проверяем память if pm.read_int(player + m_iCrosshairId) > 0 and pm.read_int(player + m_iCrosshairId)