Refactor all usage of RegisterFunction to ScriptFunction::Register

- Replace ScriptInterface::RegisterFunction with
ScriptFunction::Register
 - Mostly removing unused cmpPrivate*
 - Some usage introduces specific getters (mapgenerator, AIWorker,
XmppClient,...)
 - Several passthrough functions are simply removed in favour of calling
the original, reducing duplication
 - Make use of ScriptRequest/ScriptInterface capabilities where
relevant.
- Make JSI_* headers only expose necessary functions, lightening them
considerably and reducing duplication
 - Reuse namespaces in JSI_* implementations directly, reducing visual
noise there

Follows f3aedf88a6

Differential Revision: https://code.wildfiregames.com/D3626
This was SVN commit r24983.
This commit is contained in:
wraitii 2021-03-02 20:01:14 +00:00
parent 869076ebc5
commit cb346e207b
52 changed files with 820 additions and 1969 deletions

View file

@ -21,7 +21,6 @@
#include "graphics/HFTracer.h" #include "graphics/HFTracer.h"
#include "graphics/Terrain.h" #include "graphics/Terrain.h"
#include "graphics/scripting/JSInterface_GameView.h"
#include "lib/input.h" #include "lib/input.h"
#include "lib/timer.h" #include "lib/timer.h"
#include "maths/MathUtil.h" #include "maths/MathUtil.h"

View file

@ -35,7 +35,6 @@
#include "graphics/TerritoryTexture.h" #include "graphics/TerritoryTexture.h"
#include "graphics/Unit.h" #include "graphics/Unit.h"
#include "graphics/UnitManager.h" #include "graphics/UnitManager.h"
#include "graphics/scripting/JSInterface_GameView.h"
#include "lib/input.h" #include "lib/input.h"
#include "lib/timer.h" #include "lib/timer.h"
#include "lobby/IXmppClient.h" #include "lobby/IXmppClient.h"

View file

