1
1
using Guncho . Connections ;
2
2
using System ;
3
+ using System . Linq ;
3
4
using System . Threading . Tasks ;
4
5
5
6
namespace Guncho
@@ -36,9 +37,7 @@ private async Task<HandleSystemCommandResult> HandleSystemCommandAsync(Connectio
36
37
if ( command . Length == 0 )
37
38
return result ;
38
39
39
- Player player ;
40
- using ( await conn . Lock . ReaderLockAsync ( ) )
41
- player = conn . Player ;
40
+ var player = conn . Player ;
42
41
43
42
// check commands that can be used any time
44
43
switch ( command )
@@ -53,7 +52,8 @@ private async Task<HandleSystemCommandResult> HandleSystemCommandAsync(Connectio
53
52
return result ;
54
53
}
55
54
56
- if ( player == null || player . Realm == null )
55
+ IInstance instance ;
56
+ if ( player == null || playerInstances . TryGetValue ( player , out instance ) == false )
57
57
{
58
58
// check out-of-realm commands
59
59
switch ( command )
@@ -119,18 +119,16 @@ private async Task<HandleSystemCommandResult> HandleSystemCommandAsync(Connectio
119
119
120
120
case "again" :
121
121
case "g" :
122
- using ( await player . Lock . ReaderLockAsync ( ) )
122
+ var lastCmd = player . LastCommand ;
123
+ if ( lastCmd == null )
123
124
{
124
- if ( player . LastCommand == null )
125
- {
126
- await conn . WriteLineAsync ( "No previous command to repeat." ) ;
127
- return result ;
128
- }
129
-
130
- result . Handled = false ;
131
- result . Line = player . LastCommand ;
125
+ await conn . WriteLineAsync ( "No previous command to repeat." ) ;
132
126
return result ;
133
127
}
128
+
129
+ result . Handled = false ;
130
+ result . Line = player . LastCommand ;
131
+ return result ;
134
132
}
135
133
136
134
// save command for 'again'
@@ -144,33 +142,34 @@ private async Task<HandleSystemCommandResult> HandleSystemCommandAsync(Connectio
144
142
145
143
private async Task LogInAsPlayerAsync ( Connection conn , Player player )
146
144
{
145
+ logger . LogMessage ( LogLevel . Spam , "Setting conn.Player" ) ;
146
+
147
+ var oldConns = openConnections . Keys . Where ( c => c . Player == player ) . ToArray ( ) ;
148
+
147
149
using ( await conn . Lock . WriterLockAsync ( ) )
148
150
conn . Player = player ;
149
151
150
- Connection oldConn ;
151
- using ( await player . Lock . ReaderLockAsync ( ) )
152
- oldConn = player . Connection ;
153
-
154
- if ( oldConn != null )
152
+ if ( oldConns . Length > 0 )
155
153
{
156
- Func < Task > notifyOldConn = async ( ) =>
157
- {
158
- await oldConn . WriteLineAsync ( "*** Connection superseded ***" ) ;
159
- await oldConn . TerminateAsync ( ) ;
160
- } ;
161
- Func < Task > notifyNewConn = async ( ) =>
154
+ await Task . WhenAll ( oldConns . Select ( async c =>
162
155
{
163
- await conn . WriteLineAsync ( "*** Connection resumed ***" ) ;
164
- await conn . FlushOutputAsync ( ) ;
165
- } ;
166
- await Task . WhenAll ( notifyOldConn ( ) , notifyNewConn ( ) ) ;
156
+ logger . LogMessage ( LogLevel . Spam , "notifyOldConn: Starting" ) ;
157
+ await c . WriteLineAsync ( "*** Connection superseded ***" ) ;
158
+ await c . TerminateAsync ( ) ;
159
+ logger . LogMessage ( LogLevel . Spam , "notifyOldConn: Done" ) ;
160
+ } ) ) ;
161
+
162
+ logger . LogMessage ( LogLevel . Spam , "notifyNewConn: Starting" ) ;
163
+ await conn . WriteLineAsync ( "*** Connection resumed ***" ) ;
164
+ await conn . FlushOutputAsync ( ) ;
165
+ logger . LogMessage ( LogLevel . Spam , "notifyNewConn: Done" ) ;
167
166
}
168
167
169
- using ( await player . Lock . WriterLockAsync ( ) )
170
- player . Connection = conn ;
171
-
168
+ logger . LogMessage ( LogLevel . Spam , "Sending MOTD" ) ;
172
169
await SendTextFileAsync ( conn , player . Name , Properties . Settings . Default . MotdFileName ) ;
170
+ logger . LogMessage ( LogLevel . Spam , "Entering instance" ) ;
173
171
await EnterInstanceAsync ( player , await GetDefaultInstanceAsync ( GetRealm ( Properties . Settings . Default . StartRealmName ) ) ) ;
172
+ logger . LogMessage ( LogLevel . Spam , "Login complete" ) ;
174
173
}
175
174
176
175
private async Task LogInAsGuestAsync ( Connection conn )
@@ -187,7 +186,6 @@ private async Task LogInAsGuestAsync(Connection conn)
187
186
} while ( ! players . TryAdd ( key , null ) ) ;
188
187
189
188
guest = new Player ( - guestNum , guestName , false , true ) ;
190
- guest . Connection = conn ;
191
189
players [ key ] = guest ;
192
190
playersById [ - guestNum ] = guest ;
193
191
@@ -241,40 +239,41 @@ private async Task CmdWallAsync(Connection conn, Player player, string args)
241
239
242
240
private async Task CmdTeleportAsync ( Connection conn , Player player , string args )
243
241
{
244
- Realm dest = GetRealm ( args ) ;
242
+ var dest = GetInstance ( args ) ;
245
243
246
244
if ( dest == null )
247
245
{
248
246
await conn . WriteLineAsync ( "No such realm." ) ;
249
247
return ;
250
248
}
251
249
252
- using ( await player . Lock . ReaderLockAsync ( ) )
250
+ IInstance inst ;
251
+
252
+ if ( playerInstances . TryGetValue ( player , out inst ) && inst == dest )
253
253
{
254
- if ( player . Realm == dest )
255
- {
256
- await conn . WriteLineAsync ( "You're already in that realm." ) ;
257
- return ;
258
- }
254
+ await conn . WriteLineAsync ( "You're already in that realm." ) ;
255
+ return ;
259
256
}
260
257
261
- if ( dest . GetAccessLevel ( player ) < RealmAccessLevel . Invited &&
258
+ var realm = dest . Realm ;
259
+
260
+ if ( realm . GetAccessLevel ( player ) < RealmAccessLevel . Invited &&
262
261
args . ToLower ( ) != Properties . Settings . Default . StartRealmName . ToLower ( ) )
263
262
{
264
263
await conn . WriteLineAsync ( "Permission denied." ) ;
265
264
return ;
266
265
}
267
266
268
- if ( dest . IsCondemned )
267
+ if ( realm . IsCondemned )
269
268
{
270
269
await conn . WriteLineAsync ( "That realm has been condemned." ) ;
271
270
return ;
272
271
}
273
272
274
- IInstance inst = await GetDefaultInstanceAsync ( dest ) ;
275
273
await inst . ActivateAsync ( ) ;
276
274
277
275
string check = await inst . SendAndGetAsync ( "$knock default" ) ;
276
+
278
277
switch ( check )
279
278
{
280
279
case "ok" :
@@ -315,38 +314,41 @@ private async Task CmdPageAsync(Connection conn, Player player, string args)
315
314
return ;
316
315
}
317
316
318
- if ( msg . StartsWith ( ":" ) )
317
+ if ( msg . StartsWith ( ":" , StringComparison . Ordinal ) )
319
318
{
320
319
msg = msg . Substring ( 1 ) ;
321
- using ( await targetPlayer . Lock . ReaderLockAsync ( ) )
320
+
321
+ var sendPage = WithPlayerConnectionsAsync ( targetPlayer , async c =>
322
322
{
323
- if ( targetPlayer . Connection != null )
324
- {
325
- await targetPlayer . Connection . WriteLineAsync ( player . Name + " (paging you) " + msg ) ;
326
- await targetPlayer . Connection . FlushOutputAsync ( ) ;
327
- await conn . WriteLineAsync ( "You page-posed " + targetPlayer . Name + ": " +
328
- player . Name + " " + msg ) ;
329
- }
330
- else
331
- {
332
- await conn . WriteLineAsync ( "That player is not connected." ) ;
333
- }
323
+ await c . WriteLineAsync ( player . Name + " (paging you) " + msg ) ;
324
+ await c . FlushOutputAsync ( ) ;
325
+ } ) ;
326
+
327
+ if ( await sendPage )
328
+ {
329
+ await conn . WriteLineAsync ( "You page-posed " + targetPlayer . Name + ": " +
330
+ player . Name + " " + msg ) ;
331
+ }
332
+ else
333
+ {
334
+ await conn . WriteLineAsync ( "That player is not connected." ) ;
334
335
}
335
336
}
336
337
else
337
338
{
338
- using ( await targetPlayer . Lock . ReaderLockAsync ( ) )
339
+ var sendPage = WithPlayerConnectionsAsync ( targetPlayer , async c =>
339
340
{
340
- if ( targetPlayer . Connection != null )
341
- {
342
- await targetPlayer . Connection . WriteLineAsync ( player . Name + " pages: " + msg ) ;
343
- await targetPlayer . Connection . FlushOutputAsync ( ) ;
344
- await conn . WriteLineAsync ( "You paged " + targetPlayer . Name + ": " + msg ) ;
345
- }
346
- else
347
- {
348
- await conn . WriteLineAsync ( "That player is not connected." ) ;
349
- }
341
+ await c . WriteLineAsync ( player . Name + " pages: " + msg ) ;
342
+ await c . FlushOutputAsync ( ) ;
343
+ } ) ;
344
+
345
+ if ( await sendPage )
346
+ {
347
+ await conn . WriteLineAsync ( "You paged " + targetPlayer . Name + ": " + msg ) ;
348
+ }
349
+ else
350
+ {
351
+ await conn . WriteLineAsync ( "That player is not connected." ) ;
350
352
}
351
353
}
352
354
}
0 commit comments