示例#1
0
        public override void SuggestInvitation(Google.ProtocolBuffers.IRpcController controller, bnet.protocol.channel_invitation.SuggestInvitationRequest request, Action <bnet.protocol.NoData> done)
        {
            var suggester = GameAccountManager.GetAccountByPersistentID(request.TargetId.Low);   //wants invite
            var suggestee = GameAccountManager.GetAccountByPersistentID(request.ApprovalId.Low); //approves invite

            if (suggestee == null)
            {
                return;
            }

            Logger.Debug("{0} suggested {1} to invite him.", suggester, suggestee);
            var respone = bnet.protocol.NoData.CreateBuilder();

            done(respone.Build());

            // Even though it makes no sense, the suggester is used for all fields in the caps and is what works with the client. /dustinconrad
            var suggestion = bnet.protocol.invitation.Suggestion.CreateBuilder()
                             .SetChannelId(request.ChannelId)
                             .SetSuggesterId(suggester.BnetEntityId)
                             .SetSuggesterName(suggester.Owner.BattleTag)
                             .SetSuggesteeId(suggester.BnetEntityId)
                             .SetSuggesteeName(suggester.Owner.BattleTag)
                             .Build();

            var notification = bnet.protocol.channel_invitation.SuggestionAddedNotification.CreateBuilder().SetSuggestion(suggestion);

            suggestee.LoggedInClient.MakeTargetedRPC(this._invitationManager, () =>
                                                     bnet.protocol.channel_invitation.ChannelInvitationNotify.CreateStub(suggestee.LoggedInClient).NotifyReceivedSuggestionAdded(null, notification.Build(), callback => { }));
        }
示例#2
0
        public override void SendReport(IRpcController controller, bnet.protocol.report.SendReportRequest request, Action <bnet.protocol.NoData> done)
        {
            Logger.Trace("SendReport()");

            var report = request.Report;

            //TODO: Store reports against accounts
            foreach (var attribute in report.AttributeList)
            {
                switch (attribute.Name)
                {
                case "target_toon_id":     //uint GameAccount.Low
                    var reportee = GameAccountManager.GetAccountByPersistentID(attribute.Value.UintValue);
                    Logger.Trace("{0} reported {1} for \"{2}\".", this.Client.Account.CurrentGameAccount.CurrentToon, reportee, report.ReportType);
                    break;
                    //case "target_account_id": //uint Account.Low
                    //case "target_toon_name": //string
                    //case "target_toon_program": //fourcc
                    //case "target_toon_region": //string
                    //case "note": //string - not currently used in client
                }
            }

            var builder = bnet.protocol.NoData.CreateBuilder();

            done(builder.Build());
        }
示例#3
0
        public override void Subscribe(Google.ProtocolBuffers.IRpcController controller, bnet.protocol.presence.SubscribeRequest request, System.Action <bnet.protocol.NoData> done)
        {
            switch (request.EntityId.GetHighIdType())
            {
            case EntityIdHelper.HighIdType.AccountId:
                var account = AccountManager.GetAccountByPersistentID(request.EntityId.Low);
                if (account != null)
                {
                    Logger.Trace("Subscribe() {0} {1}", this.Client, account);
                    account.AddSubscriber(this.Client, request.ObjectId);
                }
                break;

            case EntityIdHelper.HighIdType.GameAccountId:
                var gameaccount = GameAccountManager.GetAccountByPersistentID(request.EntityId.Low);
                if (gameaccount != null)
                {
                    Logger.Trace("Subscribe() {0} {1}", this.Client, gameaccount);
                    gameaccount.AddSubscriber(this.Client, request.ObjectId);
                }
                break;

            default:
                Logger.Warn("Recieved an unhandled Presence.Subscribe request with type {0} (0x{1})", request.EntityId.GetHighIdType(), request.EntityId.High.ToString("X16"));
                break;
            }

            var builder = bnet.protocol.NoData.CreateBuilder();

            done(builder.Build());
        }
