Files
MVP1/Assets/Scripts/Social/ChatService.cs
T

96 lines
4.0 KiB
C#

using System;
using System.Collections.Generic;
public enum ChatChannel
{
World, // общий чат всего мира
Circle // чат своего Круга
}
[Serializable]
public class ChatMessage
{
public ChatChannel channel;
public string senderId;
public string senderName;
public string text;
public long timeMs; // Unix-время в миллисекундах
}
// История чата. Обычный класс со статическим экземпляром -- переживает смену сцен,
// поэтому переписка не теряется при переходе город <-> карта. Пока всё локально;
// когда появится сервер, Send будет отправлять сообщение туда, а входящие -- приходить через MessageReceived.
public class ChatService
{
public const int MaxMessageLength = 200;
public const int MaxStoredPerChannel = 100;
// Пока аккаунтов нет -- одно имя для локального игрока
public const string LocalPlayerName = "Богатырь";
private static ChatService instance;
public static ChatService Instance => instance ??= new ChatService(MarchManager.NowMs);
public event Action<ChatMessage> MessageReceived;
private readonly Dictionary<ChatChannel, List<ChatMessage>> history = new Dictionary<ChatChannel, List<ChatMessage>>
{
{ ChatChannel.World, new List<ChatMessage>() },
{ ChatChannel.Circle, new List<ChatMessage>() }
};
ChatService(long nowMs)
{
SeedDemoMessages(nowMs);
}
public IReadOnlyList<ChatMessage> GetMessages(ChatChannel channel)
{
return history[channel];
}
public bool Send(ChatChannel channel, string text)
{
text = text?.Trim();
if (string.IsNullOrEmpty(text)) return false;
if (text.Length > MaxMessageLength) text = text.Substring(0, MaxMessageLength);
Add(new ChatMessage
{
channel = channel,
senderId = MarchManager.LocalPlayerId,
senderName = LocalPlayerName,
text = text,
timeMs = MarchManager.NowMs
});
return true;
}
void Add(ChatMessage message)
{
List<ChatMessage> list = history[message.channel];
list.Add(message);
if (list.Count > MaxStoredPerChannel) list.RemoveAt(0);
MessageReceived?.Invoke(message);
}
// Несколько сообщений "от других игроков", чтобы чат не был пустым. Уберётся с приходом сервера.
void SeedDemoMessages(long nowMs)
{
const long minute = 60_000;
AddDemo(ChatChannel.World, "npc_sever", "Север", "Кто идёт на Змея Горыныча?", nowMs - 5 * minute);
AddDemo(ChatChannel.World, "npc_dreadwolf", "DreadWolf", "Набор в Круг, нужны активные игроки!", nowMs - 4 * minute);
AddDemo(ChatChannel.World, "npc_moroz", "Мороз", "На западе замечен Круг Стальные Волки.", nowMs - 3 * minute);
AddDemo(ChatChannel.World, "npc_tairon", "Тайрон", "Собираем отряд на древний храм.", nowMs - 2 * minute);
AddDemo(ChatChannel.World, "npc_veles", "Велес", "Всем удачной охоты!", nowMs - minute);
AddDemo(ChatChannel.Circle, "npc_ratibor", "Ратибор", "Братья, завтра вместе идём на замок.", nowMs - 10 * minute);
AddDemo(ChatChannel.Circle, "npc_svetozar", "Светозар", "Скиньте еды в казну Круга, кому не жалко.", nowMs - 6 * minute);
}
void AddDemo(ChatChannel channel, string id, string name, string text, long timeMs)
{
history[channel].Add(new ChatMessage { channel = channel, senderId = id, senderName = name, text = text, timeMs = timeMs });
}
}