Large chat and IM support

This commit is contained in:
Madpeter 2020-04-26 05:52:00 +01:00
parent 865293f144
commit 4c93b59239
2 changed files with 118 additions and 71 deletions

View file

@ -1561,6 +1561,8 @@ namespace OpenMetaverse
#region Chat and instant messages
protected int message_chunk_group_id = 0; // a int that starts at 1 goes upto 500 (then back to 1)
/// <summary>
/// Send a text message from the Agent to the Simulator
/// </summary>
@ -1568,7 +1570,29 @@ namespace OpenMetaverse
/// <param name="channel">The channel to send the message on, 0 is the public channel. Channels above 0
/// can be used however only scripts listening on the specified channel will see the message</param>
/// <param name="type">Denotes the type of message being sent, shout, whisper, etc.</param>
public void Chat(string message, int channel, ChatType type)
/// <param name="allow_split_message">Enables large messages to be split into chunks of 900 with [CHUNKGROUPID|CHUNKID|TOTALCHUNKS] at the start</param>
/// <param name="hide_chunk_grouping">Hides [CHUNKGROUPID|CHUNKID|TOTALCHUNKS] at the start of chunked messages</param>
public void Chat(string message, int channel, ChatType type, bool allow_split_message = true, bool hide_chunk_grouping = true)
{
if ((message.Length > 900) && (allow_split_message == true))
{
int group_id = message_chunk_group_id;
message_chunk_group_id++;
if (message_chunk_group_id > 500) message_chunk_group_id = 1;
string[] chunks = message.SplitBy(900).ToArray();
int chunkid = 1;
foreach (string C in chunks)
{
string chunk_grouping = "";
if (hide_chunk_grouping == false)
{
chunk_grouping = "[" + group_id.ToString() + "|" + chunkid.ToString() + "|" + chunks.Length.ToString() + "]";
}
Chat("" + chunk_grouping + "" + C + "", channel, type, false);
chunkid++;
}
}
else if ((message.Length > 0) && (message.Length < 1000))
{
ChatFromViewerPacket chat = new ChatFromViewerPacket
{
@ -1584,9 +1608,9 @@ namespace OpenMetaverse
Type = (byte) type
}
};
Client.Network.SendPacket(chat);
}
}
/// <summary>
/// Request any instant messages sent while the client was offline to be resent.
@ -1675,6 +1699,9 @@ namespace OpenMetaverse
byte[] binaryBucket)
{
if (target != UUID.Zero)
{
string[] chunks = message.SplitBy(900).ToArray();
foreach (string C in chunks)
{
ImprovedInstantMessagePacket im = new ImprovedInstantMessagePacket();
@ -1688,7 +1715,9 @@ namespace OpenMetaverse
im.MessageBlock.FromAgentName = Utils.StringToBytes(fromName);
im.MessageBlock.FromGroup = false;
im.MessageBlock.ID = imSessionID;
im.MessageBlock.Message = Utils.StringToBytes(message);
im.MessageBlock.Message = Utils.StringToBytes(C);
im.MessageBlock.Offline = (byte)offline;
im.MessageBlock.ToAgentID = target;
@ -1701,6 +1730,8 @@ namespace OpenMetaverse
// Send the message
Client.Network.SendPacket(im);
Thread.Sleep(100);
}
}
else
{
@ -3801,7 +3832,8 @@ namespace OpenMetaverse
}
};
var postData = new OSDMap {
var postData = new OSDMap
{
["hover_height"] = hoverHeight
};
request.BeginGetResponse(postData, OSDFormat.Xml, Client.Settings.CAPS_TIMEOUT);

View file

@ -74,6 +74,21 @@ namespace OpenMetaverse
Debug
};
public static IEnumerable<string> SplitBy(this string str, int chunkLength)
{
if (String.IsNullOrEmpty(str)) throw new ArgumentException();
if (chunkLength < 1) throw new ArgumentException();
for (int i = 0; i < str.Length; i += chunkLength)
{
if (chunkLength + i > str.Length)
chunkLength = str.Length - i;
yield return str.Substring(i, chunkLength);
}
}
/// <summary>
///
/// </summary>