1
1
import os
2
2
import time
3
- from threading import Thread
3
+ #import threading
4
+ from threading import Thread , Lock
4
5
import ast
5
6
import sys
6
7
import requests
97
98
oscListen = True #in conf
98
99
oscForeword = False #in conf
99
100
101
+ output = ''
102
+ logOutput = False #in conf
103
+
100
104
oscForewordPortMemory = ''
101
105
oscForewordAddressMemory = ''
102
106
runForewordServer = False
@@ -118,26 +122,30 @@ def afk_handler(unused_address, args):
118
122
global isAfk
119
123
isAfk = args
120
124
print ('isAfk' , isAfk )
125
+ outputLog ('isAfk' , isAfk )
121
126
122
127
def mute_handler (unused_address , args ):
123
128
global isMute
124
129
isMute = args
125
130
print ('isMute' ,isMute )
131
+ outputLog ('isMute' ,isMute )
126
132
127
133
def inSeat_handler (unused_address , args ):
128
134
global isInSeat
129
135
isInSeat = args
130
136
print ('isInSeat' ,isInSeat )
137
+ outputLog ('isInSeat' ,isInSeat )
131
138
132
139
def volume_handler (unused_address , args ):
133
140
global voiceVolume
134
141
voiceVolume = args
135
142
#print('voiceVolume',voiceVolume)
136
-
143
+ #outputLog('voiceVolume',voiceVolume)
137
144
def usingEarmuffs_handler (unused_address , args ):
138
145
global isUsingEarmuffs
139
146
isUsingEarmuffs = args
140
147
print ('isUsingEarmuffs' , isUsingEarmuffs )
148
+ outputLog ('isUsingEarmuffs' , isUsingEarmuffs )
141
149
142
150
def vr_handler (unused_address , args ):# The game never sends this value from what I've seen
143
151
global isVR
@@ -146,6 +154,31 @@ def vr_handler(unused_address, args):# The game never sends this value from what
146
154
else :
147
155
isVR == False
148
156
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 ()
149
182
150
183
def update_checker (a ):
151
184
global updatePrompt
@@ -159,6 +192,7 @@ def update_checker(a):
159
192
data = response .json ()
160
193
if int (data [0 ]["tag_name" ].replace ('v' , '' ).replace ('.' , '' ).replace (' ' , '' ).replace ('Version' , '' ).replace ('version' , '' )) != int (version .replace ('v' , '' ).replace ('.' , '' ).replace (' ' , '' ).replace ('Version' , '' ).replace ('version' , '' )):
161
194
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' , '' ))
162
196
if updatePrompt :
163
197
def updatePromptWaitThread ():
164
198
while windowAccess == None :
@@ -179,9 +213,11 @@ def waitThread():
179
213
if a :
180
214
windowAccess .write_event_value ('popup' , "Program is up to date! Version " + version )
181
215
print ("Program is up to date! Version " + version )
216
+ outputLog ("Program is up to date! Version " + version )
182
217
183
218
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 )
185
221
186
222
187
223
async def get_media_info ():
@@ -224,7 +260,7 @@ def mediaIs(state):
224
260
225
261
confDataDict = { #this dictionary will always exclude position 0 which is the config version!
226
262
"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' ]
228
264
}
229
265
230
266
if os .path .isfile ('please-do-not-delete.txt' ):
@@ -238,10 +274,13 @@ def mediaIs(state):
238
274
globals ()[x ] = fixed_list [i ]
239
275
#print(f"{x} = {fixed_list[i]}")
240
276
print ("Successfully Loaded config file version " + fixed_list [0 ])
277
+ outputLog ("Successfully Loaded config file version " + fixed_list [0 ])
241
278
else :
242
279
print ('Config file is Too Old! Not Updating Values...' )
280
+ outputLog ('Config file is Too Old! Not Updating Values...' )
243
281
except :
244
282
print ('Config File Load Error! Not Updating Values...' )
283
+ outputLog ('Config File Load Error! Not Updating Values...' )
245
284
def uiThread ():
246
285
global version
247
286
global msgOutput
@@ -299,6 +338,7 @@ def uiThread():
299
338
global oscForewordPort
300
339
global oscListen
301
340
global oscForeword
341
+ global logOutput
302
342
layout_layout = [[sg .Column (
303
343
[[sg .Text ('Configure chatbox layout' , background_color = 'darkseagreen' , font = ('Arial' , 12 , 'bold' ))],
304
344
[sg .Column ([
@@ -389,7 +429,7 @@ def uiThread():
389
429
[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' )],
390
430
[sg .Text ('Imagine That there is a checkbox here :)' )],
391
431
[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' )]
393
433
], expand_x = True , size = (379 , 130 ))]
394
434
]
395
435
, scrollable = True , vertical_scroll_only = True , expand_x = True , expand_y = True , background_color = 'turquoise4' )]]
@@ -432,8 +472,13 @@ def uiThread():
432
472
], size = (379 , 150 ))]
433
473
] , scrollable = True , vertical_scroll_only = True , expand_x = True , expand_y = True , background_color = 'turquoise4' )]]
434
474
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
+
435
480
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' ]]]
437
482
topMenuBar = sg .Menu (menu_def , key = "menuBar" )
438
483
right_click_menu = ['&Right' , ['You thought' ]]
439
484
layout = [
@@ -445,7 +490,8 @@ def uiThread():
445
490
sg .Tab ('Preview' , preview_layout , background_color = 'DarkGreen' ),
446
491
sg .Tab ('Keybindings' , keybindings_layout , background_color = 'turquoise4' ),
447
492
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' )
449
495
]],
450
496
key = 'mainTabs' , tab_location = 'lefttop' , selected_title_color = 'white' , selected_background_color = 'gray' , expand_x = True , expand_y = True , size = (440 , 300 )
451
497
)
@@ -501,7 +547,8 @@ def resetVars():
501
547
window ['oscForewordPort' ].update (value = '9002' )
502
548
window ['oscListen' ].update (value = True )
503
549
window ['oscForeword' ].update (value = False )
504
- def pullVars ():
550
+ window ['logOutput' ].update (value = False )
551
+ def updateUI ():
505
552
global playMsg
506
553
global msgOutput
507
554
if os .path .isfile ('please-do-not-delete.txt' ):
@@ -547,6 +594,7 @@ def pullVars():
547
594
window ['oscForewordPort' ].update (value = oscForewordPort )
548
595
window ['oscListen' ].update (value = oscListen )
549
596
window ['oscForeword' ].update (value = oscForeword )
597
+ window ['logOutput' ].update (value = logOutput )
550
598
while run :
551
599
if run :
552
600
try :
@@ -558,8 +606,8 @@ def pullVars():
558
606
if run :
559
607
window ['runThing' ].update (value = playMsg )
560
608
window ['afk' ].update (value = afk )
561
- pullVarsThread = Thread (target = pullVars )
562
- pullVarsThread .start ()
609
+ updateUIThread = Thread (target = updateUI )
610
+ updateUIThread .start ()
563
611
if minimizeOnStart :
564
612
window .minimize ()
565
613
windowAccess = window
@@ -681,9 +729,10 @@ def pullVars():
681
729
oscForewordPort = values ['oscForewordPort' ]
682
730
oscListen = values ['oscListen' ]
683
731
oscForeword = values ['oscForeword' ]
732
+ logOutput = values ['logOutput' ]
684
733
with open ('please-do-not-delete.txt' , 'w' , encoding = "utf-8" ) as f :
685
734
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 ]))
687
736
except Exception as e :
688
737
sg .popup ('Error saving config to file:\n ' + str (e ))
689
738
"""print('Popup Open') #Popup Shit is broken
@@ -699,7 +748,7 @@ def pullVars():
699
748
if event == 'Open Github Page' :
700
749
webbrowser .open ('https://github.com/Lioncat6/OSC-Chat-Tools' )
701
750
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' )]]
703
752
about_window = sg .Window ('About' , about_popop_layout )
704
753
event , values = about_window .read ()
705
754
about_window .close ()
@@ -778,6 +827,21 @@ def checkPressThread():
778
827
window ['versionText' ].update (value = window ['versionText' ].get ()+ " - New Update Available" )
779
828
if event == 'popup' :
780
829
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 ])
781
845
window .close ()
782
846
playMsg = False
783
847
run = False
@@ -859,6 +923,7 @@ def dataSender():
859
923
global oscForeword
860
924
runForewordServer = True
861
925
print ('Starting Forwarding server on ' + str (forward_addresses ))
926
+ outputLog ('Starting Forwarding server on ' + str (forward_addresses ))
862
927
oscListenAddressMemory = oscListenAddress
863
928
oscListenPortMemory = oscListenPort
864
929
oscForewordPortMemory = oscForewordPort
@@ -885,6 +950,7 @@ def dataSender():
885
950
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 ):
886
951
if oscForeword or oscListen :
887
952
print ('Foreword/Listen Server Config Updated, Restarting Forwarding Server...\n ' )
953
+ outputLog ('Foreword/Listen Server Config Updated, Restarting Forwarding Server...\n ' )
888
954
runForewordServer = False
889
955
time .sleep (.5 )
890
956
if not runForewordServer :
@@ -893,6 +959,7 @@ def dataSender():
893
959
if runForewordServer and not (oscForeword or oscListen ):
894
960
runForewordServer = False
895
961
print ('No OSC Foreword/Listening Options are selected, stopping Forwarding Server...' )
962
+ outputLog ('No OSC Foreword/Listening Options are selected, stopping Forwarding Server...' )
896
963
time .sleep (.5 )
897
964
oscForwardingManagerThread = Thread (target = oscForwardingManager )
898
965
oscForwardingManagerThread .start ()
@@ -919,7 +986,7 @@ def listenServerThread():
919
986
listenServer = osc_server .ThreadingOSCUDPServer (
920
987
(args .ip , args .port ), dispatcher )
921
988
print ("Osc Listen Server Serving on {}" .format (listenServer .server_address ))
922
-
989
+ outputLog ( "Osc Listen Server Serving on {}" . format ( listenServer . server_address ))
923
990
sockett = listenServer .socket
924
991
sockett .setsockopt (socket .SOL_SOCKET , socket .SO_REUSEADDR , 1 )
925
992
@@ -928,13 +995,15 @@ def listenServerThread():
928
995
listenServer .serve_forever ()
929
996
except Exception as e :
930
997
print ('Osc Listen Server Failed to Start, Retying...' + str (e ))
998
+ outputLog ('Osc Listen Server Failed to Start, Retying...' + str (e ))
931
999
pass
932
1000
933
1001
if not isListenServerRunning :
934
1002
oscServerThread = Thread (target = listenServerThread )
935
1003
oscServerThread .start ()
936
1004
if not oscListen and isListenServerRunning :
937
1005
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...' )
938
1007
isListenServerRunning = False
939
1008
listenServer .shutdown ()
940
1009
listenServer .server_close ()
@@ -1154,7 +1223,7 @@ def hrConnectionThread():
1154
1223
if not hrConnected :
1155
1224
try :
1156
1225
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
1158
1227
hrConnected = True
1159
1228
def pulsoidListen ():
1160
1229
global heartRate
@@ -1169,10 +1238,10 @@ def pulsoidListen():
1169
1238
pass
1170
1239
if not run or not hrConnected :
1171
1240
break
1172
-
1173
1241
pulsoidListenThread = Thread (target = pulsoidListen )
1174
1242
pulsoidListenThread .start ()
1175
1243
def blinkHR ():
1244
+ global blinkThread
1176
1245
global heartRate
1177
1246
global blinkOverride
1178
1247
global blinkSpeed
@@ -1194,13 +1263,15 @@ def blinkHR():
1194
1263
blinkHRThread = Thread (target = blinkHR )
1195
1264
blinkHRThread .start ()
1196
1265
print ('Pulsoid Connection Started...' )
1266
+ outputLog ('Pulsoid Connection Started...' )
1197
1267
except Exception as e :
1198
1268
if windowAccess != None :
1199
1269
if playMsg :
1200
1270
windowAccess .write_event_value ('pulsoidError' , e )
1201
1271
if ((not topHRToggle and not bottomHRToggle and not avatarHR ) or not (playMsg or avatarHR )) and hrConnected :
1202
1272
hrConnected = False
1203
1273
print ('Pulsoid Connection Stopped' )
1274
+ outputLog ('Pulsoid Connection Stopped' )
1204
1275
time .sleep (.3 )
1205
1276
hrConnectionThreadRun = Thread (target = hrConnectionThread )
1206
1277
hrConnectionThreadRun .start ()
0 commit comments