Пример #1
0
        public GameFactory(MooNetClient owner, bnet.protocol.game_master.FindGameRequest request, ulong requestId)
            : base(owner, true)
        {
            this.Started      = false;
            this.Owner        = owner; //Game is really the owner Channel.Owner should maybe be EntityId instead of MooNetClient -Egris
            this.RequestId    = requestId;
            this.FactoryID    = request.FactoryId;
            this.BnetEntityId = bnet.protocol.EntityId.CreateBuilder().SetHigh((ulong)EntityIdHelper.HighIdType.GameId).SetLow(this.DynamicId).Build();
            this.GameHandle   = bnet.protocol.game_master.GameHandle.CreateBuilder().SetFactoryId(this.FactoryID).SetGameId(this.BnetEntityId).Build();

            foreach (bnet.protocol.attribute.Attribute attribute in request.Properties.CreationAttributesList)
            {
                if (attribute.Name != "GameCreateParams")
                {
                    Logger.Warn("FindGame(): Unknown CreationAttribute: {0}", attribute.Name);
                }
                else
                {
                    this.GameCreateParams = D3.OnlineService.GameCreateParams.ParseFrom(attribute.Value.MessageValue);
                }
            }

            foreach (bnet.protocol.attribute.Attribute attribute in request.Properties.Filter.AttributeList)
            {
                if (attribute.Name != "version")
                {
                    Logger.Warn("FindGame(): Unknown Attribute: {0}", attribute.Name);
                }
                else
                {
                    this.Version = attribute.Value.StringValue;
                }
            }
        }
Пример #2
0
        public static GameFactory CreateGame(MooNetClient owner, bnet.protocol.game_master.FindGameRequest request, ulong requestId)
        {
            var gameFactory = new GameFactory(owner, request, requestId);

            GameCreators.Add(gameFactory.DynamicId, gameFactory);
            ChannelManager.AddGameChannel(gameFactory);
            return(gameFactory);
        }
Пример #3
0
        public override void FindGame(IRpcController controller, bnet.protocol.game_master.FindGameRequest request, Action <bnet.protocol.game_master.FindGameResponse> done)
        {
            Logger.Trace("FindGame() {0}", this.Client);

            // find the game.
            var gameFound = GameFactoryManager.FindGame(this.Client, request, ++GameFactoryManager.RequestIdCounter);

            //TODO: All these ChannelState updates can be moved to functions someplace else after packet flow is discovered and working -Egris
            //Send current JoinPermission to client before locking it
            var channelStatePermission = bnet.protocol.channel.ChannelState.CreateBuilder()
                                         .AddAttribute(bnet.protocol.attribute.Attribute.CreateBuilder()
                                                       .SetName("D3.Party.JoinPermissionPreviousToLock")
                                                       .SetValue(bnet.protocol.attribute.Variant.CreateBuilder().SetIntValue(1).Build())
                                                       .Build()).Build();

            var notificationPermission = bnet.protocol.channel.UpdateChannelStateNotification.CreateBuilder()
                                         .SetAgentId(this.Client.CurrentToon.BnetEntityID)
                                         .SetStateChange(channelStatePermission)
                                         .Build();

            this.Client.MakeTargetedRPC(Client.CurrentChannel, () =>
                                        bnet.protocol.channel.ChannelSubscriber.CreateStub(this.Client).NotifyUpdateChannelState(null, notificationPermission, callback => { }));

            var builder = bnet.protocol.game_master.FindGameResponse.CreateBuilder().SetRequestId(gameFound.RequestId);

            done(builder.Build());

            var clients = new List <MooNetClient>();

            foreach (var player in request.PlayerList)
            {
                var toon = ToonManager.GetToonByLowID(player.ToonId.Low);
                if (toon.Owner.LoggedInClient == null)
                {
                    continue;
                }
                clients.Add(toon.Owner.LoggedInClient);
            }

            // send game found notification.
            var notificationBuilder = bnet.protocol.game_master.GameFoundNotification.CreateBuilder()
                                      .SetRequestId(gameFound.RequestId)
                                      .SetGameHandle(gameFound.GameHandle);

            this.Client.MakeRPCWithListenerId(request.ObjectId, () =>
                                              bnet.protocol.game_master.GameFactorySubscriber.CreateStub(this.Client).NotifyGameFound(null, notificationBuilder.Build(), callback => { }));

            if (gameFound.Started)
            {
                Logger.Warn("Client {0} joining game with FactoryID:{1}", this.Client.CurrentToon.Name, gameFound.FactoryID);
                gameFound.JoinGame(clients, request.ObjectId);
            }
            else
            {
                Logger.Warn("Client {0} creating new game", this.Client.CurrentToon.Name);
                gameFound.StartGame(clients, request.ObjectId);
            }
        }
