Implemented v1

This commit is contained in:
2026-06-03 13:26:46 +01:00
parent dcf7a59ea9
commit a95c6e7183
3 changed files with 98 additions and 0 deletions

View File

@ -1,2 +1,10 @@
# Simple OSC Router # Simple OSC Router
A simple router for allowing multiple applications to talk to VRChat simultaneously. A simple router for allowing multiple applications to talk to VRChat simultaneously.
## How do I use it?
By default, this software broadcasts anthing from ports 9100 to 9199 (depending on the `--count` / `-c` option) to port 9000 (VRChat's OSC server).
And broadcasts anything from port 9001 (VRChat's OSC client) to ports 9200 to 9299 (still depending on `-c`).
The only command line argument is `--count` / `-c`, which specifies how many routes will be created. This defaults to `5`.
For most cases you can simply run `main.py`, if you want more configuration (such as changing port numbers, binds etc.) see `python3 main.py --help` or `py main.py --help` on Windows.

89
main.py Normal file
View File

@ -0,0 +1,89 @@
"""
A simple router for allowing multiple applications to talk to VRChat simultaneously.
"""
from threading import Thread
import argparse
import logging
from pythonosc import udp_client, osc_server
from pythonosc.dispatcher import Dispatcher
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger('main')
parser = argparse.ArgumentParser(description='Simple OSC router/')
parser.add_argument('--count', '-c', type=int, help='How many routers to create', default=5)
parser.add_argument('--routerIP', type=str, default='127.0.0.1',
help='')
parser.add_argument('--routerTXStartPort', '-ssp', type=int,
help='The starting port for the router servers.', default=9100)
parser.add_argument('--routerRXStartPort', '-csp', type=int,
help='The starting port for the router clients.', default=9200)
parser.add_argument('--masterIP', type=str, default='127.0.0.1',
help='')
parser.add_argument('--masterTXPort', type=int,
help='', default=9000)
parser.add_argument('--masterRXPort', type=int,
help='', default=9001)
args = parser.parse_args()
routerDispatcher = Dispatcher()
masterDispatcher = Dispatcher()
masterServer = osc_server.ThreadingOSCUDPServer((args.masterIP, args.masterRXPort),
masterDispatcher, timeout=2.5)
masterClient = udp_client.SimpleUDPClient(args.masterIP, args.masterTXPort, timeout=2.5)
routerServers = []
routerClients = []
def broadcastToMaster(address, value):
"""
Broadcasts anything sent from a router to the master.
"""
logger.debug('Broadcasting "%s"="%s" to master...', address, value)
masterClient.send_message(address, value)
def broadcastToRouters(address, value):
"""
Broadcasts anything sent from the master to the routers.
"""
logger.debug('Broadcasting "%s"="%s" to %s routers...', address, value, len(routerClients))
for c in routerClients:
c.send_message(address, value)
routerDispatcher.map('*', broadcastToMaster)
masterDispatcher.map('*', broadcastToRouters)
for i in range(args.count):
logger.debug('Starting router #%s...', i+1)
serverPort = args.routerRXStartPort + i
clientPort = args.routerTXStartPort + i
server = osc_server.ThreadingOSCUDPServer((args.routerIP, serverPort), routerDispatcher,
timeout=2.5)
client = udp_client.SimpleUDPClient(args.routerIP, clientPort, timeout=2.5)
routerClients.append(client)
routerServers.append(server)
Thread(target=server.serve_forever).start()
logger.info('Ready. Press CTRL+C to quit.')
try:
masterServer.serve_forever()
except KeyboardInterrupt:
pass
masterServer.server_close()
for s in routerServers:
s.server_close()

1
requirements.txt Normal file
View File

@ -0,0 +1 @@
python-osc