示例#4
0
        public void Revoke(MooNetClient client, bnet.protocol.channel_invitation.RevokeInvitationRequest request)
        {
            if (!this._onGoingInvitations.ContainsKey(request.InvitationId))
            {
                return;
            }
            var invitation = this._onGoingInvitations[request.InvitationId];

            var channel = ChannelManager.GetChannelByEntityId(request.ChannelId);

            //notify inviter about revoke
            var updateChannelNotification =
                bnet.protocol.channel.UpdateChannelStateNotification.CreateBuilder()
                .SetAgentId(bnet.protocol.EntityId.CreateBuilder().SetHigh(0).SetLow(0)) // caps have this set to high: 0 low: 0 /dustin
                .SetStateChange(bnet.protocol.channel.ChannelState.CreateBuilder()
                                .AddInvitation(invitation)
                                .SetReason((uint)InvitationRemoveReason.Revoked));

            this._onGoingInvitations.Remove(request.InvitationId);

            client.MakeTargetedRPC(channel, () =>
                                   bnet.protocol.channel.ChannelSubscriber.CreateStub(client).NotifyUpdateChannelState(null, updateChannelNotification.Build(), callback => { }));

            //notify invitee about revoke
            var invitationRemoved =
                bnet.protocol.channel_invitation.InvitationRemovedNotification.CreateBuilder()
                .SetInvitation(invitation)
                .SetReason((uint)InvitationRemoveReason.Revoked);

            var invitee = GameAccountManager.GetAccountByPersistentID(invitation.InviteeIdentity.AccountId.Low);

            invitee.LoggedInClient.MakeTargetedRPC(this, () =>
                                                   bnet.protocol.channel_invitation.ChannelInvitationNotify.CreateStub(invitee.LoggedInClient).NotifyReceivedInvitationRemoved(null, invitationRemoved.Build(), callback => { }));
        }
示例#5
0
        public Channel HandleAccept(MooNetClient client, bnet.protocol.channel_invitation.AcceptInvitationRequest request)
        {
            if (!this._onGoingInvitations.ContainsKey(request.InvitationId))
            {
                return(null);
            }

            var invitation = this._onGoingInvitations[request.InvitationId];
            var channel    = ChannelManager.GetChannelByEntityId(invitation.GetExtension(bnet.protocol.channel_invitation.ChannelInvitation.ChannelInvitationProp).ChannelDescription.ChannelId);

            var notification = bnet.protocol.channel_invitation.InvitationRemovedNotification.CreateBuilder().SetInvitation(invitation.ToBuilder()).SetReason((uint)InvitationRemoveReason.Accepted);

            this._onGoingInvitations.Remove(invitation.Id);

            // notify invitee and let him remove the handled invitation.
            client.MakeTargetedRPC(this, () =>
                                   bnet.protocol.channel_invitation.ChannelInvitationNotify.CreateStub(client).NotifyReceivedInvitationRemoved(null, notification.Build(), callback => { }));

            channel.Join(client, request.ObjectId); // add invitee to channel -- so inviter and other members will also be notified too.

            var inviter = GameAccountManager.GetAccountByPersistentID(invitation.InviterIdentity.AccountId.Low);

            var stateNotification = bnet.protocol.channel.UpdateChannelStateNotification.CreateBuilder()
                                    .SetAgentId(bnet.protocol.EntityId.CreateBuilder().SetHigh(0).SetLow(0).Build())
                                    .SetStateChange(bnet.protocol.channel.ChannelState.CreateBuilder().AddRangeInvitation(channel.Invitations.Values).SetReason(0).Build())
                                    .Build();

            foreach (var member in channel.Members.Keys)
            {
                member.MakeTargetedRPC(channel, () =>
                                       bnet.protocol.channel.ChannelSubscriber.CreateStub(member).NotifyUpdateChannelState(null, stateNotification, callback => { }));
            }

            return(channel);
        }
