Files
src-1.2/engine/server/library/serverScript/src/shared/JavaLibrary.cpp
T

6741 lines
222 KiB
C++
Executable File

//========================================================================
//
// 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
#ifdef linux
// shared library includes
#include <dlfcn.h>
#include <signal.h>
#endif
#ifndef JNI_VERSION_1_4
#error JNI version 1.4 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<jclass>(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<std::string> 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<char *>(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<uint32>(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<uint32>(frameAddress) >> 16);
crashAddress2a = __builtin_return_address(0);
if (crashAddress2a != NULL)
{
frameAddressA = __builtin_frame_address(1);
if (frameAddressA != NULL &&
(reinterpret_cast<uint32>(frameAddressA) >> 16 == frameAddressHigh))
{
crashAddress2b = __builtin_return_address(1);
if (crashAddress2b != NULL)
{
frameAddressB = __builtin_frame_address(2);
if (frameAddressB != NULL &&
(reinterpret_cast<uint32>(frameAddressB) >> 16 == frameAddressHigh))
{
crashAddress2c = __builtin_return_address(2);
if (crashAddress2c != NULL)
{
result2 = DebugHelp::lookupAddress(reinterpret_cast<uint32>(
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
// this pthread method is not in later versions of glibc as the kernel should handle the kill
//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>("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 &&
strcmp(javaVMName, "oracle") != 0))
{
FATAL(true, ("[ServerGame] javaVMName not defined. Valid values are: "
"none, ibm, oracle, or sun"));
}
else if (strcmp(javaVMName, "ibm") == 0)
{
ms_javaVmType = JV_ibm;
}
else if (strcmp(javaVMName, "sun") == 0 || strcmp(javaVMName, "oracle") == 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;
}
}
#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 += ConfigServerGame::getScriptPath();
JavaVMInitArgs vm_args;
JavaVMOption tempOption = {NULL, NULL};
std::vector<JavaVMOption> options;
char *jdwpBuffer = NULL;
UNREF(jdwpBuffer);
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<char *>(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);
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);
}
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);
}
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);
}
#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 (ConfigServerGame::getJavaDebugPort()[0] == '\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<char *>(classPath.c_str());
options.push_back(tempOption);
#ifdef JNI_VERSION_1_8
vm_args.version = JNI_VERSION_1_8;
#define JAVAVERSET = 1
#endif
#ifndef JAVAVERSET
#ifdef JNI_VERSION_1_7
vm_args.version = JNI_VERSION_1_7;
#define JAVAVERSET = 1
#endif
#endif
#ifndef JAVAVERSET
#ifdef JNI_VERSION_1_6
vm_args.version = JNI_VERSION_1_6;
#define JAVAVERSET = 1
#endif
#endif
#ifndef JAVAVERSET
#ifdef JNI_VERSION_1_5
vm_args.version = JNI_VERSION_1_5;
#define JAVAVERSET = 1
#endif
#endif
#ifndef JAVAVERSET
#ifdef JNI_VERSION_1_4
vm_args.version = JNI_VERSION_1_4;
#define JAVAVERSET = 1
#endif
#endif
#ifdef JAVAVERSET
#undef JAVAVERSET
#endif
vm_args.options = &options[0];
vm_args.nOptions = options.size();
vm_args.ignoreUnrecognized = JNI_TRUE;
// create the JVM
JNIEnv * env = NULL;
jint result = (*JNI_CreateJavaVMProc)(&ms_jvm, reinterpret_cast<void**>(&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<HMODULE>(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<void**>(&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, "<init>", "(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, "<init>", "(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, "<init>", "(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, "<init>", "()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, "<init>", "(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, "<init>", "()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, "<init>", "()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, "<init>", "()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, "<init>", "(Ljava/lang/String;I)V");
GET_METHOD(ms_midDynamicVariableIntArray, ms_clsDynamicVariable, "<init>", "(Ljava/lang/String;[I)V");
GET_METHOD(ms_midDynamicVariableFloat, ms_clsDynamicVariable, "<init>", "(Ljava/lang/String;F)V");
GET_METHOD(ms_midDynamicVariableFloatArray, ms_clsDynamicVariable, "<init>", "(Ljava/lang/String;[F)V");
GET_METHOD(ms_midDynamicVariableString, ms_clsDynamicVariable, "<init>", "(Ljava/lang/String;Ljava/lang/String;)V");
GET_METHOD(ms_midDynamicVariableStringArray, ms_clsDynamicVariable, "<init>", "(Ljava/lang/String;[Ljava/lang/String;)V");
GET_METHOD(ms_midDynamicVariableObjId, ms_clsDynamicVariable, "<init>", "(Ljava/lang/String;J)V");
GET_METHOD(ms_midDynamicVariableObjIdArray, ms_clsDynamicVariable, "<init>", "(Ljava/lang/String;[J)V");
GET_METHOD(ms_midDynamicVariableLocation, ms_clsDynamicVariable, "<init>", "(Ljava/lang/String;Lscript/location;)V");
GET_METHOD(ms_midDynamicVariableLocationArray, ms_clsDynamicVariable, "<init>", "(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, "<init>", "(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, "<init>", "(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, "<init>", "()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, "<init>", "(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, "<init>", "(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, "<init>", "()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, "<init>", "()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, "<init>", "(JLjava/lang/String;I)V");
GET_CLASS(ms_clsRangedIntCustomVar, "script/ranged_int_custom_var");
GET_METHOD(ms_midRangedIntCustomVar, ms_clsRangedIntCustomVar, "<init>", "(JLjava/lang/String;III)V");
GET_CLASS(ms_clsPalcolorCustomVar, "script/palcolor_custom_var");
GET_METHOD(ms_midPalcolorCustomVar, ms_clsPalcolorCustomVar, "<init>", "(JLjava/lang/String;III)V");
GET_CLASS(ms_clsColor, "script/color");
GET_METHOD(ms_midColor, ms_clsColor, "<init>", "(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, "<init>", "(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, "<init>", "(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, "<init>", "(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, "<init>", "(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, "<init>", "(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<std::string> & 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<NetworkId::NetworkIdType>(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<NetworkId::NetworkIdType>(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<jboolean>(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<jstring>(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<bool> & 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<bool>
// does not store the array of bool contiguously; neither
// does a vector<bool>; 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<bool>::const_iterator iter = boolArray.begin(); iter != boolArray.end(); ++iter, ++indexBoolArray)
tempBoolArray[indexBoolArray] = *iter;
setBooleanArrayRegion(*array, 0, boolArray.size(),
const_cast<jboolean *>(reinterpret_cast<const jboolean *>(&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<int> & 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<jint *>(
reinterpret_cast<const jint *>(&intArray[0])));
#else
std::vector<jint> intArray2(intArray.begin(), intArray.end());
setIntArrayRegion(*array, 0, intArray.size(), const_cast<jint *>(&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<NetworkId> & 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<CachedNetworkId> & 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<const std::vector<NetworkId> *> & 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<NetworkId> * 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<int>(
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<jsize>(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<jsize>(
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<bool> & 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<bool>
// does not store the array of bool contiguously; neither
// does a vector<bool>; 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<bool>::const_iterator iter = param.begin(); iter != param.end(); ++iter, ++indexBoolArray)
tempBoolArray[indexBoolArray] = *iter;
setBooleanArrayRegion(*localInstance, 0, count,
const_cast<jboolean *>(reinterpret_cast<const jboolean *>(&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<int> & 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; i<count; ++i)
{
destination[i] = param[i];
}
ms_env->ReleaseIntArrayElements(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<unsigned char> & 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; i<count; ++i)
{
destination[i] = param[i];
}
ms_env->ReleaseByteArrayElements(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<float> & 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<float *>(&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<const char *> & strings =
args.getStringArrayParam(paramIndex);
LocalObjectArrayRefPtr localInstance = createNewObjectArray(strings.size(), ms_clsString);
int i;
std::vector<const char *>::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 &param = args.getUnicodeParam(paramIndex);
arg = createNewString(param.c_str(), static_cast<jsize>(param.size()));
}
else
{
if (args.getParamType(paramIndex) != Param::UNICODE_ARRAY)
break;
const std::vector<const Unicode::String *> & strings =
args.getUnicodeArrayParam(paramIndex);
LocalObjectArrayRefPtr localInstance = createNewObjectArray(strings.size(), ms_clsString);
int i;
std::vector<const Unicode::String *>::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<const 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<NetworkId> & 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<jsize>(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<CachedNetworkId> & 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<jsize>(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<jint>(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<const StringId *> & strings = args.getStringIdArrayParam(paramIndex);
LocalObjectArrayRefPtr localInstance = createNewObjectArray(strings.size(), ms_clsStringId);
int i;
std::vector<const StringId *>::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<jint>(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<AttribMod::AttribMod> & 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<jint>(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<jsize>(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<jsize>(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 &param = 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<ServerObjectTemplate::MentalStateMod> & 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<jsize>(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<jsize>(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 &param = 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<ValueDictionary> & param = args.getValueDictionaryArrayParam(paramIndex);
LocalObjectArrayRefPtr localInstance = createNewObjectArray(param.size(), ms_clsDictionary);
int paramCount = 0;
std::vector<ValueDictionary>::const_iterator iter;
for (iter = param.begin(); iter != param.end(); ++iter)
{
setObjectArrayElement(*localInstance, static_cast<jsize>(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<unsigned>(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<jsize>(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<int> * values = new std::vector<int>(count, 0);
jint * jvalues = static_cast<jint *>(ms_env->GetPrimitiveArrayCritical(static_cast<jintArray>(arg->getValue()), NULL));
for (int j = 0; j < count; ++j)
{
values->at(j) = static_cast<int>(jvalues[j]);
}
ms_env->ReleasePrimitiveArrayCritical(static_cast<jintArray>(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<unsigned char> 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<unsigned char> * values = new std::vector<unsigned char>(count, 0);
jbyte * jvalues = static_cast<jbyte *>(ms_env->GetPrimitiveArrayCritical(static_cast<jbyteArray>(arg->getValue()), NULL));
for (int j = 0; j < count; ++j)
{
values->at(j) = static_cast<unsigned char>(jvalues[j]);
}
ms_env->ReleasePrimitiveArrayCritical(static_cast<jbyteArray>(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<const char *> * strings = new std::vector<const char *>();
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<const Unicode::String *> * strings = new std::vector<const Unicode::String *>();
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<jsize>(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<jfloat>(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<jsize>(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<jint>(param));
}
break;
#endif
default:
DEBUG_REPORT_LOG(true, ("unknown parameter type %c(%#x)\n", argList[i],
static_cast<unsigned>(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<jsize>(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<const JavaDictionary *>(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<const JavaDictionary *>(&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<int8> & packedData)
{
const_cast<ScriptDictionary &>(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<int8> & 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<int8>::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<int8 *>(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<int8> & 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<std::string, int> & source, JavaDictionaryPtr & target)
{
std::vector<std::pair<std::string, int> > sourceData;
std::map<std::string, int>:: 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<std::pair<std::string, int> > & source, JavaDictionaryPtr & target)
{
if (!JavaLibrary::getEnv())
return false;
target = createNewDictionary();
if (target == JavaDictionary::cms_nullPtr)
return false;
std::vector<std::pair<std::string, int> >::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<std::pair<std::string, std::pair<int, int> > > & source, JavaDictionaryPtr & target)
{
if (!JavaLibrary::getEnv())
return false;
target = createNewDictionary();
if (target == JavaDictionary::cms_nullPtr)
return false;
std::vector<std::pair<std::string, std::pair<int, int> > >::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<std::pair<std::string, bool> > & source, JavaDictionaryPtr & target)
{
if (!JavaLibrary::getEnv())
return false;
target = createNewDictionary();
if (target == JavaDictionary::cms_nullPtr)
return false;
std::vector<std::pair<std::string, bool> >::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<const Unicode::String *> & 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<std::string> & source, LocalObjectArrayRefPtr & strArray)
{
JNIEnv * env = JavaLibrary::getEnv();
if (!env)
return false;
if (env->ExceptionCheck())
{
env->ExceptionDescribe();
return false;
}
strArray = createNewObjectArray(static_cast<jsize>(source.size()), JavaLibrary::ms_clsString);
std::vector<std::string>::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<const char *> & source, LocalObjectArrayRefPtr & strArray)
{
JNIEnv * env = JavaLibrary::getEnv();
if (!env)
return false;
if (env->ExceptionCheck())
{
env->ExceptionDescribe();
return false;
}
strArray = createNewObjectArray(static_cast<jsize>(source.size()), JavaLibrary::ms_clsString);
std::vector<const char *>::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<CellPermissions::PermissionObject> & source, LocalObjectArrayRefPtr & strArray)
{
JNIEnv * env = JavaLibrary::getEnv();
if (!env)
return false;
if (env->ExceptionCheck())
{
env->ExceptionDescribe();
return false;
}
strArray = createNewObjectArray(static_cast<jsize>(source.size()), JavaLibrary::ms_clsString);
std::set<CellPermissions::PermissionObject>::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<std::string>::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<NetworkId> &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; i<count; ++i)
{
env->GetLongArrayRegion(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<ServerObject *> &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; i<count; ++i)
{
jlong id;
env->GetLongArrayRegion(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<ServerObject *> &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<jsize>(--resultCount), 1, &arg);
}
}
if (env->ExceptionCheck())
{
env->ExceptionDescribe();
rv = false;
}
return rv;
}
const bool convert(const std::vector<NetworkId> &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<jsize>(--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.clear();
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.clear();
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<Location> & 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<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<count; ++i)
{
LocalRefPtr element = getObjectArrayElement(LocalObjectArrayRefParam(source), i);
if (convertWorld(*element, v))
{
target.push_back(v);
}
else
{
result = false;
}
}
return result && !target.empty();
}
const bool convert(const std::vector<const Vector *> & 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<Transform> &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<Transform> &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<AttribMod::AttribMod> & 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<AttribMod::AttribMod> & 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<int8> & 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<int8> & 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<int8> & 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<int8 *>(&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);
}
}
//-----------------------------------------------------------------------