11import os
22import time
3- from threading import Thread
3+ #import threading
4+ from threading import Thread , Lock
45import ast
56import sys
67import requests
9798oscListen = True #in conf
9899oscForeword = False #in conf
99100
101+ output = ''
102+ logOutput = False #in conf
103+
100104oscForewordPortMemory = ''
101105oscForewordAddressMemory = ''
102106runForewordServer = False
@@ -118,26 +122,30 @@ def afk_handler(unused_address, args):
118122 global isAfk
119123 isAfk = args
120124 print ('isAfk' , isAfk )
125+ outputLog ('isAfk' , isAfk )
121126
122127def mute_handler (unused_address , args ):
123128 global isMute
124129 isMute = args
125130 print ('isMute' ,isMute )
131+ outputLog ('isMute' ,isMute )
126132
127133def inSeat_handler (unused_address , args ):
128134 global isInSeat
129135 isInSeat = args
130136 print ('isInSeat' ,isInSeat )
137+ outputLog ('isInSeat' ,isInSeat )
131138
132139def volume_handler (unused_address , args ):
133140 global voiceVolume
134141 voiceVolume = args
135142 #print('voiceVolume',voiceVolume)
136-
143+ #outputLog('voiceVolume',voiceVolume)
137144def usingEarmuffs_handler (unused_address , args ):
138145 global isUsingEarmuffs
139146 isUsingEarmuffs = args
140147 print ('isUsingEarmuffs' , isUsingEarmuffs )
148+ outputLog ('isUsingEarmuffs' , isUsingEarmuffs )
141149
142150def vr_handler (unused_address , args ):# The game never sends this value from what I've seen
143151 global isVR
@@ -146,6 +154,31 @@ def vr_handler(unused_address, args):# The game never sends this value from what
146154 else :
147155 isVR == False
148156 print ('isVR' , isVR )
157+ outputLog ('isVR' , isVR )
158+
159+ """def thread_exists(name):
160+ for thread in threading.enumerate():
161+ if thread.name == name:
162+ return True
163+ return False"""
164+
165+ message_queue = []
166+ queue_lock = Lock ()
167+
168+ def outputLog (text ):
169+ def waitThread ():
170+ timestamp = datetime .now ()
171+ with queue_lock :
172+ message_queue .append ((timestamp , text ))
173+ while windowAccess is None :
174+ time .sleep (.01 )
175+ with queue_lock :
176+ message_queue .sort (key = lambda x : x [0 ])
177+ for message in message_queue :
178+ windowAccess .write_event_value ('outputSend' , str (message [0 ]) + " " + message [1 ])
179+ message_queue .clear ()
180+ waitThreadHandler = Thread (target = waitThread )
181+ waitThreadHandler .start ()
149182
150183def update_checker (a ):
151184 global updatePrompt
@@ -159,6 +192,7 @@ def update_checker(a):
159192 data = response .json ()
160193 if int (data [0 ]["tag_name" ].replace ('v' , '' ).replace ('.' , '' ).replace (' ' , '' ).replace ('Version' , '' ).replace ('version' , '' )) != int (version .replace ('v' , '' ).replace ('.' , '' ).replace (' ' , '' ).replace ('Version' , '' ).replace ('version' , '' )):
161194 print ("A new version is available! " + data [0 ]["tag_name" ].replace ('v' , '' ).replace (' ' , '' ).replace ('Version' , '' ).replace ('version' , '' )+ " > " + version .replace ('v' , '' ).replace (' ' , '' ).replace ('Version' , '' ).replace ('version' , '' ))
195+ outputLog ("A new version is available! " + data [0 ]["tag_name" ].replace ('v' , '' ).replace (' ' , '' ).replace ('Version' , '' ).replace ('version' , '' )+ " > " + version .replace ('v' , '' ).replace (' ' , '' ).replace ('Version' , '' ).replace ('version' , '' ))
162196 if updatePrompt :
163197 def updatePromptWaitThread ():
164198 while windowAccess == None :
@@ -179,9 +213,11 @@ def waitThread():
179213 if a :
180214 windowAccess .write_event_value ('popup' , "Program is up to date! Version " + version )
181215 print ("Program is up to date! Version " + version )
216+ outputLog ("Program is up to date! Version " + version )
182217
183218 else :
184- print ('Update Error occurred:' , response .status_code )
219+ print ('Update Checking Error occurred:' , response .status_code )
220+ outputLog ('Update Checking Error occurred:' , response .status_code )
185221
186222
187223async def get_media_info ():
@@ -224,7 +260,7 @@ def mediaIs(state):
224260
225261confDataDict = { #this dictionary will always exclude position 0 which is the config version!
226262 "1.4.1" : ['confVersion' , 'topTextToggle' , 'topTimeToggle' , 'topSongToggle' , 'topCPUToggle' , 'topRAMToggle' , 'topNoneToggle' , 'bottomTextToggle' , 'bottomTimeToggle' , 'bottomSongToggle' , 'bottomCPUToggle' , 'bottomRAMToggle' , 'bottomNoneToggle' , 'message_delay' , 'messageString' , 'FileToRead' , 'scrollText' , 'hideSong' , 'hideMiddle' , 'hideOutside' , 'showPaused' , 'songDisplay' , 'showOnChange' , 'songChangeTicks' , 'minimizeOnStart' , 'keybind_run' , 'keybind_afk' ,'topBar' , 'middleBar' , 'bottomBar' , 'topHRToggle' , 'bottomHRToggle' , 'pulsoidToken' , 'avatarHR' , 'blinkOverride' , 'blinkSpeed' , 'useAfkKeybind' , 'toggleBeat' , 'updatePrompt' ],
227- "1.4.20" : ['confVersion' , 'topTextToggle' , 'topTimeToggle' , 'topSongToggle' , 'topCPUToggle' , 'topRAMToggle' , 'topNoneToggle' , 'bottomTextToggle' , 'bottomTimeToggle' , 'bottomSongToggle' , 'bottomCPUToggle' , 'bottomRAMToggle' , 'bottomNoneToggle' , 'message_delay' , 'messageString' , 'FileToRead' , 'scrollText' , 'hideSong' , 'hideMiddle' , 'hideOutside' , 'showPaused' , 'songDisplay' , 'showOnChange' , 'songChangeTicks' , 'minimizeOnStart' , 'keybind_run' , 'keybind_afk' ,'topBar' , 'middleBar' , 'bottomBar' , 'topHRToggle' , 'bottomHRToggle' , 'pulsoidToken' , 'avatarHR' , 'blinkOverride' , 'blinkSpeed' , 'useAfkKeybind' , 'toggleBeat' , 'updatePrompt' , 'oscListenAddress' , 'oscListenPort' , 'oscSendAddress' , 'oscSendPort' , 'oscForewordAddress' , 'oscForeword' , 'oscListen' , 'oscForeword' ]
263+ "1.4.20" : ['confVersion' , 'topTextToggle' , 'topTimeToggle' , 'topSongToggle' , 'topCPUToggle' , 'topRAMToggle' , 'topNoneToggle' , 'bottomTextToggle' , 'bottomTimeToggle' , 'bottomSongToggle' , 'bottomCPUToggle' , 'bottomRAMToggle' , 'bottomNoneToggle' , 'message_delay' , 'messageString' , 'FileToRead' , 'scrollText' , 'hideSong' , 'hideMiddle' , 'hideOutside' , 'showPaused' , 'songDisplay' , 'showOnChange' , 'songChangeTicks' , 'minimizeOnStart' , 'keybind_run' , 'keybind_afk' ,'topBar' , 'middleBar' , 'bottomBar' , 'topHRToggle' , 'bottomHRToggle' , 'pulsoidToken' , 'avatarHR' , 'blinkOverride' , 'blinkSpeed' , 'useAfkKeybind' , 'toggleBeat' , 'updatePrompt' , 'oscListenAddress' , 'oscListenPort' , 'oscSendAddress' , 'oscSendPort' , 'oscForewordAddress' , 'oscForeword' , 'oscListen' , 'oscForeword' , 'logOutput' ]
228264}
229265
230266if os .path .isfile ('please-do-not-delete.txt' ):
@@ -238,10 +274,13 @@ def mediaIs(state):
238274 globals ()[x ] = fixed_list [i ]
239275 #print(f"{x} = {fixed_list[i]}")
240276 print ("Successfully Loaded config file version " + fixed_list [0 ])
277+ outputLog ("Successfully Loaded config file version " + fixed_list [0 ])
241278 else :
242279 print ('Config file is Too Old! Not Updating Values...' )
280+ outputLog ('Config file is Too Old! Not Updating Values...' )
243281 except :
244282 print ('Config File Load Error! Not Updating Values...' )
283+ outputLog ('Config File Load Error! Not Updating Values...' )
245284def uiThread ():
246285 global version
247286 global msgOutput
@@ -299,6 +338,7 @@ def uiThread():
299338 global oscForewordPort
300339 global oscListen
301340 global oscForeword
341+ global logOutput
302342 layout_layout = [[sg .Column (
303343 [[sg .Text ('Configure chatbox layout' , background_color = 'darkseagreen' , font = ('Arial' , 12 , 'bold' ))],
304344 [sg .Column ([
@@ -389,7 +429,7 @@ def uiThread():
389429 [sg .Text ('Toggle Run' ), sg .Frame ('' ,[[sg .Text ('Unbound' , key = 'keybind_run' , background_color = 'DarkSlateGray4' , pad = (10 , 0 ))]],background_color = 'DarkSlateGray4' ), sg .Button ('Bind Key' , key = 'run_binding' )],
390430 [sg .Text ('Imagine That there is a checkbox here :)' )],
391431 [sg .Text ('Toggle Afk' ), sg .Frame ('' ,[[sg .Text ('Unbound' , key = 'keybind_afk' , background_color = 'DarkSlateGray4' , pad = (10 , 0 ))]],background_color = 'DarkSlateGray4' ), sg .Button ('Bind Key' , key = 'afk_binding' )],
392- [sg .Checkbox ('Use keybind (Otherwise, uses osc to check afk status)' , default = False , enable_events = True , key = 'useAfkKeybind' )]
432+ [sg .Checkbox ('Use keybind (Otherwise, uses OSC to check afk status)' , default = False , enable_events = True , key = 'useAfkKeybind' )]
393433 ], expand_x = True , size = (379 , 130 ))]
394434 ]
395435 , scrollable = True , vertical_scroll_only = True , expand_x = True , expand_y = True , background_color = 'turquoise4' )]]
@@ -432,8 +472,13 @@ def uiThread():
432472 ], size = (379 , 150 ))]
433473 ] , scrollable = True , vertical_scroll_only = True , expand_x = True , expand_y = True , background_color = 'turquoise4' )]]
434474
475+ output_layout = [[sg .Column (
476+ [[sg .Text ('Program Output' , background_color = 'DarkGreen' , font = ('Arial' , 12 , 'bold' )), sg .Checkbox ('Log to file (OCT_debug_log.txt)' , default = False , key = 'logOutput' , background_color = 'DarkGreen' )],
477+ [sg .Multiline ('' , disabled = True , key = 'output' , size = (53 , 30 ), background_color = 'DarkSlateGrey' , text_color = 'white' , expand_x = True , expand_y = True )]
478+ ] , expand_x = True , expand_y = True , background_color = 'DarkGreen' )]]
479+
435480 menu_def = [['&File' , ['A&pply' , '&Reset' , '---' , 'Open Config File' , '---' ,'E&xit' ]],
436- ['&Help' , ['&About' , '---' , 'Submit Feedback' , '---' , 'Open &Github Page' , '&Check For Updates' ]]]
481+ ['&Help' , ['&About' , '---' , 'Submit Feedback' , '---' , 'Open &Github Page' , '&Check For Updates' , '&FAQ' ]]]
437482 topMenuBar = sg .Menu (menu_def , key = "menuBar" )
438483 right_click_menu = ['&Right' , ['You thought' ]]
439484 layout = [
@@ -445,7 +490,8 @@ def uiThread():
445490 sg .Tab ('Preview' , preview_layout , background_color = 'DarkGreen' ),
446491 sg .Tab ('Keybindings' , keybindings_layout , background_color = 'turquoise4' ),
447492 sg .Tab ('Options' , options_layout , background_color = 'SteelBlue4' ),
448- sg .Tab ('OSC Options' , osc_layout , background_color = 'turquoise4' )
493+ sg .Tab ('OSC Options' , osc_layout , background_color = 'turquoise4' ),
494+ sg .Tab ('Output' , output_layout , background_color = 'DarkGreen' )
449495 ]],
450496 key = 'mainTabs' , tab_location = 'lefttop' , selected_title_color = 'white' , selected_background_color = 'gray' , expand_x = True , expand_y = True , size = (440 , 300 )
451497 )
@@ -501,7 +547,8 @@ def resetVars():
501547 window ['oscForewordPort' ].update (value = '9002' )
502548 window ['oscListen' ].update (value = True )
503549 window ['oscForeword' ].update (value = False )
504- def pullVars ():
550+ window ['logOutput' ].update (value = False )
551+ def updateUI ():
505552 global playMsg
506553 global msgOutput
507554 if os .path .isfile ('please-do-not-delete.txt' ):
@@ -547,6 +594,7 @@ def pullVars():
547594 window ['oscForewordPort' ].update (value = oscForewordPort )
548595 window ['oscListen' ].update (value = oscListen )
549596 window ['oscForeword' ].update (value = oscForeword )
597+ window ['logOutput' ].update (value = logOutput )
550598 while run :
551599 if run :
552600 try :
@@ -558,8 +606,8 @@ def pullVars():
558606 if run :
559607 window ['runThing' ].update (value = playMsg )
560608 window ['afk' ].update (value = afk )
561- pullVarsThread = Thread (target = pullVars )
562- pullVarsThread .start ()
609+ updateUIThread = Thread (target = updateUI )
610+ updateUIThread .start ()
563611 if minimizeOnStart :
564612 window .minimize ()
565613 windowAccess = window
@@ -681,9 +729,10 @@ def pullVars():
681729 oscForewordPort = values ['oscForewordPort' ]
682730 oscListen = values ['oscListen' ]
683731 oscForeword = values ['oscForeword' ]
732+ logOutput = values ['logOutput' ]
684733 with open ('please-do-not-delete.txt' , 'w' , encoding = "utf-8" ) as f :
685734 try :
686- f .write (str ([confVersion , topTextToggle , topTimeToggle , topSongToggle , topCPUToggle , topRAMToggle , topNoneToggle , bottomTextToggle , bottomTimeToggle , bottomSongToggle , bottomCPUToggle , bottomRAMToggle , bottomNoneToggle , message_delay , messageString , FileToRead , scrollText , hideSong , hideMiddle , hideOutside , showPaused , songDisplay , showOnChange , songChangeTicks , minimizeOnStart , keybind_run , keybind_afk ,topBar , middleBar , bottomBar , topHRToggle , bottomHRToggle , pulsoidToken , avatarHR , blinkOverride , blinkSpeed , useAfkKeybind , toggleBeat , updatePrompt , oscListenAddress , oscListenPort , oscSendAddress , oscSendPort , oscForewordAddress , oscForeword , oscListen , oscForeword ]))
735+ f .write (str ([confVersion , topTextToggle , topTimeToggle , topSongToggle , topCPUToggle , topRAMToggle , topNoneToggle , bottomTextToggle , bottomTimeToggle , bottomSongToggle , bottomCPUToggle , bottomRAMToggle , bottomNoneToggle , message_delay , messageString , FileToRead , scrollText , hideSong , hideMiddle , hideOutside , showPaused , songDisplay , showOnChange , songChangeTicks , minimizeOnStart , keybind_run , keybind_afk ,topBar , middleBar , bottomBar , topHRToggle , bottomHRToggle , pulsoidToken , avatarHR , blinkOverride , blinkSpeed , useAfkKeybind , toggleBeat , updatePrompt , oscListenAddress , oscListenPort , oscSendAddress , oscSendPort , oscForewordAddress , oscForeword , oscListen , oscForeword , logOutput ]))
687736 except Exception as e :
688737 sg .popup ('Error saving config to file:\n ' + str (e ))
689738 """print('Popup Open') #Popup Shit is broken
@@ -699,7 +748,7 @@ def pullVars():
699748 if event == 'Open Github Page' :
700749 webbrowser .open ('https://github.com/Lioncat6/OSC-Chat-Tools' )
701750 if event == 'About' :
702- about_popop_layout = [[sg .Text ('OSC Chat Tools by' , font = ('Arial' , 11 , 'bold' ), pad = (0 , 20 )), sg .Text ('Lioncat6' , font = ('Arial' , 12 , 'bold' ), text_color = 'lime' )],[sg .Text ('Modules Used:' ,font = ('Arial' , 11 , 'bold' ))], [sg .Text ('- PySimpleGUI\n - argparse\n - datetime\n - pythonosc (udp_client)\n - keyboard\n - asyncio\n - psutil\n - webbrowser\n - winsdk (windows.media.control)\n - websocket-client' )], [sg .Text ( 'Python Version: ' + str ( sys . version ))], [ sg . Button ('Ok' )]]
751+ about_popop_layout = [[sg .Text ('OSC Chat Tools by' , font = ('Arial' , 11 , 'bold' ), pad = (0 , 20 )), sg .Text ('Lioncat6' , font = ('Arial' , 12 , 'bold' ), text_color = 'lime' )],[sg .Text ('Modules Used:' ,font = ('Arial' , 11 , 'bold' ))], [sg .Text ('- PySimpleGUI\n - argparse\n - datetime\n - pythonosc (udp_client)\n - keyboard\n - asyncio\n - psutil\n - webbrowser\n - winsdk (windows.media.control)\n - websocket-client' )], [sg .Button ('Ok' )]]
703752 about_window = sg .Window ('About' , about_popop_layout )
704753 event , values = about_window .read ()
705754 about_window .close ()
@@ -778,6 +827,21 @@ def checkPressThread():
778827 window ['versionText' ].update (value = window ['versionText' ].get ()+ " - New Update Available" )
779828 if event == 'popup' :
780829 sg .popup (values ['popup' ])
830+ if event == 'FAQ' :
831+ webbrowser .open ('https://github.com/Lioncat6/OSC-Chat-Tools/wiki/FAQ' )
832+ if event == 'outputSend' :
833+ current_text = values ['output' ]
834+ if current_text == '' :
835+ new_text = values [event ]
836+ else :
837+ new_text = current_text + '\n ' + values [event ]
838+ window ['output' ].update (new_text )
839+ if logOutput :
840+ with open ('OCT_debug_log.txt' , 'a+' , encoding = "utf-8" ) as f :
841+ if f .read () == '' :
842+ f .write (values [event ])
843+ else :
844+ f .write ("\n " + values [event ])
781845 window .close ()
782846 playMsg = False
783847 run = False
@@ -859,6 +923,7 @@ def dataSender():
859923 global oscForeword
860924 runForewordServer = True
861925 print ('Starting Forwarding server on ' + str (forward_addresses ))
926+ outputLog ('Starting Forwarding server on ' + str (forward_addresses ))
862927 oscListenAddressMemory = oscListenAddress
863928 oscListenPortMemory = oscListenPort
864929 oscForewordPortMemory = oscForewordPort
@@ -885,6 +950,7 @@ def dataSender():
885950 if oscListenAddressMemory != oscListenAddress or oscListenPortMemory != oscListenPort or oscForewordPortMemory != oscForewordPort or oscForewordAddressMemory != oscForewordAddress or useForewordMemory != oscForeword or useForewordMemory != oscForeword or ((oscForeword or oscListen ) and not runForewordServer ):
886951 if oscForeword or oscListen :
887952 print ('Foreword/Listen Server Config Updated, Restarting Forwarding Server...\n ' )
953+ outputLog ('Foreword/Listen Server Config Updated, Restarting Forwarding Server...\n ' )
888954 runForewordServer = False
889955 time .sleep (.5 )
890956 if not runForewordServer :
@@ -893,6 +959,7 @@ def dataSender():
893959 if runForewordServer and not (oscForeword or oscListen ):
894960 runForewordServer = False
895961 print ('No OSC Foreword/Listening Options are selected, stopping Forwarding Server...' )
962+ outputLog ('No OSC Foreword/Listening Options are selected, stopping Forwarding Server...' )
896963 time .sleep (.5 )
897964 oscForwardingManagerThread = Thread (target = oscForwardingManager )
898965 oscForwardingManagerThread .start ()
@@ -919,7 +986,7 @@ def listenServerThread():
919986 listenServer = osc_server .ThreadingOSCUDPServer (
920987 (args .ip , args .port ), dispatcher )
921988 print ("Osc Listen Server Serving on {}" .format (listenServer .server_address ))
922-
989+ outputLog ( "Osc Listen Server Serving on {}" . format ( listenServer . server_address ))
923990 sockett = listenServer .socket
924991 sockett .setsockopt (socket .SOL_SOCKET , socket .SO_REUSEADDR , 1 )
925992
@@ -928,13 +995,15 @@ def listenServerThread():
928995 listenServer .serve_forever ()
929996 except Exception as e :
930997 print ('Osc Listen Server Failed to Start, Retying...' + str (e ))
998+ outputLog ('Osc Listen Server Failed to Start, Retying...' + str (e ))
931999 pass
9321000
9331001 if not isListenServerRunning :
9341002 oscServerThread = Thread (target = listenServerThread )
9351003 oscServerThread .start ()
9361004 if not oscListen and isListenServerRunning :
9371005 print ('No OSC Listen Options are Selected, Shutting Down OSC Listen Server...' )
1006+ outputLog ('No OSC Listen Options are Selected, Shutting Down OSC Listen Server...' )
9381007 isListenServerRunning = False
9391008 listenServer .shutdown ()
9401009 listenServer .server_close ()
@@ -1154,7 +1223,7 @@ def hrConnectionThread():
11541223 if not hrConnected :
11551224 try :
11561225 ws = create_connection ("wss://dev.pulsoid.net/api/v1/data/real_time?access_token=" + pulsoidToken + "&response_mode=text_plain_only_heart_rate" )
1157- ws .settimeout (1 ) # Set a timeout of 1 second so the thread stops
1226+ ws .settimeout (.4 ) # Set a timeout of 1 second so the thread stops
11581227 hrConnected = True
11591228 def pulsoidListen ():
11601229 global heartRate
@@ -1169,10 +1238,10 @@ def pulsoidListen():
11691238 pass
11701239 if not run or not hrConnected :
11711240 break
1172-
11731241 pulsoidListenThread = Thread (target = pulsoidListen )
11741242 pulsoidListenThread .start ()
11751243 def blinkHR ():
1244+ global blinkThread
11761245 global heartRate
11771246 global blinkOverride
11781247 global blinkSpeed
@@ -1194,13 +1263,15 @@ def blinkHR():
11941263 blinkHRThread = Thread (target = blinkHR )
11951264 blinkHRThread .start ()
11961265 print ('Pulsoid Connection Started...' )
1266+ outputLog ('Pulsoid Connection Started...' )
11971267 except Exception as e :
11981268 if windowAccess != None :
11991269 if playMsg :
12001270 windowAccess .write_event_value ('pulsoidError' , e )
12011271 if ((not topHRToggle and not bottomHRToggle and not avatarHR ) or not (playMsg or avatarHR )) and hrConnected :
12021272 hrConnected = False
12031273 print ('Pulsoid Connection Stopped' )
1274+ outputLog ('Pulsoid Connection Stopped' )
12041275 time .sleep (.3 )
12051276hrConnectionThreadRun = Thread (target = hrConnectionThread )
12061277hrConnectionThreadRun .start ()
0 commit comments