示例#6
0
        public void HandleDecline(MooNetClient client, bnet.protocol.invitation.GenericRequest request)
        {
            if (!this._onGoingInvitations.ContainsKey(request.InvitationId))
            {
                return;
            }
            var invitation = this._onGoingInvitations[request.InvitationId];

            var inviter = GameAccountManager.GetAccountByPersistentID(invitation.InviterIdentity.AccountId.Low);

            if (inviter == null || inviter.LoggedInClient == null)
            {
                return;
            }

            var notification =
                bnet.protocol.channel.UpdateChannelStateNotification.CreateBuilder()
                .SetAgentId(bnet.protocol.EntityId.CreateBuilder().SetHigh(0).SetLow(0)) // caps have this set to high: 0 low: 0 /raist.
                .SetStateChange(bnet.protocol.channel.ChannelState.CreateBuilder().AddInvitation(invitation)
                                .SetReason((uint)InvitationRemoveReason.Declined));

            this._onGoingInvitations.Remove(invitation.Id);

            // notify invoker about the decline.
            inviter.LoggedInClient.MakeTargetedRPC(inviter.LoggedInClient.PartyChannel, () =>
                                                   bnet.protocol.channel.ChannelSubscriber.CreateStub(inviter.LoggedInClient).NotifyUpdateChannelState(null, notification.Build(), callback => { }));

            //inviter.LoggedInClient.MakeTargetedRPC(inviter.LoggedInClient.CurrentChannel, () =>
            //    bnet.protocol.channel.ChannelSubscriber.CreateStub(inviter.LoggedInClient).NotifyUpdateChannelState(null, notification.Build(), callback => { }));
        }
示例#7
0
        public override void Unsubscribe(Google.ProtocolBuffers.IRpcController controller, bnet.protocol.presence.UnsubscribeRequest request, System.Action <bnet.protocol.NoData> done)
        {
            switch (request.EntityId.GetHighIdType())
            {
            case EntityIdHelper.HighIdType.AccountId:
                var account = AccountManager.GetAccountByPersistentID(request.EntityId.Low);
                // The client will probably make sure it doesn't unsubscribe to a null ID, but just to make sure..
                if (account != null)
                {
                    account.RemoveSubscriber(this.Client);
                    Logger.Trace("Unsubscribe() {0} {1}", this.Client, account);
                }
                break;

            case EntityIdHelper.HighIdType.GameAccountId:
                var gameaccount = GameAccountManager.GetAccountByPersistentID(request.EntityId.Low);
                if (gameaccount != null)
                {
                    gameaccount.RemoveSubscriber(this.Client);
                    Logger.Trace("Unsubscribe() {0} {1}", this.Client, gameaccount);
                }
                break;

            default:
                Logger.Warn("Recieved an unhandled Presence.Unsubscribe request with type {0} (0x{1})", request.EntityId.GetHighIdType(), request.EntityId.High.ToString("X16"));
                break;
            }

            var builder = bnet.protocol.NoData.CreateBuilder();

            done(builder.Build());
        }
示例#8
0
        public override void Update(Google.ProtocolBuffers.IRpcController controller, bnet.protocol.presence.UpdateRequest request, System.Action <bnet.protocol.NoData> done)
        {
            //Logger.Warn("request:\n{0}", request.ToString());
            // This "UpdateRequest" is not, as it may seem, a request to update the client on the state of an object,
            // but instead the *client* requesting to change fields on an object that it has subscribed to.
            // Check docs/rpc/presence.txt in branch wip-docs (or master)

            switch (request.EntityId.GetHighIdType())
            {
            case EntityIdHelper.HighIdType.AccountId:
                var account = AccountManager.GetAccountByPersistentID(request.EntityId.Low);
                Logger.Trace("Update() {0} {1} - {2} Operations", this.Client, account, request.FieldOperationCount);
                Logger.Warn("No AccountManager updater.");
                break;

            case EntityIdHelper.HighIdType.GameAccountId:
                var gameaccount = GameAccountManager.GetAccountByPersistentID(request.EntityId.Low);
                var trace       = string.Format("Update() {0} {1} - {2} Operations", this.Client, gameaccount, request.FieldOperationCount);
                foreach (var fieldOp in request.FieldOperationList)
                {
                    trace += string.Format("\t{0}, {1}, {2}", (FieldKeyHelper.Program)fieldOp.Field.Key.Program, (FieldKeyHelper.OriginatingClass)fieldOp.Field.Key.Group, fieldOp.Field.Key.Field);
                    gameaccount.Update(fieldOp);
                }
                Logger.Trace(trace);
                break;

            default:
                Logger.Warn("Recieved an unhandled Presence.Update request with type {0} (0x{1})", request.EntityId.GetHighIdType(), request.EntityId.High.ToString("X16"));
                break;
            }

            var builder = bnet.protocol.NoData.CreateBuilder();

            done(builder.Build());
        }
