public string ClientServices(string[] @params, MooNetClient invokerClient) { var client = invokerClient; if (client == null && @params.Count() < 1) return "Invalid arguments. Type 'help services client' to get help."; var output = ""; if (client == null) { var email = @params[0]; var account = AccountManager.GetAccountByEmail(email); if (account == null) return string.Format("No account with email '{0}' exists.", email); if (!account.IsOnline) return string.Format("Account '{0}' is not logged in.", email); var gameAccounts = GameAccountManager.GetGameAccountsForAccount(account); foreach (var gameAccount in gameAccounts) { output += this.ClientServices(null, gameAccount.LoggedInClient); } } else { output = string.Format("Imported service list for account: {0}\n", client.Account.Email); output = client.Services.Aggregate(output, (current, pair) => current + string.Format("Id: 0x{0} Hash: 0x{1}\n", pair.Value.ToString("X2"), pair.Key.ToString("X8"))); } return output; }
public void ParseCommand(bnet.protocol.notification.Notification request, MooNetClient client) { if (request.Type != "WHISPER") return; if (request.AttributeCount <= 0 || !request.AttributeList[0].HasValue) return; CommandManager.TryParse(request.AttributeList[0].Value.StringValue, client, CommandManager.RespondOver.Whisper); }
private static readonly byte[] ModuleHash = "8F52906A2C85B416A595702251570F96D3522F39237603115F2F1AB24962043C".ToByteArray(); // Password.dll public static void StartAuthentication(MooNetClient client, bnet.protocol.authentication.LogonRequest request) { if (Config.Instance.BypassAuthentication) BypassAuthentication(client, request); else InitAuthentication(client, request); }
public string HashNormal(string[] @params, MooNetClient invokerClient) { if (@params.Count() < 1) return "Invalid arguments. Type 'help hash show' to get help."; return StringHashHelper.HashNormal(@params[0]).ToString(); }
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; }
public string Show(string[] @params, MooNetClient invokerClient) { if (@params.Count() < 1) return "Invalid arguments. Type 'help rpcobject show' to get help."; ulong localId; var id = @params[0]; if (!ulong.TryParse(id, out localId)) return string.Format("Can not parse '{0}' as valid id.", id); if(!RPCObjectManager.Objects.ContainsKey(localId)) return string.Format("There exists no RPCObject with dynamidId: {0}", localId); var rpcObject = RPCObjectManager.Objects[localId]; var output = string.Format("[RPCObject]\nDynamicId: 0x{0}\nType: {1}\nObject: {2}\n", rpcObject.DynamicId, rpcObject.GetType().Name, rpcObject); output += "[Subscribers]\n"; foreach(var client in rpcObject.Subscribers) { var remoteId = client.GetRemoteObjectID(rpcObject.DynamicId); output += string.Format("RemoteId: 0x{0} - {1}\n", remoteId.ToString("X8"), client.Account.Email); } return output; }
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; } }
private static void BypassAuthentication(MooNetClient client, bnet.protocol.authentication.LogonRequest request) { client.Account = AccountManager.GetAccountByEmail(request.Email) ?? AccountManager.CreateAccount(request.Email, request.Email); client.Account.LoggedInClient = client; client.AuthenticationCompleteSignal.Set(); // signal about completion of authentication processes so we can return the response for AuthenticationService:LogonRequest. }
public string Portal(string[] @params, MooNetClient invokerClient) { if (invokerClient == null) return "You can not invoke this command from console."; if (invokerClient.InGameClient == null) return "You can only invoke this command while ingame."; if (@params != null && @params.Count() > 0) { var worldId = 0; Int32.TryParse(@params[0], out worldId); if (worldId == 0) return "Invalid arguments. Type 'help tp' to get help."; if (!MPQStorage.Data.Assets[SNOGroup.Worlds].ContainsKey(worldId)) return "There exist no world with SNOId: " + worldId; var world = invokerClient.InGameClient.Game.GetWorld(worldId); if (world == null) return "Can't teleport you to world with snoId " + worldId; invokerClient.InGameClient.Player.ChangeWorld(world, world.StartingPoints.First().Position); return string.Format("Teleported to: {0} [id: {1}]", MPQStorage.Data.Assets[SNOGroup.Worlds][worldId].Name, worldId); } return "Invalid arguments. Type 'help tp' to get help."; }
public static void HandleInvitation(MooNetClient client, bnet.protocol.invitation.Invitation invitation) { var invitee = AccountManager.GetAccountByPersistentID(invitation.InviteeIdentity.AccountId.Low); //var invitee = Instance.Subscribers.FirstOrDefault(subscriber => subscriber.Account.BnetEntityId.Low == invitation.InviteeIdentity.AccountId.Low); if (invitee == null) return; // if we can't find invite just return - though we should actually check for it until expiration time and store this in database. //Check for duplicate invites foreach (var oldInvite in OnGoingInvitations.Values) { if ((oldInvite.InviteeIdentity.AccountId == invitation.InviteeIdentity.AccountId) && (oldInvite.InviterIdentity.AccountId == invitation.InviterIdentity.AccountId)) return; } OnGoingInvitations.Add(invitation.Id, invitation); // track ongoing invitations so we can tranport it forth and back. if (invitee.IsOnline) { var inviter = AccountManager.GetAccountByPersistentID(invitation.InviterIdentity.AccountId.Low); var notification = bnet.protocol.friends.InvitationNotification.CreateBuilder().SetInvitation(invitation).SetGameAccountId(inviter.CurrentGameAccount.BnetEntityId); invitee.CurrentGameAccount.LoggedInClient.MakeTargetedRPC(FriendManager.Instance, () => bnet.protocol.friends.FriendsNotify.CreateStub(invitee.CurrentGameAccount.LoggedInClient).NotifyReceivedInvitationAdded(null, notification.Build(), callback => { })); } }
public virtual string Handle(string parameters, MooNetClient invokerClient = null) { // check if the user has enough privileges to access command group. // check if the user has enough privileges to invoke the command. if (invokerClient != null && this.Attributes.MinUserLevel > invokerClient.Account.UserLevel) return "You don't have enough privileges to invoke that command."; string[] @params = null; CommandAttribute target = null; if (parameters == string.Empty) target = this.GetDefaultSubcommand(); else { @params = parameters.Split(' '); target = this.GetSubcommand(@params[0]) ?? this.GetDefaultSubcommand(); if (target != this.GetDefaultSubcommand()) @params = @params.Skip(1).ToArray(); } // check if the user has enough privileges to invoke the command. if (invokerClient != null && target.MinUserLevel > invokerClient.Account.UserLevel) return "You don't have enough privileges to invoke that command."; return (string)this._commands[target].Invoke(this, new object[] { @params, invokerClient }); }
public void Revoke(MooNetClient client, bnet.protocol.channel_invitation.RevokeInvitationRequest request) { if (!this._onGoingInvitations.ContainsKey(request.InvitationId)) return; this._onGoingInvitations.Remove(request.InvitationId); //TODO: We should be also notifying invitee somehow /raist }
public void Revoke(MooNetClient client, bnet.protocol.channel_invitation.RevokeInvitationRequest request) { if (!this._onGoingInvitations.ContainsKey(request.InvitationId)) return; var invitation = this._onGoingInvitations[request.InvitationId]; //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(client.CurrentChannel, () => 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 = ToonManager.GetToonByLowID(invitation.InviteeIdentity.ToonId.Low); invitee.Owner.LoggedInClient.MakeTargetedRPC(this, () => bnet.protocol.channel_invitation.ChannelInvitationNotify.CreateStub(invitee.Owner.LoggedInClient).NotifyReceivedInvitationRemoved(null, invitationRemoved.Build(), callback => { })); }
private static void InitAuthentication(MooNetClient client, bnet.protocol.authentication.LogonRequest request) { client.LoginEmail = request.Email; var account = AccountManager.GetAccountByEmail(request.Email.ToLower()); // check if account exists. if (account == null) // we should be returning an error to client /raist. { client.AuthenticationErrorCode = AuthenticationErrorCodes.NoGameAccount; client.AuthenticationComplete(); return; } var thumbprintData = "f9513183031b3836103ac3a3bb606c0e06fd3b94ae4a6b6e405844085b794e901b0ebb1db650b85bac4b489a38a1ca9dcef2bbd13445d0cd85accfc62d84bc3a8d960b1a7a65cd8d3f72a172f41dca98459015ffbd25d766b02824a42dacb7c4cd64f4b3b9e316de23ec1dbb0153b73a4fa58ffb39c3f484b4b478a660dc8979e16e52f978a0ca2fc4184fa0f69844d73ef99f47e3ccb02cf6a636b4ae9513404eee7e0ad536dcef50cd1699e38195e6afdd3655a3a3529b4e52b33ac5d04f5fa2b15536a2c782c89c0acf133e14eac15af035abf5e44e9e1124a3397dac8f90a4ccb1717540698869fc1ba9037e099d68698ecf17ffdd36f07013176be24269fda1e5d221708181d95474fc1d74bb901062a9f6a3e24aef79e9d583d9126796d63c153a0f75f02da27ecc0971f39a46ec29087c3ae474e08fdf8f65d1445b293399bc495ff651b7d2d7a36216ba5e4400ea7bbc884dc4cf3ed27f14501b8bb7fc0f86b5089880e6889bcd851153e299a337d6c945f710559595e351995341cbef44abac379cf0f845b362d294eec390d50f1a50089d250eae1b1205cea1aff514de076516f467cd077a1fbb759b415dc6c0ea1617f31f7d764a0d60d5b67aa82b4202b2a9455eb9ca3683955ec45aaf56aba42a2f3ae9be5f3eed093a6601816d00e0569bfcb91fb7843945336c99757812d373d510d25744f9480b6cc87e8a".ToByteArray(); var srp6a = new SRP6a(account); // create srp6 handler to process the authentication. OngoingAuthentications.Add(client, srp6a); // request client to load thumbprint.dll for authentication. var moduleLoadRequest = bnet.protocol.authentication.ModuleLoadRequest.CreateBuilder() .SetModuleHandle(bnet.protocol.ContentHandle.CreateBuilder() .SetRegion(0x00005858) // XX .SetUsage(0x61757468) // auth - thumbprint.dll .SetHash(ByteString.CopyFrom(VersionInfo.MooNet.ThumbprintHashMap[client.Platform]))) .SetMessage(ByteString.CopyFrom(thumbprintData)) .Build(); client.ThumbprintReq = true; client.MakeRPC(() => bnet.protocol.authentication.AuthenticationClient.CreateStub(client).ModuleLoad(null, moduleLoadRequest, callback => { })); }
public static void HandleAuthResponse(MooNetClient client, int moduleId, byte[] authMessage) { if(!OngoingAuthentications.ContainsKey(client)) return; // TODO: disconnect him also. /raist. var srp6 = OngoingAuthentications[client]; byte[] A = authMessage.Skip(1).Take(128).ToArray(); // client's public ephemeral byte[] M_client = authMessage.Skip(1 + 128).Take(32).ToArray(); // client's proof of session key. byte[] seed = authMessage.Skip(1 + 32 + 128).Take(128).ToArray(); // client's second challenge. if(srp6.Verify(A,M_client,seed)) // authentication sucesseful { // send the logon proof. var message = bnet.protocol.authentication.ModuleMessageRequest.CreateBuilder() .SetModuleId(moduleId) .SetMessage(ByteString.CopyFrom(srp6.LogonProof)) .Build(); client.MakeRPC(() => bnet.protocol.authentication.AuthenticationClient.CreateStub(client).ModuleMessage(null, message, callback => { })); client.Account = AccountManager.GetAccountByEmail(srp6.Account.Email); if (client.Account.LoggedInClient != null) client.Account.LoggedInClient.Connection.Disconnect(); client.Account.LoggedInClient = client; } else // authentication failed because of invalid credentals. { client.AuthenticationErrorCode = AuthenticationErrorCodes.InvalidCredentials; } OngoingAuthentications.Remove(client); client.AuthenticationCompleteSignal.Set(); // signal about completion of authentication processes so we can return the response for AuthenticationService:LogonRequest. }
public string ClientChannels(string[] @params, MooNetClient invokerClient) { var client = invokerClient; if (client == null && @params.Count() < 1) return "Invalid arguments. Type 'help channels client' to get help."; var output = ""; if (client == null) { var email = @params[0]; var account = AccountManager.GetAccountByEmail(email); if (account == null) return string.Format("No account with email '{0}' exists.", email); if (!account.IsOnline) return string.Format("Account '{0}' is not logged in.", email); var gameAccounts = GameAccountManager.GetGameAccountsForAccount(account); foreach (var gameAccount in gameAccounts) { output += this.ClientChannels(null, gameAccount.LoggedInClient); } } else { output = string.Format("Active channels for account: {0}\n", client.Account.Email); output = ChannelManager.Channels.Aggregate(output, (current, pair) => current + string.Format("Id: {0} \tOwner: {1}\n", pair.Value.DynamicId, pair.Value.Owner)); } return output; }
public string Revealed(string[] @params, MooNetClient invokerClient) { Player player; if (invokerClient != null && invokerClient.InGameClient != null) player = invokerClient.InGameClient.Player; else { if (@params.Count() < 1) return "Invalid arguments. Type 'help debug revealed' to get help."; var account = AccountManager.GetAccountByEmail(@params[0]); if(account==null) return string.Format("No account with email: {0} exists.", @params[0]); if(account.LoggedInClient==null || account.LoggedInClient.InGameClient==null) return string.Format("Account {0} is not in-game.", @params[0]); player = account.LoggedInClient.InGameClient.Player; } var output = new StringBuilder("Revealed objects:" + Environment.NewLine); foreach(var @object in player.RevealedObjects.Values) { output.Append(@object + Environment.NewLine); } return output.ToString(); }
private static void InitAuthentication(MooNetClient client, bnet.protocol.authentication.LogonRequest request) { var account = AccountManager.GetAccountByEmail(request.Email); // check if account exists. if (account == null) // we should be returning an error to client /raist. { client.AuthenticationErrorCode = AuthenticationErrorCodes.NoGameAccount; client.AuthenticationCompleteSignal.Set(); return; } var srp6a = new SRP6a(account); // create srp6 handler to process the authentication. OngoingAuthentications.Add(client, srp6a); // request client to load password.dll for authentication. var moduleLoadRequest = bnet.protocol.authentication.ModuleLoadRequest.CreateBuilder() .SetModuleHandle(bnet.protocol.ContentHandle.CreateBuilder() .SetRegion(0x00005553) // us .SetUsage(0x61757468) // auth - password.dll .SetHash(ByteString.CopyFrom(ModuleHash))) .SetMessage(ByteString.CopyFrom(srp6a.LogonChallenge)) .Build(); client.MakeRPCWithListenerId(request.ListenerId, () => bnet.protocol.authentication.AuthenticationClient.CreateStub(client).ModuleLoad(null, moduleLoadRequest, ModuleLoadResponse)); }
private void SendConnectionInfo(MooNetClient client) { if (client == this.Channel.Owner) // we should send a GameFoundNotification to part leader { var builder = bnet.protocol.game_master.GameFoundNotification.CreateBuilder(); builder.AddConnectInfo(GetConnectionInfoForClient(client)); builder.SetRequestId(this.RequestId); builder.SetGameHandle(this.GameHandle); client.CallMethod(bnet.protocol.game_master.GameFactorySubscriber.Descriptor.FindMethodByName("NotifyGameFound"), builder.Build(), this.DynamicId); } else // where as other members should get a bnet.protocol.notification.Notification { var connectionInfo = GetConnectionInfoForClient(client); var connectionInfoAttribute = bnet.protocol.attribute.Attribute.CreateBuilder().SetName("connection_info") .SetValue(bnet.protocol.attribute.Variant.CreateBuilder().SetMessageValue(connectionInfo.ToByteString()).Build()) .Build(); var gameHandleAttribute = bnet.protocol.attribute.Attribute.CreateBuilder().SetName("game_handle") .SetValue(bnet.protocol.attribute.Variant.CreateBuilder().SetMessageValue(this.GameHandle.ToByteString()).Build()) .Build(); var builder = bnet.protocol.notification.Notification.CreateBuilder() .SetSenderId(this.Channel.Owner.CurrentToon.BnetEntityID) .SetTargetId(client.CurrentToon.BnetEntityID) .SetType("GAME_CONNECTION_INFO") .AddAttribute(connectionInfoAttribute) .AddAttribute(gameHandleAttribute); client.CallMethod(bnet.protocol.notification.NotificationListener.Descriptor.FindMethodByName("OnNotificationReceived"), builder.Build()); } }
public static void HandleAuthResponse(MooNetClient client, int moduleId, byte[] authMessage) { if(!OngoingAuthentications.ContainsKey(client)) return; // TODO: disconnect him also. /raist. var srp6 = OngoingAuthentications[client]; byte[] A = authMessage.Skip(1).Take(128).ToArray(); // client's public ephemeral byte[] M_client = authMessage.Skip(1 + 128).Take(32).ToArray(); // client's proof of session key. byte[] seed = authMessage.Skip(1 + 32 + 128).Take(128).ToArray(); // client's second challenge. var success = srp6.Verify(A, M_client, seed); if (Config.Instance.DisablePasswordChecks || success) // if authentication is sucesseful or password check's are disabled. { // send the logon proof. var message = bnet.protocol.authentication.ModuleMessageRequest.CreateBuilder() .SetModuleId(moduleId) .SetMessage(ByteString.CopyFrom(srp6.LogonProof)) .Build(); client.MakeRPC(() => bnet.protocol.authentication.AuthenticationClient.CreateStub(client).ModuleMessage(null, message, callback => client.CheckAuthenticator())); client.Account = AccountManager.GetAccountByEmail(srp6.Account.Email); //if (client.Account.LoggedInClient != null) // client.Account.LoggedInClient.Connection.Disconnect(); //client.Account.LoggedInClient = client; } else // authentication failed because of invalid credentals. { client.AuthenticationErrorCode = AuthenticationErrorCodes.InvalidCredentials; //end authentication client.AuthenticationComplete(); } OngoingAuthentications.Remove(client); }
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; }
/// <summary> /// Adds a client subscriber to object, which will eventually be notified whenever the object changes state. /// </summary> /// <param name="client">The client to add as a subscriber.</param> /// <param name="remoteObjectId">The client's dynamic ID.</param> public void AddSubscriber(MooNetClient client, ulong remoteObjectId) { // Map the subscriber's dynamic ID to to our dynamic ID so we know how to translate later on when the object makes a notify call client.MapLocalObjectID(this.DynamicId, remoteObjectId); this.Subscribers.Add(client); // Since the client wasn't previously subscribed, it should not be aware of the object's state -- let's notify it this.NotifySubscriptionAdded(client); }
private bnet.protocol.game_master.ConnectInfo GetConnectionInfoForClient(MooNetClient client) { //TODO: We should actually find the server's public-interface and use that /raist return bnet.protocol.game_master.ConnectInfo.CreateBuilder().SetToonId(client.CurrentToon.BnetEntityID) .SetHost(Net.Utils.GetGameServerIPForClient(client)).SetPort(Config.Instance.Port).SetToken(ByteString.CopyFrom(new byte[] { 0x07, 0x34, 0x02, 0x60, 0x91, 0x93, 0x76, 0x46, 0x28, 0x84 })) .AddAttribute(bnet.protocol.attribute.Attribute.CreateBuilder().SetName("SGameId").SetValue(bnet.protocol.attribute.Variant.CreateBuilder().SetIntValue((long)this.DynamicId).Build())) .Build(); }
public void HandleInvitation(MooNetClient client, bnet.protocol.invitation.Invitation invitation) { MooNetClient invitee = this.Subscribers.FirstOrDefault(subscriber => subscriber.CurrentToon.BnetEntityID.Low == invitation.InviteeIdentity.ToonId.Low); if (invitee == null) return; // if we can't find invite just return - though we should actually check for it until expiration time. var notification = bnet.protocol.channel_invitation.InvitationAddedNotification.CreateBuilder().SetInvitation(invitation); invitee.CallMethod(bnet.protocol.channel_invitation.ChannelInvitationNotify.Descriptor.FindMethodByName("NotifyReceivedInvitationAdded"), notification.Build(), this.DynamicId); }
public static void Identify(MooNetClient client) { var packet = new PacketIn(client, client.IncomingMooNetStream.GetPacketHeader()); if (packet.Header.ServiceId == ServiceReply) ProcessReply(client, packet); else ProcessMessage(client, packet); }
public static void HandleAccept(MooNetClient client, bnet.protocol.invitation.GenericRequest request) { if (!OnGoingInvitations.ContainsKey(request.InvitationId)) return; var invitation = OnGoingInvitations[request.InvitationId]; var inviter = AccountManager.GetAccountByPersistentID(invitation.InviterIdentity.AccountId.Low); var invitee = AccountManager.GetAccountByPersistentID(invitation.InviteeIdentity.AccountId.Low); var inviteeAsFriend = bnet.protocol.friends.Friend.CreateBuilder().SetId(invitation.InviteeIdentity.AccountId).Build(); var inviterAsFriend = bnet.protocol.friends.Friend.CreateBuilder().SetId(invitation.InviterIdentity.AccountId).Build(); var notificationToInviter = bnet.protocol.friends.InvitationNotification.CreateBuilder() .SetGameAccountId(invitee.BnetEntityId) .SetInvitation(invitation) .SetReason((uint)InvitationRemoveReason.Accepted) // success? .Build(); var notificationToInvitee = bnet.protocol.friends.InvitationNotification.CreateBuilder() .SetGameAccountId(inviter.BnetEntityId) .SetInvitation(invitation) .SetReason((uint)InvitationRemoveReason.Accepted) // success? .Build(); Friends.Add(invitee.BnetEntityId.Low, inviterAsFriend); Friends.Add(inviter.BnetEntityId.Low, inviteeAsFriend); AddFriendshipToDB(inviter,invitee); // send friend added notifications var friendAddedNotificationToInviter = bnet.protocol.friends.FriendNotification.CreateBuilder().SetTarget(inviteeAsFriend).SetGameAccountId(invitee.BnetEntityId).Build(); var friendAddedNotificationToInvitee = bnet.protocol.friends.FriendNotification.CreateBuilder().SetTarget(inviterAsFriend).SetGameAccountId(inviter.BnetEntityId).Build(); var inviterGameAccounts = GameAccountManager.GetGameAccountsForAccount(inviter).Values; var inviteeGameAccounts = GameAccountManager.GetGameAccountsForAccount(invitee).Values; foreach (var inviterGameAccount in inviterGameAccounts) { if (inviterGameAccount.IsOnline) { inviterGameAccount.LoggedInClient.MakeTargetedRPC(FriendManager.Instance, () => bnet.protocol.friends.FriendsNotify.CreateStub(inviterGameAccount.LoggedInClient).NotifyReceivedInvitationRemoved(null, notificationToInviter, callback => { })); inviterGameAccount.LoggedInClient.MakeTargetedRPC(FriendManager.Instance, () => bnet.protocol.friends.FriendsNotify.CreateStub(inviterGameAccount.LoggedInClient).NotifyFriendAdded(null, friendAddedNotificationToInviter, callback => { })); } } foreach (var inviteeGameAccount in inviteeGameAccounts) { if (inviteeGameAccount.IsOnline) { inviteeGameAccount.LoggedInClient.MakeTargetedRPC(FriendManager.Instance, () => bnet.protocol.friends.FriendsNotify.CreateStub(inviteeGameAccount.LoggedInClient).NotifyFriendAdded(null, friendAddedNotificationToInvitee, callback => { })); inviteeGameAccount.LoggedInClient.MakeTargetedRPC(FriendManager.Instance, () => bnet.protocol.friends.FriendsNotify.CreateStub(inviteeGameAccount.LoggedInClient).NotifyReceivedInvitationRemoved(null, notificationToInvitee, callback => { })); } } }
public void HandleInvitation(MooNetClient client, bnet.protocol.invitation.Invitation invitation) { var invitee = this.Subscribers.FirstOrDefault(subscriber => subscriber.Account.BnetAccountID.Low == invitation.InviteeIdentity.AccountId.Low); if (invitee == null) return; // if we can't find invite just return - though we should actually check for it until expiration time and store this in database. this._onGoingInvitations.Add(invitation.Id, invitation); // track ongoing invitations so we can tranport it forth and back. var notification = bnet.protocol.friends.InvitationAddedNotification.CreateBuilder().SetInvitation(invitation); invitee.CallMethod(bnet.protocol.friends.FriendsNotify.Descriptor.FindMethodByName("NotifyReceivedInvitationAdded"), notification.Build(), this.DynamicId); }
private bnet.protocol.storage.ExecuteResponse GetHeroDigest(MooNetClient client, bnet.protocol.storage.ExecuteRequest request) { var results = new List<bnet.protocol.storage.OperationResult>(); foreach(var operation in request.OperationsList) { Google.ProtocolBuffers.ByteString data = null; // find the requested toons entity-id. var stream = new MemoryStream(operation.RowId.Hash.ToByteArray()); // contains ToonHandle in field form with one unknown field (which is not in message definition): // int16 unknown; uint8 realm; uint8 region; uint32 program; uint64 id; stream.ReadValueU16(); // unknown stream.ReadValueU8(); // realm stream.ReadValueU8(); // region stream.ReadValueU32(false); // program var toonId = stream.ReadValueU64(false); if (!client.Account.CurrentGameAccount.Toons.ContainsKey(toonId)) { Logger.Error("Can't find the requested toon: {0}", toonId); continue; } var toon = client.Account.CurrentGameAccount.Toons[toonId]; if (operation.ColumnId.Hash.Equals(HeroDigestColumn)) data = toon.Digest.ToByteString(); else Logger.Warn("Unknown ColumndId requested: {0}", operation.ColumnId.Hash.ToByteArray().HexDump()); //else if (operation.ColumnId.Hash.Equals(HeroNameColumn)) // data = toon.NameText.ToByteString(); var operationResult = bnet.protocol.storage.OperationResult.CreateBuilder().SetTableId(operation.TableId); operationResult.AddData( bnet.protocol.storage.Cell.CreateBuilder() .SetColumnId(request.OperationsList[0].ColumnId) .SetRowId(request.OperationsList[0].RowId) .SetVersion(1) .SetData(data) .Build() ); results.Add(operationResult.Build()); } var builder = bnet.protocol.storage.ExecuteResponse.CreateBuilder(); foreach(var result in results) { builder.AddResults(result); } return builder.Build(); }
public string Portal(string[] @params, MooNetClient invokerClient) { if (invokerClient == null) return "You can not invoke this command from console."; if (invokerClient.InGameClient == null) return "You can only invoke this command while ingame."; invokerClient.InGameClient.Player.EnableStoneOfRecall(); return string.Format("Done"); }
public void HandleInvitation(MooNetClient client, bnet.protocol.invitation.Invitation invitation) { var invitee = this.Subscribers.FirstOrDefault(subscriber => subscriber.CurrentToon.BnetEntityID.Low == invitation.InviteeIdentity.ToonId.Low); if (invitee == null) return; // if we can't find invite just return - though we should actually check for it until expiration time. this._onGoingInvitations.Add(invitation.Id, invitation); // track ongoing invitations so we can tranport it forth and back. var notification = bnet.protocol.channel_invitation.InvitationAddedNotification.CreateBuilder().SetInvitation(invitation); invitee.MakeTargetedRPC(this,() => bnet.protocol.channel_invitation.ChannelInvitationNotify.CreateStub(invitee).NotifyReceivedInvitationAdded(null, notification.Build(), callback => { })); }
public static void Identify(MooNetClient client) { var packet = new PacketIn(client, client.IncomingMooNetStream.GetPacketHeader()); if (packet.Header.ServiceId == ServiceReply) { ProcessReply(client, packet); } else { ProcessMessage(client, packet); } }
private static void ProcessReply(MooNetClient client, PacketIn packet) { if (client.RPCCallbacks.ContainsKey(packet.Header.Token)) { var callback = client.RPCCallbacks[packet.Header.Token]; Logger.Trace("RPCReply => {0}", callback.Action.Target); callback.Action(packet.ReadMessage(callback.Builder)); client.RPCCallbacks.Remove(packet.Header.Token); } else { Logger.Warn("RPC callback contains unexpected token: {0}", packet.Header.Token); client.Connection.Disconnect(); } }
private static void ProcessMessage(MooNetClient client, PacketIn packet) { var service = Service.GetByID(packet.Header.ServiceId); if (service == null) { Logger.Error("No service exists with id: 0x{0}", packet.Header.ServiceId.ToString("X2")); return; } var method = service.DescriptorForType.Methods.Single(m => GetMethodId(m) == packet.Header.MethodId); var proto = service.GetRequestPrototype(method); var builder = proto.WeakCreateBuilderForType(); var message = packet.ReadMessage(builder); Logger.LogIncoming(message, packet.Header); try { lock (service) // lock the service so that its in-context client does not get changed.. { ((IServerService)service).Client = client; ((IServerService)service).LastCallHeader = packet.Header; ((IServerService)service).Status = 0; service.CallMethod(method, null, message, (msg => SendRPCResponse(client.Connection, packet.Header.Token, msg, ((IServerService)service).Status))); } } catch (NotImplementedException) { Logger.Warn("Unimplemented service method: {0}.{1}", service.GetType().Name, method.Name); } catch (UninitializedMessageException e) { Logger.Debug("Failed to parse message: {0}", e.Message); } catch (Exception e) { Logger.DebugException(e, string.Empty); } }