1- using ConnectX . Client . Interfaces ;
1+ using System . Collections . ObjectModel ;
2+ using ConnectX . Client . Interfaces ;
23using ConnectX . Client . Managers ;
34using ConnectX . Client . Route ;
45using ConnectX . Shared . Helpers ;
@@ -14,6 +15,12 @@ namespace ConnectX.Client;
1415
1516public record PartnerConnectionState ( bool IsConnected , bool IsDirectConnection , int Latency ) ;
1617
18+ public record OpResult (
19+ GroupInfo ? Info ,
20+ GroupCreationStatus Status ,
21+ IReadOnlyDictionary < string , string > Metadata ,
22+ string ? Error ) ;
23+
1724public class Client
1825{
1926 private readonly IDispatcher _dispatcher ;
@@ -112,12 +119,17 @@ private void OnGroupUserStateChanged(MessageContext<GroupUserStateChanged> ctx)
112119
113120 switch ( state )
114121 {
122+ case GroupUserStates . Joined :
123+ if ( _isInGroup && _roomInfoManager . CurrentGroupInfo ? . RoomId != null )
124+ _roomInfoManager . AcquireGroupInfoAsync ( _roomInfoManager . CurrentGroupInfo ! . RoomId ) . Forget ( ) ;
125+ break ;
115126 case GroupUserStates . Left :
116127 case GroupUserStates . Disconnected :
117128 case GroupUserStates . Kicked :
118129 if ( userInfo ? . UserId == _serverLinkHolder . UserId )
119130 ResetRoomState ( ) . Forget ( ) ;
120- else _roomInfoManager . AcquireGroupInfoAsync ( _roomInfoManager . CurrentGroupInfo ! . RoomId ) . Forget ( ) ;
131+ else if ( _isInGroup && _roomInfoManager . CurrentGroupInfo ? . RoomId != null )
132+ _roomInfoManager . AcquireGroupInfoAsync ( _roomInfoManager . CurrentGroupInfo ! . RoomId ) . Forget ( ) ;
121133 break ;
122134 case GroupUserStates . Dismissed :
123135 ResetRoomState ( ) . Forget ( ) ;
@@ -127,74 +139,84 @@ private void OnGroupUserStateChanged(MessageContext<GroupUserStateChanged> ctx)
127139 OnGroupStateChanged ? . Invoke ( state , userInfo ) ;
128140 }
129141
130- private async Task < ( GroupInfo ? , GroupCreationStatus , string ? ) > PerformOpAndGetRoomInfoAsync < T > ( T message , CancellationToken ct )
142+ private async Task < OpResult > PerformOpAndGetRoomInfoAsync < T > ( T message , CancellationToken ct )
131143 {
132- var createResult = await PerformGroupOpAsync ( message ) ;
144+ var opResult = await PerformGroupOpAsync ( message ) ;
133145
134- if ( createResult == null )
135- return ( null , GroupCreationStatus . Other , null ) ;
136- if ( createResult . Status != GroupCreationStatus . Succeeded )
137- return ( null , createResult . Status , createResult . ErrorMessage ) ;
146+ if ( opResult == null )
147+ return new OpResult ( null , GroupCreationStatus . Other , ReadOnlyDictionary < string , string > . Empty , null ) ;
148+ if ( opResult . Status != GroupCreationStatus . Succeeded )
149+ return new OpResult ( null , opResult . Status , ReadOnlyDictionary < string , string > . Empty , opResult . ErrorMessage ) ;
138150
139- var groupInfo = await _roomInfoManager . AcquireGroupInfoAsync ( createResult . RoomId ) ;
151+ var groupInfo = await _roomInfoManager . AcquireGroupInfoAsync ( opResult . RoomId ) ;
140152
141153 if ( groupInfo == null )
142- return ( null , GroupCreationStatus . Other , "Failed to acquire group info" ) ;
154+ return new OpResult ( null , GroupCreationStatus . Other , ReadOnlyDictionary < string , string > . Empty , "Failed to acquire group info" ) ;
143155
144156 if ( OperatingSystem . IsWindows ( ) &&
145157 message is JoinGroup or CreateGroup )
146158 {
147- if ( createResult . Status != GroupCreationStatus . Succeeded )
148- return ( null , createResult . Status , createResult . ErrorMessage ) ;
149-
150- _logger . LogJoiningNetwork ( groupInfo . RoomNetworkId ) ;
151-
152- var networkResult = await _zeroTierNodeLinkHolder . JoinNetworkAsync ( groupInfo . RoomNetworkId , ct ) ;
153-
154- if ( ! networkResult )
155- return ( null , GroupCreationStatus . Other , "Failed to join the network" ) ;
159+ if ( opResult . Status != GroupCreationStatus . Succeeded )
160+ return new OpResult ( null , opResult . Status , ReadOnlyDictionary < string , string > . Empty , opResult . ErrorMessage ) ;
156161
157- await TaskHelper . WaitUntilAsync ( _zeroTierNodeLinkHolder . IsNodeOnline , ct ) ;
158-
159- var nodeId = _zeroTierNodeLinkHolder . Node ! . IdString ;
160- var updateInfo = new UpdateRoomMemberNetworkInfo
162+ if ( opResult . Metadata . TryGetValue ( GroupOpResult . UseRelayServerKey , out var useRelayServerStr ) &&
163+ bool . TryParse ( useRelayServerStr , out var useRelayServer ) &&
164+ ! useRelayServer )
161165 {
162- NetworkNodeId = nodeId ,
163- NetworkIpAddresses = _zeroTierNodeLinkHolder . GetIpAddresses ( )
164- } ;
165-
166- var result = await _dispatcher . SendAndListenOnce < UpdateRoomMemberNetworkInfo , GroupOpResult > (
167- _serverLinkHolder . ServerSession ! ,
168- updateInfo , ct ) ;
169-
170- if ( result is not { Status : GroupCreationStatus . Succeeded } )
171- return ( null , result ? . Status ?? GroupCreationStatus . Other , "Failed to update room member network info" ) ;
166+ // If the group is not using relay server, we need to join the network
167+ _logger . LogJoiningNetwork ( groupInfo . RoomNetworkId ) ;
168+
169+ var networkResult = await _zeroTierNodeLinkHolder . JoinNetworkAsync ( groupInfo . RoomNetworkId , ct ) ;
170+
171+ if ( ! networkResult )
172+ return new OpResult ( null , GroupCreationStatus . Other , ReadOnlyDictionary < string , string > . Empty , "Failed to join the network" ) ;
173+
174+ await TaskHelper . WaitUntilAsync ( _zeroTierNodeLinkHolder . IsNodeOnline , ct ) ;
175+
176+ var nodeId = _zeroTierNodeLinkHolder . Node ! . IdString ;
177+ var updateInfo = new UpdateRoomMemberNetworkInfo
178+ {
179+ NetworkNodeId = nodeId ,
180+ NetworkIpAddresses = _zeroTierNodeLinkHolder . GetIpAddresses ( )
181+ } ;
182+
183+ var result = await _dispatcher . SendAndListenOnce < UpdateRoomMemberNetworkInfo , GroupOpResult > (
184+ _serverLinkHolder . ServerSession ! ,
185+ updateInfo , ct ) ;
186+
187+ if ( result is not { Status : GroupCreationStatus . Succeeded } )
188+ return new OpResult (
189+ null ,
190+ result ? . Status ?? GroupCreationStatus . Other ,
191+ ReadOnlyDictionary < string , string > . Empty ,
192+ "Failed to update room member network info" ) ;
193+ }
172194 }
173195
174196 _isInGroup = true ;
175- return ( groupInfo , GroupCreationStatus . Succeeded , null ) ;
197+ return new OpResult ( groupInfo , GroupCreationStatus . Succeeded , opResult . Metadata , null ) ;
176198 }
177199
178- public async Task < ( GroupInfo ? Info , GroupCreationStatus Status , string ? Error ) > CreateGroupAsync ( CreateGroup createGroup , CancellationToken ct )
200+ public async Task < OpResult > CreateGroupAsync ( CreateGroup createGroup , CancellationToken ct )
179201 {
180202 if ( ! _serverLinkHolder . IsConnected )
181- return ( null , GroupCreationStatus . Other , "Not connected to the server" ) ;
203+ return new OpResult ( null , GroupCreationStatus . Other , ReadOnlyDictionary < string , string > . Empty , "Not connected to the server" ) ;
182204 if ( ! _serverLinkHolder . IsSignedIn )
183- return ( null , GroupCreationStatus . Other , "Not signed in" ) ;
205+ return new OpResult ( null , GroupCreationStatus . Other , ReadOnlyDictionary < string , string > . Empty , "Not signed in" ) ;
184206 if ( ! OperatingSystem . IsWindows ( ) && ! createGroup . UseRelayServer )
185- return ( null , GroupCreationStatus . Other , "Only Windows platform supports direct connection" ) ;
207+ return new OpResult ( null , GroupCreationStatus . Other , ReadOnlyDictionary < string , string > . Empty , "Only Windows platform supports direct connection" ) ;
186208
187209 return await PerformOpAndGetRoomInfoAsync ( createGroup , ct ) ;
188210 }
189211
190- public async Task < ( GroupInfo ? , GroupCreationStatus , string ? ) > JoinGroupAsync ( JoinGroup joinGroup , CancellationToken ct )
212+ public async Task < OpResult > JoinGroupAsync ( JoinGroup joinGroup , CancellationToken ct )
191213 {
192214 if ( ! _serverLinkHolder . IsConnected )
193- return ( null , GroupCreationStatus . Other , "Not connected to the server" ) ;
215+ return new OpResult ( null , GroupCreationStatus . Other , ReadOnlyDictionary < string , string > . Empty , "Not connected to the server" ) ;
194216 if ( ! _serverLinkHolder . IsSignedIn )
195- return ( null , GroupCreationStatus . Other , "Not signed in" ) ;
196- if ( ! OperatingSystem . IsWindows ( ) && ! joinGroup . UseRelayServer )
197- return ( null , GroupCreationStatus . Other , "Only Windows platform supports direct connection" ) ;
217+ return new OpResult ( null , GroupCreationStatus . Other , ReadOnlyDictionary < string , string > . Empty , "Not signed in" ) ;
218+ // if (!OperatingSystem.IsWindows() && !joinGroup.UseRelayServer)
219+ // return (null, GroupCreationStatus.Other, "Only Windows platform supports direct connection");
198220
199221 return await PerformOpAndGetRoomInfoAsync ( joinGroup , ct ) ;
200222 }
0 commit comments