示例#9
0
        private ByteString GetHeroProfiles(D3.GameMessage.GetHeroProfiles profiles)
        {
            Logger.Trace("GetHeroProfiles()");

            var profileList = D3.Profile.HeroProfileList.CreateBuilder();

            if (profiles.HeroIdsCount > 0)
            {
                foreach (var hero in profiles.HeroIdsList)
                {
                    var toon = ToonManager.GetToonByLowID(hero.IdLow);
                    profileList.AddHeros(toon.Profile);
                }
            }
            else
            {
                var heroList = GameAccountManager.GetAccountByPersistentID(profiles.AccountId.IdLow).Toons;
                foreach (var hero in heroList)
                {
                    profileList.AddHeros(hero.Profile);
                }
            }

            return(profileList.Build().ToByteString());
        }
示例#10
0
        private ByteString GetAccountProfile(D3.GameMessage.GetAccountProfile profile)
        {
            Logger.Trace("GetAccountProfile()");

            var account = GameAccountManager.GetAccountByPersistentID(profile.AccountId.IdLow);

            return(account.Profile.ToByteString());
        }
示例#11
0
        public override void SelectGameAccount(Google.ProtocolBuffers.IRpcController controller, bnet.protocol.EntityId request, Action <bnet.protocol.NoData> done)
        {
            this.Client.Account.CurrentGameAccount = GameAccountManager.GetAccountByPersistentID(request.Low);
            this.Client.Account.CurrentGameAccount.LoggedInClient = this.Client;

            Logger.Trace("SelectGameAccount(): {0}", this.Client.Account.CurrentGameAccount);

            done(bnet.protocol.NoData.CreateBuilder().Build());
        }
示例#12
0
        private ByteString GetGameAccountSettings(D3.GameMessage.GetGameAccountSettings settings)
        {
            Logger.Trace("GetGameAccountSettings()");

            var gameAccount = GameAccountManager.GetAccountByPersistentID(settings.AccountId.IdLow);

            return(gameAccount.Settings.ToByteString());
            //var pref = D3.Client.Preferences.CreateBuilder().SetVersion(105).Build(); //hack since client is expecting this atm -Egris
            //return pref.ToByteString();
        }
示例#13
0
        public override void RemoveMember(Google.ProtocolBuffers.IRpcController controller, bnet.protocol.channel.RemoveMemberRequest request, System.Action <bnet.protocol.NoData> done)
        {
            Logger.Trace("RemoveMember()");
            var channel     = ChannelManager.GetChannelByDynamicId(LastCallHeader.ObjectId);
            var gameAccount = GameAccountManager.GetAccountByPersistentID(request.MemberId.Low);

            var builder = bnet.protocol.NoData.CreateBuilder();

            done(builder.Build());

            channel.RemoveMember(gameAccount.LoggedInClient, Channel.GetRemoveReasonForRequest((Channel.RemoveRequestReason)request.Reason));
        }
示例#14
0
        private ByteString GetHeroList(D3.GameMessage.GetHeroIds heroIds)
        {
            Logger.Trace("GetHeroList()");

            var HeroList    = D3.Hero.HeroList.CreateBuilder();
            var gameAccount = GameAccountManager.GetAccountByPersistentID(heroIds.AccountId.IdLow);

            foreach (var toon in gameAccount.Toons.Values)
            {
                HeroList.AddHeroIds(toon.D3EntityID);
            }
            return(HeroList.Build().ToByteString());
        }
