Skip to content

Commit 059b8de

Browse files
authored
Added in reload commands for tracker and discord (#44)
* Reflowed global variables, added command to reload discord bits manually, working on discord relay * Updated docs for reload commands
1 parent 908af47 commit 059b8de

File tree

3 files changed

+118
-72
lines changed

3 files changed

+118
-72
lines changed

.env.template

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ CollectMessages=true
2626
CountdownMessages=true
2727
DeathlinkMessages=true
2828
#
29+
#---[Drawbridge Config]---
30+
DiscordBridgeEnabled=true
31+
#
2932
#---[Meta Config]---
3033
FlavorDeathlink=false
3134
DeathlinkLottery=false

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,15 @@ Hopefully that makes sense.
8787
|$deathcount|Scans the deathlog and tallies up the current deathcount for each slot|
8888
|$checkcount|Fetches the current Arch server's progress in simple txt format|
8989
|$checkgraph|Plots the current Arch progress in a picture|
90-
|$reloadbot|Forces the tracker client to reload|
91-
|$setenv \<key> \<value>|Allows you to set .env options via discord|
92-
||Current keys: ArchipelagoPort|
9390

9491
|Debug Commands|Description|
9592
|---|---|
9693
|$iloveyou|We all need to hear this sometimes.|
9794
|$hello|The bot says hello!|
95+
|$reloadtracker|Forces the tracker client to reload|
96+
|$reloaddiscord|Forces the discord bot to reload|
97+
|$setenv \<key> \<value>|Allows you to set .env options via discord|
98+
||Current keys: ArchipelagoPort|
9899
|$ArchInfo|\[CONSOLE] General bot details for debugging .env tables^|
99100

100101
**\[^] DebugMode only commands**
@@ -133,6 +134,8 @@ Hopefully that makes sense.
133134
|CollectMessages|Will relay collect messages|
134135
|CountdownMessages|Will relay server coutndown messages|
135136
|DeathlinkMessages|Will relay deathlink messages|
137+
|**Drawbridge Config**||
138+
|DiscordBridgeEnabled|\[Unfinished\]|
136139
|||
137140
|**Meta Config**||
138141
|FlavorDeathLink|Will change deathlink messages to have a little more personality$|

bridgeipelago.py

Lines changed: 109 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@
3131
import numpy as np
3232

3333
#Websocket Dependencies
34+
import websockets
3435
from websockets.sync.client import connect, ClientConnection
3536

37+
3638
#Discord Dependencies
3739
from discord.ext import tasks
3840
import discord
@@ -63,6 +65,8 @@
6365
EnableCountdownMessages = os.getenv('CountdownMessages')
6466
EnableDeathlinkMessages = os.getenv('DeathlinkMessages')
6567

68+
EnableDiscordBridge = os.getenv('DiscordBridgeEnabled')
69+
6670
EnableFlavorDeathlink = os.getenv('FlavorDeathlink')
6771
EnableDeathlinkLottery = os.getenv('DeathlinkLottery')
6872

@@ -96,6 +100,16 @@
96100
ReconnectionTimer = 5
97101
EnvPath = os.getcwd() + "/.env"
98102

103+
## These are the main queues for processing data from the Archipelago Tracker to the Discord Bot
104+
item_queue = Queue()
105+
death_queue = Queue()
106+
chat_queue = Queue()
107+
seppuku_queue = Queue()
108+
discordseppuku_queue = Queue()
109+
websocket_queue = Queue()
110+
lottery_queue = Queue()
111+
port_queue = Queue()
112+
99113
if(DebugMode == "true"):
100114
WSdbug = True
101115
else:
@@ -149,7 +163,7 @@
149163

150164
## ARCHIPELAGO TRACKER CLIENT + CORE FUNCTION
151165
class TrackerClient:
152-
tags: set[str] = {'Tracker', 'DeathLink'}
166+
tags: set[str] = {'TextOnly','Tracker', 'DeathLink'}
153167
version: dict[str, any] = {"major": 0, "minor": 6, "build": 0, "class": "Version"}
154168
items_handling: int = 0b000 # This client does not receive any items
155169

@@ -188,61 +202,67 @@ def __init__(
188202
self.socket_thread: Thread = None
189203

190204
def run(self):
191-
"""Handles incoming messages from the Archipelago MultiServer."""
192-
DebugMode = os.getenv('DebugMode')
193-
for RawMessage in self.ap_connection:
194-
195-
if(DebugMode == "true"):
196-
print("==RawMessage==")
197-
print(RawMessage)
198-
print("=====")
199-
200-
for i in range(len(json.loads(RawMessage))):
201-
202-
args: dict = json.loads(RawMessage)[i]
203-
cmd = args.get('cmd')
205+
try:
206+
"""Handles incoming messages from the Archipelago MultiServer."""
207+
DebugMode = os.getenv('DebugMode')
208+
for RawMessage in self.ap_connection:
204209

205210
if(DebugMode == "true"):
206-
print("==Args==")
207-
print(args)
211+
print("==RawMessage==")
212+
print(RawMessage)
208213
print("=====")
209214

210-
if cmd == self.MessageCommand.ROOM_INFO.value:
211-
self.send_connect()
212-
WriteRoomInfo(args)
213-
self.check_datapackage()
214-
elif cmd == self.MessageCommand.DATA_PACKAGE.value:
215-
WriteDataPackage(args)
216-
elif cmd == self.MessageCommand.CONNECTED.value:
217-
WriteConnectionPackage(args)
218-
print("Connected to server.")
219-
elif cmd == self.MessageCommand.CONNECTIONREFUSED.value:
220-
print("Connection refused by server - check your slot name / port / whatever, and try again.")
221-
print(args)
222-
seppuku_queue.put(args)
223-
elif cmd == self.MessageCommand.PRINT_JSON.value:
224-
if args.get('type') == 'ItemSend' and self.on_item_send:
225-
self.on_item_send(args)
226-
elif args.get('type') == 'Chat':
227-
if EnableChatMessages == "true" and self.on_chat_send:
228-
self.on_chat_send(args)
229-
elif args.get('type') == 'ServerChat':
230-
if EnableServerChatMessages == "true" and self.on_chat_send:
231-
self.on_chat_send(args)
232-
elif args.get('type') == 'Goal':
233-
if EnableGoalMessages == "true" and self.on_chat_send:
234-
self.on_chat_send(args)
235-
elif args.get('type') == 'Release':
236-
if EnableReleaseMessages == "true" and self.on_chat_send:
237-
self.on_chat_send(args)
238-
elif args.get('type') == 'Collect':
239-
if EnableCollectMessages == "true" and self.on_chat_send:
240-
self.on_chat_send(args)
241-
elif args.get('type') == 'Countdown':
242-
if EnableCountdownMessages == "true" and self.on_chat_send:
243-
self.on_chat_send(args)
244-
elif 'DeathLink' in args.get('tags', []) and self.on_death_link:
245-
self.on_death_link(args)
215+
for i in range(len(json.loads(RawMessage))):
216+
217+
args: dict = json.loads(RawMessage)[i]
218+
cmd = args.get('cmd')
219+
220+
if(DebugMode == "true"):
221+
print("==Args==")
222+
print(args)
223+
print("=====")
224+
225+
if cmd == self.MessageCommand.ROOM_INFO.value:
226+
self.send_connect()
227+
WriteRoomInfo(args)
228+
self.check_datapackage()
229+
elif cmd == self.MessageCommand.DATA_PACKAGE.value:
230+
WriteDataPackage(args)
231+
elif cmd == self.MessageCommand.CONNECTED.value:
232+
WriteConnectionPackage(args)
233+
print("Connected to server.")
234+
elif cmd == self.MessageCommand.CONNECTIONREFUSED.value:
235+
print("Connection refused by server - check your slot name / port / whatever, and try again.")
236+
print(args)
237+
seppuku_queue.put(args)
238+
elif cmd == self.MessageCommand.PRINT_JSON.value:
239+
if args.get('type') == 'ItemSend' and self.on_item_send:
240+
self.on_item_send(args)
241+
elif args.get('type') == 'Chat':
242+
if EnableChatMessages == "true" and self.on_chat_send:
243+
self.on_chat_send(args)
244+
elif args.get('type') == 'ServerChat':
245+
if EnableServerChatMessages == "true" and self.on_chat_send:
246+
self.on_chat_send(args)
247+
elif args.get('type') == 'Goal':
248+
if EnableGoalMessages == "true" and self.on_chat_send:
249+
self.on_chat_send(args)
250+
elif args.get('type') == 'Release':
251+
if EnableReleaseMessages == "true" and self.on_chat_send:
252+
self.on_chat_send(args)
253+
elif args.get('type') == 'Collect':
254+
if EnableCollectMessages == "true" and self.on_chat_send:
255+
self.on_chat_send(args)
256+
elif args.get('type') == 'Countdown':
257+
if EnableCountdownMessages == "true" and self.on_chat_send:
258+
self.on_chat_send(args)
259+
elif 'DeathLink' in args.get('tags', []) and self.on_death_link:
260+
self.on_death_link(args)
261+
else:
262+
print("Unknown command received from Archipelago MultiServer:")
263+
print(args)
264+
except websockets.exceptions.ConnectionClosedError as e:
265+
print(e)
246266

247267
def on_error(self, string, opcode) -> None:
248268
if self.verbose_logging:
@@ -310,6 +330,13 @@ def start(self) -> None:
310330
print(e)
311331
websocket_queue.put("!! Tracker start error...")
312332

333+
def debug_print(self, who: str, what: str) -> None:
334+
relayed_message = "Discord; " + who + ": " + what
335+
payload = {
336+
'cmd': 'Say',
337+
'text': relayed_message}
338+
self.send_message(payload)
339+
313340

314341

315342
## DISCORD EVENT HANDLERS + CORE FUNTION
@@ -397,23 +424,34 @@ async def on_message(message):
397424
rtrnmessage = SetEnvVariable(pair[0], pair[1])
398425
await SendMainChannelMessage(rtrnmessage)
399426

400-
if message.content.startswith('$reloadbot'):
427+
if message.content.startswith('$reloadtracker'):
401428
ReloadBot()
402-
await SendMainChannelMessage("Reloading bot... Please wait.")
429+
await SendMainChannelMessage("Reloading tracker... Please wait about 5-10 seconds.")
430+
431+
if message.content.startswith('$reloaddiscord'):
432+
discordseppuku_queue.put("Reloading Discord bot...")
433+
await SendMainChannelMessage("Reloading Discord bot... Please wait.")
434+
435+
# Broken code for sending messages to AP from discord. :( im working on it
436+
#if not message.content.startswith('$'):
437+
# tracker_client.debug_print(str(message.author), message.content)
438+
# return
403439

404440
@tasks.loop(seconds=1)
405441
async def CheckCommandQueue():
406442
if discordseppuku_queue.empty():
407443
return
408444
else:
445+
while not discordseppuku_queue.empty():
446+
QueueMessage = discordseppuku_queue.get()
447+
print("++ Shutting down Discord tasks")
409448
CheckArchHost.stop()
410449
ProcessItemQueue.stop()
411450
ProcessDeathQueue.stop()
412451
ProcessChatQueue.stop()
413-
while not discordseppuku_queue.empty():
414-
item = discordseppuku_queue.get()
415-
416-
await DiscordClient.close()
452+
453+
print("++ Closing Discord Client")
454+
exit()
417455

418456
@tasks.loop(seconds=900)
419457
async def CheckArchHost():
@@ -546,7 +584,8 @@ async def ProcessChatQueue():
546584
return
547585
else:
548586
chatmessage = chat_queue.get()
549-
await SendMainChannelMessage(chatmessage['data'][0]['text'])
587+
if not (chatmessage['data'][0]['text']).startswith(ArchipelagoBotSlot):
588+
await SendMainChannelMessage(chatmessage['data'][0]['text'])
550589

551590
@tree.command(name="register",
552591
description="Registers you for AP slot",
@@ -1344,18 +1383,9 @@ async def CancelProcess():
13441383
return 69420
13451384

13461385
def Discord():
1386+
print("++ Starting Discord Client")
13471387
DiscordClient.run(DiscordToken)
13481388

1349-
## Three main queues for processing data from the Archipelago Tracker to the bot
1350-
item_queue = Queue()
1351-
death_queue = Queue()
1352-
chat_queue = Queue()
1353-
seppuku_queue = Queue()
1354-
discordseppuku_queue = Queue()
1355-
websocket_queue = Queue()
1356-
lottery_queue = Queue()
1357-
port_queue = Queue()
1358-
13591389
## Threadded async functions
13601390
if(DiscordJoinOnly == "false"):
13611391
# Start the tracker client
@@ -1469,6 +1499,16 @@ def main():
14691499
DiscordThread = Process(target=Discord)
14701500
DiscordThread.start()
14711501
DiscordCycleCount = 0
1502+
1503+
if not DiscordThread.is_alive():
1504+
print("++ Discord thread is not running, restarting it")
1505+
print("++ Closing the discord thread")
1506+
DiscordThread.close()
1507+
print("++ Sleeping for 3 seconds to allow the discord thread to close")
1508+
time.sleep(3)
1509+
print("++ Starting the discord thread again")
1510+
DiscordThread = Process(target=Discord)
1511+
DiscordThread.start()
14721512

14731513
try:
14741514
time.sleep(1)

0 commit comments

Comments
 (0)