Skip to content

Commit 512bdcb

Browse files
committed
create safe fetch on player
1 parent 24e60f9 commit 512bdcb

File tree

2 files changed

+70
-135
lines changed

2 files changed

+70
-135
lines changed

Intersect.Server.Core/Entities/Player.Database.cs

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,42 +39,45 @@ public partial class Player
3939

4040
#region Lookup
4141

42-
public static bool TryFetch(LookupKey lookupKey, [NotNullWhen(true)] out Tuple<Client, Player>? tuple)
42+
public static bool TryFetch(LookupKey lookupKey, [NotNullWhen(true)] out Client? client)
4343
{
44-
tuple = Fetch(lookupKey);
45-
return tuple.Item1 != default || tuple.Item2 != default;
44+
return TryFetch(lookupKey, out client, out _);
4645
}
4746

48-
public static Tuple<Client, Player> Fetch(LookupKey lookupKey, bool loadRelationships = false,
49-
bool loadBags = false)
47+
public static bool TryFetch(
48+
LookupKey lookupKey,
49+
[NotNullWhen(true)] out Client? client,
50+
out Player? player,
51+
bool loadRelationships = false,
52+
bool loadBags = false
53+
)
5054
{
51-
if (lookupKey is { HasName: false, HasId: false })
55+
if (lookupKey.IsInvalid)
5256
{
53-
return new Tuple<Client, Player>(null, null);
57+
client = default;
58+
player = default;
59+
return false;
5460
}
5561

5662
// HasName checks if null or empty
5763
// ReSharper disable once AssignNullToNotNullAttribute
5864
return lookupKey.HasId
59-
? Fetch(lookupKey.Id)
60-
: Fetch(lookupKey.Name, loadRelationships: loadRelationships, loadBags: loadBags);
65+
? Fetch(lookupKey.Id, out client, out player)
66+
: Fetch(lookupKey.Name, out client, out player, loadRelationships: loadRelationships, loadBags: loadBags);
6167
}
6268

63-
public static Tuple<Client, Player> Fetch(string playerName, bool loadRelationships = false, bool loadBags = false)
69+
private static bool Fetch(string playerName, [NotNullWhen(true)] out Client? client, out Player? player, bool loadRelationships = false, bool loadBags = false)
6470
{
65-
var client = Globals.Clients.Find(queryClient => Entity.CompareName(playerName, queryClient?.Entity?.Name));
66-
67-
return new Tuple<Client, Player>(
68-
client,
69-
client?.Entity ?? Find(playerName, loadRelationships: loadRelationships, loadBags: loadBags)
70-
);
71+
client = Globals.Clients.Find(queryClient => CompareName(playerName, queryClient?.Entity?.Name));
72+
player = client?.Entity ?? Find(playerName, loadRelationships: loadRelationships, loadBags: loadBags);
73+
return player != default;
7174
}
7275

73-
public static Tuple<Client, Player> Fetch(Guid playerId)
76+
private static bool Fetch(Guid playerId, [NotNullWhen(true)] out Client? client, out Player? player)
7477
{
75-
var client = Globals.Clients.Find(queryClient => playerId == queryClient?.Entity?.Id);
76-
77-
return new Tuple<Client, Player>(client, client?.Entity ?? Player.Find(playerId));
78+
client = Globals.Clients.Find(queryClient => playerId == queryClient?.Entity?.Id);
79+
player = client?.Entity ?? Find(playerId);
80+
return player != default;
7881
}
7982

8083
public static Player Find(Guid playerId)

Intersect.Server/Web/RestApi/Routes/V1/PlayerController.cs

Lines changed: 47 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -171,13 +171,12 @@ public IActionResult LookupPlayer(LookupKey lookupKey)
171171
return BadRequest(lookupKey.IsIdInvalid ? @"Invalid player id." : @"Invalid player name.");
172172
}
173173

174-
var (_, player) = Player.Fetch(lookupKey, loadRelationships: true, loadBags: true);
175-
if (player != null)
174+
if (!Player.TryFetch(lookupKey, out var _, out var player, loadRelationships: true, loadBags: true))
176175
{
177-
return Ok(player);
176+
return NotFound($@"No player found for lookup key '{lookupKey}'");
178177
}
179178

180-
return NotFound(lookupKey.HasId ? $@"No player with id '{lookupKey.Id}'." : $@"No player with name '{lookupKey.Name}'.");
179+
return Ok(player);
181180
}
182181

183182
[HttpDelete("{lookupKey:LookupKey}")]
@@ -192,10 +191,9 @@ public IActionResult DeletePlayer(LookupKey lookupKey)
192191
return BadRequest(lookupKey.IsIdInvalid ? @"Invalid player id." : @"Invalid player name.");
193192
}
194193