示例#15
0
        public override void SendNotification(Google.ProtocolBuffers.IRpcController controller, bnet.protocol.notification.Notification request, Action <bnet.protocol.NoData> done)
        {
            switch (request.GetNotificationType())
            {
            case NotificationTypeHelper.NotificationType.Whisper:

                // NOTE: Real implementation doesn't even handle the situation where neither client knows about the other.
                // Client requires prior knowledge of sender and target (and even then it cannot whisper by using the /whisper command).

                var targetAccount = GameAccountManager.GetAccountByPersistentID(request.TargetId.Low);
                Logger.Trace(string.Format("NotificationRequest.Whisper by {0} to {1}", this.Client.Account.CurrentGameAccount, targetAccount));

                if (targetAccount.LoggedInClient == null)
                {
                    return;
                }

                if (targetAccount == this.Client.Account.CurrentGameAccount)                          // check if whisper targets the account itself.
                {
                    CommandManager.TryParse(request.AttributeList[0].Value.StringValue, this.Client); // try parsing it as a command and respond it if so.
                }
                else
                {
                    var notification = bnet.protocol.notification.Notification.CreateBuilder(request)
                                       .SetSenderId(this.Client.Account.CurrentGameAccount.BnetEntityId)
                                       .SetSenderAccountId(this.Client.Account.BnetEntityId)
                                       .Build();

                    targetAccount.LoggedInClient.MakeRPC(() =>
                                                         bnet.protocol.notification.NotificationListener.CreateStub(targetAccount.LoggedInClient).OnNotificationReceived(controller, notification, callback => { }));
                }
                break;

            default:
                Logger.Warn("Unhandled notification type: {0}", request.Type);
                break;
            }

            var builder = bnet.protocol.NoData.CreateBuilder();

            done(builder.Build());
        }
示例#16
0
        public override void Query(Google.ProtocolBuffers.IRpcController controller, bnet.protocol.presence.QueryRequest request, Action <bnet.protocol.presence.QueryResponse> done)
        {
            var builder = bnet.protocol.presence.QueryResponse.CreateBuilder();

            switch (request.EntityId.GetHighIdType())
            {
            case EntityIdHelper.HighIdType.AccountId:
                var account = AccountManager.GetAccountByPersistentID(request.EntityId.Low);
                foreach (var key in request.KeyList)
                {
                    Logger.Trace("Query() {0} {1} - {2}, {3}, {4}", this.Client, account, (FieldKeyHelper.Program)key.Program, (FieldKeyHelper.OriginatingClass)key.Group, key.Field);
                    var field = account.QueryField(key);
                    if (field != null)
                    {
                        builder.AddField(field);
                    }
                }
                break;

            case EntityIdHelper.HighIdType.GameAccountId:
                var gameaccount = GameAccountManager.GetAccountByPersistentID(request.EntityId.Low);
                foreach (var key in request.KeyList)
                {
                    Logger.Trace("Query() {0} {1} - {2}, {3}, {4}", this.Client, gameaccount, (FieldKeyHelper.Program)key.Program, (FieldKeyHelper.OriginatingClass)key.Group, key.Field);
                    var field = gameaccount.QueryField(key);
                    if (field != null)
                    {
                        builder.AddField(field);
                    }
                }
                break;

            default:
                Logger.Warn("Recieved an unhandled Presence.Query request with type {0} (0x{1})", request.EntityId.GetHighIdType(), request.EntityId.High.ToString("X16"));
                break;
            }

            done(builder.Build());
        }
示例#17
0
文件: Toon.cs 项目: DZilli/mooege
 public Toon(ulong persistentId, string name, int hashCode, byte @class, byte gender, byte level, long accountId, uint timePlayed, int goldAmount, Dictionary <uint, Item> items) // Toon with given persistent ID
     : base(persistentId)
 {
     this.HeroClassField.transformDelegate += HeroClassFieldTransform;
     this.SetFields(name, hashCode, (int)@class, (ToonFlags)gender, level, GameAccountManager.GetAccountByPersistentID((ulong)accountId), timePlayed, goldAmount, items);
 }
示例#18
0
 public Toon(ulong persistentId, string name, int hashCode, byte @class, byte gender, byte level, long accountId, uint timePlayed) // Toon with given persistent ID
     : base(persistentId)
 {
     this.SetFields(name, hashCode, (ToonClass)@class, (ToonFlags)gender, level, GameAccountManager.GetAccountByPersistentID((ulong)accountId), timePlayed);
 }
