corrected script notecard parser. It now handles notecards with inventory as well.
Signed-off-by: BlueWall <jamesh@bluewallgroup.com>inv-download
parent
c02636b6f3
commit
fb48ee1cb6
|
@ -25,13 +25,9 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using OpenMetaverse;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Xml;
|
|
||||||
using log4net;
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Framework
|
namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
|
@ -251,19 +247,260 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
#endregion SL / file extension / content-type conversions
|
#endregion SL / file extension / content-type conversions
|
||||||
|
|
||||||
|
private class NotecardReader
|
||||||
|
{
|
||||||
|
private string rawInput;
|
||||||
|
private int lineNumber;
|
||||||
|
|
||||||
|
public int LineNumber
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return lineNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotecardReader(string _rawInput)
|
||||||
|
{
|
||||||
|
rawInput = (string)_rawInput.Clone();
|
||||||
|
lineNumber = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string getLine()
|
||||||
|
{
|
||||||
|
if(rawInput.Length == 0)
|
||||||
|
{
|
||||||
|
throw new NotANotecardFormatException(lineNumber + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int pos = rawInput.IndexOf('\n');
|
||||||
|
if(pos < 0)
|
||||||
|
{
|
||||||
|
pos = rawInput.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cut line from rest */
|
||||||
|
++lineNumber;
|
||||||
|
string line = rawInput.Substring(0, pos);
|
||||||
|
if (pos + 1 >= rawInput.Length)
|
||||||
|
{
|
||||||
|
rawInput = string.Empty;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rawInput = rawInput.Substring(pos + 1);
|
||||||
|
}
|
||||||
|
/* clean up line from double spaces and tabs */
|
||||||
|
line = line.Replace("\t", " ");
|
||||||
|
while(line.IndexOf(" ") >= 0)
|
||||||
|
{
|
||||||
|
line = line.Replace(" ", " ");
|
||||||
|
}
|
||||||
|
return line.Replace("\r", "").Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string getBlock(int length)
|
||||||
|
{
|
||||||
|
/* cut line from rest */
|
||||||
|
if(length > rawInput.Length)
|
||||||
|
{
|
||||||
|
throw new NotANotecardFormatException(lineNumber);
|
||||||
|
}
|
||||||
|
string line = rawInput.Substring(0, length);
|
||||||
|
rawInput = rawInput.Substring(length);
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NotANotecardFormatException : Exception
|
||||||
|
{
|
||||||
|
public int lineNumber;
|
||||||
|
public NotANotecardFormatException(int _lineNumber)
|
||||||
|
: base()
|
||||||
|
{
|
||||||
|
lineNumber = _lineNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void skipSection(NotecardReader reader)
|
||||||
|
{
|
||||||
|
if (reader.getLine() != "{")
|
||||||
|
throw new NotANotecardFormatException(reader.LineNumber);
|
||||||
|
|
||||||
|
string line;
|
||||||
|
while ((line = reader.getLine()) != "}")
|
||||||
|
{
|
||||||
|
if(line.IndexOf('{')>=0)
|
||||||
|
{
|
||||||
|
throw new NotANotecardFormatException(reader.LineNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void skipInventoryItem(NotecardReader reader)
|
||||||
|
{
|
||||||
|
if (reader.getLine() != "{")
|
||||||
|
throw new NotANotecardFormatException(reader.LineNumber);
|
||||||
|
|
||||||
|
string line;
|
||||||
|
while((line = reader.getLine()) != "}")
|
||||||
|
{
|
||||||
|
string[] data = line.Split(' ');
|
||||||
|
if(data.Length == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(data[0] == "permissions")
|
||||||
|
{
|
||||||
|
skipSection(reader);
|
||||||
|
}
|
||||||
|
else if(data[0] == "sale_info")
|
||||||
|
{
|
||||||
|
skipSection(reader);
|
||||||
|
}
|
||||||
|
else if (line.IndexOf('{') >= 0)
|
||||||
|
{
|
||||||
|
throw new NotANotecardFormatException(reader.LineNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void skipInventoryItems(NotecardReader reader)
|
||||||
|
{
|
||||||
|
if(reader.getLine() != "{")
|
||||||
|
{
|
||||||
|
throw new NotANotecardFormatException(reader.LineNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
string line;
|
||||||
|
while((line = reader.getLine()) != "}")
|
||||||
|
{
|
||||||
|
string[] data = line.Split(' ');
|
||||||
|
if(data.Length == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(data[0] == "inv_item")
|
||||||
|
{
|
||||||
|
skipInventoryItem(reader);
|
||||||
|
}
|
||||||
|
else if (line.IndexOf('{') >= 0)
|
||||||
|
{
|
||||||
|
throw new NotANotecardFormatException(reader.LineNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void skipInventory(NotecardReader reader)
|
||||||
|
{
|
||||||
|
if (reader.getLine() != "{")
|
||||||
|
throw new NotANotecardFormatException(reader.LineNumber);
|
||||||
|
|
||||||
|
string line;
|
||||||
|
while((line = reader.getLine()) != "}")
|
||||||
|
{
|
||||||
|
string[] data = line.Split(' ');
|
||||||
|
if(data[0] == "count")
|
||||||
|
{
|
||||||
|
int count = Int32.Parse(data[1]);
|
||||||
|
for(int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
skipInventoryItems(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (line.IndexOf('{') >= 0)
|
||||||
|
{
|
||||||
|
throw new NotANotecardFormatException(reader.LineNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string readNotecardText(NotecardReader reader)
|
||||||
|
{
|
||||||
|
if (reader.getLine() != "{")
|
||||||
|
throw new NotANotecardFormatException(reader.LineNumber);
|
||||||
|
|
||||||
|
string notecardString = string.Empty;
|
||||||
|
string line;
|
||||||
|
while((line = reader.getLine()) != "}")
|
||||||
|
{
|
||||||
|
string[] data = line.Split(' ');
|
||||||
|
if (data.Length == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data[0] == "LLEmbeddedItems")
|
||||||
|
{
|
||||||
|
skipInventory(reader);
|
||||||
|
}
|
||||||
|
else if(data[0] == "Text" && data.Length == 3)
|
||||||
|
{
|
||||||
|
int length = Int32.Parse(data[2]);
|
||||||
|
notecardString = reader.getBlock(length);
|
||||||
|
}
|
||||||
|
else if (line.IndexOf('{') >= 0)
|
||||||
|
{
|
||||||
|
throw new NotANotecardFormatException(reader.LineNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return notecardString;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string readNotecard(byte[] rawInput)
|
||||||
|
{
|
||||||
|
string rawIntermedInput = string.Empty;
|
||||||
|
|
||||||
|
/* make up a Raw Encoding here */
|
||||||
|
foreach(byte c in rawInput)
|
||||||
|
{
|
||||||
|
char d = (char)c;
|
||||||
|
rawIntermedInput += d;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotecardReader reader = new NotecardReader(rawIntermedInput);
|
||||||
|
string line;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
line = reader.getLine();
|
||||||
|
}
|
||||||
|
catch(Exception)
|
||||||
|
{
|
||||||
|
return System.Text.Encoding.UTF8.GetString(rawInput);
|
||||||
|
}
|
||||||
|
string[] versioninfo = line.Split(' ');
|
||||||
|
if(versioninfo.Length < 3)
|
||||||
|
{
|
||||||
|
return System.Text.Encoding.UTF8.GetString(rawInput);
|
||||||
|
}
|
||||||
|
else if(versioninfo[0] != "Linden" || versioninfo[1] != "text")
|
||||||
|
{
|
||||||
|
return System.Text.Encoding.UTF8.GetString(rawInput);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* now we actually decode the Encoding, before we needed it in raw */
|
||||||
|
string o = readNotecardText(reader);
|
||||||
|
byte[] a = new byte[o.Length];
|
||||||
|
for(int i = 0; i < o.Length; ++i)
|
||||||
|
{
|
||||||
|
a[i] = (byte)o[i];
|
||||||
|
}
|
||||||
|
return System.Text.Encoding.UTF8.GetString(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Parse a notecard in Linden format to a string of ordinary text.
|
/// Parse a notecard in Linden format to a string of ordinary text.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="rawInput"></param>
|
/// <param name="rawInput"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static string ParseNotecardToString(string rawInput)
|
public static string ParseNotecardToString(byte[] rawInput)
|
||||||
{
|
{
|
||||||
string[] output = ParseNotecardToList(rawInput).ToArray();
|
return readNotecard(rawInput);
|
||||||
|
|
||||||
// foreach (string line in output)
|
|
||||||
// m_log.DebugFormat("[PARSE NOTECARD]: ParseNotecardToString got line {0}", line);
|
|
||||||
|
|
||||||
return string.Join("\n", output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -271,86 +508,9 @@ namespace OpenSim.Framework
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="rawInput"></param>
|
/// <param name="rawInput"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static List<string> ParseNotecardToList(string rawInput)
|
public static string[] ParseNotecardToArray(byte[] rawInput)
|
||||||
{
|
{
|
||||||
string[] input;
|
return readNotecard(rawInput).Replace("\r", "").Split('\n');
|
||||||
int idx = 0;
|
|
||||||
int level = 0;
|
|
||||||
List<string> output = new List<string>();
|
|
||||||
string[] words;
|
|
||||||
|
|
||||||
//The Linden format always ends with a } after the input data.
|
|
||||||
//Strip off trailing } so there is nothing after the input data.
|
|
||||||
int i = rawInput.LastIndexOf("}");
|
|
||||||
rawInput = rawInput.Remove(i, rawInput.Length-i);
|
|
||||||
input = rawInput.Replace("\r", "").Split('\n');
|
|
||||||
|
|
||||||
while (idx < input.Length)
|
|
||||||
{
|
|
||||||
if (input[idx] == "{")
|
|
||||||
{
|
|
||||||
level++;
|
|
||||||
idx++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (input[idx]== "}")
|
|
||||||
{
|
|
||||||
level--;
|
|
||||||
idx++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (level)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
words = input[idx].Split(' '); // Linden text ver
|
|
||||||
// Notecards are created *really* empty. Treat that as "no text" (just like after saving an empty notecard)
|
|
||||||
if (words.Length < 3)
|
|
||||||
return output;
|
|
||||||
|
|
||||||
int version = int.Parse(words[3]);
|
|
||||||
if (version != 2)
|
|
||||||
return output;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
words = input[idx].Split(' ');
|
|
||||||
if (words[0] == "LLEmbeddedItems")
|
|
||||||
break;
|
|
||||||
if (words[0] == "Text")
|
|
||||||
{
|
|
||||||
idx++; //Now points to first line of notecard text
|
|
||||||
|
|
||||||
//Number of lines in notecard.
|
|
||||||
int lines = input.Length - idx;
|
|
||||||
int line = 0;
|
|
||||||
|
|
||||||
while (line < lines)
|
|
||||||
{
|
|
||||||
// m_log.DebugFormat("[PARSE NOTECARD]: Adding line {0}", input[idx]);
|
|
||||||
output.Add(input[idx]);
|
|
||||||
idx++;
|
|
||||||
line++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
words = input[idx].Split(' '); // count
|
|
||||||
if (words[0] == "count")
|
|
||||||
{
|
|
||||||
int c = int.Parse(words[1]);
|
|
||||||
if (c > 0)
|
|
||||||
return output;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
idx++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -595,11 +595,15 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data));
|
string jsondata = SLUtil.ParseNotecardToString(a.Data);
|
||||||
int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0;
|
int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0;
|
||||||
m_comms.DispatchReply(scriptID, result, "", reqID.ToString());
|
m_comms.DispatchReply(scriptID, result, "", reqID.ToString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
catch(SLUtil.NotANotecardFormatException e)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[JsonStoreScripts]: Notecard parsing failed; assetId {0} at line number {1}", assetID.ToString(), e.lineNumber);
|
||||||
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("[JsonStoreScripts]: Json parsing failed; {0}", e.Message);
|
m_log.WarnFormat("[JsonStoreScripts]: Json parsing failed; {0}", e.Message);
|
||||||
|
|
|
@ -11632,9 +11632,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string data = Encoding.UTF8.GetString(a.Data);
|
NotecardCache.Cache(id, a.Data);
|
||||||
//m_log.Debug(data);
|
|
||||||
NotecardCache.Cache(id, data);
|
|
||||||
AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(id).ToString());
|
AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(id).ToString());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -11688,7 +11686,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
string data = Encoding.UTF8.GetString(a.Data);
|
string data = Encoding.UTF8.GetString(a.Data);
|
||||||
//m_log.Debug(data);
|
//m_log.Debug(data);
|
||||||
NotecardCache.Cache(id, data);
|
NotecardCache.Cache(id, a.Data);
|
||||||
AsyncCommands.DataserverPlugin.DataserverReply(
|
AsyncCommands.DataserverPlugin.DataserverReply(
|
||||||
reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax));
|
reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax));
|
||||||
});
|
});
|
||||||
|
@ -12461,10 +12459,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
public DateTime lastRef;
|
public DateTime lastRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Dictionary<UUID, Notecard> m_Notecards =
|
private static Dictionary<UUID, Notecard> m_Notecards =
|
||||||
new Dictionary<UUID, Notecard>();
|
new Dictionary<UUID, Notecard>();
|
||||||
|
|
||||||
public static void Cache(UUID assetID, string text)
|
public static void Cache(UUID assetID, byte[] text)
|
||||||
{
|
{
|
||||||
CheckCache();
|
CheckCache();
|
||||||
|
|
||||||
|
@ -12475,7 +12473,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
Notecard nc = new Notecard();
|
Notecard nc = new Notecard();
|
||||||
nc.lastRef = DateTime.Now;
|
nc.lastRef = DateTime.Now;
|
||||||
nc.text = SLUtil.ParseNotecardToList(text).ToArray();
|
try
|
||||||
|
{
|
||||||
|
nc.text = SLUtil.ParseNotecardToArray(text);
|
||||||
|
}
|
||||||
|
catch(SLUtil.NotANotecardFormatException)
|
||||||
|
{
|
||||||
|
nc.text = new string[0];
|
||||||
|
}
|
||||||
m_Notecards[assetID] = nc;
|
m_Notecards[assetID] = nc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1926,8 +1926,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
if (a == null)
|
if (a == null)
|
||||||
return UUID.Zero;
|
return UUID.Zero;
|
||||||
|
|
||||||
string data = Encoding.UTF8.GetString(a.Data);
|
NotecardCache.Cache(assetID, a.Data);
|
||||||
NotecardCache.Cache(assetID, data);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return assetID;
|
return assetID;
|
||||||
|
|
Loading…
Reference in New Issue