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; } } }
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); }
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); } }
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); } }
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); }
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); }