//======================================================================== // // JavaLibrary.cpp - interface to the JVM via JNI. // // copyright 2001 Sony Online Entertainment // //======================================================================== #include "serverScript/FirstServerScript.h" #include "serverScript/JavaLibrary.h" #include "serverGame/AttribModNameManager.h" #include "serverGame/CellPermissions.h" #include "serverGame/ConfigServerGame.h" #include "serverGame/ConsoleManager.h" #include "serverGame/ContainerInterface.h" #include "serverGame/CreatureObject.h" #include "serverGame/GameServer.h" #include "serverGame/ManufactureSchematicObject.h" #include "serverGame/NameManager.h" #include "serverGame/PlanetObject.h" #include "serverGame/PlayerObject.h" #include "serverGame/Region.h" #include "serverGame/RegionMaster.h" #include "serverGame/ServerObjectTemplate.h" #include "serverGame/ServerWorld.h" #include "serverScript/ConfigServerScript.h" #include "serverScript/GameScriptObject.h" #include "serverScript/ScriptListEntry.h" #include "serverScript/ScriptParameters.h" #include "sharedDebug/DebugHelp.h" #include "sharedDebug/Profiler.h" #include "sharedFoundation/ConfigFile.h" #include "sharedFoundation/Crc.h" #include "sharedFoundation/DynamicVariable.h" #include "sharedFoundation/DynamicVariableList.h" #include "sharedFoundation/Os.h" #include "sharedGame/TextManager.h" #include "sharedLog/Log.h" #include "sharedNetworkMessages/ObjectMenuRequestData.h" //@todo move this header into a different library (sharedUserInterface) #include "sharedObject/NetworkIdManager.h" #include "sharedObject/Object.h" #include "sharedSynchronization/Semaphore.h" #include "sharedThread/RunThread.h" #include "sharedUtility/ValueDictionary.h" using namespace JNIWrappersNamespace; #if !defined(linux) && !defined(WIN32) #error Unsupported platform #endif #if !defined(JNI_IBM_JAVA) && defined(WIN32) //-- Justin Randall [1/21/2003 4:43:15 PM] -- // The scripting system simply will not work properly with // our linux servers running the ibm java vm if the win32 // server is not also using that vm. There are serialization // issues that render the game useless. Please do not // change this until the broken interaction between various // VM's has been rectified! //#error Unsupported Java VM #endif//JNI_IBM_JAVA //#undef JNI_IBM_JAVA #ifdef linux // shared library includes #include #include #endif #ifndef JNI_VERSION_1_2 #error JNI version 1.2 or better only! #endif //======================================================================== // macros //======================================================================== #define GET_CLASS(var, name) tempClass = ms_env->FindClass(name); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); WARNING(true, ("Unable to find Java class "#name)); return false; } var = static_cast(ms_env->NewGlobalRef(tempClass)); ms_env->DeleteLocalRef(tempClass); if (var == 0) { DEBUG_WARNING(true, ("Unable to create global reference for JavaLibrary " #var )); return false; } #define GET_FIELD(var, clazz, name, sig) var = ms_env->GetFieldID(clazz, name, sig); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); WARNING(true, ("Unable to find Java field "#name" for class "#clazz)); return false; } #define GET_METHOD(var, clazz, name, sig) var = ms_env->GetMethodID(clazz, name, sig); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); WARNING(true, ("Unable to find Java method "#name" for class "#clazz)); return false; } #define GET_STATIC_METHOD(var, clazz, name, sig) var = ms_env->GetStaticMethodID(clazz, name, sig); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); WARNING(true, ("Unable to find Java static method "#name" for class "#clazz)); return false; } #define FREE_CLASS(var) if (ms_env != NULL && var != NULL) { ms_env->DeleteGlobalRef(var); var = NULL; } //======================================================================== // local constants //======================================================================== // set path to jvm #if defined(WIN32) #define PATH_SEPARATOR ";" const char *JNI_DLL_PATH = "jvm.dll"; #else #define PATH_SEPARATOR ":" const char *JNI_DBG_DLL_PATH = "libjvm.so";//"libjvm_g.so"; const char *JNI_DLL_PATH = "libjvm.so"; #endif extern "C" { typedef jint (JNICALL *JNI_CREATEJAVAVMPROC)(JavaVM**, void**, void*); } //======================================================================== // JNI native function namespaces //======================================================================== namespace ScriptMethodsActionStatesNamespace { bool install(); } namespace ScriptMethodsAiNamespace { bool install(); } namespace ScriptMethodsAnimationNamespace { bool install(); } namespace ScriptMethodsAttributesNamespace { bool install(); } namespace ScriptMethodsAuctionNamespace { bool install(); } namespace ScriptMethodsBankNamespace { bool install(); } namespace ScriptMethodsBeastMasterNamespace { bool install(); } namespace ScriptMethodsBroadcastingNamespace { bool install(); } namespace ScriptMethodsBuffBuilderNamespace { bool install(); } namespace ScriptMethodsBuffNamespace { bool install(); } namespace ScriptMethodsChatNamespace { bool install(); } namespace ScriptMethodsCityNamespace { bool install(); } namespace ScriptMethodsClientEffectNamespace { bool install(); } namespace ScriptMethodsClusterWideDataNamespace { bool install(); } namespace ScriptMethodsCollectionNamespace { bool install(); } namespace ScriptMethodsCombatNamespace { bool install(); } namespace ScriptMethodsCommandQueueNamespace { bool install(); } namespace ScriptMethodsConsoleNamespace { bool install(); } namespace ScriptMethodsContainersNamespace { bool install(); } namespace ScriptMethodsCraftingNamespace { bool install(); } namespace ScriptMethodsDataTableNamespace { bool install(); } namespace ScriptMethodsDebugNamespace { bool install(); } namespace ScriptMethodsDynamicVariableNamespace { bool install(); } namespace ScriptMethodsFormNamespace { bool install(); } namespace ScriptMethodsGlobalQueryNamespace { bool install(); } namespace ScriptMethodsGuildNamespace { bool install(); } namespace ScriptMethodsHateListNamespace { bool install(); } namespace ScriptMethodsHolocubeNamespace { bool install(); } namespace ScriptMethodsHyperspaceNamespace { bool install(); } namespace ScriptMethodsImageDesignNamespace { bool install(); } namespace ScriptMethodsInstallationNamespace { bool install(); } namespace ScriptMethodsInterestNamespace { bool install(); } namespace ScriptMethodsInteriorsNamespace { bool install(); } namespace ScriptMethodsJediNamespace { bool install(); } namespace ScriptMethodsMapNamespace { bool install(); } namespace ScriptMethodsMentalStatesNamespace { bool install(); } namespace ScriptMethodsMenuNamespace { bool install(); } namespace ScriptMethodsMissionNamespace { bool install(); } namespace ScriptMethodsMoneyNamespace { bool install(); } namespace ScriptMethodsMountNamespace { bool install(); } namespace ScriptMethodsNewbieTutorialNamespace { bool install(); } namespace ScriptMethodsNotificationNamespace { bool install(); } namespace ScriptMethodsNpcNamespace { bool install(); } namespace ScriptMethodsObjectCreateNamespace { bool install(); } namespace ScriptMethodsObjectInfoNamespace { bool install(); } namespace ScriptMethodsObjectMoveNamespace { bool install(); } namespace ScriptMethodsPermissionsNamespace { bool install(); } namespace ScriptMethodsPilotNamespace { bool install(); } namespace ScriptMethodsPlanetNamespace { bool install(); } namespace ScriptMethodsPlayerAccountNamespace { bool install(); } namespace ScriptMethodsPlayerQuestNamespace { bool install(); } namespace ScriptMethodsPvpNamespace { bool install(); } namespace ScriptMethodsQuestNamespace { bool install(); } namespace ScriptMethodsRegionNamespace { bool install(); } namespace ScriptMethodsRegion3dNamespace { bool install(); } namespace ScriptMethodsRemoteDebugNamespace { bool install(); } namespace ScriptMethodsResourceNamespace { bool install(); } namespace ScriptMethodsScriptNamespace { bool install(); } namespace ScriptMethodsServerUINamespace { bool install(); } namespace ScriptMethodsShipNamespace { bool install(); } namespace ScriptMethodsSkillNamespace { bool install(); } namespace ScriptMethodsSpawnerNamespace { bool install(); } namespace ScriptMethodsStringNamespace { bool install(); } namespace ScriptMethodsSystemNamespace { bool install(); } namespace ScriptMethodsTerrainNamespace { bool install(); } namespace ScriptMethodsTriggerVolumeNamespace { bool install(); } namespace ScriptMethodsVeteranNamespace { bool install(); } namespace ScriptMethodsWaypointNamespace { bool install(); } namespace ScriptMethodsWorldInfoNamespace { bool install(); } //======================================================================== // class JavaLibrary static members //======================================================================== JavaLibrary* JavaLibrary::ms_instance = NULL; int JavaLibrary::ms_javaVmType = JV_none; //void* JavaLibrary::ms_libHandle = NULL; JavaVM* JavaLibrary::ms_jvm = NULL; JNIEnv* JavaLibrary::ms_env = NULL; Thread * JavaLibrary::m_initializerThread = NULL; int JavaLibrary::ms_envCount = 0; int JavaLibrary::ms_currentRecursionCount = 0; bool JavaLibrary::ms_resetJava = false; jclass JavaLibrary::ms_clsScriptEntry = NULL; jobject JavaLibrary::ms_scriptEntry = NULL; jmethodID JavaLibrary::ms_midScriptEntryGetOwnerContext = NULL; jmethodID JavaLibrary::ms_midScriptEntryEnableLogging = NULL; jmethodID JavaLibrary::ms_midScriptEntryEnableNewJediTracking = NULL; jmethodID JavaLibrary::ms_midScriptEntryGetFreeMem = NULL; jclass JavaLibrary::ms_clsObject = NULL; jclass JavaLibrary::ms_clsClass = NULL; jmethodID JavaLibrary::ms_midClassGetName = NULL; jmethodID JavaLibrary::ms_midClassGetMethods = NULL; jclass JavaLibrary::ms_clsMethod = NULL; jmethodID JavaLibrary::ms_midMethodGetName = NULL; jclass JavaLibrary::ms_clsBoolean = NULL; jclass JavaLibrary::ms_clsBooleanArray = NULL; jmethodID JavaLibrary::ms_midBoolean = NULL; jmethodID JavaLibrary::ms_midBooleanBooleanValue = NULL; jclass JavaLibrary::ms_clsInteger = NULL; jclass JavaLibrary::ms_clsIntegerArray = NULL; jmethodID JavaLibrary::ms_midInteger = NULL; jmethodID JavaLibrary::ms_midIntegerIntValue = NULL; jclass JavaLibrary::ms_clsModifiableInt = NULL; jmethodID JavaLibrary::ms_midModifiableInt = NULL; jfieldID JavaLibrary::ms_fidModifiableIntData = NULL; jclass JavaLibrary::ms_clsFloat = NULL; jclass JavaLibrary::ms_clsFloatArray = NULL; jmethodID JavaLibrary::ms_midFloat = NULL; jmethodID JavaLibrary::ms_midFloatFloatValue = NULL; jclass JavaLibrary::ms_clsModifiableFloat = NULL; jmethodID JavaLibrary::ms_midModifiableFloat = NULL; jfieldID JavaLibrary::ms_fidModifiableFloatData = NULL; jclass JavaLibrary::ms_clsString = NULL; jclass JavaLibrary::ms_clsStringArray = NULL; jclass JavaLibrary::ms_clsMap = NULL; jmethodID JavaLibrary::ms_midMapPut = NULL; jmethodID JavaLibrary::ms_midMapGet = NULL; jclass JavaLibrary::ms_clsHashtable = NULL; jmethodID JavaLibrary::ms_midHashtable = NULL; jclass JavaLibrary::ms_clsThrowable = NULL; jclass JavaLibrary::ms_clsError = NULL; jclass JavaLibrary::ms_clsStackOverflowError = NULL; jmethodID JavaLibrary::ms_midThrowableGetMessage = NULL; jclass JavaLibrary::ms_clsThread = NULL; jmethodID JavaLibrary::ms_midThreadDumpStack = NULL; jclass JavaLibrary::ms_clsInternalScriptError = NULL; jclass JavaLibrary::ms_clsInternalScriptSeriousError = NULL; jfieldID JavaLibrary::ms_fidInternalScriptSeriousErrorError = NULL; jclass JavaLibrary::ms_clsDictionary = NULL; jmethodID JavaLibrary::ms_midDictionary = NULL; jmethodID JavaLibrary::ms_midDictionaryPack = NULL; jmethodID JavaLibrary::ms_midDictionaryUnpack = NULL; jmethodID JavaLibrary::ms_midDictionaryKeys = NULL; jmethodID JavaLibrary::ms_midDictionaryValues = NULL; jmethodID JavaLibrary::ms_midDictionaryPut = NULL; jmethodID JavaLibrary::ms_midDictionaryPutInt = NULL; jmethodID JavaLibrary::ms_midDictionaryPutFloat = NULL; jmethodID JavaLibrary::ms_midDictionaryPutBool = NULL; jmethodID JavaLibrary::ms_midDictionaryGet = NULL; jclass JavaLibrary::ms_clsCollection = NULL; jmethodID JavaLibrary::ms_midCollectionToArray = NULL; jclass JavaLibrary::ms_clsEnumeration = NULL; jmethodID JavaLibrary::ms_midEnumerationHasMoreElements = NULL; jmethodID JavaLibrary::ms_midEnumerationNextElement = NULL; jclass JavaLibrary::ms_clsBaseClassRangeInfo = NULL; jfieldID JavaLibrary::ms_fidBaseClassRangeInfoMinRange = NULL; jfieldID JavaLibrary::ms_fidBaseClassRangeInfoMaxRange = NULL; jclass JavaLibrary::ms_clsBaseClassAttackerResults = NULL; jfieldID JavaLibrary::ms_fidBaseClassAttackerResultsId = NULL; jfieldID JavaLibrary::ms_fidBaseClassAttackerResultsWeapon = NULL; jfieldID JavaLibrary::ms_fidBaseClassAttackerResultsPosture = NULL; jfieldID JavaLibrary::ms_fidBaseClassAttackerResultsTrailBits = NULL; jfieldID JavaLibrary::ms_fidBaseClassAttackerResultsClientEffectId = NULL; jfieldID JavaLibrary::ms_fidBaseClassAttackerResultsActionName = NULL; jfieldID JavaLibrary::ms_fidBaseClassAttackerResultsUseLocation = NULL; jfieldID JavaLibrary::ms_fidBaseClassAttackerResultsTargetLocation = NULL; jfieldID JavaLibrary::ms_fidBaseClassAttackerResultsTargetCell = NULL; jclass JavaLibrary::ms_clsBaseClassDefenderResults = NULL; jfieldID JavaLibrary::ms_fidBaseClassDefenderResultsId = NULL; jfieldID JavaLibrary::ms_fidBaseClassDefenderResultsPosture = NULL; jfieldID JavaLibrary::ms_fidBaseClassDefenderResultsResult = NULL; jfieldID JavaLibrary::ms_fidBaseClassDefenderResultsClientEffectId = NULL; jfieldID JavaLibrary::ms_fidBaseClassDefenderResultsHitLocation = NULL; jfieldID JavaLibrary::ms_fidBaseClassDefenderDamageAmount = NULL; jclass JavaLibrary::ms_clsDynamicVariable = NULL; jfieldID JavaLibrary::ms_fidDynamicVariableName = NULL; jfieldID JavaLibrary::ms_fidDynamicVariableData = NULL; jmethodID JavaLibrary::ms_midDynamicVariableInt = NULL; jmethodID JavaLibrary::ms_midDynamicVariableIntArray = NULL; jmethodID JavaLibrary::ms_midDynamicVariableFloat = NULL; jmethodID JavaLibrary::ms_midDynamicVariableFloatArray = NULL; jmethodID JavaLibrary::ms_midDynamicVariableString = NULL; jmethodID JavaLibrary::ms_midDynamicVariableStringArray = NULL; jmethodID JavaLibrary::ms_midDynamicVariableObjId = NULL; jmethodID JavaLibrary::ms_midDynamicVariableObjIdArray = NULL; jmethodID JavaLibrary::ms_midDynamicVariableLocation = NULL; jmethodID JavaLibrary::ms_midDynamicVariableLocationArray = NULL; jclass JavaLibrary::ms_clsDynamicVariableList = NULL; jmethodID JavaLibrary::ms_midDynamicVariableList = NULL; jmethodID JavaLibrary::ms_midDynamicVariableListSet = NULL; jmethodID JavaLibrary::ms_midDynamicVariableListSetInt = NULL; jmethodID JavaLibrary::ms_midDynamicVariableListSetIntArray = NULL; jmethodID JavaLibrary::ms_midDynamicVariableListSetFloat = NULL; jmethodID JavaLibrary::ms_midDynamicVariableListSetFloatArray = NULL; jmethodID JavaLibrary::ms_midDynamicVariableListSetString = NULL; jmethodID JavaLibrary::ms_midDynamicVariableListSetStringArray = NULL; jmethodID JavaLibrary::ms_midDynamicVariableListSetObjId = NULL; jmethodID JavaLibrary::ms_midDynamicVariableListSetObjIdArray = NULL; jmethodID JavaLibrary::ms_midDynamicVariableListSetLocation = NULL; jmethodID JavaLibrary::ms_midDynamicVariableListSetLocationArray = NULL; jmethodID JavaLibrary::ms_midDynamicVariableListSetStringId = NULL; jmethodID JavaLibrary::ms_midDynamicVariableListSetStringIdArray = NULL; jmethodID JavaLibrary::ms_midDynamicVariableListSetTransform = NULL; jmethodID JavaLibrary::ms_midDynamicVariableListSetTransformArray = NULL; jmethodID JavaLibrary::ms_midDynamicVariableListSetVector = NULL; jmethodID JavaLibrary::ms_midDynamicVariableListSetVectorArray = NULL; jclass JavaLibrary::ms_clsObjId = NULL; jclass JavaLibrary::ms_clsObjIdArray = NULL; jmethodID JavaLibrary::ms_midObjIdGetValue = NULL; jmethodID JavaLibrary::ms_midObjIdGetObjId = NULL; jmethodID JavaLibrary::ms_midObjIdClearObjId = NULL; jmethodID JavaLibrary::ms_midObjIdFlagDestroyed = NULL; jmethodID JavaLibrary::ms_midObjIdSetAuthoritative = NULL; jmethodID JavaLibrary::ms_midObjIdSetLoaded = NULL; jmethodID JavaLibrary::ms_midObjIdSetInitialized = NULL; jmethodID JavaLibrary::ms_midObjIdSetLoggedIn = NULL; jmethodID JavaLibrary::ms_midObjIdPackAllDeltaScriptVars = NULL; jmethodID JavaLibrary::ms_midObjIdSetScriptVarInt = NULL; jmethodID JavaLibrary::ms_midObjIdSetScriptVarFloat = NULL; jmethodID JavaLibrary::ms_midObjIdSetScriptVarString = NULL; jmethodID JavaLibrary::ms_midObjIdClearScriptVars = NULL; jmethodID JavaLibrary::ms_midObjIdPackScriptVars = NULL; jmethodID JavaLibrary::ms_midObjIdUnpackDeltaScriptVars = NULL; jmethodID JavaLibrary::ms_midObjIdUnpackScriptVars = NULL; jmethodID JavaLibrary::ms_midObjIdAttachScript = NULL; jmethodID JavaLibrary::ms_midObjIdAttachScripts = NULL; jmethodID JavaLibrary::ms_midObjIdDetachScript = NULL; jmethodID JavaLibrary::ms_midObjIdDetachAllScripts = NULL; jclass JavaLibrary::ms_clsStringId = NULL; jmethodID JavaLibrary::ms_midStringId = NULL; jclass JavaLibrary::ms_clsStringIdArray = NULL; jfieldID JavaLibrary::ms_fidStringIdTable = NULL; jfieldID JavaLibrary::ms_fidStringIdAsciiId = NULL; jfieldID JavaLibrary::ms_fidStringIdIndexId = NULL; jclass JavaLibrary::ms_clsModifiableStringId = NULL; jclass JavaLibrary::ms_clsAttribute = NULL; jmethodID JavaLibrary::ms_midAttribute = NULL; jfieldID JavaLibrary::ms_fidAttributeType = NULL; jfieldID JavaLibrary::ms_fidAttributeValue = NULL; jclass JavaLibrary::ms_clsAttribMod = NULL; jmethodID JavaLibrary::ms_midAttribMod = NULL; jfieldID JavaLibrary::ms_fidAttribModName = NULL; jfieldID JavaLibrary::ms_fidAttribModSkill = NULL; jfieldID JavaLibrary::ms_fidAttribModType = NULL; jfieldID JavaLibrary::ms_fidAttribModValue = NULL; jfieldID JavaLibrary::ms_fidAttribModTime = NULL; jfieldID JavaLibrary::ms_fidAttribModAttack = NULL; jfieldID JavaLibrary::ms_fidAttribModDecay = NULL; jfieldID JavaLibrary::ms_fidAttribModFlags = NULL; jclass JavaLibrary::ms_clsMentalState = NULL; jmethodID JavaLibrary::ms_midMentalState = NULL; jfieldID JavaLibrary::ms_fidMentalStateType = NULL; jfieldID JavaLibrary::ms_fidMentalStateValue = NULL; jclass JavaLibrary::ms_clsMentalStateMod = NULL; jmethodID JavaLibrary::ms_midMentalStateMod = NULL; jfieldID JavaLibrary::ms_fidMentalStateModType = NULL; jfieldID JavaLibrary::ms_fidMentalStateModValue = NULL; jfieldID JavaLibrary::ms_fidMentalStateModTime = NULL; jfieldID JavaLibrary::ms_fidMentalStateModAttack = NULL; jfieldID JavaLibrary::ms_fidMentalStateModDecay = NULL; jclass JavaLibrary::ms_clsLocation = NULL; jclass JavaLibrary::ms_clsLocationArray = NULL; jfieldID JavaLibrary::ms_fidLocationX = NULL; jfieldID JavaLibrary::ms_fidLocationY = NULL; jfieldID JavaLibrary::ms_fidLocationZ = NULL; jfieldID JavaLibrary::ms_fidLocationArea = NULL; jfieldID JavaLibrary::ms_fidLocationCell = NULL; jmethodID JavaLibrary::ms_midRunOne = NULL; jmethodID JavaLibrary::ms_midRunAll = NULL; jmethodID JavaLibrary::ms_midCallMessages = NULL; jmethodID JavaLibrary::ms_midRunConsoleHandler = NULL; jmethodID JavaLibrary::ms_midUnload = NULL; jmethodID JavaLibrary::ms_midGetClass = NULL; jmethodID JavaLibrary::ms_midGetScriptFunctions = NULL; jclass JavaLibrary::ms_clsMenuInfo = NULL; jmethodID JavaLibrary::ms_midMenuInfo = NULL; jmethodID JavaLibrary::ms_midMenuInfoSetMenuItemsInternal = NULL; jmethodID JavaLibrary::ms_midMenuInfoGetMenuItemsInternal = NULL; jclass JavaLibrary::ms_clsMenuInfoData = NULL; jmethodID JavaLibrary::ms_midMenuInfoData = NULL; jfieldID JavaLibrary::ms_fidMenuInfoDataId; jfieldID JavaLibrary::ms_fidMenuInfoDataParent; jfieldID JavaLibrary::ms_fidMenuInfoDataType; jfieldID JavaLibrary::ms_fidMenuInfoDataLabel; jfieldID JavaLibrary::ms_fidMenuInfoDataEnabled; jfieldID JavaLibrary::ms_fidMenuInfoDataServerNotify; jclass JavaLibrary::ms_clsCustomVar; jmethodID JavaLibrary::ms_midCustomVarObjIdStringInt; jclass JavaLibrary::ms_clsRangedIntCustomVar; jmethodID JavaLibrary::ms_midRangedIntCustomVar; jclass JavaLibrary::ms_clsPalcolorCustomVar; jmethodID JavaLibrary::ms_midPalcolorCustomVar; jclass JavaLibrary::ms_clsColor; jmethodID JavaLibrary::ms_midColor; jclass JavaLibrary::ms_clsDraftSchematic = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicCategory = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicComplexity = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicSlots = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicAttribs = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicExperimentalAttribs = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicCustomizations = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicAttribMap = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicObjectTemplateCreated = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicScripts = NULL; jclass JavaLibrary::ms_clsDraftSchematicSlot = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicSlotName = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicSlotOption = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicSlotIngredientType = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicSlotIngredientName = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicSlotIngredients = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicSlotComplexity = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicSlotAmountRequired = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicSlotAppearance = NULL; jclass JavaLibrary::ms_clsDraftSchematicAttrib = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicAttribName = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicAttribMinValue = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicAttribMaxValue = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicAttribResourceMaxValue = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicAttribCurrentValue = NULL; jclass JavaLibrary::ms_clsDraftSchematicSimpleIngredient = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicSimpleIngredientIngredient = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicSimpleIngredientCount = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicSimpleIngredientSource = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicSimpleIngredientXpType = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicSimpleIngredientXpAmount = NULL; jclass JavaLibrary::ms_clsDraftSchematicCustom = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicCustomName = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicCustomValue = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicCustomMinValue = NULL; jfieldID JavaLibrary::ms_fidDraftSchematicCustomMaxValue = NULL; //jfieldID JavaLibrary::ms_fidDraftSchematicCustomLocked = NULL; jclass JavaLibrary::ms_clsMapLocation = NULL; jmethodID JavaLibrary::ms_midMapLocation = NULL; jclass JavaLibrary::ms_clsRegion = NULL; jmethodID JavaLibrary::ms_midRegion = NULL; jfieldID JavaLibrary::ms_fidRegionName = NULL; jfieldID JavaLibrary::ms_fidRegionPlanet = NULL; jclass JavaLibrary::ms_clsCombatEngine = NULL; jclass JavaLibrary::ms_clsCombatEngineCombatantData = NULL; jfieldID JavaLibrary::ms_fidCombatEngineCombatantDataPos = NULL; jfieldID JavaLibrary::ms_fidCombatEngineCombatantDataWorldPos = NULL; jfieldID JavaLibrary::ms_fidCombatEngineCombatantDataRadius = NULL; jfieldID JavaLibrary::ms_fidCombatEngineCombatantDataIsCreature = NULL; jfieldID JavaLibrary::ms_fidCombatEngineCombatantDataPosture = NULL; jfieldID JavaLibrary::ms_fidCombatEngineCombatantDataLocomotion = NULL; jfieldID JavaLibrary::ms_fidCombatEngineCombatantDataScriptMod = NULL; jclass JavaLibrary::ms_clsCombatEngineAttackerData = NULL; jfieldID JavaLibrary::ms_fidCombatEngineAttackerDataWeaponSkill = NULL; jfieldID JavaLibrary::ms_fidCombatEngineAttackerDataAims = NULL; jclass JavaLibrary::ms_clsCombatEngineDefenderData = NULL; jfieldID JavaLibrary::ms_fidCombatEngineDefenderDataCombatSkeleton = NULL; jfieldID JavaLibrary::ms_fidCombatEngineDefenderDataCover = NULL; jfieldID JavaLibrary::ms_fidCombatEngineDefenderDataHitLocationChances = NULL; jclass JavaLibrary::ms_clsCombatEngineWeaponData = NULL; jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataId = NULL; jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataMinDamage = NULL; jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataMaxDamage = NULL; jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataWeaponType = NULL; jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataAttackType = NULL; jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataDamageType = NULL; jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataElementalType = NULL; jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataElementalValue = NULL; jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataAttackSpeed = NULL; jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataWoundChance = NULL; jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataAccuracy = NULL; jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataMinRange = NULL; jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataMaxRange = NULL; jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataDamageRadius = NULL; jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataAttackCost = NULL; jfieldID JavaLibrary::ms_fidCombatEngineWeaponDataIsDisabled = NULL; jclass JavaLibrary::ms_clsCombatEngineHitResult; jfieldID JavaLibrary::ms_fidCombatEngineHitResultSuccess; jfieldID JavaLibrary::ms_fidCombatEngineHitResultCritical; jfieldID JavaLibrary::ms_fidCombatEngineHitResultGlancing; jfieldID JavaLibrary::ms_fidCombatEngineHitResultCrushing; jfieldID JavaLibrary::ms_fidCombatEngineHitResultStrikethrough; jfieldID JavaLibrary::ms_fidCombatEngineHitResultStrikethroughAmount; jfieldID JavaLibrary::ms_fidCombatEngineHitResultEvadeResult; jfieldID JavaLibrary::ms_fidCombatEngineHitResultEvadeAmount; jfieldID JavaLibrary::ms_fidCombatEngineHitResultBlockResult; jfieldID JavaLibrary::ms_fidCombatEngineHitResultBlock; jfieldID JavaLibrary::ms_fidCombatEngineHitResultDodge; jfieldID JavaLibrary::ms_fidCombatEngineHitResultParry; jfieldID JavaLibrary::ms_fidCombatEngineHitResultProc; jfieldID JavaLibrary::ms_fidCombatEngineHitResultBaseRoll; jfieldID JavaLibrary::ms_fidCombatEngineHitResultFinalRoll; jfieldID JavaLibrary::ms_fidCombatEngineHitResultAttackVal; jfieldID JavaLibrary::ms_fidCombatEngineHitResultCanSee; jfieldID JavaLibrary::ms_fidCombatEngineHitResultHitLocation; jfieldID JavaLibrary::ms_fidCombatEngineHitResultDamage; jfieldID JavaLibrary::ms_fidCombatEngineHitResultDamageType; jfieldID JavaLibrary::ms_fidCombatEngineHitResultRawDamage; jfieldID JavaLibrary::ms_fidCombatEngineHitResultElementalDamage; jfieldID JavaLibrary::ms_fidCombatEngineHitResultElementalDamageType; jfieldID JavaLibrary::ms_fidCombatEngineHitResultBleedDamage; jfieldID JavaLibrary::ms_fidCombatEngineHitResultCritDamage; jfieldID JavaLibrary::ms_fidCombatEngineHitResultBlockedDamage; jfieldID JavaLibrary::ms_fidCombatEngineHitResultBlockingArmor; jfieldID JavaLibrary::ms_fidCombatEngineHitResultBleedingChance; jclass JavaLibrary::ms_clsTransform = NULL; jclass JavaLibrary::ms_clsTransformArray = NULL; jmethodID JavaLibrary::ms_midTransform = NULL; jfieldID JavaLibrary::ms_fidTransformMatrix = NULL; jclass JavaLibrary::ms_clsVector = NULL; jclass JavaLibrary::ms_clsVectorArray = NULL; jfieldID JavaLibrary::ms_fidVectorX = NULL; jfieldID JavaLibrary::ms_fidVectorY = NULL; jfieldID JavaLibrary::ms_fidVectorZ = NULL; jclass JavaLibrary::ms_clsResourceDensity = NULL; jfieldID JavaLibrary::ms_fidResourceDensityResourceType = NULL; jfieldID JavaLibrary::ms_fidResourceDensityDensity = NULL; jclass JavaLibrary::ms_clsResourceAttribute = NULL; jfieldID JavaLibrary::ms_fidResourceAttributeName = NULL; jfieldID JavaLibrary::ms_fidResourceAttributeValue = NULL; jclass JavaLibrary::ms_clsLibrarySpaceTransition = NULL; jmethodID JavaLibrary::ms_midLibrarySpaceTransitionSetPlayerOvert = NULL; jmethodID JavaLibrary::ms_midLibrarySpaceTransitionClearOvertStatus = NULL; ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // CS handlers jclass JavaLibrary::ms_clsLibraryDump = NULL; jmethodID JavaLibrary::ms_midLibraryDumpDumpTargetInfo = NULL; jclass JavaLibrary::ms_clsLibraryGMLib = NULL; jmethodID JavaLibrary::ms_midLibraryGMLibFreeze = NULL; jmethodID JavaLibrary::ms_midLibraryGMLibUnfreeze = NULL; ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// int JavaLibrary::ms_loaded = 0; Semaphore * JavaLibrary::ms_shutdownJava = NULL; int JavaLibrary::GlobalInstances::ms_stringIdIndex = 0; int JavaLibrary::GlobalInstances::ms_attribModIndex = 0; int JavaLibrary::GlobalInstances::ms_mentalStateModIndex = 0; int JavaLibrary::GlobalInstances::ms_modifiableIntIndex = 0; int JavaLibrary::GlobalInstances::ms_modifiableFloatIndex = 0; int JavaLibrary::GlobalInstances::ms_modifiableStringIdIndex = 0; GlobalRefPtr JavaLibrary::GlobalInstances::ms_stringIds[MAX_STRING_ID_PARAMS]; GlobalRefPtr JavaLibrary::GlobalInstances::ms_attribMods[MAX_ATTRIB_MOD_PARAMS]; GlobalRefPtr JavaLibrary::GlobalInstances::ms_mentalStateMods[MAX_MENTAL_STATE_MOD_PARAMS]; GlobalRefPtr JavaLibrary::GlobalInstances::ms_modifiableInts[MAX_MODIFIABLE_INT_PARAMS]; GlobalRefPtr JavaLibrary::GlobalInstances::ms_modifiableFloats[MAX_MODIFIABLE_FLOAT_PARAMS]; GlobalRefPtr JavaLibrary::GlobalInstances::ms_modifiableStringIds[MAX_MODIFIABLE_STRING_ID_PARAMS]; GlobalRefPtr JavaLibrary::GlobalInstances::ms_menuInfo; GlobalArrayRefPtr JavaLibrary::ms_attribModList[MAX_RECURSION_COUNT]; GlobalArrayRefPtr JavaLibrary::ms_mentalStateModList[MAX_RECURSION_COUNT]; // ====================================================================== std::set s_profileSections; //======================================================================== // class JavaLibrary methods //======================================================================== void JavaLibrary::throwScriptException(char const * const format, ...) { va_list va; va_start(va, format); throwScriptException(format, va); va_end(va); } void JavaLibrary::throwScriptException(char const * const format, va_list va) { DEBUG_FATAL(!ms_env, ("JavaLibrary::throwScriptException: ms_env is NULL")); if (ms_env) { char buffer[1024]; vsnprintf(buffer, sizeof(buffer), format, va); buffer[sizeof(buffer) - 1] = 0; throwInternalScriptError(buffer); } } #ifdef linux static struct sigaction OrgSa; // original signal handler, used to generate core files static struct sigaction JavaSa; // Java signal handler, used to generate Java exceptions static struct sigaction OurSa; // our signal handler #endif void JavaLibrary::fatalHandler(int signum) { #ifdef linux fprintf(stderr, "In JavaLibrary::fatalHandler, signal %d: ", signum); if (signum == SIGSEGV && ms_jvm) { // try to see if our call stack came from C or Java void *frameAddress = __builtin_frame_address(0); // the address that generated the segfault is stored at an offset of 0x44 from // the frame address // @todo: find documentation on the offset to verify it is stable void *crashAddress1 = *((void**)((static_cast(frameAddress)) + 0x44)); // pass the crash address to addr2line to get the file name where the crash occurred static const int BUFLEN = 2048; char lib1[BUFLEN], lib2[BUFLEN]; char file1[BUFLEN], file2[BUFLEN]; int line1, line2; bool result1 = DebugHelp::lookupAddress(reinterpret_cast(crashAddress1), lib1, file1, BUFLEN, line1); // do a second test based on the return address // it turns out that in some java crashes we don't even have 2 return // addresses, so check 0 and 1 just to make sure bool result2 = false; void *crashAddress2a = NULL; void *crashAddress2b = NULL; void *crashAddress2c = NULL; void *frameAddressA = NULL; void *frameAddressB = NULL; uint32 frameAddressHigh = (reinterpret_cast(frameAddress) >> 16); crashAddress2a = __builtin_return_address(0); if (crashAddress2a != NULL) { frameAddressA = __builtin_frame_address(1); if (frameAddressA != NULL && (reinterpret_cast(frameAddressA) >> 16 == frameAddressHigh)) { crashAddress2b = __builtin_return_address(1); if (crashAddress2b != NULL) { frameAddressB = __builtin_frame_address(2); if (frameAddressB != NULL && (reinterpret_cast(frameAddressB) >> 16 == frameAddressHigh)) { crashAddress2c = __builtin_return_address(2); if (crashAddress2c != NULL) { result2 = DebugHelp::lookupAddress(reinterpret_cast( crashAddress2c), lib2, file2, BUFLEN, line2); } } } } } bool javaCrash = true; if ((result1 || result2) && strstr(lib1, "libjvm.so") == NULL && strstr(lib2, "libjvm.so") == NULL) { if (result1 && result2) { fprintf(stderr, "I crashed in a file: <%s>, line %d, or in file " "<%s>, line %d, going to core.\n", file1, line1, file2, line2); } else if (result1) { fprintf(stderr, "I crashed in a file: <%s>, line %d, going to core.\n", file1, line1); } else { fprintf(stderr, "I crashed in a file: <%s>, line %d, going to core.\n", file2, line2); } javaCrash = false; } if (javaCrash) { fprintf(stderr, "I think I crashed in Java, calling the Java segfault hanlder.\n"); IGNORE_RETURN(sigaction(SIGSEGV, &JavaSa, NULL)); IGNORE_RETURN(pthread_kill(pthread_self(), SIGSEGV)); } else { // destroy Java threads // @note apathy - this pthread method is not in later versions of glibc //pthread_kill_other_threads_np(); ms_instance = NULL; ms_env = NULL; ms_jvm = NULL; // restore original signal handler and rethrow signal IGNORE_RETURN(sigaction(SIGSEGV, &OrgSa, NULL)); IGNORE_RETURN(pthread_kill(pthread_self(), SIGSEGV)); } } else ::abort(); #endif } // JavaLibrary::fatalHandler /** * Class constructor. */ JavaLibrary::JavaLibrary(void) { int i; if (ms_instance != NULL || ms_loaded != 0) return; ms_shutdownJava = new Semaphore(); for (i = 0; i < MAX_RECURSION_COUNT; ++i) { ms_attribModList[i] = GlobalArrayRef::cms_nullPtr; ms_mentalStateModList[i] = GlobalArrayRef::cms_nullPtr; } // initialize the GlobalInstances class static members for (i = 0; i < MAX_STRING_ID_PARAMS; ++i) GlobalInstances::ms_stringIds[i] = GlobalRef::cms_nullPtr; for (i = 0; i < MAX_ATTRIB_MOD_PARAMS; ++i) GlobalInstances::ms_attribMods[i] = GlobalRef::cms_nullPtr; for (i = 0; i < MAX_MENTAL_STATE_MOD_PARAMS; ++i) GlobalInstances::ms_mentalStateMods[i] = GlobalRef::cms_nullPtr; for (i = 0; i < MAX_MODIFIABLE_INT_PARAMS; ++i) GlobalInstances::ms_modifiableInts[i] = GlobalRef::cms_nullPtr; for (i = 0; i < MAX_MODIFIABLE_FLOAT_PARAMS; ++i) GlobalInstances::ms_modifiableFloats[i] = GlobalRef::cms_nullPtr; for (i = 0; i < MAX_MODIFIABLE_STRING_ID_PARAMS; ++i) GlobalInstances::ms_modifiableStringIds[i] = GlobalRef::cms_nullPtr; m_initializerThread = new MemberFunctionThreadZero("JavaLibrary", *this, &JavaLibrary::initializeJavaThread); ThreadHandle tempThreadHandle(m_initializerThread); // for some obscure reason, the thread doesn't run unless you create a handle, but we don't need the handle for anything UNREF(tempThreadHandle); // wait until ms_loaded != 0; if it is 1, we have successfully initialized Java, // if it is not 1, there was an error while (ms_loaded == 0) Os::sleep(100); if (ms_loaded != 1) return; if (!connectToJava()) return; ms_instance = this; DEBUG_REPORT_LOG(true, ("Java initialized\n")); } // JavaLibrary::JavaLibrary /** * Class destructor. */ JavaLibrary::~JavaLibrary() { disconnectFromJava(); if (ms_shutdownJava != NULL) { // tell the initialize thread to shut down if (ms_loaded > 0) { ms_shutdownJava->signal(); while (ms_loaded > 0) Os::sleep(100); } delete ms_shutdownJava; ms_shutdownJava = NULL; } ms_instance = NULL; } // JavaLibrary::~JavaLibrary //---------------------------------------------------------------------- /** * Creates the singleton JavaLibrary instance. */ void JavaLibrary::install(void) { if (ms_instance == NULL) { JavaLibrary *lib = new JavaLibrary; if (lib != ms_instance) { if (ms_instance == NULL) { delete lib; if (ms_javaVmType != JV_none) FATAL (true, ("Unable to initialize Java")); } } } else DEBUG_REPORT_LOG(true, ("JavaLibrary::JavaLibrary error: dup instance\n")); } // JavaLibrary::install //---------------------------------------------------------------------- /** * Destroys the singleton JavaLibrary instance. */ void JavaLibrary::remove(void) { if (ms_instance != NULL) { JavaLibrary * temp = ms_instance; ms_instance = NULL; delete temp; s_profileSections.clear(); } } // JavaLibrary::remove //---------------------------------------------------------------------- /** * Entry point for the Java initialization thread. We create the Java VM from here, * and then wait until we get a signal to shut down Java. The main game thread will * connect to our VM via the connectToJava function. */ void JavaLibrary::initializeJavaThread() { if (ms_loaded != 0) { WARNING(true, ("JavaLibrary::initializeJavaThread called when already loaded!")); return; } const char *javaVMName = ConfigServerGame::getJavaVMName(); if (javaVMName == NULL || ( strcmp(javaVMName, "none") != 0 && strcmp(javaVMName, "ibm") != 0 && strcmp(javaVMName, "sun") != 0)) { FATAL(true, ("[ServerGame] javaVMName not defined. Valid values are: " "none, ibm, or sun")); } else if (strcmp(javaVMName, "ibm") == 0) { ms_javaVmType = JV_ibm; } else if (strcmp(javaVMName, "sun") == 0) { ms_javaVmType = JV_sun; } if (ms_javaVmType == JV_none) { DEBUG_REPORT_LOG(true, ("Scripting is disabled.\n")); ms_loaded = -1; return; } #ifdef linux // get the default signal handler IGNORE_RETURN(sigaction(SIGSEGV, NULL, &OrgSa)); if (ms_javaVmType == JV_ibm) { // check PATH to make sure that it has /usr/bin/java const char * env = getenv("PATH"); const char * bin = NULL; int envlen = 0; if (env != NULL) { bin = strstr(env, "/usr/java/bin"); envlen = strlen(env); } if (bin == NULL) { WARNING(true, ("/usr/java/bin not found in PATH which is needed for IBM Java VM. Adding it now")); char * tmpbuffer = new char[envlen + 128]; if (env) strcpy(tmpbuffer, env); strcat(tmpbuffer, ":/usr/java/bin"); setenv("PATH", tmpbuffer, 1); delete [] tmpbuffer; } // check LD_LIBRARY_PATH for /usr/java/jre/bin and /usr/java/jre/bin/classic env = getenv("LD_LIBRARY_PATH"); bin = NULL; envlen = 0; const char * classic = NULL; if (env != NULL) { bin = strstr(env, "/usr/java/jre/bin"); classic = strstr(env, "/usr/java/jre/bin/classic"); if (bin == classic && bin != NULL) bin = strstr(classic + 1, "/usr/java/jre/bin"); envlen = strlen(env); } if (bin == NULL || classic == NULL) { WARNING(true, ("/usr/java/jre/bin or /usr/java/jre/bin/classic not found " "in LD_LIBRARY_PATH, needed for IBM Java VM. Adding them both now.")); char * tmpbuffer = new char[envlen + 256]; memset(tmpbuffer, 0, envlen + 256); if (env) strcpy(tmpbuffer, env); strcat(tmpbuffer, ":/usr/java/jre/bin"); strcat(tmpbuffer, ":/usr/java/jre/bin/classic"); setenv("LD_LIBRARY_PATH", tmpbuffer, 1); delete [] tmpbuffer; } // check if LD_ASSUME_KERNEL is defined env = getenv("LD_ASSUME_KERNEL"); if (env == NULL || strcmp(env, "2.4.1") != 0) { // WARNING(true, ("LD_ASSUME_KERNEL=2.4.1 not set, Java may not run correctly")); } } #endif // linux // dynamically load the jni dll and JNI_CreateJavaVM void * libHandle = NULL; JNI_CREATEJAVAVMPROC JNI_CreateJavaVMProc; #if defined(WIN32) std::string dllPath = ConfigServerGame::getJavaLibPath(); HINSTANCE hVm = LoadLibrary(dllPath.c_str()); if (hVm == NULL) { FATAL(true, ("jvm open fail error: could not open %s", dllPath.c_str())); ms_loaded = -1; return; } libHandle = hVm; JNI_CreateJavaVMProc = (JNI_CREATEJAVAVMPROC)GetProcAddress(hVm, "JNI_CreateJavaVM"); //lint !e1924 C-style cast #else void *libVM = NULL; std::string dllPath = ConfigServerGame::getJavaLibPath(); libVM = dlopen(dllPath.c_str(), RTLD_LAZY); if (libVM == NULL) { FATAL(true, ("jvm open fail! error: %s", dlerror())); ms_loaded = -1; return; } libHandle = libVM; JNI_CreateJavaVMProc = (JNI_CREATEJAVAVMPROC)dlsym(libVM, "JNI_CreateJavaVM"); #endif if (JNI_CreateJavaVMProc == NULL) { FATAL(true, ("Error getting JNI_CreateJavaVM from jvm shared library")); ms_loaded = -1; return; } #if defined(_DEBUG) //&& defined(linux) #define REMOTE_DEBUG_ON #endif // set up the args to initialize the jvm std::string classPath = "-Djava.class.path="; // classPath += PATH_SEPARATOR; classPath += ConfigServerGame::getScriptPath(); // DEBUG_REPORT_LOG(true, ("Java class path = %s\n", classPath.c_str())); JavaVMInitArgs vm_args; JavaVMOption tempOption = {NULL, NULL}; std::vector options; char *jdwpBuffer = NULL; UNREF(jdwpBuffer); // classPath += PATH_SEPARATOR; // classPath += "/home/sjakab/temp/OptimizeitSuiteDemo/lib/optit.jar"; // tempOption.optionString = "-Xnoclassgc"; // options.push_back(tempOption); if (ConfigServerScript::hasJavaOptions()) { int const numberOfJavaOptions = ConfigServerScript::getNumberOfJavaOptions(); for (int i = 0; i < numberOfJavaOptions; ++i) { char const * p = ConfigServerScript::getJavaOptions(i); tempOption.optionString = const_cast(p); options.push_back(tempOption); } } else { // use options derived from config file settings // set up memory requirements tempOption.optionString = "-Xms128m"; options.push_back(tempOption); tempOption.optionString = "-Xmx512m"; options.push_back(tempOption); tempOption.optionString = "-Xss768k"; options.push_back(tempOption); if (ms_javaVmType == JV_ibm) { tempOption.optionString = "-Xoss768k"; options.push_back(tempOption); } if (ms_javaVmType == JV_ibm) { tempOption.optionString = "-Xcheck:jni"; options.push_back(tempOption); tempOption.optionString = "-Xcheck:nabounds"; options.push_back(tempOption); tempOption.optionString = "-Xrs"; options.push_back(tempOption); #ifndef WIN32 tempOption.optionString = "-Xgcpolicy:optavgpause"; options.push_back(tempOption); #endif } else { if (ConfigServerGame::getCompileScripts()) { tempOption.optionString = "-Xint"; options.push_back(tempOption); } tempOption.optionString = "-Xincgc"; options.push_back(tempOption); } if (ConfigServerGame::getUseVerboseJava()) { tempOption.optionString = "-verbose:jni"; options.push_back(tempOption); tempOption.optionString = "-verbose:gc"; options.push_back(tempOption); tempOption.optionString = "-verbose:class"; options.push_back(tempOption); } #ifdef JNI_VERSION_1_4 if (!ms_javaVmType == JV_ibm) { tempOption.optionString = "-Xrs"; options.push_back(tempOption); tempOption.optionString = "-Xcheck:jni"; options.push_back(tempOption); } if (ConfigServerGame::getLogJavaGc()) { tempOption.optionString = "-Xloggc:javagc.log"; options.push_back(tempOption); // tempOption.optionString = "-Xrunpri"; // options.push_back(tempOption); // tempOption.optionString = "-Xbootclasspath/a:/home/sjakab/temp/OptimizeitSuiteDemo/lib/oibcp.jar"; // options.push_back(tempOption); // tempOption.optionString = "-Xboundthreads"; // options.push_back(tempOption); // tempOption.optionString = "-Xrunhprof:heap=format=b"; // options.push_back(tempOption); } #endif #ifdef REMOTE_DEBUG_ON char *jdwpBuffer = NULL; if (ConfigServerGame::getUseRemoteDebugJava()) { if (ms_javaVmType == JV_ibm) { tempOption.optionString = "-Xnoagent"; options.push_back(tempOption); tempOption.optionString = "-Djava.compiler=NONE"; options.push_back(tempOption); } tempOption.optionString = "-Xdebug"; options.push_back(tempOption); // we need to copy the -Xrunjdwp parameter into a char buffer due to a bug // in the Java VM const char * jdwpString = "-Xrunjdwp:transport=dt_socket,server=y,suspend=n"; jdwpBuffer = new char[strlen(jdwpString) + 32]; strcpy(jdwpBuffer, jdwpString); if (strlen(ConfigServerGame::getJavaDebugPort()) > 0) { strcat(jdwpBuffer, ",address="); strcat(jdwpBuffer, ConfigServerGame::getJavaDebugPort()); } tempOption.optionString = jdwpBuffer; options.push_back(tempOption); } #endif // REMOTE_DEBUG_ON if (ConfigServerGame::getProfileScripts()) { if (ms_javaVmType == JV_ibm) { char profileBuffer[128]; strcpy(profileBuffer,"-Xrunhprof:cpu=times"); tempOption.optionString = profileBuffer; options.push_back(tempOption); } else { WARNING(true, ("profileScripts option enabled using Sun JVM. This option " "is only supported using the IBM JVM.")); } } } tempOption.optionString = const_cast(classPath.c_str()); options.push_back(tempOption); #ifdef JNI_VERSION_1_4 vm_args.version = JNI_VERSION_1_4; #else vm_args.version = JNI_VERSION_1_2; #endif vm_args.options = &options[0]; vm_args.nOptions = options.size(); vm_args.ignoreUnrecognized = JNI_FALSE; // create the JVM JNIEnv * env = NULL; jint result = (*JNI_CreateJavaVMProc)(&ms_jvm, reinterpret_cast(&env), &vm_args); #ifdef REMOTE_DEBUG_ON if (jdwpBuffer != NULL) { delete[] jdwpBuffer; jdwpBuffer = NULL; } #endif if (result != 0) { FATAL (true, ("Failed to CreateJavaVMProc: %d", result)); ms_loaded = -1; return; } ms_loaded = 1; #ifdef linux if (ConfigServerGame::getTrapScriptCrashes()) { //set up signal handler for fatals in linux OurSa.sa_handler = fatalHandler; sigemptyset(&OurSa.sa_mask); OurSa.sa_flags = 0; IGNORE_RETURN(sigaction(SIGSEGV, &OurSa, &JavaSa)); } #endif // wait until the main thread tells us to shutdown ms_shutdownJava->wait(); // clean up IGNORE_RETURN(ms_jvm->DestroyJavaVM()); ms_jvm = NULL; #ifdef linux if (ConfigServerGame::getTrapScriptCrashes()) { // restore the default signal handler IGNORE_RETURN(sigaction(SIGSEGV, &OrgSa, NULL)); } #endif #if defined(_WIN32) IGNORE_RETURN(FreeLibrary(static_cast(libHandle))); #elif defined(linux) dlclose(libHandle); #endif ms_loaded = 0; } // JavaLibrary::initializeJavaThread //---------------------------------------------------------------------- /** * Connects this thread to the Java VM and initializes our member vars that * reference Java objects. * * @return true on success, false if we were unable to connect to Java or * initialize our members */ bool JavaLibrary::connectToJava() { if (ms_jvm == 0) return false; // attach our thread to the VM jint result = ms_jvm->AttachCurrentThread(reinterpret_cast(&ms_env), NULL); if (result != 0) { FATAL(true, ("Failed to attach to the Java VM! Error code returned = %d", result)); return false; } int i; jmethodID constructor; LocalRefPtr localInstance; LocalObjectArrayRefPtr localArrayInstance; jclass tempClass; // set the local reference count limit int localRefLimit = ConfigServerGame::getJavaLocalRefLimit(); if (localRefLimit < 16) localRefLimit = 16; ms_env->EnsureLocalCapacity(localRefLimit); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } // get the script_entry class GET_CLASS(ms_clsScriptEntry, "script/script_entry"); GET_METHOD(constructor, ms_clsScriptEntry, "", "(Ljava/lang/String;ZZIIIZ)V"); GET_STATIC_METHOD(ms_midScriptEntryGetOwnerContext, ms_clsScriptEntry, "getOwnerContext", "()Lscript/obj_id;"); GET_STATIC_METHOD(ms_midScriptEntryEnableLogging, ms_clsScriptEntry, "enableScriptLogging", "(Z)V"); GET_STATIC_METHOD(ms_midScriptEntryEnableNewJediTracking, ms_clsScriptEntry, "enableNewJediTracking", "(Z)V"); GET_STATIC_METHOD(ms_midScriptEntryGetFreeMem, ms_clsScriptEntry, "getFreeMemory", "()J"); // create an instance of script_entry class to initialze the system on the Java side JavaString scriptPath(ConfigServerGame::getScriptPath()); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } jobject localEntry = ms_env->NewObject(ms_clsScriptEntry, constructor, scriptPath.getValue(), ConfigServerGame::getJavaConsoleDebugMessages(), ConfigServerGame::getCrashOnScriptError(), ConfigServerGame::getScriptWatcherWarnTime(), ConfigServerGame::getScriptWatcherInterruptTime(), ConfigServerGame::getScriptStackErrorLimit(), ConfigServerGame::getScriptStackErrorLevel() == 1); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } ms_scriptEntry = ms_env->NewGlobalRef(localEntry); ms_env->DeleteLocalRef(localEntry); // get the methodIDs for the runScript() and the unloadClass() methods GET_STATIC_METHOD(ms_midRunOne,ms_clsScriptEntry, "runScript", "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)I"); GET_STATIC_METHOD(ms_midRunAll, ms_clsScriptEntry, "runScripts", "(Ljava/lang/String;[Ljava/lang/Object;)I"); GET_STATIC_METHOD(ms_midCallMessages, ms_clsScriptEntry, "callMessageHandlers", "(Ljava/lang/String;JLscript/dictionary;)I"); GET_STATIC_METHOD(ms_midRunConsoleHandler, ms_clsScriptEntry, "runConsoleHandler", "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;"); GET_STATIC_METHOD(ms_midUnload, ms_clsScriptEntry, "unloadClass", "(Ljava/lang/String;)Z"); GET_STATIC_METHOD(ms_midGetClass, ms_clsScriptEntry, "getClass", "(Ljava/lang/String;)Ljava/lang/Class;"); GET_STATIC_METHOD(ms_midGetScriptFunctions, ms_clsScriptEntry, "getScriptFunctions", "(Ljava/lang/String;)[Ljava/lang/String;"); // get the class and method ids for java.lang.Object GET_CLASS(ms_clsObject, "java/lang/Object"); // get the class and method ids for java.lang.Class GET_CLASS(ms_clsClass, "java/lang/Class"); GET_METHOD(ms_midClassGetName, ms_clsClass, "getName", "()Ljava/lang/String;"); GET_METHOD(ms_midClassGetMethods, ms_clsClass, "getMethods", "()[Ljava/lang/reflect/Method;"); // get the class and method ids for java.reflect.Method GET_CLASS(ms_clsMethod, "java/lang/reflect/Method"); GET_METHOD(ms_midMethodGetName, ms_clsMethod, "getName", "()Ljava/lang/String;"); // get the class and constructor methodID for java.lang.Boolean GET_CLASS(ms_clsBoolean, "java/lang/Boolean"); GET_CLASS(ms_clsBooleanArray, "[Ljava/lang/Boolean;"); GET_METHOD(ms_midBoolean, ms_clsBoolean, "", "(Z)V"); GET_METHOD(ms_midBooleanBooleanValue, ms_clsBoolean, "booleanValue", "()Z"); // get the class and constructor methodID for java.lang.Integer GET_CLASS(ms_clsInteger, "java/lang/Integer"); GET_CLASS(ms_clsIntegerArray, "[Ljava/lang/Integer;"); GET_METHOD(ms_midInteger, ms_clsInteger, "", "(I)V"); GET_METHOD(ms_midIntegerIntValue, ms_clsInteger, "intValue", "()I"); // get the class and constructor methodID for modifiable_int GET_CLASS(ms_clsModifiableInt, "script/modifiable_int"); GET_FIELD(ms_fidModifiableIntData, ms_clsModifiableInt, "m_data", "I"); GET_METHOD(ms_midModifiableInt, ms_clsModifiableInt, "", "()V"); // create some global modifiable_int class instances to be used parameters for // events for (i = 0; i < MAX_MODIFIABLE_INT_PARAMS; ++i) { localInstance = createNewObject(ms_clsModifiableInt, ms_midModifiableInt); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } GlobalInstances::ms_modifiableInts[i] = GlobalRefPtr(new GlobalRef(*localInstance)); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } } // get the class and constructor methodID for java.lang.Float GET_CLASS(ms_clsFloat, "java/lang/Float"); GET_CLASS(ms_clsFloatArray, "[Ljava/lang/Float;"); GET_METHOD(ms_midFloat, ms_clsFloat, "", "(F)V"); GET_METHOD(ms_midFloatFloatValue, ms_clsFloat, "floatValue", "()F"); // get the class and constructor methodID for modifiable_float GET_CLASS(ms_clsModifiableFloat, "script/modifiable_float"); GET_FIELD(ms_fidModifiableFloatData, ms_clsModifiableFloat, "m_data", "F"); GET_METHOD(ms_midModifiableFloat, ms_clsModifiableFloat, "", "()V"); // create some global modifiable_float class instances to be used parameters for // events for (i = 0; i < MAX_MODIFIABLE_FLOAT_PARAMS; ++i) { localInstance = createNewObject(ms_clsModifiableFloat, ms_midModifiableFloat); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } GlobalInstances::ms_modifiableFloats[i] = GlobalRefPtr(new GlobalRef(*localInstance)); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } } // get the class for java.lang.String GET_CLASS(ms_clsString, "java/lang/String"); GET_CLASS(ms_clsStringArray, "[Ljava/lang/String;"); // get the class and methods for java.util.Map and java.util.Hashtable GET_CLASS(ms_clsMap, "java/util/Map"); GET_METHOD(ms_midMapPut, ms_clsMap, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); GET_METHOD(ms_midMapGet, ms_clsMap, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); GET_CLASS(ms_clsHashtable, "java/util/Hashtable"); GET_METHOD(ms_midHashtable, ms_clsHashtable, "", "()V"); GET_CLASS(ms_clsThrowable, "java/lang/Throwable"); GET_CLASS(ms_clsError, "java/lang/Error"); GET_CLASS(ms_clsStackOverflowError, "java/lang/StackOverflowError"); GET_METHOD(ms_midThrowableGetMessage, ms_clsThrowable, "getMessage", "()Ljava/lang/String;"); GET_CLASS(ms_clsThread, "java/lang/Thread"); GET_STATIC_METHOD(ms_midThreadDumpStack, ms_clsThread, "dumpStack", "()V"); GET_CLASS(ms_clsInternalScriptError, "script/internal_script_exception"); GET_CLASS(ms_clsInternalScriptSeriousError, "script/internal_script_error"); GET_FIELD(ms_fidInternalScriptSeriousErrorError, ms_clsInternalScriptSeriousError, "wrappedError", "Ljava/lang/Error;"); // get the class and methods for dictionary GET_CLASS(ms_clsDictionary, "script/dictionary"); GET_METHOD(ms_midDictionary, ms_clsDictionary, "", "()V"); GET_METHOD(ms_midDictionaryPack, ms_clsDictionary, "pack", "()[B"); GET_METHOD(ms_midDictionaryKeys, ms_clsDictionary, "keys", "()Ljava/util/Enumeration;"); GET_METHOD(ms_midDictionaryValues, ms_clsDictionary, "values", "()Ljava/util/Collection;"); GET_METHOD(ms_midDictionaryPut, ms_clsDictionary, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); GET_METHOD(ms_midDictionaryPutInt, ms_clsDictionary, "put", "(Ljava/lang/Object;I)Ljava/lang/Object;"); GET_METHOD(ms_midDictionaryPutBool, ms_clsDictionary, "put", "(Ljava/lang/Object;Z)Ljava/lang/Object;"); GET_METHOD(ms_midDictionaryPutFloat, ms_clsDictionary, "put", "(Ljava/lang/Object;F)Ljava/lang/Object;"); GET_METHOD(ms_midDictionaryGet, ms_clsDictionary, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); GET_STATIC_METHOD(ms_midDictionaryUnpack, ms_clsDictionary, "unpack", "([B)Lscript/dictionary;"); // get the class and methods for java.util.Collection GET_CLASS(ms_clsCollection, "java/util/Collection"); GET_METHOD(ms_midCollectionToArray, ms_clsCollection, "toArray", "()[Ljava/lang/Object;"); // get the class and methods for java.util.Enumeration GET_CLASS(ms_clsEnumeration, "java/util/Enumeration"); GET_METHOD(ms_midEnumerationHasMoreElements, ms_clsEnumeration, "hasMoreElements", "()Z"); GET_METHOD(ms_midEnumerationNextElement, ms_clsEnumeration, "nextElement", "()Ljava/lang/Object;"); // get the class, field ids and constructor methodIDs for obj_var GET_CLASS(ms_clsDynamicVariable, "script/obj_var"); GET_FIELD(ms_fidDynamicVariableName, ms_clsDynamicVariable, "m_name", "Ljava/lang/String;"); GET_FIELD(ms_fidDynamicVariableData, ms_clsDynamicVariable, "m_data", "Ljava/lang/Object;"); GET_METHOD(ms_midDynamicVariableInt, ms_clsDynamicVariable, "", "(Ljava/lang/String;I)V"); GET_METHOD(ms_midDynamicVariableIntArray, ms_clsDynamicVariable, "", "(Ljava/lang/String;[I)V"); GET_METHOD(ms_midDynamicVariableFloat, ms_clsDynamicVariable, "", "(Ljava/lang/String;F)V"); GET_METHOD(ms_midDynamicVariableFloatArray, ms_clsDynamicVariable, "", "(Ljava/lang/String;[F)V"); GET_METHOD(ms_midDynamicVariableString, ms_clsDynamicVariable, "", "(Ljava/lang/String;Ljava/lang/String;)V"); GET_METHOD(ms_midDynamicVariableStringArray, ms_clsDynamicVariable, "", "(Ljava/lang/String;[Ljava/lang/String;)V"); GET_METHOD(ms_midDynamicVariableObjId, ms_clsDynamicVariable, "", "(Ljava/lang/String;J)V"); GET_METHOD(ms_midDynamicVariableObjIdArray, ms_clsDynamicVariable, "", "(Ljava/lang/String;[J)V"); GET_METHOD(ms_midDynamicVariableLocation, ms_clsDynamicVariable, "", "(Ljava/lang/String;Lscript/location;)V"); GET_METHOD(ms_midDynamicVariableLocationArray, ms_clsDynamicVariable, "", "(Ljava/lang/String;[Lscript/location;)V"); // get the class, field ids and constructor methodIDs for obj_var_list GET_CLASS(ms_clsDynamicVariableList, "script/obj_var_list"); GET_METHOD(ms_midDynamicVariableList, ms_clsDynamicVariableList, "", "(Ljava/lang/String;I)V"); GET_METHOD(ms_midDynamicVariableListSet, ms_clsDynamicVariableList, "setObjVar", "(Lscript/obj_var;)Z"); GET_METHOD(ms_midDynamicVariableListSetInt, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;I)Z"); GET_METHOD(ms_midDynamicVariableListSetIntArray, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;[I)Z"); GET_METHOD(ms_midDynamicVariableListSetFloat, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;F)Z"); GET_METHOD(ms_midDynamicVariableListSetFloatArray, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;[F)Z"); GET_METHOD(ms_midDynamicVariableListSetString, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;Ljava/lang/String;)Z"); GET_METHOD(ms_midDynamicVariableListSetStringArray, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;[Ljava/lang/String;)Z"); GET_METHOD(ms_midDynamicVariableListSetObjId, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;J)Z"); GET_METHOD(ms_midDynamicVariableListSetObjIdArray, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;[J)Z"); GET_METHOD(ms_midDynamicVariableListSetLocation, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;Lscript/location;)Z"); GET_METHOD(ms_midDynamicVariableListSetLocationArray, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;[Lscript/location;)Z"); GET_METHOD(ms_midDynamicVariableListSetStringId, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;Lscript/string_id;)Z"); GET_METHOD(ms_midDynamicVariableListSetStringIdArray, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;[Lscript/string_id;)Z"); GET_METHOD(ms_midDynamicVariableListSetTransform, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;Lscript/transform;)Z"); GET_METHOD(ms_midDynamicVariableListSetTransformArray, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;[Lscript/transform;)Z"); GET_METHOD(ms_midDynamicVariableListSetVector, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;Lscript/vector;)Z"); GET_METHOD(ms_midDynamicVariableListSetVectorArray, ms_clsDynamicVariableList, "setObjVar", "(Ljava/lang/String;[Lscript/vector;)Z"); // get the class, field ids and constructor methodID for attribute GET_CLASS(ms_clsAttribute, "script/attribute"); GET_FIELD(ms_fidAttributeType, ms_clsAttribute, "m_type", "I"); GET_FIELD(ms_fidAttributeValue, ms_clsAttribute, "m_value", "I"); GET_METHOD(ms_midAttribute, ms_clsAttribute, "", "(II)V"); // get the class, field ids and constructor methodID for attribMod GET_CLASS(ms_clsAttribMod, "script/attrib_mod"); GET_FIELD(ms_fidAttribModName, ms_clsAttribMod, "m_name", "Ljava/lang/String;"); GET_FIELD(ms_fidAttribModSkill, ms_clsAttribMod, "m_skill", "Ljava/lang/String;"); GET_FIELD(ms_fidAttribModType, ms_clsAttribMod, "m_attrib", "I"); GET_FIELD(ms_fidAttribModValue, ms_clsAttribMod, "m_value", "I"); GET_FIELD(ms_fidAttribModTime, ms_clsAttribMod, "m_duration", "F"); GET_FIELD(ms_fidAttribModAttack, ms_clsAttribMod, "m_attack", "F"); GET_FIELD(ms_fidAttribModDecay, ms_clsAttribMod, "m_decay", "F"); GET_FIELD(ms_fidAttribModFlags, ms_clsAttribMod, "m_flags", "I"); GET_METHOD(ms_midAttribMod, ms_clsAttribMod, "", "()V"); // create some attribMod instances for use as script paramters for (i = 0; i < MAX_ATTRIB_MOD_PARAMS; ++i) { localInstance = createNewObject(ms_clsAttribMod, ms_midAttribMod); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } GlobalInstances::ms_attribMods[i] = GlobalRefPtr(new GlobalRef(*localInstance)); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } } // create the attribModList for (i = 0; i < MAX_RECURSION_COUNT; ++i) { localArrayInstance = createNewObjectArray(MAX_ATTRIB_MOD_PARAMS, ms_clsAttribMod); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } ms_attribModList[i] = GlobalArrayRefPtr(new GlobalArrayRef(*localArrayInstance)); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } } //------- // get the class, field ids and constructor methodID for mental state GET_CLASS(ms_clsMentalState, "script/mental_state"); GET_FIELD(ms_fidMentalStateType, ms_clsMentalState, "m_type", "I"); GET_FIELD(ms_fidMentalStateValue, ms_clsMentalState, "m_value", "F"); GET_METHOD(ms_midMentalState, ms_clsMentalState, "", "(IF)V"); // get the class, field ids and constructor methodID for mental_state_mod GET_CLASS(ms_clsMentalStateMod, "script/mental_state_mod"); GET_FIELD(ms_fidMentalStateModType, ms_clsMentalStateMod, "m_mental_state", "I"); GET_FIELD(ms_fidMentalStateModValue, ms_clsMentalStateMod, "m_value", "F"); GET_FIELD(ms_fidMentalStateModTime, ms_clsMentalStateMod, "m_duration", "F"); GET_FIELD(ms_fidMentalStateModAttack, ms_clsMentalStateMod, "m_attack", "F"); GET_FIELD(ms_fidMentalStateModDecay, ms_clsMentalStateMod, "m_decay", "F"); GET_METHOD(ms_midMentalStateMod, ms_clsMentalStateMod, "", "(IFFFF)V"); // create some mentalStateMod instances for use as script paramters for (i = 0; i < MAX_MENTAL_STATE_MOD_PARAMS; ++i) { localInstance = createNewObject(ms_clsMentalStateMod, ms_midMentalStateMod, 0, 0, 0, 0, 0); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } GlobalInstances::ms_mentalStateMods[i] = GlobalRefPtr(new GlobalRef(*localInstance)); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } } // create the mentalStateModList for (i = 0; i < MAX_RECURSION_COUNT; ++i) { localArrayInstance = createNewObjectArray(MAX_MENTAL_STATE_MOD_PARAMS, ms_clsMentalStateMod); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } ms_mentalStateModList[i] = GlobalArrayRefPtr(new GlobalArrayRef(*localArrayInstance)); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } } //---------------------------------------------------------------------- // MenuInfo GET_CLASS(ms_clsMenuInfo, "script/menu_info"); GET_METHOD(ms_midMenuInfo, ms_clsMenuInfo, "", "()V"); GET_METHOD(ms_midMenuInfoSetMenuItemsInternal, ms_clsMenuInfo, "setMenuItemsInternal", "([Lscript/menu_info_data;)Z"); GET_METHOD(ms_midMenuInfoGetMenuItemsInternal, ms_clsMenuInfo, "getMenuItemsInternal", "()[Ljava/lang/Object;"); //-- create the global instance for the menu_info { localInstance = createNewObject(ms_clsMenuInfo, ms_midMenuInfo); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } GlobalInstances::ms_menuInfo = GlobalRefPtr(new GlobalRef(*localInstance)); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } } //-- menu_info_data // GET_CLASS(ms_clsMenuInfoData, "script/menu_info_data"); GET_FIELD(ms_fidMenuInfoDataId, ms_clsMenuInfoData, "m_id", "I"); GET_FIELD(ms_fidMenuInfoDataParent, ms_clsMenuInfoData, "m_parent", "I"); GET_FIELD(ms_fidMenuInfoDataLabel, ms_clsMenuInfoData, "m_label", "Lscript/string_id;"); GET_FIELD(ms_fidMenuInfoDataType, ms_clsMenuInfoData, "m_type", "I"); GET_FIELD(ms_fidMenuInfoDataEnabled, ms_clsMenuInfoData, "m_enabled", "Z"); GET_FIELD(ms_fidMenuInfoDataServerNotify, ms_clsMenuInfoData, "m_serverNotify", "Z"); GET_METHOD(ms_midMenuInfoData, ms_clsMenuInfoData, "", "()V"); // // get class and fields for class draft_schematic // GET_CLASS(ms_clsDraftSchematic, "script/draft_schematic"); GET_FIELD(ms_fidDraftSchematicCategory, ms_clsDraftSchematic, "m_category", "I"); GET_FIELD(ms_fidDraftSchematicComplexity, ms_clsDraftSchematic, "m_complexity", "F"); GET_FIELD(ms_fidDraftSchematicSlots, ms_clsDraftSchematic, "m_slots", "[Lscript/draft_schematic$slot;"); GET_FIELD(ms_fidDraftSchematicAttribs, ms_clsDraftSchematic, "m_attribs", "[Lscript/draft_schematic$attribute;"); GET_FIELD(ms_fidDraftSchematicExperimentalAttribs, ms_clsDraftSchematic, "m_experimentalAttribs", "[Lscript/draft_schematic$attribute;"); GET_FIELD(ms_fidDraftSchematicCustomizations, ms_clsDraftSchematic, "m_customizations", "[Lscript/draft_schematic$custom;"); GET_FIELD(ms_fidDraftSchematicAttribMap, ms_clsDraftSchematic, "m_attribMap", "Ljava/util/Hashtable;"); GET_FIELD(ms_fidDraftSchematicObjectTemplateCreated, ms_clsDraftSchematic, "m_objectTemplateCreated", "I"); GET_FIELD(ms_fidDraftSchematicScripts, ms_clsDraftSchematic, "m_scripts", "[Ljava/lang/String;"); // get the draft_schematic.slot data GET_CLASS(ms_clsDraftSchematicSlot, "script/draft_schematic$slot"); GET_FIELD(ms_fidDraftSchematicSlotName, ms_clsDraftSchematicSlot, "name", "Lscript/string_id;"); GET_FIELD(ms_fidDraftSchematicSlotOption, ms_clsDraftSchematicSlot, "slotOption", "I"); GET_FIELD(ms_fidDraftSchematicSlotIngredientType, ms_clsDraftSchematicSlot, "ingredientType", "I"); GET_FIELD(ms_fidDraftSchematicSlotIngredientName, ms_clsDraftSchematicSlot, "ingredientName", "Ljava/lang/String;"); GET_FIELD(ms_fidDraftSchematicSlotIngredients, ms_clsDraftSchematicSlot, "ingredients", "[Lscript/draft_schematic$simple_ingredient;"); GET_FIELD(ms_fidDraftSchematicSlotComplexity, ms_clsDraftSchematicSlot, "complexity", "F"); GET_FIELD(ms_fidDraftSchematicSlotAmountRequired, ms_clsDraftSchematicSlot, "amountRequired", "I"); GET_FIELD(ms_fidDraftSchematicSlotAppearance, ms_clsDraftSchematicSlot, "appearance", "Ljava/lang/String;"); // get the draft_schematic.attribute data GET_CLASS(ms_clsDraftSchematicAttrib, "script/draft_schematic$attribute"); GET_FIELD(ms_fidDraftSchematicAttribName, ms_clsDraftSchematicAttrib, "name", "Lscript/string_id;"); GET_FIELD(ms_fidDraftSchematicAttribMinValue, ms_clsDraftSchematicAttrib, "minValue", "F"); GET_FIELD(ms_fidDraftSchematicAttribMaxValue, ms_clsDraftSchematicAttrib, "maxValue", "F"); GET_FIELD(ms_fidDraftSchematicAttribResourceMaxValue, ms_clsDraftSchematicAttrib, "resourceMaxValue", "F"); GET_FIELD(ms_fidDraftSchematicAttribCurrentValue, ms_clsDraftSchematicAttrib, "currentValue", "F"); // get the draft_schematic.simple_ingredient data GET_CLASS(ms_clsDraftSchematicSimpleIngredient, "script/draft_schematic$simple_ingredient"); GET_FIELD(ms_fidDraftSchematicSimpleIngredientIngredient, ms_clsDraftSchematicSimpleIngredient, "ingredient", "Lscript/obj_id;"); GET_FIELD(ms_fidDraftSchematicSimpleIngredientCount, ms_clsDraftSchematicSimpleIngredient, "count", "I"); GET_FIELD(ms_fidDraftSchematicSimpleIngredientSource, ms_clsDraftSchematicSimpleIngredient, "source", "Lscript/obj_id;"); GET_FIELD(ms_fidDraftSchematicSimpleIngredientXpType, ms_clsDraftSchematicSimpleIngredient, "xpType", "I"); GET_FIELD(ms_fidDraftSchematicSimpleIngredientXpAmount, ms_clsDraftSchematicSimpleIngredient, "xpAmount", "I"); // get the draft_schematic.custom data GET_CLASS(ms_clsDraftSchematicCustom, "script/draft_schematic$custom"); GET_FIELD(ms_fidDraftSchematicCustomName, ms_clsDraftSchematicCustom, "name", "Ljava/lang/String;"); GET_FIELD(ms_fidDraftSchematicCustomValue, ms_clsDraftSchematicCustom, "value", "I"); GET_FIELD(ms_fidDraftSchematicCustomMinValue, ms_clsDraftSchematicCustom, "minValue", "I"); GET_FIELD(ms_fidDraftSchematicCustomMaxValue, ms_clsDraftSchematicCustom, "maxValue", "I"); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // customization data // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GET_CLASS(ms_clsCustomVar, "script/custom_var"); GET_METHOD(ms_midCustomVarObjIdStringInt, ms_clsCustomVar, "", "(JLjava/lang/String;I)V"); GET_CLASS(ms_clsRangedIntCustomVar, "script/ranged_int_custom_var"); GET_METHOD(ms_midRangedIntCustomVar, ms_clsRangedIntCustomVar, "", "(JLjava/lang/String;III)V"); GET_CLASS(ms_clsPalcolorCustomVar, "script/palcolor_custom_var"); GET_METHOD(ms_midPalcolorCustomVar, ms_clsPalcolorCustomVar, "", "(JLjava/lang/String;III)V"); GET_CLASS(ms_clsColor, "script/color"); GET_METHOD(ms_midColor, ms_clsColor, "", "(IIII)V"); //---------------------------------------------------------------------- // get the class, field ids and constructor methodID for location GET_CLASS(ms_clsLocation, "script/location"); GET_CLASS(ms_clsLocationArray, "[Lscript/location;"); GET_FIELD(ms_fidLocationX, ms_clsLocation, "x", "F"); GET_FIELD(ms_fidLocationY, ms_clsLocation, "y", "F"); GET_FIELD(ms_fidLocationZ, ms_clsLocation, "z", "F"); GET_FIELD(ms_fidLocationArea, ms_clsLocation, "area", "Ljava/lang/String;"); GET_FIELD(ms_fidLocationCell, ms_clsLocation, "cell", "Lscript/obj_id;"); // get class and fields for map location GET_CLASS(ms_clsMapLocation, "script/map_location"); GET_METHOD(ms_midMapLocation, ms_clsMapLocation, "", "(JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;JJB)V"); // get class and fields for class region GET_CLASS(ms_clsRegion, "script/region"); GET_FIELD(ms_fidRegionName, ms_clsRegion, "m_name", "Ljava/lang/String;"); GET_FIELD(ms_fidRegionPlanet, ms_clsRegion, "m_planetName", "Ljava/lang/String;"); GET_METHOD(ms_midRegion, ms_clsRegion, "", "(Ljava/lang/String;IIIIIIIILjava/lang/String;)V"); // get class and fields for base_class.range_info GET_CLASS(ms_clsBaseClassRangeInfo, "script/base_class$range_info"); GET_FIELD(ms_fidBaseClassRangeInfoMinRange, ms_clsBaseClassRangeInfo, "minRange", "F"); GET_FIELD(ms_fidBaseClassRangeInfoMaxRange, ms_clsBaseClassRangeInfo, "maxRange", "F"); // get class and fields for base_class.attacker_results GET_CLASS(ms_clsBaseClassAttackerResults, "script/base_class$attacker_results"); GET_FIELD(ms_fidBaseClassAttackerResultsId, ms_clsBaseClassAttackerResults, "id", "Lscript/obj_id;"); GET_FIELD(ms_fidBaseClassAttackerResultsWeapon, ms_clsBaseClassAttackerResults, "weapon", "Lscript/obj_id;"); GET_FIELD(ms_fidBaseClassAttackerResultsPosture, ms_clsBaseClassAttackerResults, "endPosture", "I"); GET_FIELD(ms_fidBaseClassAttackerResultsTrailBits, ms_clsBaseClassAttackerResults, "m_trailBits", "I"); GET_FIELD(ms_fidBaseClassAttackerResultsClientEffectId, ms_clsBaseClassAttackerResults, "clientEffectId", "I"); GET_FIELD(ms_fidBaseClassAttackerResultsActionName, ms_clsBaseClassAttackerResults, "actionName", "I"); GET_FIELD(ms_fidBaseClassAttackerResultsUseLocation, ms_clsBaseClassAttackerResults, "useLocation", "Z"); GET_FIELD(ms_fidBaseClassAttackerResultsTargetLocation, ms_clsBaseClassAttackerResults, "targetLocation", "Lscript/vector;"); GET_FIELD(ms_fidBaseClassAttackerResultsTargetCell, ms_clsBaseClassAttackerResults, "targetCell", "Lscript/obj_id;"); // get class and fields for base_class.defender_results GET_CLASS(ms_clsBaseClassDefenderResults, "script/base_class$defender_results"); GET_FIELD(ms_fidBaseClassDefenderResultsId, ms_clsBaseClassDefenderResults, "id", "Lscript/obj_id;"); GET_FIELD(ms_fidBaseClassDefenderResultsPosture, ms_clsBaseClassDefenderResults, "endPosture", "I"); GET_FIELD(ms_fidBaseClassDefenderResultsResult, ms_clsBaseClassDefenderResults, "result", "I"); GET_FIELD(ms_fidBaseClassDefenderResultsClientEffectId, ms_clsBaseClassDefenderResults, "clientEffectId", "I"); GET_FIELD(ms_fidBaseClassDefenderResultsHitLocation, ms_clsBaseClassDefenderResults, "hitLocation", "I"); GET_FIELD(ms_fidBaseClassDefenderDamageAmount, ms_clsBaseClassDefenderResults, "damageAmount", "I"); // get class obj_id info GET_CLASS(ms_clsObjId, "script/obj_id"); GET_CLASS(ms_clsObjIdArray, "[Lscript/obj_id;"); GET_METHOD(ms_midObjIdGetValue, ms_clsObjId, "getValue", "()J"); GET_METHOD(ms_midObjIdSetAuthoritative, ms_clsObjId, "setAuthoritative", "(ZI)V"); GET_METHOD(ms_midObjIdSetLoaded, ms_clsObjId, "setLoaded", "()V"); GET_METHOD(ms_midObjIdSetInitialized, ms_clsObjId, "setInitialized", "()V"); GET_METHOD(ms_midObjIdSetLoggedIn, ms_clsObjId, "setLoggedIn", "(Z)V"); GET_METHOD(ms_midObjIdAttachScript, ms_clsObjId, "attachScript", "(Ljava/lang/String;)V"); GET_METHOD(ms_midObjIdAttachScripts, ms_clsObjId, "attachScript", "([Ljava/lang/String;)V"); GET_METHOD(ms_midObjIdDetachScript, ms_clsObjId, "detachScript", "(Ljava/lang/String;)V"); GET_METHOD(ms_midObjIdDetachAllScripts, ms_clsObjId, "detachAllScripts", "()V"); GET_METHOD(ms_midObjIdSetScriptVarInt, ms_clsObjId, "setScriptVar", "(Ljava/lang/String;I)V"); GET_METHOD(ms_midObjIdSetScriptVarFloat, ms_clsObjId, "setScriptVar", "(Ljava/lang/String;F)V"); GET_METHOD(ms_midObjIdSetScriptVarString, ms_clsObjId, "setScriptVar", "(Ljava/lang/String;Ljava/lang/String;)V"); GET_METHOD(ms_midObjIdClearScriptVars, ms_clsObjId, "clearScriptVars", "()V"); GET_STATIC_METHOD(ms_midObjIdGetObjId, ms_clsObjId, "getObjId", "(J)Lscript/obj_id;"); GET_STATIC_METHOD(ms_midObjIdClearObjId, ms_clsObjId, "clearObjId", "(J)V"); GET_STATIC_METHOD(ms_midObjIdFlagDestroyed, ms_clsObjId, "flagDestroyed", "(J)V"); GET_STATIC_METHOD(ms_midObjIdPackAllDeltaScriptVars, ms_clsObjId, "packAllScriptVars", "()V"); GET_STATIC_METHOD(ms_midObjIdPackScriptVars, ms_clsObjId, "packScriptVars", "(J)[B"); GET_STATIC_METHOD(ms_midObjIdUnpackDeltaScriptVars, ms_clsObjId, "unpackDeltaScriptVars", "(J[B)V"); GET_STATIC_METHOD(ms_midObjIdUnpackScriptVars, ms_clsObjId, "unpackScriptVars", "(J[B)V"); // get class combat_engine info GET_CLASS(ms_clsCombatEngine, "script/combat_engine"); GET_CLASS(ms_clsCombatEngineCombatantData, "script/combat_engine$combatant_data"); GET_FIELD(ms_fidCombatEngineCombatantDataPos, ms_clsCombatEngineCombatantData, "pos", "Lscript/location;"); GET_FIELD(ms_fidCombatEngineCombatantDataWorldPos, ms_clsCombatEngineCombatantData, "worldPos", "Lscript/location;"); GET_FIELD(ms_fidCombatEngineCombatantDataRadius, ms_clsCombatEngineCombatantData, "radius", "F"); GET_FIELD(ms_fidCombatEngineCombatantDataIsCreature, ms_clsCombatEngineCombatantData, "isCreature", "Z"); GET_FIELD(ms_fidCombatEngineCombatantDataPosture, ms_clsCombatEngineCombatantData, "posture", "I"); GET_FIELD(ms_fidCombatEngineCombatantDataLocomotion, ms_clsCombatEngineCombatantData, "locomotion", "I"); GET_FIELD(ms_fidCombatEngineCombatantDataScriptMod, ms_clsCombatEngineCombatantData, "scriptMod", "I"); GET_CLASS(ms_clsCombatEngineAttackerData, "script/combat_engine$attacker_data"); GET_FIELD(ms_fidCombatEngineAttackerDataWeaponSkill, ms_clsCombatEngineAttackerData, "weaponSkillMod", "I"); GET_FIELD(ms_fidCombatEngineAttackerDataAims, ms_clsCombatEngineAttackerData, "aims", "I"); GET_CLASS(ms_clsCombatEngineDefenderData, "script/combat_engine$defender_data"); GET_FIELD(ms_fidCombatEngineDefenderDataCombatSkeleton, ms_clsCombatEngineDefenderData, "combatSkeleton", "I"); GET_FIELD(ms_fidCombatEngineDefenderDataCover, ms_clsCombatEngineDefenderData, "cover", "I"); GET_FIELD(ms_fidCombatEngineDefenderDataHitLocationChances, ms_clsCombatEngineDefenderData, "hitLocationChances", "[I"); GET_CLASS(ms_clsCombatEngineWeaponData, "script/combat_engine$weapon_data"); GET_FIELD(ms_fidCombatEngineWeaponDataId, ms_clsCombatEngineWeaponData, "id", "Lscript/obj_id;"); GET_FIELD(ms_fidCombatEngineWeaponDataMinDamage, ms_clsCombatEngineWeaponData, "minDamage", "I"); GET_FIELD(ms_fidCombatEngineWeaponDataMaxDamage, ms_clsCombatEngineWeaponData, "maxDamage", "I"); GET_FIELD(ms_fidCombatEngineWeaponDataWeaponType, ms_clsCombatEngineWeaponData, "weaponType", "I"); GET_FIELD(ms_fidCombatEngineWeaponDataAttackType, ms_clsCombatEngineWeaponData, "attackType", "I"); GET_FIELD(ms_fidCombatEngineWeaponDataDamageType, ms_clsCombatEngineWeaponData, "damageType", "I"); GET_FIELD(ms_fidCombatEngineWeaponDataElementalType, ms_clsCombatEngineWeaponData, "elementalType", "I"); GET_FIELD(ms_fidCombatEngineWeaponDataElementalValue, ms_clsCombatEngineWeaponData, "elementalValue", "I"); GET_FIELD(ms_fidCombatEngineWeaponDataAttackSpeed, ms_clsCombatEngineWeaponData, "attackSpeed", "F"); GET_FIELD(ms_fidCombatEngineWeaponDataWoundChance, ms_clsCombatEngineWeaponData, "woundChance", "F"); GET_FIELD(ms_fidCombatEngineWeaponDataAccuracy, ms_clsCombatEngineWeaponData, "accuracy", "I"); GET_FIELD(ms_fidCombatEngineWeaponDataMinRange, ms_clsCombatEngineWeaponData, "minRange", "F"); GET_FIELD(ms_fidCombatEngineWeaponDataMaxRange, ms_clsCombatEngineWeaponData, "maxRange", "F"); GET_FIELD(ms_fidCombatEngineWeaponDataDamageRadius, ms_clsCombatEngineWeaponData, "damageRadius", "F"); GET_FIELD(ms_fidCombatEngineWeaponDataAttackCost, ms_clsCombatEngineWeaponData, "attackCost", "I"); GET_FIELD(ms_fidCombatEngineWeaponDataIsDisabled, ms_clsCombatEngineWeaponData, "isDisabled", "Z"); GET_CLASS(ms_clsCombatEngineHitResult, "script/combat_engine$hit_result"); GET_FIELD(ms_fidCombatEngineHitResultSuccess, ms_clsCombatEngineHitResult, "success", "Z"); GET_FIELD(ms_fidCombatEngineHitResultCritical, ms_clsCombatEngineHitResult, "critical", "Z"); GET_FIELD(ms_fidCombatEngineHitResultGlancing, ms_clsCombatEngineHitResult, "glancing", "Z"); GET_FIELD(ms_fidCombatEngineHitResultCrushing, ms_clsCombatEngineHitResult, "crushing", "Z"); GET_FIELD(ms_fidCombatEngineHitResultStrikethrough, ms_clsCombatEngineHitResult, "strikethrough", "Z"); GET_FIELD(ms_fidCombatEngineHitResultStrikethroughAmount, ms_clsCombatEngineHitResult, "strikethroughAmmount", "F"); GET_FIELD(ms_fidCombatEngineHitResultEvadeResult, ms_clsCombatEngineHitResult, "evadeResult", "Z"); GET_FIELD(ms_fidCombatEngineHitResultEvadeAmount, ms_clsCombatEngineHitResult, "evadeAmmount", "F"); GET_FIELD(ms_fidCombatEngineHitResultBlockResult, ms_clsCombatEngineHitResult, "blockResult", "Z"); GET_FIELD(ms_fidCombatEngineHitResultBlock, ms_clsCombatEngineHitResult, "block", "I"); GET_FIELD(ms_fidCombatEngineHitResultDodge, ms_clsCombatEngineHitResult, "dodge", "Z"); GET_FIELD(ms_fidCombatEngineHitResultParry, ms_clsCombatEngineHitResult, "parry", "Z"); GET_FIELD(ms_fidCombatEngineHitResultProc, ms_clsCombatEngineHitResult, "proc", "Z"); GET_FIELD(ms_fidCombatEngineHitResultBaseRoll, ms_clsCombatEngineHitResult, "baseRoll", "I"); GET_FIELD(ms_fidCombatEngineHitResultFinalRoll, ms_clsCombatEngineHitResult, "finalRoll", "I"); GET_FIELD(ms_fidCombatEngineHitResultAttackVal, ms_clsCombatEngineHitResult, "attackVal", "F"); GET_FIELD(ms_fidCombatEngineHitResultCanSee, ms_clsCombatEngineHitResult, "canSee", "Z"); GET_FIELD(ms_fidCombatEngineHitResultHitLocation, ms_clsCombatEngineHitResult, "hitLocation", "I"); GET_FIELD(ms_fidCombatEngineHitResultDamage, ms_clsCombatEngineHitResult, "damage", "I"); GET_FIELD(ms_fidCombatEngineHitResultDamageType, ms_clsCombatEngineHitResult, "damageType", "I"); GET_FIELD(ms_fidCombatEngineHitResultRawDamage, ms_clsCombatEngineHitResult, "rawDamage", "I"); GET_FIELD(ms_fidCombatEngineHitResultElementalDamage, ms_clsCombatEngineHitResult, "elementalDamage", "I"); GET_FIELD(ms_fidCombatEngineHitResultElementalDamageType, ms_clsCombatEngineHitResult, "elementalDamageType", "I"); GET_FIELD(ms_fidCombatEngineHitResultBleedDamage, ms_clsCombatEngineHitResult, "bleedDamage", "I"); GET_FIELD(ms_fidCombatEngineHitResultCritDamage, ms_clsCombatEngineHitResult, "critDamage", "I"); GET_FIELD(ms_fidCombatEngineHitResultBlockedDamage, ms_clsCombatEngineHitResult, "blockedDamage", "I"); GET_FIELD(ms_fidCombatEngineHitResultBlockingArmor, ms_clsCombatEngineHitResult, "blockingArmor", "Lscript/obj_id;"); GET_FIELD(ms_fidCombatEngineHitResultBleedingChance, ms_clsCombatEngineHitResult, "bleedingChance", "I"); // be used parameters for events GET_CLASS(ms_clsStringId, "script/string_id"); GET_CLASS(ms_clsStringIdArray, "[Lscript/string_id;"); GET_CLASS(ms_clsModifiableStringId, "script/modifiable_string_id"); GET_FIELD(ms_fidStringIdTable, ms_clsStringId, "m_table", "Ljava/lang/String;"); GET_FIELD(ms_fidStringIdAsciiId, ms_clsStringId, "m_asciiId", "Ljava/lang/String;"); GET_FIELD(ms_fidStringIdIndexId, ms_clsStringId, "m_indexId", "I"); GET_METHOD(ms_midStringId, ms_clsStringId, "", "(Ljava/lang/String;I)V"); for (i = 0; i < MAX_STRING_ID_PARAMS; ++i) { localInstance = createNewObject(ms_clsStringId, ms_midStringId, NULL, -1); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } GlobalInstances::ms_stringIds[i] = GlobalRefPtr(new GlobalRef(*localInstance)); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } } GET_METHOD(constructor, ms_clsModifiableStringId, "", "(Ljava/lang/String;I)V"); for (i = 0; i < MAX_MODIFIABLE_STRING_ID_PARAMS; ++i) { localInstance = createNewObject(ms_clsModifiableStringId, constructor, NULL, -1); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } GlobalInstances::ms_modifiableStringIds[i] = GlobalRefPtr(new GlobalRef(*localInstance)); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } } // get class and fields for class transform GET_CLASS(ms_clsTransform, "script/transform"); GET_CLASS(ms_clsTransformArray, "[Lscript/transform;"); GET_METHOD(ms_midTransform, ms_clsTransform, "", "(FFFFFFFFFFFF)V"); GET_FIELD(ms_fidTransformMatrix, ms_clsTransform, "matrix", "[[F"); // get class and fields for class vector GET_CLASS(ms_clsVector, "script/vector"); GET_CLASS(ms_clsVectorArray, "[Lscript/vector;"); GET_FIELD(ms_fidVectorX, ms_clsVector, "x", "F"); GET_FIELD(ms_fidVectorY, ms_clsVector, "y", "F"); GET_FIELD(ms_fidVectorZ, ms_clsVector, "z", "F"); GET_CLASS(ms_clsResourceDensity, "script/resource_density"); GET_FIELD(ms_fidResourceDensityResourceType, ms_clsResourceDensity, "m_resourceType", "Lscript/obj_id;"); GET_FIELD(ms_fidResourceDensityDensity, ms_clsResourceDensity, "m_density", "F"); GET_CLASS(ms_clsResourceAttribute, "script/resource_attribute"); GET_FIELD(ms_fidResourceAttributeName, ms_clsResourceAttribute, "m_name", "Ljava/lang/String;"); GET_FIELD(ms_fidResourceAttributeValue, ms_clsResourceAttribute, "m_value", "I"); GET_CLASS(ms_clsLibrarySpaceTransition, "script/library/space_transition"); GET_STATIC_METHOD(ms_midLibrarySpaceTransitionSetPlayerOvert, ms_clsLibrarySpaceTransition, "setPlayerOvert", "(J)V"); GET_STATIC_METHOD(ms_midLibrarySpaceTransitionClearOvertStatus, ms_clsLibrarySpaceTransition, "clearOvertStatus", "(J)V"); /////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////// // get class and field info needed by the CS Handler stuff. These may not have been // written specifically for the CS Handler. GET_CLASS( ms_clsLibraryDump, "script/library/dump" ); GET_STATIC_METHOD( ms_midLibraryDumpDumpTargetInfo, ms_clsLibraryDump, "getTargetInfoStringByLong", "(J)Ljava/lang/String;" ); GET_CLASS( ms_clsLibraryGMLib, "script/library/gmlib" ); GET_STATIC_METHOD( ms_midLibraryGMLibFreeze, ms_clsLibraryGMLib, "freezePlayer", "(J)Ljava/lang/String;" ); GET_STATIC_METHOD( ms_midLibraryGMLibUnfreeze, ms_clsLibraryGMLib, "unFreezePlayer", "(J)V" ); ///////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////// // register our native methods bool registerSuccess = true; registerSuccess &= ScriptMethodsActionStatesNamespace::install(); registerSuccess &= ScriptMethodsAiNamespace::install(); registerSuccess &= ScriptMethodsAnimationNamespace::install(); registerSuccess &= ScriptMethodsAttributesNamespace::install(); registerSuccess &= ScriptMethodsAuctionNamespace::install(); registerSuccess &= ScriptMethodsBankNamespace::install(); registerSuccess &= ScriptMethodsBeastMasterNamespace::install(); registerSuccess &= ScriptMethodsBroadcastingNamespace::install(); registerSuccess &= ScriptMethodsBuffBuilderNamespace::install(); registerSuccess &= ScriptMethodsBuffNamespace::install(); registerSuccess &= ScriptMethodsChatNamespace::install(); registerSuccess &= ScriptMethodsCityNamespace::install(); registerSuccess &= ScriptMethodsClientEffectNamespace::install(); registerSuccess &= ScriptMethodsClusterWideDataNamespace::install(); registerSuccess &= ScriptMethodsCollectionNamespace::install(); registerSuccess &= ScriptMethodsCombatNamespace::install(); registerSuccess &= ScriptMethodsCommandQueueNamespace::install(); registerSuccess &= ScriptMethodsConsoleNamespace::install(); registerSuccess &= ScriptMethodsContainersNamespace::install(); registerSuccess &= ScriptMethodsCraftingNamespace::install(); registerSuccess &= ScriptMethodsDataTableNamespace::install(); registerSuccess &= ScriptMethodsDebugNamespace::install(); registerSuccess &= ScriptMethodsDynamicVariableNamespace::install(); registerSuccess &= ScriptMethodsFormNamespace::install(); registerSuccess &= ScriptMethodsGlobalQueryNamespace::install(); registerSuccess &= ScriptMethodsGuildNamespace::install(); registerSuccess &= ScriptMethodsHateListNamespace::install(); registerSuccess &= ScriptMethodsHolocubeNamespace::install(); registerSuccess &= ScriptMethodsHyperspaceNamespace::install(); registerSuccess &= ScriptMethodsImageDesignNamespace::install(); registerSuccess &= ScriptMethodsInstallationNamespace::install(); registerSuccess &= ScriptMethodsInterestNamespace::install(); registerSuccess &= ScriptMethodsInteriorsNamespace::install(); registerSuccess &= ScriptMethodsJediNamespace::install(); registerSuccess &= ScriptMethodsMapNamespace::install(); registerSuccess &= ScriptMethodsMentalStatesNamespace::install(); registerSuccess &= ScriptMethodsMenuNamespace::install(); registerSuccess &= ScriptMethodsMissionNamespace::install(); registerSuccess &= ScriptMethodsMoneyNamespace::install(); registerSuccess &= ScriptMethodsMountNamespace::install(); registerSuccess &= ScriptMethodsNewbieTutorialNamespace::install(); registerSuccess &= ScriptMethodsNotificationNamespace::install(); registerSuccess &= ScriptMethodsNpcNamespace::install(); registerSuccess &= ScriptMethodsObjectCreateNamespace::install(); registerSuccess &= ScriptMethodsObjectInfoNamespace::install(); registerSuccess &= ScriptMethodsObjectMoveNamespace::install(); registerSuccess &= ScriptMethodsPermissionsNamespace::install(); registerSuccess &= ScriptMethodsPilotNamespace::install(); registerSuccess &= ScriptMethodsPlanetNamespace::install(); registerSuccess &= ScriptMethodsPlayerAccountNamespace::install(); registerSuccess &= ScriptMethodsPlayerQuestNamespace::install(); registerSuccess &= ScriptMethodsPvpNamespace::install(); registerSuccess &= ScriptMethodsQuestNamespace::install(); registerSuccess &= ScriptMethodsRegionNamespace::install(); registerSuccess &= ScriptMethodsRegion3dNamespace::install(); registerSuccess &= ScriptMethodsRemoteDebugNamespace::install(); registerSuccess &= ScriptMethodsResourceNamespace::install(); registerSuccess &= ScriptMethodsScriptNamespace::install(); registerSuccess &= ScriptMethodsServerUINamespace::install(); registerSuccess &= ScriptMethodsShipNamespace::install(); registerSuccess &= ScriptMethodsSkillNamespace::install(); registerSuccess &= ScriptMethodsSpawnerNamespace::install(); registerSuccess &= ScriptMethodsStringNamespace::install(); registerSuccess &= ScriptMethodsSystemNamespace::install(); registerSuccess &= ScriptMethodsTerrainNamespace::install(); registerSuccess &= ScriptMethodsTriggerVolumeNamespace::install(); registerSuccess &= ScriptMethodsVeteranNamespace::install(); registerSuccess &= ScriptMethodsWaypointNamespace::install(); registerSuccess &= ScriptMethodsWorldInfoNamespace::install(); if (!registerSuccess) { FATAL(true, ("JavaLibrary RegisterNatives fail!\n")); return false; } ++ms_envCount; return true; } // JavaLibrary::connectToJava //---------------------------------------------------------------------- bool JavaLibrary::registerNatives(const JNINativeMethod natives[], int count) { jclass baseClass = ms_env->FindClass("script/base_class"); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } int result = 0; for (int i = 0; i < count; ++i) { if (!natives[i].signature) { DEBUG_REPORT_LOG(true, ("RegisterNatives failed: %s - NULL signature\n", natives[i].name)); result = 1; continue; } int lresult = ms_env->RegisterNatives(baseClass, &natives[i], 1); if (lresult != 0) { ms_env->ExceptionClear(); DEBUG_REPORT_LOG(true, ("RegisterNatives failed: %s: %s\n", natives[i].name, natives[i].signature)); result = lresult; } } ms_env->DeleteLocalRef(baseClass); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } if (result != 0) { FATAL(true, ("JavaLibrary RegisterNatives fail!\n")); return false; } return true; } //---------------------------------------------------------------------- /** * Disconnects this thread from the Java VM. Any vars that reference Java objects * will be invalid after this call. */ void JavaLibrary::disconnectFromJava() { int i; if (ms_jvm == 0 || ms_env == 0) return; FREE_CLASS(ms_clsScriptEntry); FREE_CLASS(ms_clsObject); FREE_CLASS(ms_clsClass); FREE_CLASS(ms_clsMethod); FREE_CLASS(ms_clsBoolean); FREE_CLASS(ms_clsBooleanArray); FREE_CLASS(ms_clsInteger); FREE_CLASS(ms_clsIntegerArray); FREE_CLASS(ms_clsModifiableInt); FREE_CLASS(ms_clsFloat); FREE_CLASS(ms_clsFloatArray); FREE_CLASS(ms_clsModifiableFloat); FREE_CLASS(ms_clsString); FREE_CLASS(ms_clsStringArray); FREE_CLASS(ms_clsMap); FREE_CLASS(ms_clsHashtable); FREE_CLASS(ms_clsThrowable); FREE_CLASS(ms_clsError); FREE_CLASS(ms_clsStackOverflowError); FREE_CLASS(ms_clsThread); FREE_CLASS(ms_clsInternalScriptError); FREE_CLASS(ms_clsInternalScriptSeriousError); FREE_CLASS(ms_clsDictionary); FREE_CLASS(ms_clsCollection); FREE_CLASS(ms_clsDynamicVariable); FREE_CLASS(ms_clsDynamicVariableList); FREE_CLASS(ms_clsAttribute); FREE_CLASS(ms_clsAttribMod); FREE_CLASS(ms_clsMentalState); FREE_CLASS(ms_clsMentalStateMod); FREE_CLASS(ms_clsMenuInfo); FREE_CLASS(ms_clsMenuInfoData); FREE_CLASS(ms_clsDraftSchematic); FREE_CLASS(ms_clsDraftSchematicSlot); FREE_CLASS(ms_clsDraftSchematicAttrib); FREE_CLASS(ms_clsDraftSchematicSimpleIngredient); FREE_CLASS(ms_clsDraftSchematicCustom); FREE_CLASS(ms_clsCustomVar); FREE_CLASS(ms_clsRangedIntCustomVar); FREE_CLASS(ms_clsPalcolorCustomVar); FREE_CLASS(ms_clsColor); FREE_CLASS(ms_clsLocation); FREE_CLASS(ms_clsLocationArray); FREE_CLASS(ms_clsRegion); FREE_CLASS(ms_clsObjId); FREE_CLASS(ms_clsObjIdArray); FREE_CLASS(ms_clsStringId); FREE_CLASS(ms_clsStringIdArray); FREE_CLASS(ms_clsModifiableStringId); FREE_CLASS(ms_clsBaseClassRangeInfo); FREE_CLASS(ms_clsBaseClassAttackerResults); FREE_CLASS(ms_clsBaseClassDefenderResults); FREE_CLASS(ms_clsCombatEngine); FREE_CLASS(ms_clsCombatEngineCombatantData); FREE_CLASS(ms_clsCombatEngineAttackerData); FREE_CLASS(ms_clsCombatEngineDefenderData); FREE_CLASS(ms_clsCombatEngineWeaponData); FREE_CLASS(ms_clsCombatEngineHitResult); FREE_CLASS(ms_clsTransform); FREE_CLASS(ms_clsTransformArray); FREE_CLASS(ms_clsVector); FREE_CLASS(ms_clsVectorArray); FREE_CLASS(ms_clsResourceDensity); FREE_CLASS(ms_clsResourceAttribute); FREE_CLASS(ms_clsLibrarySpaceTransition); FREE_CLASS(ms_clsLibraryDump); FREE_CLASS(ms_clsLibraryGMLib); if (ms_scriptEntry != NULL) { if (ms_env) ms_env->DeleteGlobalRef(ms_scriptEntry); ms_scriptEntry = NULL; } for (i = 0; i < MAX_RECURSION_COUNT; ++i) { ms_attribModList[i] = GlobalArrayRef::cms_nullPtr; ms_mentalStateModList[i] = GlobalArrayRef::cms_nullPtr; } for (i = 0; i < MAX_STRING_ID_PARAMS; ++i) GlobalInstances::ms_stringIds[i] = GlobalRef::cms_nullPtr; for (i = 0; i < MAX_ATTRIB_MOD_PARAMS; ++i) GlobalInstances::ms_attribMods[i] = GlobalRef::cms_nullPtr; for (i = 0; i < MAX_MENTAL_STATE_MOD_PARAMS; ++i) GlobalInstances::ms_mentalStateMods[i] = GlobalRef::cms_nullPtr; for (i = 0; i < MAX_MODIFIABLE_INT_PARAMS; ++i) GlobalInstances::ms_modifiableInts[i] = GlobalRef::cms_nullPtr; for (i = 0; i < MAX_MODIFIABLE_FLOAT_PARAMS; ++i) GlobalInstances::ms_modifiableFloats[i] = GlobalRef::cms_nullPtr; for (i = 0; i < MAX_MODIFIABLE_STRING_ID_PARAMS; ++i) GlobalInstances::ms_modifiableStringIds[i] = GlobalRef::cms_nullPtr; GlobalInstances::ms_menuInfo = GlobalRef::cms_nullPtr; IGNORE_RETURN(ms_jvm->DetachCurrentThread()); ms_env = NULL; } // JavaLibrary::disconnectFromJava //---------------------------------------------------------------------- /** * Resets our connection to the Java VM. */ void JavaLibrary::resetJavaConnection() { if (ms_currentRecursionCount == 0) { LOG("ScriptInvestigation", ("Reconnecting to Java after VM error")); ms_instance->disconnectFromJava(); if (!ms_instance->connectToJava()) { FATAL(true, ("Unable to reconnect to Java after error, fataling")); } ms_resetJava = false; LOG("ScriptInvestigation", ("Reconnection succeeded")); } else ms_resetJava = true; } // JavaLibrary::resetJavaConnection() //---------------------------------------------------------------------- /** * Gets a list of public methods of a given script, and adds the info to the * GameScriptObject class so we don't have to go into the JVM to see if a * script handles a given trigger, etc. * * @param scriptName the name of the script to query * @return false on failure. True on success. */ bool JavaLibrary::queryScriptFunctions(const std::string & scriptName) { if (ms_instance == NULL) return false; JavaString scriptClassName(("script." + scriptName).c_str()); LocalObjectArrayRefPtr scriptMethods = callStaticObjectArrayMethod( ms_clsScriptEntry, ms_midGetScriptFunctions, scriptClassName.getValue()); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } if (scriptMethods == LocalObjectArrayRef::cms_nullPtr) return false; std::set & functionList = GameScriptObject::getScriptFunctions( scriptName); functionList.clear(); // DEBUG_REPORT_LOG(true, ("Querying script %s methods:\n", scriptName.c_str())); // get the name of each method bool result = true; int count = getArrayLength(*scriptMethods); for (int i = 0; i < count; ++i) { JavaStringPtr methodName = getStringArrayElement(*scriptMethods, i); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); result = false; break; } if (methodName == JavaString::cms_nullPtr) { result = false; break; } // convert the method name to a C string and store it std::string localName; convert(*methodName, localName); // DEBUG_REPORT_LOG(true, ("\t%s\n", localName)); functionList.insert(localName); } return result; } // JavaLibrary::queryScriptFunctions /** * Returns the amount of free Java heap space left. * * @return the amount of Java memory free */ jlong JavaLibrary::getFreeJavaMemory() { if (ms_instance == NULL || ms_env == NULL) return 0; return ms_env->CallStaticLongMethod(ms_clsScriptEntry, ms_midScriptEntryGetFreeMem); } // JavaLibrary::getFreeJavaMemory /** * Prints the current java stack to stdout. */ void JavaLibrary::printJavaStack() { ms_env->CallStaticVoidMethod(ms_clsThread, ms_midThreadDumpStack); } /** * Turns script logging on or off. * * @param enable flag to turn logging on or off */ void JavaLibrary::enableLogging(bool enable) const { if (ms_instance == NULL || ms_env == NULL) return; ms_env->CallStaticVoidMethod(ms_clsScriptEntry, ms_midScriptEntryEnableLogging, enable); } // JavaLibrary::enableLogging /** * Turns tracking of players to see if they can become Jedi on or off. * * @param enableTracking flag to turn tracking on or off */ void JavaLibrary::enableNewJediTracking(bool enableTracking) { if (ms_instance == NULL || ms_env == NULL) return; ms_env->CallStaticVoidMethod(ms_clsScriptEntry, ms_midScriptEntryEnableNewJediTracking, enableTracking); } // JavaLibrary::enableNewJediTracking /** * Asks the Java script library for a obj_id mapped to a ServerObject. * * @param object the NetworkId::NetworkIdType we want to map * * @return the jobject obj_id */ LocalRefPtr JavaLibrary::getObjId(const ServerObject & object) { return getObjId(object.getNetworkId()); } // JavaLibrary::getObjId(const ServerObject &) /** * Asks the Java script library for a obj_id mapped to a NetworkId::NetworkIdType. * * @param id the NetworkId::NetworkIdType we want to map * * @return the jobject obj_id */ LocalRefPtr JavaLibrary::getObjId(const NetworkId::NetworkIdType & id) { return getObjId(NetworkId(id)); } // JavaLibrary::getObjId(const NetworkId::NetworkIdType &) /** * Asks the Java script library for a obj_id mapped to a NetworkId. * * @param id the NetworkId we want to map * * @return the jobject obj_id */ LocalRefPtr JavaLibrary::getObjId(const NetworkId & id) { if (ms_env != NULL && ms_instance != NULL) return callStaticObjectMethod(ms_clsObjId, ms_midObjIdGetObjId, id.getValue()); return LocalRef::cms_nullPtr; } // JavaLibrary::getObjId(const CachedNetworkId &) void JavaLibrary::spaceMakeOvert(const NetworkId & player) { callStaticVoidMethod(ms_clsLibrarySpaceTransition, ms_midLibrarySpaceTransitionSetPlayerOvert, player.getValue()); } void JavaLibrary::spaceClearOvert(const NetworkId & ship) { callStaticVoidMethod(ms_clsLibrarySpaceTransition, ms_midLibrarySpaceTransitionClearOvertStatus, ship.getValue()); } std::string JavaLibrary::getObjectDumpInfo( NetworkId id ) { JavaStringPtr s = callStaticStringMethod(ms_clsLibraryDump, ms_midLibraryDumpDumpTargetInfo, id.getValue() ); std::string retval; convert( *s, retval ); return retval; } void JavaLibrary::freezePlayer( const NetworkId & id ) { DEBUG_REPORT_LOG( true, ( "calling freeze code in script" ) ); JavaStringPtr s = callStaticStringMethod( ms_clsLibraryGMLib, ms_midLibraryGMLibFreeze, id.getValue() ); DEBUG_REPORT_LOG( true, ( "done with script" ) ); std::string retval; convert( *s, retval ); DEBUG_REPORT_LOG( true, ("Got back %s", retval.c_str() ) ); } void JavaLibrary::unFreezePlayer( const NetworkId & id ) { callStaticVoidMethod( ms_clsLibraryGMLib, ms_midLibraryGMLibUnfreeze, id.getValue() ); } /** * Returns the NetworkId associated with a Java obj_id. * * @param source the obj_id * * @return the NetworkId */ const NetworkId JavaLibrary::getNetworkId(const jobject & source) { NetworkId result(NetworkId::cms_invalid); if (ms_env && source != 0 && ms_env->IsInstanceOf(source, ms_clsObjId)) { result = NetworkId(static_cast(ms_env->CallLongMethod(source, ms_midObjIdGetValue))); } return result; } // getNetworkId(const jobject &) /** * Returns the NetworkId associated with a Java obj_id. * * @param source the obj_id * * @return the NetworkId */ const NetworkId JavaLibrary::getNetworkId(const LocalRefParam & source) { NetworkId result(NetworkId::cms_invalid); if (ms_env && source.getValue() != 0 && isInstanceOf(source, ms_clsObjId)) { result = NetworkId(static_cast(callLongMethod(source, ms_midObjIdGetValue))); } return result; } // getNetworkId(const LocalRef &) LocalRefPtr JavaLibrary::getVector(Vector const & vector) { LocalRefPtr temp; ScriptConversion::convert(vector, temp); return temp; } /** * Frees a Java obj_id matching a NetwrokId. * * @param id the NetworkId we want to remove */ void JavaLibrary::removeJavaId(const NetworkId & id) { if (ms_env == NULL || ms_clsObjId == NULL || ms_midObjIdClearObjId == NULL) { return; } if (id.getValue()) { ms_env->CallStaticVoidMethod(ms_clsObjId, ms_midObjIdClearObjId, id.getValue()); } } // JavaLibrary::removeJavaId /** * Flag the object in script as going to be destroyed, but hasn't actually been removed from the game yet. * * @param id the NetworkId of the object */ void JavaLibrary::flagDestroyed(const NetworkId & id) { if (ms_env == NULL || ms_clsObjId == NULL || ms_midObjIdFlagDestroyed == NULL) { return; } if (id.getValue()) { ms_env->CallStaticVoidMethod(ms_clsObjId, ms_midObjIdFlagDestroyed, id.getValue()); } } // JavaLibrary::flagDestroyed /** * Sets the authoritative flag of an obj_id. * * @param object the object we want to flag * @param authoritative authoritative flag */ void JavaLibrary::setObjIdAuthoritative(const NetworkId & object, bool authoritative, uint32 pid) { if (ms_env == NULL || ms_midObjIdSetAuthoritative == NULL) { return; } LocalRefPtr id = getObjId(object); if (id == LocalRef::cms_nullPtr) { DEBUG_WARNING(true, ("JavaLibrary::setObjIdAuthoritative: could not get id for object %s", object.getValueString().c_str())); return; } callVoidMethod(*id, ms_midObjIdSetAuthoritative, static_cast(authoritative ? JNI_TRUE : JNI_FALSE), pid); } // JavaLibrary::setObjIdAuthoritative /** * Sets the loaded flag of an obj_id. You cannot unload an object, it is marked * unloaded when it is deleted. * * @param object the object we want to flag as loaded */ void JavaLibrary::setObjIdLoaded(const NetworkId &object) { if (ms_env == NULL || ms_midObjIdSetLoaded == NULL) { return; } LocalRefPtr id = getObjId(object); if (id == LocalRef::cms_nullPtr) { DEBUG_WARNING(true, ("JavaLibrary::setObjIdLoaded: could not get id for object %s", object.getValueString().c_str())); return; } callVoidMethod(*id, ms_midObjIdSetLoaded); } // JavaLibrary::setObjIdLoaded /** * Sets the initialized flag of an obj_id. You cannot uninitialize an object, * it is marked uninitialized when it is deleted. * * @param object the object we want to flag as initialized */ void JavaLibrary::setObjIdInitialized(const NetworkId &object) { if (ms_env == NULL || ms_midObjIdSetInitialized == NULL) { return; } LocalRefPtr id = getObjId(object); if (id == LocalRef::cms_nullPtr) { DEBUG_WARNING(true, ("JavaLibrary::setObjIdInitialized: could not get " "id for object %s", object.getValueString().c_str())); return; } callVoidMethod(*id, ms_midObjIdSetInitialized); } // JavaLibrary::setObjIdInitialized /** * Sets the logged in flag of an obj_id. * * @param object the object we want to flag * @param loggedIn true if logged in, false if logged out */ void JavaLibrary::setObjIdLoggedIn(const NetworkId & object, bool loggedIn) { if (ms_env == NULL || ms_midObjIdSetLoggedIn == NULL) { return; } LocalRefPtr id = getObjId(object); if (id == LocalRef::cms_nullPtr) { DEBUG_WARNING(true, ("JavaLibrary::setObjIdLoggedIn: could not get " "id for object %s", object.getValueString().c_str())); return; } callVoidMethod(*id, ms_midObjIdSetLoggedIn, loggedIn); } // JavaLibrary::setObjIdLoggedIn /** * Adds a script name to an obj_id. * * @param object object we want to attach the script to * @param script name of the script to attach */ void JavaLibrary::attachScriptToObjId(const NetworkId &object, const std::string & script) { if (ms_env != NULL) { LocalRefPtr obj_id = getObjId(object); if (obj_id == LocalRef::cms_nullPtr) return; JavaString jscript(script.c_str()); callVoidMethod(*obj_id, ms_midObjIdAttachScript, jscript.getValue()); } } // JavaLibrary::attachScriptToObjId /** * Adds script names to an obj_id. * * @param object object we want to attach the scripts to * @param scripts names of the scripts to attach */ void JavaLibrary::attachScriptsToObjId(const NetworkId &object, const ScriptList & scripts) { if (scripts.size() == 0 || ms_env == NULL) return; LocalRefPtr obj_id = getObjId(object); if (obj_id == LocalRef::cms_nullPtr) return; LocalObjectArrayRefPtr jscripts = createNewObjectArray(scripts.size(), ms_clsString); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return; } int index = 0; for (ScriptList::const_iterator i = scripts.begin(); i != scripts.end(); ++i) { if ((*i).isValid()) { JavaString js((*i).getScriptName()); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return; } setObjectArrayElement(*jscripts, index, js); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return; } ++index; } } callVoidMethod(*obj_id, ms_midObjIdAttachScripts, jscripts->getValue()); } // JavaLibrary::attachScriptsToObjId /** * Removes a script name from an obj_id. * * @param object object we want to detach the script from * @param script name of the script to detach */ void JavaLibrary::detachScriptFromObjId(const NetworkId &object, const std::string & script) { if (ms_env != NULL) { LocalRefPtr obj_id = getObjId(object); if (obj_id == LocalRef::cms_nullPtr) return; JavaString jscript(script.c_str()); callVoidMethod(*obj_id, ms_midObjIdDetachScript, jscript.getValue()); } } // JavaLibrary::detachScriptFromObjId /** * Removes all the scripts from an obj_id. * * @param object object we want to detach the script from */ void JavaLibrary::detachAllScriptsFromObjId(const NetworkId &object) { if (ms_env != NULL) { LocalRefPtr obj_id = getObjId(object); if (obj_id == LocalRef::cms_nullPtr) return; callVoidMethod(*obj_id, ms_midObjIdDetachAllScripts); } } // JavaLibrary::detachAllScriptsFromObjId /** * Handles errors after calling into script_entry.java. * * @param result the result we got back from script_entry * * @return the result to be returned to the calling trigger */ jint JavaLibrary::handleScriptEntryCleanup(jint result) { if (ms_resetJava) { ms_instance->resetJavaConnection(); result = SCRIPT_CONTINUE; } else if (result == SCRIPT_INTERNAL_ERROR || ms_env->ExceptionCheck()) { if (ms_env->ExceptionCheck()) { // if this is an internal error, clear it so we don't print the error // message later jthrowable err = ms_env->ExceptionOccurred(); ms_env->ExceptionClear(); if (ms_env->IsInstanceOf(err, ms_clsError)) { if (ms_env->IsInstanceOf(err, ms_clsInternalScriptError)) { LOG("ScriptInvestigation", ("call to script_entry.java failed because of a script internal error")); if (ConfigServerGame::getScriptStackErrorLevel() == 2) { // if the internal error was caused by a stack overflow, fatal LocalRefPtr wrappedErr = getObjectField(LocalRefParam(err), ms_fidInternalScriptSeriousErrorError); if (wrappedErr != LocalRef::cms_nullPtr && isInstanceOf(*wrappedErr, ms_clsStackOverflowError)) { FATAL(true, ("Java stack overflow error, fataling")); } } } // we are going to reset our connection to the Java VM ms_instance->resetJavaConnection(); result = SCRIPT_CONTINUE; } else ms_env->DeleteLocalRef(err); } else if (result == SCRIPT_INTERNAL_ERROR) { LOG("ScriptInvestigation", ("call to script_entry.java failed because of a script internal exception")); result = SCRIPT_CONTINUE; } #ifdef linux if (ConfigServerGame::getTrapScriptCrashes()) { // the script threw an error or exception, restore our segfault handler IGNORE_RETURN(sigaction(SIGSEGV, &OurSa, NULL)); } #endif } return result; } // JavaLibrary::handleScriptEntryCleanup /** * Entry point into the Java VM for scripts. All functions should use this to call * into the VM. This version of the function executes on a single script. * * @param script the script name to use * @param method the script method to call * @param params parameters to be sent to the script method * * @return return value from the script method, usually SCRIPT_CONTINUE or SCRIPT_OVERRIDE */ jint JavaLibrary::callScriptEntry(const JavaStringParam & script, const JavaStringParam & method, jobjectArray params) { if (ms_env == NULL || ms_clsScriptEntry == NULL || ms_midRunOne == NULL) { LOG("ScriptInvestigation", ("callScriptEntry failed because something was null")); if (!ms_env) { LOG("ScriptInvestigation", ("callScriptEntry failed because ms_env was null")); } if (!ms_clsScriptEntry) { LOG("ScriptInvestigation", ("callScriptEntry failed because scriptEntry was null")); } if (!ms_midRunOne) { LOG("ScriptInvestigation", ("callScriptEntry failed because runOne was null")); } return SCRIPT_OVERRIDE; } PROFILER_BLOCK_DEFINE(p, "JavaLibrary::callScriptEntry1"); PROFILER_BLOCK_ENTER(p); ++ms_currentRecursionCount; if (ms_currentRecursionCount > 3) { LOG("ScriptRecursion", ("callScriptEntry1 recursion %d", ms_currentRecursionCount)); } jint result = ms_env->CallStaticIntMethod(ms_clsScriptEntry, ms_midRunOne, script.getValue(), method.getValue(), params); --ms_currentRecursionCount; result = handleScriptEntryCleanup(result); PROFILER_BLOCK_LOST_CHECK(p); PROFILER_BLOCK_LEAVE(p); return result; } // JavaLibrary::callScriptEntry(JavaStringParam, JavaStringParam, jobjectArray) /** * Entry point into the Java VM for scripts. All functions should use this to call * into the VM. This version of the function executes on all scripts attached to * an object. * * @param method the script method to call * @param params parameters to be sent to the script method * * @return return value from the script method, usually SCRIPT_CONTINUE or SCRIPT_OVERRIDE */ jint JavaLibrary::callScriptEntry(const JavaStringParam & method, jobjectArray params) { if (ms_env == NULL || ms_clsScriptEntry == NULL || ms_midRunAll == NULL) { LOG("ScriptInvestigation", ("callScriptEntry2 failed because something was null")); if (!ms_env) { LOG("ScriptInvestigation", ("callScriptEntry2 failed because ms_env was null")); } if (!ms_clsScriptEntry) { LOG("ScriptInvestigation", ("callScriptEntry2 failed because scriptEntry was null")); } if (!ms_midRunOne) { LOG("ScriptInvestigation", ("callScriptEntry2 failed because runOne was null")); } return SCRIPT_OVERRIDE; } PROFILER_BLOCK_DEFINE(p, "JavaLibrary::callScriptEntry2"); PROFILER_BLOCK_ENTER(p); ++ms_currentRecursionCount; if (ms_currentRecursionCount > 3) { LOG("ScriptRecursion", ("callScriptEntry2 recursion %d", ms_currentRecursionCount)); } jint result = ms_env->CallStaticIntMethod(ms_clsScriptEntry, ms_midRunAll, method.getValue(), params); --ms_currentRecursionCount; result = handleScriptEntryCleanup(result); PROFILER_BLOCK_LOST_CHECK(p); PROFILER_BLOCK_LEAVE(p); return result; } // JavaLibrary::callScriptEntry(JavaStringParam, jobjectArray) /** * Entry point into the Java VM for calling console handler script functions. * * @param script the script name to use * @param method the script method to call * @param params parameters to be sent to the script method * * @return string returned by the console handler */ jstring JavaLibrary::callScriptConsoleHandlerEntry(const JavaStringParam & script, const JavaStringParam & method, jobjectArray params) { if (ms_env == NULL || ms_clsScriptEntry == NULL || ms_midRunConsoleHandler == NULL) { LOG("ScriptInvestigation", ("callScriptConsoleHandlerEntry failed because something was null")); if (!ms_env) { LOG("ScriptInvestigation", ("callScriptConsoleHandlerEntry failed because ms_env was null")); } if (!ms_clsScriptEntry) { LOG("ScriptInvestigation", ("callScriptConsoleHandlerEntry failed because scriptEntry was null")); } if (!ms_midRunConsoleHandler) { LOG("ScriptInvestigation", ("callScriptConsoleHandlerEntry failed because runConsoleHandler was null")); } return 0; } PROFILER_BLOCK_DEFINE(p, "JavaLibrary::callScriptConsoleHandlerEntry"); PROFILER_BLOCK_ENTER(p); ++ms_currentRecursionCount; if (ms_currentRecursionCount > 3) { LOG("ScriptRecursion", ("callScriptConsoleHandlerEntry recursion %d", ms_currentRecursionCount)); } jstring result = static_cast(ms_env->CallStaticObjectMethod( ms_clsScriptEntry, ms_midRunConsoleHandler, script.getValue(), method.getValue(), params)); --ms_currentRecursionCount; IGNORE_RETURN(handleScriptEntryCleanup(SCRIPT_CONTINUE)); PROFILER_BLOCK_LOST_CHECK(p); PROFILER_BLOCK_LEAVE(p); return result; } // JavaLibrary::callScriptConsoleHandlerEntry // ---------------------------------------------------------------------- /** * Converts ScriptParams into a Java script.dictionary class. * * @param params the ScriptParams to convert * @param dictionary pointer that will be set to the dictionary. The caller * is responsible for deleting the pointer. */ void JavaLibrary::convert(const ScriptParams & params, JavaDictionaryPtr & dictionary) { dictionary.reset(); if (ms_env == NULL) return; // create the dictionary JavaDictionaryPtr localDictionary(createNewDictionary()); if (localDictionary == JavaDictionary::cms_nullPtr) return; for (int i = 0; i < params.getParamCount(); ++i) { JavaString paramName(params.getParamName(i).c_str()); switch (params.getParamType(i)) { case Param::BOOL: { callObjectMethod(*localDictionary, ms_midDictionaryPutBool, paramName.getValue(), params.getBoolParam(i)); } break; case Param::BOOL_ARRAY: { const std::deque & boolArray = params.getBoolArrayParam(i); LocalBooleanArrayRefPtr array = createNewBooleanArray(boolArray.size()); if (array != LocalBooleanArrayRef::cms_nullPtr) { if (boolArray.size() > 0) { // we need the array of bool to be contiguous in order to // "memcopy" it into the Java return buffer; a deque // does not store the array of bool contiguously; neither // does a vector; in fact, if you find an stl container // of bool that stores the array of bool contiguously, you // should change this code to use it; for now, we allocate // a temporary bool array and copy the deque's bool array // into it, and pass that to the JNI call to do the "memcopy" bool * tempBoolArray = new bool[boolArray.size()]; int indexBoolArray = 0; for (std::deque::const_iterator iter = boolArray.begin(); iter != boolArray.end(); ++iter, ++indexBoolArray) tempBoolArray[indexBoolArray] = *iter; setBooleanArrayRegion(*array, 0, boolArray.size(), const_cast(reinterpret_cast(&tempBoolArray[0]))); delete [] tempBoolArray; } callObjectMethod(*localDictionary, ms_midDictionaryPut, paramName.getValue(), array->getValue() ); } } break; case Param::INT: { callObjectMethod(*localDictionary, ms_midDictionaryPutInt, paramName.getValue(), params.getIntParam(i)); } break; case Param::INT_ARRAY: { const std::vector & intArray = params.getIntArrayParam(i); LocalIntArrayRefPtr array = createNewIntArray(intArray.size()); if (array != LocalIntArrayRef::cms_nullPtr) { if (intArray.size() > 0) { #if INT_MAX == LONG_MAX setIntArrayRegion(*array, 0, intArray.size(), const_cast( reinterpret_cast(&intArray[0]))); #else std::vector intArray2(intArray.begin(), intArray.end()); setIntArrayRegion(*array, 0, intArray.size(), const_cast(&intArray2[0])); #endif } callObjectMethod(*localDictionary, ms_midDictionaryPut, paramName.getValue(), array->getValue() ); } } break; case Param::FLOAT: { callObjectMethod(*localDictionary, ms_midDictionaryPutFloat, paramName.getValue(), params.getFloatParam(i)); } break; case Param::STRING: { JavaString value(params.getStringParam(i)); callObjectMethod(*localDictionary, ms_midDictionaryPut, paramName.getValue(), value.getValue()); } break; case Param::STRING_ARRAY: { LocalObjectArrayRefPtr value; ScriptConversion::convert(params.getStringArrayParam(i), value); callObjectMethod(*localDictionary, ms_midDictionaryPut, paramName.getValue(), value->getValue()); } break; case Param::UNICODE: { JavaString value(params.getUnicodeParam(i)); callObjectMethod(*localDictionary, ms_midDictionaryPut, paramName.getValue(), value.getValue()); } break; case Param::UNICODE_ARRAY: { LocalObjectArrayRefPtr value; ScriptConversion::convert(params.getUnicodeArrayParam(i), value); callObjectMethod(*localDictionary, ms_midDictionaryPut, paramName.getValue(), value->getValue()); } break; case Param::OBJECT_ID: { LocalRefPtr arg = getObjId(params.getObjIdParam(i)); if (arg == LocalRef::cms_nullPtr) return; callObjectMethod(*localDictionary, ms_midDictionaryPut, paramName.getValue(), arg->getValue()); } break; case Param::OBJECT_ID_ARRAY: { const std::vector & objIds = params.getObjIdArrayParam(i); LocalObjectArrayRefPtr array = createNewObjectArray(objIds.size(), ms_clsObjId); if (array != LocalObjectArrayRef::cms_nullPtr) { int count = objIds.size(); for (int j = 0; j < count; ++j) { LocalRefPtr id = getObjId(objIds[j]); if (id != LocalRef::cms_nullPtr) { setObjectArrayElement(*array, j, *id); } } callObjectMethod(*localDictionary, ms_midDictionaryPut, paramName.getValue(), array->getValue()); } else { if (ms_env->ExceptionCheck()) ms_env->ExceptionDescribe(); return; } } break; case Param::CACHED_OBJECT_ID_ARRAY: { const std::vector & objIds = params.getCachedObjIdArrayParam(i); LocalObjectArrayRefPtr array = createNewObjectArray(objIds.size(), ms_clsObjId); if (array != LocalObjectArrayRef::cms_nullPtr) { int count = objIds.size(); for (int j = 0; j < count; ++j) { LocalRefPtr id = getObjId(objIds[j]); if (id != LocalRef::cms_nullPtr) { setObjectArrayElement(*array, j, *id); } } callObjectMethod(*localDictionary, ms_midDictionaryPut, paramName.getValue(), array->getValue()); } else { if (ms_env->ExceptionCheck()) ms_env->ExceptionDescribe(); return; } } break; case Param::OBJECT_ID_ARRAY_ARRAY: { const std::vector *> & objIds = params.getObjIdArrayArrayParam(i); LocalObjectArrayRefPtr array = createNewObjectArray(objIds.size(), ms_clsObjIdArray); if (array != LocalObjectArrayRef::cms_nullPtr) { int count = objIds.size(); for (int j = 0; j < count; ++j) { const std::vector * inner = objIds[j]; if (inner != NULL) { LocalObjectArrayRefPtr innerArray = createNewObjectArray(inner->size(), ms_clsObjId); if (innerArray != LocalObjectArrayRef::cms_nullPtr) { int innerCount = inner->size(); for (int k = 0; k < innerCount; ++k) { LocalRefPtr id = getObjId(inner->at(k)); if (id != LocalRef::cms_nullPtr) { setObjectArrayElement(*innerArray, k, *id); } } setObjectArrayElement(*array, j, *innerArray); } else { if (ms_env->ExceptionCheck()) ms_env->ExceptionDescribe(); return; } } else { setObjectArrayElement(*array, j, *LocalRef::cms_nullPtr); } } callObjectMethod(*localDictionary, ms_midDictionaryPut, paramName.getValue(), array->getValue()); } else { if (ms_env->ExceptionCheck()) ms_env->ExceptionDescribe(); return; } } break; case Param::LOCATION: { LocalRefPtr location; if (ScriptConversion::convert(params.getLocationParam(i), "", NetworkId::cms_invalid, location)) { callObjectMethod(*localDictionary, ms_midDictionaryPut, paramName.getValue(), location->getValue()); } } break; case Param::LOCATION_ARRAY: { LocalObjectArrayRefPtr locations; if (ScriptConversion::convert(params.getLocationArrayParam(i), locations)) { callObjectMethod(*localDictionary, ms_midDictionaryPut, paramName.getValue(), locations->getValue()); } } break; case Param::DICTIONARY: { LocalRefPtr dictionaryArg = convert(params.getValueDictionaryParam(i)); if (dictionaryArg != LocalRef::cms_nullPtr) { callObjectMethod(*localDictionary, ms_midDictionaryPut, paramName.getValue(), dictionaryArg->getValue()); } else { if (ms_env->ExceptionCheck()) ms_env->ExceptionDescribe(); return; } } break; default: { DEBUG_REPORT_LOG(true, ("Unknown/unhandled parameter type " "%d while parsing ScriptParameters\n", static_cast( params.getParamType(i)))); return; } break; } } dictionary = localDictionary; } // JavaLibrary::convert(const ScriptParams &, ScriptDictionaryPtr &) // ---------------------------------------------------------------------- /** * Converts ScriptParams to an array of Java objects. The first parameter of the * objects will be the NetworkId of the object we are running scripts on ("self"). * * @param self the network id that scripts are attached to * @param argList argument list description * @param args the parameters we want to convert * * @return self and args converted to Java data, or 0 on error */ LocalObjectArrayRefPtr JavaLibrary::convert(const NetworkId & self, const std::string& argList, const ScriptParams &args) { if (ms_env == NULL) return LocalObjectArrayRef::cms_nullPtr; // convert the params to jobjects LocalObjectArrayRefPtr jparams = createNewObjectArray(static_cast(args.getParamCount() + 1), ms_clsObject); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return LocalObjectArrayRef::cms_nullPtr; } // add the "self" parameter { LocalRefPtr jself = getObjId(self); setObjectArrayElement(*jparams, 0, *jself); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return LocalObjectArrayRef::cms_nullPtr; } } if (convert(jparams, 1, argList, args)) return jparams; return LocalObjectArrayRef::cms_nullPtr; } // JavaLibrary::convert /** * Converts ScriptParams to an array of Java objects. * * @param argList argument list description * @param args the parameters we want to convert * * @return args converted to Java data, or 0 on error */ LocalObjectArrayRefPtr JavaLibrary::convert(const std::string& argList, const ScriptParams &args) { if (ms_env == NULL) return LocalObjectArrayRef::cms_nullPtr; // convert the params to jobjects LocalObjectArrayRefPtr jparams = createNewObjectArray(static_cast( args.getParamCount()), ms_clsObject); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return LocalObjectArrayRef::cms_nullPtr; } if (convert(jparams, 0, argList, args)) return jparams; return LocalObjectArrayRef::cms_nullPtr; } // JavaLibrary::convert /** * Converts ScriptParams to an array of Java objects. * * @param javaParams Java object array to be filled in with the params * @param startIndex index to start inserting params into the javaParams * @param argList argument list description * @param args the parameters we want to convert * * @return true on success, false if there was an error */ bool JavaLibrary::convert(LocalObjectArrayRefPtr & javaParams, int startIndex, const std::string& argList, const ScriptParams &args) { if (ms_env == NULL) return 0; GlobalInstances globals; PROFILER_AUTO_BLOCK_CHECK_DEFINE("JavaLibrary::convert(ScriptParams)"); // add the rest of the parameters jsize paramIndex = 0; for (unsigned i = 0; i < argList.size(); ++paramIndex) { const char argType = argList[i]; int dimensions = 0; int modifiable = false; while (argList[i]) { ++i; if (argList[i] == '*') modifiable = true; else if (argList[i] != '[') break; else ++dimensions; } if (paramIndex >= args.getParamCount()) { REPORT_LOG(true, ("JavaLibrary::convert(argList, ScriptParams) called with too few parameters: expected %s, got %d\n", argList.c_str(), args.getParamCount())); return 0; } LocalRefParamPtr arg = LocalRefParam::cms_nullPtr; switch (argType) { case 'b': if (dimensions == 0) { if (args.getParamType(paramIndex) != Param::BOOL) break; jboolean param = args.getBoolParam(paramIndex); arg = createNewObject(ms_clsBoolean, ms_midBoolean, param); } else { if (args.getParamType(paramIndex) != Param::BOOL_ARRAY) break; const std::deque & param = args.getBoolArrayParam(paramIndex); int count = param.size(); LocalBooleanArrayRefPtr localInstance = createNewBooleanArray(count); if (count > 0) { // we need the array of bool to be contiguous in order to // "memcopy" it into the Java return buffer; a deque // does not store the array of bool contiguously; neither // does a vector; in fact, if you find an stl container // of bool that stores the array of bool contiguously, you // should change this code to use it; for now, we allocate // a temporary bool array and copy the deque's bool array // into it, and pass that to the JNI call to do the "memcopy" bool * tempBoolArray = new bool[count]; int indexBoolArray = 0; for (std::deque::const_iterator iter = param.begin(); iter != param.end(); ++iter, ++indexBoolArray) tempBoolArray[indexBoolArray] = *iter; setBooleanArrayRegion(*localInstance, 0, count, const_cast(reinterpret_cast(&tempBoolArray[0]))); delete [] tempBoolArray; } if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return 0; } arg = localInstance; } break; case 'i': if (dimensions == 0) { if (args.getParamType(paramIndex) != Param::INT) break; if (modifiable) { arg = globals.getNextModifiableInt(); if (arg == GlobalRef::cms_nullPtr) break; jint param = args.getIntParam(paramIndex); setIntField(*arg, ms_fidModifiableIntData, param); } else { jint param = args.getIntParam(paramIndex); arg = createNewObject(ms_clsInteger, ms_midInteger, param); } } else { if (args.getParamType(paramIndex) != Param::INT_ARRAY) break; const std::vector & param = args.getIntArrayParam(paramIndex); int count = param.size(); LocalIntArrayRefPtr localInstance = createNewIntArray(count); jint * destination = ms_env->GetIntArrayElements(localInstance->getValue(), 0); if (destination) { int i; for (i=0; iReleaseIntArrayElements(localInstance->getValue(), destination, 0); } if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return 0; } arg = localInstance; } break; case 'U': { if (dimensions != 0) { if (args.getParamType(paramIndex) != Param::BYTE_ARRAY) break; const std::vector & param = args.getByteArrayParam(paramIndex); int count = param.size(); LocalByteArrayRefPtr localInstance = createNewByteArray(count); jbyte * destination = ms_env->GetByteArrayElements(localInstance->getValue(), 0); if (destination) { int i; for (i=0; iReleaseByteArrayElements(localInstance->getValue(), destination, 0); } if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return 0; } arg = localInstance; } } break; case 'f': if (dimensions == 0) { if (args.getParamType(paramIndex) != Param::FLOAT) break; if (modifiable) { arg = globals.getNextModifiableFloat(); if (arg == GlobalRef::cms_nullPtr) break; jfloat param = args.getFloatParam(paramIndex); setFloatField(*arg, ms_fidModifiableFloatData, param); } else { jfloat param = args.getFloatParam(paramIndex); arg = createNewObject(ms_clsFloat, ms_midFloat, param); } } else { if (args.getParamType(paramIndex) != Param::FLOAT_ARRAY) break; const std::vector & floats = args.getFloatArrayParam(paramIndex); LocalFloatArrayRefPtr farray = createNewFloatArray(floats.size()); if (farray != LocalFloatArrayRef::cms_nullPtr) { if (floats.size() > 0) setFloatArrayRegion(*farray, 0, floats.size(), const_cast(&floats[0])); arg = farray; } } break; case 's': if (dimensions == 0) { if (args.getParamType(paramIndex) != Param::STRING) break; arg = createNewString(args.getStringParam(paramIndex)); } else { if (args.getParamType(paramIndex) != Param::STRING_ARRAY) break; const std::vector & strings = args.getStringArrayParam(paramIndex); LocalObjectArrayRefPtr localInstance = createNewObjectArray(strings.size(), ms_clsString); int i; std::vector::const_iterator iter; for (i = 0, iter = strings.begin(); iter != strings.end(); ++i, ++iter) { if (*iter) { JavaString newString(*iter); setObjectArrayElement(*localInstance, i, newString); } } arg = localInstance; } break; case 'u': if (dimensions == 0) { if (args.getParamType(paramIndex) != Param::UNICODE) break; if (modifiable) break; const String_t ¶m = args.getUnicodeParam(paramIndex); arg = createNewString(param.c_str(), static_cast(param.size())); } else { if (args.getParamType(paramIndex) != Param::UNICODE_ARRAY) break; const std::vector & strings = args.getUnicodeArrayParam(paramIndex); LocalObjectArrayRefPtr localInstance = createNewObjectArray(strings.size(), ms_clsString); int i; std::vector::const_iterator iter; for (i = 0, iter = strings.begin(); iter != strings.end(); ++i, ++iter) { if (*iter != NULL) { JavaString newString(**iter); setObjectArrayElement(*localInstance, i, newString); } } arg = localInstance; } break; case 'L': if (dimensions == 0) { if (args.getParamType(paramIndex) != Param::LOCATION) break; NetworkId cell; LocalRefPtr target; if (!ScriptConversion::convert(args.getLocationParam(paramIndex), cell, target)) break; arg = target; } else { if (args.getParamType(paramIndex) != Param::LOCATION_ARRAY) break; const std::vector & locations = args.getLocationArrayParam(paramIndex); LocalObjectArrayRefPtr target; if (!ScriptConversion::convert(locations, target)) break; arg = target; } break; case 'O': { if (modifiable || dimensions > 1) break; if (dimensions == 1) { // obj_id array if (args.getParamType(paramIndex) == Param::OBJECT_ID_ARRAY) { const std::vector & param = args.getObjIdArrayParam(paramIndex); int count = param.size(); int paramCount = 0; LocalObjectArrayRefPtr localInstance = createNewObjectArray(count, ms_clsObjId); for (int j = 0; j < count; ++j) { LocalRefPtr id = getObjId(param[j]); if (id == LocalRef::cms_nullPtr) break; setObjectArrayElement(*localInstance, static_cast(paramCount), *id); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return 0; } ++paramCount; } arg = localInstance; } else if (args.getParamType(paramIndex) == Param::CACHED_OBJECT_ID_ARRAY) { const std::vector & param = args.getCachedObjIdArrayParam(paramIndex); int count = param.size(); int paramCount = 0; LocalObjectArrayRefPtr localInstance = createNewObjectArray(count, ms_clsObjId); for (int j = 0; j < count; ++j) { LocalRefPtr id = getObjId(param[j]); if (id == LocalRef::cms_nullPtr) break; setObjectArrayElement(*localInstance, static_cast(paramCount), *id); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return 0; } ++paramCount; } arg = localInstance; } } else { if (args.getParamType(paramIndex) != Param::OBJECT_ID) break; arg = getObjId(args.getObjIdParam(paramIndex)); } } break; //---------------------------------------------------------------------- //-- menu info case 'm': { if (dimensions != 0) break; if (args.getParamType(paramIndex) != Param::OBJECT_MENU_INFO) break; const MenuDataVector & menuVector = args.getObjectMenuRequestDataArrayParam (paramIndex); arg = globals.getMenuInfo (); if (!convert (menuVector, arg)) { return 0; } } break; //---------------------------------------------------------------------- case 'S': if (dimensions == 0) { if (args.getParamType(paramIndex) != Param::STRING_ID) break; if (modifiable) arg = globals.getNextModifiableStringId(); else arg = globals.getNextStringId(); if (arg == GlobalArrayRef::cms_nullPtr) break; const StringId & param = args.getStringIdParam(paramIndex); JavaString text(param.getTable().c_str()); setObjectField(*arg, ms_fidStringIdTable, text); if (param.getText().empty()) { setIntField(*arg, ms_fidStringIdIndexId, static_cast(param.getTextIndex())); JavaString text(""); setObjectField(*arg, ms_fidStringIdAsciiId, text); } else { JavaString text(param.getText().c_str()); setObjectField(*arg, ms_fidStringIdAsciiId, text); } } else { if (args.getParamType(paramIndex) != Param::STRING_ID_ARRAY) break; if (modifiable) break; const std::vector & strings = args.getStringIdArrayParam(paramIndex); LocalObjectArrayRefPtr localInstance = createNewObjectArray(strings.size(), ms_clsStringId); int i; std::vector::const_iterator iter; for (i = 0, iter = strings.begin(); iter != strings.end(); ++i, ++iter) { const StringId * param = *iter; // get the next available stringId from the pool GlobalRefPtr stringIdObject = globals.getNextStringId(); if (stringIdObject == GlobalRef::cms_nullPtr) break; // set the stringId elements JavaString text(param->getTable().c_str()); setObjectField(*stringIdObject, ms_fidStringIdTable, text); if (param->getText().empty()) { setIntField(*stringIdObject, ms_fidStringIdIndexId, static_cast(param->getTextIndex())); JavaString text(""); setObjectField(*stringIdObject, ms_fidStringIdAsciiId, text); } else { JavaString text(param->getText().c_str()); setObjectField(*stringIdObject, ms_fidStringIdAsciiId, text); } // add the string id to the array setObjectArrayElement(*localInstance, i, *stringIdObject); } arg = localInstance; } break; case 'E': //@todo: implement this break; case 'A': if (modifiable || dimensions > 1) break; if (dimensions == 1) { // attribMod array if (args.getParamType(paramIndex) != Param::ATTRIB_MOD_ARRAY) break; const std::vector & param = args.getAttribModArrayParam(paramIndex); int count = param.size(); int paramCount = 0; for (int j = 0; j < count; ++j) { // only send attribMods that actually do something if (param[j].value != 0) { arg = globals.getNextAttribMod(); if (arg == GlobalRef::cms_nullPtr) return 0; JavaString name(AttribModNameManager::getInstance( ).getAttribModName(param[j].tag)); setObjectField(*arg, ms_fidAttribModName, name); if (!AttribMod::isSkillMod(param[j])) { setIntField(*arg, ms_fidAttribModType, static_cast(param[j].attrib)); } else { JavaString skill(AttribModNameManager::getInstance( ).getAttribModName(param[j].skill)); setObjectField(*arg, ms_fidAttribModSkill, skill); } setIntField(*arg, ms_fidAttribModValue, param[j].value); setFloatField(*arg, ms_fidAttribModTime, param[j].sustain); setFloatField(*arg, ms_fidAttribModAttack, param[j].attack); setFloatField(*arg, ms_fidAttribModDecay, param[j].decay); setIntField(*arg, ms_fidAttribModFlags, param[j].flags); setObjectArrayElement(*ms_attribModList[ms_currentRecursionCount], static_cast(paramCount), *arg); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return 0; } ++paramCount; } } // fill in the rest of ms_attribModList with null for (; paramCount < MAX_ATTRIB_MOD_PARAMS; ++paramCount) { setObjectArrayElement(*ms_attribModList[ms_currentRecursionCount], static_cast(paramCount), *LocalRefParam::cms_nullPtr); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return 0; } } arg = ms_attribModList[ms_currentRecursionCount]; } else { // single attribMod if (args.getParamType(paramIndex) != Param::ATTRIB_MOD) break; const AttribMod::AttribMod ¶m = args.getAttribModParam(paramIndex); arg = globals.getNextAttribMod(); if (arg == GlobalRef::cms_nullPtr) return 0; JavaString name(AttribModNameManager::getInstance( ).getAttribModName(param.tag)); setObjectField(*arg, ms_fidAttribModName, name); if (!AttribMod::isSkillMod(param)) { setIntField(*arg, ms_fidAttribModType, param.attrib); } else { JavaString skill(AttribModNameManager::getInstance( ).getAttribModName(param.skill)); setObjectField(*arg, ms_fidAttribModSkill, skill); } setIntField(*arg, ms_fidAttribModValue, param.value); setFloatField(*arg, ms_fidAttribModTime, param.sustain); setFloatField(*arg, ms_fidAttribModAttack, param.attack); setFloatField(*arg, ms_fidAttribModDecay, param.decay); setIntField(*arg, ms_fidAttribModFlags, param.flags); } break; case 'M': if (modifiable || dimensions > 1) break; if (dimensions == 1) { // mental_state_mod array if (args.getParamType(paramIndex) != Param::MENTAL_STATE_MOD_ARRAY) break; const std::vector & param = args.getMentalStateModArrayParam(paramIndex); int count = param.size(); int paramCount = 0; for (int j = 0; j < count; ++j) { // only send mental_state_mods that actually do something if (param[j].value != 0) { arg = globals.getNextMentalStateMod(); if (arg == GlobalRef::cms_nullPtr) return 0; setIntField(*arg, ms_fidMentalStateModType, param[j].target); setFloatField(*arg, ms_fidMentalStateModValue, param[j].value); setFloatField(*arg, ms_fidMentalStateModTime, param[j].timeAtValue); setFloatField(*arg, ms_fidMentalStateModAttack, param[j].time); setFloatField(*arg, ms_fidMentalStateModDecay, param[j].decay); setObjectArrayElement( *ms_mentalStateModList[ms_currentRecursionCount], static_cast(paramCount), *arg); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return 0; } ++paramCount; } } // fill in the rest of ms_mentalStateModList with null for (; paramCount < MAX_MENTAL_STATE_MOD_PARAMS; ++paramCount) { setObjectArrayElement( *ms_mentalStateModList[ms_currentRecursionCount], static_cast(paramCount), *LocalRefParam::cms_nullPtr); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return 0; } } arg = ms_mentalStateModList[ms_currentRecursionCount]; } else { // single mental_state_mod if (args.getParamType(paramIndex) != Param::MENTAL_STATE_MOD) break; const ServerObjectTemplate::MentalStateMod ¶m = args.getMentalStateModParam(paramIndex); arg = globals.getNextMentalStateMod(); if (arg == GlobalRef::cms_nullPtr) return 0; setIntField(*arg, ms_fidMentalStateModType, param.target); setFloatField(*arg, ms_fidMentalStateModValue, param.value); setFloatField(*arg, ms_fidMentalStateModTime, param.timeAtValue); setFloatField(*arg, ms_fidMentalStateModAttack, param.time); setFloatField(*arg, ms_fidMentalStateModDecay, param.decay); } break; case 'D': if (!modifiable && dimensions == 0) { const ManufactureObjectInterface & schematic = args.getManufactureSchematicParam(paramIndex); arg = convert(schematic); } break; case 'I': if (!modifiable && dimensions == 0) { const Crafting::IngredientSlot & slot = args.getIngredientSlotParam(paramIndex); const ManufactureObjectInterface & schematic = args.getIngredientSlotParamSchematic(paramIndex); int amountRequired = args.getIngredientSlotParamAmountRequired(paramIndex); const std::string & appearance = args.getIngredientSlotParamAppearance(paramIndex); arg = convert(schematic, slot, amountRequired, appearance, ""); } break; case 'V': if (!modifiable) { if (dimensions == 0) { const ValueDictionary & dictionary = args.getValueDictionaryParam(paramIndex); arg = convert(dictionary); } else if (dimensions == 1) { const std::vector & param = args.getValueDictionaryArrayParam(paramIndex); LocalObjectArrayRefPtr localInstance = createNewObjectArray(param.size(), ms_clsDictionary); int paramCount = 0; std::vector::const_iterator iter; for (iter = param.begin(); iter != param.end(); ++iter) { setObjectArrayElement(*localInstance, static_cast(paramCount++), *convert(*iter)); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return 0; } } arg = localInstance; } } break; default: DEBUG_REPORT_LOG(true, ("unknown parameter type %c(%#x)\n", argType, static_cast(argType))); //lint !e571 suspicious cast return 0; } if (arg.get() == NULL || arg == LocalRef::cms_nullPtr) { DEBUG_REPORT_LOG(true, ("bad parameter, %c%s%d%s\n", argType, modifiable ? "*" : "", dimensions, dimensions > 0 ? " dimensions" : "" )); return 0; } if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return 0; } setObjectArrayElement(*javaParams, static_cast(paramIndex + startIndex), *arg); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return 0; } } return true; } // JavaLibrary::convert /** * Copies any modifiable params from Java to C. This is called after a script * has run. * * @param jparams Java parameters * @param argList argument list description * @param args arguments that were passed to the script */ void JavaLibrary::alterScriptParams(jobjectArray jparams, const std::string& argList, ScriptParams &args) { if (ms_env == NULL) return; PROFILER_AUTO_BLOCK_CHECK_DEFINE("JavaLibrary::alterScriptParams"); int paramIndex = 0; for (unsigned i = 0; i < argList.size(); ++i, ++paramIndex) { switch (argList[i]) { case 'i': if (i < argList.size() - 1 && argList[i+1] == '*') { ++i; if (i == argList.size() || argList[i+1] != '[') { LocalRefPtr arg = getObjectArrayElement(LocalObjectArrayRefParam(jparams), paramIndex + 1); if (arg != LocalRef::cms_nullPtr) { int value = getIntField(*arg, ms_fidModifiableIntData); args.changeParam(paramIndex, value); } else { WARNING_STRICT_FATAL(true, ("Error getting back integer param on script return paramIndex=%d, i=%d", paramIndex, i)); } } else if (i < argList.size() - 1 && argList[i+1] == '[') { ++i; LocalArrayRefPtr arg = getArrayArrayElement(LocalObjectArrayRefParam(jparams), paramIndex + 1); if (arg != LocalArrayRef::cms_nullPtr) { int count = getArrayLength(*arg); std::vector * values = new std::vector(count, 0); jint * jvalues = static_cast(ms_env->GetPrimitiveArrayCritical(static_cast(arg->getValue()), NULL)); for (int j = 0; j < count; ++j) { values->at(j) = static_cast(jvalues[j]); } ms_env->ReleasePrimitiveArrayCritical(static_cast(arg->getValue()), jvalues, JNI_ABORT); args.changeParam(paramIndex, *values, true); } else { WARNING_STRICT_FATAL(true, ("Error getting back integer array param on script return")); } } } break; case 'U': if (i < argList.size() - 1 && argList[i+1] == '*') { ++i; if (i == argList.size() || argList[i+1] != '[') { WARNING_STRICT_FATAL(true, ("Error getting back vector param on script return paramIndex=%d, i=%d", paramIndex, i)); } else if (i < argList.size() - 1 && argList[i+1] == '[') { ++i; LocalArrayRefPtr arg = getArrayArrayElement(LocalObjectArrayRefParam(jparams), paramIndex + 1); if (arg != LocalArrayRef::cms_nullPtr) { int count = getArrayLength(*arg); std::vector * values = new std::vector(count, 0); jbyte * jvalues = static_cast(ms_env->GetPrimitiveArrayCritical(static_cast(arg->getValue()), NULL)); for (int j = 0; j < count; ++j) { values->at(j) = static_cast(jvalues[j]); } ms_env->ReleasePrimitiveArrayCritical(static_cast(arg->getValue()), jvalues, JNI_ABORT); args.changeParam(paramIndex, *values, true); } else { WARNING_STRICT_FATAL(true, ("Error getting back integer array param on script return")); } } } break; case 'f': if (i < argList.size() - 1 && argList[i+1] == '*') { ++i; LocalRefPtr arg = getObjectArrayElement(LocalObjectArrayRefParam(jparams), paramIndex + 1); if (arg != LocalRef::cms_nullPtr) { args.changeParam(paramIndex, getFloatField(*arg, ms_fidModifiableFloatData)); } else { WARNING_STRICT_FATAL(true, ("Error getting back float param on script return")); } } break; case 's': if (i < argList.size() - 1 && argList[i+1] == '*') { ++i; if (i < argList.size() - 1 && argList[i+1] == '[') { ++i; LocalObjectArrayRefPtr arg = getObjectArrayArrayElement(LocalObjectArrayRefParam(jparams), paramIndex + 1); if (arg != LocalObjectArrayRef::cms_nullPtr) { std::vector * strings = new std::vector(); getStringArray(*arg, *strings); args.changeParam(paramIndex, *strings, true); } else { WARNING_STRICT_FATAL(true, ("Error getting back string array param on script return")); } } } break; case 'u': if (i < argList.size() - 1 && argList[i+1] == '*') { ++i; if (i < argList.size() - 1 && argList[i+1] == '[') { ++i; LocalObjectArrayRefPtr arg = getObjectArrayArrayElement(LocalObjectArrayRefParam(jparams), paramIndex + 1); if (arg != LocalObjectArrayRef::cms_nullPtr) { std::vector * strings = new std::vector(); getStringArray(*arg, *strings); args.changeParam(paramIndex, *strings, true); } else { WARNING_STRICT_FATAL(true, ("Error getting back string array param on script return")); } } } break; case 'S': if (i < argList.size() - 1 && argList[i+1] == '*') { ++i; StringId * value = new StringId(); LocalRefPtr arg = getObjectArrayElement(LocalObjectArrayRefParam(jparams), paramIndex + 1); if (arg != LocalRef::cms_nullPtr) { // get the string id table JavaStringPtr table = getStringField(*arg, ms_fidStringIdTable); std::string localString; convert(*table, localString); value->setTable(localString); // get the string id text, if it is not NULL/empty, use it localString.clear(); JavaStringPtr text = getStringField(*arg, ms_fidStringIdAsciiId); if (text != JavaString::cms_nullPtr) convert(*text, localString); if (localString[0] != '\0') value->setText(localString); else { // use the textIndex field instead jint textIndex = getIntField(*arg, ms_fidStringIdIndexId); value->setTextIndex(textIndex); } args.changeParam(paramIndex, *value, true); } else { WARNING_STRICT_FATAL(true, ("Error getting back string id param on script return")); } } break; //---------------------------------------------------------------------- //-- menu info case 'm': if (i < argList.size() - 1 && argList[i+1] == '*') { ++i; LocalRefPtr arg = getObjectArrayElement(LocalObjectArrayRefParam(jparams), paramIndex + 1); MenuDataVector * menuVector = new MenuDataVector; convert(arg, *menuVector); args.changeParam (paramIndex, *menuVector, true); } break; //---------------------------------------------------------------------- default: break; } // skip extra characters in the arglist if (i < argList.size() - 1) { if (argList[i+1] == '[' || argList[i+1] == '*') ++i; } } } // JavaLibrary::alterScriptParams /** * Executes all the scripts attached to an object; invoked from C code. * * @param caller object id of the network object invoking this script * @param method script method name * @param argList argument list description * @param args arguments to be passed to the script * * @return SCRIPT_CONTINUE or SCRIPT_OVERRIDE */ int JavaLibrary::runScripts(const NetworkId & caller, const std::string& method, const std::string& argList, ScriptParams & args) { // get the current env count, in case we reset our Java connection int currentEnvCount = ms_envCount; PROFILER_AUTO_BLOCK_CHECK_DEFINE("JavaLibrary::runScripts"); GlobalInstances globals; DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::runScripts enter, self = %s, method = %s\n", caller.getValueString().c_str(), method.c_str())); if (ms_env == NULL || ms_clsObject == NULL) { DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::runScripts exit, self = %s, method = %s\n", caller.getValueString().c_str(), method.c_str())); if (!ms_env) { LOG("ScriptInvestigation", ("runSCripts failed because env was null")); } else { LOG("ScriptInvestigation", ("runSCripts failed because clsObject was null")); } return SCRIPT_OVERRIDE; } if (ms_currentRecursionCount >= MAX_RECURSION_COUNT) { DEBUG_REPORT_LOG(true, ("JavaLibrary::runScripts (C version) max recursion " "count reached, method = %s, object id = %s, dumping script!\n", method.c_str(), caller.getValueString().c_str())); LOG("ScriptInvestigation", ("runSCripts failed because max recursion count reached")); return SCRIPT_OVERRIDE; } // convert the script and method strings to jstrings JavaString jmethod(method.c_str()); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::runScripts exit, self = %s, method = %s\n", caller.getValueString().c_str(), method.c_str())); LOG("ScriptInvestigation", ("runScripts failed trying to convert method " "name to jstring")); return SCRIPT_OVERRIDE; } // convert the params to jobjects LocalObjectArrayRefPtr jparams = convert(caller, argList, args); if (jparams == LocalObjectArrayRef::cms_nullPtr) { DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::runScripts exit, self = %s, method = %s\n", caller.getValueString().c_str(), method.c_str())); LOG("ScriptInvestigation", ("runSCripts failed because could not convert params")); return SCRIPT_OVERRIDE; } // invoke the script method jint result = callScriptEntry(jmethod, jparams->getValue()); //========================================================================== // !!IMPORTANT after this point our env pointer may have changed, we can't // call any JNI functions on objects created with the old pointer!! //========================================================================== if (result == SCRIPT_CONTINUE && argList.find('*') != std::string::npos) { if (currentEnvCount == ms_envCount) { // copy any modifiable params from Java to C alterScriptParams(jparams->getValue(), argList, args); } else { LOG("ScriptInvestigation", ("JavaLibrary::runScripts env has changed, " "we can't get return params for trigger %s", method.c_str())); } } if (currentEnvCount == ms_envCount) { if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::runScripts exit, self = %s, method = %s\n", caller.getValueString().c_str(), method.c_str())); LOG("ScriptInvestigation", ("runSCripts failed because exception after delete")); return SCRIPT_OVERRIDE; } } else { DEBUG_LOG("ScriptInvestigation", ("JavaLibrary::runScripts env changed after trigger %s", method.c_str())); jmethod.emergencyClear(); } DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::runScripts exit, self = %s, method = %s\n", caller.getValueString().c_str(), method.c_str())); return result; } // JavaLibrary::runScripts(const ScriptParams & args) /** * Executes all the scripts attached to an object; invoked from the console. * * @param caller object id of the network object invoking this script * @param method script method name * @param argList argument list description * @param args arguments to be passed to the script * * @return SCRIPT_CONTINUE or SCRIPT_OVERRIDE */ int JavaLibrary::runScripts(const NetworkId & caller, const std::string& method, const std::string& argList, const StringVector_t &args) { DEBUG_WARNING(true, ("Running scripts from the console not currently supported")); LOG("ScriptInvestigation", ("runScripts from console is not supported")); return SCRIPT_OVERRIDE; } // JavaLibrary::runScripts(StringVector_t args) /** * Executes a script invoked from C code. * * @param caller object id of the network object invoking this script * @param script script name * @param method script method name * @param argList argument list description * @param args arguments to be passed to the script * * @return SCRIPT_CONTINUE or SCRIPT_OVERRIDE */ int JavaLibrary::runScript(const NetworkId & caller, const std::string& script, const std::string& method, const std::string& argList, ScriptParams & args) { // get the current env count, in case we reset our Java connection int currentEnvCount = ms_envCount; PROFILER_AUTO_BLOCK_CHECK_DEFINE("JavaLibrary::runScript"); GlobalInstances globals; DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::runScript %s enter, self = %s, method = %s\n", script.c_str(), caller.getValueString().c_str(), method.c_str())); if (ms_env == NULL || ms_midRunOne == NULL || ms_clsObject == NULL) { if (!ms_env) { LOG("ScriptInvestigation", ("runSCripts2 failed because env was null")); } else if (!ms_midRunOne) { LOG("ScriptInvestigation", ("runSCripts2 failed because midRunOne was null")); } else { LOG("ScriptInvestigation", ("runSCripts2 failed because clsObject was null")); } return SCRIPT_OVERRIDE; } if (ms_currentRecursionCount >= MAX_RECURSION_COUNT) { DEBUG_REPORT_LOG(true, ("JavaLibrary::runScript (C version) max recursion " "count reached, script = %s, method = %s, object id = %s, dumping " "script!\n", script.c_str(), method.c_str(), caller.getValueString().c_str())); LOG("ScriptInvestigation", ("runSCripts2 failed because max recursion count reached")); return SCRIPT_OVERRIDE; } // convert the script and method strings to jstrings JavaString jscript(("script." + script).c_str()); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); LOG("ScriptInvestigation", ("runSCripts2 failed because of exception")); return SCRIPT_OVERRIDE; } JavaString jmethod(method.c_str()); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); LOG("ScriptInvestigation", ("runSCripts2 failed because of exception2")); return SCRIPT_OVERRIDE; } // convert the params to jobjects LocalObjectArrayRefPtr jparams = convert(caller, argList, args); if (jparams == LocalObjectArrayRef::cms_nullPtr) { ms_env->ExceptionDescribe(); LOG("ScriptInvestigation", ("runSCripts2 failed because of exception3")); return SCRIPT_OVERRIDE; } // invoke the script method jint result = callScriptEntry(jscript, jmethod, jparams->getValue()); //========================================================================== // !!IMPORTANT after this point our env pointer may have changed, we can't // call any JNI functions on objects created with the old pointer!! //========================================================================== if (result == SCRIPT_DEFAULT) result = SCRIPT_CONTINUE; if (result == SCRIPT_CONTINUE && argList.find('*') != std::string::npos) { if (currentEnvCount == ms_envCount) { // copy any modifiable params from Java to C alterScriptParams(jparams->getValue(), argList, args); } else { LOG("ScriptInvestigation", ("JavaLibrary::runScript env has changed, " "we can't get return params for trigger %s", method.c_str())); } } if (currentEnvCount == ms_envCount) { if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); LOG("ScriptInvestigation", ("runScript failed because of exception4")); return SCRIPT_OVERRIDE; } } else { DEBUG_LOG("ScriptInvestigation", ("JavaLibrary::runScript env changed after trigger %s", method.c_str())); jscript.emergencyClear(); jmethod.emergencyClear(); } DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::runScript %s exit, self = %s, method = %s\n", script.c_str(), caller.getValueString().c_str(), method.c_str())); return result; } // JavaLibrary::runScript(const ScriptParams & args) /** * Executes a script invoked from Java code. * * @param caller object id of the network object invoking this script * @param script script name * @param method script method name * @param args arguments to be passed to the script * * @return SCRIPT_CONTINUE or SCRIPT_OVERRIDE */ int JavaLibrary::runScript(const NetworkId & caller, const std::string& script, const std::string& method, jobjectArray args) { // get the current env count, in case we reset our Java connection int currentEnvCount = ms_envCount; PROFILER_AUTO_BLOCK_CHECK_DEFINE("JavaLibrary::runScript"); DEBUG_REPORT_LOG(true, ("JavaLibrary::runScript %s enter, method = %s\n", script.c_str(), method.c_str())); if (ms_env == NULL || ms_midRunOne == NULL || ms_clsObject == NULL) { if (!ms_env) { LOG("ScriptInvestigation", ("runSCripts3 failed because env was null")); } else if (!ms_midRunOne) { LOG("ScriptInvestigation", ("runSCripts3 failed because midRunOne was null")); } else { LOG("ScriptInvestigation", ("runSCripts3 failed because clsObject was null")); } return SCRIPT_OVERRIDE; } if (ms_currentRecursionCount >= MAX_RECURSION_COUNT) { DEBUG_REPORT_LOG(true, ("JavaLibrary::runScript (Java version) max " "recursion count reached, script = %s, method = %s, object id = %s, " "dumping script!\n", script.c_str(), method.c_str(), caller.getValueString().c_str())); LOG("ScriptInvestigation", ("runSCripts3 failed because of max recursion count")); return SCRIPT_OVERRIDE; } // convert the script and method strings to jstrings JavaString jscript(("script." + script).c_str()); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); LOG("ScriptInvestigation", ("runSCripts3 failed because of exception")); return SCRIPT_OVERRIDE; } JavaString jmethod(method.c_str()); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); LOG("ScriptInvestigation", ("runSCripts3 failed because of exception2")); return SCRIPT_OVERRIDE; } // copy the args to a new array that has the object id tacked on int argsCount = 1; if (args != 0) argsCount += ms_env->GetArrayLength(args); LocalObjectArrayRefPtr jparams = createNewObjectArray(argsCount, ms_clsObject); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); LOG("ScriptInvestigation", ("runSCripts3 failed because of exception3")); return SCRIPT_OVERRIDE; } for (int i = 1; i < argsCount; ++i) { LocalRefPtr element = getObjectArrayElement(LocalObjectArrayRefParam(args), i - 1); setObjectArrayElement(*jparams, i, *element); } // add the "self" parameter as the 1st argument LocalRefPtr self = getObjId(caller); setObjectArrayElement(*jparams, 0, *self); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); LOG("ScriptInvestigation", ("runSCripts3 failed because of exception4")); return SCRIPT_OVERRIDE; } // invoke the script method jint result = callScriptEntry(jscript, jmethod, jparams->getValue()); //========================================================================== // !!IMPORTANT after this point our env pointer may have changed, we can't // call any JNI functions on objects created with the old pointer!! //========================================================================== if (currentEnvCount == ms_envCount) { if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); LOG("ScriptInvestigation", ("runSCripts3 failed because of exception5")); return SCRIPT_OVERRIDE; } } else { DEBUG_LOG("ScriptInvestigation", ("JavaLibrary::runScript(from java) env changed after trigger %s", method.c_str())); self->emergencyClear(); jparams->emergencyClear(); jscript.emergencyClear(); jmethod.emergencyClear(); } DEBUG_REPORT_LOG(true, ("JavaLibrary::runScript %s exit, method = %s\n", script.c_str(), method.c_str())); return result; } // JavaLibrary::runScript(jobjectArray args) /** * Executes a script invoked from the console. * * @param caller object id of the network object invoking this script * @param script script name * @param method script method name * @param argList argument list description * @param args arguments to be passed to the script * * @return SCRIPT_CONTINUE or SCRIPT_OVERRIDE */ int JavaLibrary::runScript(const NetworkId & caller, const std::string& script, const std::string& method, const std::string& argList, const StringVector_t &args) { // get the current env count, in case we reset our Java connection int currentEnvCount = ms_envCount; PROFILER_AUTO_BLOCK_CHECK_DEFINE("JavaLibrary::runScript"); GlobalInstances globals; DEBUG_REPORT_LOG(true, ("JavaLibrary::runScript %s enter, method = %s\n", script.c_str(), method.c_str())); if (ms_env == NULL || ms_midRunOne == NULL || ms_clsObject == NULL) { if (!ms_env) { LOG("ScriptInvestigation", ("runSCripts4 failed because env was null")); } else if (!ms_midRunOne) { LOG("ScriptInvestigation", ("runSCripts4 failed because midRunOne was null")); } else { LOG("ScriptInvestigation", ("runSCripts4 failed because clsObject was null")); } return SCRIPT_OVERRIDE; } if (ms_currentRecursionCount >= MAX_RECURSION_COUNT) { DEBUG_REPORT_LOG(true, ("JavaLibrary::runScript (console version) max " "recursion count reached, script = %s, method = %s, object id = %s, " "dumping script!\n", script.c_str(), method.c_str(), caller.getValueString().c_str())); LOG("ScriptInvestigation", ("runSCripts4 failed because of max recursion count")); return SCRIPT_OVERRIDE; } // convert the script and method strings to jstrings JavaString jscript(("script." + script).c_str()); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); LOG("ScriptInvestigation", ("runSCripts4 failed because of exception")); return SCRIPT_OVERRIDE; } JavaString jmethod(method.c_str()); if (ms_env->ExceptionCheck()) { LOG("ScriptInvestigation", ("runSCripts4 failed because of exception2")); ms_env->ExceptionDescribe(); return SCRIPT_OVERRIDE; } // convert the params to jobjects LocalObjectArrayRefPtr jparams = createNewObjectArray(static_cast(argList.size() + 1), ms_clsObject); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); LOG("ScriptInvestigation", ("runSCripts4 failed because of exception3")); return SCRIPT_OVERRIDE; } // add the "self" parameter LocalRefPtr self = getObjId(caller); setObjectArrayElement(*jparams, 0, *self); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); LOG("ScriptInvestigation", ("runSCripts4 failed because of exception4")); return SCRIPT_OVERRIDE; } // add the rest of the parameters for (unsigned i = 0; i < argList.size(); ++i) { LocalRefParamPtr arg = LocalRefParam::cms_nullPtr; const char *stringArg = Unicode::wideToNarrow(args[i]).c_str(); switch (argList[i]) { case 'i': { jint param = atoi(stringArg); arg = createNewObject(ms_clsInteger, ms_midInteger, param); } break; case 'f': { jfloat param = static_cast(atof(stringArg)); arg = createNewObject(ms_clsFloat, ms_midFloat, param); } break; case 's': { arg = createNewString(stringArg); } break; case 'u': { arg = createNewString(args[i].c_str(), static_cast(args[i].size())); } break; case 'O': { arg = getObjId(NetworkId(stringArg)); if (arg == LocalRef::cms_nullPtr) { LOG("ScriptInvestigation", ("runSCripts4 failed because of bad objid")); return SCRIPT_OVERRIDE; } } break; #if 0 case 'S': { arg = globals.getNextStringId(); if (arg == 0) { return SCRIPT_OVERRIDE; } // @todo: fix this when we get real string ids // int param = atoi(stringArg); // ms_env->SetIntField(arg, ms_fidStringIdData, static_cast(param)); } break; #endif default: DEBUG_REPORT_LOG(true, ("unknown parameter type %c(%#x)\n", argList[i], static_cast(argList[i]))); //lint !e571 suspicious cast LOG("ScriptInvestigation", ("runSCripts4 failed because of param")); return SCRIPT_OVERRIDE; } if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); LOG("ScriptInvestigation", ("runSCripts4 failed because of exception5")); return SCRIPT_OVERRIDE; } setObjectArrayElement(*jparams, static_cast(i + 1), *arg); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); LOG("ScriptInvestigation", ("runSCripts4 failed because of exception6")); return SCRIPT_OVERRIDE; } } // invoke the script method jint result = callScriptEntry(jscript, jmethod, jparams->getValue()); //========================================================================== // !!IMPORTANT after this point our env pointer may have changed, we can't // call any JNI functions on objects created with the old pointer!! //========================================================================== if (currentEnvCount == ms_envCount) { if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); LOG("ScriptInvestigation", ("runSCripts4 failed because of exception7")); return SCRIPT_OVERRIDE; } } else { DEBUG_LOG("ScriptInvestigation", ("JavaLibrary::runScript(from console) env changed after trigger %s", method.c_str())); self->emergencyClear(); jparams->emergencyClear(); jscript.emergencyClear(); jmethod.emergencyClear(); } return result; } // JavaLibrary::runScript(StringVector_t args) /** * Calls a special function on a script that returns a string instead of an * integer. The script function has no "self" associated with it. * * @param script the name of the script to call * @param method the function name in the script * @param argList the argument types that are being passed to the script * @param args the arguments that are being passed to the script * * @return the string returned from the script function */ std::string JavaLibrary::callScriptConsoleHandler(const std::string & script, const std::string & method, const std::string & argList, ScriptParams & args) { static const std::string errorReturnString; // get the current env count, in case we reset our Java connection int currentEnvCount = ms_envCount; PROFILER_AUTO_BLOCK_CHECK_DEFINE("JavaLibrary::callScriptConsoleHandler"); GlobalInstances globals; DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::runScript %s enter, method = %s\n", script.c_str(), method.c_str())); if (ms_env == NULL || ms_midRunConsoleHandler == NULL || ms_clsObject == NULL) { if (!ms_env) { LOG("ScriptInvestigation", ("runSCripts2 failed because env was null")); } else if (!ms_midRunConsoleHandler) { LOG("ScriptInvestigation", ("runSCripts2 failed because midRunConsoleHandler was null")); } else { LOG("ScriptInvestigation", ("runSCripts2 failed because clsObject was null")); } return errorReturnString; } if (ms_currentRecursionCount >= MAX_RECURSION_COUNT) { DEBUG_REPORT_LOG(true, ("JavaLibrary::callScriptConsoleHandler max recursion " "count reached, script = %s, method = %s, dumping " "script!\n", script.c_str(), method.c_str())); LOG("ScriptInvestigation", ("callScriptConsoleHandler failed because max recursion count reached")); return errorReturnString; } // convert the script and method strings to jstrings JavaString jscript(("script." + script).c_str()); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); LOG("ScriptInvestigation", ("callScriptConsoleHandler failed because of exception")); return errorReturnString; } JavaString jmethod(method.c_str()); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); LOG("ScriptInvestigation", ("callScriptConsoleHandler failed because of exception2")); return errorReturnString; } // convert the params to jobjects LocalObjectArrayRefPtr jparams = convert(argList, args); if (jparams == LocalObjectArrayRef::cms_nullPtr) { ms_env->ExceptionDescribe(); LOG("ScriptInvestigation", ("callScriptConsoleHandler failed because of exception3")); return errorReturnString; } // invoke the script method jstring result = callScriptConsoleHandlerEntry(jscript, jmethod, jparams->getValue()); //========================================================================== // !!IMPORTANT after this point our env pointer may have changed, we can't // call any JNI functions on objects created with the old pointer!! //========================================================================== std::string returnResult; if (currentEnvCount == ms_envCount) { JavaString resultString(result); if (argList.find('*') != std::string::npos) { // copy any modifiable params from Java to C alterScriptParams(jparams->getValue(), argList, args); } if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); LOG("ScriptInvestigation", ("callScriptConsoleHandler failed because of exception4")); return errorReturnString; } convert(resultString, returnResult); } else { DEBUG_LOG("ScriptInvestigation", ("JavaLibrary::callScriptConsoleHandler env changed after trigger %s", method.c_str())); jscript.emergencyClear(); jmethod.emergencyClear(); } DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::callScriptConsoleHandler %s exit, method = %s\n", script.c_str(), method.c_str())); return returnResult; } // JavaLibrary::callScriptConsoleHandler /** * Tells the script engine to reload a script file. * * @param scriptName the script name * * @return true on success, false if the script wasn't found */ bool JavaLibrary::reloadScript(const std::string& scriptName) { if (ms_env == NULL || ms_clsScriptEntry == NULL || ms_midUnload == NULL) return false; // convert the script name to jstring JavaString jscript(("script." + scriptName).c_str()); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } // call the unload method jboolean result = ms_env->CallStaticBooleanMethod(ms_clsScriptEntry, ms_midUnload, jscript.getValue()); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); return false; } return result; } // JavaLibrary::reloadScript /** * Calls a user-defined message method on all scripts attached to an object. * * @param caller object id of the network object invoking this script * @param method script message method name * @param data data to be passed to the message * * @return SCRIPT_CONTINUE or SCRIPT_OVERRIDE */ int JavaLibrary::callMessages(const NetworkId & caller, const std::string & method, const ScriptDictionaryPtr & data) { // get the current env count, in case we reset our Java connection int currentEnvCount = ms_envCount; DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::callMessages enter, self = %s, method = %s\n", caller.getValueString().c_str(), method.c_str())); int result = SCRIPT_CONTINUE; if (ms_env == NULL || ms_midRunOne == NULL || ms_clsObject == NULL) { DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::callMessages exit, self = %s, method = %s\n", caller.getValueString().c_str(), method.c_str())); if (!ms_env) { LOG("ScriptInvestigation", ("callMessages failed because env was null")); } else if (!ms_midRunOne) { LOG("ScriptInvestigation", ("callMessages failed because midRunOne was null")); } else { LOG("ScriptInvestigation", ("callMessages failed because clsObject was null")); } return SCRIPT_OVERRIDE; } if (ms_currentRecursionCount >= MAX_RECURSION_COUNT) { DEBUG_REPORT_LOG(true, ("JavaLibrary::callMessages max recursion count reached, " "method = %s, object id = %s, dumping script!\n", method.c_str(), caller.getValueString().c_str())); LOG("ScriptInvestigation", ("callMessages failed because max recurion count")); return SCRIPT_OVERRIDE; } const JavaDictionary * dictionary = safe_cast(data.get()); jobject jdictionary = 0; if (dictionary != NULL) jdictionary = dictionary->getValue(); // convert the method string to jstrings JavaString jmethod(method.c_str()); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::callMessages exit, self = %s, method = %s\n", caller.getValueString().c_str(), method.c_str())); LOG("ScriptInvestigation", ("callMessages failed because of exception")); return SCRIPT_OVERRIDE; } ++ms_currentRecursionCount; if (ms_currentRecursionCount > 3) { LOG("ScriptRecursion", ("callMessages recursion %d", ms_currentRecursionCount)); } result = ms_env->CallStaticIntMethod(ms_clsScriptEntry, ms_midCallMessages, jmethod.getValue(), caller.getValue(), jdictionary); --ms_currentRecursionCount; result = handleScriptEntryCleanup(result); //========================================================================== // !!IMPORTANT after this point our env pointer may have changed, we can't // call any JNI functions on objects created with the old pointer!! //========================================================================== if (currentEnvCount != ms_envCount) { jmethod.emergencyClear(); } DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::callMessages exit, self = %s, method = %s\n", caller.getValueString().c_str(), method.c_str())); return result; } // JavaLibrary::callMessages /** * Calls a user-defined message method on a script attached to an object. * * @param caller object id of the network object invoking this script * @param script script name * @param method script message method name * @param data data to be passed to the message * * @return SCRIPT_CONTINUE or SCRIPT_OVERRIDE */ int JavaLibrary::callMessage(const NetworkId & caller, const std::string & script, const std::string & method, const ScriptDictionary & data) { // get the current env count, in case we reset our Java connection int currentEnvCount = ms_envCount; DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::callMessage %s enter, self = %s, method = %s\n", script.c_str(), caller.getValueString().c_str(), method.c_str())); if (ms_env == NULL || ms_midRunOne == NULL || ms_clsObject == NULL) { DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::callMessage %s exit, self = %s, method = %s\n", script.c_str(), caller.getValueString().c_str(), method.c_str())); if (!ms_env) { LOG("ScriptInvestigation", ("callMessage failed because env was null")); } else if (!ms_midRunOne) { LOG("ScriptInvestigation", ("callMessage failed because midRunOne was null")); } else { LOG("ScriptInvestigation", ("callMessage failed because clsObject was null")); } return SCRIPT_OVERRIDE; } if (ms_currentRecursionCount >= MAX_RECURSION_COUNT) { DEBUG_REPORT_LOG(true, ("JavaLibrary::callMessage max recursion count reached, " "script = %s, method = %s, object id = %s, dumping script!\n", script.c_str(), method.c_str(), caller.getValueString().c_str())); LOG("ScriptInvestigation", ("callMessage failed because max recursion count")); return SCRIPT_OVERRIDE; } const JavaDictionary * dictionary = dynamic_cast(&data); if (dictionary == NULL) { DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::callMessage %s exit, self = %s, method = %s\n", script.c_str(), caller.getValueString().c_str(), method.c_str())); LOG("ScriptInvestigation", ("callMessage failed because bad dictionary")); return SCRIPT_OVERRIDE; } // convert the script and method strings to jstrings JavaString jscript(script.c_str()); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::callMessage %s exit, self = %s, method = %s\n", script.c_str(), caller.getValueString().c_str(), method.c_str())); LOG("ScriptInvestigation", ("callMessage failed because exception")); return SCRIPT_OVERRIDE; } JavaString jmethod(method.c_str()); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::callMessage %s exit, self = %s, method = %s\n", script.c_str(), caller.getValueString().c_str(), method.c_str())); LOG("ScriptInvestigation", ("callMessage failed because exception2")); return SCRIPT_OVERRIDE; } // set up the parameters LocalObjectArrayRefPtr jparams = createNewObjectArray(2, ms_clsObject); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::callMessage %s exit, self = %s, method = %s\n", script.c_str(), caller.getValueString().c_str(), method.c_str())); LOG("ScriptInvestigation", ("callMessage failed because exception3")); return SCRIPT_OVERRIDE; } // add the data parameter setObjectArrayElement(*jparams, 1, *dictionary); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::callMessage %s exit, self = %s, method = %s\n", script.c_str(), caller.getValueString().c_str(), method.c_str())); LOG("ScriptInvestigation", ("callMessage failed because exception4")); return SCRIPT_OVERRIDE; } // add the "self" parameter LocalRefPtr self = getObjId(caller); setObjectArrayElement(*jparams, 0, *self); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); DEBUG_REPORT_LOG(ConfigServerGame::getJavaConsoleDebugMessages(), ( "JavaLibrary::callMessage %s exit, self = %s, method = %s\n", script.c_str(), caller.getValueString().c_str(), method.c_str())); LOG("ScriptInvestigation", ("callMessage failed because exception5")); return SCRIPT_OVERRIDE; } int result = callScriptEntry(jscript, jmethod, jparams->getValue()); //========================================================================== // !!IMPORTANT after this point our env pointer may have changed, we can't // call any JNI functions on objects created with the old pointer!! //========================================================================== if (currentEnvCount == ms_envCount) { if (ms_env->ExceptionCheck()) ms_env->ExceptionDescribe(); } else { DEBUG_LOG("ScriptInvestigation", ("JavaLibrary::callMessage env changed after message %s", method.c_str())); self->emergencyClear(); jparams->emergencyClear(); jscript.emergencyClear(); jmethod.emergencyClear(); } return result; } // JavaLibrary::callMessage //======================================================================== // class JavaLibrary string/stringId methods //======================================================================== /** * Gets the name of a java class/script. * * @param sourceClass the class we want the name of * @param target string that will be filled in with the name * * @reurn true on success, false on error */ const bool JavaLibrary::getClassName(const jclass & sourceClass, std::string & target) { bool result = false; if(ms_env) { const LocalRefParamPtr classPtr(new LocalRefParam(sourceClass)); JavaStringPtr s = callStringMethod(*classPtr, JavaLibrary::ms_midClassGetName); if (s != JavaString::cms_nullPtr) { if (convert(*s, target)) { //@todo Make sure this is the correct way to do things //we need to strip script. from the beginning of the class string const std::string scriptString("script."); size_t position = target.find(scriptString); if (position == 0) { target.erase(position, scriptString.length()); } result = true; } } } return result; } // JavaLibrary::getClassName(const jclass &) /** * Gets the name of a java class/script. * * @param source the object we want the class name of * @param target string that will be filled in with the name * * @reurn true on success, false on error */ const bool JavaLibrary::getClassName(const jobject & source, std::string & target) { bool result = false; if (ms_env) { jclass tempClass = ms_env->GetObjectClass(source); result = getClassName(tempClass, target); } return result; } // JavaLibrary::getClassName(const jobject &) //----------------------------------------------------------------------- /** * Packs a Java dictionary class into a string for network transmission. * * @param dictionary the dictionary to pack * @param packedData the string to be filled with the packed dictionary */ void JavaLibrary::packDictionary(const ScriptDictionary & dictionary, std::vector & packedData) { const_cast(dictionary).serialize(); packedData = dictionary.getSerializedData(); } // JavaLibrary::packDictionary /** * Unpacks a Java dictionary class from a string. * * @param packedData the string to unpack * @param dictionary pointer to be set to the unpacked dictionary * * @return true on success, false on error */ bool JavaLibrary::unpackDictionary(const std::vector & packedData, ScriptDictionaryPtr & dictionary) { if (ms_env == NULL) return false; dictionary = JavaDictionary::cms_nullPtr; if (!packedData.empty()) { // get the crc from the data // uint32 crc = 0; int dataLen = packedData.size(); const int8 * data = &packedData[0]; /* std::vector::const_iterator result = std::find(packedData.begin(), packedData.end(), '*'); if (result != packedData.end()) { // double-check: verify all the characters before the marker are // digits int i; int markerPos = packedData.end() - result; for (i = 0; i < markerPos; ++i) { if (!isdigit(data[i])) break; crc = crc * 10 + (data[i] - '0'); } if (i == markerPos) { data = &data[markerPos+1]; // verify the crc dataLen -= markerPos + 1; uint32 dataCrc = Crc::calculate(data, dataLen); if (crc != dataCrc) { WARNING(true, ("JavaLibrary::unpackDictionary got packed data with " "bad crc! Expected: %lu, got %lu.", crc, dataCrc)); return false; } } } */ if (data != NULL && *data != '\0') { LocalByteArrayRefPtr jdata = createNewByteArray(dataLen); if (jdata != LocalByteArrayRef::cms_nullPtr) { setByteArrayRegion(*jdata, 0, dataLen, const_cast(data)); JavaDictionaryPtr lref(new JavaDictionary(ms_env->CallStaticObjectMethod(ms_clsDictionary, ms_midDictionaryUnpack, jdata->getValue()))); if (lref == JavaDictionary::cms_nullPtr) { WARNING(true, ("JavaLibrary::unpackDictionary error unpacking dictionary")); return false; } dictionary = lref; } } } return true; } // JavaLibrary::unpackDictionary //----------------------------------------------------------------------- /** * Convert a JavaString to a std::string. */ const bool JavaLibrary::convert(const JavaStringParam & source, std::string & target) { bool result = false; if (ms_env) { if (source.getValue() != 0) { jboolean isCopy(false); const char * temp = ms_env->GetStringUTFChars(source.getValue(), &isCopy); if(temp) { target = temp; ms_env->ReleaseStringUTFChars(source.getValue(), temp); result = true; } } } return result; } // JavaLibrary::convert(const JavaStringParam &, std::string &) /** * Convert a JavaString to a Unicode::String. */ const bool JavaLibrary::convert(const JavaStringParam & source, Unicode::String & target) { bool result = false; if (ms_env) { if (source.getValue() != 0) { jboolean isCopy = JNI_FALSE; jsize len = getStringLength(source); const jchar * temp = ms_env->GetStringCritical(source.getValue(), &isCopy); if (temp) { target.assign(temp, len); ms_env->ReleaseStringCritical(source.getValue(), temp); result = true; } } } return result; } // JavaLibrary::convert(const JavaStringParam &, Unicode::String &) //----------------------------------------------------------------------- /** * Serializes a JavaDictionary into a string. */ const bool JavaLibrary::convert(const JavaDictionary & source, std::vector & target) { bool result = false; if (ms_env != NULL) { if (source.getValue() != 0) { // convert the dictionary to a jstring LocalByteArrayRefPtr packedData = callByteArrayMethod(source, ms_midDictionaryPack); if (ms_env->ExceptionCheck()) { ms_env->ExceptionDescribe(); } else if (packedData != LocalByteArrayRef::cms_nullPtr) { // convert the Java array to a vector int count = getArrayLength(*packedData); target.reserve(count); target.resize(count); getByteArrayRegion(*packedData, 0, count, &target[0]); result = true; } } } return result; } // JavaLibrary::convert(const JavaDictionary &, std::string &) //======================================================================= const bool JavaLibrary::convert(const std::map & source, JavaDictionaryPtr & target) { std::vector > sourceData; std::map:: const_iterator i; for(i = source.begin(); i != source.end(); ++i) { sourceData.push_back(*i); } return convert(sourceData, target); } //----------------------------------------------------------------------- const bool JavaLibrary::convert(const std::vector > & source, JavaDictionaryPtr & target) { if (!JavaLibrary::getEnv()) return false; target = createNewDictionary(); if (target == JavaDictionary::cms_nullPtr) return false; std::vector >::const_iterator i; for(i = source.begin(); i != source.end(); ++i) { int value = (*i).second; JavaString name((*i).first.c_str()); callObjectMethod(*target, ms_midDictionaryPutInt, name.getValue(), value); } return true; } //----------------------------------------------------------------------- const bool JavaLibrary::convert(const std::vector > > & source, JavaDictionaryPtr & target) { if (!JavaLibrary::getEnv()) return false; target = createNewDictionary(); if (target == JavaDictionary::cms_nullPtr) return false; std::vector > >::const_iterator i; for(i = source.begin(); i != source.end(); ++i) { int value = (*i).second.first; JavaString name((*i).first.c_str()); callObjectMethod(*target, ms_midDictionaryPutInt, name.getValue(), value); } return true; } //----------------------------------------------------------------------- const bool JavaLibrary::convert(const std::vector > & source, JavaDictionaryPtr & target) { if (!JavaLibrary::getEnv()) return false; target = createNewDictionary(); if (target == JavaDictionary::cms_nullPtr) return false; std::vector >::const_iterator i; for(i = source.begin(); i != source.end(); ++i) { JavaString name((*i).first.c_str()); bool value = (*i).second; callObjectMethod(*target, ms_midDictionaryPutBool, name.getValue(), value); } return true; } //======================================================================= namespace ScriptConversion { const bool convert(const jobject & source, Vector & target, NetworkId & targetCell, const Vector & i_default) { if (!convert(source, target, targetCell)) { target = i_default; targetCell = NetworkId::cms_invalid; } return true; } const bool convert(const std::vector & source, LocalObjectArrayRefPtr & target) { if (!JavaLibrary::getEnv()) return false; bool result = false; int count = source.size(); target = createNewObjectArray(count, JavaLibrary::ms_clsString); if (target != LocalObjectArrayRef::cms_nullPtr) { result = true; for (int i = 0; i < count; ++i) { if (source[i] != NULL) { JavaString targetElement(*source[i]); setObjectArrayElement(*target, i, targetElement); } } } return result; } const bool convert(const jobject source, StringId & target) { if (source == 0) return false; JNIEnv * env = JavaLibrary::getEnv(); if (!env) return false; if (env->IsInstanceOf(source, JavaLibrary::ms_clsStringId) == JNI_FALSE) return false; // @todo: it would be nice if we had a known max length for the table // name and text in order to use buffers to get the strings // get the table { JavaStringPtr tempString = getStringField(LocalRefParam(source), JavaLibrary::ms_fidStringIdTable); std::string localString; JavaLibrary::convert(*tempString, localString); target.setTable(localString); } // get the text { JavaStringPtr tempString = getStringField(LocalRefParam(source), JavaLibrary::ms_fidStringIdAsciiId); if (tempString != JavaString::cms_nullPtr && getStringLength(*tempString) > 0) { std::string localString; JavaLibrary::convert(*tempString, localString); target.setText(localString); } else { // get the text index jint textIndex = env->GetIntField(source, JavaLibrary::ms_fidStringIdIndexId); target.setTextIndex(textIndex); } } return true; } const bool convert(const LocalRefParam & source, StringId & target) { return convert(source.getValue(), target); } const bool convert(const StringId & source, LocalRefPtr & target) { if (!JavaLibrary::getEnv()) return false; target = allocObject(JavaLibrary::ms_clsStringId); if (target == LocalRef::cms_nullPtr) return false; // convert the table { JavaString tempString(source.getTable().c_str()); setObjectField(*target, JavaLibrary::ms_fidStringIdTable, tempString); } // convert the text { JavaString tempString(source.getText().c_str()); setObjectField(*target, JavaLibrary::ms_fidStringIdAsciiId, tempString); } // convert the index setIntField(*target, JavaLibrary::ms_fidStringIdIndexId, source.getTextIndex()); return true; } const bool convert(const std::vector & source, LocalObjectArrayRefPtr & strArray) { JNIEnv * env = JavaLibrary::getEnv(); if (!env) return false; if (env->ExceptionCheck()) { env->ExceptionDescribe(); return false; } strArray = createNewObjectArray(static_cast(source.size()), JavaLibrary::ms_clsString); std::vector::const_iterator i; int index = 0; for(i = source.begin(); i != source.end(); ++i) { const char * s = (*i).c_str(); JavaString js(s); if (env->ExceptionCheck()) { env->ExceptionDescribe(); return false; } setObjectArrayElement(*strArray, index, js); if (env->ExceptionCheck()) { env->ExceptionDescribe(); return false; } ++index; } return true; } const bool convert(const std::vector & source, LocalObjectArrayRefPtr & strArray) { JNIEnv * env = JavaLibrary::getEnv(); if (!env) return false; if (env->ExceptionCheck()) { env->ExceptionDescribe(); return false; } strArray = createNewObjectArray(static_cast(source.size()), JavaLibrary::ms_clsString); std::vector::const_iterator i; int index = 0; for(i = source.begin(); i != source.end(); ++i) { JavaString js(*i); if (env->ExceptionCheck()) { env->ExceptionDescribe(); return false; } setObjectArrayElement(*strArray, index, js); if (env->ExceptionCheck()) { env->ExceptionDescribe(); return false; } ++index; } return true; } const bool convert(const std::set & source, LocalObjectArrayRefPtr & strArray) { JNIEnv * env = JavaLibrary::getEnv(); if (!env) return false; if (env->ExceptionCheck()) { env->ExceptionDescribe(); return false; } strArray = createNewObjectArray(static_cast(source.size()), JavaLibrary::ms_clsString); std::set::const_iterator i; int index = 0; for(i = source.begin(); i != source.end(); ++i) { const std::string name = (*i).getName(); const char * const s = name.c_str(); JavaString js(s); if (env->ExceptionCheck()) { env->ExceptionDescribe(); return false; } setObjectArrayElement(*strArray, index, js); if (env->ExceptionCheck()) { env->ExceptionDescribe(); return false; } ++index; } return true; } const bool convert(const jobjectArray & source, stdvector::fwd & target) { JNIEnv * env = JavaLibrary::getEnv(); if (!env || !source) return false; int count = env->GetArrayLength(source); target.resize(count, ""); std::string tempString; for (int i = 0; i < count; ++i) { JavaStringPtr s = getStringArrayElement(LocalObjectArrayRefParam(source), i); if (s != JavaString::cms_nullPtr) { if (JavaLibrary::convert(*s, tempString)) target[i] = tempString; } } return true; } const bool convert(const jlongArray & source, std::vector &results) { bool result = false; JNIEnv * env = JavaLibrary::getEnv(); if (!env || !source) return false; jsize count = env->GetArrayLength(source); jsize i; result = true; jlong jlongTmp; for (i=0; iGetLongArrayRegion(source, i, 1, &jlongTmp); NetworkId nid(jlongTmp); if (!nid) { result = false; } else { results.push_back(nid); } } return result; } const bool convert(const jlongArray & source, std::vector &results) { JNIEnv * env = JavaLibrary::getEnv(); if (!env || !source) return false; bool result = false; jsize count = env->GetArrayLength(source); jsize i; result = true; for (i=0; iGetLongArrayRegion(source, i, 1, &id); ServerObject * object = 0; if (!JavaLibrary::getObject(id, object)) { result = false; } else { results.push_back(object); } } return result; } const bool convert(const std::vector &source, LocalLongArrayRefPtr & result) { JNIEnv * env = JavaLibrary::getEnv(); if (!env) return false; int count = source.size(); bool rv = true; int resultCount = 0; for (int i = 0; i < count; ++i) { if (source[i]) { resultCount++; } } result = createNewLongArray(resultCount); for (int j = 0; j < count; ++j) { if (source[j]) { jlong arg = (source[j]->getNetworkId()).getValue(); if (arg == 0) { rv = false; break; } setLongArrayRegion(*result, static_cast(--resultCount), 1, &arg); } } if (env->ExceptionCheck()) { env->ExceptionDescribe(); rv = false; } return rv; } const bool convert(const std::vector &source, LocalLongArrayRefPtr & result) { JNIEnv * env = JavaLibrary::getEnv(); if (!env) return false; int count = source.size(); bool rv = true; int i; int resultCount = 0; for (i = 0; i < count; ++i) { if (source[i].isValid()) { resultCount++; } } result = createNewLongArray(resultCount); jlong jlongTmp; for (int j = 0; j < count; ++j) { if (source[j].isValid()) { jlongTmp = source[j].getValue(); setLongArrayRegion(*result, static_cast(--resultCount), 1, &jlongTmp); } else { rv = false; } } if (env->ExceptionCheck()) { env->ExceptionDescribe(); rv = false; } return rv; } const bool convert(const jobject & source, Vector &target, NetworkId & targetCell) { JNIEnv * env = JavaLibrary::getEnv(); if (!env) return false; if (!source) return false; ServerObject * object = 0; if (env->IsInstanceOf(source, JavaLibrary::ms_clsLocation)) { target.x = env->GetFloatField(source, JavaLibrary::ms_fidLocationX); target.y = env->GetFloatField(source, JavaLibrary::ms_fidLocationY); target.z = env->GetFloatField(source, JavaLibrary::ms_fidLocationZ); LocalRefPtr cell = getObjectField(LocalRefParam(source), JavaLibrary::ms_fidLocationCell); targetCell = JavaLibrary::getNetworkId(*cell); return true; } else if (JavaLibrary::getObject(source, object)) { target = object->getPosition_p(); const Object * cell = ContainerInterface::getContainedByObject(*object); targetCell = (cell) ? cell->getNetworkId() : NetworkId::cms_invalid; return true; } return false; } const bool convertWorld(const jobject & source, Vector &target) { JNIEnv * env = JavaLibrary::getEnv(); if (!env) return false; if (!source) return false; ServerObject * object = 0; if (env->IsInstanceOf(source, JavaLibrary::ms_clsLocation)) { target.x = env->GetFloatField(source, JavaLibrary::ms_fidLocationX); target.y = env->GetFloatField(source, JavaLibrary::ms_fidLocationY); target.z = env->GetFloatField(source, JavaLibrary::ms_fidLocationZ); LocalRefPtr cell = getObjectField(LocalRefParam(source), JavaLibrary::ms_fidLocationCell); Object * cellObject = 0; if (JavaLibrary::getObject(*cell, cellObject)) { target = cellObject->rotateTranslate_o2w(target); } return true; } else if (JavaLibrary::getObject(source, object)) { target = object->getPosition_w(); return true; } return false; } const bool convertWorld(const jlong & source, Vector &target) { JNIEnv * env = JavaLibrary::getEnv(); if (!env) return false; if (source == 0) return false; ServerObject * object = 0; if (JavaLibrary::getObject(source, object)) { target = object->getPosition_w(); return true; } return false; } const bool convertWorld(const LocalRefParam & source, Vector &target) { return convertWorld(source.getValue(), target); } const bool convert(const Vector & source, const NetworkId & sourceCell, LocalRefPtr & target) { return convert(source, ServerWorld::getSceneId(), sourceCell, target); } const bool convert(const jobject & source, Vector & targetLoc, std::string & targetSceneId, NetworkId & targetCell) { JNIEnv * env = JavaLibrary::getEnv(); if (!env) return false; if (!source) return false; Object * object = 0; if (env->IsInstanceOf(source, JavaLibrary::ms_clsLocation)) { // get the xyz coords targetLoc.x = env->GetFloatField(source, JavaLibrary::ms_fidLocationX); targetLoc.y = env->GetFloatField(source, JavaLibrary::ms_fidLocationY); targetLoc.z = env->GetFloatField(source, JavaLibrary::ms_fidLocationZ); // get the scene //@todo EAS what's the right answer here? JavaStringPtr sceneId = getStringField(LocalRefParam(source), JavaLibrary::ms_fidLocationArea); if (sceneId == JavaString::cms_nullPtr) { targetSceneId = ""; return false; } JavaLibrary::convert(*sceneId, targetSceneId); // get the cell LocalRefPtr cell = getObjectField(LocalRefParam(source), JavaLibrary::ms_fidLocationCell); targetCell = JavaLibrary::getNetworkId(*cell); return true; } else if (JavaLibrary::getObject(source, object)) { targetLoc = object->getPosition_p(); targetSceneId = ServerWorld::getSceneId(); const Object * cell = ContainerInterface::getContainedByObject(*object); targetCell = (cell) ? cell->getNetworkId() : NetworkId::cms_invalid; return true; } return false; } const bool convertWorld(const jobject & source, Vector & targetLoc, std::string & targetSceneId) { JNIEnv * env = JavaLibrary::getEnv(); if (!env) return false; if (!source) return false; Object * object = 0; if (env->IsInstanceOf(source, JavaLibrary::ms_clsLocation)) { // get the xyz coords targetLoc.x = env->GetFloatField(source, JavaLibrary::ms_fidLocationX); targetLoc.y = env->GetFloatField(source, JavaLibrary::ms_fidLocationY); targetLoc.z = env->GetFloatField(source, JavaLibrary::ms_fidLocationZ); // get the scene //@todo EAS what's the right answer here? JavaStringPtr sceneId = getStringField(LocalRefParam(source), JavaLibrary::ms_fidLocationArea); if (sceneId == JavaString::cms_nullPtr) { targetSceneId = ""; return false; } JavaLibrary::convert(*sceneId, targetSceneId); // get the cell LocalRefPtr cell = getObjectField(LocalRefParam(source), JavaLibrary::ms_fidLocationCell); Object * cellObject = 0; if (JavaLibrary::getObject(*cell, cellObject)) { targetLoc = cellObject->rotateTranslate_o2w(targetLoc); } return true; } else if (JavaLibrary::getObject(source, object)) { targetLoc = object->getPosition_w(); targetSceneId = ServerWorld::getSceneId(); return true; } return false; } const bool convert(const Location & sourceLoc, LocalRefPtr & target) { JNIEnv * env = JavaLibrary::getEnv(); if (!env) return false; target = allocObject(JavaLibrary::ms_clsLocation); if (target == LocalRef::cms_nullPtr) return false; // set xyz setFloatField(*target, JavaLibrary::ms_fidLocationX, sourceLoc.getCoordinates().x); setFloatField(*target, JavaLibrary::ms_fidLocationY, sourceLoc.getCoordinates().y); setFloatField(*target, JavaLibrary::ms_fidLocationZ, sourceLoc.getCoordinates().z); // set scene id JavaString area(sourceLoc.getSceneId()); //ServerWorld::getSceneId().c_str()); setObjectField(*target, JavaLibrary::ms_fidLocationArea, area); // set cell LocalRefPtr cell = JavaLibrary::getObjId(sourceLoc.getCell()); setObjectField(*target, JavaLibrary::ms_fidLocationCell, *cell); return true; } const bool convert(const LocalRefParam & sourceLoc, Location & target) { JNIEnv * env = JavaLibrary::getEnv(); if (!env) return false; if (sourceLoc.getValue() == 0) return false; float x = getFloatField(sourceLoc, JavaLibrary::ms_fidLocationX); float y = getFloatField(sourceLoc, JavaLibrary::ms_fidLocationY); float z = getFloatField(sourceLoc, JavaLibrary::ms_fidLocationZ); std::string planetName; JavaStringPtr jplanetName = getStringField(sourceLoc, JavaLibrary::ms_fidLocationArea); if (!JavaLibrary::convert(*jplanetName, planetName)) return false; LocalRefPtr cell = getObjectField(sourceLoc, JavaLibrary::ms_fidLocationCell); NetworkId targetCell = JavaLibrary::getNetworkId(*cell); target.setCoordinates(Vector(x, y, z)); target.setSceneId(planetName.c_str()); target.setCell(targetCell); return true; } const bool convert(const LocalObjectArrayRefParam & sourceLoc, std::vector & target) { JNIEnv * env = JavaLibrary::getEnv(); if (!env) return false; if (sourceLoc.getValue() == 0) return false; jsize count = getArrayLength(sourceLoc); target.resize(count); for (int i = 0; i < count; ++i) { LocalRefPtr location(getObjectArrayElement(sourceLoc, i)); if (location == LocalRef::cms_nullPtr || !convert(*location, target.at(i))) return false; } return true; } const bool convert(const Vector & sourceLoc, const std::string & sourceSceneId, const NetworkId & sourceCell, LocalRefPtr & target) { JNIEnv * env = JavaLibrary::getEnv(); if (!env) return false; target = allocObject(JavaLibrary::ms_clsLocation); if (target == LocalRef::cms_nullPtr) return false; // set xyz setFloatField(*target, JavaLibrary::ms_fidLocationX, sourceLoc.x); setFloatField(*target, JavaLibrary::ms_fidLocationY, sourceLoc.y); setFloatField(*target, JavaLibrary::ms_fidLocationZ, sourceLoc.z); // set scene id JavaString area(sourceSceneId.c_str()); //ServerWorld::getSceneId().c_str()); setObjectField(*target, JavaLibrary::ms_fidLocationArea, area); // set cell LocalRefPtr cell = JavaLibrary::getObjId(sourceCell); setObjectField(*target, JavaLibrary::ms_fidLocationCell, *cell); return true; } const bool convertWorld(const jobjectArray & source, std::vector &target) { JNIEnv * env = JavaLibrary::getEnv(); if (!env) return false; if (!source || !env->IsInstanceOf(source, JavaLibrary::ms_clsLocationArray)) return false; jsize count = env->GetArrayLength(source); jsize i; Vector v; NetworkId cell; bool result = true; for (i=0; i & source, LocalObjectArrayRefPtr & target) { JNIEnv * env = JavaLibrary::getEnv(); if (!env) return false; if (source.empty()) return false; int count = source.size(); int i; target = createNewObjectArray(source.size(), JavaLibrary::ms_clsLocation); if (target == LocalObjectArrayRef::cms_nullPtr) return false; NetworkId cell(NetworkId::cms_invalid); bool result = true; for (i=0; i < count; ++i) { LocalRefPtr element; if (convert(*source[i], cell, element)) { setObjectArrayElement(*target, i, *element); } else { result = false; } } return result; } const bool convert(const LocalRefParam & source, const Region * & target) { return convert(source.getValue(), target); } /** This method converts a java script.region class into a C++ Region class */ const bool convert(const jobject & source, const Region * &target) { JNIEnv * env = JavaLibrary::getEnv(); if (env == NULL || source == NULL) return false; if (!env->IsInstanceOf(source, JavaLibrary::ms_clsRegion)) return false; std::string planetName; JavaStringPtr jplanetName = getStringField(LocalRefParam(source), JavaLibrary::ms_fidRegionPlanet); if (!JavaLibrary::convert(*jplanetName, planetName)) return false; Unicode::String regionName; JavaStringPtr jregionName = getStringField(LocalRefParam(source), JavaLibrary::ms_fidRegionName); if (!JavaLibrary::convert(*jregionName, regionName)) return false; target = RegionMaster::getRegionByName(planetName, regionName); return target != 0; } /** This method converts a C++ RegionObject class into a Java script.region class */ const bool convert(const Region & source, LocalRefPtr & target) { JNIEnv * env = JavaLibrary::getEnv(); if (!env) return false; int pvp = source.getPvp(); int mun = source.getMunicipal(); int build = source.getBuildable(); int geo = source.getGeography(); int minDiff = source.getMinDifficulty(); int maxDiff = source.getMaxDifficulty(); int spawn = source.getSpawn(); int mission = source.getMission(); const Unicode::String name(source.getName()); JavaString jname(name); const std::string planetName(source.getPlanet()); JavaString jplanetName(planetName); target = createNewObject(JavaLibrary::ms_clsRegion, JavaLibrary::ms_midRegion, jname.getValue(), pvp, build, mun, geo, minDiff, maxDiff, spawn, mission, jplanetName.getValue()); return (target != LocalRef::cms_nullPtr); } // ---------------------------------------------------------------------- const bool convert(Transform const &sourceTransform, LocalRefPtr &target) { JNIEnv * const env = JavaLibrary::getEnv(); if (!env) return false; Vector const i(sourceTransform.getLocalFrameI_p()); Vector const j(sourceTransform.getLocalFrameJ_p()); Vector const k(sourceTransform.getLocalFrameK_p()); Vector const p(sourceTransform.getPosition_p()); target = createNewObject(JavaLibrary::ms_clsTransform, JavaLibrary::ms_midTransform, i.x, j.x, k.x, p.x, i.y, j.y, k.y, p.y, i.z, j.z, k.z, p.z); return (target != LocalRef::cms_nullPtr); } // ---------------------------------------------------------------------- const bool convert(const jobject &sourceTransform, Transform &target) { JNIEnv * const env = JavaLibrary::getEnv(); if (!env || !sourceTransform) return false; if (!env->IsInstanceOf(sourceTransform, JavaLibrary::ms_clsTransform)) return false; LocalObjectArrayRefPtr matrix = getArrayObjectField(LocalRefParam(sourceTransform), JavaLibrary::ms_fidTransformMatrix); LocalFloatArrayRefPtr row0 = getFloatArrayArrayElement(*matrix, 0); LocalFloatArrayRefPtr row1 = getFloatArrayArrayElement(*matrix, 1); LocalFloatArrayRefPtr row2 = getFloatArrayArrayElement(*matrix, 2); float * const row0Elements = env->GetFloatArrayElements(row0->getValue(), 0); float * const row1Elements = env->GetFloatArrayElements(row1->getValue(), 0); float * const row2Elements = env->GetFloatArrayElements(row2->getValue(), 0); target.setLocalFrameIJK_p( Vector(row0Elements[0], row1Elements[0], row2Elements[0]), Vector(row0Elements[1], row1Elements[1], row2Elements[1]), Vector(row0Elements[2], row1Elements[2], row2Elements[2])); target.setPosition_p(row0Elements[3], row1Elements[3], row2Elements[3]); env->ReleaseFloatArrayElements(row2->getValue(), row2Elements, JNI_ABORT); env->ReleaseFloatArrayElements(row1->getValue(), row1Elements, JNI_ABORT); env->ReleaseFloatArrayElements(row0->getValue(), row0Elements, JNI_ABORT); return true; } // ---------------------------------------------------------------------- const bool convert(const LocalRefParam &sourceTransform, Transform &target) { return convert(sourceTransform.getValue(), target); } // ---------------------------------------------------------------------- const bool convert(const jobjectArray & source, std::vector &target) { JNIEnv * const env = JavaLibrary::getEnv(); if (!env) return false; if (!source || !env->IsInstanceOf(source, JavaLibrary::ms_clsTransformArray)) return false; jsize const count = env->GetArrayLength(source); bool result = true; for (jsize i = 0; i < count; ++i) { LocalRefPtr element = getObjectArrayElement(LocalObjectArrayRefParam(source), i); Transform t; if (convert(*element, t)) { target.push_back(t); } else { result = false; } } return result && !target.empty(); } // ---------------------------------------------------------------------- const bool convert(const std::vector &source, LocalObjectArrayRefPtr & target) { JNIEnv * const env = JavaLibrary::getEnv(); if (!env) return false; int const count = source.size(); bool result = true; target = createNewObjectArray(count, JavaLibrary::ms_clsObjId); for (int i = 0; i < count; ++i) { LocalRefPtr temp; if (convert(source[i],temp)) { setObjectArrayElement(*target, i, *temp); } else { result = false; target = LocalObjectArrayRef::cms_nullPtr; break; } } if (env->ExceptionCheck()) { env->ExceptionDescribe(); result = false; } return result; } // ---------------------------------------------------------------------- const bool convert(const Vector &sourceVector, LocalRefPtr &target) { JNIEnv *env = JavaLibrary::getEnv(); if (!env) return false; target = allocObject(JavaLibrary::ms_clsVector); if (target == LocalRef::cms_nullPtr) return false; setFloatField(*target, JavaLibrary::ms_fidVectorX, sourceVector.x); setFloatField(*target, JavaLibrary::ms_fidVectorY, sourceVector.y); setFloatField(*target, JavaLibrary::ms_fidVectorZ, sourceVector.z); return true; } // ---------------------------------------------------------------------- const bool convert(const jobject & sourceVector, Vector & target) { JNIEnv *env = JavaLibrary::getEnv(); if (!env || !sourceVector) return false; if (!env->IsInstanceOf(sourceVector, JavaLibrary::ms_clsVector)) return false; target.x = env->GetFloatField(sourceVector, JavaLibrary::ms_fidVectorX); target.y = env->GetFloatField(sourceVector, JavaLibrary::ms_fidVectorY); target.z = env->GetFloatField(sourceVector, JavaLibrary::ms_fidVectorZ); return true; } // ---------------------------------------------------------------------- const bool convert(const LocalRefParam & sourceVector, Vector & target) { return convert(sourceVector.getValue(), target); } // ---------------------------------------------------------------------- /** * Convert a C++ AttribMod to a Java attrib_mod. */ const bool convert(const AttribMod::AttribMod & source, LocalRefPtr & target) { JNIEnv * env = JavaLibrary::getEnv(); if (env == NULL) return false; target = allocObject(JavaLibrary::ms_clsAttribMod); if (target == LocalRef::cms_nullPtr) return false; JavaString name(AttribModNameManager::getInstance( ).getAttribModName(source.tag)); setObjectField(*target, JavaLibrary::ms_fidAttribModName, name); if (!AttribMod::isSkillMod(source)) { setIntField(*target, JavaLibrary::ms_fidAttribModType, source.attrib); } else { JavaString skill(AttribModNameManager::getInstance( ).getAttribModName(source.skill)); setObjectField(*target, JavaLibrary::ms_fidAttribModSkill, skill); } setIntField(*target, JavaLibrary::ms_fidAttribModValue, source.value); setFloatField(*target, JavaLibrary::ms_fidAttribModTime, source.sustain); setFloatField(*target, JavaLibrary::ms_fidAttribModAttack, source.attack); setFloatField(*target, JavaLibrary::ms_fidAttribModDecay, source.decay); setIntField(*target, JavaLibrary::ms_fidAttribModFlags, source.flags); return true; } /** * Convert a Java attrib_mod to a C++ AttribMod. */ const bool convert(const jobject & source, AttribMod::AttribMod & target) { JNIEnv * env = JavaLibrary::getEnv(); if (env == NULL) return false; if (source == 0 || env->IsInstanceOf(source, JavaLibrary::ms_clsAttribMod) == JNI_FALSE) return false; std::string modName; JavaStringPtr name = getStringField(LocalRefParam(source), JavaLibrary::ms_fidAttribModName); if (name != JavaString::cms_nullPtr) { if (!JavaLibrary::convert(*name, modName)) return false; target.tag = Crc::calculate(modName.c_str()); AttribModNameManager::getInstance().addAttribModName(modName.c_str()); } else target.tag = 0; target.flags = env->GetIntField(source, JavaLibrary::ms_fidAttribModFlags); if (!AttribMod::isSkillMod(target)) { target.attrib = env->GetIntField(source, JavaLibrary::ms_fidAttribModType); } else { std::string skillModName; JavaStringPtr skillName = getStringField(LocalRefParam(source), JavaLibrary::ms_fidAttribModSkill); // a skillmod mod must have a skillmod name if (skillName == JavaString::cms_nullPtr) return false; if (!JavaLibrary::convert(*skillName, skillModName)) return false; target.skill = Crc::calculate(skillModName.c_str()); AttribModNameManager::getInstance().addAttribModName(skillModName.c_str()); } target.value = env->GetIntField(source, JavaLibrary::ms_fidAttribModValue); target.sustain = env->GetFloatField(source, JavaLibrary::ms_fidAttribModTime); target.attack = env->GetFloatField(source, JavaLibrary::ms_fidAttribModAttack); target.decay = env->GetFloatField(source, JavaLibrary::ms_fidAttribModDecay); return true; } /** * Convert a Java attrib_mod to a C++ AttribMod. */ const bool convert(const LocalRefParam & source, AttribMod::AttribMod & target) { return convert(source.getValue(), target); } /** * Convert a C++ AttribMod vector to a Java attrib_mod[]. */ const bool convert(const std::vector & source, LocalObjectArrayRefPtr & target) { JNIEnv * env = JavaLibrary::getEnv(); if (env == NULL) return false; int count = source.size(); target = createNewObjectArray(count, JavaLibrary::ms_clsAttribMod); if (target == LocalObjectArrayRef::cms_nullPtr) return false; LocalRefPtr mod; for (int i = 0; i < count; ++i) { if (!convert(source[i], mod)) { target = LocalObjectArrayRef::cms_nullPtr; return false; } setObjectArrayElement(*target, i, *mod); } return true; } /** * Convert a Java attrib_mod[] to a C++ AttribMod vector. */ const bool convert(const jobjectArray & source, std::vector & target) { JNIEnv * env = JavaLibrary::getEnv(); if (env == NULL) return false; if (source == 0) return false; AttribMod::AttribMod mod; int count = env->GetArrayLength(source); for (int i = 0; i < count; ++i) { LocalRefPtr element = getObjectArrayElement(LocalObjectArrayRefParam(source), i); bool result = convert(*element, mod); if (!result) { target.clear(); return false; } target.push_back(mod); } return true; } const bool convert(const jbyteArray & source, std::vector & target) { JNIEnv * env = JavaLibrary::getEnv(); if (env == NULL) return false; if (source == 0) return false; int size = env->GetArrayLength(source); target.reserve(size); target.resize(size); env->GetByteArrayRegion(source, 0, size, &target[0]); return true; } const bool convert(const LocalByteArrayRef & source, std::vector & target) { JNIEnv * env = JavaLibrary::getEnv(); if (env == NULL) return false; if (source.getValue() == 0) return false; int size = getArrayLength(source); target.reserve(size); target.resize(size); getByteArrayRegion(source, 0, size, &target[0]); return true; } const bool convert(const std::vector & source, LocalByteArrayRefPtr & target) { JNIEnv * env = JavaLibrary::getEnv(); if (env == NULL) return false; int count = source.size(); target = createNewByteArray(count); if (target == LocalByteArrayRef::cms_nullPtr) return false; if (count > 0) setByteArrayRegion(*target, 0, count, const_cast(&source[0])); return true; } }//namespace ScriptConversion //---------------------------------------------------------------------- ServerObject * JavaLibrary::findObjectByNetworkId (const NetworkId & id) { return ServerWorld::findObjectByNetworkId(id); } //---------------------------------------------------------------------- CreatureObject *JavaLibrary::getCreatureThrow(JNIEnv *env, jlong objId, char const *errorDescription, bool throwIfNotOnServer) { NOT_NULL(env); char buffer[512]; if (!objId) { IGNORE_RETURN(snprintf(buffer, sizeof(buffer) - 1, "%s: null object id from script.", errorDescription)); buffer[sizeof(buffer) - 1] = '\0'; throwInternalScriptError(buffer); return NULL; } else { NetworkId networkId(objId); if (!networkId.isValid()) { IGNORE_RETURN(snprintf(buffer, sizeof(buffer) - 1, "%s: invalid or non-convertable network id [%s].", errorDescription, networkId.getValueString().c_str())); buffer[sizeof(buffer) - 1] = '\0'; throwInternalScriptError(buffer); return NULL; } else { Object *const object = NetworkIdManager::getObjectById(networkId); if (!object) { if (!throwIfNotOnServer) { // The specified object is not on this server. It might not even be a real object. // Since the caller does not want this to throw, simply return NULL. return NULL; } IGNORE_RETURN(snprintf(buffer, sizeof(buffer) - 1, "%s: object for network id [%s] not on this server.", errorDescription, networkId.getValueString().c_str())); buffer[sizeof(buffer) - 1] = '\0'; throwInternalScriptError(buffer); return NULL; } else { ServerObject *const serverObject = object->asServerObject(); CreatureObject *const creatureObject = serverObject ? serverObject->asCreatureObject() : NULL; if (creatureObject) return creatureObject; else { IGNORE_RETURN(snprintf(buffer, sizeof(buffer) - 1, "%s: object id=[%s], template=[%s] is not a CreatureObject.", errorDescription, networkId.getValueString().c_str(), object->getObjectTemplateName())); buffer[sizeof(buffer) - 1] = '\0'; throwInternalScriptError(buffer); return NULL; } } } } } //---------------------------------------------------------------------- ShipObject *JavaLibrary::getShipThrow(JNIEnv *env, jlong objId, char const *errorDescription, bool throwIfNotOnServer) { NOT_NULL(env); char buffer[512]; if (objId == 0) { IGNORE_RETURN(snprintf(buffer, sizeof(buffer) - 1, "%s: null object id from script.", errorDescription)); buffer[sizeof(buffer) - 1] = '\0'; throwInternalScriptError(buffer); return NULL; } else { NetworkId networkId(objId); if (!networkId.isValid()) { IGNORE_RETURN(snprintf(buffer, sizeof(buffer) - 1, "%s: invalid or non-convertable network id [%s].", errorDescription, networkId.getValueString().c_str())); buffer[sizeof(buffer) - 1] = '\0'; throwInternalScriptError(buffer); return NULL; } else { Object *const object = NetworkIdManager::getObjectById(networkId); if (!object) { if (!throwIfNotOnServer) { // The specified object is not on this server. It might not even be a real object. // Since the caller does not want this to throw, simply return NULL. return NULL; } IGNORE_RETURN(snprintf(buffer, sizeof(buffer) - 1, "%s: object for network id [%s] not on this server.", errorDescription, networkId.getValueString().c_str())); buffer[sizeof(buffer) - 1] = '\0'; throwInternalScriptError(buffer); return NULL; } else { ServerObject *const serverObject = object->asServerObject(); ShipObject *const shipObject = serverObject ? serverObject->asShipObject() : NULL; if (shipObject) return shipObject; else { IGNORE_RETURN(snprintf(buffer, sizeof(buffer) - 1, "%s: object id=[%s], template=[%s] is not a ShipObject.", errorDescription, networkId.getValueString().c_str(), object->getObjectTemplateName())); buffer[sizeof(buffer) - 1] = '\0'; throwInternalScriptError(buffer); return NULL; } } } } } //----------------------------------------------------------------------- /** * Causes an internal_script_error to be thrown in the Java engine. * * @param message the message to be returned by internal_script_error.getMessage() */ void JavaLibrary::throwInternalScriptError(const char * message) { if (ms_env != NULL && message != NULL) { ms_env->ThrowNew(ms_clsInternalScriptError, message); } } //-----------------------------------------------------------------------