public static Channel CreateNewChannel(BNetClient client, ulong remoteObjectId) { var channel = new Channel(client, remoteObjectId); Channels.Add(channel.DynamicId, channel); return(channel); }
public void RemoveOwner(RemoveReason reason) { if (this.Owner != null) { RemoveMember(this.Owner, reason, false); this.Owner = null; } }
/// <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(BNetClient 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); }
public QueueWorker(ILogger <QueueWorker> logger, Versions versions, BGDL bgdl, CDN cdn, ConcurrentQueue <Summary> queue, IHostApplicationLifetime applicationLifetime, BNetClient bNetClient) { _logger = logger; _versions = versions; _bgdl = bgdl; _cdn = cdn; _queue = queue; _applicationLifetime = applicationLifetime; _bNetClient = bNetClient; }
public SummaryWorker(IHostApplicationLifetime appLifetime, ILogger <SummaryWorker> logger, BNetClient bNetClient, Summary summary, ConcurrentQueue <BNetLib.Models.Summary> queue, Versions versions, BGDL bgdl, CDN cdn) { _appLifetime = appLifetime; _logger = logger; _bNetClient = bNetClient; _summary = summary; _queue = queue; _versions = versions; _bgdl = bgdl; _cdn = cdn; }
public void SetOwner(BNetClient client) { if (client == this.Owner) { Logger.Warn("Tried to set client {0} as owner of channel when it was already the owner", client.Connection.RemoteEndPoint.ToString()); return; } // TODO: Should send state update to current owner instead of removing it RemoveOwner(RemoveReason.Left); this.Owner = client; AddMember(client); }
/// <summary> /// Removes a given subscriber and unmaps the object's dynamic ID. /// </summary> /// <param name="client">The client to remove.</param> public void RemoveSubscriber(BNetClient client) { if (!this.Subscribers.Contains(client)) { Logger.Warn("Attempted to remove subscriber {0}", client.Connection.RemoteEndPoint.ToString()); return; } // Unmap the object from the client client.UnmapLocalObjectID(this.DynamicId); this.Subscribers.Remove(client); // We don't need to do a notify nor respond to the client with anything since the client will ultimately act // like the object never existed in the first place }
public void AddMember(BNetClient client) { if (HasUser(client)) { Logger.Warn("Attempted to add client {0} to channel when it was already a member of the channel", client.Connection.RemoteEndPoint.ToString()); return; } var identity = client.GetIdentity(false, false, true); bool isOwner = client == this.Owner; var addedMember = new Member(identity, (isOwner) ? Member.Privilege.UnkCreator : Member.Privilege.UnkMember); if (this.Members.Count > 0) { addedMember.AddRoles( (isOwner) ? Member.Role.PartyLeader : Member.Role.PartyMember, Member.Role.ChannelMember); } else { addedMember.AddRole((isOwner) ? Member.Role.ChannelCreator : Member.Role.ChannelMember); } // This needs to be here so that the foreach below will also send to the client that was just added this.Members.Add(client, addedMember); // Cache the built state and member var channelState = this.State; var bnetMember = addedMember.BnetMember; var method = bnet.protocol.channel.ChannelSubscriber.Descriptor.FindMethodByName("NotifyAdd"); foreach (var pair in this.Members) { var message = bnet.protocol.channel.AddNotification.CreateBuilder() .SetChannelState(channelState) // Set the Self property for each call on each client // TODO: This may not be necessary here (this field is optional); check the caps .SetSelf(pair.Value.BnetMember) .AddMember(bnetMember) .Build(); //Logger.Warn("NotifyAdd:\n{0}", message.ToString()); pair.Key.CallMethod(method, message, this.DynamicId); } client.CurrentChannel = this; }
public static string GetGameServerIPForClient(BNetClient client) { if (!NATConfig.Instance.Enabled) // if NAT is not enabled, just return bnetclient's localendpoint address. { return(client.Connection.LocalEndPoint.Address.ToString()); } else { return(client.Connection.LocalEndPoint.Address.ToString() == "127.0.0.1" ? client.Connection.LocalEndPoint.ToString() : NATConfig.Instance.PublicIP); // if client is not connected over localhost, send him public-ip. // Known problems: If user enables NAT, LAN-clients (and even local-computer if d3 is configured to use lan-ip) will not able to connect in gs. // That needs a full implementation similar to pvpgn where we currently pretty miss the time for /raist. } }
public Channel(BNetClient client, ulong remoteObjectId) { this.BnetEntityId = bnet.protocol.EntityId.CreateBuilder().SetHigh((ulong)EntityIdHelper.HighIdType.ChannelId).SetLow(this.DynamicId).Build(); this.D3EntityId = D3.OnlineService.EntityId.CreateBuilder().SetIdHigh((ulong)EntityIdHelper.HighIdType.ChannelId).SetIdLow(this.DynamicId).Build(); this.PrivacyLevel = bnet.protocol.channel.ChannelState.Types.PrivacyLevel.PRIVACY_LEVEL_OPEN_INVITATION; this.MinMembers = 1; this.MaxMembers = 8; this.MaxInvitations = 12; // This is an object creator, so we have to map the remote object ID client.MapLocalObjectID(this.DynamicId, remoteObjectId); // The client can't be set as the owner (or added as a member) here because the server must first make a response // to the client before using a mapped ID (presuming that this was called from a service). // We'll just let the caller do that for us. }
public void ListenForGame(BNetClient client) { // We should actually find the server's public-interface and use that var connectionInfo = bnet.protocol.game_master.ConnectInfo.CreateBuilder().SetToonId(client.CurrentToon.BnetEntityID).SetHost (Net.Utils.GetGameServerIPForClient(client)).SetPort(Net.Game.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(); var builder = bnet.protocol.game_master.GameFoundNotification.CreateBuilder(); builder.AddConnectInfo(connectionInfo); builder.SetRequestId(this.RequestID); builder.SetGameHandle(this.GameHandle); this.Clients.Add(client); client.CallMethod(bnet.protocol.game_master.GameFactorySubscriber.Descriptor.FindMethodByName("NotifyGameFound"), builder.Build(), this.DynamicId); }
public void RemoveMember(BNetClient client, RemoveReason reason, bool dissolving) { if (client.CurrentToon == null) { Logger.Warn("Could not remove toon-less client {0}", client.Connection.RemoteEndPoint.ToString()); return; } else if (!HasUser(client)) { Logger.Warn("Attempted to remove non-member client {0} from channel", client.Connection.RemoteEndPoint.ToString()); return; } else if (client.CurrentChannel != this) { Logger.Warn("Client {0} is being removed from a channel that is not its current one..", client.Connection.RemoteEndPoint.ToString()); } var memberId = this.Members[client].Identity.ToonId; var message = bnet.protocol.channel.RemoveNotification.CreateBuilder() .SetMemberId(memberId) .SetReason((uint)reason) .Build(); //Logger.Debug("NotifyRemove message:\n{0}", message.ToString()); var method = bnet.protocol.channel.ChannelSubscriber.Descriptor.FindMethodByName("NotifyRemove"); foreach (var pair in this.Members) { pair.Key.CallMethod(method, message, this.DynamicId); } this.Members.Remove(client); client.CurrentChannel = null; if (client == this.Owner) { this.Owner = null; } if (this.Members.Count == 0 && !dissolving) { Dissolve(); } }
public bool HasUser(BNetClient client) { return(this.Members.Any(pair => pair.Key == client)); }
public void RemoveMember(BNetClient client, RemoveReason reason) { RemoveMember(client, reason, false); }
public Member GetMember(BNetClient client) { return(this.Members[client]); }
/// <summary> /// Notifies a specific subscriber about the object's present state. /// This methods should be actually implemented by deriving object classes. /// </summary> /// <param name="client">The subscriber.</param> protected virtual void NotifySubscriptionAdded(BNetClient client) { }