* Adding LSL stuff for Tedd_, implementing LSL-style functions in ScriptAPI.cs, implementing server event callbacks in ScriptInterpretedEvents.cs
* Added Tedd_'s LSL compiler thingie, although it cannot be referenced yet.afrisby
parent
540549bd89
commit
9be896c8ce
|
@ -0,0 +1,140 @@
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
using OpenSim.Region.Environment.Scripting;
|
||||||
|
|
||||||
|
namespace OpenSim.ScriptEngines.LSL
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public class Engine
|
||||||
|
{
|
||||||
|
public void Start(ScriptInfo WorldAPI)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Create Assembly Name
|
||||||
|
AssemblyName asmName = new AssemblyName();
|
||||||
|
asmName.Name = "TestAssembly";
|
||||||
|
|
||||||
|
// Create Assembly
|
||||||
|
AssemblyBuilder asmBuilder =
|
||||||
|
Thread.GetDomain().DefineDynamicAssembly
|
||||||
|
(asmName, AssemblyBuilderAccess.RunAndSave);
|
||||||
|
|
||||||
|
// Create a module (and save to disk)
|
||||||
|
ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule
|
||||||
|
(asmName.Name, asmName.Name + ".dll");
|
||||||
|
|
||||||
|
// Create a Class (/Type)
|
||||||
|
TypeBuilder typeBuilder = modBuilder.DefineType(
|
||||||
|
"MyClass",
|
||||||
|
TypeAttributes.Public,
|
||||||
|
typeof(object),
|
||||||
|
new Type[] { typeof(LSL_CLRInterface.LSLScript) });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate the IL itself
|
||||||
|
*/
|
||||||
|
|
||||||
|
GenerateIL(WorldAPI, typeBuilder);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Done generating, create a type and run it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Create type object for the class (after defining fields and methods)
|
||||||
|
Type type = typeBuilder.CreateType();
|
||||||
|
|
||||||
|
asmBuilder.Save("TestAssembly.dll");
|
||||||
|
|
||||||
|
// Create an instance we can play with
|
||||||
|
//LSLScript hello = (LSLScript)Activator.CreateInstance(type);
|
||||||
|
LSL_CLRInterface.LSLScript MyScript = (LSL_CLRInterface.LSLScript)Activator.CreateInstance(type);
|
||||||
|
|
||||||
|
// Play with it
|
||||||
|
MyScript.event_state_entry("Test");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GenerateIL(ScriptInfo WorldAPI, TypeBuilder typeBuilder)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
// For debug
|
||||||
|
LSO_Parser LSOP = new LSO_Parser();
|
||||||
|
LSOP.ParseFile("LSO\\CloseToDefault.lso", WorldAPI, ref typeBuilder);
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
// Override a Method / Function
|
||||||
|
MethodBuilder methodBuilder = typeBuilder.DefineMethod("event_state_entry",
|
||||||
|
MethodAttributes.Private | MethodAttributes.Virtual,
|
||||||
|
typeof(void),
|
||||||
|
new Type[] { typeof(object) });
|
||||||
|
|
||||||
|
typeBuilder.DefineMethodOverride(methodBuilder,
|
||||||
|
typeof(LSL_CLRInterface.LSLScript).GetMethod("event_state_entry"));
|
||||||
|
|
||||||
|
// Create the IL generator
|
||||||
|
ILGenerator il = methodBuilder.GetILGenerator();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TRY
|
||||||
|
*/
|
||||||
|
il.BeginExceptionBlock();
|
||||||
|
|
||||||
|
// Push "Hello World!" string to stack
|
||||||
|
il.Emit(OpCodes.Ldstr, "Hello World!");
|
||||||
|
|
||||||
|
// Push Console.WriteLine command to stack ... Console.WriteLine("Hello World!");
|
||||||
|
il.Emit(OpCodes.Call, typeof(Console).GetMethod
|
||||||
|
("WriteLine", new Type[] { typeof(string) }));
|
||||||
|
|
||||||
|
//il.EmitCall(OpCodes.Callvirt
|
||||||
|
//il.Emit(OpCodes.Call, typeof(WorldAPI).GetMethod
|
||||||
|
//("TestFunction"));
|
||||||
|
|
||||||
|
|
||||||
|
//il.ThrowException(typeof(NotSupportedException));
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CATCH
|
||||||
|
*/
|
||||||
|
il.BeginCatchBlock(typeof(Exception));
|
||||||
|
|
||||||
|
// Push "Hello World!" string to stack
|
||||||
|
il.Emit(OpCodes.Ldstr, "Something went wrong: ");
|
||||||
|
|
||||||
|
//call void [mscorlib]System.Console::WriteLine(string)
|
||||||
|
il.Emit(OpCodes.Call, typeof(Console).GetMethod
|
||||||
|
("Write", new Type[] { typeof(string) }));
|
||||||
|
|
||||||
|
//callvirt instance string [mscorlib]System.Exception::get_Message()
|
||||||
|
il.Emit(OpCodes.Callvirt, typeof(Exception).GetMethod
|
||||||
|
("get_Message"));
|
||||||
|
|
||||||
|
//call void [mscorlib]System.Console::WriteLine(string)
|
||||||
|
il.Emit(OpCodes.Call, typeof(Console).GetMethod
|
||||||
|
("WriteLine", new Type[] { typeof(string) }));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* END TRY
|
||||||
|
*/
|
||||||
|
il.EndExceptionBlock();
|
||||||
|
|
||||||
|
|
||||||
|
// Push "Return from current method, with return value if present" to stack
|
||||||
|
il.Emit(OpCodes.Ret);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenSim.ScriptEngines.LSL
|
||||||
|
{
|
||||||
|
public class LSL_CLRInterface
|
||||||
|
{
|
||||||
|
public interface LSLScript
|
||||||
|
{
|
||||||
|
//public virtual void Run(object arg)
|
||||||
|
//{
|
||||||
|
//}
|
||||||
|
//void Run(object arg);
|
||||||
|
|
||||||
|
void event_state_entry(object arg);
|
||||||
|
//void event_state_exit();
|
||||||
|
void event_touch_start(object arg);
|
||||||
|
//void event_touch();
|
||||||
|
//void event_touch_end();
|
||||||
|
//void event_collision_start();
|
||||||
|
//void event_collision();
|
||||||
|
//void event_collision_end();
|
||||||
|
//void event_land_collision_start();
|
||||||
|
//void event_land_collision();
|
||||||
|
//void event_land_collision_end();
|
||||||
|
//void event_timer();
|
||||||
|
//void event_listen();
|
||||||
|
//void event_on_rez();
|
||||||
|
//void event_sensor();
|
||||||
|
//void event_no_sensor();
|
||||||
|
//void event_control();
|
||||||
|
//void event_money();
|
||||||
|
//void event_email();
|
||||||
|
//void event_at_target();
|
||||||
|
//void event_not_at_target();
|
||||||
|
//void event_at_rot_target();
|
||||||
|
//void event_not_at_rot_target();
|
||||||
|
//void event_run_time_permissions();
|
||||||
|
//void event_changed();
|
||||||
|
//void event_attach();
|
||||||
|
//void event_dataserver();
|
||||||
|
//void event_link_message();
|
||||||
|
//void event_moving_start();
|
||||||
|
//void event_moving_end();
|
||||||
|
//void event_object_rez();
|
||||||
|
//void event_remote_data();
|
||||||
|
//void event_http_response();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,485 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenSim.ScriptEngines.LSL
|
||||||
|
{
|
||||||
|
static class LSO_Enums
|
||||||
|
{
|
||||||
|
|
||||||
|
public enum Variable_Type_Codes
|
||||||
|
{
|
||||||
|
Void = 0,
|
||||||
|
Integer = 1,
|
||||||
|
Float = 2,
|
||||||
|
String = 3,
|
||||||
|
Key = 4,
|
||||||
|
Vector = 5,
|
||||||
|
Rotation = 6,
|
||||||
|
List = 7
|
||||||
|
}
|
||||||
|
public enum Event_Mask_Values
|
||||||
|
{
|
||||||
|
state_entry = 0,
|
||||||
|
state_exit = 1,
|
||||||
|
touch_start = 2,
|
||||||
|
touch = 3,
|
||||||
|
touch_end = 4,
|
||||||
|
collision_start = 5,
|
||||||
|
collision = 6,
|
||||||
|
collision_end = 7,
|
||||||
|
land_collision_start = 8,
|
||||||
|
land_collision = 9,
|
||||||
|
land_collision_end = 10,
|
||||||
|
timer = 11,
|
||||||
|
listen = 12,
|
||||||
|
on_rez = 13,
|
||||||
|
sensor = 14,
|
||||||
|
no_sensor = 15,
|
||||||
|
control = 16,
|
||||||
|
money = 17,
|
||||||
|
email = 18,
|
||||||
|
at_target = 19,
|
||||||
|
not_at_target = 20,
|
||||||
|
at_rot_target = 21,
|
||||||
|
not_at_rot_target = 22,
|
||||||
|
run_time_permissions = 23,
|
||||||
|
changed = 24,
|
||||||
|
attach = 25,
|
||||||
|
dataserver = 26,
|
||||||
|
link_message = 27,
|
||||||
|
moving_start = 28,
|
||||||
|
moving_end = 29,
|
||||||
|
object_rez = 30,
|
||||||
|
remote_data = 31,
|
||||||
|
http_response = 32
|
||||||
|
}
|
||||||
|
public enum Operation_Table
|
||||||
|
{
|
||||||
|
NOOP = 0x0,
|
||||||
|
POP = 0x1,
|
||||||
|
POPS = 0x2,
|
||||||
|
POPL = 0x3,
|
||||||
|
POPV = 0x4,
|
||||||
|
POPQ = 0x5,
|
||||||
|
POPARG = 0x6,
|
||||||
|
POPIP = 0x7,
|
||||||
|
POPBP = 0x8,
|
||||||
|
POPSP = 0x9,
|
||||||
|
POPSLR = 0xa,
|
||||||
|
DUP = 0x20,
|
||||||
|
DUPS = 0x21,
|
||||||
|
DUPL = 0x22,
|
||||||
|
DUPV = 0x23,
|
||||||
|
DUPQ = 0x24,
|
||||||
|
STORE = 0x30,
|
||||||
|
STORES = 0x31,
|
||||||
|
STOREL = 0x32,
|
||||||
|
STOREV = 0x33,
|
||||||
|
STOREQ = 0x34,
|
||||||
|
STOREG = 0x35,
|
||||||
|
STOREGS = 0x36,
|
||||||
|
STOREGL = 0x37,
|
||||||
|
STOREGV = 0x38,
|
||||||
|
STOREGQ = 0x39,
|
||||||
|
LOADP = 0x3a,
|
||||||
|
LOADSP = 0x3b,
|
||||||
|
LOADLP = 0x3c,
|
||||||
|
LOADVP = 0x3d,
|
||||||
|
LOADQP = 0x3e,
|
||||||
|
LOADGP = 0x3f,
|
||||||
|
LOADGSP = 0x40,
|
||||||
|
LOADGLP = 0x41,
|
||||||
|
LOADGVP = 0x42,
|
||||||
|
LOADGQP = 0x43,
|
||||||
|
PUSH = 0x50,
|
||||||
|
PUSHS = 0x51,
|
||||||
|
PUSHL = 0x52,
|
||||||
|
PUSHV = 0x53,
|
||||||
|
PUSHQ = 0x54,
|
||||||
|
PUSHG = 0x55,
|
||||||
|
PUSHGS = 0x56,
|
||||||
|
PUSHGL = 0x57,
|
||||||
|
PUSHGV = 0x58,
|
||||||
|
PUSHGQ = 0x59,
|
||||||
|
PUSHIP = 0x5a,
|
||||||
|
PUSHBP = 0x5b,
|
||||||
|
PUSHSP = 0x5c,
|
||||||
|
PUSHARGB = 0x5d,
|
||||||
|
PUSHARGI = 0x5e,
|
||||||
|
PUSHARGF = 0x5f,
|
||||||
|
PUSHARGS = 0x60,
|
||||||
|
PUSHARGV = 0x61,
|
||||||
|
PUSHARGQ = 0x62,
|
||||||
|
PUSHE = 0x63,
|
||||||
|
PUSHEV = 0x64,
|
||||||
|
PUSHEQ = 0x65,
|
||||||
|
PUSHARGE = 0x66,
|
||||||
|
ADD = 0x70,
|
||||||
|
SUB = 0x71,
|
||||||
|
MUL = 0x72,
|
||||||
|
DIV = 0x73,
|
||||||
|
MOD = 0x74,
|
||||||
|
EQ = 0x75,
|
||||||
|
NEQ = 0x76,
|
||||||
|
LEQ = 0x77,
|
||||||
|
GEQ = 0x78,
|
||||||
|
LESS = 0x79,
|
||||||
|
GREATER = 0x7a,
|
||||||
|
BITAND = 0x7b,
|
||||||
|
BITOR = 0x7c,
|
||||||
|
BITXOR = 0x7d,
|
||||||
|
BOOLAND = 0x7e,
|
||||||
|
BOOLOR = 0x7f,
|
||||||
|
NEG = 0x80,
|
||||||
|
BITNOT = 0x81,
|
||||||
|
BOOLNOT = 0x82,
|
||||||
|
JUMP = 0x90,
|
||||||
|
JUMPIF = 0x91,
|
||||||
|
JUMPNIF = 0x92,
|
||||||
|
STATE = 0x93,
|
||||||
|
CALL = 0x94,
|
||||||
|
RETURN = 0x95,
|
||||||
|
CAST = 0xa0,
|
||||||
|
STACKTOS = 0xb0,
|
||||||
|
STACKTOL = 0xb1,
|
||||||
|
PRINT = 0xc0,
|
||||||
|
CALLLIB = 0xd0,
|
||||||
|
CALLLIB_TWO_BYTE = 0xd1,
|
||||||
|
SHL = 0xe0,
|
||||||
|
SHR = 0xe1
|
||||||
|
}
|
||||||
|
public enum BuiltIn_Functions
|
||||||
|
{
|
||||||
|
llSin = 0,
|
||||||
|
llCos = 1,
|
||||||
|
llTan = 2,
|
||||||
|
llAtan2 = 3,
|
||||||
|
llSqrt = 4,
|
||||||
|
llPow = 5,
|
||||||
|
llAbs = 6,
|
||||||
|
llFabs = 7,
|
||||||
|
llFrand = 8,
|
||||||
|
llFloor = 9,
|
||||||
|
llCeil = 10,
|
||||||
|
llRound = 11,
|
||||||
|
llVecMag = 12,
|
||||||
|
llVecNorm = 13,
|
||||||
|
llVecDist = 14,
|
||||||
|
llRot2Euler = 15,
|
||||||
|
llEuler2Rot = 16,
|
||||||
|
llAxes2Rot = 17,
|
||||||
|
llRot2Fwd = 18,
|
||||||
|
llRot2Left = 19,
|
||||||
|
llRot2Up = 20,
|
||||||
|
llRotBetween = 21,
|
||||||
|
llWhisper = 22,
|
||||||
|
llSay = 23,
|
||||||
|
llShout = 24,
|
||||||
|
llListen = 25,
|
||||||
|
llListenControl = 26,
|
||||||
|
llListenRemove = 27,
|
||||||
|
llSensor = 28,
|
||||||
|
llSensorRepeat = 29,
|
||||||
|
llSensorRemove = 30,
|
||||||
|
llDetectedName = 31,
|
||||||
|
llDetectedKey = 32,
|
||||||
|
llDetectedOwner = 33,
|
||||||
|
llDetectedType = 34,
|
||||||
|
llDetectedPos = 35,
|
||||||
|
llDetectedVel = 36,
|
||||||
|
llDetectedGrab = 37,
|
||||||
|
llDetectedRot = 38,
|
||||||
|
llDetectedGroup = 39,
|
||||||
|
llDetectedLinkNumber = 40,
|
||||||
|
llDie = 41,
|
||||||
|
llGround = 42,
|
||||||
|
llCloud = 43,
|
||||||
|
llWind = 44,
|
||||||
|
llSetStatus = 45,
|
||||||
|
llGetStatus = 46,
|
||||||
|
llSetScale = 47,
|
||||||
|
llGetScale = 48,
|
||||||
|
llSetColor = 49,
|
||||||
|
llGetAlpha = 50,
|
||||||
|
llSetAlpha = 51,
|
||||||
|
llGetColor = 52,
|
||||||
|
llSetTexture = 53,
|
||||||
|
llScaleTexture = 54,
|
||||||
|
llOffsetTexture = 55,
|
||||||
|
llRotateTexture = 56,
|
||||||
|
llGetTexture = 57,
|
||||||
|
llSetPos = 58,
|
||||||
|
llGetPos = 59,
|
||||||
|
llGetLocalPos = 60,
|
||||||
|
llSetRot = 61,
|
||||||
|
llGetRot = 62,
|
||||||
|
llGetLocalRot = 63,
|
||||||
|
llSetForce = 64,
|
||||||
|
llGetForce = 65,
|
||||||
|
llTarget = 66,
|
||||||
|
llTargetRemove = 67,
|
||||||
|
llRotTarget = 68,
|
||||||
|
llRotTargetRemove = 69,
|
||||||
|
llMoveToTarget = 70,
|
||||||
|
llStopMoveToTarget = 71,
|
||||||
|
llApplyImpulse = 72,
|
||||||
|
llApplyRotationalImpulse = 73,
|
||||||
|
llSetTorque = 74,
|
||||||
|
llGetTorque = 75,
|
||||||
|
llSetForceAndTorque = 76,
|
||||||
|
llGetVel = 77,
|
||||||
|
llGetAccel = 78,
|
||||||
|
llGetOmega = 79,
|
||||||
|
llGetTimeOfDay = 80,
|
||||||
|
llGetWallclock = 81,
|
||||||
|
llGetTime = 82,
|
||||||
|
llResetTime = 83,
|
||||||
|
llGetAndResetTime = 84,
|
||||||
|
llSound = 85,
|
||||||
|
llPlaySound = 86,
|
||||||
|
llLoopSound = 87,
|
||||||
|
llLoopSoundMaster = 88,
|
||||||
|
llLoopSoundSlave = 89,
|
||||||
|
llPlaySoundSlave = 90,
|
||||||
|
llTriggerSound = 91,
|
||||||
|
llStopSound = 92,
|
||||||
|
llPreloadSound = 93,
|
||||||
|
llGetSubString = 94,
|
||||||
|
llDeleteSubString = 95,
|
||||||
|
llInsertString = 96,
|
||||||
|
llToUpper = 97,
|
||||||
|
llToLower = 98,
|
||||||
|
llGiveMoney = 99,
|
||||||
|
llMakeExplosion = 100,
|
||||||
|
llMakeFountain = 101,
|
||||||
|
llMakeSmoke = 102,
|
||||||
|
llMakeFire = 103,
|
||||||
|
llRezObject = 104,
|
||||||
|
llLookAt = 105,
|
||||||
|
llStopLookAt = 106,
|
||||||
|
llSetTimerEvent = 107,
|
||||||
|
llSleep = 108,
|
||||||
|
llGetMass = 109,
|
||||||
|
llCollisionFilter = 110,
|
||||||
|
llTakeControls = 111,
|
||||||
|
llReleaseControls = 112,
|
||||||
|
llAttachToAvatar = 113,
|
||||||
|
llDetachFromAvatar = 114,
|
||||||
|
llTakeCamera = 115,
|
||||||
|
llReleaseCamera = 116,
|
||||||
|
llGetOwner = 117,
|
||||||
|
llInstantMessage = 118,
|
||||||
|
llEmail = 119,
|
||||||
|
llGetNextEmail = 120,
|
||||||
|
llGetKey = 121,
|
||||||
|
llSetBuoyancy = 122,
|
||||||
|
llSetHoverHeight = 123,
|
||||||
|
llStopHover = 124,
|
||||||
|
llMinEventDelay = 125,
|
||||||
|
llSoundPreload = 126,
|
||||||
|
llRotLookAt = 127,
|
||||||
|
llStringLength = 128,
|
||||||
|
llStartAnimation = 129,
|
||||||
|
llStopAnimation = 130,
|
||||||
|
llPointAt = 131,
|
||||||
|
llStopPointAt = 132,
|
||||||
|
llTargetOmega = 133,
|
||||||
|
llGetStartParameter = 134,
|
||||||
|
llGodLikeRezObject = 135,
|
||||||
|
llRequestPermissions = 136,
|
||||||
|
llGetPermissionsKey = 137,
|
||||||
|
llGetPermissions = 138,
|
||||||
|
llGetLinkNumber = 139,
|
||||||
|
llSetLinkColor = 140,
|
||||||
|
llCreateLink = 141,
|
||||||
|
llBreakLink = 142,
|
||||||
|
llBreakAllLinks = 143,
|
||||||
|
llGetLinkKey = 144,
|
||||||
|
llGetLinkName = 145,
|
||||||
|
llGetInventoryNumber = 146,
|
||||||
|
llGetInventoryName = 147,
|
||||||
|
llSetScriptState = 148,
|
||||||
|
llGetEnergy = 149,
|
||||||
|
llGiveInventory = 150,
|
||||||
|
llRemoveInventory = 151,
|
||||||
|
llSetText = 152,
|
||||||
|
llWater = 153,
|
||||||
|
llPassTouches = 154,
|
||||||
|
llRequestAgentData = 155,
|
||||||
|
llRequestInventoryData = 156,
|
||||||
|
llSetDamage = 157,
|
||||||
|
llTeleportAgentHome = 158,
|
||||||
|
llModifyLand = 159,
|
||||||
|
llCollisionSound = 160,
|
||||||
|
llCollisionSprite = 161,
|
||||||
|
llGetAnimation = 162,
|
||||||
|
llResetScript = 163,
|
||||||
|
llMessageLinked = 164,
|
||||||
|
llPushObject = 165,
|
||||||
|
llPassCollisions = 166,
|
||||||
|
llGetScriptName = 167,
|
||||||
|
llGetNumberOfSides = 168,
|
||||||
|
llAxisAngle2Rot = 169,
|
||||||
|
llRot2Axis = 170,
|
||||||
|
llRot2Angle = 171,
|
||||||
|
llAcos = 172,
|
||||||
|
llAsin = 173,
|
||||||
|
llAngleBetween = 174,
|
||||||
|
llGetInventoryKey = 175,
|
||||||
|
llAllowInventoryDrop = 176,
|
||||||
|
llGetSunDirection = 177,
|
||||||
|
llGetTextureOffset = 178,
|
||||||
|
llGetTextureScale = 179,
|
||||||
|
llGetTextureRot = 180,
|
||||||
|
llSubStringIndex = 181,
|
||||||
|
llGetOwnerKey = 182,
|
||||||
|
llGetCenterOfMass = 183,
|
||||||
|
llListSort = 184,
|
||||||
|
llGetListLength = 185,
|
||||||
|
llList2Integer = 186,
|
||||||
|
llList2Float = 187,
|
||||||
|
llList2String = 188,
|
||||||
|
llList2Key = 189,
|
||||||
|
llList2Vector = 190,
|
||||||
|
llList2Rot = 191,
|
||||||
|
llList2List = 192,
|
||||||
|
llDeleteSubList = 193,
|
||||||
|
llGetListEntryType = 194,
|
||||||
|
llList2CSV = 195,
|
||||||
|
llCSV2List = 196,
|
||||||
|
llListRandomize = 197,
|
||||||
|
llList2ListStrided = 198,
|
||||||
|
llGetRegionCorner = 199,
|
||||||
|
llListInsertList = 200,
|
||||||
|
llListFindList = 201,
|
||||||
|
llGetObjectName = 202,
|
||||||
|
llSetObjectName = 203,
|
||||||
|
llGetDate = 204,
|
||||||
|
llEdgeOfWorld = 205,
|
||||||
|
llGetAgentInfo = 206,
|
||||||
|
llAdjustSoundVolume = 207,
|
||||||
|
llSetSoundQueueing = 208,
|
||||||
|
llSetSoundRadius = 209,
|
||||||
|
llKey2Name = 210,
|
||||||
|
llSetTextureAnim = 211,
|
||||||
|
llTriggerSoundLimited = 212,
|
||||||
|
llEjectFromLand = 213,
|
||||||
|
llParseString2List = 214,
|
||||||
|
llOverMyLand = 215,
|
||||||
|
llGetLandOwnerAt = 216,
|
||||||
|
llGetNotecardLine = 217,
|
||||||
|
llGetAgentSize = 218,
|
||||||
|
llSameGroup = 219,
|
||||||
|
llUnSit = 220,
|
||||||
|
llGroundSlope = 221,
|
||||||
|
llGroundNormal = 222,
|
||||||
|
llGroundContour = 223,
|
||||||
|
llGetAttached = 224,
|
||||||
|
llGetFreeMemory = 225,
|
||||||
|
llGetRegionName = 226,
|
||||||
|
llGetRegionTimeDilation = 227,
|
||||||
|
llGetRegionFPS = 228,
|
||||||
|
llParticleSystem = 229,
|
||||||
|
llGroundRepel = 230,
|
||||||
|
llGiveInventoryList = 231,
|
||||||
|
llSetVehicleType = 232,
|
||||||
|
llSetVehicleFloatParam = 233,
|
||||||
|
llSetVehicleVectorParam = 234,
|
||||||
|
llSetVehicleRotationParam = 235,
|
||||||
|
llSetVehicleFlags = 236,
|
||||||
|
llRemoveVehicleFlags = 237,
|
||||||
|
llSitTarget = 238,
|
||||||
|
llAvatarOnSitTarget = 239,
|
||||||
|
llAddToLandPassList = 240,
|
||||||
|
llSetTouchText = 241,
|
||||||
|
llSetSitText = 242,
|
||||||
|
llSetCameraEyeOffset = 243,
|
||||||
|
llSetCameraAtOffset = 244,
|
||||||
|
llDumpList2String = 245,
|
||||||
|
llScriptDanger = 246,
|
||||||
|
llDialog = 247,
|
||||||
|
llVolumeDetect = 248,
|
||||||
|
llResetOtherScript = 249,
|
||||||
|
llGetScriptState = 250,
|
||||||
|
llRemoteLoadScript = 251,
|
||||||
|
llSetRemoteScriptAccessPin = 252,
|
||||||
|
llRemoteLoadScriptPin = 253,
|
||||||
|
llOpenRemoteDataChannel = 254,
|
||||||
|
llSendRemoteData = 255,
|
||||||
|
llRemoteDataReply = 256,
|
||||||
|
llCloseRemoteDataChannel = 257,
|
||||||
|
llMD5String = 258,
|
||||||
|
llSetPrimitiveParams = 259,
|
||||||
|
llStringToBase64 = 260,
|
||||||
|
llBase64ToString = 261,
|
||||||
|
llXorBase64Strings = 262,
|
||||||
|
llRemoteDataSetRegion = 263,
|
||||||
|
llLog10 = 264,
|
||||||
|
llLog = 265,
|
||||||
|
llGetAnimationList = 266,
|
||||||
|
llSetParcelMusicURL = 267,
|
||||||
|
llGetRootPosition = 268,
|
||||||
|
llGetRootRotation = 269,
|
||||||
|
llGetObjectDesc = 270,
|
||||||
|
llSetObjectDesc = 271,
|
||||||
|
llGetCreator = 272,
|
||||||
|
llGetTimestamp = 273,
|
||||||
|
llSetLinkAlpha = 274,
|
||||||
|
llGetNumberOfPrims = 275,
|
||||||
|
llGetNumberOfNotecardLines = 276,
|
||||||
|
llGetBoundingBox = 277,
|
||||||
|
llGetGeometricCenter = 278,
|
||||||
|
llGetPrimitiveParams = 279,
|
||||||
|
llIntegerToBase64 = 280,
|
||||||
|
llBase64ToInteger = 281,
|
||||||
|
llGetGMTclock = 282,
|
||||||
|
llGetSimulatorHostname = 283,
|
||||||
|
llSetLocalRot = 284,
|
||||||
|
llParseStringKeepNulls = 285,
|
||||||
|
llRezAtRoot = 286,
|
||||||
|
llGetObjectPermMask = 287,
|
||||||
|
llSetObjectPermMask = 288,
|
||||||
|
llGetInventoryPermMask = 289,
|
||||||
|
llSetInventoryPermMask = 290,
|
||||||
|
llGetInventoryCreator = 291,
|
||||||
|
llOwnerSay = 292,
|
||||||
|
llRequestSimulatorData = 293,
|
||||||
|
llForceMouselook = 294,
|
||||||
|
llGetObjectMass = 295,
|
||||||
|
llListReplaceList = 296,
|
||||||
|
llLoadURL = 297,
|
||||||
|
llParcelMediaCommandList = 298,
|
||||||
|
llParcelMediaQuery = 299,
|
||||||
|
llModPow = 300,
|
||||||
|
llGetInventoryType = 301,
|
||||||
|
llSetPayPrice = 302,
|
||||||
|
llGetCameraPos = 303,
|
||||||
|
llGetCameraRot = 304,
|
||||||
|
llSetPrimURL = 305,
|
||||||
|
llRefreshPrimURL = 306,
|
||||||
|
llEscapeURL = 307,
|
||||||
|
llUnescapeURL = 308,
|
||||||
|
llMapDestination = 309,
|
||||||
|
llAddToLandBanList = 310,
|
||||||
|
llRemoveFromLandPassList = 311,
|
||||||
|
llRemoveFromLandBanList = 312,
|
||||||
|
llSetCameraParams = 313,
|
||||||
|
llClearCameraParams = 314,
|
||||||
|
llListStatistics = 315,
|
||||||
|
llGetUnixTime = 316,
|
||||||
|
llGetParcelFlags = 317,
|
||||||
|
llGetRegionFlags = 318,
|
||||||
|
llXorBase64StringsCorrect = 319,
|
||||||
|
llHTTPRequest = 320,
|
||||||
|
llResetLandBanList = 321,
|
||||||
|
llResetLandPassList = 322,
|
||||||
|
llGetParcelPrimCount = 323,
|
||||||
|
llGetParcelPrimOwners = 324,
|
||||||
|
llGetObjectPrimCount = 325,
|
||||||
|
llGetParcelMaxPrims = 326,
|
||||||
|
llGetParcelDetails = 327
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,608 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using OpenSim.Region.Environment.Scripting;
|
||||||
|
|
||||||
|
namespace OpenSim.ScriptEngines.LSL
|
||||||
|
{
|
||||||
|
class LSO_Parser
|
||||||
|
{
|
||||||
|
private bool Debug = true;
|
||||||
|
private FileStream fs;
|
||||||
|
private BinaryReader br;
|
||||||
|
private LSO_Struct.Header myHeader;
|
||||||
|
|
||||||
|
private TypeBuilder typeBuilder;
|
||||||
|
private ScriptInfo WorldAPI;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parse LSO file.
|
||||||
|
/// Reads LSO ByteCode into memory structures.
|
||||||
|
/// TODO: What else does it do?
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="FileName">FileName of LSO ByteCode file</param>
|
||||||
|
public void ParseFile(string FileName, ScriptInfo _WorldAPI, ref TypeBuilder _typeBuilder)
|
||||||
|
{
|
||||||
|
typeBuilder = _typeBuilder;
|
||||||
|
WorldAPI = _WorldAPI;
|
||||||
|
// Open
|
||||||
|
SendToDebug("Opening filename: " + FileName);
|
||||||
|
fs = File.Open(FileName, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||||
|
br = new BinaryReader(fs, Encoding.BigEndianUnicode);
|
||||||
|
|
||||||
|
|
||||||
|
// The LSO Format consist of 6 major blocks: header, statics, functions, states, heap, and stack.
|
||||||
|
|
||||||
|
|
||||||
|
// HEADER BLOCK
|
||||||
|
SendToDebug("Reading HEADER BLOCK at: 0");
|
||||||
|
fs.Seek(0, SeekOrigin.Begin);
|
||||||
|
myHeader = new LSO_Struct.Header();
|
||||||
|
myHeader.TM = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.IP = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.VN = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.BP = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.SP = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.HR = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.HP = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.CS = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.NS = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.CE = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.IE = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.ER = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.FR = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.SLR = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.GVR = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.GFR = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.PR = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.ESR = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.SR = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.NCE = BitConverter.ToUInt64(br_read(8), 0);
|
||||||
|
myHeader.NIE = BitConverter.ToUInt64(br_read(8), 0);
|
||||||
|
myHeader.NER = BitConverter.ToUInt64(br_read(8), 0);
|
||||||
|
|
||||||
|
// Print Header Block to debug
|
||||||
|
SendToDebug("TM - Top of memory (size): " + myHeader.TM);
|
||||||
|
SendToDebug("IP - Instruction Pointer (0=not running): " + myHeader.IP);
|
||||||
|
SendToDebug("VN - Version number: " + myHeader.VN);
|
||||||
|
SendToDebug("BP - Local Frame Pointer: " + myHeader.BP);
|
||||||
|
SendToDebug("SP - Stack Pointer: " + myHeader.SP);
|
||||||
|
SendToDebug("HR - Heap Register: " + myHeader.HR);
|
||||||
|
SendToDebug("HP - Heap Pointer: " + myHeader.HP);
|
||||||
|
SendToDebug("CS - Current State: " + myHeader.CS);
|
||||||
|
SendToDebug("NS - Next State: " + myHeader.NS);
|
||||||
|
SendToDebug("CE - Current Events: " + myHeader.CE);
|
||||||
|
SendToDebug("IE - In Event: " + myHeader.IE);
|
||||||
|
SendToDebug("ER - Event Register: " + myHeader.ER);
|
||||||
|
SendToDebug("FR - Fault Register: " + myHeader.FR);
|
||||||
|
SendToDebug("SLR - Sleep Register: " + myHeader.SLR);
|
||||||
|
SendToDebug("GVR - Global Variable Register: " + myHeader.GVR);
|
||||||
|
SendToDebug("GFR - Global Function Register: " + myHeader.GFR);
|
||||||
|
SendToDebug("PR - Parameter Register: " + myHeader.PR);
|
||||||
|
SendToDebug("ESR - Energy Supply Register: " + myHeader.ESR);
|
||||||
|
SendToDebug("SR - State Register: " + myHeader.SR);
|
||||||
|
SendToDebug("NCE - 64-bit Current Events: " + myHeader.NCE);
|
||||||
|
SendToDebug("NIE - 64-bit In Events: " + myHeader.NIE);
|
||||||
|
SendToDebug("NER - 64-bit Event Register: " + myHeader.NER);
|
||||||
|
SendToDebug("Read position when exiting HEADER BLOCK: " + fs.Position);
|
||||||
|
|
||||||
|
// STATIC BLOCK
|
||||||
|
SendToDebug("Reading STATIC BLOCK at: " + myHeader.GVR);
|
||||||
|
fs.Seek(myHeader.GVR, SeekOrigin.Begin);
|
||||||
|
int StaticBlockCount = 0;
|
||||||
|
// Read function blocks until we hit GFR
|
||||||
|
while (fs.Position < myHeader.GFR)
|
||||||
|
{
|
||||||
|
StaticBlockCount++;
|
||||||
|
SendToDebug("Reading Static Block " + StaticBlockCount + " at: " + fs.Position);
|
||||||
|
//fs.Seek(myHeader.GVR, SeekOrigin.Begin);
|
||||||
|
LSO_Struct.StaticBlock myStaticBlock = new LSO_Struct.StaticBlock();
|
||||||
|
myStaticBlock.Static_Chunk_Header_Size = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myStaticBlock.ObjectType = br_read(1)[0];
|
||||||
|
SendToDebug("Static Block ObjectType: " + ((LSO_Enums.Variable_Type_Codes)myStaticBlock.ObjectType).ToString());
|
||||||
|
myStaticBlock.Unknown = br_read(1)[0];
|
||||||
|
// Size of datatype varies
|
||||||
|
if (myStaticBlock.ObjectType != 0)
|
||||||
|
myStaticBlock.BlockVariable = br_read(getObjectSize(myStaticBlock.ObjectType));
|
||||||
|
}
|
||||||
|
SendToDebug("Number of Static Blocks read: " + StaticBlockCount);
|
||||||
|
|
||||||
|
|
||||||
|
// FUNCTION BLOCK
|
||||||
|
// Always right after STATIC BLOCK
|
||||||
|
LSO_Struct.FunctionBlock myFunctionBlock = new LSO_Struct.FunctionBlock();
|
||||||
|
if (myHeader.GFR == myHeader.SR)
|
||||||
|
{
|
||||||
|
// If GFR and SR are at same position then there is no fuction block
|
||||||
|
SendToDebug("No FUNCTION BLOCK found");
|
||||||
|
} else {
|
||||||
|
SendToDebug("Reading FUNCTION BLOCK at: " + myHeader.GFR);
|
||||||
|
fs.Seek(myHeader.GFR, SeekOrigin.Begin);
|
||||||
|
myFunctionBlock.FunctionCount = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
SendToDebug("Number of functions in Fuction Block: " + myFunctionBlock.FunctionCount);
|
||||||
|
if (myFunctionBlock.FunctionCount > 0)
|
||||||
|
{
|
||||||
|
myFunctionBlock.CodeChunkPointer = new UInt32[myFunctionBlock.FunctionCount];
|
||||||
|
for (int i = 0; i < myFunctionBlock.FunctionCount; i++)
|
||||||
|
{
|
||||||
|
SendToDebug("Reading function " + i + " at: " + fs.Position);
|
||||||
|
// TODO: ADD TO FUNCTION LIST (How do we identify it later?)
|
||||||
|
// Note! Absolute position
|
||||||
|
myFunctionBlock.CodeChunkPointer[i] = BitConverter.ToUInt32(br_read(4), 0) + myHeader.GFR;
|
||||||
|
SendToDebug("Fuction " + i + " code chunk position: " + myFunctionBlock.CodeChunkPointer[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// STATE FRAME BLOCK
|
||||||
|
// Always right after FUNCTION BLOCK
|
||||||
|
SendToDebug("Reading STATE BLOCK at: " + myHeader.SR);
|
||||||
|
fs.Seek(myHeader.SR, SeekOrigin.Begin);
|
||||||
|
LSO_Struct.StateFrameBlock myStateFrameBlock = new LSO_Struct.StateFrameBlock();
|
||||||
|
myStateFrameBlock.StateCount = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
if (myStateFrameBlock.StateCount > 0)
|
||||||
|
{
|
||||||
|
// Initialize array
|
||||||
|
myStateFrameBlock.StatePointer = new LSO_Struct.StatePointerBlock[myStateFrameBlock.StateCount];
|
||||||
|
for (int i = 0; i < myStateFrameBlock.StateCount; i++)
|
||||||
|
{
|
||||||
|
SendToDebug("Reading STATE POINTER BLOCK " + (i+1) + " at: " + fs.Position);
|
||||||
|
// Position is relative to state frame
|
||||||
|
myStateFrameBlock.StatePointer[i].Location = myHeader.SR + BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myStateFrameBlock.StatePointer[i].EventMask = new System.Collections.BitArray(br_read(8));
|
||||||
|
SendToDebug("Pointer: " + myStateFrameBlock.StatePointer[i].Location);
|
||||||
|
SendToDebug("Total potential EventMask bits: " + myStateFrameBlock.StatePointer[i].EventMask.Count);
|
||||||
|
|
||||||
|
//// Read STATE BLOCK
|
||||||
|
//long CurPos = fs.Position;
|
||||||
|
//fs.Seek(CurPos, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// STATE BLOCK
|
||||||
|
// For each StateFrameBlock there is one StateBlock with multiple event handlers
|
||||||
|
|
||||||
|
if (myStateFrameBlock.StateCount > 0)
|
||||||
|
{
|
||||||
|
// Go through all State Frame Pointers found
|
||||||
|
for (int i = 0; i < myStateFrameBlock.StateCount; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
fs.Seek(myStateFrameBlock.StatePointer[i].Location, SeekOrigin.Begin);
|
||||||
|
SendToDebug("Reading STATE BLOCK " + (i + 1) + " at: " + fs.Position);
|
||||||
|
|
||||||
|
// READ: STATE BLOCK HEADER
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock = new LSO_Struct.StateBlock();
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock.StartPos = (UInt32)fs.Position; // Note
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock.HeaderSize = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock.Unknown = br_read(1)[0];
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock.EndPos = (UInt32)fs.Position; // Note
|
||||||
|
SendToDebug("State block Start Pos: " + myStateFrameBlock.StatePointer[i].StateBlock.StartPos);
|
||||||
|
SendToDebug("State block Header Size: " + myStateFrameBlock.StatePointer[i].StateBlock.HeaderSize);
|
||||||
|
SendToDebug("State block Header End Pos: " + myStateFrameBlock.StatePointer[i].StateBlock.EndPos);
|
||||||
|
|
||||||
|
// We need to count number of bits flagged in EventMask?
|
||||||
|
|
||||||
|
|
||||||
|
// for each bit in myStateFrameBlock.StatePointer[i].EventMask
|
||||||
|
|
||||||
|
// ADDING TO ALL RIGHT NOW, SHOULD LIMIT TO ONLY THE ONES IN USE
|
||||||
|
//TODO: Create event hooks
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers = new LSO_Struct.StateBlockHandler[myStateFrameBlock.StatePointer[i].EventMask.Count - 1];
|
||||||
|
for (int ii = 0; ii < myStateFrameBlock.StatePointer[i].EventMask.Count - 1; ii++)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (myStateFrameBlock.StatePointer[i].EventMask.Get(ii) == true)
|
||||||
|
{
|
||||||
|
// We got an event
|
||||||
|
// READ: STATE BLOCK HANDLER
|
||||||
|
SendToDebug("Reading STATE BLOCK " + (i + 1) + " HANDLER matching EVENT MASK " + ii + " (" + ((LSO_Enums.Event_Mask_Values)ii).ToString() + ") at: " + fs.Position);
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer = myStateFrameBlock.StatePointer[i].StateBlock.EndPos + BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CallFrameSize = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
SendToDebug("Reading STATE BLOCK " + (i + 1) + " HANDLER EVENT MASK " + ii + " (" + ((LSO_Enums.Event_Mask_Values)ii).ToString() + ") Code Chunk Pointer: " + myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer);
|
||||||
|
SendToDebug("Reading STATE BLOCK " + (i + 1) + " HANDLER EVENT MASK " + ii + " (" + ((LSO_Enums.Event_Mask_Values)ii).ToString() + ") Call Frame Size: " + myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CallFrameSize );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//// READ FUNCTION CODE CHUNKS
|
||||||
|
//// Functions + Function start pos (GFR)
|
||||||
|
//// TODO: Somehow be able to identify and reference this
|
||||||
|
//LSO_Struct.CodeChunk[] myFunctionCodeChunk;
|
||||||
|
//if (myFunctionBlock.FunctionCount > 0)
|
||||||
|
//{
|
||||||
|
// myFunctionCodeChunk = new LSO_Struct.CodeChunk[myFunctionBlock.FunctionCount];
|
||||||
|
// for (int i = 0; i < myFunctionBlock.FunctionCount; i++)
|
||||||
|
// {
|
||||||
|
// SendToDebug("Reading Function Code Chunk " + i);
|
||||||
|
// myFunctionCodeChunk[i] = GetCodeChunk((UInt32)myFunctionBlock.CodeChunkPointer[i]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
//}
|
||||||
|
// READ EVENT CODE CHUNKS
|
||||||
|
LSO_Struct.CodeChunk[] myEventCodeChunk;
|
||||||
|
if (myStateFrameBlock.StateCount > 0)
|
||||||
|
{
|
||||||
|
myEventCodeChunk = new LSO_Struct.CodeChunk[myStateFrameBlock.StateCount];
|
||||||
|
for (int i = 0; i < myStateFrameBlock.StateCount; i++)
|
||||||
|
{
|
||||||
|
// TODO: Somehow organize events and functions so they can be found again,
|
||||||
|
// two level search ain't no good
|
||||||
|
for (int ii = 0; ii < myStateFrameBlock.StatePointer[i].EventMask.Count - 1; ii++)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer > 0)
|
||||||
|
{
|
||||||
|
SendToDebug("Reading Event Code Chunk state " + i + ", event " + (LSO_Enums.Event_Mask_Values)ii);
|
||||||
|
|
||||||
|
|
||||||
|
// Override a Method / Function
|
||||||
|
string eventname = "event_" + (LSO_Enums.Event_Mask_Values)ii;
|
||||||
|
SendToDebug("CLR:" + eventname + ":MethodBuilder methodBuilder = typeBuilder.DefineMethod...");
|
||||||
|
MethodBuilder methodBuilder = typeBuilder.DefineMethod(eventname,
|
||||||
|
MethodAttributes.Private | MethodAttributes.Virtual,
|
||||||
|
typeof(void),
|
||||||
|
new Type[] { typeof(object) });
|
||||||
|
|
||||||
|
SendToDebug("CLR:" + eventname + ":typeBuilder.DefineMethodOverride(methodBuilder...");
|
||||||
|
typeBuilder.DefineMethodOverride(methodBuilder,
|
||||||
|
typeof(LSL_CLRInterface.LSLScript).GetMethod(eventname));
|
||||||
|
|
||||||
|
// Create the IL generator
|
||||||
|
|
||||||
|
SendToDebug("CLR:" + eventname + ":ILGenerator il = methodBuilder.GetILGenerator();");
|
||||||
|
ILGenerator il = methodBuilder.GetILGenerator();
|
||||||
|
|
||||||
|
|
||||||
|
LSO_Struct.CodeChunk myECC =
|
||||||
|
GetCodeChunk(myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer, il, eventname);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Close
|
||||||
|
br.Close();
|
||||||
|
fs.Close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private LSO_Struct.HeapBlock GetHeap(UInt32 pos)
|
||||||
|
{
|
||||||
|
// HEAP BLOCK
|
||||||
|
// TODO:? Special read for strings/keys (null terminated) and lists (pointers to other HEAP entries)
|
||||||
|
SendToDebug("Reading HEAP BLOCK at: " + pos);
|
||||||
|
fs.Seek(pos, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
LSO_Struct.HeapBlock myHeapBlock = new LSO_Struct.HeapBlock();
|
||||||
|
myHeapBlock.DataBlockSize = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeapBlock.ObjectType = br_read(1)[0];
|
||||||
|
myHeapBlock.ReferenceCount = BitConverter.ToUInt16(br_read(2), 0);
|
||||||
|
myHeapBlock.Data = br_read(getObjectSize(myHeapBlock.ObjectType));
|
||||||
|
|
||||||
|
SendToDebug("Heap Block Data Block Size: " + myHeapBlock.DataBlockSize);
|
||||||
|
SendToDebug("Heap Block ObjectType: " + ((LSO_Enums.Variable_Type_Codes)myHeapBlock.ObjectType).ToString());
|
||||||
|
SendToDebug("Heap Block Reference Count: " + myHeapBlock.ReferenceCount);
|
||||||
|
|
||||||
|
return myHeapBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private byte[] br_read(int len)
|
||||||
|
{
|
||||||
|
if (len <= 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] bytes = new byte[len];
|
||||||
|
for (int i = len - 1; i > -1; i--)
|
||||||
|
bytes[i] = br.ReadByte();
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
SendToDebug("Exception: " + e.ToString());
|
||||||
|
throw (e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//private byte[] br_read_smallendian(int len)
|
||||||
|
//{
|
||||||
|
// byte[] bytes = new byte[len];
|
||||||
|
// br.Read(bytes,0, len);
|
||||||
|
// return bytes;
|
||||||
|
//}
|
||||||
|
|
||||||
|
private int getObjectSize(byte ObjectType)
|
||||||
|
{
|
||||||
|
switch (ObjectType)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
case 7:
|
||||||
|
return 4;
|
||||||
|
case 5:
|
||||||
|
return 12;
|
||||||
|
case 6:
|
||||||
|
return 16;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void SendToDebug(string Message)
|
||||||
|
{
|
||||||
|
if (Debug == true)
|
||||||
|
Console.WriteLine("Debug: " + Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private string Read_String()
|
||||||
|
{
|
||||||
|
string ret = "";
|
||||||
|
byte reader = br_read(1)[0];
|
||||||
|
while (reader != 0x000)
|
||||||
|
{
|
||||||
|
ret += (char)reader;
|
||||||
|
reader = br_read(1)[0];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads a code chunk into structure and returns it.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pos">Absolute position in file. REMEMBER TO ADD myHeader.GFR!</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private LSO_Struct.CodeChunk GetCodeChunk(UInt32 pos, ILGenerator il, string eventname)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CLR TRY
|
||||||
|
*/
|
||||||
|
//SendToDebug("CLR:" + eventname + ":il.BeginExceptionBlock()");
|
||||||
|
il.BeginExceptionBlock();
|
||||||
|
|
||||||
|
// Push "Hello World!" string to stack
|
||||||
|
//SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Ldstr...");
|
||||||
|
il.Emit(OpCodes.Ldstr, "Starting CLR dynamic execution of: " + eventname);
|
||||||
|
|
||||||
|
// Push Console.WriteLine command to stack ... Console.WriteLine("Hello World!");
|
||||||
|
//SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call...");
|
||||||
|
il.Emit(OpCodes.Call, typeof(Console).GetMethod
|
||||||
|
("WriteLine", new Type[] { typeof(string) }));
|
||||||
|
|
||||||
|
|
||||||
|
LSO_Struct.CodeChunk myCodeChunk = new LSO_Struct.CodeChunk();
|
||||||
|
|
||||||
|
SendToDebug("Reading Function Code Chunk at: " + pos);
|
||||||
|
fs.Seek(pos, SeekOrigin.Begin);
|
||||||
|
myCodeChunk.CodeChunkHeaderSize = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
SendToDebug("CodeChunk Header Size: " + myCodeChunk.CodeChunkHeaderSize );
|
||||||
|
// Read until null
|
||||||
|
myCodeChunk.Comment = Read_String();
|
||||||
|
SendToDebug("Function comment: " + myCodeChunk.Comment);
|
||||||
|
myCodeChunk.ReturnType = br_read(1)[0];
|
||||||
|
SendToDebug("Return type: " + (LSO_Enums.Variable_Type_Codes)myCodeChunk.ReturnType);
|
||||||
|
// TODO: How to determine number of codechunks -- does this method work?
|
||||||
|
myCodeChunk.CodeChunkArguments = new System.Collections.Generic.List<LSO_Struct.CodeChunkArgument>();
|
||||||
|
byte reader = br_read(1)[0];
|
||||||
|
reader = br_read(1)[0];
|
||||||
|
int ccount = 0;
|
||||||
|
while (reader != 0x000)
|
||||||
|
{
|
||||||
|
ccount++;
|
||||||
|
SendToDebug("Reading Code Chunk Argument " + ccount);
|
||||||
|
LSO_Struct.CodeChunkArgument CCA = new LSO_Struct.CodeChunkArgument();
|
||||||
|
CCA.FunctionReturnType = reader;
|
||||||
|
reader = br_read(1)[0];
|
||||||
|
CCA.NullString = reader;
|
||||||
|
myCodeChunk.CodeChunkArguments.Add(CCA);
|
||||||
|
SendToDebug("Code Chunk Argument " + ccount + " return type: " + (LSO_Enums.Variable_Type_Codes)CCA.FunctionReturnType);
|
||||||
|
}
|
||||||
|
// End marker is 0x000
|
||||||
|
myCodeChunk.EndMarker = reader;
|
||||||
|
// TODO: How to read and identify following code
|
||||||
|
// TODO: Code is read until a return of some sort is found
|
||||||
|
bool FoundRet = false;
|
||||||
|
while (FoundRet == false)
|
||||||
|
{
|
||||||
|
//reader = br_read(1)[0];
|
||||||
|
//UInt16 opcode = BitConverter.ToUInt16(br_read(1),0);
|
||||||
|
UInt16 opcode = br_read(1)[0];
|
||||||
|
//long rPos = fs.Position;
|
||||||
|
SendToDebug("OPCODE: " + ((LSO_Enums.Operation_Table)opcode).ToString());
|
||||||
|
switch (opcode)
|
||||||
|
{
|
||||||
|
// LONG
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.POPARG:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.STORE:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.STORES:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.STOREL:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.STOREV:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.STOREQ:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.STOREG:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.STOREGS:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.STOREGL:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.STOREGV:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.STOREGQ:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.LOADP:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.LOADSP:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.LOADLP:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.LOADVP:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.LOADQP:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.PUSH:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.PUSHS:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.PUSHL:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.PUSHV:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.PUSHQ:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.PUSHG:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.PUSHGS:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.PUSHGL:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.PUSHGV:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.PUSHGQ:
|
||||||
|
SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0));
|
||||||
|
break;
|
||||||
|
// BYTE
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.PUSHARGB:
|
||||||
|
SendToDebug("Param1: " + br_read(1)[0]);
|
||||||
|
break;
|
||||||
|
// INTEGER
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.PUSHARGI:
|
||||||
|
// TODO: What is size of integer?
|
||||||
|
SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0));
|
||||||
|
break;
|
||||||
|
// FLOAT
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.PUSHARGF:
|
||||||
|
// TODO: What is size of float?
|
||||||
|
SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0));
|
||||||
|
break;
|
||||||
|
// STRING
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.PUSHARGS:
|
||||||
|
string s = Read_String();
|
||||||
|
SendToDebug("Param1: " + s);
|
||||||
|
il.Emit(OpCodes.Ldstr, s);
|
||||||
|
break;
|
||||||
|
// VECTOR z,y,x
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.PUSHARGV:
|
||||||
|
SendToDebug("Param1 Z: " + BitConverter.ToUInt32(br_read(4),0));
|
||||||
|
SendToDebug("Param1 Y: " + BitConverter.ToUInt32(br_read(4),0));
|
||||||
|
SendToDebug("Param1 X: " + BitConverter.ToUInt32(br_read(4),0));
|
||||||
|
break;
|
||||||
|
// ROTATION s,z,y,x
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.PUSHARGQ:
|
||||||
|
SendToDebug("Param1 S: " + BitConverter.ToUInt32(br_read(4),0));
|
||||||
|
SendToDebug("Param1 Z: " + BitConverter.ToUInt32(br_read(4),0));
|
||||||
|
SendToDebug("Param1 Y: " + BitConverter.ToUInt32(br_read(4),0));
|
||||||
|
SendToDebug("Param1 X: " + BitConverter.ToUInt32(br_read(4),0));
|
||||||
|
break;
|
||||||
|
// LONG
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.PUSHARGE:
|
||||||
|
SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0));
|
||||||
|
break;
|
||||||
|
// BYTE
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.ADD:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.SUB:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.MUL:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.DIV:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.MOD:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.EQ:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.NEQ:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.LEQ:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.GEQ:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.LESS:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.GREATER:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.BOOLOR:
|
||||||
|
SendToDebug("Param1: " + br_read(1)[0]);
|
||||||
|
break;
|
||||||
|
// LONG
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.JUMP:
|
||||||
|
SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0));
|
||||||
|
break;
|
||||||
|
// BYTE, LONG
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.JUMPIF:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.JUMPNIF:
|
||||||
|
SendToDebug("Param1: " + br_read(1)[0]);
|
||||||
|
SendToDebug("Param2: " + BitConverter.ToUInt32(br_read(4),0));
|
||||||
|
break;
|
||||||
|
// LONG
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.STATE:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.CALL:
|
||||||
|
SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0));
|
||||||
|
break;
|
||||||
|
// BYTE
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.CAST:
|
||||||
|
SendToDebug("Param1: " + br_read(1)[0]);
|
||||||
|
break;
|
||||||
|
// LONG
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.STACKTOS:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.STACKTOL:
|
||||||
|
SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0));
|
||||||
|
break;
|
||||||
|
// BYTE
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.PRINT:
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.CALLLIB:
|
||||||
|
SendToDebug("Param1: " + br_read(1)[0]);
|
||||||
|
break;
|
||||||
|
// SHORT
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.CALLLIB_TWO_BYTE:
|
||||||
|
// TODO: What is size of short?
|
||||||
|
UInt16 _i = BitConverter.ToUInt16(br_read(2), 0);
|
||||||
|
SendToDebug("Param1: " + _i);
|
||||||
|
switch (_i)
|
||||||
|
{
|
||||||
|
case (UInt16)LSO_Enums.BuiltIn_Functions.llSay:
|
||||||
|
il.Emit(OpCodes.Call, typeof(Console).GetMethod
|
||||||
|
("WriteLine", new Type[] { typeof(string) }));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
// RETURN
|
||||||
|
case (UInt16)LSO_Enums.Operation_Table.RETURN:
|
||||||
|
SendToDebug("Last OPCODE was return command. Code chunk execution complete.");
|
||||||
|
FoundRet = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//fs.Seek(rPos, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CATCH
|
||||||
|
*/
|
||||||
|
SendToDebug("CLR:" + eventname + ":il.BeginCatchBlock(typeof(Exception));");
|
||||||
|
il.BeginCatchBlock(typeof(Exception));
|
||||||
|
|
||||||
|
// Push "Hello World!" string to stack
|
||||||
|
SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Ldstr...");
|
||||||
|
il.Emit(OpCodes.Ldstr, "Execption executing dynamic CLR function " + eventname + ": ");
|
||||||
|
|
||||||
|
//call void [mscorlib]System.Console::WriteLine(string)
|
||||||
|
SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call...");
|
||||||
|
il.Emit(OpCodes.Call, typeof(Console).GetMethod
|
||||||
|
("Write", new Type[] { typeof(string) }));
|
||||||
|
|
||||||
|
//callvirt instance string [mscorlib]System.Exception::get_Message()
|
||||||
|
SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Callvirt...");
|
||||||
|
il.Emit(OpCodes.Callvirt, typeof(Exception).GetMethod
|
||||||
|
("get_Message"));
|
||||||
|
|
||||||
|
//call void [mscorlib]System.Console::WriteLine(string)
|
||||||
|
SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call...");
|
||||||
|
il.Emit(OpCodes.Call, typeof(Console).GetMethod
|
||||||
|
("WriteLine", new Type[] { typeof(string) }));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CLR END TRY
|
||||||
|
*/
|
||||||
|
//SendToDebug("CLR:" + eventname + ":il.EndExceptionBlock();");
|
||||||
|
il.EndExceptionBlock();
|
||||||
|
// Push "Return from current method, with return value if present" to stack
|
||||||
|
il.Emit(OpCodes.Ret);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return myCodeChunk;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenSim.ScriptEngines.LSL
|
||||||
|
{
|
||||||
|
static class LSO_Struct
|
||||||
|
{
|
||||||
|
|
||||||
|
public struct Header
|
||||||
|
{
|
||||||
|
public UInt32 TM;
|
||||||
|
public UInt32 IP;
|
||||||
|
public UInt32 VN;
|
||||||
|
public UInt32 BP;
|
||||||
|
public UInt32 SP;
|
||||||
|
public UInt32 HR;
|
||||||
|
public UInt32 HP;
|
||||||
|
public UInt32 CS;
|
||||||
|
public UInt32 NS;
|
||||||
|
public UInt32 CE;
|
||||||
|
public UInt32 IE;
|
||||||
|
public UInt32 ER;
|
||||||
|
public UInt32 FR;
|
||||||
|
public UInt32 SLR;
|
||||||
|
public UInt32 GVR;
|
||||||
|
public UInt32 GFR;
|
||||||
|
public UInt32 PR;
|
||||||
|
public UInt32 ESR;
|
||||||
|
public UInt32 SR;
|
||||||
|
public UInt64 NCE;
|
||||||
|
public UInt64 NIE;
|
||||||
|
public UInt64 NER;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct StaticBlock
|
||||||
|
{
|
||||||
|
public UInt32 Static_Chunk_Header_Size;
|
||||||
|
public byte ObjectType;
|
||||||
|
public byte Unknown;
|
||||||
|
public byte[] BlockVariable;
|
||||||
|
}
|
||||||
|
/* Not actually a structure
|
||||||
|
public struct StaticBlockVariable
|
||||||
|
{
|
||||||
|
public UInt32 Integer1;
|
||||||
|
public UInt32 Float1;
|
||||||
|
public UInt32 HeapPointer_String;
|
||||||
|
public UInt32 HeapPointer_Key;
|
||||||
|
public byte[] Vector_12;
|
||||||
|
public byte[] Rotation_16;
|
||||||
|
public UInt32 Pointer_List_Structure;
|
||||||
|
} */
|
||||||
|
public struct HeapBlock
|
||||||
|
{
|
||||||
|
public UInt32 DataBlockSize;
|
||||||
|
public byte ObjectType;
|
||||||
|
public UInt16 ReferenceCount;
|
||||||
|
public byte[] Data;
|
||||||
|
}
|
||||||
|
public struct StateFrameBlock
|
||||||
|
{
|
||||||
|
public UInt32 StateCount;
|
||||||
|
public StatePointerBlock[] StatePointer;
|
||||||
|
}
|
||||||
|
public struct StatePointerBlock
|
||||||
|
{
|
||||||
|
public UInt32 Location;
|
||||||
|
public System.Collections.BitArray EventMask;
|
||||||
|
public StateBlock StateBlock;
|
||||||
|
}
|
||||||
|
public struct StateBlock
|
||||||
|
{
|
||||||
|
public UInt32 StartPos;
|
||||||
|
public UInt32 EndPos;
|
||||||
|
public UInt32 HeaderSize;
|
||||||
|
public byte Unknown;
|
||||||
|
public StateBlockHandler[] StateBlockHandlers;
|
||||||
|
}
|
||||||
|
public struct StateBlockHandler
|
||||||
|
{
|
||||||
|
public UInt32 CodeChunkPointer;
|
||||||
|
public UInt32 CallFrameSize;
|
||||||
|
}
|
||||||
|
public struct FunctionBlock
|
||||||
|
{
|
||||||
|
public UInt32 FunctionCount;
|
||||||
|
public UInt32[] CodeChunkPointer;
|
||||||
|
}
|
||||||
|
public struct CodeChunk
|
||||||
|
{
|
||||||
|
public UInt32 CodeChunkHeaderSize;
|
||||||
|
public string Comment;
|
||||||
|
public System.Collections.Generic.List<CodeChunkArgument> CodeChunkArguments;
|
||||||
|
public byte EndMarker;
|
||||||
|
public byte ReturnType;
|
||||||
|
}
|
||||||
|
public struct CodeChunkArgument
|
||||||
|
{
|
||||||
|
public byte FunctionReturnType;
|
||||||
|
public byte NullString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,10 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Key = libsecondlife.LLUUID;
|
||||||
|
using Rotation = libsecondlife.LLQuaternion;
|
||||||
|
using Vector = libsecondlife.LLVector3;
|
||||||
|
|
||||||
|
|
||||||
using OpenSim.Region.Environment.Scenes;
|
using OpenSim.Region.Environment.Scenes;
|
||||||
|
|
||||||
|
@ -21,5 +25,111 @@ namespace OpenSim.Region.Environment.Scripting
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LSL Compatibility below
|
||||||
|
// remap LL* functions to OS*
|
||||||
|
public int osAbs(int val)
|
||||||
|
{
|
||||||
|
return Math.Abs(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float osAcos(float val)
|
||||||
|
{
|
||||||
|
return (float)Math.Acos(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Obsolete("Unimplemented")]
|
||||||
|
public void osAddToLandPassList(Key avatar, float hours)
|
||||||
|
{
|
||||||
|
OpenSim.Framework.Console.MainLog.Instance.Warn("Unimplemented function called by script: osAddToLandPassList(Key avatar, float hours)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Obsolete("Unimplemented")]
|
||||||
|
public void osAdjustSoundVolume(float volume)
|
||||||
|
{
|
||||||
|
OpenSim.Framework.Console.MainLog.Instance.Warn("Unimplemented function called by script: osAdjustSoundVolume(float volume)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Obsolete("Unimplemented")]
|
||||||
|
public void osAllowInventoryDrop(int add)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Obsolete("Unimplemented")]
|
||||||
|
public float osAngleBetween(Rotation a, Rotation b)
|
||||||
|
{
|
||||||
|
Axiom.Math.Quaternion axA = new Axiom.Math.Quaternion(a.W, a.X, a.Y, a.Z);
|
||||||
|
Axiom.Math.Quaternion axB = new Axiom.Math.Quaternion(b.W, b.X, b.Y, b.Z);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Obsolete("Unimplemented")]
|
||||||
|
public void osApplyImpulse(Vector force, int local)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Obsolete("Unimplemented")]
|
||||||
|
public void osApplyRotationalImpulse(Vector force, int local)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float osAsin(float val)
|
||||||
|
{
|
||||||
|
return (float)Math.Asin(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float osAtan2(float x, float y)
|
||||||
|
{
|
||||||
|
return (float)Math.Atan2(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Obsolete("Unimplemented")]
|
||||||
|
public void osAttachToAvatar(Key avatar, int attachmentPoint)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Obsolete("Unimplemented")]
|
||||||
|
public Key osAvatarOnSitTarget()
|
||||||
|
{
|
||||||
|
return Key.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rotation osAxes2Rot(Vector fwd, Vector left, Vector up)
|
||||||
|
{
|
||||||
|
Axiom.Math.Quaternion axQ = new Axiom.Math.Quaternion();
|
||||||
|
Axiom.Math.Vector3 axFwd = new Axiom.Math.Vector3(fwd.X, fwd.Y, fwd.Z);
|
||||||
|
Axiom.Math.Vector3 axLeft = new Axiom.Math.Vector3(left.X, left.Y, left.Z);
|
||||||
|
Axiom.Math.Vector3 axUp = new Axiom.Math.Vector3(up.X, up.Y, up.Z);
|
||||||
|
|
||||||
|
axQ.FromAxes(axFwd, axLeft, axUp);
|
||||||
|
|
||||||
|
return new Rotation(axQ.x, axQ.y, axQ.z, axQ.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rotation osAxisAngle2Rot(Vector axis, float angle)
|
||||||
|
{
|
||||||
|
Axiom.Math.Quaternion axQ = Axiom.Math.Quaternion.FromAngleAxis(angle, new Axiom.Math.Vector3(axis.X, axis.Y, axis.Z));
|
||||||
|
|
||||||
|
return new Rotation(axQ.x, axQ.y, axQ.z, axQ.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string osBase64ToString(string str)
|
||||||
|
{
|
||||||
|
Encoding enc = System.Text.Encoding.UTF8;
|
||||||
|
return enc.GetString(Convert.FromBase64String(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Obsolete("Unimplemented")]
|
||||||
|
public void osBreakAllLinks()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using OpenSim.Region.Environment.Scenes;
|
||||||
|
using libsecondlife;
|
||||||
|
using Key = libsecondlife.LLUUID;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Scripting
|
||||||
|
{
|
||||||
|
|
||||||
|
class ScriptInterpretedEvents
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue