diff --git a/src-python/controller.py b/src-python/controller.py index 11942ae8..821cd397 100644 --- a/src-python/controller.py +++ b/src-python/controller.py @@ -1426,9 +1426,12 @@ class Controller: @staticmethod def setEnableVrcMicMuteSync(*args, **kwargs) -> dict: - config.VRC_MIC_MUTE_SYNC = True - model.setMuteSelfStatus() - model.changeMicTranscriptStatus() + if model.getIsOscQueryEnabled() is False: + config.VRC_MIC_MUTE_SYNC = True + model.setMuteSelfStatus() + model.changeMicTranscriptStatus() + else: + config.VRC_MIC_MUTE_SYNC = False return {"status":200, "result":config.VRC_MIC_MUTE_SYNC} @staticmethod @@ -1909,6 +1912,12 @@ class Controller: def initializationProgress(self, progress): self.run(200, self.run_mapping["initialization_progress"], progress) + def enableOscQuery(self): + self.run(200, self.run_mapping["enable_osc_query"], True) + + def disableOscQuery(self): + self.run(200, self.run_mapping["enable_osc_query"], False) + def init(self, *args, **kwargs) -> None: removeLog() printLog("Start Initialization") @@ -1986,6 +1995,12 @@ class Controller: # init OSC receive printLog("Init OSC Receive") model.startReceiveOSC() + osc_query_enabled = model.getIsOscQueryEnabled() + if osc_query_enabled is True: + self.enableOscQuery() + else: + self.disableOscQuery() + if config.VRC_MIC_MUTE_SYNC is True: self.setEnableVrcMicMuteSync() diff --git a/src-python/mainloop.py b/src-python/mainloop.py index 6b684b38..00bc8cb5 100644 --- a/src-python/mainloop.py +++ b/src-python/mainloop.py @@ -45,6 +45,8 @@ run_mapping = { "initialization_progress":"/run/initialization_progress", "initialization_complete":"/run/initialization_complete", + + "enable_osc_query":"/run/enable_osc_query", } def run(status:int, endpoint:str, result:Any) -> None: diff --git a/src-python/model.py b/src-python/model.py index c4bd6466..3b4e51b6 100644 --- a/src-python/model.py +++ b/src-python/model.py @@ -299,11 +299,8 @@ class Model: def oscSendMessage(self, message:str): self.osc_handler.sendMessage(message=message, notification=config.NOTIFICATION_VRC_SFX) - def getMuteSelfStatus(self): - return self.osc_handler.getOSCParameterMuteSelf() - def setMuteSelfStatus(self): - self.mic_mute_status = self.getMuteSelfStatus() + self.mic_mute_status = self.osc_handler.getOSCParameterMuteSelf() def startReceiveOSC(self): def changeHandlerMute(address, osc_arguments): @@ -318,11 +315,15 @@ class Model: dict_filter_and_target = { self.osc_handler.osc_parameter_muteself: changeHandlerMute, } - self.osc_handler.receiveOscParameters(dict_filter_and_target) + self.osc_handler.setDictFilterAndTarget(dict_filter_and_target) + self.osc_handler.receiveOscParameters() def stopReceiveOSC(self): self.osc_handler.oscServerStop() + def getIsOscQueryEnabled(self): + return self.osc_handler.getIsOscQueryEnabled() + @staticmethod def checkSoftwareUpdated(): # check update @@ -510,12 +511,16 @@ class Model: def changeMicTranscriptStatus(self): if config.VRC_MIC_MUTE_SYNC is True: - if self.mic_mute_status is True: - self.pauseMicTranscript() - elif self.mic_mute_status is False: - self.resumeMicTranscript() - else: - pass + match self.mic_mute_status: + case True: + self.pauseMicTranscript() + case False: + self.resumeMicTranscript() + case None: + # mute selfの状態が不明な場合は一時停止しない + self.resumeMicTranscript() + case _: + pass else: self.resumeMicTranscript() diff --git a/src-python/models/osc/osc.py b/src-python/models/osc/osc.py index 758918af..ef4e1152 100644 --- a/src-python/models/osc/osc.py +++ b/src-python/models/osc/osc.py @@ -7,10 +7,22 @@ from tinyoscquery.queryservice import OSCQueryService from tinyoscquery.query import OSCQueryBrowser, OSCQueryClient from tinyoscquery.utility import get_open_udp_port, get_open_tcp_port from tinyoscquery.shared.node import OSCAccess -from utils import errorLogging + +try: + from utils import errorLogging +except ImportError: + def errorLogging(): + import traceback + print("Error occurred:", traceback.format_exc()) class OSCHandler: def __init__(self, ip_address="127.0.0.1", port=9000) -> None: + + if ip_address in ["127.0.0.1", "localhost"]: + self.is_osc_query_enabled = True + else: + self.is_osc_query_enabled = False + self.osc_ip_address = ip_address self.osc_port = port self.osc_parameter_muteself = "/avatar/parameters/MuteSelf" @@ -24,15 +36,28 @@ class OSCHandler: self.osc_server_ip_address = ip_address self.http_port = None self.osc_server_port = None + self.dict_filter_and_target = {} self.browser = None + def getIsOscQueryEnabled(self) -> bool: + return self.is_osc_query_enabled + def setOscIpAddress(self, ip_address:str) -> None: + if ip_address in ["127.0.0.1", "localhost"]: + self.is_osc_query_enabled = True + else: + self.is_osc_query_enabled = False + + self.oscServerStop() self.osc_ip_address = ip_address self.udp_client = udp_client.SimpleUDPClient(self.osc_ip_address, self.osc_port) + self.receiveOscParameters() def setOscPort(self, port:int) -> None: + self.oscServerStop() self.osc_port = port self.udp_client = udp_client.SimpleUDPClient(self.osc_ip_address, self.osc_port) + self.receiveOscParameters() # send OSC message typing def sendTyping(self, flag:bool=False) -> None: @@ -44,6 +69,10 @@ class OSCHandler: self.udp_client.send_message(self.osc_parameter_chatbox_input, [f"{message}", True, notification]) def getOSCParameterValue(self, address:str) -> Any: + if not self.is_osc_query_enabled: + # OSCQueryが無効な場合はNoneを返す + return None + value = None try: # browserインスタンスを再利用し、毎回の生成と破棄を避ける @@ -71,19 +100,26 @@ class OSCHandler: def getOSCParameterMuteSelf(self) -> bool: return self.getOSCParameterValue(self.osc_parameter_muteself) - def receiveOscParameters(self, dict_filter_and_target:dict) -> None: + def setDictFilterAndTarget(self, dict_filter_and_target:dict) -> None: + self.dict_filter_and_target = dict_filter_and_target + + def receiveOscParameters(self) -> None: + if self.is_osc_query_enabled is False: + # OSCQueryが無効な場合は何もしない + return + self.osc_server_port = get_open_udp_port() self.http_port = get_open_tcp_port() osc_dispatcher = dispatcher.Dispatcher() - for filter, target in dict_filter_and_target.items(): + for filter, target in self.dict_filter_and_target.items(): osc_dispatcher.map(filter, target) - self.osc_server = osc_server.ThreadingOSCUDPServer((self.osc_server_ip_address, self.osc_server_port), osc_dispatcher, asyncio.get_event_loop()) + self.osc_server = osc_server.ThreadingOSCUDPServer((self.osc_server_ip_address, self.osc_server_port), osc_dispatcher) Thread(target=self.oscServerServe, daemon=True).start() while True: try: self.osc_query_service = OSCQueryService(self.osc_query_service_name, self.http_port, self.osc_server_port) - for filter, target in dict_filter_and_target.items(): + for filter, target in self.dict_filter_and_target.items(): self.osc_query_service.advertise_endpoint(filter, access=OSCAccess.READWRITE_VALUE) break except Exception: @@ -112,12 +148,26 @@ class OSCHandler: if __name__ == "__main__": handler = OSCHandler() - handler.receiveOscParameters({ - "/avatar/parameters/MuteSelf": print, + handler.setDictFilterAndTarget({ + "/avatar/parameters/MuteSelf": lambda address, *args: print(f"Received {address} with args {args}"), + "/chatbox/typing": lambda address, *args: print(f"Received {address} with args {args}"), + "/chatbox/input": lambda address, *args: print(f"Received {address} with args {args}"), }) + handler.receiveOscParameters() sleep(5) handler.sendTyping(True) sleep(1) - handler.sendMessage(message="Hello World", notification=True) - sleep(60) + handler.sendMessage(message="Hello World 1", notification=True) + sleep(10) + + print("IP address changed to 192.168.193.2") + handler.setOscIpAddress("192.168.193.2") + sleep(5) + handler.sendMessage(message="Hello World 2", notification=True) + + print("IP address changed to 127.0.0.1") + handler.setOscIpAddress("127.0.0.1") + sleep(5) + handler.sendMessage(message="Hello World 3", notification=True) + sleep(10) handler.oscServerStop() \ No newline at end of file