Esempio n. 1
0
        public ValueTask HandleAsync(ConnectedClient sender, VoteToStartRopeWar message, CancellationToken cancellationToken)
        {
            var location = _locationStore.FindLocationForClient(sender);

            location.VoteToStartRopeWar(sender.ClientId);

            _locationStore.Save(location);
            return(default);
Esempio n. 2
0
        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);
Esempio n. 3
0
        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);
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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);