@ -32,6 +32,7 @@
#include "ps/Profile.h" #include "ps/Profile.h"
#include "ps/Threading.h" #include "ps/Threading.h"
#include "ps/scripting/JSInterface_VFS.h" #include "ps/scripting/JSInterface_VFS.h"
#include "scriptinterface/FunctionWrapper.h"
#include "scriptinterface/ScriptContext.h" #include "scriptinterface/ScriptContext.h"
#include "scriptinterface/ScriptConversions.h" #include "scriptinterface/ScriptConversions.h"
#include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptInterface.h"
@ -160,6 +161,11 @@ bool CMapGeneratorWorker::Run()
return true; return true;
} }
#define REGISTER_MAPGEN_FUNC(func) \
ScriptFunction::Register<&CMapGeneratorWorker::func, ScriptFunction::ObjectFromCBData<CMapGeneratorWorker>>(rq, #func);
#define REGISTER_MAPGEN_FUNC_NAME(func, name) \
ScriptFunction::Register<&CMapGeneratorWorker::func, ScriptFunction::ObjectFromCBData<CMapGeneratorWorker>>(rq, name);
void CMapGeneratorWorker::InitScriptInterface(const u32 seed) void CMapGeneratorWorker::InitScriptInterface(const u32 seed)
{ {
m_ScriptInterface->SetCallbackData(static_cast<void*>(this)); m_ScriptInterface->SetCallbackData(static_cast<void*>(this));
@ -174,9 +180,10 @@ void CMapGeneratorWorker::InitScriptInterface(const u32 seed)
m_ScriptInterface->LoadGlobalScripts(); m_ScriptInterface->LoadGlobalScripts();
// File loading // File loading
m_ScriptInterface->RegisterFunction<bool, VfsPath, CMapGeneratorWorker::LoadLibrary>("LoadLibrary"); ScriptRequest rq(m_ScriptInterface);
m_ScriptInterface->RegisterFunction<JS::Value, VfsPath, CMapGeneratorWorker::LoadHeightmap>("LoadHeightmapImage"); REGISTER_MAPGEN_FUNC_NAME(LoadScripts, "LoadLibrary");
m_ScriptInterface->RegisterFunction<JS::Value, VfsPath, CMapGeneratorWorker::LoadMapTerrain>("LoadMapTerrain"); REGISTER_MAPGEN_FUNC_NAME(LoadHeightmap, "LoadHeightmapImage");
REGISTER_MAPGEN_FUNC(LoadMapTerrain);
// Engine constants // Engine constants
@ -190,25 +197,30 @@ void CMapGeneratorWorker::InitScriptInterface(const u32 seed)
void CMapGeneratorWorker::RegisterScriptFunctions_MapGenerator() void CMapGeneratorWorker::RegisterScriptFunctions_MapGenerator()
{ {
ScriptRequest rq(m_ScriptInterface);
// Template functions // Template functions
m_ScriptInterface->RegisterFunction<CParamNode, std::string, CMapGeneratorWorker::GetTemplate>("GetTemplate"); REGISTER_MAPGEN_FUNC(GetTemplate);
m_ScriptInterface->RegisterFunction<bool, std::string, CMapGeneratorWorker::TemplateExists>("TemplateExists"); REGISTER_MAPGEN_FUNC(TemplateExists);
m_ScriptInterface->RegisterFunction<std::vector<std::string>, std::string, bool, CMapGeneratorWorker::FindTemplates>("FindTemplates"); REGISTER_MAPGEN_FUNC(FindTemplates);
m_ScriptInterface->RegisterFunction<std::vector<std::string>, std::string, bool, CMapGeneratorWorker::FindActorTemplates>("FindActorTemplates"); REGISTER_MAPGEN_FUNC(FindActorTemplates);
// Progression and profiling // Progression and profiling
m_ScriptInterface->RegisterFunction<void, int, CMapGeneratorWorker::SetProgress>("SetProgress"); REGISTER_MAPGEN_FUNC(SetProgress);
m_ScriptInterface->RegisterFunction<double, CMapGeneratorWorker::GetMicroseconds>("GetMicroseconds"); REGISTER_MAPGEN_FUNC(GetMicroseconds);
m_ScriptInterface->RegisterFunction<void, JS::HandleValue, CMapGeneratorWorker::ExportMap>("ExportMap"); REGISTER_MAPGEN_FUNC(ExportMap);
} }
#undef REGISTER_MAPGEN_FUNC
#undef REGISTER_MAPGEN_FUNC_NAME
int CMapGeneratorWorker::GetProgress() int CMapGeneratorWorker::GetProgress()
{ {
std::lock_guard<std::mutex> lock(m_WorkerMutex); std::lock_guard<std::mutex> lock(m_WorkerMutex);
return m_Progress; return m_Progress;
} }
double CMapGeneratorWorker::GetMicroseconds(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) double CMapGeneratorWorker::GetMicroseconds()
{ {
return JS_Now(); return JS_Now();
} }
@ -219,61 +231,47 @@ ScriptInterface::StructuredClone CMapGeneratorWorker::GetResults()
return m_MapData; return m_MapData;
} }
bool CMapGeneratorWorker::LoadLibrary(ScriptInterface::CmptPrivate* pCmptPrivate, const VfsPath& name) void CMapGeneratorWorker::ExportMap(JS::HandleValue data)
{ {
CMapGeneratorWorker* self = static_cast<CMapGeneratorWorker*>(pCmptPrivate->pCBData);
return self->LoadScripts(name);
}
void CMapGeneratorWorker::ExportMap(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue data)
{
CMapGeneratorWorker* self = static_cast<CMapGeneratorWorker*>(pCmptPrivate->pCBData);
// Copy results // Copy results
std::lock_guard<std::mutex> lock(self->m_WorkerMutex); std::lock_guard<std::mutex> lock(m_WorkerMutex);
self->m_MapData = self->m_ScriptInterface->WriteStructuredClone(data); m_MapData = m_ScriptInterface->WriteStructuredClone(data);
self->m_Progress = 0; m_Progress = 0;
} }
void CMapGeneratorWorker::SetProgress(ScriptInterface::CmptPrivate* pCmptPrivate, int progress) void CMapGeneratorWorker::SetProgress(int progress)
{ {
CMapGeneratorWorker* self = static_cast<CMapGeneratorWorker*>(pCmptPrivate->pCBData);
// Copy data // Copy data
std::lock_guard<std::mutex> lock(self->m_WorkerMutex); std::lock_guard<std::mutex> lock(m_WorkerMutex);
if (progress >= self->m_Progress) if (progress >= m_Progress)
self->m_Progress = progress; m_Progress = progress;
else else
LOGWARNING("The random map script tried to reduce the loading progress from %d to %d", self->m_Progress, progress); LOGWARNING("The random map script tried to reduce the loading progress from %d to %d", m_Progress, progress);
} }
CParamNode CMapGeneratorWorker::GetTemplate(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& templateName) CParamNode CMapGeneratorWorker::GetTemplate(const std::string& templateName)
{ {
CMapGeneratorWorker* self = static_cast<CMapGeneratorWorker*>(pCmptPrivate->pCBData); const CParamNode& templateRoot = m_TemplateLoader.GetTemplateFileData(templateName).GetChild("Entity");
const CParamNode& templateRoot = self->m_TemplateLoader.GetTemplateFileData(templateName).GetChild("Entity");
if (!templateRoot.IsOk()) if (!templateRoot.IsOk())
LOGERROR("Invalid template found for '%s'", templateName.c_str()); LOGERROR("Invalid template found for '%s'", templateName.c_str());
return templateRoot; return templateRoot;
} }
bool CMapGeneratorWorker::TemplateExists(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& templateName) bool CMapGeneratorWorker::TemplateExists(const std::string& templateName)
{ {
CMapGeneratorWorker* self = static_cast<CMapGeneratorWorker*>(pCmptPrivate->pCBData); return m_TemplateLoader.TemplateExists(templateName);
return self->m_TemplateLoader.TemplateExists(templateName);
} }
std::vector<std::string> CMapGeneratorWorker::FindTemplates(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& path, bool includeSubdirectories) std::vector<std::string> CMapGeneratorWorker::FindTemplates(const std::string& path, bool includeSubdirectories)
{ {
CMapGeneratorWorker* self = static_cast<CMapGeneratorWorker*>(pCmptPrivate->pCBData); return m_TemplateLoader.FindTemplates(path, includeSubdirectories, SIMULATION_TEMPLATES);
return self->m_TemplateLoader.FindTemplates(path, includeSubdirectories, SIMULATION_TEMPLATES);
} }
std::vector<std::string> CMapGeneratorWorker::FindActorTemplates(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& path, bool includeSubdirectories) std::vector<std::string> CMapGeneratorWorker::FindActorTemplates(const std::string& path, bool includeSubdirectories)
{ {
CMapGeneratorWorker* self = static_cast<CMapGeneratorWorker*>(pCmptPrivate->pCBData); return m_TemplateLoader.FindTemplates(path, includeSubdirectories, ACTOR_TEMPLATES);
return self->m_TemplateLoader.FindTemplates(path, includeSubdirectories, ACTOR_TEMPLATES);
} }
bool CMapGeneratorWorker::LoadScripts(const VfsPath& libraryName) bool CMapGeneratorWorker::LoadScripts(const VfsPath& libraryName)
@ -314,7 +312,7 @@ bool CMapGeneratorWorker::LoadScripts(const VfsPath& libraryName)
return true; return true;
} }
JS::Value CMapGeneratorWorker::LoadHeightmap(ScriptInterface::CmptPrivate* pCmptPrivate, const VfsPath& filename) JS::Value CMapGeneratorWorker::LoadHeightmap(const VfsPath& filename)
{ {
std::vector<u16> heightmap; std::vector<u16> heightmap;
if (LoadHeightmapImageVfs(filename, heightmap) != INFO::OK) if (LoadHeightmapImageVfs(filename, heightmap) != INFO::OK)
@ -323,18 +321,16 @@ JS::Value CMapGeneratorWorker::LoadHeightmap(ScriptInterface::CmptPrivate* pCmpt
return JS::UndefinedValue(); return JS::UndefinedValue();
} }
CMapGeneratorWorker* self = static_cast<CMapGeneratorWorker*>(pCmptPrivate->pCBData); ScriptRequest rq(m_ScriptInterface);
ScriptRequest rq(self->m_ScriptInterface);
JS::RootedValue returnValue(rq.cx); JS::RootedValue returnValue(rq.cx);
ToJSVal_vector(rq, &returnValue, heightmap); ToJSVal_vector(rq, &returnValue, heightmap);
return returnValue; return returnValue;
} }
// See CMapReader::UnpackTerrain, CMapReader::ParseTerrain for the reordering // See CMapReader::UnpackTerrain, CMapReader::ParseTerrain for the reordering
JS::Value CMapGeneratorWorker::LoadMapTerrain(ScriptInterface::CmptPrivate* pCmptPrivate, const VfsPath& filename) JS::Value CMapGeneratorWorker::LoadMapTerrain(const VfsPath& filename)
{ {
CMapGeneratorWorker* self = static_cast<CMapGeneratorWorker*>(pCmptPrivate->pCBData); ScriptRequest rq(m_ScriptInterface);
ScriptRequest rq(self->m_ScriptInterface);
if (!VfsFileExists(filename)) if (!VfsFileExists(filename))
{ {

View file

@ -133,55 +133,50 @@ private:
*/ */
bool LoadScripts(const VfsPath& libraryName); bool LoadScripts(const VfsPath& libraryName);
/**
* Recursively load all script files in the given folder.
*/
static bool LoadLibrary(ScriptInterface::CmptPrivate* pCmptPrivate, const VfsPath& name);
/** /**
* Finalize map generation and pass results from the script to the engine. * Finalize map generation and pass results from the script to the engine.
*/ */
static void ExportMap(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue data); void ExportMap(JS::HandleValue data);
/** /**
* Load an image file and return it as a height array. * Load an image file and return it as a height array.
*/ */
static JS::Value LoadHeightmap(ScriptInterface::CmptPrivate* pCmptPrivate, const VfsPath& src); JS::Value LoadHeightmap(const VfsPath& src);
/** /**
* Load an Atlas terrain file (PMP) returning textures and heightmap. * Load an Atlas terrain file (PMP) returning textures and heightmap.
*/ */
static JS::Value LoadMapTerrain(ScriptInterface::CmptPrivate* pCmptPrivate, const VfsPath& filename); JS::Value LoadMapTerrain(const VfsPath& filename);
/** /**
* Sets the map generation progress, which is one of multiple stages determining the loading screen progress. * Sets the map generation progress, which is one of multiple stages determining the loading screen progress.
*/ */
static void SetProgress(ScriptInterface::CmptPrivate* pCmptPrivate, int progress); void SetProgress(int progress);
/** /**
* Microseconds since the epoch. * Microseconds since the epoch.
*/ */
static double GetMicroseconds(ScriptInterface::CmptPrivate* pCmptPrivate); double GetMicroseconds();
/** /**
* Return the template data of the given template name. * Return the template data of the given template name.
*/ */
static CParamNode GetTemplate(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& templateName); CParamNode GetTemplate(const std::string& templateName);
/** /**
* Check whether the given template exists. * Check whether the given template exists.
*/ */
static bool TemplateExists(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& templateName); bool TemplateExists(const std::string& templateName);
/** /**
* Returns all template names of simulation entity templates. * Returns all template names of simulation entity templates.
*/ */
static std::vector<std::string> FindTemplates(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& path, bool includeSubdirectories); std::vector<std::string> FindTemplates(const std::string& path, bool includeSubdirectories);
/** /**
* Returns all template names of actors. * Returns all template names of actors.
*/ */
static std::vector<std::string> FindActorTemplates(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& path, bool includeSubdirectories); std::vector<std::string> FindActorTemplates(const std::string& path, bool includeSubdirectories);
/** /**
* Perform map generation in an independent thread. * Perform map generation in an independent thread.

View file

@ -22,13 +22,18 @@
#include "graphics/Camera.h" #include "graphics/Camera.h"
#include "graphics/GameView.h" #include "graphics/GameView.h"
#include "graphics/Terrain.h" #include "graphics/Terrain.h"
#include "maths/FixedVector3D.h"
#include "ps/Game.h" #include "ps/Game.h"
#include "ps/World.h" #include "ps/World.h"
#include "ps/CLogger.h" #include "ps/CLogger.h"
#include "scriptinterface/FunctionWrapper.h"
#include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptInterface.h"
#include "simulation2/helpers/Position.h"
namespace JSI_GameView
{
#define IMPLEMENT_BOOLEAN_SCRIPT_SETTING(NAME) \ #define IMPLEMENT_BOOLEAN_SCRIPT_SETTING(NAME) \
bool JSI_GameView::Get##NAME##Enabled(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) \ bool Get##NAME##Enabled() \
{ \ { \
if (!g_Game || !g_Game->GetView()) \ if (!g_Game || !g_Game->GetView()) \
{ \ { \
@ -38,7 +43,7 @@ bool JSI_GameView::Get##NAME##Enabled(ScriptInterface::CmptPrivate* UNUSED(pCmpt
return g_Game->GetView()->Get##NAME##Enabled(); \ return g_Game->GetView()->Get##NAME##Enabled(); \
} \ } \
\ \
void JSI_GameView::Set##NAME##Enabled(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), bool Enabled) \ void Set##NAME##Enabled(bool Enabled) \
{ \ { \
if (!g_Game || !g_Game->GetView()) \ if (!g_Game || !g_Game->GetView()) \
{ \ { \
@ -56,10 +61,10 @@ IMPLEMENT_BOOLEAN_SCRIPT_SETTING(ConstrainCamera);
#define REGISTER_BOOLEAN_SCRIPT_SETTING(NAME) \ #define REGISTER_BOOLEAN_SCRIPT_SETTING(NAME) \
scriptInterface.RegisterFunction<bool, &JSI_GameView::Get##NAME##Enabled>("GameView_Get" #NAME "Enabled"); \ ScriptFunction::Register<&Get##NAME##Enabled>(rq, "GameView_Get" #NAME "Enabled"); \
scriptInterface.RegisterFunction<void, bool, &JSI_GameView::Set##NAME##Enabled>("GameView_Set" #NAME "Enabled"); ScriptFunction::Register<&Set##NAME##Enabled>(rq, "GameView_Set" #NAME "Enabled");
void JSI_GameView::RegisterScriptFunctions_Settings(const ScriptInterface& scriptInterface) void RegisterScriptFunctions_Settings(const ScriptRequest& rq)
{ {
REGISTER_BOOLEAN_SCRIPT_SETTING(Culling); REGISTER_BOOLEAN_SCRIPT_SETTING(Culling);
REGISTER_BOOLEAN_SCRIPT_SETTING(LockCullCamera); REGISTER_BOOLEAN_SCRIPT_SETTING(LockCullCamera);
@ -68,9 +73,8 @@ void JSI_GameView::RegisterScriptFunctions_Settings(const ScriptInterface& scrip
#undef REGISTER_BOOLEAN_SCRIPT_SETTING #undef REGISTER_BOOLEAN_SCRIPT_SETTING
JS::Value JSI_GameView::GetCameraPivot(ScriptInterface::CmptPrivate* pCmptPrivate) JS::Value GetCameraPivot(const ScriptRequest& rq)
{ {
ScriptRequest rq(pCmptPrivate->pScriptInterface);
CVector3D pivot(-1, -1, -1); CVector3D pivot(-1, -1, -1);
if (g_Game && g_Game->GetView()) if (g_Game && g_Game->GetView())
pivot = g_Game->GetView()->GetCameraPivot(); pivot = g_Game->GetView()->GetCameraPivot();
@ -83,7 +87,7 @@ JS::Value JSI_GameView::GetCameraPivot(ScriptInterface::CmptPrivate* pCmptPrivat
/** /**
* Move camera to a 2D location. * Move camera to a 2D location.
*/ */
void JSI_GameView::CameraMoveTo(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), entity_pos_t x, entity_pos_t z) void CameraMoveTo(entity_pos_t x, entity_pos_t z)
{ {
if (!g_Game || !g_Game->GetWorld() || !g_Game->GetView() || !g_Game->GetWorld()->GetTerrain()) if (!g_Game || !g_Game->GetWorld() || !g_Game->GetView() || !g_Game->GetWorld()->GetTerrain())
return; return;
@ -101,7 +105,7 @@ void JSI_GameView::CameraMoveTo(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivat
/** /**
* Set the camera to look at the given location. * Set the camera to look at the given location.
*/ */
void JSI_GameView::SetCameraTarget(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float x, float y, float z) void SetCameraTarget(float x, float y, float z)
{ {
if (!g_Game || !g_Game->GetView()) if (!g_Game || !g_Game->GetView())
return; return;
@ -111,7 +115,7 @@ void JSI_GameView::SetCameraTarget(ScriptInterface::CmptPrivate* UNUSED(pCmptPri
/** /**
* Set the data (position, orientation and zoom) of the camera. * Set the data (position, orientation and zoom) of the camera.
*/ */
void JSI_GameView::SetCameraData(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), entity_pos_t x, entity_pos_t y, entity_pos_t z, entity_pos_t rotx, entity_pos_t roty, entity_pos_t zoom) void SetCameraData(entity_pos_t x, entity_pos_t y, entity_pos_t z, entity_pos_t rotx, entity_pos_t roty, entity_pos_t zoom)
{ {
if (!g_Game || !g_Game->GetView()) if (!g_Game || !g_Game->GetView())
return; return;
@ -125,7 +129,7 @@ void JSI_GameView::SetCameraData(ScriptInterface::CmptPrivate* UNUSED(pCmptPriva
* Start / stop camera following mode. * Start / stop camera following mode.
* @param entityid unit id to follow. If zero, stop following mode * @param entityid unit id to follow. If zero, stop following mode
*/ */
void JSI_GameView::CameraFollow(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), entity_id_t entityid) void CameraFollow(entity_id_t entityid)
{ {
if (!g_Game || !g_Game->GetView()) if (!g_Game || !g_Game->GetView())
return; return;
@ -137,7 +141,7 @@ void JSI_GameView::CameraFollow(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivat
* Start / stop first-person camera following mode. * Start / stop first-person camera following mode.
* @param entityid unit id to follow. If zero, stop following mode. * @param entityid unit id to follow. If zero, stop following mode.
*/ */
void JSI_GameView::CameraFollowFPS(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), entity_id_t entityid) void CameraFollowFPS(entity_id_t entityid)
{ {
if (!g_Game || !g_Game->GetView()) if (!g_Game || !g_Game->GetView())
return; return;
@ -145,7 +149,7 @@ void JSI_GameView::CameraFollowFPS(ScriptInterface::CmptPrivate* UNUSED(pCmptPri
g_Game->GetView()->FollowEntity(entityid, true); g_Game->GetView()->FollowEntity(entityid, true);
} }
entity_id_t JSI_GameView::GetFollowedEntity(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) entity_id_t GetFollowedEntity()
{ {
if (!g_Game || !g_Game->GetView()) if (!g_Game || !g_Game->GetView())
return INVALID_ENTITY; return INVALID_ENTITY;
@ -153,22 +157,23 @@ entity_id_t JSI_GameView::GetFollowedEntity(ScriptInterface::CmptPrivate* UNUSED
return g_Game->GetView()->GetFollowedEntity(); return g_Game->GetView()->GetFollowedEntity();
} }
CFixedVector3D JSI_GameView::GetTerrainAtScreenPoint(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), int x, int y) CFixedVector3D GetTerrainAtScreenPoint(int x, int y)
{ {
CVector3D pos = g_Game->GetView()->GetCamera()->GetWorldCoordinates(x, y, true); CVector3D pos = g_Game->GetView()->GetCamera()->GetWorldCoordinates(x, y, true);
return CFixedVector3D(fixed::FromFloat(pos.X), fixed::FromFloat(pos.Y), fixed::FromFloat(pos.Z)); return CFixedVector3D(fixed::FromFloat(pos.X), fixed::FromFloat(pos.Y), fixed::FromFloat(pos.Z));
} }
void JSI_GameView::RegisterScriptFunctions(const ScriptInterface& scriptInterface) void RegisterScriptFunctions(const ScriptRequest& rq)
{ {
RegisterScriptFunctions_Settings(scriptInterface); RegisterScriptFunctions_Settings(rq);
scriptInterface.RegisterFunction<JS::Value, &GetCameraPivot>("GetCameraPivot"); ScriptFunction::Register<&GetCameraPivot>(rq, "GetCameraPivot");
scriptInterface.RegisterFunction<void, entity_pos_t, entity_pos_t, &CameraMoveTo>("CameraMoveTo"); ScriptFunction::Register<&CameraMoveTo>(rq, "CameraMoveTo");
scriptInterface.RegisterFunction<void, float, float, float, &SetCameraTarget>("SetCameraTarget"); ScriptFunction::Register<&SetCameraTarget>(rq, "SetCameraTarget");
scriptInterface.RegisterFunction<void, entity_pos_t, entity_pos_t, entity_pos_t, entity_pos_t, entity_pos_t, entity_pos_t, &SetCameraData>("SetCameraData"); ScriptFunction::Register<&SetCameraData>(rq, "SetCameraData");
scriptInterface.RegisterFunction<void, entity_id_t, &CameraFollow>("CameraFollow"); ScriptFunction::Register<&CameraFollow>(rq, "CameraFollow");
scriptInterface.RegisterFunction<void, entity_id_t, &CameraFollowFPS>("CameraFollowFPS"); ScriptFunction::Register<&CameraFollowFPS>(rq, "CameraFollowFPS");
scriptInterface.RegisterFunction<entity_id_t, &GetFollowedEntity>("GetFollowedEntity"); ScriptFunction::Register<&GetFollowedEntity>(rq, "GetFollowedEntity");
scriptInterface.RegisterFunction<CFixedVector3D, int, int, &GetTerrainAtScreenPoint>("GetTerrainAtScreenPoint"); ScriptFunction::Register<&GetTerrainAtScreenPoint>(rq, "GetTerrainAtScreenPoint");
}
} }

View file

@ -18,34 +18,11 @@
#ifndef INCLUDED_JSINTERFACE_GAMEVIEW #ifndef INCLUDED_JSINTERFACE_GAMEVIEW
#define INCLUDED_JSINTERFACE_GAMEVIEW #define INCLUDED_JSINTERFACE_GAMEVIEW
#include "maths/FixedVector3D.h" class ScriptRequest;
#include "scriptinterface/ScriptInterface.h"
#include "simulation2/helpers/Position.h"
#include "simulation2/system/Entity.h"
#define DECLARE_BOOLEAN_SCRIPT_SETTING(NAME) \
bool Get##NAME##Enabled(ScriptInterface::CmptPrivate* pCmptPrivate); \
void Set##NAME##Enabled(ScriptInterface::CmptPrivate* pCmptPrivate, bool Enabled);
namespace JSI_GameView namespace JSI_GameView
{ {
void RegisterScriptFunctions(const ScriptInterface& ScriptInterface); void RegisterScriptFunctions(const ScriptRequest& rq);
void RegisterScriptFunctions_Settings(const ScriptInterface& scriptInterface);
DECLARE_BOOLEAN_SCRIPT_SETTING(Culling);
DECLARE_BOOLEAN_SCRIPT_SETTING(LockCullCamera);
DECLARE_BOOLEAN_SCRIPT_SETTING(ConstrainCamera);
JS::Value GetCameraPivot(ScriptInterface::CmptPrivate* pCmptPrivate);
void CameraMoveTo(ScriptInterface::CmptPrivate* pCmptPrivate, entity_pos_t x, entity_pos_t z);
void SetCameraTarget(ScriptInterface::CmptPrivate* pCmptPrivate, float x, float y, float z);
void SetCameraData(ScriptInterface::CmptPrivate* pCmptPrivate, entity_pos_t x, entity_pos_t y, entity_pos_t z, entity_pos_t rotx, entity_pos_t roty, entity_pos_t zoom);
void CameraFollow(ScriptInterface::CmptPrivate* pCmptPrivate, entity_id_t entityid);
void CameraFollowFPS(ScriptInterface::CmptPrivate* pCmptPrivate, entity_id_t entityid);
entity_id_t GetFollowedEntity(ScriptInterface::CmptPrivate* pCmptPrivate);
CFixedVector3D GetTerrainAtScreenPoint(ScriptInterface::CmptPrivate* pCmptPrivate, int x, int y);
} }
#undef DECLARE_BOOLEAN_SCRIPT_SETTING
#endif // INCLUDED_JSINTERFACE_GAMEVIEW #endif // INCLUDED_JSINTERFACE_GAMEVIEW

View file

@ -23,21 +23,24 @@
#include "gui/GUIManager.h" #include "gui/GUIManager.h"
#include "gui/ObjectBases/IGUIObject.h" #include "gui/ObjectBases/IGUIObject.h"
#include "ps/GameSetup/Config.h" #include "ps/GameSetup/Config.h"
#include "scriptinterface/FunctionWrapper.h"
#include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptInterface.h"
namespace JSI_GUIManager
{
// Note that the initData argument may only contain clonable data. // Note that the initData argument may only contain clonable data.
// Functions aren't supported for example! // Functions aren't supported for example!
void JSI_GUIManager::PushGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name, JS::HandleValue initData, JS::HandleValue callbackFunction) void PushGuiPage(const ScriptInterface& scriptInterface, const std::wstring& name, JS::HandleValue initData, JS::HandleValue callbackFunction)
{ {
g_GUI->PushPage(name, pCmptPrivate->pScriptInterface->WriteStructuredClone(initData), callbackFunction); g_GUI->PushPage(name, scriptInterface.WriteStructuredClone(initData), callbackFunction);
} }
void JSI_GUIManager::SwitchGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name, JS::HandleValue initData) void SwitchGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name, JS::HandleValue initData)
{ {
g_GUI->SwitchPage(name, pCmptPrivate->pScriptInterface, initData); g_GUI->SwitchPage(name, pCmptPrivate->pScriptInterface, initData);
} }
void JSI_GUIManager::PopGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue args) void PopGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue args)
{ {
if (g_GUI->GetPageCount() < 2) if (g_GUI->GetPageCount() < 2)
{ {
@ -49,61 +52,41 @@ void JSI_GUIManager::PopGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, JS::
g_GUI->PopPage(pCmptPrivate->pScriptInterface->WriteStructuredClone(args)); g_GUI->PopPage(pCmptPrivate->pScriptInterface->WriteStructuredClone(args));
} }
JS::Value JSI_GUIManager::GetGUIObjectByName(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& name) std::wstring SetCursor(const std::wstring& name)
{
CGUI* guiPage = static_cast<CGUI*>(pCmptPrivate->pCBData);
IGUIObject* guiObj = guiPage->FindObjectByName(name);
if (!guiObj)
return JS::UndefinedValue();
return JS::ObjectValue(*guiObj->GetJSObject());
}
void JSI_GUIManager::SetGlobalHotkey(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& hotkeyTag, const std::string& eventName, JS::HandleValue function)
{
CGUI* guiPage = static_cast<CGUI*>(pCmptPrivate->pCBData);
guiPage->SetGlobalHotkey(hotkeyTag, eventName, function);
}
void JSI_GUIManager::UnsetGlobalHotkey(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& hotkeyTag, const std::string& eventName)
{
CGUI* guiPage = static_cast<CGUI*>(pCmptPrivate->pCBData);
guiPage->UnsetGlobalHotkey(hotkeyTag, eventName);
}
std::wstring JSI_GUIManager::SetCursor(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& name)
{ {
std::wstring old = g_CursorName; std::wstring old = g_CursorName;
g_CursorName = name; g_CursorName = name;
return old; return old;
} }
void JSI_GUIManager::ResetCursor(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) void ResetCursor()
{ {
g_CursorName = g_DefaultCursor; g_CursorName = g_DefaultCursor;
} }
bool JSI_GUIManager::TemplateExists(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& templateName) bool TemplateExists(const std::string& templateName)
{ {
return g_GUI->TemplateExists(templateName); return g_GUI->TemplateExists(templateName);
} }
CParamNode JSI_GUIManager::GetTemplate(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& templateName) CParamNode GetTemplate(const std::string& templateName)
{ {
return g_GUI->GetTemplate(templateName); return g_GUI->GetTemplate(templateName);
} }
void JSI_GUIManager::RegisterScriptFunctions(const ScriptInterface& scriptInterface)
void RegisterScriptFunctions(const ScriptRequest& rq)
{ {
scriptInterface.RegisterFunction<void, std::wstring, JS::HandleValue, JS::HandleValue, &PushGuiPage>("PushGuiPage"); ScriptFunction::Register<&PushGuiPage>(rq, "PushGuiPage");
scriptInterface.RegisterFunction<void, std::wstring, JS::HandleValue, &SwitchGuiPage>("SwitchGuiPage"); ScriptFunction::Register<&SwitchGuiPage>(rq, "SwitchGuiPage");
scriptInterface.RegisterFunction<void, std::string, std::string, JS::HandleValue, &SetGlobalHotkey>("SetGlobalHotkey"); ScriptFunction::Register<&PopGuiPage>(rq, "PopGuiPage");
scriptInterface.RegisterFunction<void, std::string, std::string, &UnsetGlobalHotkey>("UnsetGlobalHotkey"); ScriptFunction::Register<&SetCursor>(rq, "SetCursor");
scriptInterface.RegisterFunction<void, JS::HandleValue, &PopGuiPage>("PopGuiPage"); ScriptFunction::Register<&ResetCursor>(rq, "ResetCursor");
scriptInterface.RegisterFunction<JS::Value, std::string, &GetGUIObjectByName>("GetGUIObjectByName"); ScriptFunction::Register<&TemplateExists>(rq, "TemplateExists");
scriptInterface.RegisterFunction<std::wstring, std::wstring, &SetCursor>("SetCursor"); ScriptFunction::Register<&GetTemplate>(rq, "GetTemplate");
scriptInterface.RegisterFunction<void, &ResetCursor>("ResetCursor");
scriptInterface.RegisterFunction<bool, std::string, &TemplateExists>("TemplateExists"); ScriptFunction::Register<&CGUI::FindObjectByName, &ScriptFunction::ObjectFromCBData<CGUI>>(rq, "GetGUIObjectByName");
scriptInterface.RegisterFunction<CParamNode, std::string, &GetTemplate>("GetTemplate"); ScriptFunction::Register<&CGUI::SetGlobalHotkey, &ScriptFunction::ObjectFromCBData<CGUI>>(rq, "SetGlobalHotkey");
ScriptFunction::Register<&CGUI::UnsetGlobalHotkey, &ScriptFunction::ObjectFromCBData<CGUI>>(rq, "UnsetGlobalHotkey");
}
} }

View file

@ -18,23 +18,11 @@
#ifndef INCLUDED_JSI_GUIMANAGER #ifndef INCLUDED_JSI_GUIMANAGER
#define INCLUDED_JSI_GUIMANAGER #define INCLUDED_JSI_GUIMANAGER
#include "scriptinterface/ScriptInterface.h" class ScriptRequest;
#include "simulation2/system/ParamNode.h"
namespace JSI_GUIManager namespace JSI_GUIManager
{ {
void PushGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name, JS::HandleValue initData, JS::HandleValue callbackFunction); void RegisterScriptFunctions(const ScriptRequest& rq);
void SwitchGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name, JS::HandleValue initData);
void PopGuiPage(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue args);
JS::Value GetGUIObjectByName(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& name);
void SetGlobalHotkey(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& hotkeyTag, const std::string& eventName, JS::HandleValue function);
void UnsetGlobalHotkey(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& hotkeyTag, const std::string& eventName);
std::wstring SetCursor(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name);
void ResetCursor(ScriptInterface::CmptPrivate* pCmptPrivate);
bool TemplateExists(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& templateName);
CParamNode GetTemplate(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& templateName);
void RegisterScriptFunctions(const ScriptInterface& scriptInterface);
} }
#endif // INCLUDED_JSI_GUIMANAGER #endif // INCLUDED_JSI_GUIMANAGER

View file

@ -53,24 +53,24 @@ void GuiScriptingInit(ScriptInterface& scriptInterface)
ScriptRequest rq(scriptInterface); ScriptRequest rq(scriptInterface);
JSI_GUISize::RegisterScriptClass(scriptInterface); JSI_GUISize::RegisterScriptClass(scriptInterface);
JSI_ConfigDB::RegisterScriptFunctions(scriptInterface); JSI_ConfigDB::RegisterScriptFunctions(rq);
JSI_Console::RegisterScriptFunctions(rq); JSI_Console::RegisterScriptFunctions(rq);
JSI_Debug::RegisterScriptFunctions(scriptInterface); JSI_Debug::RegisterScriptFunctions(rq);
JSI_GUIManager::RegisterScriptFunctions(scriptInterface); JSI_GUIManager::RegisterScriptFunctions(rq);
JSI_Game::RegisterScriptFunctions(scriptInterface); JSI_Game::RegisterScriptFunctions(rq);
JSI_GameView::RegisterScriptFunctions(scriptInterface); JSI_GameView::RegisterScriptFunctions(rq);
JSI_Hotkey::RegisterScriptFunctions(scriptInterface); JSI_Hotkey::RegisterScriptFunctions(rq);
JSI_L10n::RegisterScriptFunctions(scriptInterface); JSI_L10n::RegisterScriptFunctions(rq);
JSI_Lobby::RegisterScriptFunctions(scriptInterface); JSI_Lobby::RegisterScriptFunctions(rq);
JSI_Main::RegisterScriptFunctions(scriptInterface); JSI_Main::RegisterScriptFunctions(rq);
JSI_Mod::RegisterScriptFunctions(scriptInterface); JSI_Mod::RegisterScriptFunctions(rq);
JSI_ModIo::RegisterScriptFunctions(scriptInterface); JSI_ModIo::RegisterScriptFunctions(rq);
JSI_Network::RegisterScriptFunctions(scriptInterface); JSI_Network::RegisterScriptFunctions(rq);
JSI_Renderer::RegisterScriptFunctions(scriptInterface); JSI_Renderer::RegisterScriptFunctions(rq);
JSI_SavedGame::RegisterScriptFunctions(scriptInterface); JSI_SavedGame::RegisterScriptFunctions(rq);
JSI_Simulation::RegisterScriptFunctions(scriptInterface); JSI_Simulation::RegisterScriptFunctions(rq);
JSI_Sound::RegisterScriptFunctions(scriptInterface); JSI_Sound::RegisterScriptFunctions(rq);
JSI_UserReport::RegisterScriptFunctions(scriptInterface); JSI_UserReport::RegisterScriptFunctions(rq);
JSI_VFS::RegisterScriptFunctions_GUI(scriptInterface); JSI_VFS::RegisterScriptFunctions_GUI(rq);
JSI_VisualReplay::RegisterScriptFunctions(scriptInterface); JSI_VisualReplay::RegisterScriptFunctions(rq);
} }

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2018 Wildfire Games. /* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -21,169 +21,81 @@
#include "i18n/L10n.h" #include "i18n/L10n.h"
#include "lib/utf8.h" #include "lib/utf8.h"
#include "scriptinterface/FunctionWrapper.h"
#include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptInterface.h"
// Returns a translation of the specified English string into the current language. namespace JSI_L10n
std::wstring JSI_L10n::Translate(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& sourceString)
{ {
return wstring_from_utf8(g_L10n.Translate(utf8_from_wstring(sourceString))); L10n* L10nGetter(const ScriptRequest&, JS::CallArgs&)
{
if (!g_L10n.IsInitialised())
{
LOGERROR("Trying to access g_L10n when it's not initialized!");
return nullptr;
}
return &g_L10n.GetSingleton();
} }
// Returns a translation of the specified English string, for the specified context. std::vector<std::string> TranslateArray(const std::vector<std::string>& sourceArray)
std::wstring JSI_L10n::TranslateWithContext(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& context, const std::wstring& sourceString)
{ {
return wstring_from_utf8(g_L10n.TranslateWithContext(context, utf8_from_wstring(sourceString))); std::vector<std::string> translatedArray;
} if (g_L10n.IsInitialised())
for (const std::string& elem : sourceArray)
// Return a translated version of the given strings (singular and plural) depending on an integer value. translatedArray.push_back(g_L10n.Translate(elem));
std::wstring JSI_L10n::TranslatePlural(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& singularSourceString, const std::wstring& pluralSourceString, int number)
{
return wstring_from_utf8(g_L10n.TranslatePlural(utf8_from_wstring(singularSourceString), utf8_from_wstring(pluralSourceString), number));
}
// Return a translated version of the given strings (singular and plural) depending on an integer value, for the specified context.
std::wstring JSI_L10n::TranslatePluralWithContext(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& context, const std::wstring& singularSourceString, const std::wstring& pluralSourceString, int number)
{
return wstring_from_utf8(g_L10n.TranslatePluralWithContext(context, utf8_from_wstring(singularSourceString), utf8_from_wstring(pluralSourceString), number));
}
// Return a translated version of the given string, localizing it line by line.
std::wstring JSI_L10n::TranslateLines(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& sourceString)
{
return wstring_from_utf8(g_L10n.TranslateLines(utf8_from_wstring(sourceString)));
}
// Return a translated version of the items in the specified array.
std::vector<std::wstring> JSI_L10n::TranslateArray(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::vector<std::wstring>& sourceArray)
{
std::vector<std::wstring> translatedArray;
for (const std::wstring& elem : sourceArray)
translatedArray.push_back(wstring_from_utf8(g_L10n.Translate(utf8_from_wstring(elem))));
return translatedArray; return translatedArray;
} }
std::wstring JSI_L10n::GetFallbackToAvailableDictLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale)
{
return g_L10n.GetFallbackToAvailableDictLocale(locale);
}
// Return a localized version of a time given in milliseconds. // Return a localized version of a time given in milliseconds.
std::wstring JSI_L10n::FormatMillisecondsIntoDateStringLocal(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), UDate milliseconds, const std::wstring& formatString) std::string FormatMillisecondsIntoDateStringLocal(UDate milliseconds, const std::string& formatString)
{ {
return wstring_from_utf8(g_L10n.FormatMillisecondsIntoDateString(milliseconds, utf8_from_wstring(formatString), true)); return g_L10n.FormatMillisecondsIntoDateString(milliseconds, formatString, true);
} }
// Return a localized version of a duration or a time in GMT given in milliseconds. // Return a localized version of a duration or a time in GMT given in milliseconds.
std::wstring JSI_L10n::FormatMillisecondsIntoDateStringGMT(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), UDate milliseconds, const std::wstring& formatString) std::string FormatMillisecondsIntoDateStringGMT(UDate milliseconds, const std::string& formatString)
{ {
return wstring_from_utf8(g_L10n.FormatMillisecondsIntoDateString(milliseconds, utf8_from_wstring(formatString), false)); return g_L10n.FormatMillisecondsIntoDateString(milliseconds, formatString, false);
} }
// Return a localized version of the given decimal number. void RegisterScriptFunctions(const ScriptRequest& rq)
std::wstring JSI_L10n::FormatDecimalNumberIntoString(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), double number)
{ {
return wstring_from_utf8(g_L10n.FormatDecimalNumberIntoString(number)); #define REGISTER_L10N(name) \
ScriptFunction::Register<&L10n::name, &L10nGetter>(rq, #name);
#define REGISTER_L10N_FUNC(func, name) \
ScriptFunction::Register<func, &L10nGetter>(rq, name);
REGISTER_L10N(Translate)
REGISTER_L10N(TranslateWithContext)
REGISTER_L10N(TranslatePlural)
REGISTER_L10N(TranslatePluralWithContext)
REGISTER_L10N(TranslateLines)
ScriptFunction::Register<&TranslateArray>(rq, "TranslateArray");
ScriptFunction::Register<&FormatMillisecondsIntoDateStringLocal>(rq, "FormatMillisecondsIntoDateStringLocal");
ScriptFunction::Register<&FormatMillisecondsIntoDateStringGMT>(rq, "FormatMillisecondsIntoDateStringGMT");
REGISTER_L10N(FormatDecimalNumberIntoString)
REGISTER_L10N(GetSupportedLocaleBaseNames)
REGISTER_L10N(GetSupportedLocaleDisplayNames)
REGISTER_L10N_FUNC(&L10n::GetCurrentLocaleString, "GetCurrentLocale");
REGISTER_L10N(GetAllLocales)
// Select the appropriate overload.
REGISTER_L10N_FUNC(static_cast<std::string(L10n::*)(const std::string&) const>(&L10n::GetDictionaryLocale), "GetDictionaryLocale");
REGISTER_L10N(GetDictionariesForLocale)
REGISTER_L10N(UseLongStrings)
REGISTER_L10N(GetLocaleLanguage)
REGISTER_L10N(GetLocaleBaseName)
REGISTER_L10N(GetLocaleCountry)
REGISTER_L10N(GetLocaleScript)
// Select the appropriate overload.
REGISTER_L10N_FUNC(static_cast<std::wstring(L10n::*)(const std::string&) const>(&L10n::GetFallbackToAvailableDictLocale), "GetFallbackToAvailableDictLocale");
// Select the appropriate overloads.
REGISTER_L10N_FUNC(static_cast<bool(L10n::*)(const std::string&) const>(&L10n::ValidateLocale), "ValidateLocale");
REGISTER_L10N_FUNC(static_cast<bool(L10n::*)(const std::string&) const>(&L10n::SaveLocale), "SaveLocale");
REGISTER_L10N(ReevaluateCurrentLocaleAndReload)
#undef REGISTER_L10N
#undef REGISTER_L10N_FUNC
} }
std::vector<std::string> JSI_L10n::GetSupportedLocaleBaseNames(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate))
{
return g_L10n.GetSupportedLocaleBaseNames();
}
std::vector<std::wstring> JSI_L10n::GetSupportedLocaleDisplayNames(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate))
{
return g_L10n.GetSupportedLocaleDisplayNames();
}
std::string JSI_L10n::GetCurrentLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate))
{
return g_L10n.GetCurrentLocaleString();
}
bool JSI_L10n::UseLongStrings(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate))
{
return g_L10n.UseLongStrings();
}
std::vector<std::string> JSI_L10n::GetAllLocales(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate))
{
return g_L10n.GetAllLocales();
}
std::string JSI_L10n::GetDictionaryLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& configLocale)
{
return g_L10n.GetDictionaryLocale(configLocale);
}
std::vector<std::wstring> JSI_L10n::GetDictionariesForLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale)
{
return g_L10n.GetDictionariesForLocale(locale);
}
std::string JSI_L10n::GetLocaleLanguage(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale)
{
return g_L10n.GetLocaleLanguage(locale);
}
std::string JSI_L10n::GetLocaleBaseName(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale)
{
return g_L10n.GetLocaleBaseName(locale);
}
std::string JSI_L10n::GetLocaleCountry(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale)
{
return g_L10n.GetLocaleCountry(locale);
}
std::string JSI_L10n::GetLocaleScript(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale)
{
return g_L10n.GetLocaleScript(locale);
}
bool JSI_L10n::ValidateLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale)
{
return g_L10n.ValidateLocale(locale);
}
bool JSI_L10n::SaveLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale)
{
return g_L10n.SaveLocale(locale);
}
void JSI_L10n::ReevaluateCurrentLocaleAndReload(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate))
{
g_L10n.ReevaluateCurrentLocaleAndReload();
}
void JSI_L10n::RegisterScriptFunctions(const ScriptInterface& scriptInterface)
{
scriptInterface.RegisterFunction<std::wstring, std::wstring, &Translate>("Translate");
scriptInterface.RegisterFunction<std::wstring, std::string, std::wstring, &TranslateWithContext>("TranslateWithContext");
scriptInterface.RegisterFunction<std::wstring, std::wstring, std::wstring, int, &TranslatePlural>("TranslatePlural");
scriptInterface.RegisterFunction<std::wstring, std::string, std::wstring, std::wstring, int, &TranslatePluralWithContext>("TranslatePluralWithContext");
scriptInterface.RegisterFunction<std::wstring, std::wstring, &TranslateLines>("TranslateLines");
scriptInterface.RegisterFunction<std::vector<std::wstring>, std::vector<std::wstring>, &TranslateArray>("TranslateArray");
scriptInterface.RegisterFunction<std::wstring, UDate, std::wstring, &FormatMillisecondsIntoDateStringLocal>("FormatMillisecondsIntoDateStringLocal");
scriptInterface.RegisterFunction<std::wstring, UDate, std::wstring, &FormatMillisecondsIntoDateStringGMT>("FormatMillisecondsIntoDateStringGMT");
scriptInterface.RegisterFunction<std::wstring, double, &FormatDecimalNumberIntoString>("FormatDecimalNumberIntoString");
scriptInterface.RegisterFunction<std::vector<std::string>, &GetSupportedLocaleBaseNames>("GetSupportedLocaleBaseNames");
scriptInterface.RegisterFunction<std::vector<std::wstring>, &GetSupportedLocaleDisplayNames>("GetSupportedLocaleDisplayNames");
scriptInterface.RegisterFunction<std::string, &GetCurrentLocale>("GetCurrentLocale");
scriptInterface.RegisterFunction<std::vector<std::string>, &GetAllLocales>("GetAllLocales");
scriptInterface.RegisterFunction<std::string, std::string, &GetDictionaryLocale>("GetDictionaryLocale");
scriptInterface.RegisterFunction<std::vector<std::wstring>, std::string, &GetDictionariesForLocale>("GetDictionariesForLocale");
scriptInterface.RegisterFunction<bool, &UseLongStrings>("UseLongStrings");
scriptInterface.RegisterFunction<std::string, std::string, &GetLocaleLanguage>("GetLocaleLanguage");
scriptInterface.RegisterFunction<std::string, std::string, &GetLocaleBaseName>("GetLocaleBaseName");
scriptInterface.RegisterFunction<std::string, std::string, &GetLocaleCountry>("GetLocaleCountry");
scriptInterface.RegisterFunction<std::string, std::string, &GetLocaleScript>("GetLocaleScript");
scriptInterface.RegisterFunction<std::wstring, std::string, &GetFallbackToAvailableDictLocale>("GetFallbackToAvailableDictLocale");
scriptInterface.RegisterFunction<bool, std::string, &ValidateLocale>("ValidateLocale");
scriptInterface.RegisterFunction<bool, std::string, &SaveLocale>("SaveLocale");
scriptInterface.RegisterFunction<void, &ReevaluateCurrentLocaleAndReload>("ReevaluateCurrentLocaleAndReload");
} }

View file

@ -18,8 +18,7 @@
#ifndef INCLUDED_JSINTERFACE_L10N #ifndef INCLUDED_JSINTERFACE_L10N
#define INCLUDED_JSINTERFACE_L10N #define INCLUDED_JSINTERFACE_L10N
#include "lib/external_libraries/icu.h" class ScriptRequest;
#include "scriptinterface/ScriptInterface.h"
/** /**
* Namespace for the functions of the JavaScript interface for * Namespace for the functions of the JavaScript interface for
@ -37,419 +36,12 @@ namespace JSI_L10n
* internationalization and localization into the specified JavaScript * internationalization and localization into the specified JavaScript
* context. * context.
* *
* @param ScriptInterface JavaScript context where RegisterScriptFunctions() * @param ScriptRequest Script Request where RegisterScriptFunctions()
* registers the functions. * registers the functions.
* *
* @sa GuiScriptingInit() * @sa GuiScriptingInit()
*/ */
void RegisterScriptFunctions(const ScriptInterface& ScriptInterface); void RegisterScriptFunctions(const ScriptRequest& rq);
/**
* Returns the translation of the specified string to the
* @link L10n::GetCurrentLocale() current locale@endlink.
*
* This is a JavaScript interface to L10n::Translate().
*
* @param pCmptPrivate JavaScript context.
* @param sourceString String to translate to the current locale.
* @return Translation of @p sourceString to the current locale, or
* @p sourceString if there is no translation available.
*/
std::wstring Translate(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& sourceString);
/**
* Returns the translation of the specified string to the
* @link L10n::GetCurrentLocale() current locale@endlink in the specified
* context.
*
* This is a JavaScript interface to L10n::TranslateWithContext().
*
* @param pCmptPrivate JavaScript context.
* @param context Context where the string is used. See
* http://www.gnu.org/software/gettext/manual/html_node/Contexts.html
* @param sourceString String to translate to the current locale.
* @return Translation of @p sourceString to the current locale in the
* specified @p context, or @p sourceString if there is no
* translation available.
*/
std::wstring TranslateWithContext(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& context, const std::wstring& sourceString);
/**
* Returns the translation of the specified string to the
* @link L10n::GetCurrentLocale() current locale@endlink based on the
* specified number.
*
* This is a JavaScript interface to L10n::TranslatePlural().
*
* @param pCmptPrivate JavaScript context.
* @param singularSourceString String to translate to the current locale,
* in English' singular form.
* @param pluralSourceString String to translate to the current locale, in
* English' plural form.
* @param number Number that determines the required form of the translation
* (or the English string if no translation is available).
* @return Translation of the source string to the current locale for the
* specified @p number, or either @p singularSourceString (if
* @p number is 1) or @p pluralSourceString (if @p number is not 1)
* if there is no translation available.
*/
std::wstring TranslatePlural(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& singularSourceString, const std::wstring& pluralSourceString, int number);
/**
* Returns the translation of the specified string to the
* @link L10n::GetCurrentLocale() current locale@endlink in the specified
* context, based on the specified number.
*
* This is a JavaScript interface to L10n::TranslatePluralWithContext().
*
* @param pCmptPrivate JavaScript context.
* @param context Context where the string is used. See
* http://www.gnu.org/software/gettext/manual/html_node/Contexts.html
* @param singularSourceString String to translate to the current locale,
* in English' singular form.
* @param pluralSourceString String to translate to the current locale, in
* English' plural form.
* @param number Number that determines the required form of the translation
* (or the English string if no translation is available). *
* @return Translation of the source string to the current locale in the
* specified @p context and for the specified @p number, or either
* @p singularSourceString (if @p number is 1) or
* @p pluralSourceString (if @p number is not 1) if there is no
* translation available.
*/
std::wstring TranslatePluralWithContext(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& context, const std::wstring& singularSourceString, const std::wstring& pluralSourceString, int number);
/**
* Translates a text line by line to the
* @link L10n::GetCurrentLocale() current locale@endlink.
*
* TranslateLines() is helpful when you need to translate a plain text file
* after you load it.
*
* This is a JavaScript interface to L10n::TranslateLines().
*
* @param pCmptPrivate JavaScript context.
* @param sourceString Text to translate to the current locale.
* @return Line by line translation of @p sourceString to the current
* locale. Some of the lines in the returned text may be in English
* because there was not translation available for them.
*/
std::wstring TranslateLines(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& sourceString);
/**
* Translate each of the strings of a JavaScript array to the
* @link L10n::GetCurrentLocale() current locale@endlink.
*
* This is a helper function that loops through the items of the input array
* and calls L10n::Translate() on each of them.
*
* @param pCmptPrivate JavaScript context.
* @param sourceArray JavaScript array of strings to translate to the
* current locale.
* @return Item by item translation of @p sourceArray to the current locale.
* Some of the items in the returned array may be in English because
* there was not translation available for them.
*/
std::vector<std::wstring> TranslateArray(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::vector<std::wstring>& sourceArray);
/**
* Returns the specified date converted to the local timezone using the specified date format.
*
* This is a JavaScript interface to
* L10n::FormatMillisecondsIntoDateString().
*
* @param pCmptPrivate JavaScript context.
* @param milliseconds Date specified as a UNIX timestamp in milliseconds
* (not seconds). If you have a JavaScript @c Date object, you can
* use @c Date.getTime() to obtain the UNIX time in milliseconds.
* @param formatString Date format string defined using ICU date formatting
* symbols. Usually, you internationalize the format string and
* get it translated before you pass it to
* FormatMillisecondsIntoDateString().
* @return String containing the specified date with the specified date
* format.
*
* @sa http://en.wikipedia.org/wiki/Unix_time
* @sa https://sites.google.com/site/icuprojectuserguide/formatparse/datetime?pli=1#TOC-Date-Field-Symbol-Table
*/
std::wstring FormatMillisecondsIntoDateStringLocal(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), UDate milliseconds, const std::wstring& formatString);
/**
* Returns the specified date in GMT using the specified date format.
*
* This is a JavaScript interface to
* L10n::FormatMillisecondsIntoDateString().
*
* @param pCmptPrivate JavaScript context.
* @param milliseconds Date specified as a UNIX timestamp in milliseconds
* (not seconds). If you have a JavaScript @c Date object, you can
* use @c Date.getTime() to obtain the UNIX time in milliseconds.
* @param formatString Date format string defined using ICU date formatting
* symbols. Usually, you internationalize the format string and
* get it translated before you pass it to
* FormatMillisecondsIntoDateString().
* @return String containing the specified date with the specified date
* format.
*
* @sa http://en.wikipedia.org/wiki/Unix_time
* @sa https://sites.google.com/site/icuprojectuserguide/formatparse/datetime?pli=1#TOC-Date-Field-Symbol-Table
*/
std::wstring FormatMillisecondsIntoDateStringGMT(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), UDate milliseconds, const std::wstring& formatString);
/**
* Returns the specified floating-point number as a string, with the number
* formatted as a decimal number using the
* @link L10n::GetCurrentLocale() current locale@endlink.
*
* This is a JavaScript interface to L10n::FormatDecimalNumberIntoString().
*
* @param pCmptPrivate JavaScript context.
* @param number Number to format.
* @return Decimal number formatted using the current locale.
*/
std::wstring FormatDecimalNumberIntoString(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), double number);
/**
* Returns an array of supported locale codes sorted alphabetically.
*
* A locale code is a string such as "de" or "pt_BR".
*
* If yours is a development copy (the 'config/dev.cfg' file is found in the
* virtual filesystem), the output array may include the special "long"
* locale code.
*
* This is a JavaScript interface to L10n::GetSupportedLocaleBaseNames().
*
* @param pCmptPrivate JavaScript context.
* @return Array of supported locale codes.
*
* @sa GetSupportedLocaleDisplayNames()
* @sa GetAllLocales()
* @sa GetCurrentLocale()
*
* @sa http://trac.wildfiregames.com/wiki/Implementation_of_Internationalization_and_Localization#LongStringsLocale
*/
std::vector<std::string> GetSupportedLocaleBaseNames(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate));
/**
* Returns an array of supported locale names sorted alphabetically by
* locale code.
*
* A locale code is a string such as "de" or "pt_BR".
*
* If yours is a development copy (the 'config/dev.cfg' file is found in the
* virtual filesystem), the output array may include the special "Long
* Strings" locale name.
*
* This is a JavaScript interface to L10n::GetSupportedLocaleDisplayNames().
*
* @param pCmptPrivate JavaScript context.
* @return Array of supported locale codes.
*
* @sa GetSupportedLocaleBaseNames()
*
* @sa http://trac.wildfiregames.com/wiki/Implementation_of_Internationalization_and_Localization#LongStringsLocale
*/
std::vector<std::wstring> GetSupportedLocaleDisplayNames(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate));
/**
* Returns the code of the current locale.
*
* A locale code is a string such as "de" or "pt_BR".
*
* This is a JavaScript interface to L10n::GetCurrentLocaleString().
*
* @param pCmptPrivate JavaScript context.
*
* @sa GetSupportedLocaleBaseNames()
* @sa GetAllLocales()
* @sa ReevaluateCurrentLocaleAndReload()
*/
std::string GetCurrentLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate));
/**
* Returns an array of locale codes supported by ICU.
*
* A locale code is a string such as "de" or "pt_BR".
*
* This is a JavaScript interface to L10n::GetAllLocales().
*
* @param pCmptPrivate JavaScript context.
* @return Array of supported locale codes.
*
* @sa GetSupportedLocaleBaseNames()
* @sa GetCurrentLocale()
*
* @sa http://www.icu-project.org/apiref/icu4c/classicu_1_1Locale.html#a073d70df8c9c8d119c0d42d70de24137
*/
std::vector<std::string> GetAllLocales(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate));
/**
* Returns the code of the recommended locale for the current user that the
* game supports.
*
* "That the game supports" means both that a translation file is available
* for that locale and that the locale code is either supported by ICU or
* the special "long" locale code.
*
* The mechanism to select a recommended locale follows this logic:
* 1. First see if the game supports the specified locale,\n
* @p configLocale.
* 2. Otherwise, check the system locale and see if the game supports\n
* that locale.
* 3. Else, return the default locale, 'en_US'.
*
* This is a JavaScript interface to L10n::GetDictionaryLocale(std::string).
*
* @param pCmptPrivate JavaScript context.
* @param configLocale Locale to check for support first. Pass an empty
* string to check the system locale directly.
* @return Code of a locale that the game supports.
*
* @sa http://trac.wildfiregames.com/wiki/Implementation_of_Internationalization_and_Localization#LongStringsLocale
*/
std::string GetDictionaryLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& configLocale);
/**
* Returns an array of paths to files in the virtual filesystem that provide
* translations for the specified locale code.
*
* This is a JavaScript interface to L10n::GetDictionariesForLocale().
*
* @param pCmptPrivate JavaScript context.
* @param locale Locale code.
* @return Array of paths to files in the virtual filesystem that provide
* translations for @p locale.
*/
std::vector<std::wstring> GetDictionariesForLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale);
/**
* Returns the ISO-639 language code of the specified locale code.
*
* For example, if you specify the 'en_US' locate, it returns 'en'.
*
* This is a JavaScript interface to L10n::GetLocaleLanguage().
*
* @param pCmptPrivate JavaScript context.
* @param locale Locale code.
* @return Language code.
*
* @sa http://www.icu-project.org/apiref/icu4c/classicu_1_1Locale.html#af36d821adced72a870d921ebadd0ca93
*/
std::string GetLocaleLanguage(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale);
/**
* Returns the programmatic code of the entire locale without keywords.
*
* This is a JavaScript interface to L10n::GetLocaleBaseName().
*
* @param pCmptPrivate JavaScript context.
* @param locale Locale code.
* @return Locale code without keywords.
*
* @sa http://www.icu-project.org/apiref/icu4c/classicu_1_1Locale.html#a4c1acbbdf95dc15599db5f322fa4c4d0
*/
std::string GetLocaleBaseName(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale);
/**
* Returns the ISO-3166 country code of the specified locale code.
*
* For example, if you specify the 'en_US' locate, it returns 'US'.
*
* This is a JavaScript interface to L10n::GetLocaleCountry().
*
* @param pCmptPrivate JavaScript context.
* @param locale Locale code.
* @return Country code.
*
* @sa http://www.icu-project.org/apiref/icu4c/classicu_1_1Locale.html#ae3f1fc415c00d4f0ab33288ceadccbf9
*/
std::string GetLocaleCountry(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale);
/**
* Returns the ISO-15924 abbreviation script code of the specified locale code.
*
* This is a JavaScript interface to L10n::GetLocaleScript().
*
* @param pCmptPrivate JavaScript context.
* @param locale Locale code.
* @return Script code.
*
* @sa http://www.icu-project.org/apiref/icu4c/classicu_1_1Locale.html#a5e0145a339d30794178a1412dcc55abe
*/
std::string GetLocaleScript(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale);
std::wstring GetFallbackToAvailableDictLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale);
/**
* Returns @c true if the current locale is the special "Long Strings"
* locale. It returns @c false otherwise.
*
* This is a JavaScript interface to L10n::UseLongStrings().
*
* @param pCmptPrivate JavaScript context. *
* @return Whether the current locale is the special "Long Strings"
* (@c true) or not (@c false).
*/
bool UseLongStrings(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate));
/**
* Returns @c true if the locale is supported by both ICU and the game. It
* returns @c false otherwise.
*
* It returns @c true if both of these conditions are true:
* 1. ICU has resources for that locale (which also ensures it's a valid\n
* locale string).
* 2. Either a dictionary for language_country or for language is\n
* available.
*
* This is a JavaScript interface to L10n::ValidateLocale(const std::string&).
*
* @param pCmptPrivate JavaScript context.
* @param locale Locale to check.
* @return Whether @p locale is supported by both ICU and the game (@c true)
* or not (@c false).
*/
bool ValidateLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale);
/**
* Saves the specified locale in the game configuration file.
*
* The next time that the game starts, the game uses the locale in the
* configuration file if there are translation files available for it.
*
* SaveLocale() checks the validity of the specified locale with
* ValidateLocale(). If the specified locale is not valid, SaveLocale()
* returns @c false and does not save the locale to the configuration file.
*
* This is a JavaScript interface to L10n::SaveLocale().
*
* @param pCmptPrivate JavaScript context.
* @param locale Locale to save to the configuration file.
* @return Whether the specified locale is valid (@c true) or not
* (@c false).
*/
bool SaveLocale(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& locale);
/**
* Determines the best, supported locale for the current user, makes it the
* current game locale and reloads the translations dictionary with
* translations for that locale.
*
* To determine the best locale, ReevaluateCurrentLocaleAndReload():
* 1. Checks the user game configuration.
* 2. If the locale is not defined there, it checks the system locale.
* 3. If none of those locales are supported by the game, the default\n
* locale, 'en_US', is used.
*
* This is a JavaScript interface to L10n::ReevaluateCurrentLocaleAndReload().
*
* @param pCmptPrivate JavaScript context.
*
* @sa GetCurrentLocale()
*/
void ReevaluateCurrentLocaleAndReload(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate));
} }
#endif // INCLUDED_JSINTERFACE_L10N #endif // INCLUDED_JSINTERFACE_L10N