Пример #4
0
        public override void FindGame(IRpcController controller, bnet.protocol.game_master.FindGameRequest request, Action <bnet.protocol.game_master.FindGameResponse> done)
        {
            Logger.Trace("FindGame() {0}", this.Client);

            // find the game.
            var gameFound = GameFactoryManager.FindGame(this.Client, request, ++GameFactoryManager.RequestIdCounter);

            if (Client.CurrentChannel != null)
            {
                //TODO: All these ChannelState updates can be moved to functions someplace else after packet flow is discovered and working -Egris
                //Send current JoinPermission to client before locking it
                var channelStatePermission = bnet.protocol.channel.ChannelState.CreateBuilder()
                                             .AddAttribute(bnet.protocol.attribute.Attribute.CreateBuilder()
                                                           .SetName("D3.Party.JoinPermissionPreviousToLock")
                                                           .SetValue(bnet.protocol.attribute.Variant.CreateBuilder().SetIntValue(1).Build())
                                                           .Build()).Build();

                var notificationPermission = bnet.protocol.channel.UpdateChannelStateNotification.CreateBuilder()
                                             .SetAgentId(this.Client.Account.CurrentGameAccount.BnetEntityId)
                                             .SetStateChange(channelStatePermission)
                                             .Build();

                this.Client.MakeTargetedRPC(Client.CurrentChannel, () =>
                                            bnet.protocol.channel.ChannelSubscriber.CreateStub(this.Client).NotifyUpdateChannelState(null, notificationPermission, callback => { }));
            }

            var builder = bnet.protocol.game_master.FindGameResponse.CreateBuilder().SetRequestId(gameFound.RequestId);

            done(builder.Build());

            var clients = (from player in request.PlayerList select GameAccountManager.FindLoadedGameAccountByBnetId(player.Identity.GameAccountId.Low) into gameAccount where gameFound != null select gameAccount.LoggedInClient).ToList();

            // send game found notification.
            var notification = bnet.protocol.notification.Notification.CreateBuilder()
                               .SetSenderId(bnet.protocol.EntityId.CreateBuilder().SetHigh((ulong)EntityIdHelper.HighIdType.GameAccountId).SetLow(0).Build())
                               .SetTargetId(this.Client.Account.CurrentGameAccount.BnetEntityId)
                               .SetType("MM_START");
            var attr = bnet.protocol.attribute.Attribute.CreateBuilder()
                       .SetName("game_request_id")
                       .SetValue(bnet.protocol.attribute.Variant.CreateBuilder().SetUintValue(gameFound.RequestId).Build());

            notification.AddAttribute(attr);

            this.Client.MakeRPC(() =>
                                bnet.protocol.notification.NotificationListener.CreateStub(this.Client).OnNotificationReceived(null, notification.Build(), callback => { }));

            if (gameFound.Started)
            {
                Logger.Info("Client {0} joining game with FactoryID:{1}", this.Client.Account.CurrentGameAccount.CurrentToon.Name, gameFound.FactoryID);
                gameFound.JoinGame(clients, request.FactoryObjectId);
            }
            else
            {
                Logger.Info("Client {0} creating new game", this.Client.Account.CurrentGameAccount.CurrentToon.Name);
                gameFound.StartGame(clients, request.FactoryObjectId);
            }
        }
Пример #5
0
        private static List <GameFactory> FindMatchingGames(bnet.protocol.game_master.FindGameRequest request)
        {
            String version      = String.Empty;
            int    difficulty   = 0;
            int    currentQuest = 0;

            foreach (bnet.protocol.attribute.Attribute attribute in request.Properties.Filter.AttributeList)
            {
                switch (attribute.Name)
                {
                case "version":
                    version = attribute.Value.StringValue;
                    break;

                case "Game.Difficulty":
                    difficulty = (int)attribute.Value.IntValue;
                    break;

                case "Game.CurrentQuest":
                    currentQuest = (int)attribute.Value.IntValue;
                    break;
                }
            }

            Func <bool, bool, bool, bool> matchOp;

            switch (request.Properties.Filter.Op)
            {
            case bnet.protocol.attribute.AttributeFilter.Types.Operation.MATCH_ANY:
                matchOp = (bool b1, bool b2, bool b3) => b1 || b2 || b3;
                break;

            case bnet.protocol.attribute.AttributeFilter.Types.Operation.MATCH_NONE:
                matchOp = (bool b1, bool b2, bool b3) => !b1 && !b2 && !b3;
                break;

            case bnet.protocol.attribute.AttributeFilter.Types.Operation.MATCH_ALL:
            default:     //default to match all, fall through is on purpose
                matchOp = (bool b1, bool b2, bool b3) => b1 && b2 && b3;
                break;
            }

            List <GameFactory> matches = new List <GameFactory>();

            foreach (GameFactory game in GameCreators.Values)
            {
                //FIXME: don't currently track max players allowed in a game, hardcoded 4 /dustinconrad
                if (game.InGame != null && !game.GameCreateParams.IsPrivate && game.InGame.Players.Count < 4)
                {
                    if (matchOp(version == game.Version, difficulty == game.GameCreateParams.Coop.DifficultyLevel, currentQuest == game.GameCreateParams.Coop.SnoQuest))
                    {
                        matches.Add(game);
                    }
                }
            }
            return(matches);
        }
Пример #6
0
        public static GameFactory FindGame(MooNetClient client, bnet.protocol.game_master.FindGameRequest request, ulong requestId)
        {
            List <GameFactory> matchingGames = FindMatchingGames(request);
            var         rand        = new Random();
            GameFactory gameFactory = null;

            if (!request.Properties.Create && matchingGames.Count > 0)
            {
                gameFactory = matchingGames[rand.Next(matchingGames.Count)];
            }
            else
            {
                gameFactory = CreateGame(client, request, requestId);
            }

            return(gameFactory);
        }