public ValueTask HandleAsync(ConnectedClient sender, VoteToStartRopeWar message, CancellationToken cancellationToken) { var location = _locationStore.FindLocationForClient(sender); location.VoteToStartRopeWar(sender.ClientId); _locationStore.Save(location); return(default);
public ValueTask HandleAsync(Connect connect, CancellationToken cancellationToken) { var location = _locationStore.FindLocationForCharacter(connect.ClientId); if (location == null) { location = _locationStore.FindStartingLocation(); // First time joining the World. location.Characters.Add(connect.ClientId); _locationStore.Save(location); } connect.Group = location.LocationId; return(default);
public ValueTask HandleAsync(ConnectedClient sender, MoveToLocation message, CancellationToken cancellationToken) { var characterId = sender.ClientId; var location = _locationStore.FindLocationForCharacter(characterId); if (location == null) { // Character has never connected yet. throw new InvalidOperationException("Cannot move between locations. Did not join the world yet."); } // Consider using sender.Group to get current location. if (sender.Group != location.LocationId) { throw new InvalidOperationException("Current group of player is not equal to location. Synchronization mismatch."); } if (!location.Locations.Contains(message.LocationId)) { throw new InvalidOperationException("Cannot move to this location from another location."); } var newLocation = _locationStore.Find(message.LocationId); if (newLocation == null) { throw new InvalidOperationException("Location does not exist."); } // TODO: Transaction? location.Characters.Remove(characterId); _locationStore.Save(location); newLocation.Characters.Add(characterId); _locationStore.Save(newLocation); sender.Group = newLocation.LocationId; return(default);
public async ValueTask HandleAsync(ConnectedClient sender, ProposeRopeWarContest message, CancellationToken cancellationToken) { // TODO: Subtract "bet" from character money. var characterId = sender.ClientId; // TODO: Consider just using Group property to get location. var location = _locationStore.FindLocationForCharacter(sender.ClientId); if (location == null) { throw new InvalidOperationException("Location does not exist."); } if (location.LocationId != sender.Group) { throw new InvalidOperationException("Synchronization mismatch."); } if (!location.CanProposeRopeWar) { throw new InvalidOperationException("Cannot propose ropewar here."); } var activityId = Guid.NewGuid().ToString(); // TODO: Maybe consider storing this info in WORLD domain (ALL CHARACTER INFO) for quick and easy access. // Or create a separate domain with faster access than profile API. await _charactersClient.EnterActivityAsync(characterId, activityId, cancellationToken) .ConfigureAwait(false); location.RopeWars.Add(new RopeWar { ActivityId = activityId, Bet = message.Bet, Name = message.Name, CreatorId = characterId, LeftSideParticipants = message.Side == RopeWarSide.Left ? new List <string> { characterId } : new List <string>(), RightSideParticipants = message.Side == RopeWarSide.Right ? new List <string> { characterId } : new List <string>() }); _locationStore.Save(location); }
public ValueTask HandleAsync(ConnectedClient sender, JoinRopeWarContest message, CancellationToken cancellationToken) { var location = _locationStore.FindLocationForCharacter(sender.ClientId); if (location == null) { throw new InvalidOperationException("Location does not exist."); } if (location.LocationId != sender.Group) { throw new InvalidOperationException("Synchronization mismatch."); } var ropeWar = location.RopeWars.Find(rw => rw.ActivityId == message.RopeWarId); if (ropeWar == null) { throw new InvalidOperationException("RopeWar with this identity is not proposed yet."); } if (ropeWar.LeftSideParticipants.Contains(sender.ClientId) || ropeWar.RightSideParticipants.Contains(sender.ClientId)) { throw new InvalidOperationException("You are already joined to this contest."); } switch (message.Side) { case RopeWarSide.Left: ropeWar.LeftSideParticipants.Add(sender.ClientId); break; case RopeWarSide.Right: ropeWar.RightSideParticipants.Add(sender.ClientId); break; default: throw new InvalidOperationException("Unknown rope war side."); } _locationStore.Save(location); return(default);