/// <inheritdoc/> public void ForwardLetter(LetterHeader letter) { foreach (var gameServer in this.GameServers.Values) { gameServer.LetterReceived(letter); } }
/// <inheritdoc/> public void LetterReceived(LetterHeader letter) { var player = this.gameContext.GetPlayerByCharacterName(letter.Receiver); if (player != null) { var newLetterIndex = player.SelectedCharacter.Letters.Count; player.SelectedCharacter.Letters.Add(letter); player.PlayerView.MessengerView.AddToLetterList(letter, (ushort)newLetterIndex, true); } }
/// <summary> /// Deletes the letter. /// </summary> /// <param name="player">The player.</param> /// <param name="letter">The letter.</param> public void DeleteLetter(Player player, LetterHeader letter) { if (letter == null) { Log.WarnFormat("letter is null, player {0}", player.SelectedCharacter.Name); } var letterIndex = player.SelectedCharacter.Letters.IndexOf(letter); player.SelectedCharacter.Letters.RemoveAt(letterIndex); player.ViewPlugIns.GetPlugIn <ILetterDeletedPlugIn>()?.LetterDeleted((ushort)letterIndex); }
/// <summary> /// Deletes the letter. /// </summary> /// <param name="player">The player.</param> /// <param name="letter">The letter.</param> public void DeleteLetter(Player player, LetterHeader letter) { if (letter == null) { Log.WarnFormat("letter is null, player {0}", player.SelectedCharacter.Name); } var letterIndex = player.SelectedCharacter.Letters.IndexOf(letter); player.SelectedCharacter.Letters.RemoveAt(letterIndex); player.PlayerView.MessengerView.LetterDeleted((ushort)letterIndex); }
/// <summary> /// Sends the letter. /// </summary> /// <param name="player">The player.</param> /// <param name="receiver">The receiver.</param> /// <param name="message">The message.</param> /// <param name="title">The title.</param> /// <param name="rotation">The rotation.</param> /// <param name="animation">The animation.</param> /// <param name="letterId">The client side letter id.</param> public void SendLetter(Player player, string receiver, string message, string title, byte rotation, byte animation, uint letterId) { using var loggerScope = player.Logger.BeginScope(this.GetType()); var sendPrice = player.GameContext.Configuration.LetterSendPrice; if (player.Money < sendPrice) { player.ViewPlugIns.GetPlugIn <IShowMessagePlugIn>()?.ShowMessage("Not enough Zen to send a letter.", MessageType.BlueNormal); player.ViewPlugIns.GetPlugIn <ILetterSendResultPlugIn>()?.LetterSendResult(LetterSendSuccess.NotEnoughMoney, letterId); return; } LetterHeader letter = null; try { using (var context = player.GameContext.PersistenceContextProvider.CreateNewPlayerContext(player.GameContext.Configuration)) { letter = this.CreateLetter(context, player, receiver, message, title, rotation, animation); if (!context.CanSaveLetter(letter)) { player.ViewPlugIns.GetPlugIn <ILetterSendResultPlugIn>()?.LetterSendResult(LetterSendSuccess.ReceiverNotExists, letterId); return; } context.SaveChanges(); } player.ViewPlugIns.GetPlugIn <ILetterSendResultPlugIn>()?.LetterSendResult(LetterSendSuccess.Success, letterId); player.TryAddMoney(-sendPrice); } catch (Exception ex) { player.Logger.LogError(ex, "Unexpected error when trying to send a letter"); player.ViewPlugIns.GetPlugIn <ILetterSendResultPlugIn>()?.LetterSendResult(LetterSendSuccess.TryAgain, letterId); player.ViewPlugIns.GetPlugIn <IShowMessagePlugIn>()?.ShowMessage("Oops, some error happened during sending the Letter.", MessageType.BlueNormal); } // Try to forward it to the player, if he is online var receiverPlayer = player.GameContext.GetPlayerByCharacterName(receiver); if (receiverPlayer != null) { receiverPlayer.PersistenceContext.Attach(letter); receiverPlayer.SelectedCharacter.Letters.Add(letter); receiverPlayer.ViewPlugIns.GetPlugIn <IAddToLetterListPlugIn>()?.AddToLetterList(letter, (ushort)(receiverPlayer.SelectedCharacter.Letters.Count - 1), true); } else { (player.GameContext as IGameServerContext)?.FriendServer?.ForwardLetter(letter); } }
/// <summary> /// Deletes the letter. /// </summary> /// <param name="player">The player.</param> /// <param name="letter">The letter.</param> public void DeleteLetter(Player player, LetterHeader letter) { using var loggerScope = player.Logger.BeginScope(this.GetType()); if (letter == null) { player.Logger.LogWarning("letter is null, player {0}", player.SelectedCharacter.Name); } var letterIndex = player.SelectedCharacter.Letters.IndexOf(letter); player.SelectedCharacter.Letters.RemoveAt(letterIndex); player.ViewPlugIns.GetPlugIn <ILetterDeletedPlugIn>()?.LetterDeleted((ushort)letterIndex); }
/// <summary> /// Sends the letter. /// </summary> /// <param name="player">The player.</param> /// <param name="receiver">The receiver.</param> /// <param name="message">The message.</param> /// <param name="title">The title.</param> /// <param name="rotation">The rotation.</param> /// <param name="animation">The animation.</param> /// <param name="letterId">The client side letter id.</param> public void SendLetter(Player player, string receiver, string message, string title, byte rotation, byte animation, uint letterId) { if (player.Money < LetterSendCost) { player.PlayerView.ShowMessage("Not enough Zen to send a letter.", MessageType.BlueNormal); player.PlayerView.MessengerView.LetterSendResult(LetterSendSuccess.NotEnoughMoney, letterId); return; } LetterHeader letter = null; try { using (var context = this.gameContext.RepositoryManager.CreateNewAccountContext(this.gameContext.Configuration)) using (this.gameContext.RepositoryManager.UseContext(context)) { letter = this.CreateLetter(player, receiver, message, title, rotation, animation); if (!context.SaveChanges()) { player.PlayerView.MessengerView.LetterSendResult(LetterSendSuccess.ReceiverNotExists, letterId); return; } } player.PlayerView.MessengerView.LetterSendResult(LetterSendSuccess.Success, letterId); player.TryAddMoney(-LetterSendCost); } catch (Exception ex) { Log.Error("Unexpected error when trying to send a letter", ex); player.PlayerView.MessengerView.LetterSendResult(LetterSendSuccess.TryAgain, letterId); player.PlayerView.ShowMessage("Oops, some error happened during sending the Letter.", MessageType.BlueNormal); } // Try to forward it to the player, if he is online var receiverPlayer = this.gameContext.GetPlayerByCharacterName(receiver); if (receiverPlayer != null) { receiverPlayer.PersistenceContext.Attach(letter); receiverPlayer.SelectedCharacter.Letters.Add(letter); receiverPlayer.PlayerView.MessengerView.AddToLetterList(letter, (ushort)(receiverPlayer.SelectedCharacter.Letters.Count - 1), true); } else { this.friendServer.ForwardLetter(letter); } }
/// <summary> /// Deletes the letter. /// </summary> /// <param name="player">The player.</param> /// <param name="letter">The letter.</param> public void DeleteLetter(Player player, LetterHeader letter) { if (letter == null) { Log.WarnFormat("letter is null, player {0}", player.SelectedCharacter.Name); } var letterIndex = player.SelectedCharacter.Letters.IndexOf(letter); player.SelectedCharacter.Letters.RemoveAt(letterIndex); player.PlayerView.MessengerView.LetterDeleted((ushort)letterIndex); // TODO: Deleting it from the repository should not be required. using (this.gameContext.RepositoryManager.UseContext(player.PersistenceContext)) { if (!this.gameContext.RepositoryManager.GetRepository <LetterHeader>().Delete(letter)) { Log.WarnFormat("Player {0} tried to delete a letter, no success. LetterID: {1}", player.SelectedCharacter.Name, letterIndex); } } }
/// <inheritdoc/> public void AddToLetterList(LetterHeader letter, ushort newLetterIndex, bool newLetter) { using (var writer = this.connection.StartSafeWrite(0xC3, 79)) { var result = writer.Span; result[2] = 0xC6; result[4] = newLetterIndex.GetLowByte(); result[5] = newLetterIndex.GetHighByte(); result.Slice(6, 10).WriteString(letter.SenderName, Encoding.UTF8); var date = letter.LetterDate.ToUniversalTime().AddHours(this.player.Account.TimeZone).ToString("yyyy-MM-dd HH:mm:ss"); result.Slice(16, 30).WriteString(date, Encoding.UTF8); result.Slice(46, 32).WriteString(letter.Subject, Encoding.UTF8); result[78] = (byte)(letter.ReadFlag ? 1 : 0); if (result[78] == 1) { result[78] += (byte)(newLetter ? 1 : 0); } writer.Commit(); } }
/// <inheritdoc/> public void AddToLetterList(LetterHeader letter, ushort newLetterIndex, bool newLetter) { var result = new byte[0x6C]; result[0] = 0xC3; result[1] = (byte)result.Length; result[2] = 0xC6; ////4 + 5 == Id result[4] = (byte)(newLetterIndex & 0xFF); result[5] = (byte)((newLetterIndex >> 8) & 0xFF); Buffer.BlockCopy(Encoding.UTF8.GetBytes(letter.Sender.ToCharArray(), 0, letter.Sender.Length), 0, result, 6, Encoding.UTF8.GetByteCount(letter.Sender)); var date = letter.LetterDate.ToUniversalTime().AddHours(this.player.Account.TimeZone).ToString(CultureInfo.InvariantCulture.DateTimeFormat); Buffer.BlockCopy(Encoding.UTF8.GetBytes(date.ToCharArray(), 0, date.Length), 0, result, 16, Encoding.UTF8.GetByteCount(date)); Buffer.BlockCopy(Encoding.UTF8.GetBytes(letter.Subject.ToCharArray(), 0, letter.Subject.Length), 0, result, 46, Encoding.UTF8.GetByteCount(letter.Subject)); result[78] = (byte)(letter.ReadFlag ? 1 : 0); if (result[78] == 1) { result[78] += (byte)(newLetter ? 1 : 0); } this.connection.Send(result); }