156 lines
3.8 KiB
C#
156 lines
3.8 KiB
C#
using Castle.DynamicProxy.Generators.Emitters.SimpleAST;
|
|
using NLog;
|
|
|
|
namespace ChatRoom;
|
|
|
|
public class ChatRoomLogic
|
|
{
|
|
private Thread thread;
|
|
private ChatRoomState state = new ChatRoomState();
|
|
private Logger log = LogManager.GetCurrentClassLogger();
|
|
|
|
|
|
public ChatRoomLogic()
|
|
{
|
|
thread = new Thread(BackgroundTask);
|
|
thread.Start();
|
|
}
|
|
|
|
int NextId()
|
|
{
|
|
int id = state.lastUniqueId;
|
|
state.lastUniqueId++;
|
|
return id;
|
|
}
|
|
|
|
public int RegisterClient(string name)
|
|
{
|
|
lock (state.accessLock)
|
|
{
|
|
int clientId = NextId();
|
|
state.clients.Add(new Client
|
|
{
|
|
id = clientId,
|
|
name = name
|
|
});
|
|
log.Info($"Registered with client '{name}' with id {clientId}");
|
|
return clientId;
|
|
}
|
|
}
|
|
|
|
Client? FindClientById(int clientId)
|
|
{
|
|
foreach (var client in state.clients)
|
|
{
|
|
if (client.id == clientId)
|
|
{
|
|
return client;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
Message? FindMessageById(int messageId)
|
|
{
|
|
foreach (var message in state.messages)
|
|
{
|
|
if (message.id == messageId)
|
|
{
|
|
return message;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public bool SendMessage(int clientId, string contents, bool needsToBeCensored)
|
|
{
|
|
lock (state.accessLock)
|
|
{
|
|
var client = FindClientById(clientId);
|
|
if (client == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (client.blockedUntil != null)
|
|
{
|
|
if (DateTime.UtcNow < client.blockedUntil)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
client.blockedUntil = null;
|
|
}
|
|
}
|
|
|
|
var message = new Message
|
|
{
|
|
id = NextId(),
|
|
clientId = clientId,
|
|
contents = contents,
|
|
needsToBeCensored = needsToBeCensored,
|
|
status = MessageStatus.WaitingForModerator
|
|
};
|
|
state.messages.Add(message);
|
|
log.Info($"Client '{client.name}' ({client.id}) sent message '{contents}' ({message.id}). Needs to censored: {needsToBeCensored}");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public ChatRoomContract.Message? GetNewMessage()
|
|
{
|
|
lock (state.accessLock)
|
|
{
|
|
foreach (var message in state.messages)
|
|
{
|
|
if (message.status != MessageStatus.WaitingForModerator) continue;
|
|
|
|
message.status = MessageStatus.GivenToModerator;
|
|
return new ChatRoomContract.Message{
|
|
id = message.id,
|
|
contents = message.contents,
|
|
needsToBeCensored = message.needsToBeCensored
|
|
};
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public void ApproveMessage(int messageId)
|
|
{
|
|
lock (state.accessLock)
|
|
{
|
|
var message = FindMessageById(messageId);
|
|
if (message == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (message.status != MessageStatus.GivenToModerator)
|
|
{
|
|
return;
|
|
}
|
|
|
|
message.status = MessageStatus.Approved;
|
|
log.Info($"Message {message.id} was approved");
|
|
}
|
|
}
|
|
|
|
public void BackgroundTask()
|
|
{
|
|
while (true)
|
|
{
|
|
lock (state.accessLock)
|
|
{
|
|
int count = state.messages.RemoveAll(msg => msg.status == MessageStatus.Approved || msg.status == MessageStatus.Rejected);
|
|
log.Info($"Running periodic cleanup, removed {count} messages");
|
|
}
|
|
|
|
Thread.Sleep(10 * 1000);
|
|
}
|
|
}
|
|
}
|