195-
var (client, player) = Player.Fetch(lookupKey);
196-
if (player == null)
194+
if (!Player.TryFetch(lookupKey, out var client, out var player))
197195
{
198-
return NotFound(lookupKey.HasId ? $@"No player with id '{lookupKey.Id}'." : $@"No player with name '{lookupKey.Name}'.");
196+
return NotFound($@"No player found for lookup key '{lookupKey}'");
199197
}
200198

201199
if (Player.FindOnline(player.Id) != null)
@@ -239,10 +237,9 @@ public IActionResult ChangeName(LookupKey lookupKey, [FromBody] NameChangePayloa
239237
return BadRequest($@"Name already taken.");
240238
}
241239

242-
var (_, player) = Player.Fetch(lookupKey);
243-
if (player == null)
240+
if (!Player.TryFetch(lookupKey, out var _, out var player))
244241
{
245-
return NotFound(lookupKey.HasId ? $@"No player with id '{lookupKey.Id}'." : $@"No player with name '{lookupKey.Name}'.");
242+
return NotFound($@"No player found for lookup key '{lookupKey}'");
246243
}
247244

248245
player.Name = change.Name;
@@ -280,10 +277,9 @@ public IActionResult PlayerClassSet(LookupKey lookupKey, [FromBody] ClassChange
280277
return BadRequest($@"Invalid class id {change.ClassId}.");
281278
}
282279

283-
var (_, player) = Player.Fetch(lookupKey);
284-
if (player == default)
280+
if (!Player.TryFetch(lookupKey, out var _, out var player))
285281
{
286-
return NotFound(lookupKey.HasId ? $@"No player with id '{lookupKey.Id}'." : $@"No player with name '{lookupKey.Name}'.");
282+
return NotFound($@"No player found for lookup key '{lookupKey}'");
287283
}
288284

289285
player.ClassId = change.ClassId;
@@ -314,10 +310,9 @@ public IActionResult PlayerLevelSet(LookupKey lookupKey, [FromBody] LevelChange
314310
return BadRequest(lookupKey.IsIdInvalid ? @"Invalid player id." : @"Invalid player name.");
315311
}
316312

317-
var (_, player) = Player.Fetch(lookupKey);
318-
if (player == default)
313+
if (!Player.TryFetch(lookupKey, out var _, out var player))
319314
{
320-
return NotFound(lookupKey.HasId ? $@"No player with id '{lookupKey.Id}'." : $@"No player with name '{lookupKey.Name}'.");
315+
return NotFound($@"No player found for lookup key '{lookupKey}'");
321316
}
322317

323318
player.SetLevel(change.Level, true);
@@ -344,14 +339,9 @@ public IActionResult PlayerLevelSet(LookupKey lookupKey, [FromBody] LevelChange
344339
[ProducesResponseType(typeof(ItemListResponse), (int)HttpStatusCode.OK, ContentTypes.Json)]
345340
public IActionResult ItemsList(LookupKey lookupKey)
346341
{
347-
var (_, player) = Player.Fetch(lookupKey);
348-
if (player == null)
342+
if (!Player.TryFetch(lookupKey, out var _, out var player))
349343
{
350-
return NotFound(
351-
lookupKey.HasId
352-
? $@"No player with id '{lookupKey.Id}'."
353-
: $@"No player with name '{lookupKey.Name}'."
354-
);
344+
return NotFound($@"No player found for lookup key '{lookupKey}'");
355345
}
356346

357347
return Ok(new ItemListResponse(player.Bank.Where(slot => !slot.IsEmpty), player.Items.Where(slot => !slot.IsEmpty)));
@@ -368,14 +358,9 @@ public IActionResult ItemsListBank(LookupKey lookupKey)
368358
return BadRequest(lookupKey.IsIdInvalid ? @"Invalid player id." : @"Invalid player name.");
369359
}
370360

371-
var (_, player) = Player.Fetch(lookupKey);
372-
if (player == null)
361+
if (!Player.TryFetch(lookupKey, out var _, out var player))
373362
{
374-
return NotFound(
375-
lookupKey.HasId
376-
? $@"No player with id '{lookupKey.Id}'."
377-
: $@"No player with name '{lookupKey.Name}'."
378-
);
363+
return NotFound($@"No player found for lookup key '{lookupKey}'");
379364
}
380365

381366
return Ok(player.Bank.Where(slot => !slot.IsEmpty));
@@ -411,14 +396,9 @@ public IActionResult ItemsListInventory(LookupKey lookupKey)
411396
return BadRequest(lookupKey.IsIdInvalid ? @"Invalid player id." : @"Invalid player name.");
412397
}
413398

