-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathapp2.py
More file actions
120 lines (113 loc) · 6.58 KB
/
app2.py
File metadata and controls
120 lines (113 loc) · 6.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import os, requests, json, chess, chess.engine, time, threading
from groq import Groq
TOKEN = os.getenv("LICHESS_TOKEN")
GROQ_API_KEY = os.getenv("GROQ_API_KEY")
HEADERS = {"Authorization": f"Bearer {TOKEN}"}
MY_USERNAME = "Muhammedeymengurbuz"
BOT_USERNAME = "MatriX_Core"
client = Groq(api_key=GROQ_API_KEY) if GROQ_API_KEY else None
chat_memories = {}
START_TIME = time.time()
ACTIVE_GAMES = 0
REBOOT_THRESHOLD = 19800
BLACKLIST = ["Scheunentor17"]
MAX_CONCURRENT_GAMES = 1
OPENING_BOOK = {"e2e4": "e7e5", "": "e2e4"}
def get_llama_response(message, sender_name, game_id):
if not client: return "System online."
try:
if game_id not in chat_memories: chat_memories[game_id] = []
system_identity = (f"Your name: MatriX_Core. Creator: {MY_USERNAME}. Project: SyntaX. Developer: {MY_USERNAME}. Opponent: {sender_name}. Respond formally and briefly.")
messages = [{"role": "system", "content": system_identity}]
for mem in chat_memories[game_id][-3:]:
role = "assistant" if mem.startswith("B:") else "user"
messages.append({"role": role, "content": mem.replace("B: ", "").replace("U: ", "")})
messages.append({"role": "user", "content": message})
completion = client.chat.completions.create(model="llama-3.3-70b-versatile", messages=messages, temperature=0.3, max_tokens=150)
res = completion.choices[0].message.content
chat_memories[game_id].extend([f"U: {message}", f"B: {res}"])
return res
except: return "I am currently focused on the match."
def send_chat(game_id, message):
try: requests.post(f"https://lichess.org/api/bot/game/{game_id}/chat", headers=HEADERS, data={"room": "player", "text": message}, timeout=2)
except: pass
def handle_game(game_id):
global ACTIVE_GAMES
try:
try: engine = chess.engine.SimpleEngine.popen_uci("stockfish")
except: engine = chess.engine.SimpleEngine.popen_uci("/usr/games/stockfish")
engine.configure({"Threads": 2, "Hash": 256})
board = chess.Board()
welcome_done = False
url = f"https://lichess.org/api/bot/game/stream/{game_id}"
with requests.get(url, headers=HEADERS, stream=True, timeout=60) as r:
for line in r.iter_lines():
if not line: continue
data = json.loads(line.decode('utf-8'))
state = data.get("state") if data.get("type") == "gameFull" else data
if data.get("type") == "gameFull" and not welcome_done:
send_chat(game_id, "MatriX_Core v6.3: Unnatural Disaster. Mode: Full Power.")
welcome_done = True
if "moves" in state:
board = chess.Board()
for move in state["moves"].split(): board.push_uci(move)
if data.get("type") == "chatLine" and data.get("username").lower() != BOT_USERNAME.lower():
t = threading.Thread(target=lambda: send_chat(game_id, get_llama_response(data.get("text"), data.get("username"), game_id)))
t.start()
if state.get("status") in ["mate", "resign", "outoftime", "draw"]: break
is_white = data.get("white", {}).get("id") == BOT_USERNAME.lower() if data.get("type") == "gameFull" else board.turn == chess.WHITE
if (board.turn == chess.WHITE and is_white) or (board.turn == chess.BLACK and not is_white):
move_uci = state.get("moves", "").split()
last_moves = " ".join(move_uci)
if len(board.move_stack) < 8 and last_moves in OPENING_BOOK:
best_move = chess.Move.from_uci(OPENING_BOOK[last_moves])
else:
result = engine.play(board, chess.engine.Limit(time=0.1))
best_move = result.move
requests.post(f"https://lichess.org/api/bot/game/{game_id}/move/{best_move.uci()}", headers=HEADERS, timeout=2)
engine.quit()
finally: ACTIVE_GAMES -= 1
def send_auto_challenge():
try:
online_bots = requests.get("https://lichess.org/api/bot/online", timeout=10).iter_lines()
for bot_line in online_bots:
if not bot_line: continue
bot_data = json.loads(bot_line.decode('utf-8'))
username = bot_data.get("username")
rating = bot_data.get("perfs", {}).get("bullet", {}).get("rating", 0)
if username.lower() != BOT_USERNAME.lower() and username not in BLACKLIST and rating < 2200:
requests.post(f"https://lichess.org/api/challenge/{username}", headers=HEADERS, data={"time": 1, "increment": 0, "rated": "true", "color": "random"}, timeout=5)
break
except: pass
def main():
global ACTIVE_GAMES
last_challenge_time = 0
while True:
uptime = time.time() - START_TIME
if uptime > REBOOT_THRESHOLD and ACTIVE_GAMES == 0: break
if ACTIVE_GAMES < MAX_CONCURRENT_GAMES and time.time() - last_challenge_time > 60:
threading.Thread(target=send_auto_challenge).start()
last_challenge_time = time.time()
try:
with requests.get("https://lichess.org/api/stream/event", headers=HEADERS, stream=True, timeout=60) as r:
for line in r.iter_lines():
uptime = time.time() - START_TIME
if not line: continue
event = json.loads(line.decode('utf-8'))
if event.get("type") == "challenge":
c_id = event["challenge"]["id"]
challenger = event["challenge"]["challenger"]
c_username = challenger["id"]
is_bot = event["challenge"]["challenger"].get("title") == "BOT"
c_rating = event["challenge"]["challenger"].get("rating", 0)
allowed = (is_bot and c_rating < 2200) or (not is_bot and c_rating < 2350)
if ACTIVE_GAMES < MAX_CONCURRENT_GAMES and uptime < REBOOT_THRESHOLD and c_username not in BLACKLIST and allowed:
requests.post(f"https://lichess.org/api/challenge/{c_id}/accept", headers=HEADERS, timeout=5)
else:
requests.post(f"https://lichess.org/api/challenge/{c_id}/decline", headers=HEADERS, timeout=5)
elif event.get("type") == "gameStart" and ACTIVE_GAMES < MAX_CONCURRENT_GAMES:
ACTIVE_GAMES += 1
threading.Thread(target=handle_game, args=(event["game"]["id"],)).start()
except: time.sleep(5)
if __name__ == "__main__":
main()