/// <summary> /// Executes the operation's logic. /// </summary> /// <param name="context">A reference to the operation context.</param> protected override void Execute(IOperationContext context) { var targetLoginLocation = this.playerMetadata.LastLocation; if (context.Map[targetLoginLocation] == null) { targetLoginLocation = this.playerMetadata.StartingLocation; } var creationArguments = new PlayerCreationArguments() { Type = CreatureType.Player, Metadata = this.playerMetadata, PreselectedId = this.preselectedPlayerId, }; if (!(context.CreatureFactory.CreateCreature(creationArguments) is IPlayer player)) { context.Logger.LogWarning($"Unable to create player instance for {this.playerMetadata.Name}, aborting log in."); return; } if (!context.GameApi.AddCreatureToGame(targetLoginLocation, player)) { // Unable to place the player in the map. var disconnectNotification = new DisconnectNotification( player.YieldSingleItem(), "Your character could not be placed on the map.\nPlease try again, or contact an administrator if the issue persists."); context.GameApi.SendNotification(disconnectNotification); return; } var descriptionTiles = context.Map.DescribeAt(player, player.Location); // TODO: In addition, we need to send the player's inventory, the first time login message + outfit window here if applicable. // And any VIP records here. this.SendNotification(context, new PlayerLoginNotification(player, player.Location, descriptionTiles, AnimatedEffect.BubbleBlue)); this.SendNotification(context, new WorldLightChangedNotification(player.YieldSingleItem(), this.currentWorldLightLevel, this.currentWorldLightColor)); this.SendNotification(context, new CreatureLightUpdateNotification(player.YieldSingleItem(), player)); this.SendNotification(context, new TextMessageNotification(player.YieldSingleItem(), MessageType.Status, "This is a test message")); }
/// <summary> /// Executes the operation's logic. /// </summary> /// <param name="context">A reference to the operation context.</param> protected override void Execute(IElevatedOperationContext context) { // This will eventually come from the character, or fall back. var targetLoginLocation = MapConstants.ThaisTempleMark; var creationArguments = new PlayerCreationArguments() { Client = this.Client, Type = CreatureType.Player, Metadata = this.PlayerMetadata, }; if (!(context.CreatureFactory.CreateCreature(creationArguments) is IPlayer player)) { context.Logger.Warning($"Unable to create player instance for {this.PlayerMetadata.Name}, aborting log in."); return; } if (!context.Map.GetTileAt(targetLoginLocation, out ITile targetTile) || !this.PlaceCreature(context, targetTile, player)) { // Unable to place the player in the map. context.Scheduler.ScheduleEvent( new GenericNotification( () => player.YieldSingleItem(), new GameServerDisconnectPacket("Your character could not be placed on the map.\nPlease try again, or contact an administrator if the issue persists."))); return; } var(descriptionMetadata, descriptionBytes) = context.MapDescriptor.DescribeAt(player, player.Location); // TODO: In addition, we need to send the player's inventory, the first time login message + outfit window here if applicable. // And any VIP records here. var notification = new GenericNotification( () => player.YieldSingleItem(), new PlayerLoginPacket(player.Id, player), new MapDescriptionPacket(player.Location, descriptionBytes), new MagicEffectPacket(player.Location, AnimatedEffect.BubbleBlue), new PlayerStatsPacket(player), new PlayerSkillsPacket(player), new WorldLightPacket(this.CurrentWorldLightLevel, this.CurrentWorldLightColor), new CreatureLightPacket(player), new TextMessagePacket(MessageType.StatusDefault, "This is a test message"), new PlayerConditionsPacket(player)); if (descriptionMetadata.TryGetValue(IMapDescriptor.CreatureIdsToLearnMetadataKeyName, out object creatureIdsToLearnBoxed) && descriptionMetadata.TryGetValue(IMapDescriptor.CreatureIdsToForgetMetadataKeyName, out object creatureIdsToForgetBoxed) && creatureIdsToLearnBoxed is IEnumerable <uint> creatureIdsToLearn && creatureIdsToForgetBoxed is IEnumerable <uint> creatureIdsToForget) { notification.Sent += (client) => { foreach (var creatureId in creatureIdsToLearn) { client.AddKnownCreature(creatureId); } foreach (var creatureId in creatureIdsToForget) { client.RemoveKnownCreature(creatureId); } }; } notification.Send(new NotificationContext(context.Logger, context.MapDescriptor, context.CreatureFinder)); }