414-
var (_, player) = Player.Fetch(lookupKey);
415-
if (player == null)
399+
if (!Player.TryFetch(lookupKey, out var _, out var player))
416400
{
417-
return NotFound(
418-
lookupKey.HasId
419-
? $@"No player with id '{lookupKey.Id}'."
420-
: $@"No player with name '{lookupKey.Name}'."
421-
);
401+
return NotFound($@"No player found for lookup key '{lookupKey}'");
422402
}
423403

424404
return Ok(player.Items.Where(slot => !slot.IsEmpty));
@@ -446,14 +426,9 @@ public IActionResult ItemsGive(LookupKey lookupKey, [FromBody] ItemInfo itemInfo
446426
return BadRequest("Cannot give 0, or a negative amount of an item.");
447427
}
448428

449-
var (_, player) = Player.Fetch(lookupKey);
450-
if (player == null)
429+
if (!Player.TryFetch(lookupKey, out var _, out var player))
451430
{
452-
return NotFound(
453-
lookupKey.HasId
454-
? $@"No player with id '{lookupKey.Id}'."
455-
: $@"No player with name '{lookupKey.Name}'."
456-
);
431+
return NotFound($@"No player found for lookup key '{lookupKey}'");
457432
}
458433

459434
if (!player.TryGiveItem(itemInfo.ItemId, itemInfo.Quantity, ItemHandling.Normal, itemInfo.BankOverflow, -1, true))
@@ -495,14 +470,9 @@ public IActionResult ItemsTake(LookupKey lookupKey, [FromBody] ItemInfo itemInfo
495470
return BadRequest("Cannot take 0, or a negative amount of an item.");
496471
}
497472

498-
var (_, player) = Player.Fetch(lookupKey);
499-
if (player == null)
473+
if (!Player.TryFetch(lookupKey, out var _, out var player))
500474
{
501-
return NotFound(
502-
lookupKey.HasId
503-
? $@"No player with id '{lookupKey.Id}'."
504-
: $@"No player with name '{lookupKey.Name}'."
505-
);
475+
return NotFound($@"No player found for lookup key '{lookupKey}'");
506476
}
507477

508478
if (!player.TryTakeItem(itemInfo.ItemId, itemInfo.Quantity))
@@ -534,14 +504,9 @@ public IActionResult SpellsList(LookupKey lookupKey)
534504
return BadRequest(lookupKey.IsIdInvalid ? @"Invalid player id." : @"Invalid player name.");
535505
}
536506

537-
var (_, player) = Player.Fetch(lookupKey);
538-
if (player == null)
507+
if (!Player.TryFetch(lookupKey, out var _, out var player))
539508
{
540-
return NotFound(
541-
lookupKey.HasId
542-
? $@"No player with id '{lookupKey.Id}'."
543-
: $@"No player with name '{lookupKey.Name}'."
544-
);
509+
return NotFound($@"No player found for lookup key '{lookupKey}'");
545510
}
546511

547512
return Ok(player.Spells.Where(s => !s.IsEmpty));
@@ -564,14 +529,9 @@ public IActionResult SpellsTeach(LookupKey lookupKey, [FromBody] SpellInfo spell
564529
return BadRequest(@"Invalid spell id.");
565530
}
566531

567-
var (_, player) = Player.Fetch(lookupKey);
568-
if (player == null)
532+
if (!Player.TryFetch(lookupKey, out var _, out var player))
569533
{
570-
return NotFound(
571-
lookupKey.HasId
572-
? $@"No player with id '{lookupKey.Id}'."
573-
: $@"No player with name '{lookupKey.Name}'."
574-
);
534+
return NotFound($@"No player found for lookup key '{lookupKey}'");
575535
}
576536

577537
if (!player.TryTeachSpell(new Spell(spell.SpellId), true))
@@ -605,14 +565,9 @@ public IActionResult SpellsTake(LookupKey lookupKey, [FromBody] SpellInfo spell)
605565
return BadRequest(@"Invalid spell id.");
606566
}
607567

608-
var (_, player) = Player.Fetch(lookupKey);
609-
if (player == null)
568+
if (!Player.TryFetch(lookupKey, out var _, out var player))
610569
{
611-
return NotFound(
612-
lookupKey.HasId
613-
? $@"No player with id '{lookupKey.Id}'."
614-
: $@"No player with name '{lookupKey.Name}'."
615-
);
570+
return NotFound($@"No player found for lookup key '{lookupKey}'");
616571
}
617572

618573
if (!player.TryForgetSpell(new Spell(spell.SpellId), true))
@@ -644,16 +599,11 @@ public IActionResult PlayerVariablesList(LookupKey lookupKey)
644599
return BadRequest(lookupKey.IsIdInvalid ? @"Invalid id." : @"Invalid name.");
645600
}
646601

