/*==LICENSE==* CyanWorlds.com Engine - MMOG client, server and tools Copyright (C) 2011 Cyan Worlds, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . You can contact Cyan Worlds, Inc. by email legal@cyan.com or by snail mail at: Cyan Worlds, Inc. 14617 N Newport Hwy Mead, WA 99021 *==LICENSE==*/ #include "cyMisc.h" #include "pyGlueHelpers.h" #include "pyKey.h" #include "pyColor.h" #include "pyPlayer.h" #include "pyEnum.h" // for enums #include "..\plNetCommon\plNetCommon.h" #include "..\plResMgr\plLocalization.h" #include "..\plMessage\plLOSRequestMsg.h" #include PYTHON_GLOBAL_METHOD_DEFINITION(PtYesNoDialog, args, "Params: selfkey,dialogMessage\nThis will display a Yes/No dialog to the user with the text dialogMessage\n" "This dialog _has_ to be answered by the user.\n" "And their answer will be returned in a Notify message.") { PyObject* keyObj = NULL; PyObject* dialogMsgObj = NULL; if (!PyArg_ParseTuple(args, "OO", &keyObj, &dialogMsgObj)) { PyErr_SetString(PyExc_TypeError, "PtYesNoDialog expects a ptKey and a string or unicode string"); PYTHON_RETURN_ERROR; } if (!pyKey::Check(keyObj)) { PyErr_SetString(PyExc_TypeError, "PtYesNoDialog expects a ptKey and a string or unicode string"); PYTHON_RETURN_ERROR; } pyKey* key = pyKey::ConvertFrom(keyObj); if (PyUnicode_Check(dialogMsgObj)) { int len = PyUnicode_GetSize(dialogMsgObj); wchar_t* text = TRACKED_NEW wchar_t[len + 1]; PyUnicode_AsWideChar((PyUnicodeObject*)dialogMsgObj, text, len); text[len] = L'\0'; cyMisc::YesNoDialog(*key, text); delete [] text; PYTHON_RETURN_NONE; } else if (PyString_Check(dialogMsgObj)) { char* text = PyString_AsString(dialogMsgObj); cyMisc::YesNoDialog(*key, text); PYTHON_RETURN_NONE; } PyErr_SetString(PyExc_TypeError, "PtYesNoDialog expects a ptKey and a string or unicode string"); PYTHON_RETURN_ERROR; } PYTHON_GLOBAL_METHOD_DEFINITION(PtRateIt, args, "Params: chronicleName,dialogPrompt,onceFlag\nShows a dialog with dialogPrompt and stores user input rating into chronicleName") { char* chronicleName; char* dialogPrompt; char onceFlag; if (!PyArg_ParseTuple(args, "ssb", &chronicleName, &dialogPrompt, &onceFlag)) { PyErr_SetString(PyExc_TypeError, "PtRateIt expects two strings and a boolean"); PYTHON_RETURN_ERROR; } cyMisc::RateIt(chronicleName, dialogPrompt, onceFlag != 0); PYTHON_RETURN_NONE; } PYTHON_GLOBAL_METHOD_DEFINITION(PtExcludeRegionSet, args, "Params: senderKey,regionKey,state\nThis will set the state of an exclude region\n" "- 'senderKey' is a ptKey of the PythonFile component\n" "- 'regionKey' is a ptKey of the exclude region\n" "- 'state' is either kExRegRelease or kExRegClear") { PyObject* senderObj = NULL; PyObject* regionObj = NULL; unsigned short stateVal; if (!PyArg_ParseTuple(args, "OOh", &senderObj, ®ionObj, &stateVal)) { PyErr_SetString(PyExc_TypeError, "PtExcludeRegionSet expects two ptKeys and a short"); PYTHON_RETURN_ERROR; } if ((!pyKey::Check(senderObj)) || (!pyKey::Check(regionObj))) { PyErr_SetString(PyExc_TypeError, "PtExcludeRegionSet expects two ptKeys and a short"); PYTHON_RETURN_ERROR; } pyKey* sender = pyKey::ConvertFrom(senderObj); pyKey* region = pyKey::ConvertFrom(regionObj); cyMisc::ExcludeRegionSet(*sender, *region, stateVal); PYTHON_RETURN_NONE; } PYTHON_GLOBAL_METHOD_DEFINITION(PtExcludeRegionSetNow, args, "Params: senderKey,regionKey,state\nThis will set the state of an exclude region immediately on the server\n" "- 'senderKey' is a ptKey of the PythonFile component\n" "- 'regionKey' is a ptKey of the exclude region\n" "- 'state' is either kExRegRelease or kExRegClear") { PyObject* senderObj = NULL; PyObject* regionObj = NULL; unsigned short stateVal; if (!PyArg_ParseTuple(args, "OOh", &senderObj, ®ionObj, &stateVal)) { PyErr_SetString(PyExc_TypeError, "PtExcludeRegionSetNow expects two ptKeys and a short"); PYTHON_RETURN_ERROR; } if ((!pyKey::Check(senderObj)) || (!pyKey::Check(regionObj))) { PyErr_SetString(PyExc_TypeError, "PtExcludeRegionSetNow expects two ptKeys and a short"); PYTHON_RETURN_ERROR; } pyKey* sender = pyKey::ConvertFrom(senderObj); pyKey* region = pyKey::ConvertFrom(regionObj); cyMisc::ExcludeRegionSetNow(*sender, *region, stateVal); PYTHON_RETURN_NONE; } PYTHON_GLOBAL_METHOD_DEFINITION(PtAcceptInviteInGame, args, "Params: friendName,inviteKey\nSends a VaultTask to the server to perform the invite") { char* friendName; char* inviteKey; if (!PyArg_ParseTuple(args, "ss", &friendName, &inviteKey)) { PyErr_SetString(PyExc_TypeError, "PtAcceptInviteInGame expects two strings"); PYTHON_RETURN_ERROR; } cyMisc::AcceptInviteInGame(friendName, inviteKey); PYTHON_RETURN_NONE; } PYTHON_GLOBAL_METHOD_DEFINITION_NOARGS(PtGetTime, "Returns the number of seconds since the game was started.") { return PyFloat_FromDouble(cyMisc::GetSeconds()); } PYTHON_GLOBAL_METHOD_DEFINITION_NOARGS(PtGetGameTime, "Returns the system game time (frame based) in seconds.") { return PyFloat_FromDouble(cyMisc::GetSysSeconds()); } PYTHON_GLOBAL_METHOD_DEFINITION_NOARGS(PtGetFrameDeltaTime, "Returns the amount of time that has elapsed since last frame.") { return PyFloat_FromDouble(cyMisc::GetDelSysSeconds()); } PYTHON_GLOBAL_METHOD_DEFINITION(PtPageInNode, args, "Params: nodeName, ageName=\"\"\nPages in node, or a list of nodes") { PyObject* nodeNameObj = NULL; char* ageName = NULL; if (!PyArg_ParseTuple(args, "O|s", &nodeNameObj, &ageName)) { PyErr_SetString(PyExc_TypeError, "PtPageInNode expects a string or list of strings, and optionally a string"); PYTHON_RETURN_ERROR; } std::vector nodeNames; if (PyString_Check(nodeNameObj)) { nodeNames.push_back(PyString_AsString(nodeNameObj)); } else if (PyList_Check(nodeNameObj)) { int num = PyList_Size(nodeNameObj); for (int i = 0; i < num; i++) { PyObject* listItem = PyList_GetItem(nodeNameObj, i); if (!PyString_Check(listItem)) { PyErr_SetString(PyExc_TypeError, "PtPageInNode expects a string or list of strings, and optionally a string"); PYTHON_RETURN_ERROR; } nodeNames.push_back(PyString_AsString(listItem)); } } else { PyErr_SetString(PyExc_TypeError, "PtPageInNode expects a string or list of strings, and optionally a string"); PYTHON_RETURN_ERROR; } cyMisc::PageInNodes(nodeNames, ageName); PYTHON_RETURN_NONE; } PYTHON_GLOBAL_METHOD_DEFINITION(PtPageOutNode, args, "Params: nodeName\nPages out a node") { char* nodeName; if (!PyArg_ParseTuple(args, "s", &nodeName)) { PyErr_SetString(PyExc_TypeError, "PtPageOutNode expects a string"); PYTHON_RETURN_ERROR; } cyMisc::PageOutNode(nodeName); PYTHON_RETURN_NONE; } PYTHON_GLOBAL_METHOD_DEFINITION(PtLimitAvatarLOD, args, "Params: LODlimit\nSets avatar's LOD limit") { int lodLimit; if (!PyArg_ParseTuple(args, "i", &lodLimit)) { PyErr_SetString(PyExc_TypeError, "PtLimitAvatarLOD expects an integer"); PYTHON_RETURN_ERROR; } cyMisc::LimitAvatarLOD(lodLimit); PYTHON_RETURN_NONE; } PYTHON_GLOBAL_METHOD_DEFINITION(PtFogSetDefColor, args, "Params: color\nSets default fog color") { PyObject* colorObj = NULL; if (!PyArg_ParseTuple(args, "O", &colorObj)) { PyErr_SetString(PyExc_TypeError, "PtFogSetDefColor expects a ptColor object"); PYTHON_RETURN_ERROR; } if (!pyColor::Check(colorObj)) { PyErr_SetString(PyExc_TypeError, "PtFogSetDefColor expects a ptColor object"); PYTHON_RETURN_ERROR; } pyColor* color = pyColor::ConvertFrom(colorObj); cyMisc::FogSetDefColor(*color); PYTHON_RETURN_NONE; } PYTHON_GLOBAL_METHOD_DEFINITION(PtFogSetDefLinear, args, "Params: start,end,density\nSet linear fog values") { float start, end, density; if (!PyArg_ParseTuple(args, "fff", &start, &end, &density)) { PyErr_SetString(PyExc_TypeError, "PtFogSetDefLinear expects three floats"); PYTHON_RETURN_ERROR; } cyMisc::FogSetDefLinear(start, end, density); PYTHON_RETURN_NONE; } PYTHON_GLOBAL_METHOD_DEFINITION(PtFogSetDefExp, args, "Params: end,density\nSet exp fog values") { float end, density; if (!PyArg_ParseTuple(args, "ff", &end, &density)) { PyErr_SetString(PyExc_TypeError, "PtFogSetDefExp expects three floats"); PYTHON_RETURN_ERROR; } cyMisc::FogSetDefExp(end, density); PYTHON_RETURN_NONE; } PYTHON_GLOBAL_METHOD_DEFINITION(PtFogSetDefExp2, args, "Params: end,density\nSet exp2 fog values") { float end, density; if (!PyArg_ParseTuple(args, "ff", &end, &density)) { PyErr_SetString(PyExc_TypeError, "PtFogSetDefExp2 expects three floats"); PYTHON_RETURN_ERROR; } cyMisc::FogSetDefExp2(end, density); PYTHON_RETURN_NONE; } PYTHON_GLOBAL_METHOD_DEFINITION(PtLoadDialog, args, "Params: dialogName,selfKey=None,ageName=\"\"\nLoads a GUI dialog by name and optionally set the Notify proc key\n" "If the dialog is already loaded then it won't load it again") { char* dialogName; PyObject* keyObj = NULL; char* ageName = NULL; if (!PyArg_ParseTuple(args, "s|Os", &dialogName, &keyObj, &ageName)) { PyErr_SetString(PyExc_TypeError, "PtLoadDialog expects a string, and optionally a ptKey and second string"); PYTHON_RETURN_ERROR; } if (keyObj) { if (!pyKey::Check(keyObj)) { PyErr_SetString(PyExc_TypeError, "PtLoadDialog expects a string, and optionally a ptKey and second string"); PYTHON_RETURN_ERROR; } pyKey* key = pyKey::ConvertFrom(keyObj); if (ageName) cyMisc::LoadDialogKA(dialogName, *key, ageName); else cyMisc::LoadDialogK(dialogName, *key); } else cyMisc::LoadDialog(dialogName); PYTHON_RETURN_NONE; } PYTHON_GLOBAL_METHOD_DEFINITION(PtUnloadDialog, args, "Params: dialogName\nThis will unload the GUI dialog by name. If not loaded then nothing will happen") { char* dialogName; if (!PyArg_ParseTuple(args, "s", &dialogName)) { PyErr_SetString(PyExc_TypeError, "PtUnloadDialog expects a string"); PYTHON_RETURN_ERROR; } cyMisc::UnloadDialog(dialogName); PYTHON_RETURN_NONE; } PYTHON_GLOBAL_METHOD_DEFINITION(PtIsDialogLoaded, args, "Params: dialogName\nTest to see if a GUI dialog is loaded, by name") { char* dialogName; if (!PyArg_ParseTuple(args, "s", &dialogName)) { PyErr_SetString(PyExc_TypeError, "PtIsDialogLoaded expects a string"); PYTHON_RETURN_ERROR; } PYTHON_RETURN_BOOL(cyMisc::IsDialogLoaded(dialogName)); } PYTHON_GLOBAL_METHOD_DEFINITION(PtShowDialog, args, "Params: dialogName\nShow a GUI dialog by name (does not load dialog)") { char* dialogName; if (!PyArg_ParseTuple(args, "s", &dialogName)) { PyErr_SetString(PyExc_TypeError, "PtShowDialog expects a string"); PYTHON_RETURN_ERROR; } cyMisc::ShowDialog(dialogName); PYTHON_RETURN_NONE; } PYTHON_GLOBAL_METHOD_DEFINITION(PtHideDialog, args, "Params: dialogName\nHide a GUI dialog by name (does not unload dialog)") { char* dialogName; if (!PyArg_ParseTuple(args, "s", &dialogName)) { PyErr_SetString(PyExc_TypeError, "PtHideDialog expects a string"); PYTHON_RETURN_ERROR; } cyMisc::HideDialog(dialogName); PYTHON_RETURN_NONE; } PYTHON_GLOBAL_METHOD_DEFINITION(PtGetDialogFromTagID, args, "Params: tagID\nReturns the dialog associated with the tagID") { unsigned long tagID; if (!PyArg_ParseTuple(args, "l", &tagID)) { PyErr_SetString(PyExc_TypeError, "PtGetDialogFromTagID expects a long"); PYTHON_RETURN_ERROR; } return cyMisc::GetDialogFromTagID(tagID); } PYTHON_GLOBAL_METHOD_DEFINITION(PtGetDialogFromString, args, "Params: dialogName\nGet a ptGUIDialog from its name") { char* dialogName; if (!PyArg_ParseTuple(args, "s", &dialogName)) { PyErr_SetString(PyExc_TypeError, "PtHideDialog expects a string"); PYTHON_RETURN_ERROR; } return cyMisc::GetDialogFromString(dialogName); } PYTHON_GLOBAL_METHOD_DEFINITION_NOARGS(PtIsGUIModal, "Returns true if the GUI is displaying a modal dialog and blocking input") { PYTHON_RETURN_BOOL(cyMisc::IsGUIModal()); } PYTHON_GLOBAL_METHOD_DEFINITION(PtSendPrivateChatList, args, "Params: chatList\nLock the local avatar into private vox messaging, and / or add new members to his chat list") { PyObject* chatListObj = NULL; if (!PyArg_ParseTuple(args, "O", &chatListObj)) { PyErr_SetString(PyExc_TypeError, "PtSendPrivateChatList expects a list of ptPlayers"); PYTHON_RETURN_ERROR; } std::vector chatList; if (PyList_Check(chatListObj)) { int listSize = PyList_Size(chatListObj); for (int i = 0; i < listSize; i++) { PyObject* listItem = PyList_GetItem(chatListObj, i); if (!pyPlayer::Check(listItem)) { PyErr_SetString(PyExc_TypeError, "PtSendPrivateChatList expects a list of ptPlayers"); PYTHON_RETURN_ERROR; } chatList.push_back(pyPlayer::ConvertFrom(listItem)); } } else { PyErr_SetString(PyExc_TypeError, "PtSendPrivateChatList expects a list of ptPlayers"); PYTHON_RETURN_ERROR; } cyMisc::SetPrivateChatList(chatList); PYTHON_RETURN_NONE; } PYTHON_GLOBAL_METHOD_DEFINITION(PtClearPrivateChatList, args, "Params: memberKey\nRemove the local avatar from private vox messaging, and / or clear members from his chat list") { PyObject* keyObj = NULL; if (!PyArg_ParseTuple(args, "O", &keyObj)) { PyErr_SetString(PyExc_TypeError, "PtClearPrivateChatList expects a ptKey"); PYTHON_RETURN_ERROR; } if (!pyKey::Check(keyObj)) { PyErr_SetString(PyExc_TypeError, "PtClearPrivateChatList expects a ptKey"); PYTHON_RETURN_ERROR; } pyKey* key = pyKey::ConvertFrom(keyObj); cyMisc::ClearPrivateChatList(*key); PYTHON_RETURN_NONE; } /////////////////////////////////////////////////////////////////////////// // // AddPlasmaMethods - the python method definitions // void cyMisc::AddPlasmaMethods2(std::vector &methods) { PYTHON_GLOBAL_METHOD(methods, PtYesNoDialog); PYTHON_GLOBAL_METHOD(methods, PtRateIt); PYTHON_GLOBAL_METHOD(methods, PtExcludeRegionSet); PYTHON_GLOBAL_METHOD(methods, PtExcludeRegionSetNow); PYTHON_GLOBAL_METHOD(methods, PtAcceptInviteInGame); PYTHON_GLOBAL_METHOD_NOARGS(methods, PtGetTime); PYTHON_GLOBAL_METHOD_NOARGS(methods, PtGetGameTime); PYTHON_GLOBAL_METHOD_NOARGS(methods, PtGetFrameDeltaTime); PYTHON_GLOBAL_METHOD(methods, PtPageInNode); PYTHON_GLOBAL_METHOD(methods, PtPageOutNode); PYTHON_GLOBAL_METHOD(methods, PtLimitAvatarLOD); PYTHON_GLOBAL_METHOD(methods, PtFogSetDefColor); PYTHON_GLOBAL_METHOD(methods, PtFogSetDefLinear); PYTHON_GLOBAL_METHOD(methods, PtFogSetDefExp); PYTHON_GLOBAL_METHOD(methods, PtFogSetDefExp2); PYTHON_GLOBAL_METHOD(methods, PtLoadDialog); PYTHON_GLOBAL_METHOD(methods, PtUnloadDialog); PYTHON_GLOBAL_METHOD(methods, PtIsDialogLoaded); PYTHON_GLOBAL_METHOD(methods, PtShowDialog); PYTHON_GLOBAL_METHOD(methods, PtHideDialog); PYTHON_GLOBAL_METHOD(methods, PtGetDialogFromTagID); PYTHON_GLOBAL_METHOD(methods, PtGetDialogFromString); PYTHON_GLOBAL_METHOD_NOARGS(methods, PtIsGUIModal); PYTHON_GLOBAL_METHOD(methods, PtSendPrivateChatList); PYTHON_GLOBAL_METHOD(methods, PtClearPrivateChatList); } void cyMisc::AddPlasmaConstantsClasses(PyObject *m) { PYTHON_ENUM_START(PtCCRPetitionType); PYTHON_ENUM_ELEMENT(PtCCRPetitionType, kGeneralHelp,plNetCommon::PetitionTypes::kGeneralHelp); PYTHON_ENUM_ELEMENT(PtCCRPetitionType, kBug, plNetCommon::PetitionTypes::kBug); PYTHON_ENUM_ELEMENT(PtCCRPetitionType, kFeedback, plNetCommon::PetitionTypes::kFeedback); PYTHON_ENUM_ELEMENT(PtCCRPetitionType, kExploit, plNetCommon::PetitionTypes::kExploit); PYTHON_ENUM_ELEMENT(PtCCRPetitionType, kHarass, plNetCommon::PetitionTypes::kHarass); PYTHON_ENUM_ELEMENT(PtCCRPetitionType, kStuck, plNetCommon::PetitionTypes::kStuck); PYTHON_ENUM_ELEMENT(PtCCRPetitionType, kTechnical, plNetCommon::PetitionTypes::kTechnical); PYTHON_ENUM_END(m, PtCCRPetitionType); PYTHON_ENUM_START(PtLanguage); PYTHON_ENUM_ELEMENT(PtLanguage, kEnglish, plLocalization::kEnglish); PYTHON_ENUM_ELEMENT(PtLanguage, kFrench, plLocalization::kFrench); PYTHON_ENUM_ELEMENT(PtLanguage, kGerman, plLocalization::kGerman); PYTHON_ENUM_ELEMENT(PtLanguage, kSpanish, plLocalization::kSpanish); PYTHON_ENUM_ELEMENT(PtLanguage, kItalian, plLocalization::kItalian); PYTHON_ENUM_ELEMENT(PtLanguage, kJapanese, plLocalization::kJapanese); PYTHON_ENUM_ELEMENT(PtLanguage, kNumLanguages, plLocalization::kNumLanguages); PYTHON_ENUM_END(m, PtLanguage); PYTHON_ENUM_START(PtLOSReportType); PYTHON_ENUM_ELEMENT(PtLOSReportType, kReportHit, plLOSRequestMsg::kReportHit); PYTHON_ENUM_ELEMENT(PtLOSReportType, kReportMiss, plLOSRequestMsg::kReportMiss); PYTHON_ENUM_ELEMENT(PtLOSReportType, kReportHitOrMiss, plLOSRequestMsg::kReportHitOrMiss); PYTHON_ENUM_END(m, PtLOSReportType); PYTHON_ENUM_START(PtLOSObjectType); PYTHON_ENUM_ELEMENT(PtLOSObjectType, kClickables, kClickables); PYTHON_ENUM_ELEMENT(PtLOSObjectType, kCameraBlockers, kCameraBlockers); PYTHON_ENUM_ELEMENT(PtLOSObjectType, kCustom, kCustom); PYTHON_ENUM_ELEMENT(PtLOSObjectType, kShootable, kShootable); PYTHON_ENUM_END(m, PtLOSObjectType); }