Skip to content

Commit

Permalink
Added more events #1, Check [here](https://user-grinch.gitbook.io/pyl…
Browse files Browse the repository at this point in the history
  • Loading branch information
user-grinch committed May 21, 2021
1 parent 0470fa1 commit 7bc3958
Show file tree
Hide file tree
Showing 10 changed files with 276 additions and 22 deletions.
2 changes: 1 addition & 1 deletion PyLoader/DllMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved )
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
{
uint gameVersion = plugin::GetGameVersion();
if (gameVersion == GAME_10US_HOODLUM || gameVersion == GAME_10US_COMPACT)
{
Expand Down
22 changes: 7 additions & 15 deletions PyLoader/PyEvents.cpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
#include "PyEvents.h"
#include "pch.h"

void PyEvents::VehicleCreate(PyObject* pModule)
void PyEvents::InitAllEvents()
{
PyObject* pFunc = PyObject_GetAttrString(pModule, "on_veh_create");

plugin::Events::vehicleCtorEvent += [pFunc](CVehicle* pVeh)
{
if (pFunc && PyCallable_Check(pFunc))
{
PyObject* pArgs = PyTuple_New(1);
PyGILState_STATE gstate = PyGILState_Ensure();
flog << pVeh << std::endl;
flog << CPools::GetVehicleRef(pVeh) << std::endl;
PyObject_CallFunction(pFunc, "i", CPools::GetVehicleRef(pVeh));
PyGILState_Release(gstate);
}
};
PyEvents::vehCreateEvent.Init();
PyEvents::vehRenderEvent.Init();
PyEvents::vehDestroyEvent.Init();
PyEvents::pedCreateEvent.Init();
PyEvents::pedRenderEvent.Init();
PyEvents::pedDestroyEvent.Init();
}

bool PyEvents::ScriptTerminate(PyObject* pModule)
Expand Down
14 changes: 13 additions & 1 deletion PyLoader/PyEvents.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
#pragma once
#include <Python.h>
#include <vector>
#include "pch.h"
#include "PyEventsInternal.h"

class PyEvents
{
public:
static void InitAllEvents();
static bool ScriptTerminate(PyObject* pModule);
static void VehicleCreate(PyObject* pModule);
static inline PyEventsInternal::VehCreateEvent vehCreateEvent;
static inline PyEventsInternal::VehRenderEvent vehRenderEvent;
static inline PyEventsInternal::VehDestroyEvent vehDestroyEvent;
static inline PyEventsInternal::PedCreateEvent pedCreateEvent;
static inline PyEventsInternal::PedRenderEvent pedRenderEvent;
static inline PyEventsInternal::PedDestroyEvent pedDestroyEvent;
static inline PyEventsInternal::ObjCreateEvent objCreateEvent;
static inline PyEventsInternal::ObjRenderEvent objRenderEvent;
static inline PyEventsInternal::ObjDestroyEvent objDestroyEvent;

PyEvents() = delete;
PyEvents(PyEvents&) = delete;
Expand Down
216 changes: 216 additions & 0 deletions PyLoader/PyEventsInternal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
#pragma once

namespace PyEventsInternal
{
class EventBase
{
protected:
std::vector<PyObject*> pFuncs;

public:
void AddModule(PyObject* pModule, std::string func_name)
{
PyObject* pFunc = PyObject_GetAttrString(pModule, func_name.c_str());
if (pFunc)
{
pFuncs.push_back(pFunc);
Py_INCREF(pFunc);
}
}

void RemoveFunc(PyObject* pFunc)
{
for (auto it = pFuncs.begin(); it != pFuncs.end(); ++it)
{
if (*it == pFunc)
{
pFuncs.erase(it);
Py_XDECREF(*it);
}
}
}

virtual void Callback(void* ptr) = 0;
virtual void Init() = 0;
};

class VehEvent : public EventBase
{
public:
void Callback(void* ptr)
{
if (!ptr)
return;

CVehicle* pVeh = (CVehicle*)ptr;
PyGILState_STATE gstate = PyGILState_Ensure();

for (auto it = pFuncs.begin(); it != pFuncs.end(); ++it)
{
PyObject* pFunc = *it;
if (pFunc && PyCallable_Check(pFunc))
{
PyObject* pArgs = PyTuple_New(1);
PyObject_CallFunction(pFunc, "i", CPools::GetVehicleRef(pVeh));
}
}
PyGILState_Release(gstate);
}
};

class PedEvent : public EventBase
{
public:
void Callback(void* ptr)
{
if (!ptr)
return;

CPed* pPed = (CPed*)ptr;
PyGILState_STATE gstate = PyGILState_Ensure();

for (auto it = pFuncs.begin(); it != pFuncs.end(); ++it)
{
PyObject* pFunc = *it;
if (pFunc && PyCallable_Check(pFunc))
{
PyObject* pArgs = PyTuple_New(1);
PyObject_CallFunction(pFunc, "i", CPools::GetPedRef(pPed));
}
}
PyGILState_Release(gstate);
}
};

class ObjEvent : public EventBase
{
public:
void Callback(void* ptr)
{
if (!ptr)
return;

CObject* pObj = (CObject*)ptr;
PyGILState_STATE gstate = PyGILState_Ensure();

for (auto it = pFuncs.begin(); it != pFuncs.end(); ++it)
{
PyObject* pFunc = *it;
if (pFunc && PyCallable_Check(pFunc))
{
PyObject* pArgs = PyTuple_New(1);
PyObject_CallFunction(pFunc, "i", CPools::GetObjectRef(pObj));
}
}
PyGILState_Release(gstate);
}
};

class VehCreateEvent : public VehEvent
{
public:
void Init()
{
plugin::Events::vehicleCtorEvent += [&](CVehicle* pVeh)
{
Callback(pVeh);
};
}
};

class VehRenderEvent : public VehEvent
{
public:
void Init()
{
plugin::Events::vehicleRenderEvent += [&](CVehicle* pVeh)
{
Callback(pVeh);
};
}
};

class VehDestroyEvent : public VehEvent
{
public:
void Init()
{
plugin::Events::vehicleDtorEvent += [&](CVehicle* pVeh)
{
Callback(pVeh);
};
}
};

class PedCreateEvent : public PedEvent
{
public:
void Init()
{
plugin::Events::pedCtorEvent += [&](CPed* pPed)
{
Callback(pPed);
};
}
};

class PedRenderEvent : public PedEvent
{
public:
void Init()
{
plugin::Events::pedRenderEvent += [&](CPed* pPed)
{
Callback(pPed);
};
}
};

class PedDestroyEvent : public PedEvent
{
public:
void Init()
{
plugin::Events::pedDtorEvent += [&](CPed* pPed)
{
Callback(pPed);
};
}
};

class ObjCreateEvent : public ObjEvent
{
public:
void Init()
{
plugin::Events::objectCtorEvent += [&](CObject* pObj)
{
Callback(pObj);
};
}
};

class ObjRenderEvent : public ObjEvent
{
public:
void Init()
{
plugin::Events::objectRenderEvent += [&](CObject* pObj)
{
Callback(pObj);
};
}
};

class ObjDestroyEvent : public ObjEvent
{
public:
void Init()
{
plugin::Events::objectDtorEvent += [&](CObject* pObj)
{
Callback(pObj);
};
}
};
}
2 changes: 2 additions & 0 deletions PyLoader/PyLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ void PyLoader::PluginThread(void* param)
PyImport_ImportModule("common");
PyEval_ReleaseLock();

PyEvents::InitAllEvents();

// load scripts
if (dir != INVALID_HANDLE_VALUE)
{
Expand Down
1 change: 1 addition & 0 deletions PyLoader/PyLoader.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
<ItemGroup>
<ClInclude Include="depend\jute.h" />
<ClInclude Include="PyEvents.h" />
<ClInclude Include="PyEventsInternal.h" />
<ClInclude Include="sdk\PyInternal.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="PyLoader.h" />
Expand Down
1 change: 1 addition & 0 deletions PyLoader/PyLoader.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@
<ClInclude Include="sdk\PyInternal.h" />
<ClInclude Include="PyEvents.h" />
<ClInclude Include="depend\jute.h" />
<ClInclude Include="PyEventsInternal.h" />
</ItemGroup>
</Project>
8 changes: 4 additions & 4 deletions PyLoader/sdk/PyCLEO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ PyObject* PyCLEO::CallFunction(PyObject* self, PyObject* args)
AnyType* params = new AnyType[num_param];
AnyType* params_end = params + num_param * 0x4;

for (int i = 0; i < num_param; i++)
for (size_t i = 0; i < num_param; i++)
{
size_t index = i + 3; // addr, count, pop

Expand All @@ -41,7 +41,7 @@ PyObject* PyCLEO::CallFunction(PyObject* self, PyObject* args)
if (PyNumber_Check(ptemp))
{
if (PyFloat_Check(ptemp))
params[i].f = PyFloat_AsDouble(PyNumber_Float(ptemp));
params[i].f = (float)PyFloat_AsDouble(PyNumber_Float(ptemp));
else
params[i].i = PyLong_AsLong(PyNumber_Long(ptemp));
}
Expand Down Expand Up @@ -90,7 +90,7 @@ PyObject* PyCLEO::CallMethod(PyObject* self, PyObject* args)
AnyType* params = new AnyType[num_param];
AnyType* params_end = (AnyType*)(int(params) + num_param * 0x4);

for (int i = 0; i < num_param; i++)
for (size_t i = 0; i < num_param; i++)
{
size_t index = i + 4; // addr, struc, count, pop

Expand All @@ -100,7 +100,7 @@ PyObject* PyCLEO::CallMethod(PyObject* self, PyObject* args)
if (PyNumber_Check(ptemp))
{
if (PyFloat_Check(ptemp))
params[i].f = PyFloat_AsDouble(PyNumber_Float(ptemp));
params[i].f = (float)PyFloat_AsDouble(PyNumber_Float(ptemp));
else
params[i].i = PyLong_AsLong(PyNumber_Long(ptemp));
}
Expand Down
13 changes: 12 additions & 1 deletion PyLoader/sdk/PyCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,18 @@ PyObject* PyCommon::Wait(PyObject* self, PyObject* args)
ScriptData::Data* script_data = ScriptData::Get(GetCurrentThreadId());
if (!script_data->events_registered)
{
//PyEvents::VehicleCreate(script_data->pModule);

PyEvents::vehCreateEvent.AddModule(script_data->pModule, "on_veh_create");
PyEvents::vehDestroyEvent.AddModule(script_data->pModule, "on_veh_destroy");
PyEvents::vehRenderEvent.AddModule(script_data->pModule, "on_veh_render");
PyEvents::pedCreateEvent.AddModule(script_data->pModule, "on_ped_create");
PyEvents::pedDestroyEvent.AddModule(script_data->pModule, "on_ped_destroy");
PyEvents::pedRenderEvent.AddModule(script_data->pModule, "on_ped_render");
PyEvents::objCreateEvent.AddModule(script_data->pModule, "on_obj_create");
PyEvents::objDestroyEvent.AddModule(script_data->pModule, "on_obj_destroy");
PyEvents::objRenderEvent.AddModule(script_data->pModule, "on_obj_render");
PyErr_Clear();

script_data->events_registered = true;
}

Expand Down
19 changes: 19 additions & 0 deletions examples/Events.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import common

# Can be used for necessary cleanup
def on_script_terminate(error_occured: bool):
if error_occured:
print("Script terminated")
else:
print("Script exited")

while True:
if common.key_pressed(0x09):
break

common.wait(0)





0 comments on commit 7bc3958

Please sign in to comment.