647-
if (!Player.TryFetch(lookupKey, out var fetchResult))
602+
if (!Player.TryFetch(lookupKey, out var _, out var player))
648603
{
649-
return NotFound(
650-
lookupKey.HasId
651-
? $@"No player with id '{lookupKey.Id}'."
652-
: $@"No player with name '{lookupKey.Name}'."
653-
);
604+
return NotFound($@"No player found for lookup key '{lookupKey}'");
654605
}
655606

656-
var (_, player) = fetchResult;
657607
return Ok(player.Variables);
658608
}
659609

@@ -668,17 +618,11 @@ public IActionResult PlayerVariableGet(LookupKey lookupKey, Guid variableId)
668618
return BadRequest(lookupKey.IsIdInvalid ? @"Invalid id." : @"Invalid name.");
669619
}
670620

671-
if (!Player.TryFetch(lookupKey, out var fetchResult))
621+
if (!Player.TryFetch(lookupKey, out var _, out var player))
672622
{
673-
return NotFound(
674-
lookupKey.HasId
675-
? $@"No player with id '{lookupKey.Id}'."
676-
: $@"No player with name '{lookupKey.Name}'."
677-
);
623+
return NotFound($@"No player found for lookup key '{lookupKey}'");
678624
}
679625

680-
var (_, player) = fetchResult;
681-
682626
if (!PlayerVariableBase.TryGet(variableId, out var variableDescriptor))
683627
{
684628
return NotFound($@"Variable not found for id {variableId}");
@@ -699,17 +643,11 @@ public IActionResult PlayerVariableValueGet(LookupKey lookupKey, Guid variableId
699643
return BadRequest(lookupKey.IsIdInvalid ? @"Invalid id." : @"Invalid name.");
700644
}
701645

702-
if (!Player.TryFetch(lookupKey, out var fetchResult))
646+
if (!Player.TryFetch(lookupKey, out var _, out var player))
703647
{
704-
return NotFound(
705-
lookupKey.HasId
706-
? $@"No player with id '{lookupKey.Id}'."
707-
: $@"No player with name '{lookupKey.Name}'."
708-
);
648+
return NotFound($@"No player found for lookup key '{lookupKey}'");
709649
}
710650

711-
var (_, player) = fetchResult;
712-
713651
if (!PlayerVariableBase.TryGet(variableId, out var variableDescriptor))
714652
{
715653
return NotFound($@"Variable not found for id {variableId}");
@@ -733,17 +671,11 @@ public IActionResult PlayerVariableSet(LookupKey lookupKey, Guid variableId, [Fr
733671
return BadRequest(lookupKey.IsIdInvalid ? @"Invalid id." : @"Invalid name.");
734672
}
735673

736-
if (!Player.TryFetch(lookupKey, out var fetchResult))
674+
if (!Player.TryFetch(lookupKey, out var _, out var player))
737675
{
738-
return NotFound(
739-
lookupKey.HasId
740-
? $@"No player with id '{lookupKey.Id}'."
741-
: $@"No player with name '{lookupKey.Name}'."
742-
);
676+
return NotFound($@"No player found for lookup key '{lookupKey}'");
743677
}
744678

745-
var (_, player) = fetchResult;
746-
747679
if (!PlayerVariableBase.TryGet(variableId, out var variableDescriptor))
748680
{
749681
return NotFound($@"Variable not found for id {variableId}");
@@ -794,29 +726,29 @@ [FromBody] AdminActionParameters actionParameters
794726
return BadRequest(lookupKey.IsIdInvalid ? @"Invalid id." : @"Invalid name.");
795727
}
796728

797-
Tuple<Client, Player> fetchResult;
798-
fetchResult = Player.Fetch(lookupKey);
729+
if (!Player.TryFetch(lookupKey, out var client, out var player))
730+
{
731+
return NotFound($@"No player found for lookup key '{lookupKey}'");
732+
}
799733

800734
return DoAdminActionOnPlayer(
801-
() => fetchResult,
802-
() => NotFound(
803-
lookupKey.HasId
804-
? $@"No player with id '{lookupKey.Id}'."
805-
: $@"No player with name '{lookupKey.Name}'."
806-
), adminAction, actionParameters
735+
client,
736+
player,
737+
() => NotFound($@"No player found for lookup key '{lookupKey}'"),
738+
adminAction,
739+
actionParameters
807740
);
808741
}
809742

810743
private IActionResult DoAdminActionOnPlayer(
811-
Func<Tuple<Client, Player>> fetch,
744+
Client client,
745+
Player player,
812746
Func<IActionResult> onError,
813747
AdminAction adminAction,
814748
AdminActionParameters actionParameters
815749
)
816750
{
817-
var (client, player) = fetch();
818-
819-
if (player == null)
751+
if (player == default)
820752
{
821753
return onError();
822754
}

0 commit comments

Comments
 (0)