Browse Source

Pre Release

main
DangerKiddy 11 months ago
parent
commit
313a5c6744
  1. 9
      README.md
  2. 11
      diddlerInternal/Global.cpp
  3. 24
      diddlerInternal/Global.h
  4. 728
      diddlerInternal/Lua.cpp
  5. 16
      diddlerInternal/Lua.h
  6. 2
      diddlerInternal/Lua.hpp
  7. 67
      diddlerInternal/TDFuncs.cpp
  8. 1
      diddlerInternal/TDObjects.h
  9. 3
      diddlerInternal/diddlerInternal.vcxproj
  10. 6
      diddlerInternal/diddlerInternal.vcxproj.filters
  11. 2
      diddlerInternal/dllmain.cpp
  12. 18
      diddlerInternal/miscPatches.cpp
  13. 6
      diddlerInternal/miscPatches.h
  14. 132
      diddlerInternal/multiplayer/Client.cpp
  15. 2
      diddlerInternal/multiplayer/Client.h
  16. 42
      diddlerInternal/multiplayer/Main.cpp
  17. 32
      diddlerInternal/multiplayer/Main.h
  18. 130
      diddlerInternal/multiplayer/Messages.h
  19. 75
      diddlerInternal/multiplayer/Player.cpp
  20. 28
      diddlerInternal/multiplayer/Player.h
  21. 99
      diddlerInternal/multiplayer/Server.cpp
  22. 5
      diddlerInternal/multiplayer/Server.h
  23. 197
      diddlerInternal/swapBuffers.cpp
  24. 13
      knedmod.wsp
  25. 7
      lua-5.1.4/lapi.c
  26. 1
      lua-5.1.4/ldo.h

9
README.md

