Skip to content

Commit

Permalink
Initial code finished
Browse files Browse the repository at this point in the history
  • Loading branch information
caiocinel committed Jul 10, 2023
1 parent d98f7ce commit 620aa66
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 20 deletions.
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,15 @@
# gartic-dalle

# Gartic DALL·E
Uma implementação para gerar e desenhar imagens usando inteligência artificial no Gartic.com.br

## Instalação e Uso
- Abra o arquivo ``main.py`` e defina sua chave de API da OpenAI [(pegue-a aqui)](https://platform.openai.com/account/api-keys) na primeira linha
- Execute o arquivo ``main.py``

## Avisos
- O Gartic implementou uma proteção contra desenhos automatizados, então se a imagem possuir muitos pixeis, você será desconectado pelo sistema
- O script roda baseado no Google Chrome (pois o Firefox não possui as APIs necessárias), portanto ele também é um requisito para funcionamento.

## TODO
- Uma forma de "bypassear" a proteção contra desenhos automatizados
- Suportar também o [gartic.io](https://gartic.io)
- Um overlay para melhor visualização do stdout
66 changes: 48 additions & 18 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,53 @@
OPENAI_API_KEY = "API KEY here"

import importlib.util
import sys
import subprocess


# Check if all dependencies are installed
if selenium := importlib.util.find_spec("selenium") is None:
subprocess.check_call([sys.executable, "-m", "pip", "install", 'selenium'])

if openai := importlib.util.find_spec("openai") is None:
subprocess.check_call([sys.executable, "-m", "pip", "install", 'openai'])

if PIL := importlib.util.find_spec("PIL") is None:
subprocess.check_call([sys.executable, "-m", "pip", "install", 'Pillow'])

if requests := importlib.util.find_spec("requests") is None:
subprocess.check_call([sys.executable, "-m", "pip", "install", 'requests'])



from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
from env import OPENAI_API_KEY
import openai
from PIL import Image
from io import BytesIO
import requests
from datetime import datetime

openai.api_key = "API KEY here" #OPENAI_API_KEY
openai.api_key = OPENAI_API_KEY

browser = webdriver.Chrome()
browser.get("https://gartic.com.br/")

alreadyDrawed: list[dict[str, str]] = []
# this list is used to fetch the word only once, {word: "word", url: "url"}
alreadyDrawed: list[dict[str, str]] = []

while True:
# If user is in a room
if browser.find_elements(By.CSS_SELECTOR, ".btPular").__len__() == 0:
print("Not in a Room")
sleep(1)
sleep(5)
continue

# If user is drawing
if not browser.find_element(By.CSS_SELECTOR, ".btPular").is_displayed():
print("Not drawing")
sleep(1)
continue

# Get the word to draw
element = browser.find_elements(By.CSS_SELECTOR, ".contentSpan")
if element.__len__() == 0:
sleep(5)
Expand All @@ -39,6 +61,7 @@

print("Drawing: " + value)

# Check if the word was already drawed, prevent to fetch the same word twice
if not any(d["word"] == value for d in alreadyDrawed):
print("Fetching image...")

Expand All @@ -51,44 +74,51 @@
alreadyDrawed.append(
{
"word": value,
"url": "https://i.imgur.com/FTgo0DQ.png",
"url": response['images'][0]['url'],
}
)
print("Fetching done...")

print(
f"Image link: {next((item for item in alreadyDrawed if item['word'] == value), None)['url']}"
)

img = Image.open(BytesIO(requests.get(next((item for item in alreadyDrawed if item['word'] == value), None)['url']).content))

browser.execute_script("arguments[0].value = 1; arguments[0].dispatchEvent(new Event('change'))", browser.find_element(By.CSS_SELECTOR, "#tamanho"))

#Change brush size to 1px
browser.execute_script("arguments[0].value = 1; arguments[0].dispatchEvent(new Event('change'))", browser.find_element(By.CSS_SELECTOR, "#tamanho"))

drawElement = browser.find_element(By.CSS_SELECTOR ,"#telaCanvas > canvas:nth-child(2)")
action = webdriver.ActionChains(driver=browser, duration=0)


#Block gartic drawing backend url to prevent disconnects while drawing
print("Blocking Gartic servers...")
browser.execute_cdp_cmd('Network.setBlockedURLs', {"urls": ["gartic.com.br/room/atualizar.php"]})
browser.execute_cdp_cmd('Network.enable', {})


print("Start drawing...")
for x in range(img.width):
for y in range(img.height):
pixel = img.load()[x, y]

if (pixel[0] > 250 and pixel[1] > 250 and pixel[2] > 250):
# If pixel is white then skip (background already is white, best performance)
if (pixel[0] > 250 and pixel[1] > 250 and pixel[2] > 250):
continue

# Change color to pixel color
browser.execute_script(f"arguments[0].setAttribute('codigo', '{'%02x%02x%02x' % (pixel[0], pixel[1], pixel[2])}'); arguments[0].dispatchEvent(new Event('click'))", browser.find_element(By.CSS_SELECTOR, "#cores > div:nth-child(1)"))
action.move_to_element(drawElement)

# Selenium moves to center of the element, so we need to move to the top left corner and add relative position
action.move_by_offset((-drawElement.size['width']/2 + 10) + x , (-drawElement.size['height']/2 + 10) + y)
action.click()
action.perform()
print(f"{datetime.now().time()}")

print("Drawing finished...")

print("Unblocking Gartic servers...")
browser.execute_cdp_cmd('Network.setBlockedURLs', {"urls": [""]})
browser.execute_cdp_cmd('Network.disable', {})

# Wait for round to finish
while browser.find_element(By.CSS_SELECTOR, ".btPular").is_displayed():
sleep(1)

print("Ended drawing...")
print("Drawing round finished...")
4 changes: 4 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
openai==0.27.8
Pillow==10.0.0
Requests==2.31.0
selenium==4.10.0

0 comments on commit 620aa66

Please sign in to comment.