1
0
mirror of https://github.com/deavmi/birchwood synced 2024-09-20 14:43:23 +02:00

Merge branch 'deavmi:master' into master

This commit is contained in:
supremestdoggo 2023-03-15 12:16:44 -04:00 committed by GitHub
commit e785fbf8b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 117 additions and 43 deletions

View File

@ -71,6 +71,10 @@ public class Client : Thread
//TODO: Do something here, tare downs
}
public ConnectionInfo getConnInfo()
{
return connInfo;
}
/**
@ -101,6 +105,8 @@ public class Client : Thread
* User operations (request-response type)
*/
// TODO: Add joinChannels(strung[])
/**
* Joins the requested channel
*
@ -118,7 +124,8 @@ public class Client : Thread
if(channel[0] == '#')
{
/* Join the channel */
sendMessage("JOIN "~channel);
Message joinMessage = new Message("", "JOIN", channel);
sendMessage(joinMessage);
}
else
{
@ -187,7 +194,8 @@ public class Client : Thread
}
/* Leave multiple channels */
sendMessage("PART "~channelLine);
Message leaveMessage = new Message("", "PART", channelLine);
sendMessage(leaveMessage);
}
else
{
@ -212,7 +220,8 @@ public class Client : Thread
// TODO: Add check for valid and non-empty channel names
/* Leave the channel */
sendMessage("PART "~channel);
Message leaveMessage = new Message("", "PART", channel);
sendMessage(leaveMessage);
}
/**
@ -269,7 +278,8 @@ public class Client : Thread
}
/* Send the message */
sendMessage("PRIVMSG "~recipientLine~" "~message);
Message privMessage = new Message("", "PRIVMSG", recipientLine~" "~message);
sendMessage(privMessage);
}
else
{
@ -306,7 +316,8 @@ public class Client : Thread
if(recipient[0] != '#')
{
/* Send the message */
sendMessage("PRIVMSG "~recipient~" "~message);
Message privMessage = new Message("", "PRIVMSG", recipient~" "~message);
sendMessage(privMessage);
}
else
{
@ -373,7 +384,8 @@ public class Client : Thread
}
/* Send to multiple channels */
sendMessage("PRIVMSG "~channelLine~" "~message);
Message privMessage = new Message("", "PRIVMSG", channelLine~" "~message);
sendMessage(privMessage);
}
else
{
@ -408,7 +420,8 @@ public class Client : Thread
if(channel[0] == '#')
{
/* Send the channel message */
sendMessage("PRIVMSG "~channel~" "~message);
Message privMessage = new Message("", "PRIVMSG", channel~" "~message);
sendMessage(privMessage);
}
else
{
@ -431,13 +444,8 @@ public class Client : Thread
*/
public void command(Message message)
{
/* Encode according to EBNF format */
// TODO: Validty check
// TODO: Make `Message.encode()` actually encode instead of empty string
string stringToSend = message.encode();
/* Send the message */
sendMessage(stringToSend);
sendMessage(message);
}
@ -544,8 +552,9 @@ public class Client : Thread
PongEvent pongEvent = cast(PongEvent)e;
assert(pongEvent);
string messageToSend = "PONG "~pongEvent.getID();
client.sendMessage(messageToSend);
// string messageToSend = "PONG "~pongEvent.getID();
Message pongMessage = new Message("", "PONG", pongEvent.getID());
client.sendMessage(pongMessage);
logger.log("Ponged back with "~pongEvent.getID());
}
}
@ -623,28 +632,54 @@ public class Client : Thread
receiver.rq(message);
}
/**
* TODO: Make send queue which is used on another thread to send messages
*
* This allows us to intrpoduce fakelag and also prioritse pongs (we should
* send them via here)
*/
// /**
// * Sends a message to the server by enqueuing it on
// * the client-side send queue
// *
// * Params:
// * messageOut = the message to send
// */
// private void sendMessage(string messageOut)
// {
// // TODO: Do message splits here
// /* Encode the mesage */
// ubyte[] encodedMessage = encodeMessage(messageOut);
// /* Enqueue the message to the send queue */
// sender.sq(encodedMessage);
// }
/**
* Sends a message to the server by enqueuing it on
* the client-side send queue
* the client-side send queue.
*
* A BirchwoodException is thrown if the messages
* final length exceeds 512 bytes
*
* Params:
* messageOut = the message to send
* message = the message to send
*/
private void sendMessage(string messageOut)
private void sendMessage(Message message)
{
/* Encode the mesage */
ubyte[] encodedMessage = encodeMessage(messageOut);
// TODO: Do message splits here
/* Encode the message */
ubyte[] encodedMessage = encodeMessage(message.encode());
/* If the message is 512 bytes or less then send */
if(encodedMessage.length <= 512)
{
/* Enqueue the message to the send queue */
sender.sq(encodedMessage);
}
/* If above then throw an exception */
else
{
throw new BirchwoodException(BirchwoodException.ErrorType.COMMAND_TOO_LONG);
}
}
/**
* Disconnect from the IRC server gracefully
@ -653,7 +688,7 @@ public class Client : Thread
{
/* Generate the quit command using the custom quit message */
Message quitCommand = new Message("", "QUIT", connInfo.quitMessage);
sendMessage(quitCommand.encode());
sendMessage(quitCommand);
/* TODO: I don't know how long we should wait here */
Thread.sleep(dur!("seconds")(1));
@ -830,6 +865,12 @@ public class Client : Thread
}
}
version(unittest)
{
import core.thread;
}
unittest
{
/* FIXME: Get domaina name resolution support */
@ -837,15 +878,19 @@ public class Client : Thread
//freenode: 149.28.246.185
//snootnet: 178.62.125.123
//bonobonet: fd08:8441:e254::5
ConnectionInfo connInfo = ConnectionInfo.newConnection("worcester.community.deavmi.crxn", 6667, "testBirchwood");
ConnectionInfo connInfo = ConnectionInfo.newConnection("worcester.community.networks.deavmi.assigned.network", 6667, "testBirchwood");
// // Set the fakelag to 1 second
// connInfo.setFakeLag(1);
// Create a new Client
Client client = new Client(connInfo);
client.connect();
import core.thread;
Thread.sleep(dur!("seconds")(2));
client.command(new Message("", "NICK", "birchwood"));
client.command(new Message("", "NICK", "birchwood")); // TODO: add nickcommand
Thread.sleep(dur!("seconds")(2));
client.command(new Message("", "USER", "doggie doggie irc.frdeenode.net :Tristan B. Kildaire"));
@ -860,13 +905,13 @@ public class Client : Thread
client.joinChannel("#birchwoodLeave3");
Thread.sleep(dur!("seconds")(2));
client.command(new Message("", "NAMES", ""));
client.command(new Message("", "NAMES", "")); // TODO: add names commdn
Thread.sleep(dur!("seconds")(2));
client.command(new Message("", "PRIVMSG", "#birchwood naai"));
client.channelMessage("naai", "#birchwood");
Thread.sleep(dur!("seconds")(2));
client.command(new Message("", "PRIVMSG", "deavmi naai"));
client.directMessage("naai", "deavmi");
/**

View File

@ -13,7 +13,8 @@ public class BirchwoodException : Exception
EMPTY_PARAMS,
INVALID_CHANNEL_NAME,
INVALID_NICK_NAME,
ILLEGAL_CHARACTERS
ILLEGAL_CHARACTERS,
COMMAND_TOO_LONG
}
private ErrorType errType;

View File

@ -126,10 +126,14 @@ public final class ReceiverThread : Thread
ulong pos = 0;
foreach(ubyte[] message; recvQueue[])
{
// FIXME: Holy shit this is funny (see https://github.com/deavmi/birchwood/issues/13)
if(indexOf(cast(string)message, "PING") > -1)
{
pingMessage = message;
recvQueue.linearRemoveElement(message);
import std.stdio;
writeln("\n\nHOLY SHIT\n: "~cast(string)(message)~"\n\n");
break;
}

View File

@ -79,9 +79,6 @@ public final class SenderThread : Thread
*/
private void sendHandlerFunc()
{
/* TODO: Hoist up into ConnInfo */
ulong fakeLagInBetween = 1;
while(client.running)
{
// // Do a once-off call to `ensure()` here which then only runs once and
@ -115,7 +112,7 @@ public final class SenderThread : Thread
foreach(ubyte[] message; sendQueue[])
{
client.socket.send(message);
Thread.sleep(dur!("seconds")(fakeLagInBetween));
Thread.sleep(dur!("seconds")(client.getConnInfo().getFakeLag()));
}
/* Empty the send queue */

View File

@ -14,7 +14,7 @@ public struct ConnectionInfo
private ulong bulkReadSize;
/* Client behaviour (TODO: what is sleep(0), like nothing) */
private ulong fakeLag = 0;
private ulong fakeLag;
/* The quit message */
public const string quitMessage;
@ -26,6 +26,9 @@ public struct ConnectionInfo
this.nickname = nickname;
this.bulkReadSize = bulkReadSize;
this.quitMessage = quitMessage;
// Set the default fakelag to 1
this.fakeLag = 1;
}
public ulong getBulkReadSize()
@ -38,6 +41,16 @@ public struct ConnectionInfo
return addrInfo;
}
public ulong getFakeLag()
{
return fakeLag;
}
public void setFakeLag(ulong fakeLag)
{
this.fakeLag = fakeLag;
}
/**
* Creates a ConnectionInfo struct representing a client configuration which
* can be provided to the Client class to create a new connection based on its

View File

@ -0,0 +1,2 @@
module birchwood.protocol.formatting;

View File

@ -30,7 +30,16 @@ __gshared static this()
/**
* Encoding/decoding primitives
*/
public static ubyte[] encodeMessage(string messageIn)
/**
* Encodes the provided message into a CRLF
* terminated byte array
*
* Params:
* messageIn = the message to encode
* Returns: the encoded message
*/
public ubyte[] encodeMessage(string messageIn)
{
ubyte[] messageOut = cast(ubyte[])messageIn;
messageOut~=[cast(ubyte)13, cast(ubyte)10];

View File

@ -1,3 +1,6 @@
module birchwood.protocol;
public import birchwood.protocol.messages : Message;
// TODO: Look how to neaten up (if any)
public import birchwood.protocol.formatting;