View file

@ -44,7 +44,7 @@ public:
virtual void SendIqChangeStateGame(const std::string& nbp, const std::string& players) = 0; virtual void SendIqChangeStateGame(const std::string& nbp, const std::string& players) = 0;
virtual void SendIqLobbyAuth(const std::string& to, const std::string& token) = 0; virtual void SendIqLobbyAuth(const std::string& to, const std::string& token) = 0;
virtual void SetNick(const std::string& nick) = 0; virtual void SetNick(const std::string& nick) = 0;
virtual void GetNick(std::string& nick) = 0; virtual std::string GetNick() = 0;
virtual void kick(const std::string& nick, const std::string& reason) = 0; virtual void kick(const std::string& nick, const std::string& reason) = 0;
virtual void ban(const std::string& nick, const std::string& reason) = 0; virtual void ban(const std::string& nick, const std::string& reason) = 0;
virtual void SetPresence(const std::string& presence) = 0; virtual void SetPresence(const std::string& presence) = 0;
@ -52,10 +52,10 @@ public:
virtual const char* GetRole(const std::string& nickname) = 0; virtual const char* GetRole(const std::string& nickname) = 0;
virtual std::wstring GetRating(const std::string& nickname) = 0; virtual std::wstring GetRating(const std::string& nickname) = 0;
virtual const std::wstring& GetSubject() = 0; virtual const std::wstring& GetSubject() = 0;
virtual void GUIGetPlayerList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0; virtual JS::Value GUIGetPlayerList(const ScriptInterface& scriptInterface) = 0;
virtual void GUIGetGameList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0; virtual JS::Value GUIGetGameList(const ScriptInterface& scriptInterface) = 0;
virtual void GUIGetBoardList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0; virtual JS::Value GUIGetBoardList(const ScriptInterface& scriptInterface) = 0;
virtual void GUIGetProfile(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0; virtual JS::Value GUIGetProfile(const ScriptInterface& scriptInterface) = 0;
virtual JS::Value GuiPollNewMessages(const ScriptInterface& scriptInterface) = 0; virtual JS::Value GuiPollNewMessages(const ScriptInterface& scriptInterface) = 0;
virtual JS::Value GuiPollHistoricMessages(const ScriptInterface& scriptInterface) = 0; virtual JS::Value GuiPollHistoricMessages(const ScriptInterface& scriptInterface) = 0;

View file

@ -559,11 +559,12 @@ void XmppClient::handleOOB(const glooxwrapper::JID&, const glooxwrapper::OOB&)
* *
* @return A JS array containing all known players and their presences * @return A JS array containing all known players and their presences
*/ */
void XmppClient::GUIGetPlayerList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) JS::Value XmppClient::GUIGetPlayerList(const ScriptInterface& scriptInterface)
{ {
ScriptRequest rq(scriptInterface); ScriptRequest rq(scriptInterface);
ScriptInterface::CreateArray(rq, ret); JS::RootedValue ret(rq.cx);
ScriptInterface::CreateArray(rq, &ret);
int j = 0; int j = 0;
for (const std::pair<const glooxwrapper::string, SPlayer>& p : m_PlayerMap) for (const std::pair<const glooxwrapper::string, SPlayer>& p : m_PlayerMap)
@ -580,6 +581,7 @@ void XmppClient::GUIGetPlayerList(const ScriptInterface& scriptInterface, JS::Mu
scriptInterface.SetPropertyInt(ret, j++, player); scriptInterface.SetPropertyInt(ret, j++, player);
} }
return ret;
} }
/** /**
@ -587,11 +589,12 @@ void XmppClient::GUIGetPlayerList(const ScriptInterface& scriptInterface, JS::Mu
* *
* @return A JS array containing all known games * @return A JS array containing all known games
*/ */
void XmppClient::GUIGetGameList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) JS::Value XmppClient::GUIGetGameList(const ScriptInterface& scriptInterface)
{ {
ScriptRequest rq(scriptInterface); ScriptRequest rq(scriptInterface);
ScriptInterface::CreateArray(rq, ret); JS::RootedValue ret(rq.cx);
ScriptInterface::CreateArray(rq, &ret);
int j = 0; int j = 0;
const char* stats[] = { "name", "hostUsername", "state", "hasPassword", const char* stats[] = { "name", "hostUsername", "state", "hasPassword",
@ -608,6 +611,7 @@ void XmppClient::GUIGetGameList(const ScriptInterface& scriptInterface, JS::Muta
scriptInterface.SetPropertyInt(ret, j++, game); scriptInterface.SetPropertyInt(ret, j++, game);
} }
return ret;
} }
/** /**
@ -615,11 +619,12 @@ void XmppClient::GUIGetGameList(const ScriptInterface& scriptInterface, JS::Muta
* *
* @return A JS array containing all known leaderboard data * @return A JS array containing all known leaderboard data
*/ */
void XmppClient::GUIGetBoardList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) JS::Value XmppClient::GUIGetBoardList(const ScriptInterface& scriptInterface)
{ {
ScriptRequest rq(scriptInterface); ScriptRequest rq(scriptInterface);
ScriptInterface::CreateArray(rq, ret); JS::RootedValue ret(rq.cx);
ScriptInterface::CreateArray(rq, &ret);
int j = 0; int j = 0;
const char* attributes[] = { "name", "rank", "rating" }; const char* attributes[] = { "name", "rank", "rating" };
@ -634,6 +639,7 @@ void XmppClient::GUIGetBoardList(const ScriptInterface& scriptInterface, JS::Mut
scriptInterface.SetPropertyInt(ret, j++, board); scriptInterface.SetPropertyInt(ret, j++, board);
} }
return ret;
} }
/** /**
@ -641,11 +647,12 @@ void XmppClient::GUIGetBoardList(const ScriptInterface& scriptInterface, JS::Mut
* *
* @return A JS array containing the specific user's profile data * @return A JS array containing the specific user's profile data
*/ */
void XmppClient::GUIGetProfile(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) JS::Value XmppClient::GUIGetProfile(const ScriptInterface& scriptInterface)
{ {
ScriptRequest rq(scriptInterface); ScriptRequest rq(scriptInterface);
ScriptInterface::CreateArray(rq, ret); JS::RootedValue ret(rq.cx);
ScriptInterface::CreateArray(rq, &ret);
int j = 0; int j = 0;
const char* stats[] = { "player", "rating", "totalGamesPlayed", "highestRating", "wins", "losses", "rank" }; const char* stats[] = { "player", "rating", "totalGamesPlayed", "highestRating", "wins", "losses", "rank" };
@ -660,6 +667,7 @@ void XmppClient::GUIGetProfile(const ScriptInterface& scriptInterface, JS::Mutab
scriptInterface.SetPropertyInt(ret, j++, profile); scriptInterface.SetPropertyInt(ret, j++, profile);
} }
return ret;
} }
/***************************************************** /*****************************************************
@ -1157,12 +1165,10 @@ void XmppClient::SetNick(const std::string& nick)
/** /**
* Get current nickname. * Get current nickname.
*
* @param nick Variable to store the nickname in.
*/ */
void XmppClient::GetNick(std::string& nick) std::string XmppClient::GetNick()
{ {
nick = m_mucRoom->nick().to_string(); return m_mucRoom->nick().to_string();
} }
/** /**

View file

@ -91,7 +91,7 @@ public:
void SendIqChangeStateGame(const std::string& nbp, const std::string& players); void SendIqChangeStateGame(const std::string& nbp, const std::string& players);
void SendIqLobbyAuth(const std::string& to, const std::string& token); void SendIqLobbyAuth(const std::string& to, const std::string& token);
void SetNick(const std::string& nick); void SetNick(const std::string& nick);
void GetNick(std::string& nick); std::string GetNick();
void kick(const std::string& nick, const std::string& reason); void kick(const std::string& nick, const std::string& reason);
void ban(const std::string& nick, const std::string& reason); void ban(const std::string& nick, const std::string& reason);
void SetPresence(const std::string& presence); void SetPresence(const std::string& presence);
@ -100,10 +100,10 @@ public:
std::wstring GetRating(const std::string& nickname); std::wstring GetRating(const std::string& nickname);
const std::wstring& GetSubject(); const std::wstring& GetSubject();
void GUIGetPlayerList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret); JS::Value GUIGetPlayerList(const ScriptInterface& scriptInterface);
void GUIGetGameList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret); JS::Value GUIGetGameList(const ScriptInterface& scriptInterface);
void GUIGetBoardList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret); JS::Value GUIGetBoardList(const ScriptInterface& scriptInterface);
void GUIGetProfile(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret); JS::Value GUIGetProfile(const ScriptInterface& scriptInterface);
void SendStunEndpointToHost(const StunClient::StunEndpoint& stunEndpoint, const std::string& hostJID); void SendStunEndpointToHost(const StunClient::StunEndpoint& stunEndpoint, const std::string& hostJID);

View file

@ -26,68 +26,31 @@
#include "ps/CLogger.h" #include "ps/CLogger.h"
#include "ps/CStr.h" #include "ps/CStr.h"
#include "ps/Util.h" #include "ps/Util.h"
#include "scriptinterface/FunctionWrapper.h"
#include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptInterface.h"
#include "third_party/encryption/pkcs5_pbkdf2.h" #include "third_party/encryption/pkcs5_pbkdf2.h"
#include <string> #include <string>
void JSI_Lobby::RegisterScriptFunctions(const ScriptInterface& scriptInterface) namespace JSI_Lobby
{ {
// Lobby functions bool HasXmppClient()
scriptInterface.RegisterFunction<bool, &JSI_Lobby::HasXmppClient>("HasXmppClient");
scriptInterface.RegisterFunction<void, bool, &JSI_Lobby::SetRankedGame>("SetRankedGame");
#if CONFIG2_LOBBY // Allow the lobby to be disabled
scriptInterface.RegisterFunction<void, std::wstring, std::wstring, std::wstring, std::wstring, int, &JSI_Lobby::StartXmppClient>("StartXmppClient");
scriptInterface.RegisterFunction<void, std::wstring, std::wstring, &JSI_Lobby::StartRegisterXmppClient>("StartRegisterXmppClient");
scriptInterface.RegisterFunction<void, &JSI_Lobby::StopXmppClient>("StopXmppClient");
scriptInterface.RegisterFunction<void, &JSI_Lobby::ConnectXmppClient>("ConnectXmppClient");
scriptInterface.RegisterFunction<void, &JSI_Lobby::DisconnectXmppClient>("DisconnectXmppClient");
scriptInterface.RegisterFunction<bool, &JSI_Lobby::IsXmppClientConnected>("IsXmppClientConnected");
scriptInterface.RegisterFunction<void, &JSI_Lobby::SendGetBoardList>("SendGetBoardList");
scriptInterface.RegisterFunction<void, std::wstring, &JSI_Lobby::SendGetProfile>("SendGetProfile");
scriptInterface.RegisterFunction<void, JS::HandleValue, &JSI_Lobby::SendRegisterGame>("SendRegisterGame");
scriptInterface.RegisterFunction<void, JS::HandleValue, &JSI_Lobby::SendGameReport>("SendGameReport");
scriptInterface.RegisterFunction<void, &JSI_Lobby::SendUnregisterGame>("SendUnregisterGame");
scriptInterface.RegisterFunction<void, std::wstring, std::wstring, &JSI_Lobby::SendChangeStateGame>("SendChangeStateGame");
scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::GetPlayerList>("GetPlayerList");
scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::GetGameList>("GetGameList");
scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::GetBoardList>("GetBoardList");
scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::GetProfile>("GetProfile");
scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::LobbyGuiPollNewMessages>("LobbyGuiPollNewMessages");
scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::LobbyGuiPollHistoricMessages>("LobbyGuiPollHistoricMessages");
scriptInterface.RegisterFunction<bool, &JSI_Lobby::LobbyGuiPollHasPlayerListUpdate>("LobbyGuiPollHasPlayerListUpdate");
scriptInterface.RegisterFunction<void, std::wstring, &JSI_Lobby::LobbySendMessage>("LobbySendMessage");
scriptInterface.RegisterFunction<void, std::wstring, &JSI_Lobby::LobbySetPlayerPresence>("LobbySetPlayerPresence");
scriptInterface.RegisterFunction<void, std::wstring, &JSI_Lobby::LobbySetNick>("LobbySetNick");
scriptInterface.RegisterFunction<std::wstring, &JSI_Lobby::LobbyGetNick>("LobbyGetNick");
scriptInterface.RegisterFunction<void, std::wstring, std::wstring, &JSI_Lobby::LobbyKick>("LobbyKick");
scriptInterface.RegisterFunction<void, std::wstring, std::wstring, &JSI_Lobby::LobbyBan>("LobbyBan");
scriptInterface.RegisterFunction<const char*, std::wstring, &JSI_Lobby::LobbyGetPlayerPresence>("LobbyGetPlayerPresence");
scriptInterface.RegisterFunction<const char*, std::wstring, &JSI_Lobby::LobbyGetPlayerRole>("LobbyGetPlayerRole");
scriptInterface.RegisterFunction<std::wstring, std::wstring, &JSI_Lobby::LobbyGetPlayerRating>("LobbyGetPlayerRating");
scriptInterface.RegisterFunction<std::wstring, std::wstring, std::wstring, &JSI_Lobby::EncryptPassword>("EncryptPassword");
scriptInterface.RegisterFunction<std::wstring, &JSI_Lobby::LobbyGetRoomSubject>("LobbyGetRoomSubject");
#endif // CONFIG2_LOBBY
}
bool JSI_Lobby::HasXmppClient(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate))
{ {
return g_XmppClient; return g_XmppClient;
} }
void JSI_Lobby::SetRankedGame(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), bool isRanked) void SetRankedGame(bool isRanked)
{ {
g_rankedGame = isRanked; g_rankedGame = isRanked;
} }
#if CONFIG2_LOBBY #if CONFIG2_LOBBY
void JSI_Lobby::StartXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& username, const std::wstring& password, const std::wstring& room, const std::wstring& nick, int historyRequestSize) void StartXmppClient(const ScriptRequest& rq, const std::wstring& username, const std::wstring& password, const std::wstring& room, const std::wstring& nick, int historyRequestSize)
{ {
if (g_XmppClient) if (g_XmppClient)
{ {
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call StartXmppClient with an already initialized XmppClient!"); ScriptException::Raise(rq, "Cannot call StartXmppClient with an already initialized XmppClient!");
return; return;
} }
@ -104,11 +67,10 @@ void JSI_Lobby::StartXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate, cons
g_rankedGame = true; g_rankedGame = true;
} }
void JSI_Lobby::StartRegisterXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& username, const std::wstring& password) void StartRegisterXmppClient(const ScriptRequest& rq, const std::wstring& username, const std::wstring& password)
{ {
if (g_XmppClient) if (g_XmppClient)
{ {
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call StartRegisterXmppClient with an already initialized XmppClient!"); ScriptException::Raise(rq, "Cannot call StartRegisterXmppClient with an already initialized XmppClient!");
return; return;
} }
@ -124,11 +86,10 @@ void JSI_Lobby::StartRegisterXmppClient(ScriptInterface::CmptPrivate* pCmptPriva
true); true);
} }
void JSI_Lobby::StopXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate) void StopXmppClient(const ScriptRequest& rq)
{ {
if (!g_XmppClient) if (!g_XmppClient)
{ {
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call StopXmppClient without an initialized XmppClient!"); ScriptException::Raise(rq, "Cannot call StopXmppClient without an initialized XmppClient!");
return; return;
} }
@ -137,79 +98,20 @@ void JSI_Lobby::StopXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate)
g_rankedGame = false; g_rankedGame = false;
} }
void JSI_Lobby::ConnectXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate) ////////////////////////////////////////////////
////////////////////////////////////////////////
IXmppClient* XmppGetter(const ScriptRequest&, JS::CallArgs&)
{ {
if (!g_XmppClient) if (!g_XmppClient)
{ {
ScriptRequest rq(pCmptPrivate->pScriptInterface); LOGERROR("Cannot use XMPPClient functions without an initialized XmppClient!");
ScriptException::Raise(rq, "Cannot call ConnectXmppClient without an initialized XmppClient!"); return nullptr;
return;
} }
return g_XmppClient;
g_XmppClient->connect();
} }
void JSI_Lobby::DisconnectXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate) void SendRegisterGame(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue data)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call DisconnectXmppClient without an initialized XmppClient!");
return;
}
g_XmppClient->disconnect();
}
bool JSI_Lobby::IsXmppClientConnected(ScriptInterface::CmptPrivate* pCmptPrivate)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call IsXmppClientConnected without an initialized XmppClient!");
return false;
}
return g_XmppClient->isConnected();
}
void JSI_Lobby::SendGetBoardList(ScriptInterface::CmptPrivate* pCmptPrivate)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call SendGetBoardList without an initialized XmppClient!");
return;
}
g_XmppClient->SendIqGetBoardList();
}
void JSI_Lobby::SendGetProfile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& player)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call SendGetProfile without an initialized XmppClient!");
return;
}
g_XmppClient->SendIqGetProfile(utf8_from_wstring(player));
}
void JSI_Lobby::SendGameReport(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue data)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call SendGameReport without an initialized XmppClient!");
return;
}
g_XmppClient->SendIqGameReport(*(pCmptPrivate->pScriptInterface), data);
}
void JSI_Lobby::SendRegisterGame(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue data)
{ {
if (!g_XmppClient) if (!g_XmppClient)
{ {
@ -228,235 +130,15 @@ void JSI_Lobby::SendRegisterGame(ScriptInterface::CmptPrivate* pCmptPrivate, JS:
g_XmppClient->SendIqRegisterGame(*(pCmptPrivate->pScriptInterface), data); g_XmppClient->SendIqRegisterGame(*(pCmptPrivate->pScriptInterface), data);
} }
void JSI_Lobby::SendUnregisterGame(ScriptInterface::CmptPrivate* pCmptPrivate) // Unlike other functions, this one just returns Undefined if XmppClient isn't initialised.
{ JS::Value GuiPollNewMessages(const ScriptInterface& scriptInterface)
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call SendUnregisterGame without an initialized XmppClient!");
return;
}
g_XmppClient->SendIqUnregisterGame();
}
void JSI_Lobby::SendChangeStateGame(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nbp, const std::wstring& players)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call SendChangeStateGame without an initialized XmppClient!");
return;
}
g_XmppClient->SendIqChangeStateGame(utf8_from_wstring(nbp), utf8_from_wstring(players));
}
JS::Value JSI_Lobby::GetPlayerList(ScriptInterface::CmptPrivate* pCmptPrivate)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
if (!g_XmppClient)
{
ScriptException::Raise(rq, "Cannot call GetPlayerList without an initialized XmppClient!");
return JS::UndefinedValue();
}
JS::RootedValue playerList(rq.cx);
g_XmppClient->GUIGetPlayerList(*(pCmptPrivate->pScriptInterface), &playerList);
return playerList;
}
JS::Value JSI_Lobby::GetGameList(ScriptInterface::CmptPrivate* pCmptPrivate)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
if (!g_XmppClient)
{
ScriptException::Raise(rq, "Cannot call GetGameList without an initialized XmppClient!");
return JS::UndefinedValue();
}
JS::RootedValue gameList(rq.cx);
g_XmppClient->GUIGetGameList(*(pCmptPrivate->pScriptInterface), &gameList);
return gameList;
}
JS::Value JSI_Lobby::GetBoardList(ScriptInterface::CmptPrivate* pCmptPrivate)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
if (!g_XmppClient)
{
ScriptException::Raise(rq, "Cannot call GetBoardList without an initialized XmppClient!");
return JS::UndefinedValue();
}
JS::RootedValue boardList(rq.cx);
g_XmppClient->GUIGetBoardList(*(pCmptPrivate->pScriptInterface), &boardList);
return boardList;
}
JS::Value JSI_Lobby::GetProfile(ScriptInterface::CmptPrivate* pCmptPrivate)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
if (!g_XmppClient)
{
ScriptException::Raise(rq, "Cannot call GetProfile without an initialized XmppClient!");
return JS::UndefinedValue();
}
JS::RootedValue profileFetch(rq.cx);
g_XmppClient->GUIGetProfile(*(pCmptPrivate->pScriptInterface), &profileFetch);
return profileFetch;
}
bool JSI_Lobby::LobbyGuiPollHasPlayerListUpdate(ScriptInterface::CmptPrivate* pCmptPrivate)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbyGuiPollHasPlayerListUpdate without an initialized XmppClient!");
return false;
}
return g_XmppClient->GuiPollHasPlayerListUpdate();
}
JS::Value JSI_Lobby::LobbyGuiPollNewMessages(ScriptInterface::CmptPrivate* pCmptPrivate)
{ {
if (!g_XmppClient) if (!g_XmppClient)
return JS::UndefinedValue(); return JS::UndefinedValue();
return g_XmppClient->GuiPollNewMessages(*(pCmptPrivate->pScriptInterface)); return g_XmppClient->GuiPollNewMessages(scriptInterface);
} }
JS::Value JSI_Lobby::LobbyGuiPollHistoricMessages(ScriptInterface::CmptPrivate* pCmptPrivate)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbyGuiPollHistoricMessages without an initialized XmppClient!");
return JS::UndefinedValue();
}
return g_XmppClient->GuiPollHistoricMessages(*(pCmptPrivate->pScriptInterface));
}
void JSI_Lobby::LobbySendMessage(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& message)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbySendMessage without an initialized XmppClient!");
return;
}
g_XmppClient->SendMUCMessage(utf8_from_wstring(message));
}
void JSI_Lobby::LobbySetPlayerPresence(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& presence)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbySetPlayerPresence without an initialized XmppClient!");
return;
}
g_XmppClient->SetPresence(utf8_from_wstring(presence));
}
void JSI_Lobby::LobbySetNick(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nick)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbySetNick without an initialized XmppClient!");
return;
}
g_XmppClient->SetNick(utf8_from_wstring(nick));
}
std::wstring JSI_Lobby::LobbyGetNick(ScriptInterface::CmptPrivate* pCmptPrivate)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbyGetNick without an initialized XmppClient!");
return std::wstring();
}
std::string nick;
g_XmppClient->GetNick(nick);
return wstring_from_utf8(nick);
}
void JSI_Lobby::LobbyKick(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nick, const std::wstring& reason)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbyKick without an initialized XmppClient!");
return;
}
g_XmppClient->kick(utf8_from_wstring(nick), utf8_from_wstring(reason));
}
void JSI_Lobby::LobbyBan(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nick, const std::wstring& reason)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbyBan without an initialized XmppClient!");
return;
}
g_XmppClient->ban(utf8_from_wstring(nick), utf8_from_wstring(reason));
}
const char* JSI_Lobby::LobbyGetPlayerPresence(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nickname)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbyGetPlayerPresence without an initialized XmppClient!");
return "";
}
return g_XmppClient->GetPresence(utf8_from_wstring(nickname));
}
const char* JSI_Lobby::LobbyGetPlayerRole(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nickname)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbyGetPlayerRole without an initialized XmppClient!");
return "";
}
return g_XmppClient->GetRole(utf8_from_wstring(nickname));
}
std::wstring JSI_Lobby::LobbyGetPlayerRating(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nickname)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbyGetPlayerRating without an initialized XmppClient!");
return std::wstring();
}
return g_XmppClient->GetRating(utf8_from_wstring(nickname));
}
// Non-public secure PBKDF2 hash function with salting and 1,337 iterations // Non-public secure PBKDF2 hash function with salting and 1,337 iterations
// //
@ -470,7 +152,7 @@ std::wstring JSI_Lobby::LobbyGetPlayerRating(ScriptInterface::CmptPrivate* pCmpt
// the new hashing method. Dropping the old hashing code can only be done either by giving users // the new hashing method. Dropping the old hashing code can only be done either by giving users
// a way to reset their password, or by keeping track of successful password updates and dropping // a way to reset their password, or by keeping track of successful password updates and dropping
// old unused accounts after some time. // old unused accounts after some time.
std::string JSI_Lobby::EncryptPassword(const std::string& password, const std::string& username) std::string EncryptPassword(const std::string& password, const std::string& username)
{ {
ENSURE(sodium_init() >= 0); ENSURE(sodium_init() >= 0);
@ -500,21 +182,51 @@ std::string JSI_Lobby::EncryptPassword(const std::string& password, const std::s
return CStr(Hexify(encrypted, DIGESTSIZE)).UpperCase(); return CStr(Hexify(encrypted, DIGESTSIZE)).UpperCase();
} }
std::wstring JSI_Lobby::EncryptPassword(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& pass, const std::wstring& user)
{
return wstring_from_utf8(JSI_Lobby::EncryptPassword(utf8_from_wstring(pass), utf8_from_wstring(user)));
}
std::wstring JSI_Lobby::LobbyGetRoomSubject(ScriptInterface::CmptPrivate* pCmptPrivate)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbyGetRoomSubject without an initialized XmppClient!");
return std::wstring();
}
return g_XmppClient->GetSubject();
}
#endif #endif
void RegisterScriptFunctions(const ScriptRequest& rq)
{
// Lobby functions
ScriptFunction::Register<&HasXmppClient>(rq, "HasXmppClient");
ScriptFunction::Register<&SetRankedGame>(rq, "SetRankedGame");
#if CONFIG2_LOBBY // Allow the lobby to be disabled
ScriptFunction::Register<&StartXmppClient>(rq, "StartXmppClient");
ScriptFunction::Register<&StartRegisterXmppClient>(rq, "StartRegisterXmppClient");
ScriptFunction::Register<&StopXmppClient>(rq, "StopXmppClient");
#define REGISTER_XMPP(func, name) \
ScriptFunction::Register<&IXmppClient::func, &XmppGetter>(rq, name)
REGISTER_XMPP(connect, "ConnectXmppClient");
REGISTER_XMPP(disconnect, "DisconnectXmppClient");
REGISTER_XMPP(isConnected, "IsXmppClientConnected");
REGISTER_XMPP(SendIqGetBoardList, "SendGetBoardList");
REGISTER_XMPP(SendIqGetProfile, "SendGetProfile");
REGISTER_XMPP(SendIqGameReport, "SendGameReport");
ScriptFunction::Register<&SendRegisterGame>(rq, "SendRegisterGame");
REGISTER_XMPP(SendIqUnregisterGame, "SendUnregisterGame");
REGISTER_XMPP(SendIqChangeStateGame, "SendChangeStateGame");
REGISTER_XMPP(GUIGetPlayerList, "GetPlayerList");
REGISTER_XMPP(GUIGetGameList, "GetGameList");
REGISTER_XMPP(GUIGetBoardList, "GetBoardList");
REGISTER_XMPP(GUIGetProfile, "GetProfile");
ScriptFunction::Register<&GuiPollNewMessages>(rq, "LobbyGuiPollNewMessages");
REGISTER_XMPP(GuiPollHistoricMessages, "LobbyGuiPollHistoricMessages");
REGISTER_XMPP(GuiPollHasPlayerListUpdate, "LobbyGuiPollHasPlayerListUpdate");
REGISTER_XMPP(SendMUCMessage, "LobbySendMessage");
REGISTER_XMPP(SetPresence, "LobbySetPlayerPresence");
REGISTER_XMPP(SetNick, "LobbySetNick");
REGISTER_XMPP(GetNick, "LobbyGetNick");
REGISTER_XMPP(kick, "LobbyKick");
REGISTER_XMPP(ban, "LobbyBan");
REGISTER_XMPP(GetPresence, "LobbyGetPlayerPresence");
REGISTER_XMPP(GetRole, "LobbyGetPlayerRole");
REGISTER_XMPP(GetRating, "LobbyGetPlayerRating");
REGISTER_XMPP(GetSubject, "LobbyGetRoomSubject");
#undef REGISTER_XMPP
ScriptFunction::Register<&EncryptPassword>(rq, "EncryptPassword");
#endif // CONFIG2_LOBBY
}
}

View file

@ -18,56 +18,11 @@
#ifndef INCLUDED_JSI_LOBBY #ifndef INCLUDED_JSI_LOBBY
#define INCLUDED_JSI_LOBBY #define INCLUDED_JSI_LOBBY
#include "lib/config2.h" class ScriptRequest;
#include "scriptinterface/ScriptInterface.h"
#include <string>
namespace JSI_Lobby namespace JSI_Lobby
{ {
void RegisterScriptFunctions(const ScriptInterface& scriptInterface); void RegisterScriptFunctions(const ScriptRequest& rq);
bool HasXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate);
bool IsRankedGame(ScriptInterface::CmptPrivate* pCmptPrivate);
void SetRankedGame(ScriptInterface::CmptPrivate* pCmptPrivate, bool isRanked);
#if CONFIG2_LOBBY
void StartXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& username, const std::wstring& password, const std::wstring& room, const std::wstring& nick, int historyRequestSize);
void StartRegisterXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& username, const std::wstring& password);
void StopXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate);
void ConnectXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate);
void DisconnectXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate);
bool IsXmppClientConnected(ScriptInterface::CmptPrivate* pCmptPrivate);
void SendGetBoardList(ScriptInterface::CmptPrivate* pCmptPrivate);
void SendGetProfile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& player);
void SendGameReport(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue data);
void SendRegisterGame(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue data);
void SendUnregisterGame(ScriptInterface::CmptPrivate* pCmptPrivate);
void SendChangeStateGame(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nbp, const std::wstring& players);
JS::Value GetPlayerList(ScriptInterface::CmptPrivate* pCmptPrivate);
JS::Value GetGameList(ScriptInterface::CmptPrivate* pCmptPrivate);
JS::Value GetBoardList(ScriptInterface::CmptPrivate* pCmptPrivate);
JS::Value GetProfile(ScriptInterface::CmptPrivate* pCmptPrivate);
JS::Value LobbyGuiPollNewMessages(ScriptInterface::CmptPrivate* pCmptPrivate);
JS::Value LobbyGuiPollHistoricMessages(ScriptInterface::CmptPrivate* pCmptPrivate);
bool LobbyGuiPollHasPlayerListUpdate(ScriptInterface::CmptPrivate* pCmptPrivate);
void LobbySendMessage(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& message);
void LobbySetPlayerPresence(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& presence);
void LobbySetNick(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nick);
std::wstring LobbyGetNick(ScriptInterface::CmptPrivate* pCmptPrivate);
void LobbyKick(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nick, const std::wstring& reason);
void LobbyBan(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nick, const std::wstring& reason);
const char* LobbyGetPlayerPresence(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nickname);
const char* LobbyGetPlayerRole(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nickname);
std::wstring LobbyGetPlayerRating(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nickname);
std::wstring LobbyGetRoomSubject(ScriptInterface::CmptPrivate* pCmptPrivate);
// Non-public secure PBKDF2 hash function with salting and 1,337 iterations
std::string EncryptPassword(const std::string& password, const std::string& username);
// Public hash interface.
std::wstring EncryptPassword(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& pass, const std::wstring& user);
#endif // CONFIG2_LOBBY
} }
#endif // INCLUDED_JSI_LOBBY #endif // INCLUDED_JSI_LOBBY

View file

@ -31,31 +31,34 @@
#include "ps/Game.h" #include "ps/Game.h"
#include "ps/GUID.h" #include "ps/GUID.h"
#include "ps/Util.h" #include "ps/Util.h"
#include "scriptinterface/FunctionWrapper.h"
#include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptInterface.h"
#include "third_party/encryption/pkcs5_pbkdf2.h" #include "third_party/encryption/pkcs5_pbkdf2.h"
u16 JSI_Network::GetDefaultPort(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) namespace JSI_Network
{
u16 GetDefaultPort()
{ {
return PS_DEFAULT_PORT; return PS_DEFAULT_PORT;
} }
bool JSI_Network::IsNetController(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) bool IsNetController()
{ {
return !!g_NetClient && g_NetClient->IsController(); return !!g_NetClient && g_NetClient->IsController();
} }
bool JSI_Network::HasNetServer(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) bool HasNetServer()
{ {
return !!g_NetServer; return !!g_NetServer;
} }
bool JSI_Network::HasNetClient(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) bool HasNetClient()
{ {
return !!g_NetClient; return !!g_NetClient;
} }
CStr JSI_Network::HashPassword(const CStr& password) CStr HashPassword(const CStr& password)
{ {
if (password.empty()) if (password.empty())
return password; return password;
@ -84,7 +87,7 @@ CStr JSI_Network::HashPassword(const CStr& password)
return CStr(Hexify(encrypted, DIGESTSIZE)).UpperCase(); return CStr(Hexify(encrypted, DIGESTSIZE)).UpperCase();
} }
void JSI_Network::StartNetworkHost(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& playerName, const u16 serverPort, const CStr& hostLobbyName, bool useSTUN, const CStr& password) void StartNetworkHost(const ScriptRequest& rq, const CStrW& playerName, const u16 serverPort, const CStr& hostLobbyName, bool useSTUN, const CStr& password)
{ {
ENSURE(!g_NetClient); ENSURE(!g_NetClient);
ENSURE(!g_NetServer); ENSURE(!g_NetServer);
@ -109,7 +112,6 @@ void JSI_Network::StartNetworkHost(ScriptInterface::CmptPrivate* pCmptPrivate, c
// This is using port variable to store return value, do not pass serverPort itself. // This is using port variable to store return value, do not pass serverPort itself.
if (!StunClient::FindStunEndpointHost(ip, port)) if (!StunClient::FindStunEndpointHost(ip, port))
{ {
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Failed to host via STUN."); ScriptException::Raise(rq, "Failed to host via STUN.");
SAFE_DELETE(g_NetServer); SAFE_DELETE(g_NetServer);
return; return;
@ -120,7 +122,6 @@ void JSI_Network::StartNetworkHost(ScriptInterface::CmptPrivate* pCmptPrivate, c
if (!g_NetServer->SetupConnection(serverPort)) if (!g_NetServer->SetupConnection(serverPort))
{ {
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Failed to start server"); ScriptException::Raise(rq, "Failed to start server");
SAFE_DELETE(g_NetServer); SAFE_DELETE(g_NetServer);
return; return;
@ -144,14 +145,13 @@ void JSI_Network::StartNetworkHost(ScriptInterface::CmptPrivate* pCmptPrivate, c
if (!g_NetClient->SetupConnection(nullptr)) if (!g_NetClient->SetupConnection(nullptr))
{ {
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Failed to connect to server"); ScriptException::Raise(rq, "Failed to connect to server");
SAFE_DELETE(g_NetClient); SAFE_DELETE(g_NetClient);
SAFE_DELETE(g_Game); SAFE_DELETE(g_Game);
} }
} }
void JSI_Network::StartNetworkJoin(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& playerName, const CStr& serverAddress, u16 serverPort, bool useSTUN, const CStr& hostJID) void StartNetworkJoin(const ScriptRequest& rq, const CStrW& playerName, const CStr& serverAddress, u16 serverPort, bool useSTUN, const CStr& hostJID)
{ {
ENSURE(!g_NetClient); ENSURE(!g_NetClient);
ENSURE(!g_NetServer); ENSURE(!g_NetServer);
@ -165,14 +165,18 @@ void JSI_Network::StartNetworkJoin(ScriptInterface::CmptPrivate* pCmptPrivate, c
if (!g_NetClient->SetupConnection(nullptr)) if (!g_NetClient->SetupConnection(nullptr))
{ {
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Failed to connect to server"); ScriptException::Raise(rq, "Failed to connect to server");
SAFE_DELETE(g_NetClient); SAFE_DELETE(g_NetClient);
SAFE_DELETE(g_Game); SAFE_DELETE(g_Game);
} }
} }
void JSI_Network::StartNetworkJoinLobby(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const CStrW& playerName, const CStr& hostJID, const CStr& password) /**
* Requires XmppClient to send iq request to the server to get server's ip and port based on passed password.
* This is needed to not force server to share it's public ip with all potential clients in the lobby.
* XmppClient will also handle logic after receiving the answer.
*/
void StartNetworkJoinLobby(const CStrW& playerName, const CStr& hostJID, const CStr& password)
{ {
ENSURE(!!g_XmppClient); ENSURE(!!g_XmppClient);
ENSURE(!g_NetClient); ENSURE(!g_NetClient);
@ -188,7 +192,7 @@ void JSI_Network::StartNetworkJoinLobby(ScriptInterface::CmptPrivate* UNUSED(pCm
g_XmppClient->SendIqGetConnectionData(hostJID, hashedPass.c_str()); g_XmppClient->SendIqGetConnectionData(hostJID, hashedPass.c_str());
} }
void JSI_Network::DisconnectNetworkGame(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) void DisconnectNetworkGame()
{ {
// TODO: we ought to do async reliable disconnections // TODO: we ought to do async reliable disconnections
@ -197,7 +201,7 @@ void JSI_Network::DisconnectNetworkGame(ScriptInterface::CmptPrivate* UNUSED(pCm
SAFE_DELETE(g_Game); SAFE_DELETE(g_Game);
} }
CStr JSI_Network::GetPlayerGUID(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) CStr GetPlayerGUID()
{ {
if (!g_NetClient) if (!g_NetClient)
return "local"; return "local";
@ -205,7 +209,7 @@ CStr JSI_Network::GetPlayerGUID(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivat
return g_NetClient->GetGUID(); return g_NetClient->GetGUID();
} }
JS::Value JSI_Network::PollNetworkClient(ScriptInterface::CmptPrivate* pCmptPrivate) JS::Value PollNetworkClient(const ScriptInterface& scriptInterface)
{ {
if (!g_NetClient) if (!g_NetClient)
return JS::UndefinedValue(); return JS::UndefinedValue();
@ -214,62 +218,62 @@ JS::Value JSI_Network::PollNetworkClient(ScriptInterface::CmptPrivate* pCmptPriv
ScriptRequest rqNet(g_NetClient->GetScriptInterface()); ScriptRequest rqNet(g_NetClient->GetScriptInterface());
JS::RootedValue pollNet(rqNet.cx); JS::RootedValue pollNet(rqNet.cx);
g_NetClient->GuiPoll(&pollNet); g_NetClient->GuiPoll(&pollNet);
return pCmptPrivate->pScriptInterface->CloneValueFromOtherCompartment(g_NetClient->GetScriptInterface(), pollNet); return scriptInterface.CloneValueFromOtherCompartment(g_NetClient->GetScriptInterface(), pollNet);
} }
void JSI_Network::SetNetworkGameAttributes(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue attribs1) void SetNetworkGameAttributes(const ScriptInterface& scriptInterface, JS::HandleValue attribs1)
{ {
ENSURE(g_NetClient); ENSURE(g_NetClient);
// TODO: This is a workaround because we need to pass a MutableHandle to a JSAPI functions somewhere (with no obvious reason). // TODO: This is a workaround because we need to pass a MutableHandle to a JSAPI functions somewhere (with no obvious reason).
ScriptRequest rq(pCmptPrivate->pScriptInterface); ScriptRequest rq(scriptInterface);
JS::RootedValue attribs(rq.cx, attribs1); JS::RootedValue attribs(rq.cx, attribs1);
g_NetClient->SendGameSetupMessage(&attribs, *(pCmptPrivate->pScriptInterface)); g_NetClient->SendGameSetupMessage(&attribs, scriptInterface);
} }
void JSI_Network::AssignNetworkPlayer(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), int playerID, const CStr& guid) void AssignNetworkPlayer(int playerID, const CStr& guid)
{ {
ENSURE(g_NetClient); ENSURE(g_NetClient);
g_NetClient->SendAssignPlayerMessage(playerID, guid); g_NetClient->SendAssignPlayerMessage(playerID, guid);
} }
void JSI_Network::KickPlayer(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const CStrW& playerName, bool ban) void KickPlayer(const CStrW& playerName, bool ban)
{ {
ENSURE(g_NetClient); ENSURE(g_NetClient);
g_NetClient->SendKickPlayerMessage(playerName, ban); g_NetClient->SendKickPlayerMessage(playerName, ban);
} }
void JSI_Network::SendNetworkChat(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const CStrW& message) void SendNetworkChat(const CStrW& message)
{ {
ENSURE(g_NetClient); ENSURE(g_NetClient);
g_NetClient->SendChatMessage(message); g_NetClient->SendChatMessage(message);
} }
void JSI_Network::SendNetworkReady(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), int message) void SendNetworkReady(int message)
{ {
ENSURE(g_NetClient); ENSURE(g_NetClient);
g_NetClient->SendReadyMessage(message); g_NetClient->SendReadyMessage(message);
} }
void JSI_Network::ClearAllPlayerReady (ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) void ClearAllPlayerReady ()
{ {
ENSURE(g_NetClient); ENSURE(g_NetClient);
g_NetClient->SendClearAllReadyMessage(); g_NetClient->SendClearAllReadyMessage();
} }
void JSI_Network::StartNetworkGame(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) void StartNetworkGame()
{ {
ENSURE(g_NetClient); ENSURE(g_NetClient);
g_NetClient->SendStartGameMessage(); g_NetClient->SendStartGameMessage();
} }
void JSI_Network::SetTurnLength(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), int length) void SetTurnLength(int length)
{ {
if (g_NetServer) if (g_NetServer)
g_NetServer->SetTurnLength(length); g_NetServer->SetTurnLength(length);
@ -277,24 +281,25 @@ void JSI_Network::SetTurnLength(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivat
LOGERROR("Only network host can change turn length"); LOGERROR("Only network host can change turn length");
} }
void JSI_Network::RegisterScriptFunctions(const ScriptInterface& scriptInterface) void RegisterScriptFunctions(const ScriptRequest& rq)
{ {
scriptInterface.RegisterFunction<u16, &GetDefaultPort>("GetDefaultPort"); ScriptFunction::Register<&GetDefaultPort>(rq, "GetDefaultPort");
scriptInterface.RegisterFunction<bool, &IsNetController>("IsNetController"); ScriptFunction::Register<&IsNetController>(rq, "IsNetController");
scriptInterface.RegisterFunction<bool, &HasNetServer>("HasNetServer"); ScriptFunction::Register<&HasNetServer>(rq, "HasNetServer");
scriptInterface.RegisterFunction<bool, &HasNetClient>("HasNetClient"); ScriptFunction::Register<&HasNetClient>(rq, "HasNetClient");
scriptInterface.RegisterFunction<void, CStrW, u16, CStr, bool, CStr, &StartNetworkHost>("StartNetworkHost"); ScriptFunction::Register<&StartNetworkHost>(rq, "StartNetworkHost");
scriptInterface.RegisterFunction<void, CStrW, CStr, u16, bool, CStr, &StartNetworkJoin>("StartNetworkJoin"); ScriptFunction::Register<&StartNetworkJoin>(rq, "StartNetworkJoin");
scriptInterface.RegisterFunction<void, CStrW, CStr, CStr, &StartNetworkJoinLobby>("StartNetworkJoinLobby"); ScriptFunction::Register<&StartNetworkJoinLobby>(rq, "StartNetworkJoinLobby");
scriptInterface.RegisterFunction<void, &DisconnectNetworkGame>("DisconnectNetworkGame"); ScriptFunction::Register<&DisconnectNetworkGame>(rq, "DisconnectNetworkGame");
scriptInterface.RegisterFunction<CStr, &GetPlayerGUID>("GetPlayerGUID"); ScriptFunction::Register<&GetPlayerGUID>(rq, "GetPlayerGUID");
scriptInterface.RegisterFunction<JS::Value, &PollNetworkClient>("PollNetworkClient"); ScriptFunction::Register<&PollNetworkClient>(rq, "PollNetworkClient");
scriptInterface.RegisterFunction<void, JS::HandleValue, &SetNetworkGameAttributes>("SetNetworkGameAttributes"); ScriptFunction::Register<&SetNetworkGameAttributes>(rq, "SetNetworkGameAttributes");
scriptInterface.RegisterFunction<void, int, CStr, &AssignNetworkPlayer>("AssignNetworkPlayer"); ScriptFunction::Register<&AssignNetworkPlayer>(rq, "AssignNetworkPlayer");
scriptInterface.RegisterFunction<void, CStrW, bool, &KickPlayer>("KickPlayer"); ScriptFunction::Register<&KickPlayer>(rq, "KickPlayer");
scriptInterface.RegisterFunction<void, CStrW, &SendNetworkChat>("SendNetworkChat"); ScriptFunction::Register<&SendNetworkChat>(rq, "SendNetworkChat");
scriptInterface.RegisterFunction<void, int, &SendNetworkReady>("SendNetworkReady"); ScriptFunction::Register<&SendNetworkReady>(rq, "SendNetworkReady");
scriptInterface.RegisterFunction<void, &ClearAllPlayerReady>("ClearAllPlayerReady"); ScriptFunction::Register<&ClearAllPlayerReady>(rq, "ClearAllPlayerReady");
scriptInterface.RegisterFunction<void, &StartNetworkGame>("StartNetworkGame"); ScriptFunction::Register<&StartNetworkGame>(rq, "StartNetworkGame");
scriptInterface.RegisterFunction<void, int, &SetTurnLength>("SetTurnLength"); ScriptFunction::Register<&SetTurnLength>(rq, "SetTurnLength");
}
} }

View file

@ -18,38 +18,11 @@
#ifndef INCLUDED_JSI_NETWORK #ifndef INCLUDED_JSI_NETWORK
#define INCLUDED_JSI_NETWORK #define INCLUDED_JSI_NETWORK
#include "lib/types.h" class ScriptRequest;
#include "ps/CStr.h"
#include "scriptinterface/ScriptInterface.h"
namespace JSI_Network namespace JSI_Network
{ {
u16 GetDefaultPort(ScriptInterface::CmptPrivate* pCmptPrivate); void RegisterScriptFunctions(const ScriptRequest& rq);
bool IsNetController(ScriptInterface::CmptPrivate* pCmptPrivate);
bool HasNetServer(ScriptInterface::CmptPrivate* pCmptPrivate);
bool HasNetClient(ScriptInterface::CmptPrivate* pCmptPrivate);
void StartNetworkGame(ScriptInterface::CmptPrivate* pCmptPrivate);
void SetNetworkGameAttributes(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue attribs1);
void StartNetworkHost(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& playerName, const u16 serverPort, const CStr& hostLobbyName, bool useSTUN, const CStr& password);
void StartNetworkJoin(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& playerName, const CStr& serverAddress, u16 serverPort, bool useSTUN, const CStr& hostJID);
/**
* Requires XmppClient to send iq request to the server to get server's ip and port based on passed password.
* This is needed to not force server to share it's public ip with all potential clients in the lobby.
* XmppClient will also handle logic after receiving the answer.
*/
void StartNetworkJoinLobby(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& playerName, const CStr& hostJID, const CStr& password);
void DisconnectNetworkGame(ScriptInterface::CmptPrivate* pCmptPrivate);
JS::Value PollNetworkClient(ScriptInterface::CmptPrivate* pCmptPrivate);
CStr GetPlayerGUID(ScriptInterface::CmptPrivate* pCmptPrivate);
void KickPlayer(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& playerName, bool ban);
void AssignNetworkPlayer(ScriptInterface::CmptPrivate* pCmptPrivate, int playerID, const CStr& guid);
void ClearAllPlayerReady (ScriptInterface::CmptPrivate* pCmptPrivate);
void SendNetworkChat(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& message);
void SendNetworkReady(ScriptInterface::CmptPrivate* pCmptPrivate, int message);
void SetTurnLength(ScriptInterface::CmptPrivate* pCmptPrivate, int length);
CStr HashPassword(const CStr& password);
void RegisterScriptFunctions(const ScriptInterface& scriptInterface);
} }
#endif // INCLUDED_JSI_NETWORK #endif // INCLUDED_JSI_NETWORK

View file

@ -296,7 +296,7 @@ void ModIo::StartListMods()
m_DownloadProgressData.status = DownloadProgressStatus::LISTING; m_DownloadProgressData.status = DownloadProgressStatus::LISTING;
} }
void ModIo::StartDownloadMod(size_t idx) void ModIo::StartDownloadMod(u32 idx)
{ {
// Don't start such a request during active downloads. // Don't start such a request during active downloads.
if (m_DownloadProgressData.status == DownloadProgressStatus::GAMEID || if (m_DownloadProgressData.status == DownloadProgressStatus::GAMEID ||

View file

@ -133,7 +133,7 @@ public:
// Async requests // Async requests
void StartGetGameId(); void StartGetGameId();
void StartListMods(); void StartListMods();
void StartDownloadMod(size_t idx); void StartDownloadMod(u32 idx);
/** /**
* Advance the current async request and perform final steps if the download is complete. * Advance the current async request and perform final steps if the download is complete.

View file

@ -425,10 +425,10 @@ bool VisualReplay::DeleteReplay(const OsPath& replayDirectory)
return DirectoryExists(directory) && DeleteDirectory(directory) == INFO::OK; return DirectoryExists(directory) && DeleteDirectory(directory) == INFO::OK;
} }
JS::Value VisualReplay::GetReplayAttributes(ScriptInterface::CmptPrivate* pCmptPrivate, const OsPath& directoryName) JS::Value VisualReplay::GetReplayAttributes(const ScriptInterface& scriptInterface, const OsPath& directoryName)
{ {
// Create empty JS object // Create empty JS object
ScriptRequest rq(pCmptPrivate->pScriptInterface); ScriptRequest rq(scriptInterface);
JS::RootedValue attribs(rq.cx); JS::RootedValue attribs(rq.cx);
ScriptInterface::CreateObject(rq, &attribs); ScriptInterface::CreateObject(rq, &attribs);
@ -444,7 +444,7 @@ JS::Value VisualReplay::GetReplayAttributes(ScriptInterface::CmptPrivate* pCmptP
// Read and return first line // Read and return first line
std::getline(*replayStream, line); std::getline(*replayStream, line);
pCmptPrivate->pScriptInterface->ParseJSON(line, &attribs); scriptInterface.ParseJSON(line, &attribs);
SAFE_DELETE(replayStream);; SAFE_DELETE(replayStream);;
return attribs; return attribs;
} }
@ -482,12 +482,12 @@ bool VisualReplay::HasReplayMetadata(const OsPath& directoryName)
return fileInfo.Size() > 0; return fileInfo.Size() > 0;
} }
JS::Value VisualReplay::GetReplayMetadata(ScriptInterface::CmptPrivate* pCmptPrivate, const OsPath& directoryName) JS::Value VisualReplay::GetReplayMetadata(const ScriptInterface& scriptInterface, const OsPath& directoryName)
{ {
if (!HasReplayMetadata(directoryName)) if (!HasReplayMetadata(directoryName))
return JS::NullValue(); return JS::NullValue();
ScriptRequest rq(pCmptPrivate->pScriptInterface); ScriptRequest rq(scriptInterface);
JS::RootedValue metadata(rq.cx); JS::RootedValue metadata(rq.cx);
std::ifstream* stream = new std::ifstream(OsString(GetDirectoryPath() / directoryName / L"metadata.json").c_str()); std::ifstream* stream = new std::ifstream(OsString(GetDirectoryPath() / directoryName / L"metadata.json").c_str());
@ -496,7 +496,7 @@ JS::Value VisualReplay::GetReplayMetadata(ScriptInterface::CmptPrivate* pCmptPri
std::getline(*stream, line); std::getline(*stream, line);
stream->close(); stream->close();
SAFE_DELETE(stream); SAFE_DELETE(stream);
pCmptPrivate->pScriptInterface->ParseJSON(line, &metadata); scriptInterface.ParseJSON(line, &metadata);
return metadata; return metadata;
} }

View file

@ -15,15 +15,16 @@
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef INCLUDED_REPlAY #ifndef INCLUDED_VISUAL_REPLAY
#define INCLUDED_REPlAY #define INCLUDED_VISUAL_REPLAY
#include "lib/os_path.h" #include "lib/os_path.h"
#include "scriptinterface/ScriptInterface.h"
class CSimulation2; class CSimulation2;
class CGUIManager; class CGUIManager;
class ScriptInterface;
/** /**
* Contains functions for visually replaying past games. * Contains functions for visually replaying past games.
*/ */
@ -104,7 +105,7 @@ bool DeleteReplay(const OsPath& replayFile);
/** /**
* Returns the parsed header of the replay file (commands.txt). * Returns the parsed header of the replay file (commands.txt).
*/ */
JS::Value GetReplayAttributes(ScriptInterface::CmptPrivate* pCmptPrivate, const OsPath& directoryName); JS::Value GetReplayAttributes(const ScriptInterface& scriptInterface, const OsPath& directoryName);
/** /**
* Returns whether or not the metadata / summary screen data has been saved properly when the game ended. * Returns whether or not the metadata / summary screen data has been saved properly when the game ended.
@ -114,7 +115,7 @@ bool HasReplayMetadata(const OsPath& directoryName);
/** /**
* Returns the metadata of a replay. * Returns the metadata of a replay.
*/ */
JS::Value GetReplayMetadata(ScriptInterface::CmptPrivate* pCmptPrivate, const OsPath& directoryName); JS::Value GetReplayMetadata(const ScriptInterface& scriptInterface, const OsPath& directoryName);
/** /**
* Adds a replay to the replayCache. * Adds a replay to the replayCache.

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2019 Wildfire Games. /* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -21,11 +21,14 @@
#include "ps/ConfigDB.h" #include "ps/ConfigDB.h"
#include "ps/CLogger.h" #include "ps/CLogger.h"
#include "scriptinterface/FunctionWrapper.h"
#include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptInterface.h"
#include <string> #include <string>
#include <unordered_set> #include <unordered_set>
namespace JSI_ConfigDB
{
// These entries will not be readable nor writable for JS, so that e.g. malicious mods can't leak personal or sensitive data // These entries will not be readable nor writable for JS, so that e.g. malicious mods can't leak personal or sensitive data
static const std::unordered_set<std::string> g_ProtectedConfigNames = { static const std::unordered_set<std::string> g_ProtectedConfigNames = {
"modio.public_key", // See ModIO.cpp "modio.public_key", // See ModIO.cpp
@ -35,7 +38,7 @@ static const std::unordered_set<std::string> g_ProtectedConfigNames = {
"userreport.id" // Acts as authentication token for GDPR personal data requests. "userreport.id" // Acts as authentication token for GDPR personal data requests.
}; };
bool JSI_ConfigDB::IsProtectedConfigName(const std::string& name) bool IsProtectedConfigName(const std::string& name)
{ {
if (g_ProtectedConfigNames.find(name) != g_ProtectedConfigNames.end()) if (g_ProtectedConfigNames.find(name) != g_ProtectedConfigNames.end())
{ {
@ -45,7 +48,7 @@ bool JSI_ConfigDB::IsProtectedConfigName(const std::string& name)
return false; return false;
} }
bool JSI_ConfigDB::GetConfigNamespace(const std::wstring& cfgNsString, EConfigNamespace& cfgNs) bool GetConfigNamespace(const std::wstring& cfgNsString, EConfigNamespace& cfgNs)
{ {
if (cfgNsString == L"default") if (cfgNsString == L"default")
cfgNs = CFG_DEFAULT; cfgNs = CFG_DEFAULT;
@ -66,7 +69,7 @@ bool JSI_ConfigDB::GetConfigNamespace(const std::wstring& cfgNsString, EConfigNa
return true; return true;
} }
bool JSI_ConfigDB::HasChanges(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& cfgNsString) bool HasChanges(const std::wstring& cfgNsString)
{ {
EConfigNamespace cfgNs; EConfigNamespace cfgNs;
if (!GetConfigNamespace(cfgNsString, cfgNs)) if (!GetConfigNamespace(cfgNsString, cfgNs))
@ -75,7 +78,7 @@ bool JSI_ConfigDB::HasChanges(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)
return g_ConfigDB.HasChanges(cfgNs); return g_ConfigDB.HasChanges(cfgNs);
} }
bool JSI_ConfigDB::SetChanges(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& cfgNsString, bool value) bool SetChanges(const std::wstring& cfgNsString, bool value)
{ {
EConfigNamespace cfgNs; EConfigNamespace cfgNs;
if (!GetConfigNamespace(cfgNsString, cfgNs)) if (!GetConfigNamespace(cfgNsString, cfgNs))
@ -85,7 +88,7 @@ bool JSI_ConfigDB::SetChanges(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)
return true; return true;
} }
std::string JSI_ConfigDB::GetValue(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& cfgNsString, const std::string& name) std::string GetValue(const std::wstring& cfgNsString, const std::string& name)
{ {
if (IsProtectedConfigName(name)) if (IsProtectedConfigName(name))
return ""; return "";
@ -99,7 +102,7 @@ std::string JSI_ConfigDB::GetValue(ScriptInterface::CmptPrivate* UNUSED(pCmptPri
return value; return value;
} }
bool JSI_ConfigDB::CreateValue(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& cfgNsString, const std::string& name, const std::string& value) bool CreateValue(const std::wstring& cfgNsString, const std::string& name, const std::string& value)
{ {
if (IsProtectedConfigName(name)) if (IsProtectedConfigName(name))
return false; return false;
@ -112,7 +115,7 @@ bool JSI_ConfigDB::CreateValue(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate
return true; return true;
} }
bool JSI_ConfigDB::CreateValues(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& cfgNsString, const std::string& name, const std::vector<CStr>& values) bool CreateValues(const std::wstring& cfgNsString, const std::string& name, const std::vector<CStr>& values)
{ {
if (IsProtectedConfigName(name)) if (IsProtectedConfigName(name))
return false; return false;
@ -126,7 +129,7 @@ bool JSI_ConfigDB::CreateValues(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivat
} }
bool JSI_ConfigDB::RemoveValue(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& cfgNsString, const std::string& name) bool RemoveValue(const std::wstring& cfgNsString, const std::string& name)
{ {
if (IsProtectedConfigName(name)) if (IsProtectedConfigName(name))
return false; return false;
@ -139,7 +142,7 @@ bool JSI_ConfigDB::RemoveValue(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate
return true; return true;
} }
bool JSI_ConfigDB::WriteFile(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& cfgNsString, const Path& path) bool WriteFile(const std::wstring& cfgNsString, const Path& path)
{ {
EConfigNamespace cfgNs; EConfigNamespace cfgNs;
if (!GetConfigNamespace(cfgNsString, cfgNs)) if (!GetConfigNamespace(cfgNsString, cfgNs))
@ -148,7 +151,7 @@ bool JSI_ConfigDB::WriteFile(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate),
return g_ConfigDB.WriteFile(cfgNs, path); return g_ConfigDB.WriteFile(cfgNs, path);
} }
bool JSI_ConfigDB::WriteValueToFile(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& cfgNsString, const std::string& name, const std::string& value, const Path& path) bool WriteValueToFile(const std::wstring& cfgNsString, const std::string& name, const std::string& value, const Path& path)
{ {
if (IsProtectedConfigName(name)) if (IsProtectedConfigName(name))
return false; return false;
@ -160,13 +163,13 @@ bool JSI_ConfigDB::WriteValueToFile(ScriptInterface::CmptPrivate* UNUSED(pCmptPr
return g_ConfigDB.WriteValueToFile(cfgNs, name, value, path); return g_ConfigDB.WriteValueToFile(cfgNs, name, value, path);
} }
void JSI_ConfigDB::CreateAndWriteValueToFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString, const std::string& name, const std::string& value, const Path& path) void CreateAndWriteValueToFile(const std::wstring& cfgNsString, const std::string& name, const std::string& value, const Path& path)
{ {
CreateValue(pCmptPrivate, cfgNsString, name, value); CreateValue(cfgNsString, name, value);
WriteValueToFile(pCmptPrivate, cfgNsString, name, value, path); WriteValueToFile(cfgNsString, name, value, path);
} }
bool JSI_ConfigDB::Reload(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& cfgNsString) bool Reload(const std::wstring& cfgNsString)
{ {
EConfigNamespace cfgNs; EConfigNamespace cfgNs;
if (!GetConfigNamespace(cfgNsString, cfgNs)) if (!GetConfigNamespace(cfgNsString, cfgNs))
@ -175,7 +178,7 @@ bool JSI_ConfigDB::Reload(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), co
return g_ConfigDB.Reload(cfgNs); return g_ConfigDB.Reload(cfgNs);
} }
bool JSI_ConfigDB::SetFile(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& cfgNsString, const Path& path) bool SetFile(const std::wstring& cfgNsString, const Path& path)
{ {
EConfigNamespace cfgNs; EConfigNamespace cfgNs;
if (!GetConfigNamespace(cfgNsString, cfgNs)) if (!GetConfigNamespace(cfgNsString, cfgNs))
@ -185,17 +188,18 @@ bool JSI_ConfigDB::SetFile(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), c
return true; return true;
} }
void JSI_ConfigDB::RegisterScriptFunctions(const ScriptInterface& scriptInterface) void RegisterScriptFunctions(const ScriptRequest& rq)
{ {
scriptInterface.RegisterFunction<bool, std::wstring, &JSI_ConfigDB::HasChanges>("ConfigDB_HasChanges"); ScriptFunction::Register<&HasChanges>(rq, "ConfigDB_HasChanges");
scriptInterface.RegisterFunction<bool, std::wstring, bool, &JSI_ConfigDB::SetChanges>("ConfigDB_SetChanges"); ScriptFunction::Register<&SetChanges>(rq, "ConfigDB_SetChanges");
scriptInterface.RegisterFunction<std::string, std::wstring, std::string, &JSI_ConfigDB::GetValue>("ConfigDB_GetValue"); ScriptFunction::Register<&GetValue>(rq, "ConfigDB_GetValue");
scriptInterface.RegisterFunction<bool, std::wstring, std::string, std::string, &JSI_ConfigDB::CreateValue>("ConfigDB_CreateValue"); ScriptFunction::Register<&CreateValue>(rq, "ConfigDB_CreateValue");
scriptInterface.RegisterFunction<bool, std::wstring, std::string, std::vector<CStr>, &JSI_ConfigDB::CreateValues>("ConfigDB_CreateValues"); ScriptFunction::Register<&CreateValues>(rq, "ConfigDB_CreateValues");
scriptInterface.RegisterFunction<bool, std::wstring, std::string, &JSI_ConfigDB::RemoveValue>("ConfigDB_RemoveValue"); ScriptFunction::Register<&RemoveValue>(rq, "ConfigDB_RemoveValue");
scriptInterface.RegisterFunction<bool, std::wstring, Path, &JSI_ConfigDB::WriteFile>("ConfigDB_WriteFile"); ScriptFunction::Register<&WriteFile>(rq, "ConfigDB_WriteFile");
scriptInterface.RegisterFunction<bool, std::wstring, std::string, std::string, Path, &JSI_ConfigDB::WriteValueToFile>("ConfigDB_WriteValueToFile"); ScriptFunction::Register<&WriteValueToFile>(rq, "ConfigDB_WriteValueToFile");
scriptInterface.RegisterFunction<void, std::wstring, std::string, std::string, Path, &JSI_ConfigDB::CreateAndWriteValueToFile>("ConfigDB_CreateAndWriteValueToFile"); ScriptFunction::Register<&CreateAndWriteValueToFile>(rq, "ConfigDB_CreateAndWriteValueToFile");
scriptInterface.RegisterFunction<bool, std::wstring, Path, &JSI_ConfigDB::SetFile>("ConfigDB_SetFile"); ScriptFunction::Register<&SetFile>(rq, "ConfigDB_SetFile");
scriptInterface.RegisterFunction<bool, std::wstring, &JSI_ConfigDB::Reload>("ConfigDB_Reload"); ScriptFunction::Register<&Reload>(rq, "ConfigDB_Reload");
}
} }

View file

@ -18,27 +18,11 @@
#ifndef INCLUDED_JSI_CONFIGDB #ifndef INCLUDED_JSI_CONFIGDB
#define INCLUDED_JSI_CONFIGDB #define INCLUDED_JSI_CONFIGDB
#include "ps/ConfigDB.h" class ScriptRequest;
#include "scriptinterface/ScriptInterface.h"
#include <string>
namespace JSI_ConfigDB namespace JSI_ConfigDB
{ {
bool IsProtectedConfigName(const std::string& name); void RegisterScriptFunctions(const ScriptRequest& rq);
bool GetConfigNamespace(const std::wstring& cfgNsString, EConfigNamespace& cfgNs);
bool HasChanges(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString);
bool SetChanges(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString, bool value);
std::string GetValue(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString, const std::string& name);
bool CreateValue(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString, const std::string& name, const std::string& value);
bool CreateValues(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString, const std::string& name, const std::vector<CStr>& values);
bool RemoveValue(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString, const std::string& name);
bool WriteFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString, const Path& path);
bool WriteValueToFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString, const std::string& name, const std::string& value, const Path& path);
void CreateAndWriteValueToFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString, const std::string& name, const std::string& value, const Path& path);
bool Reload(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString);
bool SetFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& cfgNsString, const Path& path);
void RegisterScriptFunctions(const ScriptInterface& scriptInterface);
} }
#endif // INCLUDED_JSI_CONFIGDB #endif // INCLUDED_JSI_CONFIGDB

View file

@ -23,7 +23,7 @@
#include "ps/CLogger.h" #include "ps/CLogger.h"
#include "scriptinterface/FunctionWrapper.h" #include "scriptinterface/FunctionWrapper.h"
namespace namespace JSI_Console
{ {
CConsole* ConsoleGetter(const ScriptRequest&, JS::CallArgs&) CConsole* ConsoleGetter(const ScriptRequest&, JS::CallArgs&)
{ {
@ -34,10 +34,10 @@ CConsole* ConsoleGetter(const ScriptRequest&, JS::CallArgs&)
} }
return g_Console; return g_Console;
} }
}
void JSI_Console::RegisterScriptFunctions(const ScriptRequest& rq) void RegisterScriptFunctions(const ScriptRequest& rq)
{ {
ScriptFunction::Register<&CConsole::IsActive, ConsoleGetter>(rq, "Console_GetVisibleEnabled"); ScriptFunction::Register<&CConsole::IsActive, ConsoleGetter>(rq, "Console_GetVisibleEnabled");
ScriptFunction::Register<&CConsole::SetVisible, ConsoleGetter>(rq, "Console_SetVisibleEnabled"); ScriptFunction::Register<&CConsole::SetVisible, ConsoleGetter>(rq, "Console_SetVisibleEnabled");
} }
}

View file

@ -22,15 +22,18 @@
#include "i18n/L10n.h" #include "i18n/L10n.h"
#include "lib/svn_revision.h" #include "lib/svn_revision.h"
#include "lib/debug.h" #include "lib/debug.h"
#include "scriptinterface/FunctionWrapper.h"
#include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptInterface.h"
#include <ctime> #include <ctime>
#include <string> #include <string>
namespace JSI_Debug
{
/** /**
* Microseconds since the epoch. * Microseconds since the epoch.
*/ */
double JSI_Debug::GetMicroseconds(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) double GetMicroseconds()
{ {
return JS_Now(); return JS_Now();
} }
@ -38,18 +41,18 @@ double JSI_Debug::GetMicroseconds(ScriptInterface::CmptPrivate* UNUSED(pCmptPriv
// Deliberately cause the game to crash. // Deliberately cause the game to crash.
// Currently implemented via access violation (read of address 0). // Currently implemented via access violation (read of address 0).
// Useful for testing the crashlog/stack trace code. // Useful for testing the crashlog/stack trace code.
int JSI_Debug::Crash(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) int Crash()
{ {
debug_printf("Crashing at user's request.\n"); debug_printf("Crashing at user's request.\n");
return *(volatile int*)0; return *(volatile int*)0;
} }
void JSI_Debug::DebugWarn(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) void DebugWarn()
{ {
debug_warn(L"Warning at user's request."); debug_warn(L"Warning at user's request.");
} }
void JSI_Debug::DisplayErrorDialog(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& msg) void DisplayErrorDialog(const std::wstring& msg)
{ {
debug_DisplayError(msg.c_str(), DE_NO_DEBUG_INFO, NULL, NULL, NULL, 0, NULL, NULL); debug_DisplayError(msg.c_str(), DE_NO_DEBUG_INFO, NULL, NULL, NULL, 0, NULL, NULL);
} }
@ -58,13 +61,13 @@ void JSI_Debug::DisplayErrorDialog(ScriptInterface::CmptPrivate* UNUSED(pCmptPri
// - Displayed on main menu screen; tells non-programmers which auto-build // - Displayed on main menu screen; tells non-programmers which auto-build
// they are running. Could also be determined via .EXE file properties, // they are running. Could also be determined via .EXE file properties,
// but that's a bit more trouble. // but that's a bit more trouble.
std::wstring JSI_Debug::GetBuildDate(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) std::wstring GetBuildDate()
{ {
UDate buildDate = g_L10n.ParseDateTime(__DATE__, "MMM d yyyy", icu::Locale::getUS()); UDate buildDate = g_L10n.ParseDateTime(__DATE__, "MMM d yyyy", icu::Locale::getUS());
return wstring_from_utf8(g_L10n.LocalizeDateTime(buildDate, L10n::Date, icu::SimpleDateFormat::MEDIUM)); return wstring_from_utf8(g_L10n.LocalizeDateTime(buildDate, L10n::Date, icu::SimpleDateFormat::MEDIUM));
} }
double JSI_Debug::GetBuildTimestamp(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) double GetBuildTimestamp()
{ {
UDate buildDate = g_L10n.ParseDateTime(__DATE__ " " __TIME__, "MMM d yyyy HH:mm:ss", icu::Locale::getUS()); UDate buildDate = g_L10n.ParseDateTime(__DATE__ " " __TIME__, "MMM d yyyy HH:mm:ss", icu::Locale::getUS());
if (buildDate) if (buildDate)
@ -77,7 +80,7 @@ double JSI_Debug::GetBuildTimestamp(ScriptInterface::CmptPrivate* UNUSED(pCmptPr
// lib/svn_revision.cpp. it is useful to know when attempting to // lib/svn_revision.cpp. it is useful to know when attempting to
// reproduce bugs (the main EXE and PDB should be temporarily reverted to // reproduce bugs (the main EXE and PDB should be temporarily reverted to
// that revision so that they match user-submitted crashdumps). // that revision so that they match user-submitted crashdumps).
std::wstring JSI_Debug::GetBuildRevision(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) std::wstring GetBuildRevision()
{ {
std::wstring svnRevision(svn_revision); std::wstring svnRevision(svn_revision);
if (svnRevision == L"custom build") if (svnRevision == L"custom build")
@ -85,13 +88,14 @@ std::wstring JSI_Debug::GetBuildRevision(ScriptInterface::CmptPrivate* UNUSED(pC
return svnRevision; return svnRevision;
} }
void JSI_Debug::RegisterScriptFunctions(const ScriptInterface& scriptInterface) void RegisterScriptFunctions(const ScriptRequest& rq)
{ {
scriptInterface.RegisterFunction<double, &GetMicroseconds>("GetMicroseconds"); ScriptFunction::Register<&GetMicroseconds>(rq, "GetMicroseconds");
scriptInterface.RegisterFunction<int, &Crash>("Crash"); ScriptFunction::Register<&Crash>(rq, "Crash");
scriptInterface.RegisterFunction<void, &DebugWarn>("DebugWarn"); ScriptFunction::Register<&DebugWarn>(rq, "DebugWarn");
scriptInterface.RegisterFunction<void, std::wstring, &DisplayErrorDialog>("DisplayErrorDialog"); ScriptFunction::Register<&DisplayErrorDialog>(rq, "DisplayErrorDialog");
scriptInterface.RegisterFunction<std::wstring, &GetBuildDate>("GetBuildDate"); ScriptFunction::Register<&GetBuildDate>(rq, "GetBuildDate");
scriptInterface.RegisterFunction<double, &GetBuildTimestamp>("GetBuildTimestamp"); ScriptFunction::Register<&GetBuildTimestamp>(rq, "GetBuildTimestamp");
scriptInterface.RegisterFunction<std::wstring, &GetBuildRevision>("GetBuildRevision"); ScriptFunction::Register<&GetBuildRevision>(rq, "GetBuildRevision");
}
} }

View file

@ -18,21 +18,11 @@
#ifndef INCLUDED_JSI_DEBUG #ifndef INCLUDED_JSI_DEBUG
#define INCLUDED_JSI_DEBUG #define INCLUDED_JSI_DEBUG
#include "scriptinterface/ScriptInterface.h" class ScriptRequest;
#include <string>
namespace JSI_Debug namespace JSI_Debug
{ {
int Crash(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)); void RegisterScriptFunctions(const ScriptRequest& rq);
void DebugWarn(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate));
void DisplayErrorDialog(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& msg);
std::wstring GetBuildDate(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate));
double GetBuildTimestamp(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate));
std::wstring GetBuildRevision(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate));
double GetMicroseconds(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate));
void RegisterScriptFunctions(const ScriptInterface& ScriptInterface);
} }
#endif // INCLUDED_JSI_DEBUG #endif // INCLUDED_JSI_DEBUG

View file

@ -27,17 +27,20 @@
#include "ps/GameSetup/GameSetup.h" #include "ps/GameSetup/GameSetup.h"
#include "ps/Replay.h" #include "ps/Replay.h"
#include "ps/World.h" #include "ps/World.h"
#include "scriptinterface/FunctionWrapper.h"
#include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptInterface.h"
#include "simulation2/system/TurnManager.h" #include "simulation2/system/TurnManager.h"
#include "simulation2/Simulation2.h" #include "simulation2/Simulation2.h"
#include "soundmanager/SoundManager.h" #include "soundmanager/SoundManager.h"
bool JSI_Game::IsGameStarted(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) namespace JSI_Game
{
bool IsGameStarted()
{ {
return g_Game; return g_Game;
} }
void JSI_Game::StartGame(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue attribs, int playerID) void StartGame(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue attribs, int playerID)
{ {
ENSURE(!g_NetServer); ENSURE(!g_NetServer);
ENSURE(!g_NetClient); ENSURE(!g_NetClient);
@ -56,12 +59,12 @@ void JSI_Game::StartGame(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleV
g_Game->StartGame(&gameAttribs, ""); g_Game->StartGame(&gameAttribs, "");
} }
void JSI_Game::Script_EndGame(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) void Script_EndGame()
{ {
EndGame(); EndGame();
} }
int JSI_Game::GetPlayerID(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) int GetPlayerID()
{ {
if (!g_Game) if (!g_Game)
return -1; return -1;
@ -69,7 +72,7 @@ int JSI_Game::GetPlayerID(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate))
return g_Game->GetPlayerID(); return g_Game->GetPlayerID();
} }
void JSI_Game::SetPlayerID(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), int id) void SetPlayerID(int id)
{ {
if (!g_Game) if (!g_Game)
return; return;
@ -77,7 +80,7 @@ void JSI_Game::SetPlayerID(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), i
g_Game->SetPlayerID(id); g_Game->SetPlayerID(id);
} }
void JSI_Game::SetViewedPlayer(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), int id) void SetViewedPlayer(int id)
{ {
if (!g_Game) if (!g_Game)
return; return;
@ -85,21 +88,20 @@ void JSI_Game::SetViewedPlayer(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate
g_Game->SetViewedPlayerID(id); g_Game->SetViewedPlayerID(id);
} }
float JSI_Game::GetSimRate(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) float GetSimRate()
{ {
return g_Game->GetSimRate(); return g_Game->GetSimRate();
} }
void JSI_Game::SetSimRate(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float rate) void SetSimRate(float rate)
{ {
g_Game->SetSimRate(rate); g_Game->SetSimRate(rate);
} }
bool JSI_Game::IsPaused(ScriptInterface::CmptPrivate* pCmptPrivate) bool IsPaused(const ScriptRequest& rq)
{ {
if (!g_Game) if (!g_Game)
{ {
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Game is not started"); ScriptException::Raise(rq, "Game is not started");
return false; return false;
} }
@ -107,11 +109,10 @@ bool JSI_Game::IsPaused(ScriptInterface::CmptPrivate* pCmptPrivate)
return g_Game->m_Paused; return g_Game->m_Paused;
} }
void JSI_Game::SetPaused(ScriptInterface::CmptPrivate* pCmptPrivate, bool pause, bool sendMessage) void SetPaused(const ScriptRequest& rq, bool pause, bool sendMessage)
{ {
if (!g_Game) if (!g_Game)
{ {
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Game is not started"); ScriptException::Raise(rq, "Game is not started");
return; return;
} }
@ -130,7 +131,7 @@ void JSI_Game::SetPaused(ScriptInterface::CmptPrivate* pCmptPrivate, bool pause,
g_NetClient->SendPausedMessage(pause); g_NetClient->SendPausedMessage(pause);
} }
bool JSI_Game::IsVisualReplay(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) bool IsVisualReplay()
{ {
if (!g_Game) if (!g_Game)
return false; return false;
@ -138,7 +139,7 @@ bool JSI_Game::IsVisualReplay(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)
return g_Game->IsVisualReplay(); return g_Game->IsVisualReplay();
} }
std::wstring JSI_Game::GetCurrentReplayDirectory(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) std::wstring GetCurrentReplayDirectory()
{ {
if (!g_Game) if (!g_Game)
return std::wstring(); return std::wstring();
@ -149,17 +150,17 @@ std::wstring JSI_Game::GetCurrentReplayDirectory(ScriptInterface::CmptPrivate* U
return g_Game->GetReplayLogger().GetDirectory().Filename().string(); return g_Game->GetReplayLogger().GetDirectory().Filename().string();
} }
void JSI_Game::EnableTimeWarpRecording(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), unsigned int numTurns) void EnableTimeWarpRecording(unsigned int numTurns)
{ {
g_Game->GetTurnManager()->EnableTimeWarpRecording(numTurns); g_Game->GetTurnManager()->EnableTimeWarpRecording(numTurns);
} }
void JSI_Game::RewindTimeWarp(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) void RewindTimeWarp()
{ {
g_Game->GetTurnManager()->RewindTimeWarp(); g_Game->GetTurnManager()->RewindTimeWarp();
} }
void JSI_Game::DumpTerrainMipmap(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) void DumpTerrainMipmap()
{ {
VfsPath filename(L"screenshots/terrainmipmap.png"); VfsPath filename(L"screenshots/terrainmipmap.png");
g_Game->GetWorld()->GetTerrain()->GetHeightMipmap().DumpToDisk(filename); g_Game->GetWorld()->GetTerrain()->GetHeightMipmap().DumpToDisk(filename);
@ -168,21 +169,22 @@ void JSI_Game::DumpTerrainMipmap(ScriptInterface::CmptPrivate* UNUSED(pCmptPriva
LOGMESSAGERENDER("Terrain mipmap written to '%s'", realPath.string8()); LOGMESSAGERENDER("Terrain mipmap written to '%s'", realPath.string8());
} }
void JSI_Game::RegisterScriptFunctions(const ScriptInterface& scriptInterface) void RegisterScriptFunctions(const ScriptRequest& rq)
{ {
scriptInterface.RegisterFunction<bool, &IsGameStarted>("IsGameStarted"); ScriptFunction::Register<&IsGameStarted>(rq, "IsGameStarted");
scriptInterface.RegisterFunction<void, JS::HandleValue, int, &StartGame>("StartGame"); ScriptFunction::Register<&StartGame>(rq, "StartGame");
scriptInterface.RegisterFunction<void, &Script_EndGame>("EndGame"); ScriptFunction::Register<&Script_EndGame>(rq, "EndGame");
scriptInterface.RegisterFunction<int, &GetPlayerID>("GetPlayerID"); ScriptFunction::Register<&GetPlayerID>(rq, "GetPlayerID");
scriptInterface.RegisterFunction<void, int, &SetPlayerID>("SetPlayerID"); ScriptFunction::Register<&SetPlayerID>(rq, "SetPlayerID");
scriptInterface.RegisterFunction<void, int, &SetViewedPlayer>("SetViewedPlayer"); ScriptFunction::Register<&SetViewedPlayer>(rq, "SetViewedPlayer");
scriptInterface.RegisterFunction<float, &GetSimRate>("GetSimRate"); ScriptFunction::Register<&GetSimRate>(rq, "GetSimRate");
scriptInterface.RegisterFunction<void, float, &SetSimRate>("SetSimRate"); ScriptFunction::Register<&SetSimRate>(rq, "SetSimRate");
scriptInterface.RegisterFunction<bool, &IsPaused>("IsPaused"); ScriptFunction::Register<&IsPaused>(rq, "IsPaused");
scriptInterface.RegisterFunction<void, bool, bool, &SetPaused>("SetPaused"); ScriptFunction::Register<&SetPaused>(rq, "SetPaused");
scriptInterface.RegisterFunction<bool, &IsVisualReplay>("IsVisualReplay"); ScriptFunction::Register<&IsVisualReplay>(rq, "IsVisualReplay");
scriptInterface.RegisterFunction<std::wstring, &GetCurrentReplayDirectory>("GetCurrentReplayDirectory"); ScriptFunction::Register<&GetCurrentReplayDirectory>(rq, "GetCurrentReplayDirectory");
scriptInterface.RegisterFunction<void, unsigned int, &EnableTimeWarpRecording>("EnableTimeWarpRecording"); ScriptFunction::Register<&EnableTimeWarpRecording>(rq, "EnableTimeWarpRecording");
scriptInterface.RegisterFunction<void, &RewindTimeWarp>("RewindTimeWarp"); ScriptFunction::Register<&RewindTimeWarp>(rq, "RewindTimeWarp");
scriptInterface.RegisterFunction<void, &DumpTerrainMipmap>("DumpTerrainMipmap"); ScriptFunction::Register<&DumpTerrainMipmap>(rq, "DumpTerrainMipmap");
}
} }

View file

@ -18,27 +18,11 @@
#ifndef INCLUDED_JSI_GAME #ifndef INCLUDED_JSI_GAME
#define INCLUDED_JSI_GAME #define INCLUDED_JSI_GAME
#include "scriptinterface/ScriptInterface.h" class ScriptRequest;
namespace JSI_Game namespace JSI_Game
{ {
bool IsGameStarted(ScriptInterface::CmptPrivate* pCmptPrivate); void RegisterScriptFunctions(const ScriptRequest& rq);
void StartGame(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue attribs, int playerID);
void Script_EndGame(ScriptInterface::CmptPrivate* pCmptPrivate);
int GetPlayerID(ScriptInterface::CmptPrivate* pCmptPrivate);
void SetPlayerID(ScriptInterface::CmptPrivate* pCmptPrivate, int id);
void SetViewedPlayer(ScriptInterface::CmptPrivate* pCmptPrivate, int id);
float GetSimRate(ScriptInterface::CmptPrivate* pCmptPrivate);
void SetSimRate(ScriptInterface::CmptPrivate* pCmptPrivate, float rate);
bool IsPaused(ScriptInterface::CmptPrivate* pCmptPrivate);
void SetPaused(ScriptInterface::CmptPrivate* pCmptPrivate, bool pause, bool sendMessage);
bool IsVisualReplay(ScriptInterface::CmptPrivate* pCmptPrivate);
std::wstring GetCurrentReplayDirectory(ScriptInterface::CmptPrivate* pCmptPrivate);
void RewindTimeWarp(ScriptInterface::CmptPrivate* pCmptPrivate);
void EnableTimeWarpRecording(ScriptInterface::CmptPrivate* pCmptPrivate, unsigned int numTurns);
void DumpTerrainMipmap(ScriptInterface::CmptPrivate* pCmptPrivate);
void RegisterScriptFunctions(const ScriptInterface& ScriptInterface);
} }
#endif // INCLUDED_JSI_GAME #endif // INCLUDED_JSI_GAME

View file

@ -30,50 +30,53 @@
#include "ps/Globals.h" #include "ps/Globals.h"
#include "ps/Hotkey.h" #include "ps/Hotkey.h"
#include "ps/Util.h" #include "ps/Util.h"
#include "scriptinterface/FunctionWrapper.h"
#include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptInterface.h"
#include "tools/atlas/GameInterface/GameLoop.h" #include "tools/atlas/GameInterface/GameLoop.h"
extern void QuitEngine(); extern void QuitEngine();
extern void StartAtlas(); extern void StartAtlas();
void JSI_Main::QuitEngine(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) namespace JSI_Main
{
void QuitEngine()
{ {
::QuitEngine(); ::QuitEngine();
} }
void JSI_Main::StartAtlas(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) void StartAtlas()
{ {
::StartAtlas(); ::StartAtlas();
} }
bool JSI_Main::AtlasIsAvailable(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) bool AtlasIsAvailable()
{ {
return ATLAS_IsAvailable(); return ATLAS_IsAvailable();
} }
bool JSI_Main::IsAtlasRunning(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) bool IsAtlasRunning()
{ {
return g_AtlasGameLoop && g_AtlasGameLoop->running; return g_AtlasGameLoop && g_AtlasGameLoop->running;
} }
void JSI_Main::OpenURL(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& url) void OpenURL(const std::string& url)
{ {
sys_open_url(url); sys_open_url(url);
} }
std::wstring JSI_Main::GetSystemUsername(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) std::wstring GetSystemUsername()
{ {
return sys_get_user_name(); return sys_get_user_name();
} }
std::wstring JSI_Main::GetMatchID(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) std::wstring GetMatchID()
{ {
return ps_generate_guid().FromUTF8(); return ps_generate_guid().FromUTF8();
} }
JS::Value JSI_Main::LoadMapSettings(ScriptInterface::CmptPrivate* pCmptPrivate, const VfsPath& pathname) JS::Value LoadMapSettings(const ScriptInterface& scriptInterface, const VfsPath& pathname)
{ {
ScriptRequest rq(pCmptPrivate->pScriptInterface); ScriptRequest rq(scriptInterface);
CMapSummaryReader reader; CMapSummaryReader reader;
@ -81,18 +84,18 @@ JS::Value JSI_Main::LoadMapSettings(ScriptInterface::CmptPrivate* pCmptPrivate,
return JS::UndefinedValue(); return JS::UndefinedValue();
JS::RootedValue settings(rq.cx); JS::RootedValue settings(rq.cx);
reader.GetMapSettings(*(pCmptPrivate->pScriptInterface), &settings); reader.GetMapSettings(scriptInterface, &settings);
return settings; return settings;
} }
bool JSI_Main::HotkeyIsPressed_(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& hotkeyName) bool HotkeyIsPressed_(const std::string& hotkeyName)
{ {
return HotkeyIsPressed(hotkeyName); return HotkeyIsPressed(hotkeyName);
} }
// This value is recalculated once a frame. We take special care to // This value is recalculated once a frame. We take special care to
// filter it, so it is both accurate and free of jitter. // filter it, so it is both accurate and free of jitter.
int JSI_Main::GetFps(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) int GetFps()
{ {
if (!g_frequencyFilter) if (!g_frequencyFilter)
return 0; return 0;
@ -100,7 +103,7 @@ int JSI_Main::GetFps(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate))
return g_frequencyFilter->StableFrequency(); return g_frequencyFilter->StableFrequency();
} }
int JSI_Main::GetTextWidth(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& fontName, const std::wstring& text) int GetTextWidth(const std::string& fontName, const std::wstring& text)
{ {
int width = 0; int width = 0;
int height = 0; int height = 0;
@ -110,7 +113,7 @@ int JSI_Main::GetTextWidth(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), c
return width; return width;
} }
std::string JSI_Main::CalculateMD5(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& input) std::string CalculateMD5(const std::string& input)
{ {
u8 digest[MD5::DIGESTSIZE]; u8 digest[MD5::DIGESTSIZE];
@ -121,18 +124,19 @@ std::string JSI_Main::CalculateMD5(ScriptInterface::CmptPrivate* UNUSED(pCmptPri
return Hexify(digest, MD5::DIGESTSIZE); return Hexify(digest, MD5::DIGESTSIZE);
} }
void JSI_Main::RegisterScriptFunctions(const ScriptInterface& scriptInterface) void RegisterScriptFunctions(const ScriptRequest& rq)
{ {
scriptInterface.RegisterFunction<void, &QuitEngine>("Exit"); ScriptFunction::Register<&QuitEngine>(rq, "Exit");
scriptInterface.RegisterFunction<void, &StartAtlas>("RestartInAtlas"); ScriptFunction::Register<&StartAtlas>(rq, "RestartInAtlas");
scriptInterface.RegisterFunction<bool, &AtlasIsAvailable>("AtlasIsAvailable"); ScriptFunction::Register<&AtlasIsAvailable>(rq, "AtlasIsAvailable");
scriptInterface.RegisterFunction<bool, &IsAtlasRunning>("IsAtlasRunning"); ScriptFunction::Register<&IsAtlasRunning>(rq, "IsAtlasRunning");
scriptInterface.RegisterFunction<void, std::string, &OpenURL>("OpenURL"); ScriptFunction::Register<&OpenURL>(rq, "OpenURL");
scriptInterface.RegisterFunction<std::wstring, &GetSystemUsername>("GetSystemUsername"); ScriptFunction::Register<&GetSystemUsername>(rq, "GetSystemUsername");
scriptInterface.RegisterFunction<std::wstring, &GetMatchID>("GetMatchID"); ScriptFunction::Register<&GetMatchID>(rq, "GetMatchID");
scriptInterface.RegisterFunction<JS::Value, VfsPath, &LoadMapSettings>("LoadMapSettings"); ScriptFunction::Register<&LoadMapSettings>(rq, "LoadMapSettings");
scriptInterface.RegisterFunction<bool, std::string, &HotkeyIsPressed_>("HotkeyIsPressed"); ScriptFunction::Register<&HotkeyIsPressed_>(rq, "HotkeyIsPressed");
scriptInterface.RegisterFunction<int, &GetFps>("GetFPS"); ScriptFunction::Register<&GetFps>(rq, "GetFPS");
scriptInterface.RegisterFunction<int, std::string, std::wstring, &GetTextWidth>("GetTextWidth"); ScriptFunction::Register<&GetTextWidth>(rq, "GetTextWidth");
scriptInterface.RegisterFunction<std::string, std::string, &CalculateMD5>("CalculateMD5"); ScriptFunction::Register<&CalculateMD5>(rq, "CalculateMD5");
}
} }

View file

@ -18,24 +18,11 @@
#ifndef INCLUDED_JSI_MAIN #ifndef INCLUDED_JSI_MAIN
#define INCLUDED_JSI_MAIN #define INCLUDED_JSI_MAIN
#include "scriptinterface/ScriptInterface.h" class ScriptRequest;
namespace JSI_Main namespace JSI_Main
{ {
void QuitEngine(ScriptInterface::CmptPrivate* pCmptPrivate); void RegisterScriptFunctions(const ScriptRequest& rq);
void StartAtlas(ScriptInterface::CmptPrivate* pCmptPrivate);
bool AtlasIsAvailable(ScriptInterface::CmptPrivate* pCmptPrivate);
bool IsAtlasRunning(ScriptInterface::CmptPrivate* pCmptPrivate);
void OpenURL(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& url);
std::wstring GetSystemUsername(ScriptInterface::CmptPrivate* pCmptPrivate);
std::wstring GetMatchID(ScriptInterface::CmptPrivate* pCmptPrivate);
JS::Value LoadMapSettings(ScriptInterface::CmptPrivate* pCmptPrivate, const VfsPath& pathname);
bool HotkeyIsPressed_(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& hotkeyName);
int GetFps(ScriptInterface::CmptPrivate* pCmptPrivate);
int GetTextWidth(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& fontName, const std::wstring& text);
std::string CalculateMD5(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& input);
void RegisterScriptFunctions(const ScriptInterface& scriptInterface);
} }
#endif // INCLUDED_JSI_MAIN #endif // INCLUDED_JSI_MAIN

View file

@ -21,8 +21,21 @@
#include "ps/CLogger.h" #include "ps/CLogger.h"
#include "ps/ModIo.h" #include "ps/ModIo.h"
#include "scriptinterface/FunctionWrapper.h"
void JSI_ModIo::StartGetGameId(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) namespace JSI_ModIo
{
ModIo* ModIoGetter(const ScriptRequest&, JS::CallArgs&)
{
if (!g_ModIo)
{
LOGERROR("Trying to access ModIO when it's not initialized!");
return nullptr;
}
return g_ModIo;
}
void StartGetGameId()
{ {
if (!g_ModIo) if (!g_ModIo)
g_ModIo = new ModIo(); g_ModIo = new ModIo();
@ -32,52 +45,8 @@ void JSI_ModIo::StartGetGameId(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate
g_ModIo->StartGetGameId(); g_ModIo->StartGetGameId();
} }
void JSI_ModIo::StartListMods(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) // TODO: could provide a FromJSVal for ModIoModData
{ JS::Value GetMods(const ScriptInterface& scriptInterface)
if (!g_ModIo)
{
LOGERROR("ModIoStartListMods called before ModIoStartGetGameId");
return;
}
g_ModIo->StartListMods();
}
void JSI_ModIo::StartDownloadMod(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), uint32_t idx)
{
if (!g_ModIo)
{
LOGERROR("ModIoStartDownloadMod called before ModIoStartGetGameId");
return;
}
g_ModIo->StartDownloadMod(idx);
}
bool JSI_ModIo::AdvanceRequest(ScriptInterface::CmptPrivate* pCmptPrivate)
{
if (!g_ModIo)
{
LOGERROR("ModIoAdvanceRequest called before ModIoGetMods");
return false;
}
ScriptInterface* scriptInterface = pCmptPrivate->pScriptInterface;
return g_ModIo->AdvanceRequest(*scriptInterface);
}
void JSI_ModIo::CancelRequest(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate))
{
if (!g_ModIo)
{
LOGERROR("ModIoCancelRequest called before ModIoGetMods");
return;
}
g_ModIo->CancelRequest();
}
JS::Value JSI_ModIo::GetMods(ScriptInterface::CmptPrivate* pCmptPrivate)
{ {
if (!g_ModIo) if (!g_ModIo)
{ {
@ -85,7 +54,6 @@ JS::Value JSI_ModIo::GetMods(ScriptInterface::CmptPrivate* pCmptPrivate)
return JS::NullValue(); return JS::NullValue();
} }
ScriptInterface* scriptInterface = pCmptPrivate->pScriptInterface;
ScriptRequest rq(scriptInterface); ScriptRequest rq(scriptInterface);
const std::vector<ModIoModData>& availableMods = g_ModIo->GetMods(); const std::vector<ModIoModData>& availableMods = g_ModIo->GetMods();
@ -100,10 +68,10 @@ JS::Value JSI_ModIo::GetMods(ScriptInterface::CmptPrivate* pCmptPrivate)
ScriptInterface::CreateObject(rq, &m); ScriptInterface::CreateObject(rq, &m);
for (const std::pair<const std::string, std::string>& prop : mod.properties) for (const std::pair<const std::string, std::string>& prop : mod.properties)
scriptInterface->SetProperty(m, prop.first.c_str(), prop.second, true); scriptInterface.SetProperty(m, prop.first.c_str(), prop.second, true);
scriptInterface->SetProperty(m, "dependencies", mod.dependencies, true); scriptInterface.SetProperty(m, "dependencies", mod.dependencies, true);
scriptInterface->SetPropertyInt(mods, i++, m); scriptInterface.SetPropertyInt(mods, i++, m);
} }
return mods; return mods;
@ -123,7 +91,8 @@ const std::map<DownloadProgressStatus, std::string> statusStrings = {
{ DownloadProgressStatus::FAILED_FILECHECK, "failed_filecheck" } { DownloadProgressStatus::FAILED_FILECHECK, "failed_filecheck" }
}; };
JS::Value JSI_ModIo::GetDownloadProgress(ScriptInterface::CmptPrivate* pCmptPrivate) // TODO: could provide a FromJSVal for DownloadProgressData
JS::Value GetDownloadProgress(ScriptInterface::CmptPrivate* pCmptPrivate)
{ {
if (!g_ModIo) if (!g_ModIo)
{ {
@ -145,13 +114,14 @@ JS::Value JSI_ModIo::GetDownloadProgress(ScriptInterface::CmptPrivate* pCmptPriv
return progressData; return progressData;
} }
void JSI_ModIo::RegisterScriptFunctions(const ScriptInterface& scriptInterface) void RegisterScriptFunctions(const ScriptRequest& rq)
{ {
scriptInterface.RegisterFunction<void, &JSI_ModIo::StartGetGameId>("ModIoStartGetGameId"); ScriptFunction::Register<&StartGetGameId>(rq, "ModIoStartGetGameId");
scriptInterface.RegisterFunction<void, &JSI_ModIo::StartListMods>("ModIoStartListMods"); ScriptFunction::Register<&ModIo::StartListMods, &ModIoGetter>(rq, "ModIoStartListMods");
scriptInterface.RegisterFunction<void, uint32_t, &JSI_ModIo::StartDownloadMod>("ModIoStartDownloadMod"); ScriptFunction::Register<&ModIo::StartDownloadMod, &ModIoGetter>(rq, "ModIoStartDownloadMod");
scriptInterface.RegisterFunction<bool, &JSI_ModIo::AdvanceRequest>("ModIoAdvanceRequest"); ScriptFunction::Register<&ModIo::AdvanceRequest, &ModIoGetter>(rq, "ModIoAdvanceRequest");
scriptInterface.RegisterFunction<void, &JSI_ModIo::CancelRequest>("ModIoCancelRequest"); ScriptFunction::Register<&ModIo::CancelRequest, &ModIoGetter>(rq, "ModIoCancelRequest");
scriptInterface.RegisterFunction<JS::Value, &JSI_ModIo::GetMods>("ModIoGetMods"); ScriptFunction::Register<&GetMods>(rq, "ModIoGetMods");
scriptInterface.RegisterFunction<JS::Value, &JSI_ModIo::GetDownloadProgress>("ModIoGetDownloadProgress"); ScriptFunction::Register<&GetDownloadProgress>(rq, "ModIoGetDownloadProgress");
}
} }

View file

@ -18,19 +18,11 @@
#ifndef INCLUDED_JSI_MODIO #ifndef INCLUDED_JSI_MODIO
#define INCLUDED_JSI_MODIO #define INCLUDED_JSI_MODIO
#include "scriptinterface/ScriptInterface.h" class ScriptRequest;
namespace JSI_ModIo namespace JSI_ModIo
{ {
void RegisterScriptFunctions(const ScriptInterface& scriptInterface); void RegisterScriptFunctions(const ScriptRequest& rq);
void StartGetGameId(ScriptInterface::CmptPrivate* pCmptPrivate);
void StartListMods(ScriptInterface::CmptPrivate* pCmptPrivate);
void StartDownloadMod(ScriptInterface::CmptPrivate* pCmptPrivate, uint32_t idx);
bool AdvanceRequest(ScriptInterface::CmptPrivate* pCmptPrivate);
void CancelRequest(ScriptInterface::CmptPrivate* pCmptPrivate);
JS::Value GetMods(ScriptInterface::CmptPrivate* pCmptPrivate);
JS::Value GetDownloadProgress(ScriptInterface::CmptPrivate* pCmptPrivate);
} }
#endif // INCLUDED_JSI_MODIO #endif // INCLUDED_JSI_MODIO

View file

@ -24,35 +24,38 @@
#include "ps/CLogger.h" #include "ps/CLogger.h"
#include "ps/Game.h" #include "ps/Game.h"
#include "ps/SavedGame.h" #include "ps/SavedGame.h"
#include "scriptinterface/FunctionWrapper.h"
#include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptInterface.h"
#include "simulation2/Simulation2.h" #include "simulation2/Simulation2.h"
#include "simulation2/system/TurnManager.h" #include "simulation2/system/TurnManager.h"
JS::Value JSI_SavedGame::GetSavedGames(ScriptInterface::CmptPrivate* pCmptPrivate) namespace JSI_SavedGame
{ {
return SavedGames::GetSavedGames(*(pCmptPrivate->pScriptInterface)); JS::Value GetSavedGames(const ScriptInterface& scriptInterface)
{
return SavedGames::GetSavedGames(scriptInterface);
} }
bool JSI_SavedGame::DeleteSavedGame(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& name) bool DeleteSavedGame(const std::wstring& name)
{ {
return SavedGames::DeleteSavedGame(name); return SavedGames::DeleteSavedGame(name);
} }
void JSI_SavedGame::SaveGame(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filename, const std::wstring& description, JS::HandleValue GUIMetadata) void SaveGame(const ScriptInterface& scriptInterface, const std::wstring& filename, const std::wstring& description, JS::HandleValue GUIMetadata)
{ {
ScriptInterface::StructuredClone GUIMetadataClone = pCmptPrivate->pScriptInterface->WriteStructuredClone(GUIMetadata); ScriptInterface::StructuredClone GUIMetadataClone = scriptInterface.WriteStructuredClone(GUIMetadata);
if (SavedGames::Save(filename, description, *g_Game->GetSimulation2(), GUIMetadataClone) < 0) if (SavedGames::Save(filename, description, *g_Game->GetSimulation2(), GUIMetadataClone) < 0)
LOGERROR("Failed to save game"); LOGERROR("Failed to save game");
} }
void JSI_SavedGame::SaveGamePrefix(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& prefix, const std::wstring& description, JS::HandleValue GUIMetadata) void SaveGamePrefix(const ScriptInterface& scriptInterface, const std::wstring& prefix, const std::wstring& description, JS::HandleValue GUIMetadata)
{ {
ScriptInterface::StructuredClone GUIMetadataClone = pCmptPrivate->pScriptInterface->WriteStructuredClone(GUIMetadata); ScriptInterface::StructuredClone GUIMetadataClone = scriptInterface.WriteStructuredClone(GUIMetadata);
if (SavedGames::SavePrefix(prefix, description, *g_Game->GetSimulation2(), GUIMetadataClone) < 0) if (SavedGames::SavePrefix(prefix, description, *g_Game->GetSimulation2(), GUIMetadataClone) < 0)
LOGERROR("Failed to save game"); LOGERROR("Failed to save game");
} }
void JSI_SavedGame::QuickSave(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), JS::HandleValue GUIMetadata) void QuickSave(JS::HandleValue GUIMetadata)
{ {
if (g_NetServer || g_NetClient) if (g_NetServer || g_NetClient)
LOGERROR("Can't store quicksave during multiplayer!"); LOGERROR("Can't store quicksave during multiplayer!");
@ -62,7 +65,7 @@ void JSI_SavedGame::QuickSave(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)
LOGERROR("Can't store quicksave if game is not running!"); LOGERROR("Can't store quicksave if game is not running!");
} }
void JSI_SavedGame::QuickLoad(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) void QuickLoad()
{ {
if (g_NetServer || g_NetClient) if (g_NetServer || g_NetClient)
LOGERROR("Can't load quicksave during multiplayer!"); LOGERROR("Can't load quicksave during multiplayer!");
@ -72,13 +75,13 @@ void JSI_SavedGame::QuickLoad(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)
LOGERROR("Can't load quicksave if game is not running!"); LOGERROR("Can't load quicksave if game is not running!");
} }
JS::Value JSI_SavedGame::StartSavedGame(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name) JS::Value StartSavedGame(const ScriptInterface& scriptInterface, const std::wstring& name)
{ {
// We need to be careful with different compartments and contexts. // We need to be careful with different compartments and contexts.
// The GUI calls this function from the GUI context and expects the return value in the same context. // The GUI calls this function from the GUI context and expects the return value in the same context.
// The game we start from here creates another context and expects data in this context. // The game we start from here creates another context and expects data in this context.
ScriptRequest rqGui(pCmptPrivate->pScriptInterface); ScriptRequest rqGui(scriptInterface);
ENSURE(!g_NetServer); ENSURE(!g_NetServer);
ENSURE(!g_NetClient); ENSURE(!g_NetClient);
@ -88,7 +91,7 @@ JS::Value JSI_SavedGame::StartSavedGame(ScriptInterface::CmptPrivate* pCmptPriva
// Load the saved game data from disk // Load the saved game data from disk
JS::RootedValue guiContextMetadata(rqGui.cx); JS::RootedValue guiContextMetadata(rqGui.cx);
std::string savedState; std::string savedState;
Status err = SavedGames::Load(name, *(pCmptPrivate->pScriptInterface), &guiContextMetadata, savedState); Status err = SavedGames::Load(name, scriptInterface, &guiContextMetadata, savedState);
if (err < 0) if (err < 0)
return JS::UndefinedValue(); return JS::UndefinedValue();
@ -99,7 +102,7 @@ JS::Value JSI_SavedGame::StartSavedGame(ScriptInterface::CmptPrivate* pCmptPriva
ScriptRequest rqGame(sim->GetScriptInterface()); ScriptRequest rqGame(sim->GetScriptInterface());
JS::RootedValue gameContextMetadata(rqGame.cx, JS::RootedValue gameContextMetadata(rqGame.cx,
sim->GetScriptInterface().CloneValueFromOtherCompartment(*(pCmptPrivate->pScriptInterface), guiContextMetadata)); sim->GetScriptInterface().CloneValueFromOtherCompartment(scriptInterface, guiContextMetadata));
JS::RootedValue gameInitAttributes(rqGame.cx); JS::RootedValue gameInitAttributes(rqGame.cx);
sim->GetScriptInterface().GetProperty(gameContextMetadata, "initAttributes", &gameInitAttributes); sim->GetScriptInterface().GetProperty(gameContextMetadata, "initAttributes", &gameInitAttributes);
@ -113,21 +116,22 @@ JS::Value JSI_SavedGame::StartSavedGame(ScriptInterface::CmptPrivate* pCmptPriva
return guiContextMetadata; return guiContextMetadata;
} }
void ActivateRejoinTest(ScriptInterface::CmptPrivate*) void ActivateRejoinTest()
{ {
if (!g_Game || !g_Game->GetSimulation2() || !g_Game->GetTurnManager()) if (!g_Game || !g_Game->GetSimulation2() || !g_Game->GetTurnManager())
return; return;
g_Game->GetSimulation2()->ActivateRejoinTest(g_Game->GetTurnManager()->GetCurrentTurn() + 1); g_Game->GetSimulation2()->ActivateRejoinTest(g_Game->GetTurnManager()->GetCurrentTurn() + 1);
} }
void JSI_SavedGame::RegisterScriptFunctions(const ScriptInterface& scriptInterface) void RegisterScriptFunctions(const ScriptRequest& rq)
{ {
scriptInterface.RegisterFunction<JS::Value, &GetSavedGames>("GetSavedGames"); ScriptFunction::Register<&GetSavedGames>(rq, "GetSavedGames");
scriptInterface.RegisterFunction<bool, std::wstring, &DeleteSavedGame>("DeleteSavedGame"); ScriptFunction::Register<&DeleteSavedGame>(rq, "DeleteSavedGame");
scriptInterface.RegisterFunction<void, std::wstring, std::wstring, JS::HandleValue, &SaveGame>("SaveGame"); ScriptFunction::Register<&SaveGame>(rq, "SaveGame");
scriptInterface.RegisterFunction<void, std::wstring, std::wstring, JS::HandleValue, &SaveGamePrefix>("SaveGamePrefix"); ScriptFunction::Register<&SaveGamePrefix>(rq, "SaveGamePrefix");
scriptInterface.RegisterFunction<void, JS::HandleValue, &QuickSave>("QuickSave"); ScriptFunction::Register<&QuickSave>(rq, "QuickSave");
scriptInterface.RegisterFunction<void, &QuickLoad>("QuickLoad"); ScriptFunction::Register<&QuickLoad>(rq, "QuickLoad");
scriptInterface.RegisterFunction<void, &ActivateRejoinTest>("ActivateRejoinTest"); ScriptFunction::Register<&ActivateRejoinTest>(rq, "ActivateRejoinTest");
scriptInterface.RegisterFunction<JS::Value, std::wstring, &StartSavedGame>("StartSavedGame"); ScriptFunction::Register<&StartSavedGame>(rq, "StartSavedGame");
}
} }

View file

@ -18,19 +18,11 @@
#ifndef INCLUDED_JSI_SAVEDGAME #ifndef INCLUDED_JSI_SAVEDGAME
#define INCLUDED_JSI_SAVEDGAME #define INCLUDED_JSI_SAVEDGAME
#include "scriptinterface/ScriptInterface.h" class ScriptRequest;
namespace JSI_SavedGame namespace JSI_SavedGame
{ {
JS::Value GetSavedGames(ScriptInterface::CmptPrivate* pCmptPrivate); void RegisterScriptFunctions(const ScriptRequest& rq);
bool DeleteSavedGame(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name);
void SaveGame(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filename, const std::wstring& description, JS::HandleValue GUIMetadata);
void SaveGamePrefix(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& prefix, const std::wstring& description, JS::HandleValue GUIMetadata);
void QuickSave(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue GUIMetadata);
void QuickLoad(ScriptInterface::CmptPrivate* pCmptPrivate);
JS::Value StartSavedGame(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name);
void RegisterScriptFunctions(const ScriptInterface& scriptInterface);
} }
#endif // INCLUDED_JSI_SAVEDGAME #endif // INCLUDED_JSI_SAVEDGAME

View file

@ -22,42 +22,46 @@
#include "ps/Filesystem.h" #include "ps/Filesystem.h"
#include "ps/Pyrogenesis.h" #include "ps/Pyrogenesis.h"
#include "ps/UserReport.h" #include "ps/UserReport.h"
#include "scriptinterface/FunctionWrapper.h"
#include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptInterface.h"
#include <string> #include <string>
bool JSI_UserReport::IsUserReportEnabled(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) namespace JSI_UserReport
{
bool IsUserReportEnabled()
{ {
return g_UserReporter.IsReportingEnabled(); return g_UserReporter.IsReportingEnabled();
} }
void JSI_UserReport::SetUserReportEnabled(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), bool enabled) void SetUserReportEnabled(bool enabled)
{ {
g_UserReporter.SetReportingEnabled(enabled); g_UserReporter.SetReportingEnabled(enabled);
} }
std::string JSI_UserReport::GetUserReportStatus(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) std::string GetUserReportStatus()
{ {
return g_UserReporter.GetStatus(); return g_UserReporter.GetStatus();
} }
std::string JSI_UserReport::GetUserReportLogPath(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) std::string GetUserReportLogPath()
{ {
return psLogDir().string8(); return psLogDir().string8();
} }
std::string JSI_UserReport::GetUserReportConfigPath(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) std::string GetUserReportConfigPath()
{ {
OsPath configPath; OsPath configPath;
WARN_IF_ERR(g_VFS->GetDirectoryRealPath("config/", configPath)); WARN_IF_ERR(g_VFS->GetDirectoryRealPath("config/", configPath));
return configPath.string8(); return configPath.string8();
} }
void JSI_UserReport::RegisterScriptFunctions(const ScriptInterface& scriptInterface) void RegisterScriptFunctions(const ScriptRequest& rq)
{ {
scriptInterface.RegisterFunction<bool, &IsUserReportEnabled>("IsUserReportEnabled"); ScriptFunction::Register<&IsUserReportEnabled>(rq, "IsUserReportEnabled");
scriptInterface.RegisterFunction<void, bool, &SetUserReportEnabled>("SetUserReportEnabled"); ScriptFunction::Register<&SetUserReportEnabled>(rq, "SetUserReportEnabled");
scriptInterface.RegisterFunction<std::string, &GetUserReportStatus>("GetUserReportStatus"); ScriptFunction::Register<&GetUserReportStatus>(rq, "GetUserReportStatus");
scriptInterface.RegisterFunction<std::string, &GetUserReportLogPath>("GetUserReportLogPath"); ScriptFunction::Register<&GetUserReportLogPath>(rq, "GetUserReportLogPath");
scriptInterface.RegisterFunction<std::string, &GetUserReportConfigPath>("GetUserReportConfigPath"); ScriptFunction::Register<&GetUserReportConfigPath>(rq, "GetUserReportConfigPath");
}
} }

View file

@ -18,19 +18,11 @@
#ifndef INCLUDED_JSI_USERREPORT #ifndef INCLUDED_JSI_USERREPORT
#define INCLUDED_JSI_USERREPORT #define INCLUDED_JSI_USERREPORT
#include "scriptinterface/ScriptInterface.h" class ScriptRequest;
#include <string>
namespace JSI_UserReport namespace JSI_UserReport
{ {
bool IsUserReportEnabled(ScriptInterface::CmptPrivate* pCmptPrivate); void RegisterScriptFunctions(const ScriptRequest& rq);
void SetUserReportEnabled(ScriptInterface::CmptPrivate* pCmptPrivate, bool enabled);
std::string GetUserReportStatus(ScriptInterface::CmptPrivate* pCmptPrivate);
std::string GetUserReportLogPath(ScriptInterface::CmptPrivate* pCmptPrivate);
std::string GetUserReportConfigPath(ScriptInterface::CmptPrivate* pCmptPrivate);
void RegisterScriptFunctions(const ScriptInterface& ScriptInterface);
} }
#endif // INCLUDED_JSI_USERREPORT #endif // INCLUDED_JSI_USERREPORT

View file

@ -23,11 +23,14 @@
#include "ps/CLogger.h" #include "ps/CLogger.h"
#include "ps/CStr.h" #include "ps/CStr.h"
#include "ps/Filesystem.h" #include "ps/Filesystem.h"
#include "scriptinterface/FunctionWrapper.h"
#include "scriptinterface/ScriptExtraHeaders.h" #include "scriptinterface/ScriptExtraHeaders.h"
#include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptInterface.h"
#include <sstream> #include <sstream>
namespace JSI_VFS
{
// Only allow engine compartments to read files they may be concerned about. // Only allow engine compartments to read files they may be concerned about.
#define PathRestriction_GUI {L""} #define PathRestriction_GUI {L""}
#define PathRestriction_Simulation {L"simulation/"} #define PathRestriction_Simulation {L"simulation/"}
@ -46,19 +49,40 @@
/* else: success */ /* else: success */
// Tests whether the current script context is allowed to read from the given directory
bool PathRestrictionMet(const ScriptRequest& rq, const std::vector<CStrW>& validPaths, const CStrW& filePath)
{
for (const CStrW& validPath : validPaths)
if (filePath.find(validPath) == 0)
return true;
CStrW allowedPaths;
for (std::size_t i = 0; i < validPaths.size(); ++i)
{
if (i != 0)
allowedPaths += L", ";
allowedPaths += L"\"" + validPaths[i] + L"\"";
}
ScriptException::Raise(rq, "This part of the engine may only read from %s!", utf8_from_wstring(allowedPaths).c_str());
return false;
}
// state held across multiple BuildDirEntListCB calls; init by BuildDirEntList. // state held across multiple BuildDirEntListCB calls; init by BuildDirEntList.
struct BuildDirEntListState struct BuildDirEntListState
{ {
ScriptInterface* pScriptInterface; const ScriptRequest& rq;
JS::PersistentRootedObject filename_array; JS::PersistentRootedObject filename_array;
int cur_idx; int cur_idx;
BuildDirEntListState(ScriptInterface* scriptInterface) BuildDirEntListState(const ScriptRequest& rq)
: pScriptInterface(scriptInterface), : rq(rq),
filename_array(scriptInterface->GetGeneralJSContext()), filename_array(rq.cx),
cur_idx(0) cur_idx(0)
{ {
ScriptRequest rq(pScriptInterface);
filename_array = JS::NewArrayObject(rq.cx, JS::HandleValueArray::empty()); filename_array = JS::NewArrayObject(rq.cx, JS::HandleValueArray::empty());
} }
}; };
@ -67,12 +91,11 @@ struct BuildDirEntListState
static Status BuildDirEntListCB(const VfsPath& pathname, const CFileInfo& UNUSED(fileINfo), uintptr_t cbData) static Status BuildDirEntListCB(const VfsPath& pathname, const CFileInfo& UNUSED(fileINfo), uintptr_t cbData)
{ {
BuildDirEntListState* s = (BuildDirEntListState*)cbData; BuildDirEntListState* s = (BuildDirEntListState*)cbData;
ScriptRequest rq(s->pScriptInterface);
JS::RootedObject filenameArrayObj(rq.cx, s->filename_array); JS::RootedObject filenameArrayObj(s->rq.cx, s->filename_array);
JS::RootedValue val(rq.cx); JS::RootedValue val(s->rq.cx);
ScriptInterface::ToJSVal(rq, &val, CStrW(pathname.string()) ); ScriptInterface::ToJSVal(s->rq, &val, CStrW(pathname.string()) );
JS_SetElement(rq.cx, filenameArrayObj, s->cur_idx++, val); JS_SetElement(s->rq.cx, filenameArrayObj, s->cur_idx++, val);
return INFO::OK; return INFO::OK;
} }
@ -81,9 +104,9 @@ static Status BuildDirEntListCB(const VfsPath& pathname, const CFileInfo& UNUSED
// specified directory. // specified directory.
// filter_string: default "" matches everything; otherwise, see vfs_next_dirent. // filter_string: default "" matches everything; otherwise, see vfs_next_dirent.
// recurse: should subdirectories be included in the search? default false. // recurse: should subdirectories be included in the search? default false.
JS::Value JSI_VFS::BuildDirEntList(ScriptInterface::CmptPrivate* pCmptPrivate, const std::vector<CStrW>& validPaths, const std::wstring& path, const std::wstring& filterStr, bool recurse) JS::Value BuildDirEntList(const ScriptRequest& rq, const std::vector<CStrW>& validPaths, const std::wstring& path, const std::wstring& filterStr, bool recurse)
{ {
if (!PathRestrictionMet(pCmptPrivate, validPaths, path)) if (!PathRestrictionMet(rq, validPaths, path))
return JS::NullValue(); return JS::NullValue();
// convert to const wchar_t*; if there's no filter, pass 0 for speed // convert to const wchar_t*; if there's no filter, pass 0 for speed
@ -95,20 +118,20 @@ JS::Value JSI_VFS::BuildDirEntList(ScriptInterface::CmptPrivate* pCmptPrivate, c
int flags = recurse ? vfs::DIR_RECURSIVE : 0; int flags = recurse ? vfs::DIR_RECURSIVE : 0;
// build array in the callback function // build array in the callback function
BuildDirEntListState state(pCmptPrivate->pScriptInterface); BuildDirEntListState state(rq);
vfs::ForEachFile(g_VFS, path, BuildDirEntListCB, (uintptr_t)&state, filter, flags); vfs::ForEachFile(g_VFS, path, BuildDirEntListCB, (uintptr_t)&state, filter, flags);
return JS::ObjectValue(*state.filename_array); return JS::ObjectValue(*state.filename_array);
} }
// Return true iff the file exits // Return true iff the file exits
bool JSI_VFS::FileExists(ScriptInterface::CmptPrivate* pCmptPrivate, const std::vector<CStrW>& validPaths, const CStrW& filename) bool FileExists(const ScriptRequest& rq, const std::vector<CStrW>& validPaths, const CStrW& filename)
{ {
return PathRestrictionMet(pCmptPrivate, validPaths, filename) && g_VFS->GetFileInfo(filename, 0) == INFO::OK; return PathRestrictionMet(rq, validPaths, filename) && g_VFS->GetFileInfo(filename, 0) == INFO::OK;
} }
// Return time [seconds since 1970] of the last modification to the specified file. // Return time [seconds since 1970] of the last modification to the specified file.
double JSI_VFS::GetFileMTime(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& filename) double GetFileMTime(const std::wstring& filename)
{ {
CFileInfo fileInfo; CFileInfo fileInfo;
Status err = g_VFS->GetFileInfo(filename, &fileInfo); Status err = g_VFS->GetFileInfo(filename, &fileInfo);
@ -118,7 +141,7 @@ double JSI_VFS::GetFileMTime(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate),
} }
// Return current size of file. // Return current size of file.
unsigned int JSI_VFS::GetFileSize(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& filename) unsigned int GetFileSize(const std::wstring& filename)
{ {
CFileInfo fileInfo; CFileInfo fileInfo;
Status err = g_VFS->GetFileInfo(filename, &fileInfo); Status err = g_VFS->GetFileInfo(filename, &fileInfo);
@ -128,7 +151,7 @@ unsigned int JSI_VFS::GetFileSize(ScriptInterface::CmptPrivate* UNUSED(pCmptPriv
} }
// Return file contents in a string. Assume file is UTF-8 encoded text. // Return file contents in a string. Assume file is UTF-8 encoded text.
JS::Value JSI_VFS::ReadFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filename) JS::Value ReadFile(const ScriptRequest& rq, const std::wstring& filename)
{ {
CVFSFile file; CVFSFile file;
if (file.Load(g_VFS, filename) != PSRETURN_OK) if (file.Load(g_VFS, filename) != PSRETURN_OK)
@ -140,14 +163,13 @@ JS::Value JSI_VFS::ReadFile(ScriptInterface::CmptPrivate* pCmptPrivate, const st
contents.Replace("\r\n", "\n"); contents.Replace("\r\n", "\n");
// Decode as UTF-8 // Decode as UTF-8
ScriptRequest rq(pCmptPrivate->pScriptInterface);
JS::RootedValue ret(rq.cx); JS::RootedValue ret(rq.cx);
ScriptInterface::ToJSVal(rq, &ret, contents.FromUTF8()); ScriptInterface::ToJSVal(rq, &ret, contents.FromUTF8());
return ret; return ret;
} }
// Return file contents as an array of lines. Assume file is UTF-8 encoded text. // Return file contents as an array of lines. Assume file is UTF-8 encoded text.
JS::Value JSI_VFS::ReadFileLines(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filename) JS::Value ReadFileLines(const ScriptInterface& scriptInterface, const std::wstring& filename)
{ {
CVFSFile file; CVFSFile file;
if (file.Load(g_VFS, filename) != PSRETURN_OK) if (file.Load(g_VFS, filename) != PSRETURN_OK)
@ -161,7 +183,6 @@ JS::Value JSI_VFS::ReadFileLines(ScriptInterface::CmptPrivate* pCmptPrivate, con
// split into array of strings (one per line) // split into array of strings (one per line)
std::stringstream ss(contents); std::stringstream ss(contents);
const ScriptInterface& scriptInterface = *pCmptPrivate->pScriptInterface;
ScriptRequest rq(scriptInterface); ScriptRequest rq(scriptInterface);
JS::RootedValue line_array(rq.cx); JS::RootedValue line_array(rq.cx);
@ -181,21 +202,21 @@ JS::Value JSI_VFS::ReadFileLines(ScriptInterface::CmptPrivate* pCmptPrivate, con
return line_array; return line_array;
} }
JS::Value JSI_VFS::ReadJSONFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::vector<CStrW>& validPaths, const CStrW& filePath) // Return file contents parsed as a JS Object
JS::Value ReadJSONFile(const ScriptInterface& scriptInterface, const std::vector<CStrW>& validPaths, const CStrW& filePath)
{ {
if (!PathRestrictionMet(pCmptPrivate, validPaths, filePath)) ScriptRequest rq(scriptInterface);
if (!PathRestrictionMet(rq, validPaths, filePath))
return JS::NullValue(); return JS::NullValue();
const ScriptInterface& scriptInterface = *pCmptPrivate->pScriptInterface;
ScriptRequest rq(scriptInterface);
JS::RootedValue out(rq.cx); JS::RootedValue out(rq.cx);
scriptInterface.ReadJSONFile(filePath, &out); scriptInterface.ReadJSONFile(filePath, &out);
return out; return out;
} }
void JSI_VFS::WriteJSONFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filePath, JS::HandleValue val1) // Save given JS Object to a JSON file
void WriteJSONFile(const ScriptInterface& scriptInterface, const std::wstring& filePath, JS::HandleValue val1)
{ {
const ScriptInterface& scriptInterface = *pCmptPrivate->pScriptInterface;
ScriptRequest rq(scriptInterface); ScriptRequest rq(scriptInterface);
// TODO: This is a workaround because we need to pass a MutableHandle to StringifyJSON. // TODO: This is a workaround because we need to pass a MutableHandle to StringifyJSON.
@ -209,7 +230,7 @@ void JSI_VFS::WriteJSONFile(ScriptInterface::CmptPrivate* pCmptPrivate, const st
g_VFS->CreateFile(path, buf.Data(), buf.Size()); g_VFS->CreateFile(path, buf.Data(), buf.Size());
} }
bool JSI_VFS::DeleteCampaignSave(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const CStrW& filePath) bool DeleteCampaignSave(const CStrW& filePath)
{ {
OsPath realPath; OsPath realPath;
if (filePath.Left(16) != L"saves/campaigns/" || filePath.Right(12) != L".0adcampaign") if (filePath.Left(16) != L"saves/campaigns/" || filePath.Right(12) != L".0adcampaign")
@ -221,39 +242,18 @@ bool JSI_VFS::DeleteCampaignSave(ScriptInterface::CmptPrivate* UNUSED(pCmptPriva
wunlink(realPath) == 0; wunlink(realPath) == 0;
} }
bool JSI_VFS::PathRestrictionMet(ScriptInterface::CmptPrivate* pCmptPrivate, const std::vector<CStrW>& validPaths, const CStrW& filePath)
{
for (const CStrW& validPath : validPaths)
if (filePath.find(validPath) == 0)
return true;
CStrW allowedPaths;
for (std::size_t i = 0; i < validPaths.size(); ++i)
{
if (i != 0)
allowedPaths += L", ";
allowedPaths += L"\"" + validPaths[i] + L"\"";
}
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "This part of the engine may only read from %s!", utf8_from_wstring(allowedPaths).c_str());
return false;
}
#define VFS_ScriptFunctions(context)\ #define VFS_ScriptFunctions(context)\
JS::Value Script_ReadJSONFile_##context(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filePath)\ JS::Value Script_ReadJSONFile_##context(const ScriptInterface& scriptInterface, const std::wstring& filePath)\
{\ {\
return JSI_VFS::ReadJSONFile(pCmptPrivate, PathRestriction_##context, filePath);\ return ReadJSONFile(scriptInterface, PathRestriction_##context, filePath);\
}\ }\
JS::Value Script_ListDirectoryFiles_##context(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& path, const std::wstring& filterStr, bool recurse)\ JS::Value Script_ListDirectoryFiles_##context(const ScriptInterface& scriptInterface, const std::wstring& path, const std::wstring& filterStr, bool recurse)\
{\ {\
return JSI_VFS::BuildDirEntList(pCmptPrivate, PathRestriction_##context, path, filterStr, recurse);\ return BuildDirEntList(scriptInterface, PathRestriction_##context, path, filterStr, recurse);\
}\ }\
bool Script_FileExists_##context(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filePath)\ bool Script_FileExists_##context(const ScriptInterface& scriptInterface, const std::wstring& filePath)\
{\ {\
return JSI_VFS::FileExists(pCmptPrivate, PathRestriction_##context, filePath);\ return FileExists(scriptInterface, PathRestriction_##context, filePath);\
}\ }\
VFS_ScriptFunctions(GUI); VFS_ScriptFunctions(GUI);
@ -261,29 +261,30 @@ VFS_ScriptFunctions(Simulation);
VFS_ScriptFunctions(Maps); VFS_ScriptFunctions(Maps);
#undef VFS_ScriptFunctions #undef VFS_ScriptFunctions
void JSI_VFS::RegisterScriptFunctions_GUI(const ScriptInterface& scriptInterface) void RegisterScriptFunctions_GUI(const ScriptRequest& rq)
{ {
scriptInterface.RegisterFunction<JS::Value, std::wstring, std::wstring, bool, &Script_ListDirectoryFiles_GUI>("ListDirectoryFiles"); ScriptFunction::Register<&Script_ListDirectoryFiles_GUI>(rq, "ListDirectoryFiles");
scriptInterface.RegisterFunction<bool, std::wstring, Script_FileExists_GUI>("FileExists"); ScriptFunction::Register<&Script_FileExists_GUI>(rq, "FileExists");
scriptInterface.RegisterFunction<double, std::wstring, &JSI_VFS::GetFileMTime>("GetFileMTime"); ScriptFunction::Register<&GetFileMTime>(rq, "GetFileMTime");
scriptInterface.RegisterFunction<unsigned int, std::wstring, &JSI_VFS::GetFileSize>("GetFileSize"); ScriptFunction::Register<&GetFileSize>(rq, "GetFileSize");
scriptInterface.RegisterFunction<JS::Value, std::wstring, &JSI_VFS::ReadFile>("ReadFile"); ScriptFunction::Register<&ReadFile>(rq, "ReadFile");
scriptInterface.RegisterFunction<JS::Value, std::wstring, &JSI_VFS::ReadFileLines>("ReadFileLines"); ScriptFunction::Register<&ReadFileLines>(rq, "ReadFileLines");
scriptInterface.RegisterFunction<JS::Value, std::wstring, &Script_ReadJSONFile_GUI>("ReadJSONFile"); ScriptFunction::Register<&Script_ReadJSONFile_GUI>(rq, "ReadJSONFile");
scriptInterface.RegisterFunction<void, std::wstring, JS::HandleValue, &WriteJSONFile>("WriteJSONFile"); ScriptFunction::Register<&WriteJSONFile>(rq, "WriteJSONFile");
scriptInterface.RegisterFunction<bool, CStrW, &DeleteCampaignSave>("DeleteCampaignSave"); ScriptFunction::Register<&DeleteCampaignSave>(rq, "DeleteCampaignSave");
} }
void JSI_VFS::RegisterScriptFunctions_Simulation(const ScriptInterface& scriptInterface) void RegisterScriptFunctions_Simulation(const ScriptRequest& rq)
{ {
scriptInterface.RegisterFunction<JS::Value, std::wstring, std::wstring, bool, &Script_ListDirectoryFiles_Simulation>("ListDirectoryFiles"); ScriptFunction::Register<&Script_ListDirectoryFiles_Simulation>(rq, "ListDirectoryFiles");
scriptInterface.RegisterFunction<bool, std::wstring, Script_FileExists_Simulation>("FileExists"); ScriptFunction::Register<&Script_FileExists_Simulation>(rq, "FileExists");
scriptInterface.RegisterFunction<JS::Value, std::wstring, &Script_ReadJSONFile_Simulation>("ReadJSONFile"); ScriptFunction::Register<&Script_ReadJSONFile_Simulation>(rq, "ReadJSONFile");
} }
void JSI_VFS::RegisterScriptFunctions_Maps(const ScriptInterface& scriptInterface) void RegisterScriptFunctions_Maps(const ScriptRequest& rq)
{ {
scriptInterface.RegisterFunction<JS::Value, std::wstring, std::wstring, bool, &Script_ListDirectoryFiles_Maps>("ListDirectoryFiles"); ScriptFunction::Register<&Script_ListDirectoryFiles_Maps>(rq, "ListDirectoryFiles");
scriptInterface.RegisterFunction<bool, std::wstring, Script_FileExists_Maps>("FileExists"); ScriptFunction::Register<&Script_FileExists_Maps>(rq, "FileExists");
scriptInterface.RegisterFunction<JS::Value, std::wstring, &Script_ReadJSONFile_Maps>("ReadJSONFile"); ScriptFunction::Register<&Script_ReadJSONFile_Maps>(rq, "ReadJSONFile");
}
} }

View file

@ -18,45 +18,13 @@
#ifndef INCLUDED_JSI_VFS #ifndef INCLUDED_JSI_VFS
#define INCLUDED_JSI_VFS #define INCLUDED_JSI_VFS
#include "scriptinterface/ScriptInterface.h" class ScriptRequest;
namespace JSI_VFS namespace JSI_VFS
{ {
// Return an array of pathname strings, one for each matching entry in the void RegisterScriptFunctions_GUI(const ScriptRequest& rq);
// specified directory. void RegisterScriptFunctions_Simulation(const ScriptRequest& rq);
JS::Value BuildDirEntList(ScriptInterface::CmptPrivate* pCmptPrivate, const std::vector<CStrW>& validPaths, const std::wstring& path, const std::wstring& filterStr, bool recurse); void RegisterScriptFunctions_Maps(const ScriptRequest& rq);
// Return true iff the file exists
bool FileExists(ScriptInterface::CmptPrivate* pCmptPrivate, const std::vector<CStrW>& validPaths, const CStrW& filename);
// Return time [seconds since 1970] of the last modification to the specified file.
double GetFileMTime(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filename);
// Return current size of file.
unsigned int GetFileSize(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filename);
// Return file contents in a string.
JS::Value ReadFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filename);
// Return file contents as an array of lines.
JS::Value ReadFileLines(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filename);
// Return file contents parsed as a JS Object
JS::Value ReadJSONFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::vector<CStrW>& validPaths, const CStrW& filePath);
// Save given JS Object to a JSON file
void WriteJSONFile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filePath, JS::HandleValue val1);
// Delete the given campaign save.
// This is limited to campaign save to avoid mods deleting the wrong file.
bool DeleteCampaignSave(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& filePath);
// Tests whether the current script context is allowed to read from the given directory
bool PathRestrictionMet(ScriptInterface::CmptPrivate* pCmptPrivate, const std::vector<CStrW>& validPaths, const CStrW& filePath);
void RegisterScriptFunctions_GUI(const ScriptInterface& scriptInterface);
void RegisterScriptFunctions_Simulation(const ScriptInterface& scriptInterface);
void RegisterScriptFunctions_Maps(const ScriptInterface& scriptInterface);
} }
#endif // INCLUDED_JSI_VFS #endif // INCLUDED_JSI_VFS

View file

@ -21,56 +21,25 @@
#include "ps/CStr.h" #include "ps/CStr.h"
#include "ps/VisualReplay.h" #include "ps/VisualReplay.h"
#include "scriptinterface/FunctionWrapper.h"
#include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptInterface.h"
bool JSI_VisualReplay::StartVisualReplay(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const CStrW& directory) namespace JSI_VisualReplay
{ {
return VisualReplay::StartVisualReplay(directory); CStrW GetReplayDirectoryName(const CStrW& directoryName)
{
return OsPath(VisualReplay::GetDirectoryPath() / directoryName).string();
} }
bool JSI_VisualReplay::DeleteReplay(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const CStrW& replayFile) void RegisterScriptFunctions(const ScriptRequest& rq)
{ {
return VisualReplay::DeleteReplay(replayFile); ScriptFunction::Register<&VisualReplay::GetReplays>(rq, "GetReplays");
ScriptFunction::Register<&VisualReplay::DeleteReplay>(rq, "DeleteReplay");
ScriptFunction::Register<&VisualReplay::StartVisualReplay>(rq, "StartVisualReplay");
ScriptFunction::Register<&VisualReplay::GetReplayAttributes>(rq, "GetReplayAttributes");
ScriptFunction::Register<&VisualReplay::GetReplayMetadata>(rq, "GetReplayMetadata");
ScriptFunction::Register<&VisualReplay::HasReplayMetadata>(rq, "HasReplayMetadata");
ScriptFunction::Register<&VisualReplay::AddReplayToCache>(rq, "AddReplayToCache");
ScriptFunction::Register<&GetReplayDirectoryName>(rq, "GetReplayDirectoryName");
} }
JS::Value JSI_VisualReplay::GetReplays(ScriptInterface::CmptPrivate* pCmptPrivate, bool compareFiles)
{
return VisualReplay::GetReplays(*(pCmptPrivate->pScriptInterface), compareFiles);
}
JS::Value JSI_VisualReplay::GetReplayAttributes(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& directoryName)
{
return VisualReplay::GetReplayAttributes(pCmptPrivate, directoryName);
}
bool JSI_VisualReplay::HasReplayMetadata(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const CStrW& directoryName)
{
return VisualReplay::HasReplayMetadata(directoryName);
}
JS::Value JSI_VisualReplay::GetReplayMetadata(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& directoryName)
{
return VisualReplay::GetReplayMetadata(pCmptPrivate, directoryName);
}
void JSI_VisualReplay::AddReplayToCache(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& directoryName)
{
VisualReplay::AddReplayToCache(*(pCmptPrivate->pScriptInterface), directoryName);
}
CStrW JSI_VisualReplay::GetReplayDirectoryName(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const CStrW& directoryName)
{
return wstring_from_utf8(OsPath(VisualReplay::GetDirectoryPath() / directoryName).string8());
}
void JSI_VisualReplay::RegisterScriptFunctions(const ScriptInterface& scriptInterface)
{
scriptInterface.RegisterFunction<JS::Value, bool, &GetReplays>("GetReplays");
scriptInterface.RegisterFunction<bool, CStrW, &DeleteReplay>("DeleteReplay");
scriptInterface.RegisterFunction<bool, CStrW, &StartVisualReplay>("StartVisualReplay");
scriptInterface.RegisterFunction<JS::Value, CStrW, &GetReplayAttributes>("GetReplayAttributes");
scriptInterface.RegisterFunction<JS::Value, CStrW, &GetReplayMetadata>("GetReplayMetadata");
scriptInterface.RegisterFunction<bool, CStrW, &HasReplayMetadata>("HasReplayMetadata");
scriptInterface.RegisterFunction<void, CStrW, &AddReplayToCache>("AddReplayToCache");
scriptInterface.RegisterFunction<CStrW, CStrW, &GetReplayDirectoryName>("GetReplayDirectoryName");
} }

View file

@ -18,19 +18,11 @@
#ifndef INCLUDED_JSI_VISUALREPLAY #ifndef INCLUDED_JSI_VISUALREPLAY
#define INCLUDED_JSI_VISUALREPLAY #define INCLUDED_JSI_VISUALREPLAY
#include "scriptinterface/ScriptInterface.h" class ScriptRequest;
namespace JSI_VisualReplay namespace JSI_VisualReplay
{ {
bool StartVisualReplay(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& directory); void RegisterScriptFunctions(const ScriptRequest& rq);
bool DeleteReplay(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& replayFile);
JS::Value GetReplays(ScriptInterface::CmptPrivate* pCmptPrivate, bool compareFiles);
JS::Value GetReplayAttributes(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& directoryName);
bool HasReplayMetadata(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& directoryName);
JS::Value GetReplayMetadata(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& directoryName);
void AddReplayToCache(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& directoryName);
void RegisterScriptFunctions(const ScriptInterface& scriptInterface);
CStrW GetReplayDirectoryName(ScriptInterface::CmptPrivate* pCmptPrivate, const CStrW& directoryName);
} }
#endif // INCLUDED_JSI_VISUALREPLAY #endif // INCLUDED_JSI_VISUALREPLAY

View file

@ -22,15 +22,17 @@
#include "graphics/TextureManager.h" #include "graphics/TextureManager.h"
#include "renderer/RenderingOptions.h" #include "renderer/RenderingOptions.h"
#include "renderer/Renderer.h" #include "renderer/Renderer.h"
#include "scriptinterface/ScriptInterface.h" #include "scriptinterface/FunctionWrapper.h"
namespace JSI_Renderer
{
#define IMPLEMENT_BOOLEAN_SCRIPT_SETTING(NAME) \ #define IMPLEMENT_BOOLEAN_SCRIPT_SETTING(NAME) \
bool Get##NAME##Enabled(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) \ bool Get##NAME##Enabled() \
{ \ { \
return g_RenderingOptions.Get##NAME(); \ return g_RenderingOptions.Get##NAME(); \
} \ } \
\ \
void Set##NAME##Enabled(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), bool enabled) \ void Set##NAME##Enabled(bool enabled) \
{ \ { \
g_RenderingOptions.Set##NAME(enabled); \ g_RenderingOptions.Set##NAME(enabled); \
} }
@ -40,26 +42,27 @@ IMPLEMENT_BOOLEAN_SCRIPT_SETTING(DisplayShadowsFrustum);
#undef IMPLEMENT_BOOLEAN_SCRIPT_SETTING #undef IMPLEMENT_BOOLEAN_SCRIPT_SETTING
std::string JSI_Renderer::GetRenderPath(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) std::string GetRenderPath()
{ {
return RenderPathEnum::ToString(g_RenderingOptions.GetRenderPath()); return RenderPathEnum::ToString(g_RenderingOptions.GetRenderPath());
} }
bool JSI_Renderer::TextureExists(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& filename) bool TextureExists(const std::wstring& filename)
{ {
return g_Renderer.GetTextureManager().TextureExists(filename); return g_Renderer.GetTextureManager().TextureExists(filename);
} }
#define REGISTER_BOOLEAN_SCRIPT_SETTING(NAME) \ #define REGISTER_BOOLEAN_SCRIPT_SETTING(NAME) \
scriptInterface.RegisterFunction<bool, &Get##NAME##Enabled>("Renderer_Get" #NAME "Enabled"); \ ScriptFunction::Register<&Get##NAME##Enabled>(rq, "Renderer_Get" #NAME "Enabled"); \
scriptInterface.RegisterFunction<void, bool, &Set##NAME##Enabled>("Renderer_Set" #NAME "Enabled"); ScriptFunction::Register<&Set##NAME##Enabled>(rq, "Renderer_Set" #NAME "Enabled");
void JSI_Renderer::RegisterScriptFunctions(const ScriptInterface& scriptInterface) void RegisterScriptFunctions(const ScriptRequest& rq)
{ {
scriptInterface.RegisterFunction<std::string, &JSI_Renderer::GetRenderPath>("Renderer_GetRenderPath"); ScriptFunction::Register<&GetRenderPath>(rq, "Renderer_GetRenderPath");
scriptInterface.RegisterFunction<bool, std::wstring, &JSI_Renderer::TextureExists>("TextureExists"); ScriptFunction::Register<&TextureExists>(rq, "TextureExists");
REGISTER_BOOLEAN_SCRIPT_SETTING(DisplayFrustum); REGISTER_BOOLEAN_SCRIPT_SETTING(DisplayFrustum);
REGISTER_BOOLEAN_SCRIPT_SETTING(DisplayShadowsFrustum); REGISTER_BOOLEAN_SCRIPT_SETTING(DisplayShadowsFrustum);
} }
#undef REGISTER_BOOLEAN_SCRIPT_SETTING #undef REGISTER_BOOLEAN_SCRIPT_SETTING
}

View file

@ -18,16 +18,11 @@
#ifndef INCLUDED_JSINTERFACE_RENDERER #ifndef INCLUDED_JSINTERFACE_RENDERER
#define INCLUDED_JSINTERFACE_RENDERER #define INCLUDED_JSINTERFACE_RENDERER
#include "scriptinterface/ScriptInterface.h" class ScriptRequest;
namespace JSI_Renderer namespace JSI_Renderer
{ {
std::string GetRenderPath(ScriptInterface::CmptPrivate* pCmptPrivate); void RegisterScriptFunctions(const ScriptRequest& rq);
bool TextureExists(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& filename);
void RegisterScriptFunctions(const ScriptInterface& scriptInterface);
} }
#undef DECLARE_BOOLEAN_SCRIPT_SETTING
#endif // INCLUDED_JSINTERFACE_RENDERER #endif // INCLUDED_JSINTERFACE_RENDERER

View file

@ -56,16 +56,6 @@ template <typename T> struct MaybeRef;
#define T0_TAIL_MAYBE_REF(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_TAIL_MAYBE_REF, T) // ", const T0&, T1" #define T0_TAIL_MAYBE_REF(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_TAIL_MAYBE_REF, T) // ", const T0&, T1"
#define A0_TAIL(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_TAIL, a) // ", a0, a1" #define A0_TAIL(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_TAIL, a) // ", a0, a1"
// Define RegisterFunction<TR, T0..., f>
#define OVERLOADS(z, i, data) \
template <typename R, TYPENAME_T0_HEAD(z,i) R (*fptr) ( ScriptInterface::CmptPrivate* T0_TAIL_MAYBE_REF(z,i) )> \
void RegisterFunction(const char* name) const \
{ \
Register(name, call<R T0_TAIL(z,i), fptr>, nargs<T0(z,i)>()); \
}
BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
#undef OVERLOADS
// JSFastNative-compatible function that wraps the function identified in the template argument list // JSFastNative-compatible function that wraps the function identified in the template argument list
// (Definition comes later, since it depends on some things we haven't defined yet) // (Definition comes later, since it depends on some things we haven't defined yet)
#define OVERLOADS(z, i, data) \ #define OVERLOADS(z, i, data) \

View file

@ -17,6 +17,7 @@
#include "precompiled.h" #include "precompiled.h"
#include "FunctionWrapper.h"
#include "ScriptContext.h" #include "ScriptContext.h"
#include "ScriptExtraHeaders.h" #include "ScriptExtraHeaders.h"
#include "ScriptInterface.h" #include "ScriptInterface.h"
@ -55,7 +56,6 @@ struct ScriptInterface_impl
{ {
ScriptInterface_impl(const char* nativeScopeName, const shared_ptr<ScriptContext>& context); ScriptInterface_impl(const char* nativeScopeName, const shared_ptr<ScriptContext>& context);
~ScriptInterface_impl(); ~ScriptInterface_impl();
void Register(const char* name, JSNative fptr, uint nargs) const;
// Take care to keep this declaration before heap rooted members. Destructors of heap rooted // Take care to keep this declaration before heap rooted members. Destructors of heap rooted
// members have to be called before the context destructor. // members have to be called before the context destructor.
@ -176,107 +176,77 @@ bool error(JSContext* cx, uint argc, JS::Value* vp)
return true; return true;
} }
bool deepcopy(JSContext* cx, uint argc, JS::Value* vp) JS::Value deepcopy(const ScriptRequest& rq, JS::HandleValue val)
{ {
JS::CallArgs args = JS::CallArgsFromVp(argc, vp); if (val.isNullOrUndefined())
if (args.length() < 1)
{ {
args.rval().setUndefined(); ScriptException::Raise(rq, "deepcopy requires one argument.");
return true; return JS::UndefinedValue();
} }
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \ JS::RootedValue ret(rq.cx);
JS::RootedValue ret(cx); if (!JS_StructuredClone(rq.cx, val, &ret, NULL, NULL))
if (!JS_StructuredClone(rq.cx, args[0], &ret, NULL, NULL)) {
return false; ScriptException::Raise(rq, "deepcopy StructureClone copy failed.");
return JS::UndefinedValue();
args.rval().set(ret); }
return true; return ret;
} }
bool deepfreeze(JSContext* cx, uint argc, JS::Value* vp) JS::Value deepfreeze(const ScriptInterface& scriptInterface, JS::HandleValue val)
{ {
JS::CallArgs args = JS::CallArgsFromVp(argc, vp); ScriptRequest rq(scriptInterface);
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \ if (!val.isObject())
if (args.length() != 1 || !args.get(0).isObject())
{ {
ScriptException::Raise(rq, "deepfreeze requires exactly one object as an argument."); ScriptException::Raise(rq, "deepfreeze requires exactly one object as an argument.");
return false; return JS::UndefinedValue();
} }
ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface->FreezeObject(args.get(0), true); scriptInterface.FreezeObject(val, true);
args.rval().set(args.get(0)); return val;
return true;
} }
bool ProfileStart(JSContext* cx, uint argc, JS::Value* vp) void ProfileStart(const std::string& regionName)
{ {
const char* name = "(ProfileStart)"; const char* name = "(ProfileStart)";
JS::CallArgs args = JS::CallArgsFromVp(argc, vp); typedef boost::flyweight<
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \ std::string,
if (args.length() >= 1) boost::flyweights::no_tracking,
{ boost::flyweights::no_locking
std::string str; > StringFlyweight;
if (!ScriptInterface::FromJSVal(rq, args[0], str))
return false;
typedef boost::flyweight< if (!regionName.empty())
std::string, name = StringFlyweight(regionName).get().c_str();
boost::flyweights::no_tracking,
boost::flyweights::no_locking
> StringFlyweight;
name = StringFlyweight(str).get().c_str();
}
if (CProfileManager::IsInitialised() && Threading::IsMainThread()) if (CProfileManager::IsInitialised() && Threading::IsMainThread())
g_Profiler.StartScript(name); g_Profiler.StartScript(name);
g_Profiler2.RecordRegionEnter(name); g_Profiler2.RecordRegionEnter(name);
args.rval().setUndefined();
return true;
} }
bool ProfileStop(JSContext* UNUSED(cx), uint argc, JS::Value* vp) void ProfileStop()
{ {
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
if (CProfileManager::IsInitialised() && Threading::IsMainThread()) if (CProfileManager::IsInitialised() && Threading::IsMainThread())
g_Profiler.Stop(); g_Profiler.Stop();
g_Profiler2.RecordRegionLeave(); g_Profiler2.RecordRegionLeave();
args.rval().setUndefined();
return true;
} }
bool ProfileAttribute(JSContext* cx, uint argc, JS::Value* vp) void ProfileAttribute(const std::string& attr)
{ {
const char* name = "(ProfileAttribute)"; const char* name = "(ProfileAttribute)";
JS::CallArgs args = JS::CallArgsFromVp(argc, vp); typedef boost::flyweight<
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \ std::string,
if (args.length() >= 1) boost::flyweights::no_tracking,
{ boost::flyweights::no_locking
std::string str; > StringFlyweight;
if (!ScriptInterface::FromJSVal(rq, args[0], str))
return false;
typedef boost::flyweight< if (!attr.empty())
std::string, name = StringFlyweight(attr).get().c_str();
boost::flyweights::no_tracking,
boost::flyweights::no_locking
> StringFlyweight;
name = StringFlyweight(str).get().c_str();
}
g_Profiler2.RecordAttribute("%s", name); g_Profiler2.RecordAttribute("%s", name);
args.rval().setUndefined();
return true;
} }
// Math override functions: // Math override functions:
@ -336,18 +306,19 @@ ScriptInterface_impl::ScriptInterface_impl(const char* nativeScopeName, const sh
JS_DefineProperty(m_cx, m_glob, "global", m_glob, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineProperty(m_cx, m_glob, "global", m_glob, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
m_nativeScope = JS_DefineObject(m_cx, m_glob, nativeScopeName, nullptr, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); // These first 4 actually use CallArgs & thus don't use ScriptFunction
JS_DefineFunction(m_cx, m_glob, "print", ::print, 0, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(m_cx, m_glob, "print", ::print, 0, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(m_cx, m_glob, "log", ::logmsg, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(m_cx, m_glob, "log", ::logmsg, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(m_cx, m_glob, "warn", ::warn, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(m_cx, m_glob, "warn", ::warn, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(m_cx, m_glob, "error", ::error, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(m_cx, m_glob, "error", ::error, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(m_cx, m_glob, "clone", ::deepcopy, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); ScriptFunction::Register<deepcopy>(m_cx, m_glob, "clone");
JS_DefineFunction(m_cx, m_glob, "deepfreeze", ::deepfreeze, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); ScriptFunction::Register<deepfreeze>(m_cx, m_glob, "deepfreeze");
Register("ProfileStart", ::ProfileStart, 1); m_nativeScope = JS_DefineObject(m_cx, m_glob, nativeScopeName, nullptr, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
Register("ProfileStop", ::ProfileStop, 0);
Register("ProfileAttribute", ::ProfileAttribute, 1); ScriptFunction::Register<&ProfileStart>(m_cx, m_nativeScope, "ProfileStart");
ScriptFunction::Register<&ProfileStop>(m_cx, m_nativeScope, "ProfileStop");
ScriptFunction::Register<&ProfileAttribute>(m_cx, m_nativeScope, "ProfileAttribute");
m_context->RegisterRealm(JS::GetObjectRealmOrNull(m_glob)); m_context->RegisterRealm(JS::GetObjectRealmOrNull(m_glob));
} }
@ -357,13 +328,6 @@ ScriptInterface_impl::~ScriptInterface_impl()
m_context->UnRegisterRealm(JS::GetObjectRealmOrNull(m_glob)); m_context->UnRegisterRealm(JS::GetObjectRealmOrNull(m_glob));
} }
void ScriptInterface_impl::Register(const char* name, JSNative fptr, uint nargs) const
{
JSAutoRealm autoRealm(m_cx, m_glob);
JS::RootedObject nativeScope(m_cx, m_nativeScope);
JS::RootedFunction func(m_cx, JS_DefineFunction(m_cx, nativeScope, name, fptr, nargs, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT));
}
ScriptInterface::ScriptInterface(const char* nativeScopeName, const char* debugName, const shared_ptr<ScriptContext>& context) : ScriptInterface::ScriptInterface(const char* nativeScopeName, const char* debugName, const shared_ptr<ScriptContext>& context) :
m(std::make_unique<ScriptInterface_impl>(nativeScopeName, context)) m(std::make_unique<ScriptInterface_impl>(nativeScopeName, context))
{ {
@ -441,11 +405,6 @@ bool ScriptInterface::ReplaceNondeterministicRNG(boost::rand48& rng)
return false; return false;
} }
void ScriptInterface::Register(const char* name, JSNative fptr, size_t nargs) const
{
m->Register(name, fptr, (uint)nargs);
}
JSContext* ScriptInterface::GetGeneralJSContext() const JSContext* ScriptInterface::GetGeneralJSContext() const
{ {
return m->m_context->GetGeneralJSContext(); return m->m_context->GetGeneralJSContext();

View file

@ -34,7 +34,6 @@ ERROR_TYPE(Scripting_LoadFile, OpenFailed);
ERROR_TYPE(Scripting_LoadFile, EvalErrors); ERROR_TYPE(Scripting_LoadFile, EvalErrors);
ERROR_TYPE(Scripting, CallFunctionFailed); ERROR_TYPE(Scripting, CallFunctionFailed);
ERROR_TYPE(Scripting, RegisterFunctionFailed);
ERROR_TYPE(Scripting, DefineConstantFailed); ERROR_TYPE(Scripting, DefineConstantFailed);
ERROR_TYPE(Scripting, CreateObjectFailed); ERROR_TYPE(Scripting, CreateObjectFailed);
ERROR_TYPE(Scripting, TypeDoesNotExist); ERROR_TYPE(Scripting, TypeDoesNotExist);
@ -105,7 +104,7 @@ public:
/** /**
* Constructor. * Constructor.
* @param nativeScopeName Name of global object that functions (via RegisterFunction) will * @param nativeScopeName Name of global object that functions (via ScriptFunction::Register) will
* be placed into, as a scoping mechanism; typically "Engine" * be placed into, as a scoping mechanism; typically "Engine"
* @param debugName Name of this interface for CScriptStats purposes. * @param debugName Name of this interface for CScriptStats purposes.
* @param context ScriptContext to use when initializing this interface. * @param context ScriptContext to use when initializing this interface.
@ -455,7 +454,6 @@ private:
JSClass* m_Class; JSClass* m_Class;
JSNative m_Constructor; JSNative m_Constructor;
}; };
void Register(const char* name, JSNative fptr, size_t nargs) const;
// Take care to keep this declaration before heap rooted members. Destructors of heap rooted // Take care to keep this declaration before heap rooted members. Destructors of heap rooted
// members have to be called before the custom destructor of ScriptInterface_impl. // members have to be called before the custom destructor of ScriptInterface_impl.
@ -470,9 +468,6 @@ public:
// This declares: // This declares:
// //
// template <R, T0..., TR (*fptr) (void* cbdata, T0...)> // template <R, T0..., TR (*fptr) (void* cbdata, T0...)>
// void RegisterFunction(const char* functionName) const;
//
// template <R, T0..., TR (*fptr) (void* cbdata, T0...)>
// static JSNative call; // static JSNative call;
// //
// template <R, T0..., JSClass*, TC, TR (TC:*fptr) (T0...)> // template <R, T0..., JSClass*, TC, TR (TC:*fptr) (T0...)>

View file

@ -32,6 +32,7 @@
#include "ps/scripting/JSInterface_VFS.h" #include "ps/scripting/JSInterface_VFS.h"
#include "ps/TemplateLoader.h" #include "ps/TemplateLoader.h"
#include "ps/Util.h" #include "ps/Util.h"
#include "scriptinterface/FunctionWrapper.h"
#include "scriptinterface/ScriptContext.h" #include "scriptinterface/ScriptContext.h"
#include "simulation2/components/ICmpAIInterface.h" #include "simulation2/components/ICmpAIInterface.h"
#include "simulation2/components/ICmpCommandQueue.h" #include "simulation2/components/ICmpCommandQueue.h"
@ -228,16 +229,22 @@ public:
JS_AddExtraGCRootsTracer(m_ScriptInterface->GetGeneralJSContext(), Trace, this); JS_AddExtraGCRootsTracer(m_ScriptInterface->GetGeneralJSContext(), Trace, this);
m_ScriptInterface->RegisterFunction<void, int, JS::HandleValue, CAIWorker::PostCommand>("PostCommand"); ScriptRequest rq(m_ScriptInterface);
m_ScriptInterface->RegisterFunction<void, std::wstring, CAIWorker::IncludeModule>("IncludeModule"); #define REGISTER_FUNC_NAME(func, name) \
m_ScriptInterface->RegisterFunction<void, CAIWorker::ExitProgram>("Exit"); ScriptFunction::Register<&CAIWorker::func, ScriptFunction::ObjectFromCBData<CAIWorker>>(rq, name);
m_ScriptInterface->RegisterFunction<JS::Value, JS::HandleValue, JS::HandleValue, pass_class_t, CAIWorker::ComputePath>("ComputePath"); REGISTER_FUNC_NAME(PostCommand, "PostCommand");
REGISTER_FUNC_NAME(LoadScripts, "IncludeModule");
ScriptFunction::Register<QuitEngine>(rq, "Exit");
m_ScriptInterface->RegisterFunction<void, std::wstring, std::vector<u32>, u32, u32, u32, CAIWorker::DumpImage>("DumpImage"); REGISTER_FUNC_NAME(ComputePathScript, "ComputePath");
m_ScriptInterface->RegisterFunction<CParamNode, std::string, CAIWorker::GetTemplate>("GetTemplate");
JSI_VFS::RegisterScriptFunctions_Simulation(*(m_ScriptInterface.get())); REGISTER_FUNC_NAME(DumpImage, "DumpImage");
REGISTER_FUNC_NAME(GetTemplate, "GetTemplate");
#undef REGISTER_FUNC_NAME
JSI_VFS::RegisterScriptFunctions_Simulation(rq);
// Globalscripts may use VFS script functions // Globalscripts may use VFS script functions
m_ScriptInterface->LoadGlobalScripts(); m_ScriptInterface->LoadGlobalScripts();
@ -279,20 +286,6 @@ public:
return true; return true;
} }
static void IncludeModule(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name)
{
ENSURE(pCmptPrivate->pCBData);
CAIWorker* self = static_cast<CAIWorker*> (pCmptPrivate->pCBData);
self->LoadScripts(name);
}
static void PostCommand(ScriptInterface::CmptPrivate* pCmptPrivate, int playerid, JS::HandleValue cmd)
{
ENSURE(pCmptPrivate->pCBData);
CAIWorker* self = static_cast<CAIWorker*> (pCmptPrivate->pCBData);
self->PostCommand(playerid, cmd);
}
void PostCommand(int playerid, JS::HandleValue cmd) void PostCommand(int playerid, JS::HandleValue cmd)
{ {
for (size_t i=0; i<m_Players.size(); i++) for (size_t i=0; i<m_Players.size(); i++)
@ -307,22 +300,19 @@ public:
LOGERROR("Invalid playerid in PostCommand!"); LOGERROR("Invalid playerid in PostCommand!");
} }
static JS::Value ComputePath(ScriptInterface::CmptPrivate* pCmptPrivate, JS::Value ComputePathScript(JS::HandleValue position, JS::HandleValue goal, pass_class_t passClass)
JS::HandleValue position, JS::HandleValue goal, pass_class_t passClass)
{ {
ENSURE(pCmptPrivate->pCBData); ScriptRequest rq(m_ScriptInterface);
CAIWorker* self = static_cast<CAIWorker*> (pCmptPrivate->pCBData);
ScriptRequest rq(self->m_ScriptInterface);
CFixedVector2D pos, goalPos; CFixedVector2D pos, goalPos;
std::vector<CFixedVector2D> waypoints; std::vector<CFixedVector2D> waypoints;
JS::RootedValue retVal(rq.cx); JS::RootedValue retVal(rq.cx);
self->m_ScriptInterface->FromJSVal<CFixedVector2D>(rq, position, pos); m_ScriptInterface->FromJSVal<CFixedVector2D>(rq, position, pos);
self->m_ScriptInterface->FromJSVal<CFixedVector2D>(rq, goal, goalPos); m_ScriptInterface->FromJSVal<CFixedVector2D>(rq, goal, goalPos);
self->ComputePath(pos, goalPos, passClass, waypoints); ComputePath(pos, goalPos, passClass, waypoints);
self->m_ScriptInterface->ToJSVal<std::vector<CFixedVector2D> >(rq, &retVal, waypoints); m_ScriptInterface->ToJSVal<std::vector<CFixedVector2D> >(rq, &retVal, waypoints);
return retVal; return retVal;
} }
@ -337,14 +327,6 @@ public:
waypoints.emplace_back(wp.x, wp.z); waypoints.emplace_back(wp.x, wp.z);
} }
static CParamNode GetTemplate(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& name)
{
ENSURE(pCmptPrivate->pCBData);
CAIWorker* self = static_cast<CAIWorker*> (pCmptPrivate->pCBData);
return self->GetTemplate(name);
}
CParamNode GetTemplate(const std::string& name) CParamNode GetTemplate(const std::string& name)
{ {
if (!m_TemplateLoader.TemplateExists(name)) if (!m_TemplateLoader.TemplateExists(name))
@ -352,15 +334,10 @@ public:
return m_TemplateLoader.GetTemplateFileData(name).GetChild("Entity"); return m_TemplateLoader.GetTemplateFileData(name).GetChild("Entity");
} }
static void ExitProgram(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate))
{
QuitEngine();
}
/** /**
* Debug function for AI scripts to dump 2D array data (e.g. terrain tile weights). * Debug function for AI scripts to dump 2D array data (e.g. terrain tile weights).
*/ */
static void DumpImage(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& name, const std::vector<u32>& data, u32 w, u32 h, u32 max) void DumpImage(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& name, const std::vector<u32>& data, u32 w, u32 h, u32 max)
{ {
// TODO: this is totally not threadsafe. // TODO: this is totally not threadsafe.
VfsPath filename = L"screenshots/aidump/" + name; VfsPath filename = L"screenshots/aidump/" + name;

View file

@ -92,7 +92,8 @@ public:
CComponentManager componentManager(context, g_ScriptContext, true); CComponentManager componentManager(context, g_ScriptContext, true);
ScriptTestSetup(componentManager.GetScriptInterface()); ScriptTestSetup(componentManager.GetScriptInterface());
componentManager.GetScriptInterface().RegisterFunction<JS::Value, JS::HandleValue, Script_SerializationRoundTrip> ("SerializationRoundTrip"); ScriptRequest rq(componentManager.GetScriptInterface());
ScriptFunction::Register<Script_SerializationRoundTrip>(rq, "SerializationRoundTrip");
load_script(componentManager.GetScriptInterface(), path); load_script(componentManager.GetScriptInterface(), path);
} }

View file

@ -24,6 +24,7 @@
#include "ps/Game.h" #include "ps/Game.h"
#include "ps/GameSetup/Config.h" #include "ps/GameSetup/Config.h"
#include "ps/Pyrogenesis.h" #include "ps/Pyrogenesis.h"
#include "scriptinterface/FunctionWrapper.h"
#include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptInterface.h"
#include "simulation2/components/ICmpAIManager.h" #include "simulation2/components/ICmpAIManager.h"
#include "simulation2/components/ICmpCommandQueue.h" #include "simulation2/components/ICmpCommandQueue.h"
@ -39,7 +40,9 @@
#include <array> #include <array>
#include <fstream> #include <fstream>
JS::Value JSI_Simulation::GuiInterfaceCall(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name, JS::HandleValue data) namespace JSI_Simulation
{
JS::Value GuiInterfaceCall(const ScriptInterface& scriptInterface, const std::wstring& name, JS::HandleValue data)
{ {
if (!g_Game) if (!g_Game)
return JS::UndefinedValue(); return JS::UndefinedValue();
@ -52,14 +55,14 @@ JS::Value JSI_Simulation::GuiInterfaceCall(ScriptInterface::CmptPrivate* pCmptPr
return JS::UndefinedValue(); return JS::UndefinedValue();
ScriptRequest rqSim(sim->GetScriptInterface()); ScriptRequest rqSim(sim->GetScriptInterface());
JS::RootedValue arg(rqSim.cx, sim->GetScriptInterface().CloneValueFromOtherCompartment(*(pCmptPrivate->pScriptInterface), data)); JS::RootedValue arg(rqSim.cx, sim->GetScriptInterface().CloneValueFromOtherCompartment(scriptInterface, data));
JS::RootedValue ret(rqSim.cx); JS::RootedValue ret(rqSim.cx);
cmpGuiInterface->ScriptCall(g_Game->GetViewedPlayerID(), name, arg, &ret); cmpGuiInterface->ScriptCall(g_Game->GetViewedPlayerID(), name, arg, &ret);
return pCmptPrivate->pScriptInterface->CloneValueFromOtherCompartment(sim->GetScriptInterface(), ret); return scriptInterface.CloneValueFromOtherCompartment(sim->GetScriptInterface(), ret);
} }
void JSI_Simulation::PostNetworkCommand(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue cmd) void PostNetworkCommand(const ScriptInterface& scriptInterface, JS::HandleValue cmd)
{ {
if (!g_Game) if (!g_Game)
return; return;
@ -73,39 +76,39 @@ void JSI_Simulation::PostNetworkCommand(ScriptInterface::CmptPrivate* pCmptPriva
ScriptRequest rqSim(sim->GetScriptInterface()); ScriptRequest rqSim(sim->GetScriptInterface());
JS::RootedValue cmd2(rqSim.cx, JS::RootedValue cmd2(rqSim.cx,
sim->GetScriptInterface().CloneValueFromOtherCompartment(*(pCmptPrivate->pScriptInterface), cmd)); sim->GetScriptInterface().CloneValueFromOtherCompartment(scriptInterface, cmd));
cmpCommandQueue->PostNetworkCommand(cmd2); cmpCommandQueue->PostNetworkCommand(cmd2);
} }
void JSI_Simulation::DumpSimState(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) void DumpSimState()
{ {
OsPath path = psLogDir()/"sim_dump.txt"; OsPath path = psLogDir()/"sim_dump.txt";
std::ofstream file (OsString(path).c_str(), std::ofstream::out | std::ofstream::trunc); std::ofstream file (OsString(path).c_str(), std::ofstream::out | std::ofstream::trunc);
g_Game->GetSimulation2()->DumpDebugState(file); g_Game->GetSimulation2()->DumpDebugState(file);
} }
entity_id_t JSI_Simulation::PickEntityAtPoint(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), int x, int y) entity_id_t PickEntityAtPoint(int x, int y)
{ {
return EntitySelection::PickEntityAtPoint(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x, y, g_Game->GetViewedPlayerID(), false); return EntitySelection::PickEntityAtPoint(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x, y, g_Game->GetViewedPlayerID(), false);
} }
std::vector<entity_id_t> JSI_Simulation::PickPlayerEntitiesInRect(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), int x0, int y0, int x1, int y1, int player) std::vector<entity_id_t> PickPlayerEntitiesInRect(int x0, int y0, int x1, int y1, int player)
{ {
return EntitySelection::PickEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x0, y0, x1, y1, player, false); return EntitySelection::PickEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x0, y0, x1, y1, player, false);
} }
std::vector<entity_id_t> JSI_Simulation::PickPlayerEntitiesOnScreen(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), int player) std::vector<entity_id_t> PickPlayerEntitiesOnScreen(int player)
{ {
return EntitySelection::PickEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), 0, 0, g_xres, g_yres, player, false); return EntitySelection::PickEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), 0, 0, g_xres, g_yres, player, false);
} }
std::vector<entity_id_t> JSI_Simulation::PickNonGaiaEntitiesOnScreen(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) std::vector<entity_id_t> PickNonGaiaEntitiesOnScreen()
{ {
return EntitySelection::PickNonGaiaEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), 0, 0, g_xres, g_yres, false); return EntitySelection::PickNonGaiaEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), 0, 0, g_xres, g_yres, false);
} }
std::vector<entity_id_t> JSI_Simulation::GetEntitiesWithStaticObstructionOnScreen(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) std::vector<entity_id_t> GetEntitiesWithStaticObstructionOnScreen()
{ {
struct StaticObstructionFilter struct StaticObstructionFilter
{ {
@ -118,7 +121,7 @@ std::vector<entity_id_t> JSI_Simulation::GetEntitiesWithStaticObstructionOnScree
return EntitySelection::GetEntitiesWithComponentInRect<StaticObstructionFilter>(*g_Game->GetSimulation2(), IID_Obstruction, *g_Game->GetView()->GetCamera(), 0, 0, g_xres, g_yres); return EntitySelection::GetEntitiesWithComponentInRect<StaticObstructionFilter>(*g_Game->GetSimulation2(), IID_Obstruction, *g_Game->GetView()->GetCamera(), 0, 0, g_xres, g_yres);
} }
JS::Value JSI_Simulation::GetEdgesOfStaticObstructionsOnScreenNearTo(ScriptInterface::CmptPrivate* pCmptPrivate, entity_pos_t x, entity_pos_t z) JS::Value GetEdgesOfStaticObstructionsOnScreenNearTo(const ScriptInterface& scriptInterface, entity_pos_t x, entity_pos_t z)
{ {
if (!g_Game) if (!g_Game)
return JS::UndefinedValue(); return JS::UndefinedValue();
@ -126,7 +129,7 @@ JS::Value JSI_Simulation::GetEdgesOfStaticObstructionsOnScreenNearTo(ScriptInter
CSimulation2* sim = g_Game->GetSimulation2(); CSimulation2* sim = g_Game->GetSimulation2();
ENSURE(sim); ENSURE(sim);
ScriptRequest rq(pCmptPrivate->pScriptInterface); ScriptRequest rq(scriptInterface);
JS::RootedValue edgeList(rq.cx); JS::RootedValue edgeList(rq.cx);
ScriptInterface::CreateArray(rq, &edgeList); ScriptInterface::CreateArray(rq, &edgeList);
int edgeListIndex = 0; int edgeListIndex = 0;
@ -135,7 +138,7 @@ JS::Value JSI_Simulation::GetEdgesOfStaticObstructionsOnScreenNearTo(ScriptInter
CFG_GET_VAL("gui.session.snaptoedgesdistancethreshold", distanceThreshold); CFG_GET_VAL("gui.session.snaptoedgesdistancethreshold", distanceThreshold);
CFixedVector2D entityPos(x, z); CFixedVector2D entityPos(x, z);
std::vector<entity_id_t> entities = GetEntitiesWithStaticObstructionOnScreen(pCmptPrivate); std::vector<entity_id_t> entities = GetEntitiesWithStaticObstructionOnScreen();
for (entity_id_t entity : entities) for (entity_id_t entity : entities)
{ {
CmpPtr<ICmpObstruction> cmpObstruction(sim->GetSimContext(), entity); CmpPtr<ICmpObstruction> cmpObstruction(sim->GetSimContext(), entity);
@ -182,39 +185,40 @@ JS::Value JSI_Simulation::GetEdgesOfStaticObstructionsOnScreenNearTo(ScriptInter
"normal", normal, "normal", normal,
"order", "cw"); "order", "cw");
pCmptPrivate->pScriptInterface->SetPropertyInt(edgeList, edgeListIndex++, edge); scriptInterface.SetPropertyInt(edgeList, edgeListIndex++, edge);
} }
} }
return edgeList; return edgeList;
} }
std::vector<entity_id_t> JSI_Simulation::PickSimilarPlayerEntities(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::string& templateName, bool includeOffScreen, bool matchRank, bool allowFoundations) std::vector<entity_id_t> PickSimilarPlayerEntities(const std::string& templateName, bool includeOffScreen, bool matchRank, bool allowFoundations)
{ {
return EntitySelection::PickSimilarEntities(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), templateName, g_Game->GetViewedPlayerID(), includeOffScreen, matchRank, false, allowFoundations); return EntitySelection::PickSimilarEntities(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), templateName, g_Game->GetViewedPlayerID(), includeOffScreen, matchRank, false, allowFoundations);
} }
JS::Value JSI_Simulation::GetAIs(ScriptInterface::CmptPrivate* pCmptPrivate) JS::Value GetAIs(const ScriptInterface& scriptInterface)
{ {
return ICmpAIManager::GetAIs(*(pCmptPrivate->pScriptInterface)); return ICmpAIManager::GetAIs(scriptInterface);
} }
void JSI_Simulation::SetBoundingBoxDebugOverlay(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), bool enabled) void SetBoundingBoxDebugOverlay(bool enabled)
{ {
ICmpSelectable::ms_EnableDebugOverlays = enabled; ICmpSelectable::ms_EnableDebugOverlays = enabled;
} }
void JSI_Simulation::RegisterScriptFunctions(const ScriptInterface& scriptInterface) void RegisterScriptFunctions(const ScriptRequest& rq)
{ {
scriptInterface.RegisterFunction<JS::Value, std::wstring, JS::HandleValue, &GuiInterfaceCall>("GuiInterfaceCall"); ScriptFunction::Register<&GuiInterfaceCall>(rq, "GuiInterfaceCall");
scriptInterface.RegisterFunction<void, JS::HandleValue, &PostNetworkCommand>("PostNetworkCommand"); ScriptFunction::Register<&PostNetworkCommand>(rq, "PostNetworkCommand");
scriptInterface.RegisterFunction<void, &DumpSimState>("DumpSimState"); ScriptFunction::Register<&DumpSimState>(rq, "DumpSimState");
scriptInterface.RegisterFunction<JS::Value, &GetAIs>("GetAIs"); ScriptFunction::Register<&GetAIs>(rq, "GetAIs");
scriptInterface.RegisterFunction<entity_id_t, int, int, &PickEntityAtPoint>("PickEntityAtPoint"); ScriptFunction::Register<&PickEntityAtPoint>(rq, "PickEntityAtPoint");
scriptInterface.RegisterFunction<std::vector<entity_id_t>, int, int, int, int, int, &PickPlayerEntitiesInRect>("PickPlayerEntitiesInRect"); ScriptFunction::Register<&PickPlayerEntitiesInRect>(rq, "PickPlayerEntitiesInRect");
scriptInterface.RegisterFunction<std::vector<entity_id_t>, int, &PickPlayerEntitiesOnScreen>("PickPlayerEntitiesOnScreen"); ScriptFunction::Register<&PickPlayerEntitiesOnScreen>(rq, "PickPlayerEntitiesOnScreen");
scriptInterface.RegisterFunction<std::vector<entity_id_t>, &PickNonGaiaEntitiesOnScreen>("PickNonGaiaEntitiesOnScreen"); ScriptFunction::Register<&PickNonGaiaEntitiesOnScreen>(rq, "PickNonGaiaEntitiesOnScreen");
scriptInterface.RegisterFunction<std::vector<entity_id_t>, &GetEntitiesWithStaticObstructionOnScreen>("GetEntitiesWithStaticObstructionOnScreen"); ScriptFunction::Register<&GetEntitiesWithStaticObstructionOnScreen>(rq, "GetEntitiesWithStaticObstructionOnScreen");
scriptInterface.RegisterFunction<JS::Value, entity_pos_t, entity_pos_t, &GetEdgesOfStaticObstructionsOnScreenNearTo>("GetEdgesOfStaticObstructionsOnScreenNearTo"); ScriptFunction::Register<&GetEdgesOfStaticObstructionsOnScreenNearTo>(rq, "GetEdgesOfStaticObstructionsOnScreenNearTo");
scriptInterface.RegisterFunction<std::vector<entity_id_t>, std::string, bool, bool, bool, &PickSimilarPlayerEntities>("PickSimilarPlayerEntities"); ScriptFunction::Register<&PickSimilarPlayerEntities>(rq, "PickSimilarPlayerEntities");
scriptInterface.RegisterFunction<void, bool, &SetBoundingBoxDebugOverlay>("SetBoundingBoxDebugOverlay"); ScriptFunction::Register<&SetBoundingBoxDebugOverlay>(rq, "SetBoundingBoxDebugOverlay");
}
} }

View file

@ -18,26 +18,11 @@
#ifndef INCLUDED_JSI_SIMULATION #ifndef INCLUDED_JSI_SIMULATION
#define INCLUDED_JSI_SIMULATION #define INCLUDED_JSI_SIMULATION
#include "scriptinterface/ScriptInterface.h" class ScriptRequest;
#include "simulation2/helpers/Position.h"
#include "simulation2/system/Entity.h"
namespace JSI_Simulation namespace JSI_Simulation
{ {
JS::Value GuiInterfaceCall(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& name, JS::HandleValue data); void RegisterScriptFunctions(const ScriptRequest& rq);
void PostNetworkCommand(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue cmd);
entity_id_t PickEntityAtPoint(ScriptInterface::CmptPrivate* pCmptPrivate, int x, int y);
void DumpSimState(ScriptInterface::CmptPrivate* pCmptPrivate);
std::vector<entity_id_t> PickPlayerEntitiesInRect(ScriptInterface::CmptPrivate* pCmptPrivate, int x0, int y0, int x1, int y1, int player);
std::vector<entity_id_t> PickPlayerEntitiesOnScreen(ScriptInterface::CmptPrivate* pCmptPrivate, int player);
std::vector<entity_id_t> PickNonGaiaEntitiesOnScreen(ScriptInterface::CmptPrivate* pCmptPrivate);
std::vector<entity_id_t> GetEntitiesWithStaticObstructionOnScreen(ScriptInterface::CmptPrivate* pCmptPrivate);
JS::Value GetEdgesOfStaticObstructionsOnScreenNearTo(ScriptInterface::CmptPrivate* pCmptPrivate, entity_pos_t x, entity_pos_t z);
std::vector<entity_id_t> PickSimilarPlayerEntities(ScriptInterface::CmptPrivate* pCmptPrivate, const std::string& templateName, bool includeOffScreen, bool matchRank, bool allowFoundations);
JS::Value GetAIs(ScriptInterface::CmptPrivate* pCmptPrivate);
void SetBoundingBoxDebugOverlay(ScriptInterface::CmptPrivate* pCmptPrivate, bool enabled);
void RegisterScriptFunctions(const ScriptInterface& ScriptInterface);
} }
#endif // INCLUDED_JSI_SIMULATION #endif // INCLUDED_JSI_SIMULATION

View file

@ -22,6 +22,7 @@
#include "lib/utf8.h" #include "lib/utf8.h"
#include "maths/Vector3D.h" #include "maths/Vector3D.h"
#include "ps/Filesystem.h" #include "ps/Filesystem.h"
#include "scriptinterface/FunctionWrapper.h"
#include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptInterface.h"
#include "soundmanager/SoundManager.h" #include "soundmanager/SoundManager.h"
@ -31,84 +32,84 @@ namespace JSI_Sound
{ {
#if CONFIG2_AUDIO #if CONFIG2_AUDIO
void StartMusic(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) void StartMusic()
{ {
if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager)
sndManager->SetMusicEnabled(true); sndManager->SetMusicEnabled(true);
} }
void StopMusic(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) void StopMusic()
{ {
if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager)
sndManager->SetMusicEnabled(false); sndManager->SetMusicEnabled(false);
} }
void ClearPlaylist(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) void ClearPlaylist()
{ {
if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager)
sndManager->ClearPlayListItems(); sndManager->ClearPlayListItems();
} }
void AddPlaylistItem(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& filename) void AddPlaylistItem(const std::wstring& filename)
{ {
if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager)
sndManager->AddPlayListItem(VfsPath(filename)); sndManager->AddPlayListItem(VfsPath(filename));
} }
void StartPlaylist(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), bool looping) void StartPlaylist(bool looping)
{ {
if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager)
sndManager->StartPlayList(looping ); sndManager->StartPlayList(looping );
} }
void PlayMusic(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& filename, bool looping) void PlayMusic(const std::wstring& filename, bool looping)
{ {
if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager)
sndManager->PlayAsMusic(filename, looping); sndManager->PlayAsMusic(filename, looping);
} }
void PlayUISound(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& filename, bool looping) void PlayUISound(const std::wstring& filename, bool looping)
{ {
if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager)
sndManager->PlayAsUI(filename, looping); sndManager->PlayAsUI(filename, looping);
} }
void PlayAmbientSound(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& filename, bool looping) void PlayAmbientSound(const std::wstring& filename, bool looping)
{ {
if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager)
sndManager->PlayAsAmbient(filename, looping); sndManager->PlayAsAmbient(filename, looping);
} }
bool MusicPlaying(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate)) bool MusicPlaying()
{ {
return true; return true;
} }
void SetMasterGain(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float gain) void SetMasterGain(float gain)
{ {
if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager)
sndManager->SetMasterGain(gain); sndManager->SetMasterGain(gain);
} }
void SetMusicGain(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float gain) void SetMusicGain(float gain)
{ {
if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager)
sndManager->SetMusicGain(gain); sndManager->SetMusicGain(gain);
} }
void SetAmbientGain(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float gain) void SetAmbientGain(float gain)
{ {
if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager)
sndManager->SetAmbientGain(gain); sndManager->SetAmbientGain(gain);
} }
void SetActionGain(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float gain) void SetActionGain(float gain)
{ {
if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager)
sndManager->SetActionGain(gain); sndManager->SetActionGain(gain);
} }
void SetUIGain(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float gain) void SetUIGain(float gain)
{ {
if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager) if (CSoundManager* sndManager = (CSoundManager*)g_SoundManager)
sndManager->SetUIGain(gain); sndManager->SetUIGain(gain);
@ -116,38 +117,38 @@ namespace JSI_Sound
#else #else
bool MusicPlaying(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate) ){ return false; } bool MusicPlaying( ){ return false; }
void PlayAmbientSound(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& UNUSED(filename), bool UNUSED(looping) ){} void PlayAmbientSound(const std::wstring& UNUSED(filename), bool UNUSED(looping) ){}
void PlayUISound(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& UNUSED(filename), bool UNUSED(looping) ) {} void PlayUISound(const std::wstring& UNUSED(filename), bool UNUSED(looping) ) {}
void PlayMusic(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& UNUSED(filename), bool UNUSED(looping) ) {} void PlayMusic(const std::wstring& UNUSED(filename), bool UNUSED(looping) ) {}
void StartPlaylist(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), bool UNUSED(looping) ){} void StartPlaylist(bool UNUSED(looping) ){}
void AddPlaylistItem(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& UNUSED(filename) ){} void AddPlaylistItem(const std::wstring& UNUSED(filename) ){}
void ClearPlaylist(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate) ){} void ClearPlaylist( ){}
void StopMusic(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate) ){} void StopMusic( ){}
void StartMusic(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate) ){} void StartMusic( ){}
void SetMasterGain(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float UNUSED(gain)){} void SetMasterGain(float UNUSED(gain)){}
void SetMusicGain(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float UNUSED(gain)){} void SetMusicGain(float UNUSED(gain)){}
void SetAmbientGain(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float UNUSED(gain)){} void SetAmbientGain(float UNUSED(gain)){}
void SetActionGain(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float UNUSED(gain)){} void SetActionGain(float UNUSED(gain)){}
void SetUIGain(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), float UNUSED(gain)){} void SetUIGain(float UNUSED(gain)){}
#endif #endif
void RegisterScriptFunctions(const ScriptInterface& scriptInterface) void RegisterScriptFunctions(const ScriptRequest& rq)
{ {
scriptInterface.RegisterFunction<void, &StartMusic>("StartMusic"); ScriptFunction::Register<&StartMusic>(rq, "StartMusic");
scriptInterface.RegisterFunction<void, &StopMusic>("StopMusic"); ScriptFunction::Register<&StopMusic>(rq, "StopMusic");
scriptInterface.RegisterFunction<void, &ClearPlaylist>("ClearPlaylist"); ScriptFunction::Register<&ClearPlaylist>(rq, "ClearPlaylist");
scriptInterface.RegisterFunction<void, std::wstring, &AddPlaylistItem>("AddPlaylistItem"); ScriptFunction::Register<&AddPlaylistItem>(rq, "AddPlaylistItem");
scriptInterface.RegisterFunction<void, bool, &StartPlaylist>("StartPlaylist"); ScriptFunction::Register<&StartPlaylist>(rq, "StartPlaylist");
scriptInterface.RegisterFunction<void, std::wstring, bool, &PlayMusic>("PlayMusic"); ScriptFunction::Register<&PlayMusic>(rq, "PlayMusic");
scriptInterface.RegisterFunction<void, std::wstring, bool, &PlayUISound>("PlayUISound"); ScriptFunction::Register<&PlayUISound>(rq, "PlayUISound");
scriptInterface.RegisterFunction<void, std::wstring, bool, &PlayAmbientSound>("PlayAmbientSound"); ScriptFunction::Register<&PlayAmbientSound>(rq, "PlayAmbientSound");
scriptInterface.RegisterFunction<bool, &MusicPlaying>("MusicPlaying"); ScriptFunction::Register<&MusicPlaying>(rq, "MusicPlaying");
scriptInterface.RegisterFunction<void, float, &SetMasterGain>("SetMasterGain"); ScriptFunction::Register<&SetMasterGain>(rq, "SetMasterGain");
scriptInterface.RegisterFunction<void, float, &SetMusicGain>("SetMusicGain"); ScriptFunction::Register<&SetMusicGain>(rq, "SetMusicGain");
scriptInterface.RegisterFunction<void, float, &SetAmbientGain>("SetAmbientGain"); ScriptFunction::Register<&SetAmbientGain>(rq, "SetAmbientGain");
scriptInterface.RegisterFunction<void, float, &SetActionGain>("SetActionGain"); ScriptFunction::Register<&SetActionGain>(rq, "SetActionGain");
scriptInterface.RegisterFunction<void, float, &SetUIGain>("SetUIGain"); ScriptFunction::Register<&SetUIGain>(rq, "SetUIGain");
} }
} }

View file

@ -19,11 +19,11 @@
#ifndef INCLUDED_SOUNDSCRIPTINTERFACE #ifndef INCLUDED_SOUNDSCRIPTINTERFACE
#define INCLUDED_SOUNDSCRIPTINTERFACE #define INCLUDED_SOUNDSCRIPTINTERFACE
class ScriptInterface; class ScriptRequest;
namespace JSI_Sound namespace JSI_Sound
{ {
void RegisterScriptFunctions(const ScriptInterface& scriptInterface); void RegisterScriptFunctions(const ScriptRequest& rq);
} }
#endif // INCLUDED_SOUNDSCRIPTINTERFACE #endif // INCLUDED_SOUNDSCRIPTINTERFACE