From 9be896c8cec45279e71d341ef988b8249e2cbf36 Mon Sep 17 00:00:00 2001 From: Adam Frisby Date: Fri, 13 Jul 2007 17:14:30 +0000 Subject: * 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. --- .../Engines/LSLEngine/LSLHandler/Engine.cs | 140 +++++ .../LSLEngine/LSLHandler/LSL_CLRInterface.cs | 51 ++ .../Engines/LSLEngine/LSLHandler/LSO_Enums.cs | 485 ++++++++++++++++ .../Engines/LSLEngine/LSLHandler/LSO_Parser.cs | 608 +++++++++++++++++++++ .../Engines/LSLEngine/LSLHandler/LSO_Struct.cs | 105 ++++ .../Environment/Scenes/scripting/ScriptAPI.cs | 110 ++++ .../Scenes/scripting/ScriptInterpretedEvents.cs | 14 + 7 files changed, 1513 insertions(+) create mode 100644 OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/Engine.cs create mode 100644 OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSL_CLRInterface.cs create mode 100644 OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Enums.cs create mode 100644 OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Parser.cs create mode 100644 OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Struct.cs create mode 100644 OpenSim/Region/Environment/Scenes/scripting/ScriptInterpretedEvents.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/Engine.cs b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/Engine.cs new file mode 100644 index 0000000..814f15a --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/Engine.cs @@ -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); + + + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSL_CLRInterface.cs b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSL_CLRInterface.cs new file mode 100644 index 0000000..dc612ff --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSL_CLRInterface.cs @@ -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(); + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Enums.cs b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Enums.cs new file mode 100644 index 0000000..edeccdd --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Enums.cs @@ -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 + } + + } +} diff --git a/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Parser.cs b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Parser.cs new file mode 100644 index 0000000..5f2e3c1 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Parser.cs @@ -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; + + /// + /// Parse LSO file. + /// Reads LSO ByteCode into memory structures. + /// TODO: What else does it do? + /// + /// FileName of LSO ByteCode file + 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; + } + + /// + /// Reads a code chunk into structure and returns it. + /// + /// Absolute position in file. REMEMBER TO ADD myHeader.GFR! + /// + 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(); + 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; + + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Struct.cs b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Struct.cs new file mode 100644 index 0000000..3b91e9f --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Struct.cs @@ -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 CodeChunkArguments; + public byte EndMarker; + public byte ReturnType; + } + public struct CodeChunkArgument + { + public byte FunctionReturnType; + public byte NullString; + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/scripting/ScriptAPI.cs b/OpenSim/Region/Environment/Scenes/scripting/ScriptAPI.cs index fd601cb..894713f 100644 --- a/OpenSim/Region/Environment/Scenes/scripting/ScriptAPI.cs +++ b/OpenSim/Region/Environment/Scenes/scripting/ScriptAPI.cs @@ -1,6 +1,10 @@ using System; using System.Collections.Generic; using System.Text; +using Key = libsecondlife.LLUUID; +using Rotation = libsecondlife.LLQuaternion; +using Vector = libsecondlife.LLVector3; + using OpenSim.Region.Environment.Scenes; @@ -21,5 +25,111 @@ namespace OpenSim.Region.Environment.Scripting { 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; + } } } diff --git a/OpenSim/Region/Environment/Scenes/scripting/ScriptInterpretedEvents.cs b/OpenSim/Region/Environment/Scenes/scripting/ScriptInterpretedEvents.cs new file mode 100644 index 0000000..4a4d939 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/scripting/ScriptInterpretedEvents.cs @@ -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 + { + } +} -- cgit v1.1