mirror of https://github.com/deavminet/dnetd.git
Added 'join' command
This commit is contained in:
parent
78a571ae67
commit
7e1e361c21
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* DChannel
|
||||
*
|
||||
* Represents a channel and its
|
||||
* associated information such
|
||||
* as its name, topic, members
|
||||
*/
|
||||
|
||||
module dnetd.dchannel;
|
||||
|
||||
import dnetd.dconnection : DConnection;
|
||||
|
||||
public class DChannel
|
||||
{
|
||||
/**
|
||||
* Channel information
|
||||
*/
|
||||
private string name;
|
||||
//private string topic;
|
||||
|
||||
/**
|
||||
* Users in this channel
|
||||
*/
|
||||
private DConnection[] members;
|
||||
|
||||
this(string name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public string getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void join(DConnection client)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -15,12 +15,16 @@ import std.socket : Socket;
|
|||
import bmessage;
|
||||
import tristanable.encoding : DataMessage;
|
||||
import core.sync.mutex : Mutex;
|
||||
import dnetd.dserver : DServer;
|
||||
import std.string : split;
|
||||
import dnetd.dchannel : DChannel;
|
||||
|
||||
public class DConnection : Thread
|
||||
{
|
||||
/**
|
||||
* Connection information
|
||||
*/
|
||||
private DServer server;
|
||||
private Socket socket;
|
||||
private bool hasAuthed;
|
||||
|
||||
|
@ -34,11 +38,14 @@ public class DConnection : Thread
|
|||
/* Reserved tag for push notifications */
|
||||
private long notificationTag = 0;
|
||||
|
||||
this(Socket socket)
|
||||
this(DServer server, Socket socket)
|
||||
{
|
||||
/* Set the function to be called on thread start */
|
||||
super(&worker);
|
||||
|
||||
/* Set the associated server */
|
||||
this.server = server;
|
||||
|
||||
/* Set the socket */
|
||||
this.socket = socket;
|
||||
|
||||
|
@ -94,12 +101,19 @@ public class DConnection : Thread
|
|||
|
||||
/**
|
||||
* Write to socket
|
||||
*
|
||||
* Encodes the byte array as a tristanable tagged
|
||||
* message and then encodes that as a bformat
|
||||
* message
|
||||
*
|
||||
* Locks the writeLock mutex, sends it over the
|
||||
* socket to the client/server, and unlocks the
|
||||
* mutex
|
||||
*/
|
||||
private void writeSocket(long tag, byte[] data)
|
||||
private bool writeSocket(long tag, byte[] data)
|
||||
{
|
||||
/* TODO: Implement me */
|
||||
|
||||
|
||||
/* Send status */
|
||||
bool status;
|
||||
|
||||
/* Create the tagged message */
|
||||
DataMessage message = new DataMessage(tag, data);
|
||||
|
@ -107,14 +121,13 @@ public class DConnection : Thread
|
|||
/* Lock the write mutex */
|
||||
writeLock.lock();
|
||||
|
||||
/* TODO: Do send */
|
||||
|
||||
bool status = sendMessage(socket, message.encode());
|
||||
|
||||
/* TODO: use status */
|
||||
/* Send the message */
|
||||
status = sendMessage(socket, message.encode());
|
||||
|
||||
/* Unlock the write mutex */
|
||||
writeLock.unlock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
@ -144,15 +157,48 @@ public class DConnection : Thread
|
|||
bool status = authenticate(username, password);
|
||||
|
||||
/* Encode the reply */
|
||||
byte[] reply = [1, status];
|
||||
byte[] reply = [status];
|
||||
|
||||
/* TODO: Implement me */
|
||||
/* TODO: Implement me, use return value */
|
||||
writeSocket(tag, reply);
|
||||
}
|
||||
/* If `link` command (requires: unauthed) */
|
||||
else if(commandByte == 1 && !hasAuthed)
|
||||
{
|
||||
|
||||
}
|
||||
/* */
|
||||
else if(commandByte == 2 && !hasAuthed)
|
||||
{
|
||||
|
||||
}
|
||||
/* If `join` command (requires: authed) */
|
||||
else if(commandByte == 3 && !hasAuthed)
|
||||
{
|
||||
/* Get the channel names */
|
||||
string channelList = cast(string)message.data[1..message.data.length];
|
||||
string[] channels = split(channelList, ",");
|
||||
|
||||
/**
|
||||
* Loop through each channel, check if it
|
||||
* exists, if so join it, else create it
|
||||
* and then join it
|
||||
*/
|
||||
foreach(string channelName; channels)
|
||||
{
|
||||
/* Attempt to find the channel */
|
||||
DChannel channel = server.getChannelByName(channelName);
|
||||
|
||||
/* Create the channel if it doesn't exist */
|
||||
if(channel is null)
|
||||
{
|
||||
/* TODO: Thread safety for name choice */
|
||||
channel = new DChannel(channelName);
|
||||
}
|
||||
|
||||
/* Join the channel */
|
||||
channel.join(this);
|
||||
}
|
||||
}
|
||||
/* TODO: Handle this case */
|
||||
else
|
||||
|
|
|
@ -13,6 +13,9 @@ module dnetd.dserver;
|
|||
import core.thread : Thread;
|
||||
import std.socket : Address, Socket;
|
||||
import dnetd.dconnection;
|
||||
import dnetd.dchannel;
|
||||
import std.string : cmp;
|
||||
import core.sync.mutex : Mutex;
|
||||
|
||||
public class DServer : Thread
|
||||
{
|
||||
|
@ -28,6 +31,12 @@ public class DServer : Thread
|
|||
*/
|
||||
private DConnection[] connectionQueue;
|
||||
|
||||
/**
|
||||
* Channels
|
||||
*/
|
||||
private DChannel[] channels;
|
||||
private Mutex channelLock;
|
||||
|
||||
this(Address sockAddress)
|
||||
{
|
||||
/* Set the function to be called on thread start */
|
||||
|
@ -50,6 +59,9 @@ public class DServer : Thread
|
|||
|
||||
/* Setup queues */
|
||||
initQueues();
|
||||
|
||||
/* Setup locks */
|
||||
initLocks();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -74,6 +86,12 @@ public class DServer : Thread
|
|||
/* TODO: Implement me */
|
||||
}
|
||||
|
||||
private void initLocks()
|
||||
{
|
||||
/* Initialioze the channel lock */
|
||||
channelLock = new Mutex();
|
||||
}
|
||||
|
||||
private void startServer()
|
||||
{
|
||||
/* Start the connection dequeue thread */
|
||||
|
@ -91,10 +109,42 @@ public class DServer : Thread
|
|||
Socket socket = serverSocket.accept();
|
||||
|
||||
/* Spawn a connection handler */
|
||||
DConnection connection = new DConnection(socket);
|
||||
DConnection connection = new DConnection(this, socket);
|
||||
|
||||
/* Add to the connection queue */
|
||||
connectionQueue ~= connection;
|
||||
}
|
||||
}
|
||||
|
||||
public void addChannel(DConnection causer, DChannel channel)
|
||||
{
|
||||
/* Lock the channels list */
|
||||
channelLock.lock();
|
||||
|
||||
channels ~= channel;
|
||||
|
||||
/* TODO: Use causer */
|
||||
|
||||
/* Unlock the channels list */
|
||||
channelLock.unlock();
|
||||
}
|
||||
|
||||
public DChannel getChannelByName(string channelName)
|
||||
{
|
||||
/* Lock the channels list */
|
||||
channelLock.lock();
|
||||
|
||||
foreach(DChannel currentChannel; channels)
|
||||
{
|
||||
if(cmp(currentChannel.getName(), channelName) == 0)
|
||||
{
|
||||
return currentChannel;
|
||||
}
|
||||
}
|
||||
|
||||
/* Unlock the channels list */
|
||||
channelLock.unlock();
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue