mirror of
https://github.com/deavmi/birchwood
synced 2024-09-20 07:43:55 +02:00
Merge branch 'master' into feature/splits
This commit is contained in:
commit
97790046aa
@ -241,7 +241,7 @@ public class Client : Thread
|
|||||||
public void nick(string nickname)
|
public void nick(string nickname)
|
||||||
{
|
{
|
||||||
/* Ensure no illegal characters in nick name */
|
/* Ensure no illegal characters in nick name */
|
||||||
if(isValidText(nickname))
|
if(textPass(nickname))
|
||||||
{
|
{
|
||||||
// TODO: We could investigate this later if we want to be safer
|
// TODO: We could investigate this later if we want to be safer
|
||||||
ulong maxNickLen = connInfo.getDB!(ulong)("MAXNICKLEN");
|
ulong maxNickLen = connInfo.getDB!(ulong)("MAXNICKLEN");
|
||||||
@ -276,7 +276,7 @@ public class Client : Thread
|
|||||||
public void joinChannel(string channel)
|
public void joinChannel(string channel)
|
||||||
{
|
{
|
||||||
/* Ensure no illegal characters in channel name */
|
/* Ensure no illegal characters in channel name */
|
||||||
if(isValidText(channel))
|
if(textPass(channel))
|
||||||
{
|
{
|
||||||
/* Channel name must start with a `#` */
|
/* Channel name must start with a `#` */
|
||||||
if(channel[0] == '#')
|
if(channel[0] == '#')
|
||||||
@ -296,6 +296,46 @@ public class Client : Thread
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provided with a reference to a string
|
||||||
|
* this will check to see if it contains
|
||||||
|
* any illegal characters and then if so
|
||||||
|
* it will strip them if the `ChecksMode`
|
||||||
|
* is set to `EASY` (and return `true`)
|
||||||
|
* else it will return `false` if set to
|
||||||
|
* `HARDCORE` whilst illegal characters
|
||||||
|
* are present.
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
* text = the ref'd `string`
|
||||||
|
* Returns: `true` if validated, `false`
|
||||||
|
* otherwise
|
||||||
|
*/
|
||||||
|
private bool textPass(ref string text)
|
||||||
|
{
|
||||||
|
/* If there are any invalid characters */
|
||||||
|
if(Message.hasIllegalCharacters(text))
|
||||||
|
{
|
||||||
|
import birchwood.config.conninfo : ChecksMode;
|
||||||
|
if(connInfo.getMode() == ChecksMode.EASY)
|
||||||
|
{
|
||||||
|
// Filter the text and update it in-place
|
||||||
|
text = Message.stripIllegalCharacters(text);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* If there are no invalid characters prewsent */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Joins the requested channels
|
* Joins the requested channels
|
||||||
*
|
*
|
||||||
@ -319,7 +359,7 @@ public class Client : Thread
|
|||||||
string channelLine = channels[0];
|
string channelLine = channels[0];
|
||||||
|
|
||||||
/* Ensure valid characters in first channel */
|
/* Ensure valid characters in first channel */
|
||||||
if(isValidText(channelLine))
|
if(textPass(channelLine))
|
||||||
{
|
{
|
||||||
//TODO: Add check for #
|
//TODO: Add check for #
|
||||||
|
|
||||||
@ -331,7 +371,7 @@ public class Client : Thread
|
|||||||
string currentChannel = channels[i];
|
string currentChannel = channels[i];
|
||||||
|
|
||||||
/* Ensure the character channel is valid */
|
/* Ensure the character channel is valid */
|
||||||
if(isValidText(currentChannel))
|
if(textPass(currentChannel))
|
||||||
{
|
{
|
||||||
//TODO: Add check for #
|
//TODO: Add check for #
|
||||||
|
|
||||||
@ -391,7 +431,7 @@ public class Client : Thread
|
|||||||
string channelLine = channels[0];
|
string channelLine = channels[0];
|
||||||
|
|
||||||
/* Ensure valid characters in first channel */
|
/* Ensure valid characters in first channel */
|
||||||
if(isValidText(channelLine))
|
if(textPass(channelLine))
|
||||||
{
|
{
|
||||||
//TODO: Add check for #
|
//TODO: Add check for #
|
||||||
|
|
||||||
@ -403,7 +443,7 @@ public class Client : Thread
|
|||||||
string currentChannel = channels[i];
|
string currentChannel = channels[i];
|
||||||
|
|
||||||
/* Ensure the character channel is valid */
|
/* Ensure the character channel is valid */
|
||||||
if(isValidText(currentChannel))
|
if(textPass(currentChannel))
|
||||||
{
|
{
|
||||||
//TODO: Add check for #
|
//TODO: Add check for #
|
||||||
|
|
||||||
@ -450,7 +490,7 @@ public class Client : Thread
|
|||||||
public void leaveChannel(string channel)
|
public void leaveChannel(string channel)
|
||||||
{
|
{
|
||||||
/* Ensure the channel name contains only valid characters */
|
/* Ensure the channel name contains only valid characters */
|
||||||
if(isValidText(channel))
|
if(textPass(channel))
|
||||||
{
|
{
|
||||||
/* Leave the channel */
|
/* Leave the channel */
|
||||||
Message leaveMessage = new Message("", "PART", channel);
|
Message leaveMessage = new Message("", "PART", channel);
|
||||||
@ -487,12 +527,12 @@ public class Client : Thread
|
|||||||
else if(recipients.length > 1)
|
else if(recipients.length > 1)
|
||||||
{
|
{
|
||||||
/* Ensure message is valid */
|
/* Ensure message is valid */
|
||||||
if(isValidText(message))
|
if(textPass(message))
|
||||||
{
|
{
|
||||||
string recipientLine = recipients[0];
|
string recipientLine = recipients[0];
|
||||||
|
|
||||||
/* Ensure valid characters in first recipient */
|
/* Ensure valid characters in first recipient */
|
||||||
if(isValidText(recipientLine))
|
if(textPass(recipientLine))
|
||||||
{
|
{
|
||||||
/* Append on a trailing `,` */
|
/* Append on a trailing `,` */
|
||||||
recipientLine ~= ",";
|
recipientLine ~= ",";
|
||||||
@ -502,7 +542,7 @@ public class Client : Thread
|
|||||||
string currentRecipient = recipients[i];
|
string currentRecipient = recipients[i];
|
||||||
|
|
||||||
/* Ensure valid characters in the current recipient */
|
/* Ensure valid characters in the current recipient */
|
||||||
if(isValidText(currentRecipient))
|
if(textPass(currentRecipient))
|
||||||
{
|
{
|
||||||
if(i == recipients.length-1)
|
if(i == recipients.length-1)
|
||||||
{
|
{
|
||||||
@ -555,7 +595,7 @@ public class Client : Thread
|
|||||||
// TODO: Chunked sends when over limit of `message`
|
// TODO: Chunked sends when over limit of `message`
|
||||||
|
|
||||||
/* Ensure the message and recipient are valid text */
|
/* Ensure the message and recipient are valid text */
|
||||||
if(isValidText(message) && isValidText(recipient))
|
if(textPass(message) && textPass(recipient))
|
||||||
{
|
{
|
||||||
/* Ensure the recipient does NOT start with a # (as that is reserved for channels) */
|
/* Ensure the recipient does NOT start with a # (as that is reserved for channels) */
|
||||||
if(recipient[0] != '#')
|
if(recipient[0] != '#')
|
||||||
@ -598,12 +638,12 @@ public class Client : Thread
|
|||||||
else if(channels.length > 1)
|
else if(channels.length > 1)
|
||||||
{
|
{
|
||||||
/* Ensure message is valid */
|
/* Ensure message is valid */
|
||||||
if(isValidText(message))
|
if(textPass(message))
|
||||||
{
|
{
|
||||||
string channelLine = channels[0];
|
string channelLine = channels[0];
|
||||||
|
|
||||||
/* Ensure valid characters in first channel */
|
/* Ensure valid characters in first channel */
|
||||||
if(isValidText(channelLine))
|
if(textPass(channelLine))
|
||||||
{
|
{
|
||||||
/* Append on a trailing `,` */
|
/* Append on a trailing `,` */
|
||||||
channelLine ~= ",";
|
channelLine ~= ",";
|
||||||
@ -613,7 +653,7 @@ public class Client : Thread
|
|||||||
string currentChannel = channels[i];
|
string currentChannel = channels[i];
|
||||||
|
|
||||||
/* Ensure valid characters in current channel */
|
/* Ensure valid characters in current channel */
|
||||||
if(isValidText(currentChannel))
|
if(textPass(currentChannel))
|
||||||
{
|
{
|
||||||
if(i == channels.length-1)
|
if(i == channels.length-1)
|
||||||
{
|
{
|
||||||
@ -667,7 +707,7 @@ public class Client : Thread
|
|||||||
|
|
||||||
//TODO: Add check on recipient
|
//TODO: Add check on recipient
|
||||||
//TODO: Add emptiness check
|
//TODO: Add emptiness check
|
||||||
if(isValidText(message) && isValidText(channel))
|
if(textPass(message) && textPass(channel))
|
||||||
{
|
{
|
||||||
if(channel[0] == '#')
|
if(channel[0] == '#')
|
||||||
{
|
{
|
||||||
@ -925,7 +965,7 @@ public class Client : Thread
|
|||||||
{
|
{
|
||||||
// TODO: Implement me properly with all required checks
|
// TODO: Implement me properly with all required checks
|
||||||
|
|
||||||
if(isValidText(username) && isValidText(hostname) && isValidText(servername) && isValidText(realname))
|
if(textPass(username) && textPass(hostname) && textPass(servername) && textPass(realname))
|
||||||
{
|
{
|
||||||
/* User message */
|
/* User message */
|
||||||
Message userMessage = new Message("", "USER", username~" "~hostname~" "~servername~" "~":"~realname);
|
Message userMessage = new Message("", "USER", username~" "~hostname~" "~servername~" "~":"~realname);
|
||||||
@ -954,16 +994,20 @@ public class Client : Thread
|
|||||||
* Sends a message to the server by enqueuing it on
|
* Sends a message to the server by enqueuing it on
|
||||||
* the client-side send queue.
|
* the client-side send queue.
|
||||||
*
|
*
|
||||||
|
* Any invalid characters will be stripped prior
|
||||||
|
* to encoding IF `ChecksMode` is set to `EASY` (default)
|
||||||
|
*
|
||||||
* Params:
|
* Params:
|
||||||
* message = the message to send
|
* message = the message to send
|
||||||
* Throws:
|
* Throws:
|
||||||
* `BirchwoodException` if the message's length
|
* A `BirchwoodException` is thrown if the messages
|
||||||
* exceeds 512 bytes
|
* final length exceeds 512 bytes of if `ChecksMode`
|
||||||
|
* is set to `HARDCORE`
|
||||||
*/
|
*/
|
||||||
private void sendMessage(Message message)
|
private void sendMessage(Message message)
|
||||||
{
|
{
|
||||||
/* Encode the message */
|
/* Encode the message */
|
||||||
ubyte[] encodedMessage = encodeMessage(message.encode());
|
ubyte[] encodedMessage = encodeMessage(message.encode(connInfo.getMode()));
|
||||||
|
|
||||||
/* If the message is 512 bytes or less then send */
|
/* If the message is 512 bytes or less then send */
|
||||||
if(encodedMessage.length <= 512)
|
if(encodedMessage.length <= 512)
|
||||||
@ -1265,8 +1309,8 @@ public class Client : Thread
|
|||||||
//bonobonet: fd08:8441:e254::5
|
//bonobonet: fd08:8441:e254::5
|
||||||
ConnectionInfo connInfo = ConnectionInfo.newConnection("worcester.community.networks.deavmi.assigned.network", 6667, "birchwood", "doggie", "Tristan B. Kildaire");
|
ConnectionInfo connInfo = ConnectionInfo.newConnection("worcester.community.networks.deavmi.assigned.network", 6667, "birchwood", "doggie", "Tristan B. Kildaire");
|
||||||
|
|
||||||
// // Set the fakelag to 1 second
|
// Set the fakelag to 1 second (server kicks me for spam me thinks if not)
|
||||||
// connInfo.setFakeLag(1);
|
connInfo.setFakeLag(1);
|
||||||
|
|
||||||
// Create a new Client
|
// Create a new Client
|
||||||
Client client = new Client(connInfo);
|
Client client = new Client(connInfo);
|
||||||
|
@ -7,6 +7,27 @@ import std.socket : SocketException, Address, getAddress;
|
|||||||
import birchwood.client.exceptions;
|
import birchwood.client.exceptions;
|
||||||
import std.conv : to, ConvException;
|
import std.conv : to, ConvException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mode describes how birchwood will act
|
||||||
|
* when encounterin invalid characters that
|
||||||
|
* were provided BY the user TO birchwood
|
||||||
|
*/
|
||||||
|
public enum ChecksMode
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* In this mode any invalid characters
|
||||||
|
* will be automatically stripped
|
||||||
|
*/
|
||||||
|
EASY,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In this mode any invalid characters
|
||||||
|
* will result in the throwing of a
|
||||||
|
* `BirchwoodException`
|
||||||
|
*/
|
||||||
|
HARDCORE
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the connection details for a server
|
* Represents the connection details for a server
|
||||||
* to connect to
|
* to connect to
|
||||||
@ -59,6 +80,8 @@ public shared struct ConnectionInfo
|
|||||||
|
|
||||||
/* TODO: before publishing change this bulk size */
|
/* TODO: before publishing change this bulk size */
|
||||||
|
|
||||||
|
private ChecksMode mode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new ConnectionInfo instance with the
|
* Constructs a new ConnectionInfo instance with the
|
||||||
* provided details
|
* provided details
|
||||||
@ -79,8 +102,21 @@ public shared struct ConnectionInfo
|
|||||||
this.bulkReadSize = bulkReadSize;
|
this.bulkReadSize = bulkReadSize;
|
||||||
this.quitMessage = quitMessage;
|
this.quitMessage = quitMessage;
|
||||||
|
|
||||||
// Set the default fakelag to 1
|
// Set the default fakelag to 0 seconds (no send lag)
|
||||||
this.fakeLag = 1;
|
this.fakeLag = 0;
|
||||||
|
|
||||||
|
// Set the validity mode to easy
|
||||||
|
this.mode = ChecksMode.EASY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChecksMode getMode()
|
||||||
|
{
|
||||||
|
return this.mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMode(ChecksMode mode)
|
||||||
|
{
|
||||||
|
this.mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -9,6 +9,9 @@ import std.string;
|
|||||||
import std.conv : to, ConvException;
|
import std.conv : to, ConvException;
|
||||||
import birchwood.protocol.constants : ReplyType;
|
import birchwood.protocol.constants : ReplyType;
|
||||||
|
|
||||||
|
import birchwood.client.exceptions;
|
||||||
|
import birchwood.config.conninfo : ChecksMode;
|
||||||
|
|
||||||
// TODO: Before release we should remove this import
|
// TODO: Before release we should remove this import
|
||||||
import std.stdio : writeln;
|
import std.stdio : writeln;
|
||||||
|
|
||||||
@ -146,13 +149,116 @@ public final class Message
|
|||||||
parameterParse();
|
parameterParse();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Implement encoder function */
|
/**
|
||||||
public string encode()
|
* Encodes this `Message` into a CRLF delimited
|
||||||
|
* byte array
|
||||||
|
*
|
||||||
|
* If `ChecksMode` is set to `EASY` (default) then
|
||||||
|
* any invalid characters will be stripped prior
|
||||||
|
* to encoding
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
* mode = the `ChecksMode` to use
|
||||||
|
*
|
||||||
|
* Throws:
|
||||||
|
* `BirchwoodException` if `ChecksMode` is set to
|
||||||
|
* `HARDCORE` and invalid characters are present
|
||||||
|
* Returns: the encoded format
|
||||||
|
*/
|
||||||
|
public string encode(ChecksMode mode)
|
||||||
{
|
{
|
||||||
string fullLine = from~" "~command~" "~params;
|
string fullLine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy over the values (they might be updated and we
|
||||||
|
* want to leave the originals intact)
|
||||||
|
*/
|
||||||
|
string fFrom = from, fCommand = command, fParams = params;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If in `HARDCORE` mode then and illegal characters
|
||||||
|
* are present, throw an exception
|
||||||
|
*/
|
||||||
|
if(mode == ChecksMode.HARDCORE && (
|
||||||
|
hic(fFrom) ||
|
||||||
|
hic(fCommand) ||
|
||||||
|
hic(fParams)
|
||||||
|
))
|
||||||
|
{
|
||||||
|
throw new BirchwoodException(ErrorType.ILLEGAL_CHARACTERS, "Invalid characters present");
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* If in `EASY` mode and illegal characters have
|
||||||
|
* been found, then fix them up
|
||||||
|
*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Strip illegal characters from all
|
||||||
|
fFrom = sic(fFrom);
|
||||||
|
fCommand = sic(fCommand);
|
||||||
|
fParams = sic(fParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Combine */
|
||||||
|
fullLine = fFrom~" "~fCommand~" "~fParams;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return fullLine;
|
return fullLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: comemnt
|
||||||
|
private alias sic = stripIllegalCharacters;
|
||||||
|
// TODO: comemnt
|
||||||
|
private alias hic = hasIllegalCharacters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the provided input string contains
|
||||||
|
* any invalid characters
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
* input = the string to check
|
||||||
|
* Returns: `true` if so, `false` otherwise
|
||||||
|
*/
|
||||||
|
// TODO: Add unittest
|
||||||
|
public static bool hasIllegalCharacters(string input)
|
||||||
|
{
|
||||||
|
foreach(char character; input)
|
||||||
|
{
|
||||||
|
if(character == '\n' || character == '\r')
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provided an input string this will strip any illegal
|
||||||
|
* characters present within it
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
* input = the string to filter
|
||||||
|
* Returns: the filtered string
|
||||||
|
*/
|
||||||
|
// TODO: Add unittest
|
||||||
|
public static string stripIllegalCharacters(string input)
|
||||||
|
{
|
||||||
|
string stripped;
|
||||||
|
foreach(char character; input)
|
||||||
|
{
|
||||||
|
if(character == '\n' || character == '\r')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
stripped ~= character;
|
||||||
|
}
|
||||||
|
|
||||||
|
return stripped;
|
||||||
|
}
|
||||||
|
|
||||||
public static Message parseReceivedMessage(string message)
|
public static Message parseReceivedMessage(string message)
|
||||||
{
|
{
|
||||||
/* TODO: testing */
|
/* TODO: testing */
|
||||||
@ -502,4 +608,74 @@ public final class Message
|
|||||||
{
|
{
|
||||||
return replyType;
|
return replyType;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
version(unittest)
|
||||||
|
{
|
||||||
|
// Contains illegal characters
|
||||||
|
string badString1 = "doos"~"bruh"~"lek"~cast(string)[10]~"ker";
|
||||||
|
string badString2 = "doos"~"bruh"~"lek"~cast(string)[13]~"ker";
|
||||||
|
|
||||||
|
import birchwood.config.conninfo : ChecksMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the detection of illegal characters in messages
|
||||||
|
*/
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
assert(Message.hasIllegalCharacters(badString1) == true);
|
||||||
|
assert(Message.hasIllegalCharacters(badString2) == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if a message containing bad characters,
|
||||||
|
* once stripped, is then valid.
|
||||||
|
*
|
||||||
|
* Essentially, tests the stripper.
|
||||||
|
*/
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
assert(Message.hasIllegalCharacters(Message.stripIllegalCharacters(badString1)) == false);
|
||||||
|
assert(Message.hasIllegalCharacters(Message.stripIllegalCharacters(badString2)) == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the ability, at the `Message`-level, to detect
|
||||||
|
* illegal characters and automatically strip them when
|
||||||
|
* in `ChecksMode.EASY`
|
||||||
|
*/
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
Message message = new Message(badString1, "fine", "fine");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string encoded = message.encode(ChecksMode.EASY);
|
||||||
|
assert(Message.hasIllegalCharacters(encoded) == false);
|
||||||
|
}
|
||||||
|
catch(BirchwoodException e)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the ability, at the `Message`-level, to detect
|
||||||
|
* illegal characters and throw an exception when in
|
||||||
|
* `ChecksMode.HARDCORE`
|
||||||
|
*/
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
Message message = new Message(badString1, "fine", "fine");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
message.encode(ChecksMode.HARDCORE);
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch(BirchwoodException e)
|
||||||
|
{
|
||||||
|
assert(e.getType() == ErrorType.ILLEGAL_CHARACTERS);
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user