* 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
Adam Frisby 2007-07-13 17:14:30 +00:00
parent 540549bd89
commit 9be896c8ce
7 changed files with 1513 additions and 0 deletions

View File

@ -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);
}
}
}

View File

@ -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();
}
}
}

View File

@ -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
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
} }
} }

View File

@ -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
{
}
}