12
12
13
13
namespace VRCFaceTracking . Core . Services ;
14
14
15
- public partial class OscQueryService : ObservableObject
15
+ public partial class OscQueryService (
16
+ ILogger < OscQueryService > logger ,
17
+ OscQueryConfigParser oscQueryConfigParser ,
18
+ AvatarConfigParser avatarConfigParser ,
19
+ ParameterSenderService parameterSenderService ,
20
+ IOscTarget oscTarget ,
21
+ MulticastDnsService multicastDnsService ,
22
+ OscRecvService recvService ,
23
+ ILocalSettingsService settingsService ,
24
+ HttpHandler httpHandler )
25
+ : ObservableObject
16
26
{
17
- private const string k_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ;
18
-
27
+
19
28
// Services
20
- private readonly ILogger _logger ;
21
- private readonly OscQueryConfigParser _oscQueryConfigParser ;
22
- private readonly MulticastDnsService _multicastDnsService ;
23
- private readonly AvatarConfigParser _configParser ;
24
- private readonly ParameterSenderService _parameterSenderService ;
25
- private static readonly Random Random = new ( ) ;
26
-
29
+ private readonly ILogger _logger = logger ;
30
+
27
31
[ ObservableProperty ] private IAvatarInfo _avatarInfo = new NullAvatarDef ( "Loading..." , "Loading..." ) ;
28
32
[ ObservableProperty ] private List < Parameter > _avatarParameters ;
29
33
30
- private readonly IOscTarget _oscTarget ;
31
-
32
34
// Local vars
33
- private readonly OscRecvService _recvService ;
34
- private readonly ILocalSettingsService _settingsService ;
35
- private readonly HttpHandler _httpHandler ;
36
-
37
- public OscQueryService (
38
- ILogger < OscQueryService > logger ,
39
- OscQueryConfigParser oscQueryConfigParser ,
40
- AvatarConfigParser avatarConfigParser ,
41
- ParameterSenderService parameterSenderService ,
42
- IOscTarget oscTarget ,
43
- MulticastDnsService multicastDnsService ,
44
- OscRecvService recvService ,
45
- ILocalSettingsService settingsService ,
46
- HttpHandler httpHandler
47
- )
48
- {
49
- _oscQueryConfigParser = oscQueryConfigParser ;
50
- _configParser = avatarConfigParser ;
51
- _parameterSenderService = parameterSenderService ;
52
- _logger = logger ;
53
- _recvService = recvService ;
54
- _recvService . OnMessageReceived = HandleNewMessage ;
55
- _multicastDnsService = multicastDnsService ;
56
- _oscTarget = oscTarget ;
57
- _settingsService = settingsService ;
58
- _httpHandler = httpHandler ;
59
- }
60
35
61
36
public async Task InitializeAsync ( )
62
37
{
63
38
_logger . LogDebug ( "OSC Service Initializing" ) ;
64
-
65
- await _settingsService . Load ( _oscTarget ) ;
66
-
39
+
40
+ recvService . OnMessageReceived = HandleNewMessage ;
41
+
42
+ await settingsService . Load ( oscTarget ) ;
43
+
67
44
( bool listenerSuccess , bool senderSuccess ) result = ( false , false ) ;
68
45
69
- if ( string . IsNullOrWhiteSpace ( _oscTarget . DestinationAddress ) )
46
+ if ( string . IsNullOrWhiteSpace ( oscTarget . DestinationAddress ) )
70
47
{
71
48
return ; // Return both false as we cant bind to anything without an address
72
49
}
73
50
74
- _multicastDnsService . OnVrcClientDiscovered += FirstClientDiscovered ;
75
-
76
- _multicastDnsService . SendQuery ( "_oscjson._tcp.local" ) ;
77
-
51
+ multicastDnsService . OnVrcClientDiscovered += FirstClientDiscovered ;
52
+
53
+ multicastDnsService . SendQuery ( "_oscjson._tcp.local" ) ;
54
+
78
55
_logger . LogDebug ( "OSC Service Initialized with result {0}" , result ) ;
79
56
await Task . CompletedTask ;
80
57
}
81
-
58
+
82
59
private void FirstClientDiscovered ( )
83
60
{
84
- _multicastDnsService . OnVrcClientDiscovered -= FirstClientDiscovered ;
85
-
86
- _logger . LogInformation ( "OSCQuery detected. Setting port negotiation to autopilot." ) ;
87
-
88
- var randomStr = new string ( Enumerable . Repeat ( k_chars , 6 ) . Select ( s => s [ Random . Next ( s . Length ) ] ) . ToArray ( ) ) ;
89
- _httpHandler . OnHostInfoQueried += HandleNewAvatarWrapper ;
90
-
91
- var recvEndpoint = _recvService . UpdateTarget ( new IPEndPoint ( IPAddress . Parse ( _oscTarget . DestinationAddress ) , 0 ) ) ;
61
+ multicastDnsService . OnVrcClientDiscovered -= FirstClientDiscovered ;
62
+
63
+ _logger . LogInformation ( $ "OSCQuery detected at { multicastDnsService . VrchatClientEndpoint } . Setting port negotiation to autopilot.") ;
64
+
65
+ httpHandler . OnHostInfoQueried += HandleNewAvatarWrapper ;
66
+
67
+ var recvEndpoint = recvService . UpdateTarget ( new IPEndPoint ( IPAddress . Parse ( oscTarget . DestinationAddress ) , 0 ) ) ;
92
68
if ( recvEndpoint == null )
93
69
{
94
70
_logger . LogError ( "Very strange. We were unable to bind to a random port." ) ;
95
- recvEndpoint = new IPEndPoint ( IPAddress . Parse ( _oscTarget . DestinationAddress ) , _oscTarget . InPort ) ;
71
+ recvEndpoint = new IPEndPoint ( IPAddress . Parse ( oscTarget . DestinationAddress ) , oscTarget . InPort ) ;
96
72
}
97
-
98
- // TODO: Move this somewhere more appropriate
99
- var listener = new TcpListener ( IPAddress . Any , 0 ) ;
100
- listener . Start ( ) ;
101
- var port = ( ( IPEndPoint ) listener . LocalEndpoint ) . Port ;
102
- listener . Stop ( ) ;
103
- _httpHandler . SetAppName ( "VRCFT-" + randomStr ) ;
104
- _httpHandler . BindTo ( $ "http://127.0.0.1:{ port } /", recvEndpoint . Port ) ;
105
-
73
+
74
+ var randomServiceSuffix = Utils . GetRandomChars ( 6 ) ;
75
+ var httpPort = Utils . GetRandomFreePort ( ) ;
76
+ httpHandler . SetAppName ( "VRCFT-" + randomServiceSuffix ) ;
77
+ httpHandler . BindTo ( $ "http://127.0.0.1:{ httpPort } /", recvEndpoint . Port ) ;
78
+
106
79
// Advertise our OSC JSON and OSC endpoints (OSC JSON to display the silly lil popup in-game)
107
- _multicastDnsService . Advertise ( "_oscjson._tcp" , "VRCFT-" + randomStr , port , IPAddress . Loopback ) ;
108
- _multicastDnsService . Advertise ( "_osc._udp" , "VRCFT-" + randomStr , recvEndpoint . Port , IPAddress . Loopback ) ;
109
-
80
+ multicastDnsService . Advertise ( "_oscjson._tcp" , new AdvertisedService ( "VRCFT-" + randomServiceSuffix , httpPort , IPAddress . Loopback ) ) ;
81
+ multicastDnsService . Advertise ( "_osc._udp" , new AdvertisedService ( "VRCFT-" + randomServiceSuffix , recvEndpoint . Port , IPAddress . Loopback ) ) ;
82
+
110
83
HandleNewAvatar ( ) ;
111
84
}
112
85
@@ -115,21 +88,21 @@ private async void HandleNewAvatar(string newId = null)
115
88
var newAvatar = default ( ( IAvatarInfo avatarInfo , List < Parameter > relevantParameters ) ? ) ;
116
89
if ( newId == null )
117
90
{
118
- _httpHandler . OnHostInfoQueried -= HandleNewAvatarWrapper ;
119
- newAvatar = await _oscQueryConfigParser . ParseAvatar ( "" ) ;
91
+ httpHandler . OnHostInfoQueried -= HandleNewAvatarWrapper ;
92
+ newAvatar = await oscQueryConfigParser . ParseAvatar ( "" ) ;
120
93
}
121
94
else
122
95
{
123
96
// handle normal osc
124
- newAvatar = await _configParser . ParseAvatar ( newId ) ;
97
+ newAvatar = await avatarConfigParser . ParseAvatar ( newId ) ;
125
98
}
126
99
if ( newAvatar . HasValue )
127
100
{
128
101
AvatarInfo = newAvatar . Value . avatarInfo ;
129
102
AvatarParameters = newAvatar . Value . relevantParameters ;
130
103
}
131
104
}
132
-
105
+
133
106
private void HandleNewAvatarWrapper ( )
134
107
{
135
108
HandleNewAvatar ( ) ;
@@ -145,7 +118,7 @@ private void HandleNewMessage(OscMessage msg)
145
118
case "/vrcft/settings/forceRelevant" : // Endpoint for external tools to force vrcft to send all parameters
146
119
if ( msg . Value is bool relevancy )
147
120
{
148
- _parameterSenderService . AllParametersRelevant = relevancy ;
121
+ parameterSenderService . AllParametersRelevant = relevancy ;
149
122
}
150
123
151
124
break ;
@@ -192,4 +165,4 @@ partial void OnAvatarParametersChanged(List<Parameter> value)
192
165
_logger . LogDebug ( $ "Loaded deprecated parameters: { string . Join ( ", " , deprecatedParams . SelectMany ( x => x . GetParamNames ( ) ) . Select ( y => y . paramName ) ) } ") ;
193
166
}
194
167
}
195
- }
168
+ }
0 commit comments