@ -1,9 +0,0 @@
# KnedMod - a sandbox oriented mod for teardown
The main purpose of KnedMod is to give you a spawn menu within teardown that can be used to dynamically add new objects to the world.
It also adds a toolgun with various functions and a noclip mode.
This is considered far from a complete project and has a lot of known bugs that can cause crashes, however i feel it is a good resource for anyone attempting to make their own mod.
Building requires MS Detours and GLEW. KnedMod is released under the GNU GPL v3 license.
Tons of thanks to [SK83RJOSH](https://github.com/SK83RJOSH), [Nahu](https://github.com/nxhu64) and [Xorberax](https://github.com/ss-gnalvesteffer)

11
diddlerInternal/Global.cpp

@ -98,6 +98,17 @@ namespace glb {
tRegisterGameFunctions RegisterGameFunctions;
tRegisterLuaFunction tdRegisterLuaFunction;
tluaL_loadbuffer oluaL_loadbuffer;
tluaD_pcall oluaD_pcall;
tluaD_call oluaD_call;
tluaL_error oluaL_error;
tlua_pushfstring olua_pushfstring;
tlua_pushlstring olua_pushlstring;
tlua_createtable olua_createtable;
tluaV_gettable oluaV_gettable;
tluaV_settable oluaV_settable;
tluaS_newlstr oluaS_newlstr;
tlua_index2adr olua_index2adr;
createExplosion TDcreateExplosion;
spawnParticle TDspawnParticle;

24
diddlerInternal/Global.h

@ -18,6 +18,7 @@
#include "glm/glm.hpp"
#include "crashHandler.h"
#include "Script.h"
#include "Lua.hpp"
struct RaycastFilter
{
@ -75,6 +76,18 @@ typedef void* (__fastcall* TluaAlloc)(void* userData, void* ptr, size_t oldSize,
typedef void (*tRegisterGameFunctions) (CScriptCore* pScriptCore);
typedef void (*tRegisterLuaFunction) (CScriptCore_LuaState* pSCLS, td::small_string * sFunctionName, void* pFunction);
typedef int (*tluaL_loadbuffer) (lua_State* L, const char* buff, size_t size, const char* name);
typedef int (*tluaD_call) (lua_State* L, StkId func, int nResults);
typedef int (*tluaD_pcall) (lua_State* L, Pfunc func, void* u, ptrdiff_t old_top, ptrdiff_t ef);
//lua push functions and stuff
typedef void (*tluaL_error) (lua_State* L, const char* fmt, ...);
typedef const char* (__fastcall* tlua_pushfstring) (lua_State* L, const char* fmt, ...);
typedef int(__fastcall* tlua_pushlstring) (lua_State* L, const char* s, size_t);
typedef int(__fastcall* tlua_createtable) (lua_State* L, int narray, int nrec);
typedef int(__fastcall* tluaV_gettable) (lua_State* L, const TValue* t, TValue* key, StkId val);
typedef int(__fastcall* tluaV_settable) (lua_State* L, const TValue* t, TValue* key, StkId val);
typedef int(__fastcall* tluaS_newlstr) (lua_State* L, const char* str, size_t l);
typedef TValue*(__fastcall* tlua_index2adr) (lua_State* L, int idx);
//a1: GAME + 0xA8
//a2: small_string* containing path
@ -217,6 +230,17 @@ namespace glb {
extern tRegisterGameFunctions RegisterGameFunctions;
extern tRegisterLuaFunction tdRegisterLuaFunction;
extern tluaL_loadbuffer oluaL_loadbuffer;
extern tluaD_pcall oluaD_pcall;
extern tluaD_call oluaD_call;
extern tluaL_error oluaL_error;
extern tlua_pushfstring olua_pushfstring;
extern tlua_pushlstring olua_pushlstring;
extern tlua_createtable olua_createtable;
extern tluaV_gettable oluaV_gettable;
extern tluaV_settable oluaV_settable;
extern tluaS_newlstr oluaS_newlstr;
extern tlua_index2adr olua_index2adr;
extern createExplosion TDcreateExplosion;
extern spawnParticle TDspawnParticle;

728
diddlerInternal/Lua.cpp

@ -3,15 +3,110 @@
#include "Lua.h"
#include "Lua.hpp"
#include "multiplayer/Main.h"
#include "multiplayer/Client.h"
#include "multiplayer/Server.h"
#include "multiplayer/Player.h"
#include <vector>
#include <map>
#include <windef.h>
#include <WinBase.h>
#include <detours.h>
#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))
#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject)
#define checkresults(L,na,nr) \
api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)))
#define adjustresults(L,nres) \
{ if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; }
struct CallS { /* data to `f_call' */
StkId func;
int nresults;
};
static void f_call(lua_State* L, void* ud) {
struct CallS* c = cast(struct CallS*, ud);
glb::oluaD_call(L, c->func, c->nresults);
}
int pcall(lua_State* L, int nargs, int nresults, int errfunc)
{
struct CallS c;
int status;
ptrdiff_t func;
lua_lock(L);
api_checknelems(L, nargs + 1);
checkresults(L, nargs, nresults);
func = 0;
c.func = L->top - (nargs + 1); /* function to be called */
c.nresults = nresults;
status = glb::oluaD_pcall(L, f_call, &c, savestack(L, c.func), func);
adjustresults(L, nresults);
lua_unlock(L);
return status;
}
static TValue* index2adr(lua_State* L, int idx) {
if (idx > 0) {
TValue* o = L->base + (idx - 1);
api_check(L, idx <= L->ci->top - L->base);
if (o >= L->top) return cast(TValue*, luaO_nilobject);
else return o;
}
else if (idx > LUA_REGISTRYINDEX) {
api_check(L, idx != 0 && -idx <= L->top - L->base);
return L->top + idx;
}
else switch (idx) { /* pseudo-indices */
case LUA_REGISTRYINDEX: return registry(L);
case LUA_ENVIRONINDEX: {
Closure* func = curr_func(L);
sethvalue(L, &L->env, func->c.env);
return &L->env;
}
case LUA_GLOBALSINDEX: return gt(L);
default: {
Closure* func = curr_func(L);
idx = LUA_GLOBALSINDEX - idx;
return (idx <= func->c.nupvalues)
? &func->c.upvalue[idx - 1]
: cast(TValue*, luaO_nilobject);
}
}
}
void settable(lua_State* L, int idx) {
StkId t;
lua_lock(L);
api_checknelems(L, 2);
t = index2adr(L, idx);//glb::olua_index2adr(L, idx);//
api_checkvalidindex(L, t);
glb::oluaV_settable(L, t, L->top - 2, L->top - 1);
L->top -= 2; /* pop index and value */
lua_unlock(L);
}
void pushstring(lua_State* L, const char* str)
{
glb::olua_pushlstring(L, str, strlen(str));
}
#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}
void Tick(CScriptCore* pSC, lua_State* L, CRetInfo* ret)
{
TDMP::LuaTick();
}
std::vector<LUA::Callback> callbacks;
std::vector<LUA::Callback> LUA::callbacks{};
void RegisterCallback(CScriptCore* pSC, lua_State* L, CRetInfo* ret)
{
TDMP::Debug::print(L);
@ -26,74 +121,631 @@ void RegisterCallback(CScriptCore* pSC, lua_State* L, CRetInfo* ret)
callback.L = L;
callback.name = callbackName;
callback.ref = luaL_ref(L, LUA_REGISTRYINDEX);
callbacks.push_back(callback);
TDMP::Debug::print("Callback \"" + std::string(callbackName) + "\" was registered");
LUA::callbacks.push_back(callback);
TDMP::Debug::print("Event \"" + std::string(callbackName) + "\" was registered");
}
lua_pop(L, top);
}
void CallCallback(CScriptCore* pSC, lua_State* L, CRetInfo* ret)
std::map<std::string, std::map<const char*, LUA::Hook>> LUA::hooks;
struct callHook
{
LUA::Hook hook;
std::string json;
};
std::map<int, std::vector<callHook>> hookQueue;
void AddHook(CScriptCore* pSC, lua_State* L, CRetInfo* ret)
{
int top = lua_gettop(L);
const char* callbackName = luaL_checkstring(L, 1);
const char* hookEvent = luaL_checkstring(L, 1);
const char* hookName = luaL_checkstring(L, 2);
if (lua_isfunction(L, 3))
{
LUA::Hook hook;
hook.L = L;
hook.hook = std::string(hookEvent);
hook.name = hookName;
hook.ref = luaL_ref(L, LUA_REGISTRYINDEX);
if (LUA::hooks.count(hook.hook) <= 0)
LUA::hooks[hook.hook] = std::map<const char*, LUA::Hook>{};
LUA::hooks[hook.hook][hook.name] = hook;
}
lua_pop(L, top);
}
void LUA::RunLuaHooks(const char* hookName, const char* jsonData)
{
for (const auto& [hook, hookListeners] : LUA::hooks)
{
if (hook == std::string(hookName))
{
for (const auto& [hookName, hook] : hookListeners)
{
if (hook.L == nullptr)
continue;
hookQueue[(int)hook.L].push_back(callHook{
hook, std::string(jsonData)
});
}
break;
}
}
}
void RunGlobalHook(CScriptCore* pSC, lua_State* L, CRetInfo* ret)
{
int top = lua_gettop(L);
const char* hookName = luaL_checkstring(L, 1);
const char* jsonData = luaL_checkstring(L, 2);
lua_pop(L, top);
LUA::RunLuaHooks(hookName, jsonData);
}
void RunHooks(CScriptCore* pSC, lua_State* L, CRetInfo* ret)
{
for (size_t i = 0; i < hookQueue[(int)L].size(); i++)
{
callHook* cH = &hookQueue[(int)L][i];
lua_rawgeti(cH->hook.L, LUA_REGISTRYINDEX, cH->hook.ref);
pushstring(cH->hook.L, cH->json.c_str());
if (pcall(cH->hook.L, 1, 0, 0))
{
const char* err = lua_tolstring(cH->hook.L, -1, NULL);
TDMP::Debug::error(err);
lua_pop(cH->hook.L, 1);
}
}
hookQueue[(int)L].clear();
}
void LUA::CallCallbacks(const char* callbackName)
{
for (size_t i = 0; i < callbacks.size(); i++)
{
if (std::string(callbacks[i].name) == std::string(callbackName))
{
Callback* callback = &callbacks.data()[i];
if (callback->L == nullptr)
continue;
lua_rawgeti(callback->L, LUA_REGISTRYINDEX, callback->ref);
if (pcall(callback->L, 0, 0, 0))
{
const char* err = lua_tolstring(callback->L, -1, NULL);
TDMP::Debug::error(err);
lua_pop(callback->L, 1);
}
}
}
}
void LUA::CallEvent(const char* eventName, const char* jsonData)
{
for (size_t i = 0; i < callbacks.size(); i++)
{
if (callbacks[i].name == callbackName)
Callback* callback = &callbacks.data()[i];
if (std::string(callback->name) == std::string(eventName))
{
lua_rawgeti(callbacks[i].L, LUA_REGISTRYINDEX, callbacks[i].ref);
lua_pushvalue(callbacks[i].L, 2);
if (lua_pcall(callbacks[i].L, 1, 0, 0))
if (callback->L == nullptr)
continue;
lua_rawgeti(callback->L, LUA_REGISTRYINDEX, callback->ref);
pushstring(callback->L, jsonData);
if (pcall(callback->L, 1, 0, 0))
{
const char* err = lua_tolstring(callbacks[i].L, -1, NULL);
const char* err = lua_tolstring(callback->L, -1, NULL);
TDMP::Debug::error(err);
lua_pop(callbacks[i].L, 1);
lua_pop(callback->L, 1);
}
}
}
}
lua_pop(callbacks[i].L, lua_gettop(callbacks[i].L));
void SendCallback(CScriptCore* pSC, lua_State* L, CRetInfo* ret)
{
int top = lua_gettop(L);
const char* callbackName = luaL_checkstring(L, 1);
bool callbackFound = false;
for (size_t i = 0; i < LUA::callbacks.size(); i++)
{
if (LUA::callbacks[i].name == callbackName)
{
callbackFound = true;
break;
}
}
if (!callbackFound)
{
lua_pop(L, top);
glb::oluaL_error(L, "Unkown callback! (%s)", callbackName);
return;
}
int secondArgType = lua_type(L, 2);
bool reliable = lua_toboolean(L, 3);
const char* json = luaL_checkstring(L, 4);
int sendType = reliable ? k_nSteamNetworkingSend_Reliable : k_nSteamNetworkingSend_Unreliable;
MsgLuaCallback msg;
msg.SetCallback(callbackName);
msg.SetJson(json);
msg.SetReliable(reliable);
// If server sends message to the client
if (secondArgType == LUA_TSTRING)
{
if (TDMP::server == nullptr)
{
lua_pop(L, top);
TDMP::Debug::error("Tried to SendEvent without server initialised");
return;
}
const char* steamId = luaL_checkstring(L, 2);
lua_pop(L, top);
if (TDMP::playersBySteamId.count(steamId))
{
TDMP::server->SendDataToConnection(&msg, sizeof(msg), TDMP::players[TDMP::playersBySteamId[steamId]].conn, sendType);
}
else
{
TDMP::Debug::error("Tried to send event to unknown SteamID!");
}
return;
}
lua_pop(L, top);
// Otherwise client sends message to the server
TDMP::client->SendData(&msg, sizeof(msg), sendType);
}
void LUA::RegisterLuaCFunctions(CScriptCore_LuaState* pSCLS)
void BroadcastCallback(CScriptCore* pSC, lua_State* L, CRetInfo* ret)
{
RegisterLuaFunction(pSCLS, "TDMP_Tick", Tick);
int top = lua_gettop(L);
if (TDMP::server == nullptr)
{
lua_pop(L, top);
TDMP::Debug::error("Tried to broadcast without server initialised");
return;
}
const char* callbackName = luaL_checkstring(L, 1);
bool reliable = lua_toboolean(L, 2);
bool sendSelf = lua_toboolean(L, 3);
const char* json = luaL_checkstring(L, 4);
lua_pop(L, top);
RegisterLuaFunction(pSCLS, "TDMP_RegisterCallback", RegisterCallback);
RegisterLuaFunction(pSCLS, "TDMP_CallCallback", CallCallback);
// We're checking does this callback exists at all, so we won't overflow network with empty callbacks
for (size_t i = 0; i < LUA::callbacks.size(); i++)
{
if (LUA::callbacks[i].name == callbackName)
{
MsgLuaCallback msg;
msg.SetCallback(callbackName);
msg.SetJson(json);
TDMP::server->BroadcastData(&msg, sizeof(msg), reliable ? k_nSteamNetworkingSend_Reliable : k_nSteamNetworkingSend_Unreliable, sendSelf);
return;
}
}
glb::oluaL_error(L, "Unkown callback! (%s)", callbackName);
}
void* luaAlloc(void* userData, void* ptr, size_t oldSize, size_t newSize)
{
if (newSize == 0)
void pushplayer(lua_State* L, int plyId)
{
TDMP::Player ply = TDMP::players[plyId];
glb::olua_createtable(L, 0, 4);
pushstring(L, "steamId");
pushstring(L, ply.steamIdStr.c_str());
settable(L, -3);
pushstring(L, "nick");
pushstring(L, ply.nick.c_str());
settable(L, -3);
pushstring(L, "id");
lua_pushinteger(L, plyId);
settable(L, -3);
pushstring(L, "hp");
lua_pushinteger(L, ply.hp);
settable(L, -3);
if (ply.currentVehicle != 0)
{
if (ptr != nullptr)
glb::oTFree((uintptr_t)ptr);
return NULL;
pushstring(L, "veh");
lua_pushnumber(L, ply.currentVehicle->Id);
settable(L, -3);
}
if (ply.body.body != 0 && ply.bodyExists)
{
pushstring(L, "body");
lua_pushnumber(L, ply.body.body->Id);
settable(L, -3);
}
else
return glb::oTRealloc(ptr, newSize);
}
void GetPlayerTransform(CScriptCore* pSC, lua_State* L, int* ret)
{
int id = luaL_checkinteger(L, 1);
lua_pop(L, 1);
void hRegisterGameFunctions(CScriptCore* pSC)
if (id > TDMP::MaxPlayers - 1 || id < 0)
{
glb::oluaL_error(L, "incorrect id (must be 0-%d)", TDMP::MaxPlayers - 1);
return;
}
TDMP::Player ply = TDMP::players[id];
glb::olua_createtable(L, 0, 2);
pushstring(L, "pos");
glb::olua_createtable(L, 0, 3);
lua_pushnumber(L, 1);
lua_pushnumber(L, ply.Position.x);
settable(L, -3);
lua_pushnumber(L, 2);
lua_pushnumber(L, ply.Position.y);
settable(L, -3);
lua_pushnumber(L, 3);
lua_pushnumber(L, ply.Position.z);
settable(L, -3);
settable(L, -3);
pushstring(L, "rot");
glb::olua_createtable(L, 0, 4);
lua_pushnumber(L, 1);
lua_pushnumber(L, ply.Rotation.x);
settable(L, -3);
lua_pushnumber(L, 2);
lua_pushnumber(L, ply.Rotation.y);
settable(L, -3);
lua_pushnumber(L, 3);
lua_pushnumber(L, ply.Rotation.z);
settable(L, -3);
lua_pushnumber(L, 4);
lua_pushnumber(L, ply.Rotation.w);
settable(L, -3);
settable(L, -3);
(*ret) = 1;
}
void GetPlayerCameraTransform(CScriptCore* pSC, lua_State* L, int* ret)
{
int id = luaL_checkinteger(L, 1);
lua_pop(L, 1);
if (id > TDMP::MaxPlayers - 1 || id < 0)
{
glb::oluaL_error(L, "incorrect id (must be 0-%d)", TDMP::MaxPlayers - 1);
return;
}
TDMP::Player ply = TDMP::players[id];
glb::olua_createtable(L, 0, 2);
pushstring(L, "pos");
glb::olua_createtable(L, 0, 3);
lua_pushnumber(L, 1);
lua_pushnumber(L, ply.CamPosition.x);
settable(L, -3);
lua_pushnumber(L, 2);
lua_pushnumber(L, ply.CamPosition.y);
settable(L, -3);
lua_pushnumber(L, 3);
lua_pushnumber(L, ply.CamPosition.z);
settable(L, -3);
settable(L, -3);
pushstring(L, "rot");
glb::olua_createtable(L, 0, 4);
lua_pushnumber(L, 1);
lua_pushnumber(L, ply.CamRotation.w);
settable(L, -3);
lua_pushnumber(L, 2);
lua_pushnumber(L, ply.CamRotation.x);
settable(L, -3);
lua_pushnumber(L, 3);
lua_pushnumber(L, ply.CamRotation.y);
settable(L, -3);
lua_pushnumber(L, 4);
lua_pushnumber(L, ply.CamRotation.z);
settable(L, -3);
settable(L, -3);
(*ret) = 1;
}
/// <summary>
/// Returns table of active players
/// </summary>
void GetPlayers(CScriptCore* pSC, lua_State* L, int* ret)
{
glb::olua_createtable(L, 0, 0);
int k = 0;
for (uint32 i = 0; i < TDMP::MaxPlayers; ++i)
{
TDMP::Player ply = TDMP::players[i];
if (ply.Active)
{
lua_pushinteger(L, ++k);
pushplayer(L, i);
settable(L, -3);
}
}
(*ret) = 1;
}
/// <summary>
/// Returns player at specific id
/// </summary>
void GetPlayer(CScriptCore* pSC, lua_State* L, int* ret)
{
int id = luaL_checkinteger(L, 1);
lua_pop(L, 1);
if (id > TDMP::MaxPlayers - 1 || id < 0)
{
glb::oluaL_error(L, "incorrect id (must be 0-%d)", TDMP::MaxPlayers - 1);
return;
}
pushplayer(L, id);
(*ret) = 1;
}
/// <summary>
/// This function returns not cached player's nick
/// </summary>
void GetNick(CScriptCore* pSC, lua_State* L, int* ret)
{
int id = luaL_checkinteger(L, 1);
lua_pop(L, lua_gettop(L));
if (id > TDMP::MaxPlayers - 1 || id < 0)
{
glb::oluaL_error(L, "incorrect id (must be 0-%d)", TDMP::MaxPlayers - 1);
return;
}
pushstring(L, SteamFriends()->GetPlayerNickname(TDMP::players[id].SteamId));
(*ret) = 1;
}
void GetTableId(CScriptCore* pSC, lua_State* L, int* ret)
{
int top = lua_gettop(L);
const char* steamId = luaL_checkstring(L, 1);
lua_pop(L, top);
if (TDMP::playersBySteamId.count(steamId))
{
lua_pushinteger(L, TDMP::playersBySteamId[steamId]);
(*ret) = 1;
}
}
void IsMe(CScriptCore* pSC, lua_State* L, int* ret)
{
int id = luaL_checkinteger(L, 1);
lua_pop(L, 1);
if (id > TDMP::MaxPlayers - 1 || id < 0)
{
glb::oluaL_error(L, "incorrect id (must be 0-%d)", TDMP::MaxPlayers - 1);
return;
}
lua_pushboolean(L, TDMP::players[id].IsMe());
(*ret) = 1;
}
bool notCached = true;
std::string localSteamId;
void LocalSteamId(CScriptCore* pSC, lua_State* L, int* ret)
{
if (notCached)
{
notCached = false;
localSteamId = std::to_string(SteamUser()->GetSteamID().ConvertToUint64());
}
pushstring(L, localSteamId.c_str());
(*ret) = 1;
}
void IsServerInitialised(CScriptCore* pSC, lua_State* L, int* ret)
{
lua_pushboolean(L, TDMP::server != nullptr);
(*ret) = 1;
}
void IsServer(CScriptCore* pSC, lua_State* L, int* ret)
{
void* ud;
lua_Alloc a = lua_getallocf(*pSC->m_SCLuaState.m_LuaState, &ud);
TDMP::Debug::print(a);
lua_pushboolean(L, TDMP::IsServer());
lua_setallocf(*pSC->m_SCLuaState.m_LuaState, a, ud);
(*ret) = 1;
}
void SetPlayerModelEnabled(CScriptCore* pSC, lua_State* L, int* ret)
{
int id = luaL_checkinteger(L, 1);
bool enable = lua_toboolean(L, 2);
lua_pop(L, lua_gettop(L));
if (id > TDMP::MaxPlayers - 1 || id < 0)
{
glb::oluaL_error(L, "incorrect id (must be 0-%d)", TDMP::MaxPlayers - 1);
return;
}
if (TDMP::players[id].Active)
{
if (enable)
{
TDMP::players[id].hideBody = false;
TDMP::players[id].CreateBodyIfNotExists();
}
else
{
TDMP::players[id].hideBody = true;
TDMP::players[id].RemoveBodyIfExists();
}
}
}
void GetPlayerModelEnabled(CScriptCore* pSC, lua_State* L, int* ret)
{
int id = luaL_checkinteger(L, 1);
lua_pop(L, lua_gettop(L));
if (id > TDMP::MaxPlayers - 1 || id < 0)
{
glb::oluaL_error(L, "incorrect id (must be 0-%d)", TDMP::MaxPlayers - 1);
return;
}
lua_pushboolean(L, !TDMP::players[id].hideBody);
(*ret) = 1;
}
void ConsolePrint(CScriptCore* pSC, lua_State* L, int* ret)
{
int top = lua_gettop(L);
std::string output = "";
for (size_t i = 1; i <= top; i++)
{
output += lua_tostring(L, i) + std::string("\t");
}
TDMP::Debug::print(output);
}
void Update(CScriptCore* pSC, lua_State* L, int* ret)
{
TDMP::LuaUpdate();
}
void Time(CScriptCore* pSC, lua_State* L, int* ret)
{
lua_pushnumber(L, ((lua_Number)clock()) / (lua_Number)CLOCKS_PER_SEC);
(*ret) = 1;
}
void LUA::RegisterLuaCFunctions(CScriptCore_LuaState* pSCLS)
{
hookQueue[(int)*pSCLS->m_LuaState] = std::vector<callHook>{};
RegisterLuaFunction(pSCLS, "TDMP_ConPrint", ConsolePrint);
RegisterLuaFunction(pSCLS, "TDMP_UnixTime", Time);
RegisterLuaFunction(pSCLS, "TDMP_Tick", Tick);
RegisterLuaFunction(pSCLS, "TDMP_Update", Update);
RegisterLuaFunction(pSCLS, "TDMP_IsServerInitialised", IsServerInitialised);
RegisterLuaFunction(pSCLS, "TDMP_IsServer", IsServer);
RegisterLuaFunction(pSCLS, "TDMP_RegisterEvent", RegisterCallback);
RegisterLuaFunction(pSCLS, "TDMP_SendEvent", SendCallback);
RegisterLuaFunction(pSCLS, "TDMP_BroadcastEvent", BroadcastCallback);
RegisterLuaFunction(pSCLS, "TDMP_GetPlayers", GetPlayers);
RegisterLuaFunction(pSCLS, "TDMP_GetPlayer", GetPlayer);
RegisterLuaFunction(pSCLS, "TDMP_GetPlayerTransform", GetPlayerTransform);
RegisterLuaFunction(pSCLS, "TDMP_GetPlayerCameraTransform", GetPlayerCameraTransform);
RegisterLuaFunction(pSCLS, "TDMP_SetPlayerBodyEnabled", SetPlayerModelEnabled);
RegisterLuaFunction(pSCLS, "TDMP_LocalSteamId", LocalSteamId);
RegisterLuaFunction(pSCLS, "TDMP_IsMe", IsMe);
RegisterLuaFunction(pSCLS, "TDMP_RunGlobalHook", RunGlobalHook);
RegisterLuaFunction(pSCLS, "TDMP_AddGlobalHookListener", AddHook);
RegisterLuaFunction(pSCLS, "TDMP_Hook_Queue", RunHooks);
}
void hRegisterGameFunctions(CScriptCore* pSC)
{
glb::RegisterGameFunctions(pSC);
TDMP::Debug::print("Registering lua functions");
@ -106,12 +758,22 @@ int hluaL_loadbuffer(lua_State* L, const char* buff, size_t size, const char* na
return glb::oluaL_loadbuffer(L, buff, size, name);
}
void makehole(TDScene* scene, td::Vec3* position, float damageA, float damageB, int unkn1, int* unkn2)
{
}
void LUA::HookRegisterGameFunctions()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)glb::RegisterGameFunctions, hRegisterGameFunctions);
DetourTransactionCommit();
//DetourTransactionBegin();
//DetourUpdateThread(GetCurrentThread());
//DetourAttach(&(PVOID&)glb::oWrappedDamage, makehole);
//DetourTransactionCommit();
}
int CallLuaFunction(lua_State* L) {
@ -126,8 +788,6 @@ int CallLuaFunction(lua_State* L) {
void LUA::RegisterLuaFunction(CScriptCore_LuaState* pSCLS, const char* cFunctionName, void* pFunction)
{
TDMP::Debug::print("Registering " + std::string(cFunctionName));
lua_pushlightuserdata(*pSCLS->m_LuaState, pFunction);
lua_pushlightuserdata(*pSCLS->m_LuaState, pSCLS);
lua_pushcclosure(*pSCLS->m_LuaState, CallLuaFunction, 2);

16
diddlerInternal/Lua.h

@ -1,5 +1,6 @@
#pragma once
#include "Script.h"
#include <map>
namespace LUA
{
@ -16,4 +17,19 @@ namespace LUA
const char* name;
int ref;
};
struct Hook
{
lua_State* L;
std::string hook;
const char* name;
int ref;
};
extern std::vector<Callback> callbacks;
extern std::map<std::string, std::map<const char*, LUA::Hook>> hooks;
void RunLuaHooks(const char* hookName, const char* jsonData);
void CallCallbacks(const char* callbackName);
void CallEvent(const char* eventName, const char* jsonData);
}

2
diddlerInternal/Lua.hpp

@ -2,4 +2,6 @@ extern "C" {
#include "../lua-5.1.4/lua.h"
#include "../lua-5.1.4/lualib.h"
#include "../lua-5.1.4/lauxlib.h"
#include "../lua-5.1.4/lobject.h"
#include "../lua-5.1.4/ldo.h"
}

67
diddlerInternal/TDFuncs.cpp

@ -16,6 +16,11 @@ void printIntegPercentage(float p) {
SetConsoleTextAttribute(hConsole, 15);
}
void hLog(td::small_string* msg)
{
printf_s("[Game Log] %s\n", msg->c_str());
}
void sigscanItems() {
//glb::oTdDelBdy = (deleteBody)mem::FindPattern((PBYTE)"\x48\x83\xEC\x28\x48\x8B\xCA\x33\xD2\xE8\x82\x16\x0F\x00\x48\x8B", "xxxxxxxxxxxxxxxx", GetModuleHandle(NULL), &percentage);
//glb::oMakeHole = (makeHole)mem::FindPattern((PBYTE)"\x48\x8B\xC4\x53\x48\x81\xEC\x90\x00\x00\x00\x0F\x29\x70\xE8\x4C\x8D\x40\xA8\x48\x8B\xDA\x0F\x29\x78\xD8\x44\x0F\x29\x40\xC8\x48", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", GetModuleHandle(NULL), &percentage);
@ -53,7 +58,7 @@ void sigscanItems() {
bool sigScanError = false;
float percentage = 0;
glb::TDOL = *(TDObjectList**)(glb::moduleBase + 0x00455100);
glb::TDOL = *(TDObjectList**)(glb::moduleBase + 0x00456140);
glb::game = (TDGame*)glb::TDOL;
glb::scene = (TDScene*)glb::TDOL->objs[9];
glb::renderer = (TDRenderer*)glb::TDOL->objs[8];
@ -293,6 +298,66 @@ void sigscanItems() {
printIntegPercentage(percentage);
if (!glb::oluaL_loadbuffer) { sigScanError = true; }
glb::oluaD_pcall = (tluaD_pcall)mem::FindPattern((PBYTE)"\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x48\x89\x74\x24\x00\x48\x89\x7C\x24\x00\x41\x54\x41\x56\x41\x57\x48\x83\xEC\x20\x4C\x8B\x71\x28\x49\x8B\xD9\x48\x8B\x44\x24\x00\x48\x8B\xF9\x48\x8B\xA9\x00\x00\x00\x00", "xxxx?xxxx?xxxx?xxxx?xxxxxxxxxxxxxxxxxxxxx?xxxxxx????", GetModuleHandle(NULL), &percentage);
printf_s("oluaD_pcall : %p", glb::oluaD_pcall);
printIntegPercentage(percentage);
if (!glb::oluaD_pcall) { sigScanError = true; }
glb::oluaD_call = (tluaD_call)mem::FindPattern((PBYTE)"\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x20\x66\xFF\x41\x60\x48\x8B\xD9\x0F\xB7\x41\x60", "xxxx?xxxx?xxxxxxxxxxxxxxxx", GetModuleHandle(NULL), &percentage);
printf_s("oluaD_call : %p", glb::oluaD_call);
printIntegPercentage(percentage);
if (!glb::oluaD_call) { sigScanError = true; }
glb::oluaL_error = (tluaL_error)mem::FindPattern((PBYTE)"\x48\x89\x54\x24\x00\x4C\x89\x44\x24\x00\x4C\x89\x4C\x24\x00\x53\x56\x57\x48\x83\xEC\x20\xBA\x00\x00\x00\x00\x48\x8D\x74\x24\x00\x48\x8B\xD9\xE8\x00\x00\x00\x00", "xxxx?xxxx?xxxx?xxxxxxxx????xxxx?xxxx????", GetModuleHandle(NULL), &percentage);
printf_s("oluaL_error : %p", glb::oluaL_error);
printIntegPercentage(percentage);
if (!glb::oluaL_error) { sigScanError = true; }
glb::olua_pushfstring = (tlua_pushfstring)mem::FindPattern((PBYTE)"\x48\x89\x54\x24\x00", "xxxx?", GetModuleHandle(NULL), &percentage);
printf_s("olua_pushfstring : %p", glb::olua_pushfstring);
printIntegPercentage(percentage);
if (!glb::olua_pushfstring) { sigScanError = true; }
glb::olua_pushlstring = (tlua_pushlstring)mem::FindPattern((PBYTE)"\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x20\x4C\x8B\x49\x20\x49\x8B\xF0\x48\x8B\xEA\x48\x8B\xF9\x49\x8B\x41\x70\x49\x39\x41\x78\x72\x05", "xxxx?xxxx?xxxx?xxxxxxxxxxxxxxxxxxxxxxxxxxxx", GetModuleHandle(NULL), &percentage);
printf_s("olua_pushlstring : %p", glb::olua_pushlstring);
printIntegPercentage(percentage);
if (!glb::olua_pushlstring) { sigScanError = true; }
glb::olua_createtable = (tlua_createtable)mem::FindPattern((PBYTE)"\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x20\x4C\x8B\x49\x20\x41\x8B\xF0\x8B\xEA\x48\x8B\xF9\x49\x8B\x41\x70\x49\x39\x41\x78\x72\x05", "xxxx?xxxx?xxxx?xxxxxxxxxxxxxxxxxxxxxxxxxxx", GetModuleHandle(NULL), &percentage);
printf_s("olua_createtable : %p", glb::olua_createtable);
printIntegPercentage(percentage);
if (!glb::olua_createtable) { sigScanError = true; }
glb::oluaV_settable = (tluaV_settable)mem::FindPattern((PBYTE)"\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x56\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xEC\x30\x4D\x8B\xE1\x48\x89\x7C\x24\x00\x4D\x8B\xF8\x4C\x8D\x2D\x00\x00\x00\x00\x4C\x8B\xF2\x48\x8B\xF1\x33\xED", "xxxx?xxxx?xxxxxxxxxxxxxxxxxxxx?xxxxxx????xxxxxxxx", GetModuleHandle(NULL), &percentage);
printf_s("oluaV_settable : %p", glb::oluaV_settable);
printIntegPercentage(percentage);
if (!glb::oluaV_settable) { sigScanError = true; }
glb::oluaV_gettable = (tluaV_gettable)mem::FindPattern((PBYTE)"\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x48\x89\x74\x24\x00\x48\x89\x7C\x24\x00\x41\x54\x41\x56\x41\x57\x48\x83\xEC\x30\x4D\x8B\xF9\x4C\x8D\x25\x00\x00\x00\x00\x4D\x8B\xF0\x48\x8B\xFA\x48\x8B\xF1\x33\xED", "xxxx?xxxx?xxxx?xxxx?xxxxxxxxxxxxxxxx????xxxxxxxxxxx", GetModuleHandle(NULL), &percentage);
printf_s("oluaV_gettable : %p", glb::oluaV_gettable);
printIntegPercentage(percentage);
if (!glb::oluaV_gettable) { sigScanError = true; }
glb::oluaS_newlstr = (tluaS_newlstr)mem::FindPattern((PBYTE)"\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x48\x89\x74\x24\x00\x57\x41\x56\x41\x57\x48\x83\xEC\x20\x49\x8B\xF0\x41\x8B\xF8", "xxxx?xxxx?xxxx?xxxxxxxxxxxxxxx", GetModuleHandle(NULL), &percentage);
printf_s("oluaS_newlstr : %p", glb::oluaS_newlstr);
printIntegPercentage(percentage);
if (!glb::oluaS_newlstr) { sigScanError = true; }
glb::olua_index2adr = (tlua_index2adr)mem::FindPattern((PBYTE)"\x85\xD2\x7E\x1F", "xxxx", GetModuleHandle(NULL), &percentage);
printf_s("olua_index2adr : %p", glb::olua_index2adr);
printIntegPercentage(percentage);
if (!glb::olua_index2adr) { sigScanError = true; }
DWORD64 Log = mem::FindPattern((PBYTE)"\x80\x79\x0F\x00\x74\x03\x48\x8B\x09\x48\x8B\xD1\x48\x8D\x0D\x00\x00\x00\x00", "xxxxxxxxxxxxxxx????", GetModuleHandle(NULL), &percentage);
printf_s("Log : %p", &Log);
printIntegPercentage(percentage);
if (!Log) { sigScanError = true; }
else {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)Log, hLog);
DetourTransactionCommit();
}
if (sigScanError) {
std::cout << "[F] FAILED TO FIND A CRITICAL FUNCTION, EXPECT ISSUES" << std::endl;

1
diddlerInternal/TDObjects.h

@ -213,6 +213,7 @@ public:
};
// TODO: Fix offsets, "health" isn't health anymore
class TDPlayer {
public:
td::Vec3 position; //0x000 - 0x012

3
diddlerInternal/diddlerInternal.vcxproj

@ -84,6 +84,7 @@
<IncludePath>E:\visual studio projects\knedmod\MS Detours;E:\visual studio projects\knedmod\glew\GL;E:\visual studio projects\knedmod\lua-5.1.4;$(IncludePath)</IncludePath>
<LibraryPath>E:\visual studio projects\knedmod\lua-5.1.4;E:\visual studio projects\knedmod\MS Detours;E:\visual studio projects\knedmod\glew;$(LibraryPath)</LibraryPath>
<ExternalIncludePath>$(ExternalIncludePath)</ExternalIncludePath>
<TargetName>tdmp</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@ -209,7 +210,6 @@
<ClInclude Include="mainHook.h" />
<ClInclude Include="maths.h" />
<ClInclude Include="memhandler.h" />
<ClInclude Include="miscPatches.h" />
<ClInclude Include="movementLoop.h" />
<ClInclude Include="objectSpawner.h" />
<ClInclude Include="Raycaster.h" />
@ -276,7 +276,6 @@
<ClCompile Include="mainHook.cpp" />
<ClCompile Include="maths.cpp" />
<ClCompile Include="memhandler.cpp" />
<ClCompile Include="miscPatches.cpp" />
<ClCompile Include="movementLoop.cpp" />
<ClCompile Include="multiplayer\Client.cpp" />
<ClCompile Include="multiplayer\Lobby.cpp" />

6
diddlerInternal/diddlerInternal.vcxproj.filters

@ -114,9 +114,6 @@
<ClInclude Include="mainHook.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="miscPatches.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="movementLoop.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -296,9 +293,6 @@
<ClCompile Include="mainHook.cpp">
<Filter>Source Files\Mods</Filter>
</ClCompile>
<ClCompile Include="miscPatches.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="movementLoop.cpp">
<Filter>Source Files</Filter>
</ClCompile>

2
diddlerInternal/dllmain.cpp

@ -98,7 +98,7 @@ DWORD WINAPI main(HMODULE hModule)
std::cout << "| |/ | | | ___| \\| | | | \\ " << std::endl;
std::cout << "| <| | ___| -- | | - | -- |" << std::endl;
std::cout << "|__|\\__|__|____|_______|_____/|__|_|__|_______|_____/ " << std::endl;
std::cout << "For teardown MAIN BRANCH version 0.8.0" << std::endl;
std::cout << "For teardown MAIN BRANCH version 0.9.2" << std::endl;
std::cout << "KnedMod is C to Knedit and is released under the GNU public license" << std::endl;
std::cout << "" << std::endl;
std::cout << "" << std::endl;

18
diddlerInternal/miscPatches.cpp

@ -1,18 +0,0 @@
#include "Global.h"
namespace miscPatches {
bool plankPatch = false;
void updatePlankPatch () {
byte origionalAsm[9] = {0xF3, 0x0F, 0x5F, 0xF7, 0xF3, 0x41, 0x0F, 0x5D, 0xF0}; //MAXSS XMM6, XMM7 - MINSS XMMM6, XMM8
byte patchAsm[9] = {0xBA, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x0F, 0x6E, 0xF2}; //MOV EDX, FFFFFF - MOVD XMM6, EDX
uintptr_t patchLocation = glb::plankPatchFunction + 0x466;
if (plankPatch) {
mem::Patch((byte*)patchLocation, patchAsm, 9);
}
else {
mem::Patch((byte*)patchLocation, origionalAsm, 9);
}
}
}

6
diddlerInternal/miscPatches.h

@ -1,6 +0,0 @@
#pragma once
namespace miscPatches {
extern bool plankPatch;
void updatePlankPatch();
}

132
diddlerInternal/multiplayer/Client.cpp

@ -3,6 +3,7 @@
#include "Lobby.h"
#include "Player.h"
#include <thread>
#include <Windows.h>
#include "../drawCube.h"
#include "../objectSpawner.h"
@ -10,6 +11,8 @@
#include "../glm/gtc/quaternion.hpp"
#include "../glm/vec3.hpp"
#include "../Lua.h"
TDMP::Client* TDMP::client;
std::vector<std::string> TDMP::packets;
@ -99,6 +102,7 @@ void TDMP::Client::SendData(const void* pData, uint32 nSizeOfData, int nSendFlag
}
}
std::vector<LuaCallbackQueue> clientCallbackQueue;
void TDMP::Client::LuaTick()
{
for (uint32 i = 0; i < MaxPlayers; ++i)
@ -108,6 +112,17 @@ void TDMP::Client::LuaTick()
players[i].LuaTick();
}
}
int callbacks = clientCallbackQueue.size();
if (callbacks > 0)
{
for (size_t i = 0; i < callbacks; i++)
{
LUA::CallEvent(clientCallbackQueue[i].callback.c_str(), clientCallbackQueue[i].json.c_str());
}
clientCallbackQueue.clear();
}
}
void TDMP::Client::Tick()
@ -123,7 +138,7 @@ void TDMP::Client::Tick()
MsgPlayerData msg;
glm::quat rot(glm::vec3(0, -glb::player->camYaw + 270, -1.57f));
glm::quat rot(glm::vec3(0, (-glb::player->camYaw + 270), -1.57f)); // * pi / 180.0
td::Vec4 finalRot;
finalRot.x = rot.x;
@ -131,7 +146,7 @@ void TDMP::Client::Tick()
finalRot.z = rot.z;
finalRot.w = rot.w;
msg.SetPlayer(glb::player->position, finalRot);
msg.SetPlayer(glb::player->position, finalRot, glb::player->cameraPosition, glb::player->cameraQuat);
client->SendData(&msg, sizeof(msg), k_nSteamNetworkingSend_Unreliable);
}
@ -197,8 +212,11 @@ void TDMP::Client::Disconnect()
serverHandle = k_HSteamNetConnection_Invalid;
}
void TDMP::Client::HandlePlayerData(MsgPlayerData* pData)
void TDMP::Client::HandlePlayerData(MsgPlayerData* pData, HSteamNetConnection* conn)
{
if (!LevelLoaded)
return;
int found = -1;
for (uint32 i = 0; i < MaxPlayers; ++i)
{
@ -207,7 +225,12 @@ void TDMP::Client::HandlePlayerData(MsgPlayerData* pData)
players[i].Position = pData->GetPosition();
players[i].Rotation = pData->GetRotation();
// welocme to the shit code?
players[i].CamPosition = pData->GetCamPosition();
players[i].CamRotation = pData->GetCamRotation();
players[i].hp = pData->GetHealth();
// welocme to the hell
MsgVehicle v = pData->GetVehicle();
if (v.id != 0) // Player is driving a vehicle
{
@ -241,14 +264,29 @@ void TDMP::Client::HandlePlayerData(MsgPlayerData* pData)
if (found != -1)
{
players[found].id = found;
players[found].SteamId = pData->GetSteamID();
players[found].steamIdStr = std::to_string(players[found].SteamId.ConvertToUint64());
players[found].nick = SteamFriends()->GetFriendPersonaName(pData->GetSteamID());
playersBySteamId[players[found].steamIdStr.c_str()] = found;
players[found].Position = pData->GetPosition();
players[found].Rotation = pData->GetRotation();
players[found].CamPosition = pData->GetCamPosition();
players[found].CamRotation = pData->GetCamRotation();
players[found].hp = pData->GetHealth();
players[found].isCtrlPressed = pData->GetCtrl();
players[found].Active = true;
}
players[found].bodyExists = false;
players[found].hideBody = false;
if (conn != nullptr)
players[found].conn = (HSteamNetConnection)conn;
}
}
void TDMP::Client::HandleData(EMessage eMsg, SteamNetworkingMessage_t* message)
@ -283,47 +321,34 @@ void TDMP::Client::HandleData(EMessage eMsg, SteamNetworkingMessage_t* message)
break;
}
case k_EMsgServerUpdateWorld: // This is made for sending more than one body in one packet. Not finished yet
case k_EMsgServerUpdateWorld: // This is made for sending more than one body in one packet.
{
/*MsgUpdateBodies* pMsg = (MsgUpdateBodies*)message->GetData();
MsgUpdateBodies* pMsg = (MsgUpdateBodies*)message->GetData();
if (pMsg == nullptr)
{
Debug::print("corrupted k_EMsgServerUpdateWorld received");
break;
}
pMsg->Deserialize();
// temp. Not sure if I can do it better with current api
// i REALLY hate how it looks like. So I hope there is a better way of doing this
Debug::print(std::string("Received body data ") + std::to_string(pMsg->GetBodies().size()));
for (size_t j = 0; j < pMsg->GetBodies().size(); j++)
for (size_t i = 0; i < pMsg->GetBodiesCount(); i++)
{
MsgBody* netBody = pMsg->GetBodies().data()[j];
for (size_t i = 0; i < TDMP::levelBodies.size(); i++)
if (levelBodiesById.count(pMsg->GetBodies()[i].id))
{
TDBody* body = TDMP::levelBodies[i];
TDBody* body = TDMP::levelBodies[levelBodiesById[pMsg->GetBodies()[i].id]];
if (body == 0)
continue;
if (netBody->id == body->Id)
{
Debug::print(std::string("Applying received data to body ") + std::to_string(body->Id));
body->Position = netBody->pos;
body->Rotation = netBody->rot;
body->Velocity = netBody->vel;
body->RotationVelocity = netBody->rotVel;
body->isAwake = true;
body->countDown = 0x0F;
break;