From a42d913236b808d34f06606d409338ff7b6b2fc9 Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Wed, 15 Mar 2023 17:13:30 +0200 Subject: [PATCH 1/2] Receiver - Parse all messages into a `Message` array (`SList`) - If a PING is found then we put it aside and check if we have one and then reply - The PING is removed and all normal messages remain and then get EVenty events triggered for them for `IRCEvent` --- source/birchwood/client/receiver.d | 117 ++++++++++++++--------------- 1 file changed, 57 insertions(+), 60 deletions(-) diff --git a/source/birchwood/client/receiver.d b/source/birchwood/client/receiver.d index 93be2e8..4cbfbdc 100644 --- a/source/birchwood/client/receiver.d +++ b/source/birchwood/client/receiver.d @@ -117,29 +117,62 @@ public final class ReceiverThread : Thread /* Lock the receieve queue */ recvQueueLock.lock(); - /* Message being analysed */ - Message curMsg; + /* Parsed messages */ + SList!(Message) currentMessageQueue; - /* Search for a PING */ - ubyte[] pingMessage; - - ulong pos = 0; + /** + * Parse all messages and save them + * into the above array + */ 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); + /* Decode the message */ + string decodedMessage = decodeMessage(message); - import std.stdio; - writeln("\n\nHOLY SHIT\n: "~cast(string)(message)~"\n\n"); + /* Parse the message */ + Message parsedMessage = Message.parseReceivedMessage(decodedMessage); + + /* Save it */ + currentMessageQueue.insertAfter(currentMessageQueue[], parsedMessage); + } + + + /** + * Search for any PING messages, then store it if so + * and remove it so it isn't processed again later + */ + Message pingMessage; + foreach(Message curMsg; currentMessageQueue[]) + { + import std.string : cmp; + if(cmp(curMsg.getCommand(), "PING") == 0) + { + currentMessageQueue.linearRemoveElement(curMsg); + pingMessage = curMsg; break; } - - pos++; } + /** + * If we have a PING then respond with a PONG + */ + if(pingMessage !is null) + { + logger.log("Found a ping: "~pingMessage.toString()); + + /* Extract the PING ID */ + string pingID = pingMessage.getParams(); + + /* Spawn a PONG event */ + EventyEvent pongEvent = new PongEvent(pingID); + client.engine.push(pongEvent); + } + + + + + + /** * TODO: Plan of action @@ -156,61 +189,25 @@ public final class ReceiverThread : Thread * - we can cache or remember stuff when we get 353 */ - - - - /* If we found a PING */ - if(pingMessage.length > 0) - { - /* Decode the message and parse it */ - curMsg = Message.parseReceivedMessage(decodeMessage(pingMessage)); - logger.log("Found a ping: "~curMsg.toString()); - - // string ogMessage = cast(string)pingMessage; - // long idxSigStart = indexOf(ogMessage, ":")+1; - // long idxSigEnd = lastIndexOf(ogMessage, '\r'); - - // string pingID = ogMessage[idxSigStart..idxSigEnd]; - string pingID = curMsg.getParams(); - - - // this.socket.send(encodeMessage("PONG "~pingID)); - // string messageToSend = "PONG "~pingID; - - // sendMessage(messageToSend); - - // logger.log("Ponged"); - - /* TODO: Implement */ - // TODO: Remove the Eventy push and replace with a handler call (on second thought no) - EventyEvent pongEvent = new PongEvent(pingID); - client.engine.push(pongEvent); - } - /** * Process each message remaining in the queue now * till it is empty */ - while(!recvQueue.empty()) + while(!currentMessageQueue.empty()) { - ubyte[] message = recvQueue.front(); - - /* Decode message */ - string messageNormal = decodeMessage(message); - - recvQueue.linearRemoveElement(recvQueue.front()); - - // writeln("Normal message: "~messageNormal); - - - - /* TODO: Parse message and call correct handler */ - curMsg = Message.parseReceivedMessage(messageNormal); + /* Get the frontmost Message */ + Message curMsg = currentMessageQueue.front(); // TODO: Remove the Eventy push and replace with a handler call (on second thought no) EventyEvent ircEvent = new IRCEvent(curMsg); client.engine.push(ircEvent); + + /* Remove the message from the queue */ + currentMessageQueue.linearRemoveElement(curMsg); } + + /* Clear the receive queue */ + recvQueue.clear(); /* Unlock the receive queue */ recvQueueLock.unlock(); From 2a50c8efbb2238a827807422c4f4b4268b87b26f Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Wed, 15 Mar 2023 17:15:25 +0200 Subject: [PATCH 2/2] Unit tests - Switch back to my IPv6-only server for testing --- source/birchwood/client/client.d | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/birchwood/client/client.d b/source/birchwood/client/client.d index 3050b7c..eb3baff 100644 --- a/source/birchwood/client/client.d +++ b/source/birchwood/client/client.d @@ -873,12 +873,11 @@ public class Client : Thread unittest { - /* FIXME: Get domaina name resolution support */ - ConnectionInfo connInfo = ConnectionInfo.newConnection("irc.freenode.net", 6667, "testBirchwood"); + // ConnectionInfo connInfo = ConnectionInfo.newConnection("irc.freenode.net", 6667, "testBirchwood"); //freenode: 149.28.246.185 //snootnet: 178.62.125.123 //bonobonet: fd08:8441:e254::5 - // ConnectionInfo connInfo = ConnectionInfo.newConnection("worcester.community.networks.deavmi.assigned.network", 6667, "testBirchwood"); + ConnectionInfo connInfo = ConnectionInfo.newConnection("worcester.community.networks.deavmi.assigned.network", 6667, "testBirchwood"); // // Set the fakelag to 1 second // connInfo.setFakeLag(1);