96 lines
4.0 KiB
C#
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 });
|
|
}
|
|
}
|