示例#19
0
        public override void SendInvitation(Google.ProtocolBuffers.IRpcController controller, bnet.protocol.invitation.SendInvitationRequest request, Action <bnet.protocol.invitation.SendInvitationResponse> done)
        {
            var invitee = GameAccountManager.GetAccountByPersistentID(request.TargetId.Low);

            //if (this.Client.CurrentChannel.HasMember(invitee)) return; // don't allow a second invitation if invitee is already a member of client's current channel.

            Logger.Debug("{0} invited {1} to his channel.", Client.Account.CurrentGameAccount.CurrentToon, invitee);

            // somehow protobuf lib doesnt handle this extension, so we're using a workaround to get that channelinfo.
            var extensionBytes        = request.Params.UnknownFields.FieldDictionary[105].LengthDelimitedList[0].ToByteArray();
            var channelInvitationInfo = bnet.protocol.channel_invitation.ChannelInvitationParams.ParseFrom(extensionBytes);

            var channel            = ChannelManager.GetChannelByEntityId(channelInvitationInfo.ChannelId);
            var channelDescription = bnet.protocol.channel.ChannelDescription.CreateBuilder()
                                     .SetChannelId(channelInvitationInfo.ChannelId)
                                     .SetCurrentMembers((uint)channel.Members.Count)
                                     .SetState(channel.State);

            var channelInvitation = bnet.protocol.channel_invitation.ChannelInvitation.CreateBuilder()
                                    .SetChannelDescription(channelDescription)
                                    .SetReserved(channelInvitationInfo.Reserved)
                                    .SetServiceType(channelInvitationInfo.ServiceType)
                                    .SetRejoin(false).Build();

            var invitation = bnet.protocol.invitation.Invitation.CreateBuilder();

            invitation.SetId(ChannelInvitationManager.InvitationIdCounter++)
            .SetInviterIdentity(bnet.protocol.Identity.CreateBuilder().SetGameAccountId(Client.Account.CurrentGameAccount.BnetEntityId).Build())
            .SetInviterName(Client.Account.CurrentGameAccount.Owner.BattleTag)
            .SetInviteeIdentity(bnet.protocol.Identity.CreateBuilder().SetGameAccountId(request.TargetId).Build())
            .SetInviteeName(invitee.Owner.BattleTag)
            .SetInvitationMessage(request.Params.InvitationMessage)
            .SetCreationTime(DateTime.Now.ToExtendedEpoch())
            .SetExpirationTime(DateTime.Now.ToUnixTime() + request.Params.ExpirationTime)
            .SetExtension(bnet.protocol.channel_invitation.ChannelInvitation.ChannelInvitationProp, channelInvitation);

            // oh blizz, cmon. your buggy client even doesn't care this message at all but waits the UpdateChannelStateNotification with embedded invitation proto to show "invitation sent message".
            // ADVICE TO POTENTIAL BLIZZ-WORKER READING THIS;
            // change rpc SendInvitation(.bnet.protocol.invitation.SendInvitationRequest) returns (.bnet.protocol.invitation.SendInvitationResponse); to rpc SendInvitation(.bnet.protocol.invitation.SendInvitationRequest) returns (.bnet.protocol.NoData);

            var builder = bnet.protocol.invitation.SendInvitationResponse.CreateBuilder();

            channel.AddInvitation(invitation.Build());

            if (!channel.HasMember(invitee))
            {
                builder.SetInvitation(invitation.Clone()); // clone it because we need that invitation as un-builded below.
            }
            done(builder.Build());

            // send bnet.protocol.channel.UpdateChannelStateNotification to inviter - update him on invitation is sent.

            var notification = bnet.protocol.channel.UpdateChannelStateNotification.CreateBuilder()
                               .SetAgentId(Client.Account.CurrentGameAccount.BnetEntityId)
                               .SetStateChange(bnet.protocol.channel.ChannelState.CreateBuilder().AddInvitation(invitation.Clone()));

            this.Client.MakeTargetedRPC(channel, () =>
                                        bnet.protocol.channel.ChannelSubscriber.CreateStub(Client).NotifyUpdateChannelState(controller, notification.Build(), callback => { }));

            // notify the invitee on invitation.
            this._invitationManager.HandleInvitation(this.Client, invitation.Build());
        }