#include "Scene.h" #ifndef SKIMMED_NET #include "lsluasocket.h" #endif #ifdef ONLINE_MODE #include "account.h" #include "json-c/json.h" #endif #include bool debuggingLua = false; bool updateEvent = false; int UpdateEvents(lua_State *L); extern WORLD *TheScene; #ifdef ONLINE_MODE extern CCamCamAccount Account; #include std::map HttpClientChannels; #endif void FillScriptInfo(lua_State *L, int paramNum, int isError); void SaveDBGInfo(char *text); #ifndef USER_MODE void MyDebug(lua_State *L, int i = 0); static void MyDebug(lua_State *L, int i) { FillScriptInfo(L, 0, 0); return; } #else #define MyDebug(L, i) #define MyDebug(L) #endif typedef struct MouseInfo_ { int x; int y; u32 keys; int value; } MouseInfo; void getStack(lua_State *L, int index) { char * luatype = NULL, *luaval = NULL; luatype = (char *)lua_typename(L, lua_type(L, index)); if (luatype) luaval = (char *)lua_tostring(L, index); return; } void SetStrFieldFloat(lua_State *L, const char *index, float value); void SetStrFieldString(lua_State *L, const char *index, char * value); int PopColor(lua_State *L, u32 *colorPtr, int luaParam = 0); int PopPoint(lua_State *L, POINT *vectorPtr, int luaParam = 0); void PushBool(lua_State *L, BOOL value); void PushInt(lua_State *L, int value); void PushFloat(lua_State *L, float value); void PushString(lua_State *L, char *string); void PushColor(lua_State *L, DWORD color); void PushRectangle(lua_State *L, RECT *rectPtr); void PushTableInt(lua_State *L, int *tabList, int nbElmts); void PushTableFloat(lua_State *L, float *tabList, int nbElmts); void PushPoint(lua_State *L, POINT *pointPtr); void PushPoint(lua_State *L, int x, int y); void PushMouseInfo(lua_State *L, int x, int y, u32 code); void PushMatrix(lua_State *L, MATRIX *matrixPtr); void PushIntEvent(lua_State *L, int value, float time); void PushFloatEvent(lua_State *L, float value, float time); void PushStringEvent(lua_State *L, char * value, float time); Vector *PopVectorPtr(lua_State *L, int luaParam = 0); int PopVector(lua_State *L, Vector *vectorPtr, int luaParam = 0); void PushVector(lua_State *L, Vector *vectorPtr); void PushVectorPtr(lua_State *L, Vector *vectorPtr); int Vector_Clone(lua_State *L); int Vector_Add(lua_State *L); int Vector_Sub(lua_State *L); int Vector_Mul(lua_State *L); int Vector_Pow(lua_State *L); int Vector_SqrNorm(lua_State *L); int Vector_Norm(lua_State *L); int Vector_Normalize(lua_State *L); void Vector_Register(lua_State *L); void VectorPtr_Register(lua_State *L); Quat *PopQuatPtr(lua_State *L, int luaParam = 0); int PopQuat(lua_State *L, Quat *quatPtr, int luaParam = 0); void PushQuat(lua_State *L, Vector *vectorPtr); int Quat_Clone(lua_State *L); int Quat_Add(lua_State *L); int Quat_Sub(lua_State *L); int Quat_Mul(lua_State *L); int Quat_Pow(lua_State *L); int Quat_Normalize(lua_State *L); int Quat_NormalizeW(lua_State *L); void Quat_Register(lua_State *L); int PopMatrix(lua_State *L, MATRIX *matrixPtr, int luaParam = 0); MATRIX *PopMatrixPtr(lua_State *L, int luaParam = 0); int Matrix_Clone(lua_State *L); int Matrix_Mul(lua_State *L); void Matrix_Register(lua_State *L); inline void ComputeReturn(lua_State *L, int returnDone) { if (returnDone <= 1) return; if (returnDone == 2) { lua_newtable(L); lua_pushinteger(L, 1); lua_pushvalue(L, -4); lua_settable(L, -3); lua_pushinteger(L, 2); lua_pushvalue(L, -3); lua_settable(L, -3); lua_remove(L, -2); lua_remove(L, -2); return; } lua_pushinteger(L, returnDone); lua_pushvalue(L, -2); lua_remove(L, -3); lua_settable(L, -3); } /*********************** POP FUNCTIONS ***********************/ int PopFloatInTable(lua_State *L, char *name, float *val) { int returnVal = 0; lua_pushstring(L, name); lua_gettable(L, -2); if (lua_isnumber(L, -1)) { *val = (float)lua_tonumber(L, -1); returnVal = 1; } lua_pop(L,1); return returnVal; } int PopIntInTable(lua_State *L, char *name, int *val) { int returnVal = 0; lua_pushstring(L, name); lua_gettable(L, -2); if (lua_isnumber(L, -1)) { *val = (int)lua_tonumber(L, -1); returnVal = 1; } lua_pop(L,1); return returnVal; } int PopColor(lua_State *L, u32 *colorPtr, int luaParam) { int result = 1; if (luaParam > 0) lua_pushvalue(L, luaParam); *colorPtr = 0; if (lua_type(L, -1) == LUA_TSTRING) { char *color = (char *)lua_tostring(L, -1); int colorLen = strlen(color); int colorIdx = 0; for (; colorIdx < colorLen && (('0' <= color[colorIdx] && color[colorIdx] <= '9') || ('A' <= color[colorIdx] && color[colorIdx] <= 'F') || ('a' <= color[colorIdx] && color[colorIdx] <= 'f')); colorIdx++); if (colorIdx == colorLen) { if (colorLen == 8) *colorPtr = (u32)((((IsHex(*(color + 0))-1)*16 + (IsHex(*(color + 1))-1)) << 24) + ((( IsHex(*(color + 2))-1)*16 + (IsHex(*(color + 3))-1)) << 16) + ((( IsHex(*(color + 4))-1)*16 + (IsHex(*(color + 5))-1)) << 8) + ((( IsHex(*(color + 6))-1)*16 + (IsHex(*(color + 7))-1)) )); else if (colorLen == 6) *colorPtr = (u32)(( 255 << 24) + ((( IsHex(*(color + 0))-1)*16 + (IsHex(*(color + 1))-1)) << 16) + ((( IsHex(*(color + 2))-1)*16 + (IsHex(*(color + 3))-1)) << 8) + ((( IsHex(*(color + 4))-1)*16 + (IsHex(*(color + 5))-1)) )); else result = 0; } else result = 0; } else if (lua_istable(L, -1)) { int R,G,B,A; if (!result || !PopIntInTable(L, "R", &R)) result = 0; if (!result || !PopIntInTable(L, "G", &G)) result = 0; if (!result || !PopIntInTable(L, "B", &B)) result = 0; if (!result || !PopIntInTable(L, "A", &A)) A = 255; if (result) *colorPtr = (A << 24) + (R << 16) + (G << 8) + B; } else if (luaParam > 0) { int RGBA[4]; int curParam = luaParam; RGBA[3] = 255; for (int c=0; result && c<4; c++, curParam++) { if (lua_type(L, curParam) == LUA_TNUMBER) { lua_pop(L,1); lua_pushvalue(L, curParam); RGBA[c] = lua_tonumber(L, -1); if (c) result++; } else if (c < 3) result = 0; } if (result) *colorPtr = (RGBA[3] << 24) + (RGBA[0] << 16) + (RGBA[1] << 8) + RGBA[2]; } if (luaParam > 0) lua_pop(L,1); return result; } int PopPoint(lua_State *L, POINT *pointPtr, int luaParam) { BOOL result = 1; if (luaParam > 0) { lua_pushvalue(L, luaParam); luaL_checktype(L, luaParam, LUA_TTABLE); } else luaL_checktype(L, -1, LUA_TTABLE); int pointParam; if (!result || !PopIntInTable(L, "x", &pointParam)) result = 0; pointPtr->x = pointParam; if (!result || !PopIntInTable(L, "y", &pointParam)) result = 0; pointPtr->y = pointParam; if (luaParam > 0) lua_pop(L,1); return result; } /*** USER MATRIX POP ***/ int PopListInt(lua_State *L, int *resultList, int *nbElmts, int luaParam) { luaL_checktype(L, luaParam, LUA_TTABLE); lua_pushvalue(L, luaParam); *nbElmts = lua_objlen(L, -1); for (int i=0; i<*nbElmts; i++) { lua_pushnumber(L, i+1); lua_gettable(L, -2); if (lua_isnumber(L, -1)) { resultList[i] = (int)lua_tonumber(L, -1); } lua_pop(L,1); } lua_pop(L,1); return *nbElmts; } int PopListFloat(lua_State *L, float *resultList, int *nbElmts, int luaParam) { luaL_checktype(L, luaParam, LUA_TTABLE); lua_pushvalue(L, luaParam); *nbElmts = lua_objlen(L, -1); for (int i=0; i<*nbElmts; i++) { lua_pushnumber(L, i+1); lua_gettable(L, -2); if (lua_isnumber(L, -1)) { resultList[i] = (float)lua_tonumber(L, -1); } lua_pop(L,1); } lua_pop(L,1); return *nbElmts; } int PopListPoint(lua_State *L, POINT *resultList, int *nbElmts, int luaParam) { luaL_checktype(L, luaParam, LUA_TTABLE); lua_pushvalue(L, luaParam); *nbElmts = lua_objlen(L, -1); for (int i=0; i<*nbElmts; i++) { lua_pushnumber(L, i+1); lua_gettable(L, -2); PopPoint(L, &resultList[i]); lua_pop(L,1); } lua_pop(L,1); return *nbElmts; } int PopListVector(lua_State *L, Vector *resultList, int *nbElmts, int luaParam) { luaL_checktype(L, luaParam, LUA_TTABLE); lua_pushvalue(L, luaParam); *nbElmts = lua_objlen(L, -1); for (int i=0; i<*nbElmts; i++) { lua_pushnumber(L, i+1); lua_gettable(L, -2); PopVector(L, &resultList[i],-1); lua_pop(L,1); } lua_pop(L,1); return *nbElmts; } int PopListColor(lua_State *L, u32 *resultList, int *nbElmts, int luaParam) { luaL_checktype(L, luaParam, LUA_TTABLE); lua_pushvalue(L, luaParam); *nbElmts = lua_objlen(L, -1); for (int i=0; i<*nbElmts; i++) { lua_pushnumber(L, i+1); lua_gettable(L, -2); PopColor(L, &resultList[i],-1); lua_pop(L,1); } lua_pop(L,1); return *nbElmts; } /*********************** POP FUNCTIONS ***********************/ /*********************** PUSH FUNCTIONS ***********************/ void SetStrFieldFloat(lua_State *L, const char *index, float value) { lua_pushstring(L, index); lua_pushnumber(L, (double)value); //lua_settable(L, -3); lua_rawset(L, -3); } void SetStrFieldInteger(lua_State *L, const char *index, int value) { lua_pushstring(L, index); lua_pushinteger(L, value); //lua_settable(L, -3); lua_rawset(L, -3); } void SetStrFieldString(lua_State *L, const char *index, char * value) { lua_pushstring(L, index); lua_pushstring(L, value); //lua_settable(L, -3); lua_rawset(L, -3); } void SetStrFieldFunction(lua_State *L, const char *index, lua_CFunction function) { lua_pushstring(L, index); lua_pushcfunction(L, function); //lua_settable(L, -3); lua_rawset(L, -3); } void SetStrFieldBoolean(lua_State *L, const char *index, bool value) { lua_pushstring(L, index); lua_pushboolean(L, value); //lua_settable(L, -3); lua_rawset(L, -3); } void PushBool(lua_State *L, BOOL value) { lua_pushboolean(L, value); } void PushInt(lua_State *L, int value) { lua_pushinteger(L, (double)value); } void PushFloat(lua_State *L, float value) { lua_pushnumber(L, (double)value); } void PushString(lua_State *L, char *string) { lua_pushstring(L, string); } void PushColor(lua_State *L, DWORD color) { //lua_newtable(L); lua_createtable(L,0,4); SetStrFieldFloat(L, "A", (float)((color & 0xFF000000) >> 24)); SetStrFieldFloat(L, "R", (float)((color & 0x00FF0000) >> 16)); SetStrFieldFloat(L, "G", (float)((color & 0x0000FF00) >> 8 )); SetStrFieldFloat(L, "B", (float)((color & 0x000000FF) )); } void PushRectangle(lua_State *L, RECT *rectPtr) { //lua_newtable(L); lua_createtable(L,0,4); SetStrFieldFloat(L, "x", (float)rectPtr->left); SetStrFieldFloat(L, "y", (float)rectPtr->top); SetStrFieldFloat(L, "sx", (float)(rectPtr->right - rectPtr->left)); SetStrFieldFloat(L, "sy", (float)(rectPtr->bottom - rectPtr->top)); } void PushTableInt(lua_State *L, int *tabList, int nbElmts) { //lua_newtable(L); lua_createtable(L, nbElmts, 0); for (int i=0; ix, pointPtr->y); } void PushPoint(lua_State *L, float x, float y) { //lua_newtable(L); lua_createtable(L, 0, 2); SetStrFieldFloat(L, "x", x); SetStrFieldFloat(L, "y", y); } void PushPoint(lua_State *L, int x, int y) { PushPoint(L, (float)x, (float)y); } void PushMouseInfo(lua_State *L, MouseInfo *mouseInfo) { //lua_newtable(L); lua_createtable(L, 0, 4); SetStrFieldFloat(L, "x", mouseInfo->x); SetStrFieldFloat(L, "y", mouseInfo->y); lua_pushstring(L, "keys"); lua_newtable(L); if (mouseInfo->keys & MK_CONTROL) SetStrFieldFloat(L, "control", 1); if (mouseInfo->keys & MK_LBUTTON) SetStrFieldFloat(L, "lbutton", 1); if (mouseInfo->keys & MK_MBUTTON) SetStrFieldFloat(L, "mbutton", 1); if (mouseInfo->keys & MK_RBUTTON) SetStrFieldFloat(L, "rbutton", 1); if (mouseInfo->keys & MK_SHIFT) SetStrFieldFloat(L, "shift", 1); lua_settable(L, -3); SetStrFieldFloat(L, "value", mouseInfo->value); } void PushIntEvent(lua_State *L, int value, float time) { //lua_newtable(L); lua_createtable(L, 0, 2); SetStrFieldFloat(L, "data", value); SetStrFieldFloat(L, "time", time); } void PushFloatEvent(lua_State *L, float value, float time) { //lua_newtable(L); lua_createtable(L, 0, 2); SetStrFieldFloat(L, "data", value); SetStrFieldFloat(L, "time", time); } void PushStringEvent(lua_State *L, char * value, float time) { //lua_newtable(L); lua_createtable(L, 0, 2); SetStrFieldString(L, "data", value); SetStrFieldFloat(L, "time", time); } /*********************** PUSH FUNCTIONS ***********************/ /*********************** CLASS DEFINITIONS ***********************/ /*********************** VECTOR ***********************/ Vector *PopVectorPtr(lua_State *L, int luaParam) { int top = lua_gettop(L); void *p = lua_touserdata(L, luaParam); Vector *vPtr = NULL; if (p == NULL) return NULL; if (!lua_getmetatable(L, luaParam)) return NULL; lua_getfield(L, LUA_REGISTRYINDEX, "VECTOR"); if (lua_rawequal(L, -1, -2)) vPtr = (Vector *)p; else { lua_pop(L, 1); lua_getfield(L, LUA_REGISTRYINDEX, "VECTOR_PTR"); if (lua_rawequal(L, -1, -2)) vPtr = *((Vector **)p); } lua_pop(L, 2); return vPtr; } int PopVector(lua_State *L, Vector *vectorPtr, int luaParam) { Vector *vPtr = PopVectorPtr(L, luaParam); if (vPtr == NULL) return 0; memcpy(vectorPtr, vPtr, sizeof(Vector)); return 1; } void PushVector(lua_State *L, Vector *vectorPtr) { void *VectorUser = lua_newuserdata(L, sizeof(Vector)); if (!VectorUser) return; memcpy(VectorUser, vectorPtr, sizeof(Vector)); luaL_getmetatable(L, "VECTOR"); lua_setmetatable (L, -2); } void PushVector(lua_State *L, char *vectorString) { Vector *vectorPtr = (Vector*)ZeroAlloc(sizeof(Vector)); if(sscanf(vectorString,"{x=%f,y=%f,z=%f}", &vectorPtr->x, &vectorPtr->y, &vectorPtr->z)==3) PushVector(L,vectorPtr); } void PushVectorPtr(lua_State *L, Vector *vectorPtr) { void *VectorUserPtr = lua_newuserdata(L, sizeof(Vector *)); if (!VectorUserPtr) return; *((Vector **)VectorUserPtr) = vectorPtr; luaL_getmetatable(L, "VECTOR_PTR"); lua_setmetatable (L, -2); } int Vector_Index(lua_State *L) { Vector *vPtr; if (!(vPtr = PopVectorPtr(L, 1))) return 0; const char *tableStr = luaL_checkstring(L, 2); if (tableStr[1] == 0) { switch (*tableStr) { case 'x': lua_pushnumber(L, vPtr->x); return 1; case 'y': lua_pushnumber(L, vPtr->y); return 1; case 'z': lua_pushnumber(L, vPtr->z); return 1; } return 0; } if (!strcmp(tableStr, "Norm")) { lua_pushcfunction(L, Vector_Norm); return 1; } if (!strcmp(tableStr, "SqrNorm")) { lua_pushcfunction(L, Vector_SqrNorm); return 1; } if (!strcmp(tableStr, "Normalize")) { lua_pushcfunction(L, Vector_Normalize); return 1; } if (!strcmp(tableStr, "Clone")) { lua_pushcfunction(L, Vector_Clone); return 1; } return 0; } int Vector_NewIndex(lua_State *L) { Vector *vPtr; if (!(vPtr = PopVectorPtr(L, 1))) return 0; const char *tableStr = luaL_checkstring(L, 2); float number = luaL_checknumber(L, 3); if (tableStr[1] != 0) return 0; switch (*tableStr) { case 'x': vPtr->x = number; return 1; case 'y': vPtr->y = number; return 1; case 'z': vPtr->z = number; return 1; } return 0; } int Vector_Clone(lua_State *L) { Vector *vPtr; if (!(vPtr = PopVectorPtr(L, 1))) return 0; PushVector(L, vPtr); return 1; } int Vector_ToString(lua_State *L) { Vector *vPtr; char vStr[256]; if (!(vPtr = PopVectorPtr(L, 1))) return 0; sprintf(vStr, "{x=%.2f,y=%.2f,z=%.2f}", vPtr->x, vPtr->y, vPtr->z); lua_pushstring(L, vStr); return 1; } int Vector_Add(lua_State *L) { Vector v1, *v2Ptr = NULL; if (!PopVector(L, &v1, 1)) return 0; if (lua_isnumber(L, 2)) { v1 += lua_tonumber(L, -1); PushVector(L, &v1); return 1; } if ((v2Ptr = PopVectorPtr(L, 2)) != NULL) { v1 = v1+*v2Ptr; PushVector(L, &v1); return 1; } return 0; } int Vector_Sub(lua_State *L) { Vector v1, *v2Ptr = NULL; if (!PopVector(L, &v1, 1)) return 0; if (lua_isnumber(L, 2)) { v1 += -lua_tonumber(L, -1); PushVector(L, &v1); return 1; } else if ((v2Ptr = PopVectorPtr(L, 2)) != NULL) { v1 = v1-*v2Ptr; PushVector(L, &v1); return 1; } return 0; } int Vector_Mul(lua_State *L) { Vector v1, *v2Ptr = NULL; if (!PopVector(L, &v1, 1)) return 0; if (lua_isnumber(L, 2)) { v1 = v1*lua_tonumber(L, -1); PushVector(L, &v1); return 1; } else if ((v2Ptr = PopVectorPtr(L, 2)) != NULL) { lua_pushnumber(L, v1**v2Ptr); return 1; } return 0; } int Vector_Pow(lua_State *L) { Vector v1, *v2Ptr = NULL; if (!PopVector(L, &v1, 1) || !(v2Ptr = PopVectorPtr(L, 2))) return 0; v1 = v1^(*v2Ptr); PushVector(L, &v1); return 1; } int Vector_SqrNorm(lua_State *L) { Vector *v1Ptr; if (!(v1Ptr = PopVectorPtr(L, 1))) return 0; lua_pushnumber(L, v1Ptr->SqrNorm()); return 1; } int Vector_Norm(lua_State *L) { Vector *v1Ptr; if (!(v1Ptr = PopVectorPtr(L, 1))) return 0; lua_pushnumber(L, v1Ptr->Norm()); return 1; } int Vector_Normalize(lua_State *L) { Vector *v1Ptr = NULL; if (!(v1Ptr = PopVectorPtr(L, 1))) return 0; if (lua_gettop(L) > 1 && lua_toboolean(L, 2)) { Vector v2 = *v1Ptr; v2.Normalize(); PushVector(L, &v2); } else { v1Ptr->Normalize(); PushVectorPtr(L, v1Ptr); } return 1; } static const luaL_reg Vector_meta[] = { {"__index", Vector_Index}, {"__newindex", Vector_NewIndex}, {"__tostring", Vector_ToString}, {"__add", Vector_Add}, {"__sub", Vector_Sub}, {"__mul", Vector_Mul}, {"__pow", Vector_Pow}, {0, 0} }; void Vector_Register(lua_State *L) { luaL_newmetatable(L, "VECTOR"); /* create metatable for Foo, and add it to the Lua registry */ luaL_openlib(L, 0, Vector_meta, 0); /* fill metatable */ lua_pushliteral(L, "__metatable"); lua_pushvalue(L, -3); /* dup methods table*/ lua_rawset(L, -3); /* hide metatable: metatable.__metatable = methods */ lua_pop(L, 1); /* drop metatable */ } void VectorPtr_Register(lua_State *L) { luaL_newmetatable(L, "VECTOR_PTR"); /* create metatable for Foo, and add it to the Lua registry */ luaL_openlib(L, 0, Vector_meta, 0); /* fill metatable */ lua_pushliteral(L, "__metatable"); lua_pushvalue(L, -3); /* dup methods table*/ lua_rawset(L, -3); /* hide metatable: metatable.__metatable = methods */ lua_pop(L, 1); /* drop metatable */ } /*********************** QUAT ***********************/ Quat *PopQuatPtr(lua_State *L, int luaParam) { int top = lua_gettop(L); Quat *qPtr = NULL; if (luaParam > 0) { lua_pushvalue(L, luaParam); luaL_checktype(L, luaParam, LUA_TUSERDATA); qPtr = (Quat *)luaL_checkudata(L, luaParam, "QUAT"); } else { luaL_checktype(L, -1, LUA_TUSERDATA); qPtr = (Quat *)luaL_checkudata(L, luaParam, "QUAT"); } if (qPtr == NULL) luaL_typerror(L, luaParam, "QUAT"); return qPtr; } int PopQuat(lua_State *L, Quat *quatPtr, int luaParam) { Quat *qPtr = PopQuatPtr(L, luaParam); if (qPtr == NULL) return 0; memcpy(quatPtr, qPtr, sizeof(Quat)); return 1; } void PushQuat(lua_State *L, Quat *quatPtr) { void *QuatUser = lua_newuserdata(L, sizeof(Quat)); if (!QuatUser) return; memcpy(QuatUser, quatPtr, sizeof(Quat)); luaL_getmetatable(L, "QUAT"); lua_setmetatable (L, -2); } void PushQuat(lua_State *L, char *qStr) { Quat *qPtr = (Quat*)ZeroAlloc(sizeof(Quat)); if(4==sscanf(qStr, "{x=%f,y=%f,z=%f,w=%f}", &qPtr->x, &qPtr->y, &qPtr->z, &qPtr->w)) { PushQuat(L, qPtr); } } int Quat_Clone(lua_State *L) { Quat *qPtr; if (!(qPtr = PopQuatPtr(L, 1))) return 0; PushQuat(L, qPtr); return 1; } int Quat_Index(lua_State *L) { Quat *qPtr; if (!(qPtr = PopQuatPtr(L, 1))) return 0; const char *tableStr = luaL_checkstring(L, 2); if (tableStr[1] == 0) { switch (*tableStr) { case 'x': lua_pushnumber(L, qPtr->x); return 1; case 'y': lua_pushnumber(L, qPtr->y); return 1; case 'z': lua_pushnumber(L, qPtr->z); return 1; case 'w': lua_pushnumber(L, qPtr->w); return 1; } return 0; } if (!strcmp(tableStr, "Normalize")) { lua_pushcfunction(L, Quat_Normalize); return 1; } if (!strcmp(tableStr, "NormalizeW")) { lua_pushcfunction(L, Quat_NormalizeW); return 1; } if (!strcmp(tableStr, "Clone")) { lua_pushcfunction(L, Quat_Clone); return 1; } return 0; } int Quat_NewIndex(lua_State *L) { Quat *qPtr; if (!(qPtr = PopQuatPtr(L, 1))) return 0; const char *tableStr = luaL_checkstring(L, 2); float number = luaL_checknumber(L, 3); if (tableStr[1] != 0) return 0; switch (*tableStr) { case 'x': qPtr->x = number; return 1; case 'y': qPtr->y = number; return 1; case 'z': qPtr->z = number; return 1; case 'w': qPtr->w = number; return 1; } return 0; } int Quat_ToString(lua_State *L) { Quat *qPtr; char qStr[256]; if (!(qPtr = PopQuatPtr(L, 1))) return 0; sprintf(qStr, "{x=%.2f,y=%.2f,z=%.2f,w=%.2f}", qPtr->x, qPtr->y, qPtr->z, qPtr->w); lua_pushstring(L, qStr); return 1; } int Quat_Add(lua_State *L) { Quat q1, *q2Ptr = NULL; if (!PopQuat(L, &q1, 1) || !(q2Ptr = PopQuatPtr(L, 2))) return 0; q1 = q1+*q2Ptr; PushQuat(L, &q1); return 1; } int Quat_Mul(lua_State *L) { Quat q1, *q2Ptr = NULL; if (!PopQuat(L, &q1, 1)) return 0; if (lua_isnumber(L, 2)) { q1 = q1*lua_tonumber(L, 2); PushQuat(L, &q1); return 1; } else if ((q2Ptr = PopQuatPtr(L, 2)) != NULL) { q1 *= *q2Ptr; PushQuat(L, &q1); return 1; } return 0; } int Quat_Normalize(lua_State *L) { Quat *q1Ptr = NULL; if (!(q1Ptr = PopQuatPtr(L, 1))) return 0; q1Ptr->Normalize(); PushQuat(L, q1Ptr); return 1; } int Quat_NormalizeW(lua_State *L) { Quat *q1Ptr = NULL; if (!(q1Ptr = PopQuatPtr(L, 1))) return 0; q1Ptr->NormalizeW(); PushQuat(L, q1Ptr); return 1; } static const luaL_reg Quat_meta[] = { {"__index", Quat_Index}, {"__newindex", Quat_NewIndex}, {"__tostring", Quat_ToString}, {"__add", Quat_Add}, {"__mul", Quat_Mul}, {0, 0} }; void Quat_Register(lua_State *L) { luaL_newmetatable(L, "QUAT"); /* create metatable for Foo, and add it to the Lua registry */ luaL_openlib(L, 0, Quat_meta, 0); /* fill metatable */ lua_pushliteral(L, "__metatable"); lua_pushvalue(L, -3); /* dup methods table*/ lua_rawset(L, -3); /* hide metatable: metatable.__metatable = methods */ lua_pop(L, 1); /* drop metatable */ } /*********************** MATRIX **************************/ MATRIX *PopMatrixPtr(lua_State *L, int luaParam) { int top = lua_gettop(L); MATRIX *mPtr = NULL; if (luaParam > 0) { lua_pushvalue(L, luaParam); luaL_checktype(L, luaParam, LUA_TUSERDATA); mPtr = (MATRIX *)luaL_checkudata(L, luaParam, "MATRIX"); } else { luaL_checktype(L, -1, LUA_TUSERDATA); mPtr = (MATRIX *)luaL_checkudata(L, luaParam, "MATRIX"); } if (mPtr == NULL) luaL_typerror(L, luaParam, "MATRIX"); return mPtr; } int PopMatrix(lua_State *L, MATRIX *matrixPtr, int luaParam) { MATRIX *mPtr = PopMatrixPtr(L, luaParam); if (mPtr == NULL) return 0; memcpy(matrixPtr, mPtr, sizeof(MATRIX)); return 1; } void PushMatrix(lua_State *L, MATRIX *matrixPtr) { void *MatrixUser = lua_newuserdata(L, sizeof(MATRIX)); if (!MatrixUser) return; memcpy(MatrixUser, matrixPtr, sizeof(MATRIX)); luaL_getmetatable(L, "MATRIX"); //lua_getglobal(L, "MATRIX"); lua_setmetatable (L, -2); } void PushMatrix(lua_State *L, char *matrixString) { MATRIX *mPtr = (MATRIX*)ZeroAlloc(sizeof(MATRIX)); if(12==sscanf(matrixString, "{I={x=%f,y=%f,z=%f},J={x=%f,y=%f,z=%f},K={x=%f,y=%f,z=%f},T={x=%f,y=%f,z=%f}}", &mPtr->I.x, &mPtr->I.y, &mPtr->I.z, &mPtr->J.x, &mPtr->J.y, &mPtr->J.z, &mPtr->K.x, &mPtr->K.y, &mPtr->K.z, &mPtr->T.x, &mPtr->T.y, &mPtr->T.z)) { PushMatrix(L, mPtr); } } int Matrix_Clone(lua_State *L) { MATRIX *mPtr; if (!(mPtr = PopMatrixPtr(L, 1))) return 0; PushMatrix(L, mPtr); return 1; } #define MATRIX_FLOAT_SETGET(Vct,Wct) \ int Matrix_Set##Vct##Wct(lua_State *L) \ { \ MATRIX *mPtr = NULL; \ float number= 0; \ if (!(mPtr = PopMatrixPtr(L, 1))) return 0; \ number = luaL_checknumber(L, 2); \ mPtr->Vct.Wct = number; return 1; \ } \ int Matrix_Get##Vct##Wct(lua_State *L) \ { \ MATRIX *mPtr = NULL; \ if (!(mPtr = PopMatrixPtr(L, 1))) return 0; \ lua_pushnumber(L, mPtr->Vct.Wct); return 1; \ } #define PUSH_SETGET(Vct, Wct) \ if (tableStr[0] == 'S' && tableStr[3] == *#Vct && tableStr[4] == *#Wct) \ { lua_pushcfunction(L, Matrix_Set##Vct##Wct); return 1; } \ if (tableStr[0] == 'G' && tableStr[3] == *#Vct && tableStr[4] == *#Wct) \ { lua_pushcfunction(L, Matrix_Get##Vct##Wct); return 1; } MATRIX_FLOAT_SETGET(I,x) MATRIX_FLOAT_SETGET(I,y) MATRIX_FLOAT_SETGET(I,z) MATRIX_FLOAT_SETGET(J,x) MATRIX_FLOAT_SETGET(J,y) MATRIX_FLOAT_SETGET(J,z) MATRIX_FLOAT_SETGET(K,x) MATRIX_FLOAT_SETGET(K,y) MATRIX_FLOAT_SETGET(K,z) MATRIX_FLOAT_SETGET(T,x) MATRIX_FLOAT_SETGET(T,y) MATRIX_FLOAT_SETGET(T,z) int Matrix_Index(lua_State *L) { MATRIX *mPtr; if (!(mPtr = PopMatrixPtr(L, 1))) return 0; const char *tableStr = luaL_checkstring(L, 2); if (tableStr[1] == 0) { switch (*tableStr) { case 'I': PushVectorPtr(L, &mPtr->I); return 1; case 'J': PushVectorPtr(L, &mPtr->J); return 1; case 'K': PushVectorPtr(L, &mPtr->K); return 1; case 'T': PushVectorPtr(L, &mPtr->T); return 1; } return 0; } if (!strcmp(tableStr, "Clone")) { lua_pushcfunction(L, Matrix_Clone); return 1; } if (strlen(tableStr) == 5) { PUSH_SETGET(I,x) PUSH_SETGET(I,y) PUSH_SETGET(I,z) PUSH_SETGET(J,x) PUSH_SETGET(J,y) PUSH_SETGET(J,z) PUSH_SETGET(K,x) PUSH_SETGET(K,y) PUSH_SETGET(K,z) PUSH_SETGET(T,x) PUSH_SETGET(T,y) PUSH_SETGET(T,z) } return 0; } int Matrix_NewIndex(lua_State *L) { MATRIX *mPtr = PopMatrixPtr(L, 1); if (!mPtr) return 0; const char *tableStr = luaL_checkstring(L, 2); if (tableStr[1] != 0) return 0; Vector *vPtr = PopVectorPtr(L, 3); if (!vPtr) return 0; switch (*tableStr) { case 'I': mPtr->I = *vPtr; return 1; case 'J': mPtr->J = *vPtr; return 1; case 'K': mPtr->K = *vPtr; return 1; case 'T': mPtr->T = *vPtr; return 1; } return 0; } int Matrix_ToString(lua_State *L) { MATRIX *mPtr; char mStr[512]; if (!(mPtr = PopMatrixPtr(L, 1))) return 0; sprintf(mStr, "{I={x=%.2f,y=%.2f,z=%.2f},J={x=%.2f,y=%.2f,z=%.2f},K={x=%.2f,y=%.2f,z=%.2f},T={x=%.2f,y=%.2f,z=%.2f}}", mPtr->I.x, mPtr->I.y, mPtr->I.z, mPtr->J.x, mPtr->J.y, mPtr->J.z, mPtr->K.x, mPtr->K.y, mPtr->K.z, mPtr->T.x, mPtr->T.y, mPtr->T.z); lua_pushstring(L, mStr); return 1; } int Matrix_Mul(lua_State *L) { MATRIX m1, *m2Ptr; Vector v1; if (!PopMatrix(L, &m1, 1)) return 0; if (PopVector(L, &v1, 2)) { v1 = m1*v1; PushVector(L, &v1); return 1; } if ((m2Ptr = PopMatrixPtr(L, 2)) != NULL) { m1 *= *m2Ptr; PushMatrix(L, &m1); return 1; } return 0; } #define MATRIX_VECTOR_SETGET(Vct) \ int Matrix_Set##Vct(lua_State *L) \ { \ MATRIX * mPtr = NULL; \ Vector * vPtr = NULL; \ if (!(mPtr = PopMatrixPtr(L, 1)) || !(vPtr = PopVectorPtr(L, 2))) return 0; \ mPtr->Vct = *vPtr; return 1; \ } \ int Matrix_Get##Vct(lua_State *L) \ { \ MATRIX * mPtr = NULL; \ if (!(mPtr = PopMatrixPtr(L, 1))) return 0; \ PushVector(L, &mPtr->Vct); return 1; \ } \ int Matrix_GetPtr##Vct(lua_State *L) \ { \ MATRIX * mPtr = NULL; \ if (!(mPtr = PopMatrixPtr(L, 1))) return 0; \ PushVectorPtr(L, &mPtr->Vct); return 1; \ } #define MATRIX_VECTOR_DECLARE(Vct) \ {"Set"#Vct, Matrix_Set##Vct}, \ {"Get"#Vct, Matrix_Get##Vct}, \ {"GetPtr"#Vct, Matrix_GetPtr##Vct}, #define MATRIX_FLOAT_DECLARE(Vct,Wct) \ {"Set"#Vct#Wct, Matrix_Set##Vct##Wct}, \ {"Get"#Vct#Wct, Matrix_Get##Vct##Wct}, static const luaL_reg Matrix_meta[] = { {"__mul", Matrix_Mul}, {"__index", Matrix_Index}, {"__newindex", Matrix_NewIndex}, {"__tostring", Matrix_ToString}, {0, 0} }; void Matrix_Register(lua_State *L) { luaL_newmetatable(L, "MATRIX"); luaL_openlib(L, 0, Matrix_meta, 0); /* fill metatable */ lua_pushliteral(L, "__metatable"); lua_pushvalue(L, -3); /* dup methods table*/ lua_rawset(L, -3); /* hide metatable: metatable.__metatable = methods */ lua_pop(L, 1); /* drop metatable */ } /*********************** CLASS DEFINITIONS ***********************/ /*********************** CONVERSTION FUNCTIONS ***********************/ BOOL IsTableBase(lua_State *L) { BOOL isBase = true; int index = 1; lua_pushnil(L); /* first key */ while (isBase && lua_next(L, -2) != 0) { isBase = lua_isnumber(L, -2) && lua_tonumber(L, -2) == index; index++; lua_pop(L, 1); } if (!isBase) lua_pop(L, 1); return isBase; } static int curLevel; static int maxLevel = 512; static void **levelsPtr = NULL; //#define EVENT_CONFLICT #ifdef EVENT_CONFLICT static char **levelsCharsPtr = NULL; #endif char *TableToStringRec(lua_State *L, char *bufferPtr, bool isTableBase, int precision, int *remaningLen) { BOOL isFirst = true; BOOL isNumber; char *tmpBufferPtr; static char tmpBuffer[2048]; static void *tmpLevels[512]; if (curLevel >= 512) return bufferPtr; tmpLevels[curLevel] = (void *)lua_topointer(L, -1); for (int lvlIdx=0; lvlIdx strlen("rec_val")) { (*remaningLen) -= strlen("rec_val"); strcpy(bufferPtr, "rec_val"); bufferPtr += strlen(bufferPtr); } else *remaningLen = 0; lua_pop(L, 1); return bufferPtr; } else { curLevel++; } lua_pushnil(L); /* first key */ while (lua_next(L, -2) != 0 && *remaningLen > 0 ) { /* uses 'key' (at index -2) and 'value' (at index -1) */ if (lua_isfunction(L, -1)) { lua_pop(L, 1); continue; } if (isFirst) isFirst = false; else { if (*remaningLen > strlen(",")) { strcpy(bufferPtr, ","); (*remaningLen)-= strlen(","); bufferPtr += strlen(bufferPtr); } else *remaningLen = 0; } if (!isTableBase) { lua_pushvalue(L, -2); if ((*remaningLen) > strlen(lua_tostring(L, -1))) { (*remaningLen) -= strlen(lua_tostring(L, -1)) + 1; sprintf(bufferPtr, "%s=", lua_tostring(L, -1)); bufferPtr += strlen(bufferPtr); } else *remaningLen = 0; lua_pop(L, 1); } if (lua_istable(L, -1)) { if (*remaningLen > strlen("{")) { strcpy(bufferPtr, "{"); *remaningLen -= strlen(bufferPtr); bufferPtr += strlen(bufferPtr); } else *remaningLen = 0; bufferPtr = TableToStringRec(L, bufferPtr, IsTableBase(L), precision, remaningLen); if (*remaningLen > strlen("}")) { strcpy(bufferPtr, "}"); *remaningLen -= strlen(bufferPtr); bufferPtr += strlen(bufferPtr); } else *remaningLen = 0; } else { float number = 0; tmpBufferPtr = tmpBuffer; if (precision >= 0 && lua_isnumber(L, -1)) { number = lua_tonumber(L, -1); if (number == (float)((int)number)) number = 0; } if (number) { char precisionStr[64]; sprintf(precisionStr, "%%.%if", precision); sprintf(tmpBuffer, precisionStr, number); } else { if (luaL_callmeta(L, -1, "__tostring")) { strcpy(tmpBuffer, lua_tostring(L, -1)); lua_pop(L, 1); } else { switch (lua_type(L, -1)) { case LUA_TNUMBER: strcpy(tmpBuffer, lua_tostring(L, -1)); break; case LUA_TSTRING: strcpy(tmpBuffer, lua_tostring(L, -1)); break; case LUA_TBOOLEAN: strcpy(tmpBuffer, (lua_toboolean(L, -1) ? "true" : "false")); break; case LUA_TNIL: strcpy(tmpBuffer, "nil"); break; default: sprintf(tmpBuffer, "%s: %p", luaL_typename(L, -1), lua_topointer(L, -1)); break; } } } if (*remaningLen > strlen(tmpBufferPtr)) { strcpy(bufferPtr, tmpBufferPtr); *remaningLen -= strlen(tmpBufferPtr); bufferPtr += strlen(bufferPtr); } else *remaningLen = 0; lua_pop(L, 1); } } lua_pop(L, 1); return bufferPtr; } int TableToString(lua_State *L, int tableIndex) { static char buffer[4096]; int remaningLen = 1920; char *bufferPtr = buffer; int precision = -1; if (!lua_istable(L, tableIndex)) { if (luaL_callmeta(L, tableIndex, "__tostring")) return 1; switch (lua_type(L, tableIndex)) { case LUA_TNUMBER: lua_pushstring(L, lua_tostring(L, tableIndex)); break; case LUA_TSTRING: lua_pushvalue(L, tableIndex); break; case LUA_TBOOLEAN: lua_pushstring(L, (lua_toboolean(L, tableIndex) ? "true" : "false")); break; case LUA_TNIL: lua_pushliteral(L, "nil"); break; default: lua_pushfstring(L, "%s: %p", luaL_typename(L, tableIndex), lua_topointer(L, 1)); break; } return 1; } if (tableIndex == -2 || lua_gettop(L) == 2) { precision = luaL_checknumber(L, -1); lua_pop(L, 1); } strcpy(bufferPtr, "{"); bufferPtr += strlen(bufferPtr); curLevel = 0; bufferPtr = TableToStringRec(L, bufferPtr, IsTableBase(L), precision, &remaningLen); if (remaningLen <= 0) { strcpy(bufferPtr, "..."); precision = strlen(buffer); } else strcpy(bufferPtr, "}"); lua_pushstring(L, buffer); return 1; } int TableToString(lua_State *L) { return TableToString(L, 1); } /**********************************************************************************************/ /***** FILE SEARCH ****************************************************************************/ /**********************************************************************************************/ int PushSystemTime(lua_State *L, SYSTEMTIME sysTime); int PushFileTime(lua_State *L, FILETIME time) { SYSTEMTIME sysTime; FileTimeToSystemTime(&time, &sysTime); return PushSystemTime(L, sysTime); } int PushSystemTime(lua_State *L, SYSTEMTIME sysTime) { lua_newtable(L); lua_pushstring(L, "year"); lua_pushnumber(L, sysTime.wYear); lua_settable(L, -3); lua_pushstring(L, "month"); lua_pushnumber(L, sysTime.wMonth); lua_settable(L, -3); lua_pushstring(L, "day"); lua_pushnumber(L, sysTime.wDay); lua_settable(L, -3); lua_pushstring(L, "hour"); lua_pushnumber(L, sysTime.wHour); lua_settable(L, -3); lua_pushstring(L, "minute"); lua_pushnumber(L, sysTime.wMinute); lua_settable(L, -3); lua_pushstring(L, "second"); lua_pushnumber(L, sysTime.wSecond); lua_settable(L, -3); lua_pushstring(L, "milliseconds"); lua_pushnumber(L, sysTime.wMilliseconds); lua_settable(L, -3); return 1; } bool CheckFocus() { #ifdef ONLINE_MODE // return ((GetFocus() == TheScene->OwnerHwnd) || Account.logInPageHasFocus() || Account.shopHasFocus() || Account.youupPugPageHasFocus() /*|| Account.uploadBrowserHasFocus()*/); bool focusTestOld = (GetFocus() == TheScene->OwnerHwnd) || Account.logInPageHasFocus() || Account.shopHasFocus() || Account.youupPugPageHasFocus() /*|| Account.uploadBrowserHasFocus()*/; bool focusTestNew = GetForegroundWindow() == TheScene->OwnerHwnd; if (focusTestNew && !focusTestOld) SetFocus(TheScene->OwnerHwnd); return focusTestNew; #else return (GetFocus() == TheScene->OwnerHwnd); #endif } int EnumFilesRec(lua_State *L, char *dirname, char *ext, BOOL recursiv, BOOL fullInfo) { char dirSearch[1024]; char fileExt[64]; HANDLE fileFind; WIN32_FIND_DATA fileData; sprintf(dirSearch, "%s\\*.*", dirname); fileFind = FindFirstFile(dirSearch, &fileData); if (fileFind == INVALID_HANDLE_VALUE) return 0; int index = 1; do { if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (recursiv && strcmp(".", fileData.cFileName) && strcmp("..", fileData.cFileName)) { char dirNameIn[1024]; sprintf(dirNameIn, "%s\\%s", dirname, fileData.cFileName); lua_pushstring(L, fileData.cFileName); lua_newtable(L); EnumFilesRec(L, dirNameIn, ext, recursiv, fullInfo); lua_settable(L, -3); } } else { if (ext) { strcpy(fileExt, fileData.cFileName + strlen(fileData.cFileName) - strlen(ext)); strlwr(fileExt); if (strcmp(fileExt, ext)) continue; } lua_pushinteger(L, index++); if (fullInfo) { lua_newtable(L); lua_pushfstring(L, "name"); lua_pushfstring(L, fileData.cFileName); lua_settable(L, -3); lua_pushfstring(L, "creationTime"); PushFileTime(L, fileData.ftCreationTime); lua_settable(L, -3); lua_pushfstring(L, "writeTime"); PushFileTime(L, fileData.ftLastWriteTime); lua_settable(L, -3); lua_pushfstring(L, "size"); lua_pushnumber(L, fileData.nFileSizeLow); lua_settable(L, -3); } else { lua_pushfstring(L, fileData.cFileName); } lua_settable(L, -3); } } while (FindNextFile(fileFind, &fileData)); return 1; } int EnumFiles(lua_State *L) { if (lua_gettop(L) < 1 || !lua_tostring(L, 1)) return 0; char *dirname = (char *)lua_tostring(L, 1); char extData[128]; char *ext = NULL; int recursiv = 0; int fullInfo = 0; if (lua_gettop(L) > 1) recursiv = (int)lua_tonumber(L, 2); if (lua_gettop(L) > 2 && lua_tostring(L, 3) && *lua_tostring(L, 3)) { strcpy(extData, lua_tostring(L, 3)); strlwr(extData); ext = extData; } if (lua_gettop(L) > 3) fullInfo = lua_tonumber(L, 4); lua_newtable(L); EnumFilesRec(L, dirname, ext, recursiv, fullInfo); return 1; } /**********************************************************************************************/ /***** INI VALUE ******************************************************************************/ /**********************************************************************************************/ extern char CamcamCCM[]; int IniLoad(lua_State *L) { int nbArgs = lua_gettop(L); int saveRet; switch (nbArgs) { case 0 : saveRet = TheScene->LoadIniFile(CamcamCCM); lua_pushboolean(L, saveRet >= 0); return 1; break; default : if(lua_isstring(L,1)) { char destFile[2048] = ""; strcpy(destFile, lua_tostring(L, 1)); destFile[strlen(lua_tostring(L, 1))] = 0; if(strlen(destFile)<4 || strcmp(".ccm", strlwr(destFile+strlen(destFile)-4))!=0) { strcpy(destFile, lua_tostring(L, 1)); destFile[strlen(lua_tostring(L, 1))] = 0; strcat(destFile, ".ccm"); destFile[4+strlen(lua_tostring(L, 1))] = 0; } else { strcpy(destFile, lua_tostring(L, 1)); destFile[strlen(lua_tostring(L, 1))] = 0; } saveRet = TheScene->LoadIniFile(destFile); lua_pushboolean(L, saveRet >= 0); return 1; } else { lua_pushboolean(L, false); return 1; } break; } } int IniSave(lua_State *L) { int nbArgs = lua_gettop(L); int saveRet; switch (nbArgs) { case 0 : saveRet = TheScene->SaveIniFile(CamcamCCM); lua_pushboolean(L, saveRet >= 0); return 1; break; default : if(lua_isstring(L,1)) { char destFile[2048] = ""; strcpy(destFile, lua_tostring(L, 1)); destFile[strlen(lua_tostring(L, 1))] = 0; if(strlen(destFile)<4 || strcmp(".ccm", strlwr(destFile+strlen(destFile)-4))!=0) { strcpy(destFile, lua_tostring(L, 1)); destFile[strlen(lua_tostring(L, 1))] = 0; strcat(destFile, ".ccm"); destFile[4+strlen(lua_tostring(L, 1))] = 0; } else { strcpy(destFile, lua_tostring(L, 1)); destFile[strlen(lua_tostring(L, 1))] = 0; } saveRet = TheScene->SaveIniFile(destFile); lua_pushboolean(L, saveRet >= 0); return 1; } else { lua_pushboolean(L, false); return 1; } break; } } int IniDestroy(lua_State *L) { int nbArgs = lua_gettop(L); int saveRet; switch (nbArgs) { case 0 : saveRet = TheScene->DestroyIniFile(CamcamCCM); lua_pushboolean(L, saveRet >= 0); return 1; default : saveRet = TheScene->DestroyIniFile((char *)luaL_checkstring(L,1)); lua_pushboolean(L, saveRet >= 0); return 1; } return 0; } int IniValueDel(lua_State *L) { char iniFile[2048]; strcpy(iniFile, CamcamCCM); if(lua_gettop(L)==0 || (lua_gettop(L)>0 && !lua_isstring(L,1))) return false; char completedVarname[2048] = "."; if(lua_tostring(L,1)[0]!='.') { strcat(completedVarname, lua_tostring(L,1)); completedVarname[strlen(lua_tostring(L,1))+1] = 0; } else { strcpy(completedVarname, lua_tostring(L,1)); } if(lua_gettop(L)==2) { if(!lua_isstring(L,2)) return false; strcpy(iniFile, lua_tostring(L, 2)); iniFile[strlen(lua_tostring(L, 2))] = 0; if(strlen(iniFile)<4 || strcmp(".ccm", strlwr(iniFile+strlen(iniFile)-4))!=0) { strcpy(iniFile, lua_tostring(L, 2)); iniFile[strlen(lua_tostring(L, 2))] = 0; strcat(iniFile, ".ccm"); iniFile[4+strlen(lua_tostring(L, 2))] = 0; } else { strcpy(iniFile, lua_tostring(L, 2)); iniFile[strlen(lua_tostring(L, 2))] = 0; } } if (TheScene->IniFileDico.IsExist(iniFile) == -1 && TheScene->LoadIniFile(iniFile) == -1) return false; u32 ID; UnicID mUID; TheScene->IniFileDico.GetUnic(&mUID,iniFile); ID = TheScene->IniFileDico.mpst_Dico[mUID].AssociatedValue; INIFILE* inifile = &(TheScene->IniFiles[ID]); if(inifile->variableDico.IsExist(completedVarname)!=-1) { inifile->delVariable(completedVarname); return true; } if(strcmp(completedVarname,".")==0) { u32 currentChild = inifile->root; u32 nextChild = -1; while(currentChild!=-1) { nextChild = inifile->variables[currentChild].next; inifile->delVariable(inifile->variables[currentChild].name); currentChild = nextChild; } return true; } return false; } int IniValueDelOld(lua_State *L) { char iniFile[2048] = "Camcam.ini"; if(lua_gettop(L)==0 || (lua_gettop(L)>0 && !lua_isstring(L,1))) return false; char completedVarname[2048] = "."; if(lua_tostring(L,1)[0]!='.') { strcat(completedVarname, lua_tostring(L,1)); completedVarname[strlen(lua_tostring(L,1))+1] = 0; } else { strcpy(completedVarname, lua_tostring(L,1)); } if(lua_gettop(L)==2) { if(!lua_isstring(L,2)) return false; strcpy(iniFile, lua_tostring(L, 2)); iniFile[strlen(lua_tostring(L, 2))] = 0; if(strlen(iniFile)<4 || strcmp(".ini", strlwr(iniFile+strlen(iniFile)-4))!=0) { strcpy(iniFile, lua_tostring(L, 2)); iniFile[strlen(lua_tostring(L, 2))] = 0; strcat(iniFile, ".ini"); iniFile[4+strlen(lua_tostring(L, 2))] = 0; } else { strcpy(iniFile, lua_tostring(L, 2)); iniFile[strlen(lua_tostring(L, 2))] = 0; } } if (TheScene->IniFileDico.IsExist(iniFile) == -1 && TheScene->LoadIniFile(iniFile) == -1) return false; u32 ID; UnicID mUID; TheScene->IniFileDico.GetUnic(&mUID,iniFile); ID = TheScene->IniFileDico.mpst_Dico[mUID].AssociatedValue; INIFILE* inifile = &(TheScene->IniFiles[ID]); if(inifile->variableDico.IsExist(completedVarname)!=-1) { inifile->delVariable(completedVarname); return true; } if(strcmp(completedVarname,".")==0) { u32 currentChild = inifile->root; while(currentChild!=-1) { inifile->delVariable(inifile->variables[currentChild].name); currentChild = inifile->variables[currentChild].next; } return true; } return false; } void IniValueGetRec(lua_State *L, INI_VARIABLE* variables, u32 ID) { if(variables[ID].child==-1) { bool knownFound = false; if(strlen(variables[ID].value)>=3) { if(strcmp(" #s", variables[ID].value+strlen(variables[ID].value)-3)==0) { char value[2048]; strcpy(value, variables[ID].value); value[strlen(variables[ID].value)-3] = 0; PushString(L, value); knownFound = true; } if(strcmp(" #b", variables[ID].value+strlen(variables[ID].value)-3)==0) { if(strcmp("true #b", variables[ID].value)==0) { PushBool(L, true); } else { PushBool(L, false); } knownFound = true; } if(strcmp(" #n", variables[ID].value+strlen(variables[ID].value)-3)==0) { char value[2048]; strcpy(value, variables[ID].value); value[strlen(variables[ID].value)-3] = 0; lua_pushnumber(L, (double)atof(value)); knownFound = true; } if(strcmp(" #v", variables[ID].value+strlen(variables[ID].value)-3)==0) { char value[2048]; strcpy(value, variables[ID].value); value[strlen(variables[ID].value)-3] = 0; PushVector(L, value); knownFound = true; } if(strcmp(" #m", variables[ID].value+strlen(variables[ID].value)-3)==0) { char value[2048]; strcpy(value, variables[ID].value); value[strlen(variables[ID].value)-3] = 0; PushMatrix(L, value); knownFound = true; } if(strcmp(" #q", variables[ID].value+strlen(variables[ID].value)-3)==0) { char value[2048]; strcpy(value, variables[ID].value); value[strlen(variables[ID].value)-3] = 0; PushQuat(L, value); knownFound = true; } if(strcmp("nil #0", variables[ID].value)==0) { lua_pushnil(L); knownFound = true; } if(strcmp("{} #0", variables[ID].value)==0) { lua_newtable(L); knownFound = true; } } if(!knownFound) { char value[2048]; strcpy(value, variables[ID].value); PushString(L, value); } } else { lua_newtable(L); u32 currentChild = variables[ID].child; do { char key[2048] = ""; strcpy(key, strrchr(variables[currentChild].name, '.')+1); if(key[strlen(key)-1]=='#') { key[strlen(key)-1] = 0; lua_pushnumber(L, atoi(key)); } else { PushString(L, key); } IniValueGetRec(L, variables, currentChild); lua_settable(L,-3); currentChild = variables[currentChild].next; } while(currentChild!=-1); } } int DoIniValueGet(lua_State *L/*, bool fromServer*/) { char iniFile[2048]; strcpy(iniFile, CamcamCCM); if(lua_gettop(L)==0 || (lua_gettop(L)>0 && !lua_isstring(L,1))) return false; char completedVarname[2048] = "."; if(lua_tostring(L,1)[0]!='.') { strcat(completedVarname, lua_tostring(L,1)); completedVarname[strlen(lua_tostring(L,1))+1] = 0; } else { strcpy(completedVarname, lua_tostring(L,1)); } if(lua_gettop(L)==3) { if(!lua_isstring(L,3)) return false; strcpy(iniFile, lua_tostring(L, 3)); iniFile[strlen(lua_tostring(L, 3))] = 0; if(strlen(iniFile)<4 || strcmp(".ccm", strlwr(iniFile+strlen(iniFile)-4))!=0) { strcpy(iniFile, lua_tostring(L, 3)); iniFile[strlen(lua_tostring(L, 3))] = 0; strcat(iniFile, ".ccm"); iniFile[4+strlen(lua_tostring(L, 3))] = 0; } else { strcpy(iniFile, lua_tostring(L, 3)); iniFile[strlen(lua_tostring(L, 3))] = 0; } } if (TheScene->IniFileDico.IsExist(iniFile) == -1 && TheScene->LoadIniFile(iniFile) == -1) { if(lua_gettop(L)==1) lua_pushnil(L); else lua_pushvalue(L, 2); return true; } u32 ID; UnicID mUID; TheScene->IniFileDico.GetUnic(&mUID,iniFile); ID = TheScene->IniFileDico.mpst_Dico[mUID].AssociatedValue; INIFILE* inifile = &(TheScene->IniFiles[ID]); if(inifile->variableDico.IsExist(completedVarname)!=-1) { inifile->variableDico.GetUnic(&mUID,completedVarname); ID = inifile->variableDico.mpst_Dico[mUID].AssociatedValue; IniValueGetRec(L, inifile->variables, ID); return true; } if (strcmp(completedVarname,".")==0) { lua_newtable(L); u32 currentChild = inifile->root; while(currentChild!=-1) { char key[2048] = ""; strcpy(key, strrchr(inifile->variables[currentChild].name, '.')+1); if(key[strlen(key)-1]=='#') { key[strlen(key)-1] = 0; lua_pushnumber(L, atoi(key)); } else { PushString(L, key); } IniValueGetRec(L, inifile->variables, currentChild); lua_settable(L,-3); currentChild = inifile->variables[currentChild].next; } return true; } if(lua_gettop(L)==1) lua_pushnil(L); else lua_pushvalue(L, 2); return true; } int IniValueGet(lua_State *L) { return DoIniValueGet(L/*, false*/); } //int IniValueGetFromServer(lua_State *L) //{ // return DoIniValueGet(L, true); //} int IniValueGetOld(lua_State *L) { char iniFile[2048] = "Camcam.ini"; if(lua_gettop(L)==0 || (lua_gettop(L)>0 && !lua_isstring(L,1))) return false; char completedVarname[2048] = "."; if(lua_tostring(L,1)[0]!='.') { strcat(completedVarname, lua_tostring(L,1)); completedVarname[strlen(lua_tostring(L,1))+1] = 0; } else { strcpy(completedVarname, lua_tostring(L,1)); } if(lua_gettop(L)==3) { if(!lua_isstring(L,3)) return false; strcpy(iniFile, lua_tostring(L, 3)); iniFile[strlen(lua_tostring(L, 3))] = 0; if(strlen(iniFile)<4 || strcmp(".ini", strlwr(iniFile+strlen(iniFile)-4))!=0) { strcpy(iniFile, lua_tostring(L, 3)); iniFile[strlen(lua_tostring(L, 3))] = 0; strcat(iniFile, ".ini"); iniFile[4+strlen(lua_tostring(L, 3))] = 0; } else { strcpy(iniFile, lua_tostring(L, 3)); iniFile[strlen(lua_tostring(L, 3))] = 0; } } if (TheScene->IniFileDico.IsExist(iniFile) == -1 && TheScene->LoadIniFile(iniFile) == -1) return false; u32 ID; UnicID mUID; TheScene->IniFileDico.GetUnic(&mUID,iniFile); ID = TheScene->IniFileDico.mpst_Dico[mUID].AssociatedValue; INIFILE* inifile = &(TheScene->IniFiles[ID]); if(inifile->variableDico.IsExist(completedVarname)!=-1) { inifile->variableDico.GetUnic(&mUID,completedVarname); ID = inifile->variableDico.mpst_Dico[mUID].AssociatedValue; IniValueGetRec(L, inifile->variables, ID); return true; } if(lua_gettop(L)==1) lua_pushnil(L); else lua_pushvalue(L, 2); return true; } void IniValueSetRec(lua_State *L, char* parentName, char* inifile) { if(!lua_istable(L,-1)) { char* iniVarname = (char*)ZeroAlloc(strlen(parentName)+1+1); strcpy(iniVarname,parentName); strcat(iniVarname, "."); if(lua_type(L, -2)==LUA_TSTRING) { iniVarname = (char*)CC_realloc(iniVarname, 1+strlen(parentName)+1+strlen(lua_tostring(L,-2))); strcat(iniVarname, lua_tostring(L,-2)); iniVarname[strlen(parentName)+1+strlen(lua_tostring(L,-2))] = 0; } else { lua_pushvalue(L,-2); iniVarname = (char*)CC_realloc(iniVarname, 1+1+strlen(parentName)+1+strlen(lua_tostring(L,-1))); strcat(iniVarname, lua_tostring(L,-1)); strcat(iniVarname, "#"); iniVarname[1+strlen(parentName)+1+strlen(lua_tostring(L,-1))] = 0; lua_pop(L,1); } char* value = 0; switch (lua_type(L,-1)) { case LUA_TNUMBER: { value = (char*)ZeroAlloc(3+strlen(lua_tostring(L,-1))+1); lua_pushvalue(L,-1); strcpy(value, lua_tostring(L,-1)); strcat(value, " #n"); value[3+strlen(lua_tostring(L,-1))] = 0; lua_pop(L,1); TheScene->SetIniValue(inifile, iniVarname, value); } break; case LUA_TSTRING: { value = (char*)ZeroAlloc(3+strlen(lua_tostring(L,-1))+1); strcpy(value, lua_tostring(L,-1)); //strcat(value, " #s"); value[3+strlen(lua_tostring(L,-1))] = 0; TheScene->SetIniValue(inifile, iniVarname, value); } break; case LUA_TBOOLEAN: { value = (char*)ZeroAlloc(3+strlen((lua_toboolean(L, -1) ? "true" : "false"))+1); strcpy(value, (lua_toboolean(L, -1) ? "true" : "false")); strcat(value, " #b"); value[3+strlen((lua_toboolean(L, -1) ? "true" : "false"))] = 0; TheScene->SetIniValue(inifile, iniVarname, value); } break; case LUA_TNIL: { value = (char*)ZeroAlloc(strlen("nil #0")+1); strcpy(value, "nil #0"); value[6] = 0; TheScene->SetIniValue(inifile, iniVarname, value); } break; default: { void *p = lua_touserdata(L, -1); if (p != NULL) { if (lua_getmetatable(L, -1)) { lua_getfield(L, LUA_REGISTRYINDEX, "VECTOR"); if (lua_rawequal(L, -1, -2)) { lua_pop(L, 2); luaL_callmeta(L, -1, "__tostring"); value = (char*)ZeroAlloc(strlen(lua_tostring(L, -1))+3+1); strcpy(value, lua_tostring(L, -1)); strcat(value, " #v\0"); TheScene->SetIniValue(inifile, iniVarname, value); lua_pop(L,1); } else { lua_pop(L, 2); } } if (lua_getmetatable(L, -1)) { lua_getfield(L, LUA_REGISTRYINDEX, "MATRIX"); if (lua_rawequal(L, -1, -2)) { lua_pop(L, 2); luaL_callmeta(L, -1, "__tostring"); value = (char*)ZeroAlloc(strlen(lua_tostring(L, -1))+3+1); strcpy(value, lua_tostring(L, -1)); strcat(value, " #m\0"); TheScene->SetIniValue(inifile, iniVarname, value); lua_pop(L,1); } else { lua_pop(L, 2); } } if (lua_getmetatable(L, -1)) { lua_getfield(L, LUA_REGISTRYINDEX, "QUAT"); if (lua_rawequal(L, -1, -2)) { lua_pop(L, 2); luaL_callmeta(L, -1, "__tostring"); value = (char*)ZeroAlloc(strlen(lua_tostring(L, -1))+3+1); strcpy(value, lua_tostring(L, -1)); strcat(value, " #q\0"); TheScene->SetIniValue(inifile, iniVarname, value); lua_pop(L,1); } else { lua_pop(L, 2); } } } } break; } if (value) CC_free(value); if (iniVarname) CC_free(iniVarname); } else { char* iniVarname = (char*)ZeroAlloc(1+strlen(parentName)+1); strcpy(iniVarname,parentName); strcat(iniVarname, "."); lua_pushvalue(L,-2); if(lua_type(L, -1)==LUA_TSTRING) { iniVarname = (char*)CC_realloc(iniVarname, 1+strlen(parentName)+1+strlen(lua_tostring(L,-1))+1); strcat(iniVarname, lua_tostring(L,-1)); iniVarname[strlen(parentName)+1+strlen(lua_tostring(L,-1))] = 0; } else { iniVarname = (char*)CC_realloc(iniVarname, 1+strlen(parentName)+1+strlen(lua_tostring(L,-1))+1); strcat(iniVarname, lua_tostring(L,-1)); strcat(iniVarname, "#"); iniVarname[1+strlen(parentName)+1+strlen(lua_tostring(L,-1))] = 0; } lua_pop(L,1); TheScene->SetIniValue(inifile, iniVarname, ""); //iniVarname = prochain parent lua_pushnil(L); bool atLeastOne = false; while (lua_next(L, -2) != 0) { atLeastOne = true; IniValueSetRec(L, iniVarname, inifile); } if(!atLeastOne) TheScene->SetIniValue(inifile, iniVarname, "{} #0"); CC_free(iniVarname); } lua_pop(L,1); } int IniValueSet(lua_State *L) { char iniFile[1024]; strcpy(iniFile, CamcamCCM); int s = lua_gettop(L); if(lua_gettop(L)==0 || (lua_gettop(L)>0 && !lua_isstring(L,1))) return false; char* completedVarname = (char*)ZeroAlloc(2048); strcpy(completedVarname, "."); if(lua_tostring(L,1)[0]!='.') { if (strlen(lua_tostring(L,1))+strlen(completedVarname)+1 > 2048) { completedVarname = (char*)CC_realloc(completedVarname, strlen(lua_tostring(L,1))+strlen(completedVarname))+1; } strcat(completedVarname, lua_tostring(L,1)); completedVarname[strlen(lua_tostring(L,1))+1] = 0; } else { if (strlen(lua_tostring(L,1))+1 > 2048) { completedVarname = (char*)CC_realloc(completedVarname, strlen(lua_tostring(L,1))+1); } strcpy(completedVarname, lua_tostring(L,1)); } char* posPtr = strrchr(completedVarname, '.'); int pos = posPtr-completedVarname; char* parent = (char*)ZeroAlloc(pos+1); strncpy(parent, completedVarname, pos); parent[pos] = 0; char* varName = (char*)ZeroAlloc(strlen(completedVarname)-pos+1); strncpy(varName, completedVarname+pos+1, strlen(completedVarname)-pos); if(lua_gettop(L)==3) { if(!lua_isstring(L,3)) return false; strcpy(iniFile, lua_tostring(L, 3)); if(strlen(iniFile)<4 || strcmp(".ccm", strlwr(iniFile+strlen(iniFile)-4))!=0) { strcpy(iniFile, lua_tostring(L, 3)); iniFile[strlen(lua_tostring(L, 3))] = 0; strcat(iniFile, ".ccm"); iniFile[4+strlen(lua_tostring(L, 3))] = 0; } } if (*varName) { if(lua_gettop(L)==1) { lua_pushstring(L, varName); lua_pushstring(L, "1"); } else { lua_pushstring(L, varName); lua_pushvalue(L, 2); } IniValueSetRec(L, parent, iniFile); CC_free(completedVarname); CC_free(parent); CC_free(varName); return false; } else { if(lua_gettop(L)!=1 && (lua_istable(L,2))) { lua_pushnil(L); while (lua_next(L, 2) != 0) { IniValueSetRec(L, parent, iniFile); } CC_free(completedVarname); CC_free(parent); CC_free(varName); return false; } else { CC_free(completedVarname); CC_free(parent); CC_free(varName); return true; } } } int IniValueSetOld(lua_State *L) { char iniFile[2048] = "Camcam.ini"; if(lua_gettop(L)==0 || (lua_gettop(L)>0 && !lua_isstring(L,1))) return false; char completedVarname[2048] = "."; if(lua_tostring(L,1)[0]!='.') { strcat(completedVarname, lua_tostring(L,1)); completedVarname[strlen(lua_tostring(L,1))+1] = 0; } else { strcpy(completedVarname, lua_tostring(L,1)); } char* posPtr = strrchr(completedVarname, '.'); int pos = posPtr-completedVarname; char parent[2048] = ""; strncpy(parent, completedVarname, pos); parent[pos] = 0; char varName[2048] = ""; strncpy(varName, completedVarname+pos+1, strlen(completedVarname)-pos); if(lua_gettop(L)==3) { if(!lua_isstring(L,3)) return false; strcpy(iniFile, lua_tostring(L, 3)); iniFile[strlen(lua_tostring(L, 3))] = 0; if(strlen(iniFile)<4 || strcmp(".ini", strlwr(iniFile+strlen(iniFile)-4))!=0) { strcpy(iniFile, lua_tostring(L, 3)); iniFile[strlen(lua_tostring(L, 3))] = 0; strcat(iniFile, ".ini"); iniFile[4+strlen(lua_tostring(L, 3))] = 0; } else { strcpy(iniFile, lua_tostring(L, 3)); iniFile[strlen(lua_tostring(L, 3))] = 0; } } if(lua_gettop(L)==1) { lua_pushstring(L, varName); lua_pushstring(L, "1"); } else { lua_pushstring(L, varName); lua_pushvalue(L, 2); } char value[2048]; strcpy(value, lua_tostring(L,-1)); TheScene->SetIniValue(iniFile, varName, value); TheScene->SaveIniFile(iniFile); return false; } /****************************************************/ // Note: returns an empty string in case of error; max len of string : 2047. std::string GetRegistryValueStr(HKEY rootKey, const char *subKey, const char *name) { HKEY key; if (RegOpenKeyEx(rootKey, subKey, 0, KEY_READ, &key) != ERROR_SUCCESS) return std::string(); char str[2048] = ""; DWORD strType = NULL; DWORD strLen = 2048; DWORD error = RegQueryValueEx(key, name, 0, &strType, (BYTE *)str, &strLen); /************************ DEBUG BEGINS HERE *************************/ /* char info[2048] = ""; sprintf(info, "error=%u", error); MessageBox(NULL, info, "Info", MB_OK); //*/ /* if (error!=ERROR_SUCCESS) { char info[2048] = ""; wchar_t Winfo[2048]; DWORD err = error; //GetLastError(); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, LANG_NEUTRAL, info, sizeof(Winfo)/sizeof(wchar_t), NULL); wcstombs(info,Winfo,2048-1); strcat(info, " : "); strcat(info, str); MessageBox(NULL, info, "Info", MB_OK); } //*/ /************************* DEBUG ENDS HERE **************************/ RegCloseKey(key); return std::string(str); } /****************************************************/ bool GetDemoBranchFlagFromRegistry() { /*static volatile*/ short int DemoState = -1; // no cache //if (DemoState == -1) DemoState = (GetRegistryValueStr(HKEY_LOCAL_MACHINE, (std::string(CAMCAM_REG_KEY)+std::string(GAME_UPDATE_SUBKEY)).c_str(), "branch") == "demo") ? 1 : 0; return (DemoState == 1); } static const char *OC_KEY_CAMCAM = "OnceConnected"; /****************************************************/ bool GetFirstRunFlag() { return (GetRegistryValueStr(HKEY_CURRENT_USER, CAMCAM_REG_KEY, OC_KEY_CAMCAM) != "1"); } /****************************************************/ bool SetFirstRunFlag() { HKEY newKey; if (RegCreateKey(HKEY_CURRENT_USER, CAMCAM_REG_KEY, &newKey) != ERROR_SUCCESS) return false; const char *frvalue = "1"; bool ret = (RegSetValueEx(newKey, OC_KEY_CAMCAM, 0, REG_EXPAND_SZ, (BYTE *)frvalue, strlen(frvalue)+1) == ERROR_SUCCESS); RegCloseKey(newKey); return ret; } /****************************************************/ // dst: max 2047 chars /*void GetCamCamValueFromRegistry(char *dst, char *item, bool fromHKCU) { std::string value; if (fromHKCU) value = GetRegistryValueStr(HKEY_CURRENT_USER, CAMCAM_REG_KEY, item); else value = GetRegistryValueStr(HKEY_LOCAL_MACHINE, (std::string(CAMCAM_REG_KEY)+std::string(GAME_UPDATE_SUBKEY).c_str(), item); strncpy(dst, value, 2047); }*/ /****************************************************/ // dst: max 2 chars void GetInstalledLanguageCode(char *dst) { strncpy(dst, GetRegistryValueStr(HKEY_LOCAL_MACHINE, (std::string(CAMCAM_REG_KEY)+std::string(GAME_UPDATE_SUBKEY)).c_str(), "language").c_str(), 2); } ///****************************************************/ //bool SetRegistryValueStr(HKEY rootKey, const char *key, const char *name, const char *value) //{ // HKEY hkey; // if (RegOpenKeyEx(rootKey, key, 0, KEY_ALL_ACCESS, &hkey) != ERROR_SUCCESS) // return false; // bool ret = RegSetValueEx(hkey, name, 0, REG_EXPAND_SZ, (BYTE *)value, strlen(value)+1); // RegCloseKey(hkey); // return ret; //} // ///****************************************************/ //bool SetBranch(const char *branch, const char *newGameId) //{ // const char *BRANCH_KEY_CAMCAM = "branch"; // const char *GAMEID_KEY_CAMCAM = "info"; // bool res = SetRegistryValueStr(HKEY_LOCAL_MACHINE, CAMCAM_REG_KEY, BRANCH_KEY_CAMCAM, branch); // if (!res) // return false; // return SetRegistryValueStr(HKEY_LOCAL_MACHINE, CAMCAM_REG_KEY, GAMEID_KEY_CAMCAM, newGameId); //} // ///****************************************************/ //bool SwitchToBetaBranch() //{ //#ifdef ONLINE_MODE // if (Account.sameCurrentDemoAndBeta()) // return SetBranch("beta", Account.getBetaGameId().c_str()); // else // return false; // user must download a new beta installer //#endif // return false; //} /****************************************************/ int GetAccountInfo(lua_State *L) { lua_newtable(L); lua_pushstring(L, "v"); #ifdef ONLINE_MODE lua_pushnumber(L, Account.getProtocolNum()); #else lua_pushnumber(L, 0); #endif lua_settable(L, -3); lua_pushstring(L, "ia"); #ifdef ONLINE_MODE lua_pushnumber(L, Account.getIdAccount()); #else lua_pushnumber(L, 0); #endif lua_settable(L, -3); return true; } #ifdef ONLINE_MODE /****************************************************/ int lua_push_json_object(lua_State *L, json_object *jo, bool freeJO=false) { if (!jo) return 0; switch(json_object_get_type(jo)) { case json_type_boolean: lua_pushboolean(L, json_object_get_boolean(jo)); break; case json_type_double: lua_pushnumber(L, json_object_get_double(jo)); break; case json_type_int: lua_pushnumber(L, (double)json_object_get_int(jo)); break; case json_type_object: lua_newtable(L); json_object_object_foreach(jo, key, val) { lua_pushstring(L, key); lua_push_json_object(L, val); lua_settable(L, -3); } break; case json_type_array: { lua_newtable(L); int len = json_object_array_length(jo); for (int i=0; i!=len; ++i) { lua_pushnumber(L, i+1); // wants index starting at 1 lua_push_json_object(L, json_object_array_get_idx(jo, i)); lua_settable(L, -3); } } break; case json_type_string: lua_pushstring(L, json_object_get_string(jo)); break; default: lua_pushboolean(L, false); // avoid corrupting the table in case something went really wrong return 0; } if (freeJO) json_object_put(jo); return 1; } #endif /****************************************************/ int JSONToTable(lua_State *L) { if(lua_gettop(L)<1) return false; #ifdef ONLINE_MODE json_object *jo = json_tokener_parse(const_cast(lua_tostring(L, 1))); if (is_error(jo)) lua_newtable(L); else lua_push_json_object(L, jo, true); #else lua_newtable(L); #endif return true; } /****************************************************/ int AddCredits(lua_State *L) { if(lua_gettop(L)<1) return false; #ifdef ONLINE_MODE //lua_pushboolean(L, Account.addCredits(lua_tonumber(L, 1))); MessageBox(NULL, "Deprecated", "AddCredits", MB_ICONWARNING); lua_pushboolean(L, true); #else lua_pushboolean(L, true); #endif return true; } extern HWND hWnd; /****************************************************/ int OpenExternalBrowser(lua_State *L) { if(lua_gettop(L)<1) return false; // Prevent from spawning an exe... char url[2048]; strncpy(url, lua_tostring(L, 1), 2047); #ifdef ONLINE_MODE if (!*url) { // If first arg is empty, auto-log-in to web page, using arg 2 index CCamCamAccount::WebPage page = CCamCamAccount::Profile; if (lua_gettop(L)>1) { if (lua_tointeger(L, 2) >= CCamCamAccount::NbWebPages) { lua_pushboolean(L, false); return true; } page = (CCamCamAccount::WebPage)lua_tointeger(L, 2); } if(CCamCamAccount::CNT_NORMAL != Account.getConnectionMode()) { // If account is not a normal connection, we cant auto-log-in lua_pushboolean(L, Account.callGuestPage(Account.getPage(page))); return true; } strncpy(url, Account.getLoggedProfileURL(page).c_str(), 2047); } // Launch lua_pushboolean(L, Account.openExternalWebBrowser(url)); #else if ((strncmp(url, "http://", 7) == 0) || (strncmp(url, "https://", 8) == 0)) { HINSTANCE r = ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL); lua_pushboolean(L, ((int)r)>32); } else lua_pushboolean(L, false); #endif return true; } std::string getNextToken(char const**ppSrc, char delimiter) { const char *pStart = *ppSrc; const char *pEnd = strchr(pStart, delimiter); if (pEnd != NULL) { *ppSrc = pEnd+1; return std::string(pStart, pEnd-pStart); } else { *ppSrc = NULL; return std::string(pStart); } } #ifdef ONLINE_MODE /****************************************************/ void releaseLuaHTTPClients() { for (std::map::iterator it=HttpClientChannels.begin(); it!=HttpClientChannels.end(); ++it) { it->second.release(); } HttpClientChannels.clear(); } #endif /****************************************************/ //int GetHTTPProxy(lua_State *L) //{ //#ifdef ONLINE_MODE // const char *proxy = Account.getHttpClient().getProxy(); // if (proxy) // lua_pushstring(L, proxy); // else // lua_pushnil(L); //#else // lua_pushnil(L); //#endif // return true; //} // ///****************************************************/ //int SetRecommendedHTTPProxy(lua_State *L) //{ // if (lua_gettop(L) < 1) return false; //#ifdef ONLINE_MODE // Account.setProxy(lua_tostring(L, 1)); //#endif // return true; //} /****************************************************/ #ifdef ONLINE_MODE bool hasChannelClient(int channel) { if (channel == -1) return true; return (HttpClientChannels.find(channel) != HttpClientChannels.end()); } CHttpClient *getChannelClient(int channel) { if (channel < 0) { if (channel == -1) return &Account._HttpClient; else return &HttpClientChannels[channel]; // TODO } else return &HttpClientChannels[channel]; } #endif /****************************************************/ int HTTPRequest(lua_State *L, int channel, bool isPostRequest, bool isMultipart=false) { // Get URL if(lua_gettop(L)<1) return false; const char *url = lua_tostring(L,1); const char *urlParams; if (isPostRequest) { urlParams = lua_tostring(L,2); } else { urlParams = strchr(url, '?'); char blankParams [1] = ""; char pageURL [1024]; strncpy(pageURL, url, min(1024, urlParams ? (urlParams-url) : 1024)); pageURL[min(1023, urlParams ? (urlParams-url) : 1023)] = 0; strncpy(pageURL, url, min(1024, urlParams ? (urlParams-url) : 1024)); url = pageURL; urlParams = urlParams ? urlParams+1 : blankParams; // skip separator } int paramDelta = (isPostRequest ? 1 : 0); // Get optional destination file const char *destFile = (lua_gettop(L)>1+paramDelta) ? lua_tostring(L,2+paramDelta) : NULL; // Get optional verbose param bool verbose = ((lua_gettop(L)>2+paramDelta) && lua_toboolean(L,2+paramDelta)); #ifdef ONLINE_MODE // Quick config bool isNewClient = !hasChannelClient(channel); CHttpClient *httpClient = getChannelClient(channel); if (isNewClient && channel >= 0) { httpClient->init(); httpClient->setCurrentPacMethod(CHttpClient::PacmManual); httpClient->setProxy(Account.getHttpClient().getProxy()); } bool res; bool canTryOtherProxy = false; if (isPostRequest && isMultipart) { const char *bufPos = urlParams; while (bufPos) { std::string field = getNextToken(&bufPos, '='); std::string value = (bufPos ? getNextToken(&bufPos, '&') : ""); if (value[0] == '@') httpClient->addMultipartParam(field.c_str(), CHttpClient::MultipartParam(value.substr(1).c_str(), CHttpClient::ParamLoadFile)); else httpClient->addMultipartParam(field.c_str(), value.c_str()); } do { // Do request, and reconfigure proxy if needed res = httpClient->sendMultipartRequest(url, false, verbose); if (!res && httpClient->mayRetryAfterProxyAutoConfig()) canTryOtherProxy = httpClient->nextTryAutoConfigureProxy(url); // needs XP SP1 or newer } while (!res && canTryOtherProxy); } else { if (channel == -1) { if (!Account.isLoggedIn()) res = false; else res = Account.doRequest(url, urlParams, FAILED_SCRIPT_REQUEST, __FUNCTION__, "", true); } else { do { // Do request, and reconfigure proxy if needed res = httpClient->sendRequest(url, urlParams, isPostRequest, false, verbose); if (!res && httpClient->mayRetryAfterProxyAutoConfig()) canTryOtherProxy = httpClient->nextTryAutoConfigureProxy(url); // needs XP SP1 or newer } while (!res && canTryOtherProxy); } } if (destFile && *destFile) { if (!res) lua_pushboolean(L, false); else { if (fileExists(const_cast(destFile))) { lua_pushboolean(L, false); return true; } FILE *f = CC_fopen(destFile, "wb"); if (f) { fwrite(httpClient->getResponsePage().data(), 1, httpClient->getResponsePage().size(), f); CC_fclose(f); lua_pushboolean(L, true); } else lua_pushboolean(L, false); } } else { lua_pushstring(L, httpClient->getResponsePage().c_str()); } #else lua_pushstring(L, ""); #endif // ONLINE_MODE return true; } /****************************************************/ int HTTPGet(lua_State *L) { int channel = (lua_gettop(L)>=4) ? lua_tonumber(L, 4) : 0; return HTTPRequest(L, channel, false); } /****************************************************/ int HTTPPost(lua_State *L) { int channel = (lua_gettop(L)>=5) ? lua_tonumber(L, 5) : 0; return HTTPRequest(L, channel, true, false); } /****************************************************/ int HTTPPostMultipart(lua_State *L) { int channel = (lua_gettop(L)>=5) ? lua_tonumber(L, 5) : 0; return HTTPRequest(L, channel, true, true); } /*********************** Get Object List *****************************/ int GetObjectList(lua_State *L) { if (lua_gettop(L) == 0 || (lua_gettop(L)>0 && !lua_isstring(L,1))) return 0; char *sceneName = (char *)lua_tostring(L,1); SmallScene *SmSc = TheScene->SmallNameToScene(sceneName); _3D_Object **pObj; int onlyMesh = 0; if (lua_gettop(L) > 1 && lua_isnumber(L, 2)) onlyMesh = lua_tonumber(L, 2); if (!SmSc) return 0; pObj = SmSc->ObjectsPtrs; lua_newtable(L); int nbInTable = 0; for (int counter = 0; counter < SmSc->ulNumberOfObjects; counter++,pObj++) { if (onlyMesh && (*pObj)->MeshIndex == -1) continue; lua_pushnumber(L, ++nbInTable); lua_newtable(L); lua_pushstring(L, "name"); lua_pushstring(L, (char *)(*pObj)->pObjectName); lua_settable(L, -3); lua_pushstring(L, "father"); lua_pushnumber(L, (*pObj)->FatherIndex + 1); lua_settable(L, -3); lua_settable(L, -3); } return 1; } /*********************** Get Material List *****************************/ static int matEnumIndex; void MatEnumProcess(char *String,void *UserParam) { int len; lua_State *L = (lua_State *)UserParam; lua_pushnumber(L, ++matEnumIndex); lua_pushstring(L, (char *)String); lua_settable(L, -3); } int GetMatList(lua_State *L) { if (lua_gettop(L) == 0 || (lua_gettop(L)>0 && !lua_isstring(L,1))) return 0; char *sceneName = (char *)lua_tostring(L,1); SmallScene *SmSc = TheScene->SmallNameToScene(sceneName); if (!SmSc) return 0; lua_newtable(L); matEnumIndex = 0; SmSc->MaterialNameDico.EnumWords(MatEnumProcess,L); return 1; } /*********************** Get Material List *****************************/ int GetMediaList(lua_State *L) { if (lua_gettop(L) == 0 || (lua_gettop(L)>0 && !lua_isstring(L,1))) return 0; char *sceneName = (char *)lua_tostring(L,1); SmallScene *SmSc = TheScene->SmallNameToScene(sceneName); int mediaEnumIndex = 0; if (!SmSc) return 0; lua_newtable(L); for (int i=0; iulNumberOfMaterials; i++) { for (int j=0; jMaterialsPtrs[i]->NumberOfLayers; j++) { u32 textureIndex = SmSc->MaterialsPtrs[i]->Layers[j].TextureMediaIndex; if (textureIndex != -1) textureIndex = TheScene->MediaDico.mpst_Dico[textureIndex].AssociatedValue; if (textureIndex != -1 && TheScene->ID_MEDIA[textureIndex]) { lua_pushnumber(L, ++mediaEnumIndex); lua_pushstring(L, (char *)TheScene->ID_MEDIA[textureIndex]->MediaName); lua_settable(L, -3); } } } return 1; } /*********************** CONVERSTION FUNCTIONS ***********************/ int ProcessTableRec(lua_State *L, char *strPtr, int nbElmts) { // Set Variable char inBuffer[256]; char *inBufferPtr; int keyIndex = 1; lua_newtable(L); while (nbElmts > 0) { memset(inBuffer, 0, sizeof(inBuffer)); for (;nbElmts > 0 && *strPtr <= 32; strPtr++, nbElmts--); for (inBufferPtr=inBuffer;nbElmts > 0 && *strPtr != '=' && *strPtr != '{'; strPtr++, inBufferPtr++, nbElmts--) *inBufferPtr = *strPtr; if (*inBuffer) { lua_pushstring(L, inBuffer); strPtr++; nbElmts--; } else { lua_pushnumber(L, keyIndex++); } for (;nbElmts > 0 && *strPtr <= 32; strPtr++, nbElmts--); if (*strPtr == '{') { int level = 1; int nbElmtsIn = 0; strPtr++; nbElmts--; while (level != 0 && nbElmts > 0) { if (*strPtr == '{') level++; if (*strPtr == '}') level--; strPtr++; nbElmts--; nbElmtsIn++; } ProcessTableRec(L, strPtr-nbElmtsIn, nbElmtsIn-1); } else { BOOL isNumber = true; memset(inBuffer, 0, sizeof(inBuffer)); inBufferPtr = inBuffer; for (inBufferPtr = inBuffer; nbElmts > 0 && *strPtr != ','; strPtr++, inBufferPtr++, nbElmts--) { if (*strPtr <= 32) continue; if ((*strPtr < '0' || *strPtr > '9') && *strPtr != '+' && *strPtr != '-' && *strPtr != '.' ) isNumber = false; *inBufferPtr = *strPtr; } *inBufferPtr = 0; if (isNumber) lua_pushnumber(L, (double)atof(inBuffer)); else lua_pushstring(L, inBuffer); } for (;*strPtr <= 32 && nbElmts > 0; strPtr++, nbElmts--); if (nbElmts > 0 && *strPtr == ',' ) { strPtr++; nbElmts--; } lua_settable(L, -3); } return 1; } int StringToTable(lua_State *L) { char *strPtr = (char *)lua_tostring(L, -1); int strLen = strlen(strPtr); if (*strPtr != '{' && strPtr[strLen-1] != '}') return 0; strPtr++; ProcessTableRec(L, strPtr, strLen-2); return 1; } /*********************** EVENT FUNCTIONS ***********************/ typedef struct { char name[512]; DWORD mode; int nbObject; int maxObject; ObjectEventInfo *object; } EventInfo; #define BASE_MAX_OBJECT 8 static BOOL IsEventListGlobal = 1; static BOOL IsEventListEmpty[MAX_SCRIPTS]; static EventInfo EventList[MAX_SCRIPTS][MAX_EVENT]; #define MAX_EVENT_EXEC 1024 static int nbEventsExec = 0; static int currentEvent = 0; static ObjectEventDatas EventsExec[MAX_EVENT_EXEC]; static UNIC_Dico objEventDico; void LuaEventAdd(EventInfo *EventListPtr, int eventNum, char* eventName, DWORD mode) { strcpy(EventListPtr[eventNum].name, eventName); EventListPtr[eventNum].mode = mode; EventListPtr[eventNum].nbObject = 0; EventListPtr[eventNum].maxObject = BASE_MAX_OBJECT; EventListPtr[eventNum].object = (ObjectEventInfo *)CC_malloc(EventListPtr[eventNum].maxObject*sizeof(ObjectEventInfo)); memset(EventListPtr[eventNum].object, 0, EventListPtr[eventNum].maxObject*sizeof(ObjectEventInfo)); } void LuaAddAllEvents(lua_State *L, EventInfo *EventListPtr) { #define LUA_EVENT_SET(a,m) LuaEventAdd(EventListPtr, EVT_##a, #a, m); #include "LuaEvents.h" } inline void LuaEventAddObject(EventInfo *EventListPtr, int eventNum, char *function, int *levels, int nbLevels) { if (!function) return; EventInfo *eventPtr = EventListPtr + eventNum; ObjectEventInfo *objectPtr; int functionLen; if (eventPtr->nbObject >= eventPtr->maxObject) { while (eventPtr->maxObject <= eventPtr->nbObject) eventPtr->maxObject *= 2; eventPtr->object = (ObjectEventInfo *)CC_realloc(eventPtr->object, eventPtr->maxObject*sizeof(ObjectEventInfo)); memset(eventPtr->object + eventPtr->nbObject, 0, (eventPtr->maxObject-eventPtr->nbObject)*sizeof(ObjectEventInfo)); } objectPtr = eventPtr->object + eventPtr->nbObject++; objectPtr->nbLevels = nbLevels; UnicID id; for (int i=0; i<=nbLevels; i++) { id = objEventDico.IsExist(function + levels[i]); if (id == -1) objEventDico.GetUnic(&id, function + levels[i]); objectPtr->objID[i] = id; } memcpy(objectPtr->levels, levels, (nbLevels+1)*sizeof(int)); memcpy(objectPtr->luaFunction, function, objectPtr->levels[objectPtr->nbLevels]); } void adressToString(u32 adress, char *buffer) { buffer[0] = ((adress >> 28) & 0xf) + 'A'; buffer[1] = ((adress >> 24) & 0xf) + 'A'; buffer[2] = ((adress >> 20) & 0xf) + 'A'; buffer[3] = ((adress >> 16) & 0xf) + 'A'; buffer[4] = ((adress >> 12) & 0xf) + 'A'; buffer[5] = ((adress >> 8) & 0xf) + 'A'; buffer[6] = ((adress >> 4) & 0xf) + 'A'; buffer[7] = ((adress >> 0) & 0xf) + 'A'; buffer[8] = 0; } void LuaPreProcessEvent(lua_State *L, EventInfo *EventListPtr, int nbLevels, int *levels, char *functionName, int len, char *name) { if (!L) return; static UNIC_Dico levelsDico; char adressStr[16]; if (nbLevels < 0) { char nameBuffer[1024]; *functionName = 0; if (name == NULL) strcpy(nameBuffer, "UI"); else strcpy(nameBuffer, name); lua_getglobal(L, nameBuffer); curLevel = 0; levelsDico.Init(); levelsDico.IsCaseSensitive = 1; LuaPreProcessEvent(L, EventListPtr, 0, levels, functionName, 0, nameBuffer); levelsDico.Destroy(); lua_pop(L, 1); return; } if (!lua_istable(L,-1)) return; adressToString((u32)lua_topointer(L, -1), adressStr); if (levelsDico.IsExist(adressStr) != -1) return; levelsDico.AddWord(adressStr); /* // Verify if event already done if (curLevel >= maxLevel) { maxLevel *= 2; levelsPtr = (void **)CC_realloc(levelsPtr, maxLevel*sizeof(void *)); #ifdef EVENT_CONFLICT levelsCharsPtr = (char **)CC_realloc(levelsCharsPtr, maxLevel*sizeof(char *)); #endif } levelsPtr[curLevel] = (void *)lua_topointer(L, -1); #ifdef EVENT_CONFLICT char buffer[1024]; memset(buffer, 0, sizeof(buffer)); memcpy(buffer, functionName, len); for (int i=0; i %s", levelsCharsPtr[lvlIdx], buffer); SaveDBGInfo(log); #endif break; } } if (levelsPtr[curLevel] == NULL) return; else curLevel++; #ifdef EVENT_CONFLICT levelsCharsPtr[curLevel-1] = strdup(buffer); #endif */ levels[nbLevels] = len; strcpy(functionName + len, name); len += strlen(functionName + len) + 1; nbLevels++; lua_pushnil(L); /* first key */ while (lua_next(L, -2) != 0) { /* uses 'key' (at index -2) and 'value' (at index -1) */ if (lua_isnumber(L, -2)) { lua_pop(L, 1); continue; } lua_pushvalue(L, -2); strcpy(name, (char *)lua_tostring(L,-1)); lua_pop(L, 1); LuaPreProcessEvent(L, EventListPtr, nbLevels, levels, functionName, len, name); lua_pop(L, 1); } for (int eventIdx=0; eventIdx= MAX_EVENT_EXEC) return; EventsExec[nbEventsExec++] = *datas; } inline BOOL PushLuaParents(lua_State *L, ObjectEventInfo *event) { int nbPtsIn = 0; lua_getglobal(L, event->luaFunction); if (lua_isnil(L, -1)) return false; for (int lev=1; levnbLevels; lev++) { lua_pushstring(L, event->luaFunction+event->levels[lev]); lua_gettable(L, -2); if (lua_isnil(L, -1)) return false; } nbPtsIn = event->nbLevels; while (nbPtsIn > 1) { lua_insert (L, -nbPtsIn--); } return true; } void WORLD::LuaEventsExec() { ObjectEventInfo *lastObject = NULL; ObjectEventInfo *objPtr; BOOL result = false; lua_State *luaScriptPtr = luaScriptTable[currentScript]; if (!luaScriptPtr) { nbEventsExec = 0; return; } START_RASTER(LUA_CALLS); if (WAIT_OBJECT_0 == WaitForSingleObject(ScriptAccesMutex, INFINITE)) { LUA_DEBUG_RASTER_STOP(); for (currentEvent=0; currentEventnbLevels == 0) continue; if (result && strcmp( lastObject->luaFunction + lastObject->levels[lastObject->nbLevels-1], objPtr->luaFunction + objPtr->levels[objPtr->nbLevels-1])) result = 0; if (result && (lastObject->levels[lastObject->nbLevels-1] > objPtr->levels[objPtr->nbLevels-1]) && !memcmp(lastObject->luaFunction, objPtr->luaFunction, objPtr->levels[objPtr->nbLevels-1])) continue; if (!PushLuaParents(luaScriptPtr, objPtr)) continue; #ifndef USER_MODE extern int mainThread; if (mainThread != GetCurrentThreadId()) MessageBox(NULL, "Bad Threard Access 6!", "YouUp", MB_OK | MB_ICONERROR); #endif if(debuggingLua) { lua_call(luaScriptPtr,objPtr->nbLevels-1,1); } else { if (lua_pcall(luaScriptPtr,objPtr->nbLevels-1,1,0) != 0) { char * luaRes = (char *)lua_tostring(luaScriptPtr, -1); if (luaRes) strcpy(LuaErrors, luaRes); else strcpy(LuaErrors, "LUA Unknown error (set debuggingLua to 1 in camcam.ccm !!)"); lua_pop(luaScriptPtr, 1); SaveDBGInfo(LuaErrors); STOP_RASTER(LUA_CALLS) ReleaseMutex(ScriptAccesMutex); nbEventsExec = 0; return; } } if (lua_isboolean(luaScriptPtr, -1)) { result = lua_toboolean(luaScriptPtr, -1); if (result) lastObject = objPtr; } else result = false; lua_pop(luaScriptPtr, 1); } LUA_DEBUG_RASTER_STOP(); STOP_RASTER(LUA_CALLS); ReleaseMutex(ScriptAccesMutex); nbEventsExec = 0; } if (updateEvent) { UpdateEvents(NULL); updateEvent = false; } } static char inScriptError[2048]; void FillScriptInfo(lua_State *L, int paramNum, int isError) { lua_Debug ar[64]; int nbLevels = 1; char *inScriptErrorPtr = inScriptError; lua_getstack(L, 0, &ar[0]); lua_getinfo(L, "n", &ar[0]); for (; nbLevels < 64 && lua_getstack(L, nbLevels, &ar[nbLevels]); nbLevels++) lua_getinfo(L, "lS", &ar[nbLevels]); for (nbLevels--; nbLevels > 1; nbLevels--) { sprintf(inScriptErrorPtr, "%s:%i\n", ar[nbLevels].short_src, ar[nbLevels].currentline); inScriptErrorPtr += strlen(inScriptErrorPtr); } if (isError) sprintf(inScriptErrorPtr, "%s:%i: bad argument #%i to '%s\'", ar[1].short_src, ar[1].currentline, paramNum, ar[0].name); else sprintf(inScriptErrorPtr, "%s:%i: function '%s\'", ar[1].short_src, ar[1].currentline, ar[0].name); } void HandleError(lua_State *L, int paramNum) { FillScriptInfo(L, paramNum, 1); lua_pushstring(L, inScriptError); lua_error(L); } bool PopBoolean(lua_State *L, int narg) { if (!lua_isboolean(L, narg)) HandleError(L, narg); return lua_toboolean(L, narg); } int PopInteger(lua_State *L, int narg) { lua_Integer d = lua_tointeger(L, narg); if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ HandleError(L, narg); return d; } double PopNumber(lua_State *L, int narg) { lua_Number d = lua_tonumber(L, narg); if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ HandleError(L, narg); return d; } const char *PopString(lua_State *L, int narg) { const char *s = lua_tolstring(L, narg, NULL); if (!s) HandleError(L, narg); return s; } //FillScriptInfo(L, 0, 0); \ /* #define DEFINE_SCRIPT_SPECIAL(scriptName, functionName, parameters, helpString) #define DEFINE_SCRIPT(a,params,Help,b) \ int WORLD::WSCRIPT_##a(lua_State *L) {int ParamsOk=1; int luaParam=1; int returnDone = 0; int luaArgs = lua_gettop(L); params; \ if (!ParamsOk) { HandleError(L, luaParam); return 0; } \ b; \ if (!returnDone) lua_pushnil(L); \ else if (returnDone > 1) \ { lua_newtable(L); for (int idx=0; idxWSCRIPT_##a(L); } #define DEFINE_SCRIPT_REN(n,a,params,Help,b) \ DEFINE_SCRIPT(n,params,Help,b) #include "Script_Commands.h" */ #define DEFINE_SCRIPT_SPECIAL(scriptName, functionName, parameters, helpString) #define DEFINE_SCRIPT(a,params,Help,b) \ int WORLD::WSCRIPT_##a(lua_State *L) {START_RASTER(LUA_SUB_CALLS); int ParamsOk=1; int luaParam=1; int returnDone = 0; int luaArgs = lua_gettop(L); params; \ if (!ParamsOk) { HandleError(L, luaParam); STOP_RASTER(LUA_SUB_CALLS); return 0; } \ b; \ if (!returnDone) lua_pushnil(L); STOP_RASTER(LUA_SUB_CALLS);\ return 1; } \ int SCRIPT_##a(lua_State *L) { return TheScene->WSCRIPT_##a(L); } #define DEFINE_SCRIPT_REN(n,a,params,Help,b) \ DEFINE_SCRIPT(n,params,Help,b) #ifdef ONLINE_MODE #define DEFINE_SCRIPT_ONLINE(a,params,Help,b,c) \ DEFINE_SCRIPT(a,params,Help,b) #else #define DEFINE_SCRIPT_ONLINE(a,params,Help,b,c) \ DEFINE_SCRIPT(a,params,Help,c) #endif #include "Script_Commands.h" int SCRIPT_SmallSceneNewMultiMaterial(lua_State *L) { return TheScene->SmallSceneNewMultiMaterial(L); } /************************ LUA SPECIFUC GENERIC ***********************************/ int SCRIPT_Xml2Lua(lua_State *L) { return TheScene->Xml2Lua(L, (char *)lua_tostring(L, 1)); } int SCRIPT_XmlFile2Lua(lua_State *L) { int result = 0; FILE * file = fopen(lua_tostring(L, 1), "rt"); if (file) { fseek(file, 0, SEEK_END); int size = ftell(file); fseek(file, 0, SEEK_SET); char *buffer = (char *)CC_malloc(size+1); if (buffer) { fread(buffer, size, 1, file); buffer[size] = 0; result = TheScene->Xml2Lua(L, buffer); CC_free(buffer); } fclose(file); } return result; } #ifndef SKIMMED_NET int SCRIPT_SendFlash(lua_State *L) { if (!lua_isstring(L, -1)) return 0; TheScene->FlashCom_Send((char *)lua_tostring(L, -1)); return 1; } #endif int SCRIPT_DoFile(lua_State *L) { char *filename = (char *)lua_tostring(L, -1); #ifdef USER_MODE char filenameX[1024]; sprintf(filenameX, "%sx", filename); filename = filenameX; BOOL IsFileAllowed(char *filename, bool fromLua); void displayIntegrityError(int num); /*// Check integrity of caller, if it is a registered file lua_Debug ar; lua_getstack(L, 1, &ar); lua_getinfo(L, "lS", &ar); if (!IsFileAllowed((char *)ar.source, 1)) { displayIntegrityError(2); lua_pushboolean(L, false); return 1; }*/ // New: check integrity of called file, if it is a registered file if (!IsFileAllowed(filename, 1)) { displayIntegrityError(3); lua_pushboolean(L, false); return 1; } #endif //USER_MODE FILE *fileF = CC_fopen(filename, "r"); UnicID ID; if (fileF) { CC_fclose(fileF); TheScene->luaLoaddedFilesDICO.GetUnic(&ID,(char *)lua_tostring(L, -1)); if (luaL_loadfile(L, (char *)lua_tostring(L, -1)) != 0) lua_error(L); lua_call(L, 0, LUA_MULTRET); lua_pushboolean(L, true); } else { lua_pushboolean(L, false); } return 1; } void FreeEvents(int scriptIndex) { if (IsEventListGlobal) { for (int evIdx=0; evIdxcurrentScript); LuaAddAllEvents(TheScene->luaScriptTable[TheScene->currentScript], EventList[TheScene->currentScript]); IsEventListEmpty[TheScene->currentScript] = 0; levelsPtr = (void **)CC_malloc(maxLevel*sizeof(void *)); #ifdef EVENT_CONFLICT levelsCharsPtr = (char **)CC_malloc(maxLevel*sizeof(char *)); #endif objEventDico.Init(); LuaPreProcessEvent( TheScene->luaScriptTable[TheScene->currentScript], EventList[TheScene->currentScript], -1, levels, luaFunction, 0, NULL); CC_free(levelsPtr); #ifdef EVENT_CONFLICT for (int i=0; icurrentScript][0].name) LuaAddAllEvents(L, EventList[TheScene->currentScript]); for (int Idx = 0; IdxcurrentScript][Idx].name, eventFunction)) { eventIndex = Idx; break; } } if (eventIndex == -1) { HandleError(L, 0); return 0; } LuaEventAddObject(EventList[TheScene->currentScript], eventIndex, eventNameLocal, eventLevelsTab, eventLevels); } lua_pop(L, 1); return 1; } int GetEventsData(lua_State *L) { if (currentEvent < nbEventsExec) { switch (EventsExec[currentEvent].type) { case EVENT_TYPE_MOUSE: PushMouseInfo(L, (MouseInfo *)EventsExec[currentEvent].data); break; case EVENT_TYPE_KEY: PushInt(L, *((int *)EventsExec[currentEvent].data)); break; case EVENT_TYPE_STRING: PushString(L, EventsExec[currentEvent].data); break; case EVENT_TYPE_SIZE: PushPoint(L, (POINT *)EventsExec[currentEvent].data); break; } } return 1; } BOOL WORLD::LuaSetLevel(int changeLevel) { nbEventsExec = 0; if (changeLevel < 0) { int newLevel = currentScript + changeLevel; if (newLevel >= 0) { for (int luaIdx = currentScript; luaIdx>newLevel; luaIdx--) { if (luaScriptTable[luaIdx]) { lua_State *luaScriptPtr = luaScriptTable[luaIdx]; luaScriptTable[luaIdx] = NULL; FreeEvents(luaIdx); lua_close(luaScriptPtr); } } currentScript = newLevel; return true; } return false; } if (changeLevel == 0) { for (int luaIdx=MAX_SCRIPTS-1; luaIdx >= 0; luaIdx--) { if (luaScriptTable[luaIdx]) { lua_State *luaScriptPtr = luaScriptTable[luaIdx]; luaScriptTable[luaIdx] = NULL; FreeEvents(luaIdx); lua_close(luaScriptPtr); } } currentScript = 0; return true; } if (changeLevel == 1) { if ((currentScript+1) < MAX_SCRIPTS) { currentScript++; if (luaScriptTable[currentScript]) { lua_State *luaScriptPtr = luaScriptTable[currentScript]; luaScriptTable[currentScript] = NULL; FreeEvents(currentScript); lua_close(luaScriptPtr); } return true; } return false; } return false; } int WORLD::LoadLua(char *filename, BOOL clearParams) { LUA_DEBUG_CLEAN(); if (WAIT_OBJECT_0 == WaitForSingleObject(ScriptAccesMutex, INFINITE)) { lua_State * lua_L; luaLoaddedFilesDICO.Destroy(); luaLoaddedFilesDICO.Init(); memset(LuaErrors, 0, sizeof(LuaErrors)); SceneScript_DESTROY(&SceneScript_Loop); if (clearParams == 1 || (currentScript == 0 && clearParams != 2)) { #ifdef ONLINE_MODE Account.logOut(); #endif LuaSetLevel(0); DestroyAllSMSC(); DestroyAllPGenerator(); DestroyAllMedia(); DestroyAllAnim(); DestroyTrackeur(); if (WSPC) WSPC_Destroy(WSPC); WSPC = NULL; u32 Counter = MAX_INIFILES; while (Counter--) IniFiles[Counter].Destroy(); IniFileDico.Destroy(); ulFullRefresh = true; } else if (luaScriptTable[currentScript] != NULL) { lua_close(luaScriptTable[currentScript]); luaScriptTable[currentScript] = NULL; } if (currentScript == 0) VirtuallyDestroyAllMedia(); nbEventsExec = 0; lua_L = lua_open(); luaL_openlibs(lua_L); #ifndef SKIMMED_NET luaopen_socket_core(lua_L); // socket register #endif Vector_Register(lua_L); VectorPtr_Register(lua_L); Quat_Register(lua_L); Matrix_Register(lua_L); #define DEFINE_SCRIPT_SPECIAL(scriptName, functionName, parameters, helpString) \ lua_register(lua_L,#scriptName,functionName); #define DEFINE_SCRIPT(a,params,Help,b) \ lua_register(lua_L,#a,SCRIPT_##a); #define DEFINE_SCRIPT_REN(n,a,params,Help,b) \ lua_register(lua_L,#a,SCRIPT_##n); \ lua_register(lua_L,#n,SCRIPT_##n); #define DEFINE_SCRIPT_ONLINE(a,params,Help,b,c) \ lua_register(lua_L,#a,SCRIPT_##a); #include "Script_Commands.h" #ifndef USER_MODE extern int mainThread; if (mainThread != GetCurrentThreadId()) MessageBox(NULL, "Bad Threard Access 7!", "YouUp", MB_OK | MB_ICONERROR); #endif if(debuggingLua) { luaScriptTable[currentScript] = lua_L; if(!luaL_loadfile(lua_L, filename)) lua_call(lua_L, 0, LUA_MULTRET); } else { luaScriptTable[currentScript] = lua_L; if(luaL_loadfile(lua_L, filename) || lua_pcall(lua_L, 0, LUA_MULTRET, 0)) { if (lua_tostring(lua_L, -1) != NULL) strcpy(LuaErrors, (char *)lua_tostring(lua_L, -1)); else strcpy(LuaErrors, "Error Openning LUA File"); SaveDBGInfo(LuaErrors); lua_close(lua_L); ReleaseMutex(ScriptAccesMutex); luaScriptTable[currentScript] = NULL; return 0; } } luaScriptTable[currentScript] = lua_L; UpdateEvents(NULL); ReleaseMutex(ScriptAccesMutex); } return 1; } int WORLD::LuaHandle(UINT message, WPARAM wParam, LPARAM lParam) { BOOL result = 0; ObjectEventDatas datas; if (luaScriptTable[currentScript] == NULL) return 0; if (bManualBoot && !oldManualBoot) return 0; switch (message) { case WM_MOUSEMOVE: case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_LBUTTONDBLCLK: case 0x020A: datas.type = EVENT_TYPE_MOUSE; ((MouseInfo *)datas.data)->x = (INT16)LOWORD(lParam); ((MouseInfo *)datas.data)->y = (INT16)HIWORD(lParam); ((MouseInfo *)datas.data)->keys = (INT16)LOWORD(wParam); ((MouseInfo *)datas.data)->value = (INT16)HIWORD(wParam); break; case WM_KEYUP: case WM_KEYDOWN: datas.type = EVENT_TYPE_KEY; *((int *)datas.data) = (int) wParam; break; case WM_DROPFILES: { HDROP hDropFiles = (HDROP)wParam; int nChar = 1 + DragQueryFile(hDropFiles,0,NULL,0); datas.type = EVENT_TYPE_STRING; if (nChar < 256) DragQueryFile(hDropFiles,0,datas.data,nChar); else *datas.data = 0; //DragFinish(hDropFiles); } break; case WM_SIZE: datas.type = EVENT_TYPE_SIZE; ((POINT *)datas.data)->x = (INT16)LOWORD(lParam); ((POINT *)datas.data)->y = (INT16)HIWORD(lParam); break; case WM_SIZING: datas.type = EVENT_TYPE_SIZE; ((POINT *)datas.data)->x = ((RECT *)lParam)->right - ((RECT *)lParam)->left; ((POINT *)datas.data)->y = ((RECT *)lParam)->bottom - ((RECT *)lParam)->top; break; } switch (message) { case WM_MOUSEMOVE: result = LuaProcessEventDatas(EVT_onMouseMove, &datas); break; case WM_LBUTTONDOWN: result = LuaProcessEventDatas(EVT_onPressOut, &datas) || LuaProcessEventDatas(EVT_onPress, &datas); PickReportClick = PickReportFinal; break; case WM_LBUTTONUP: result = LuaProcessEventDatas(EVT_onReleaseIn, &datas) || LuaProcessEventDatas(EVT_onReleaseOut, &datas) || LuaProcessEventDatas(EVT_onRelease, &datas); memset(&PickReportClick, 0, sizeof(PickReportClick)); break; case WM_RBUTTONDOWN: case WM_RBUTTONUP: memset(&PickReportClick, 0, sizeof(PickReportClick)); break; case WM_LBUTTONDBLCLK: LuaProcessEventDatas(EVT_onDoubleClick, &datas); result = 1; break; case 0x020A: if ((int) wParam < 0) result = LuaProcessEventDatas(EVT_onMouseWheelDown, &datas); else result = LuaProcessEventDatas(EVT_onMouseWheelUp, &datas); result = result || LuaProcessEventDatas(EVT_onMouseWheel, &datas); break; case WM_KEYDOWN: result = LuaProcessEventDatas(EVT_onKeyDown, &datas); break; case WM_KEYUP: result = LuaProcessEventDatas(EVT_onKeyUp, &datas); break; case WM_DROPFILES: result = LuaProcessEventDatas(EVT_onDropFiles, &datas); break; case WM_SIZE: case WM_SIZING: result = LuaProcessEventDatas(EVT_onWndSize, &datas); break; case WM_CLOSE: case WM_DESTROY: result = LuaProcessEventDatas(EVT_onExit, &datas); break; } return result; } inline int PickingClass(char *str, char *pickingStr, DWORD currentMask) { char *pickPtr; int maskPos = 0; int strLen = strlen(str); while ((pickPtr = strchr(pickingStr, '.')) != NULL) { if (!(currentMask & (1<nbLevels-1; lev++) { currentStr = event->luaFunction + event->levels[lev]; if ((maskIndex = PickingClass(currentStr, report->PickingClass, mask[0])) != -1) { mask[0] |= (1<CollidedSmallSceneName, mask[1])) != -1) { mask[1] |= (1<CollidedSmallSceneGameObjectName, mask[2])) != -1) { mask[2] |= (1<CollidedSmallMaterialName, mask[3])) != -1) { mask[3] |= (1<MediaName, mask[4])) != -1) { mask[4] |= (1<Nickname, mask[5])) != -1) { mask[5] |= (1<PickingClassNb = FillUIDString(PR->PickingClass, PRID->PickingClassId); PRID->CollidedSmallSceneNameNb = FillUIDString(PR->CollidedSmallSceneName, PRID->CollidedSmallSceneNameId); PRID->CollidedSmallSceneGameObjectNameNb= FillUIDString(PR->CollidedSmallSceneGameObjectName, PRID->CollidedSmallSceneGameObjectNameId); PRID->CollidedSmallMaterialNameNb = FillUIDString(PR->CollidedSmallMaterialName, PRID->CollidedSmallMaterialNameId); if (mediaPtr) { PRID->MediaNameNb = FillUIDString((char *)mediaPtr->MediaName, PRID->MediaNameId); PRID->NicknameNb = FillUIDString((char *)mediaPtr->Nickname, PRID->NicknameId); } else { PRID->MediaNameNb = -1; PRID->NicknameNb = -1; } } inline BOOL IsFunctionOnPickID(ObjectEventInfo *event, PickingReportUId *PRID) { UnicID *objID = event->objID+1; int testLvl = event->nbLevels - 2; int compSize= testLvl*sizeof(UnicID); if (PRID->PickingClassNb >= testLvl && !memcmp(PRID->PickingClassId, objID, compSize)) return true; if (PRID->CollidedSmallSceneNameNb >= testLvl && !memcmp(PRID->CollidedSmallSceneNameId, objID, compSize)) return true; if (PRID->CollidedSmallSceneGameObjectNameNb >= testLvl && !memcmp(PRID->CollidedSmallSceneGameObjectNameId, objID, compSize)) return true; if (PRID->CollidedSmallMaterialNameNb >= testLvl && !memcmp(PRID->CollidedSmallMaterialNameId, objID, compSize)) return true; if (PRID->MediaNameNb >= testLvl && !memcmp(PRID->MediaNameId, objID, compSize)) return true; if (PRID->NicknameNb >= testLvl && !memcmp(PRID->PickingClassId, objID, compSize)) return true; return false; } int WORLD::LuaProcessEventDatas(int eventNum, ObjectEventDatas *dataPtr) { DWORD mode = EventList[currentScript][eventNum].mode; BOOL verifyEqual = (mode >> LUA_MODE_DEC) & 1; BOOL mainTest = !((mode >> LUA_MAIN_TEST_DEC) & 1); BOOL process; ObjectEventInfo *objPtr; PickingReport *mainReport; PickingReportUId mainReportID; PickingReport *compReport; PickingReportUId compReportID; START_RASTER(Events); objPtr = EventList[currentScript][eventNum].object; switch(mode & 255) { case LUA_RESULT_PICK: mainReport = &PickReportResult; break; case LUA_FINAL_PICK: mainReport = &PickReportFinal; break; case LUA_PRESSED_PICK: mainReport = &PickReportClick; break; case LUA_TOWATCH_PICK: mainReport = &PickReportToWatch; break; default: mainReport = NULL; } switch((mode>>LUA_SRC_DEC) & 255) { case LUA_RESULT_PICK: compReport = &PickReportResult; break; case LUA_FINAL_PICK: compReport = &PickReportFinal; break; case LUA_PRESSED_PICK: compReport = &PickReportClick; break; case LUA_TOWATCH_PICK: compReport = &PickReportToWatch; break; default: compReport = NULL; } if (mainReport) FillPickReportID(mainReport, &mainReportID, GetMediaFromImage(mainReport->CollidedMap)); if (compReport) FillPickReportID(compReport, &compReportID, GetMediaFromImage(compReport->CollidedMap)); for (int objIdx=0; objIdxnbLevels <= 2); if (!process) { //for (int idx=0; idxnbLevels; idx++) //{ // if (!strcmp(objPtr->luaFunction+objPtr->levels[idx], "item3")) // { // int BreackPoint = 0; // } //} if (!mainReport) continue; //if (mainTest == IsFunctionOnPick(objPtr, mainReport, GetMediaFromImage(mainReport->CollidedMap))) if (mainTest == IsFunctionOnPickID(objPtr, &mainReportID)) { if (compReport) { //process = IsFunctionOnPick(objPtr, compReport, GetMediaFromImage(compReport->CollidedMap)) == verifyEqual; process = IsFunctionOnPickID(objPtr, &compReportID) == verifyEqual; } else process = 1; } } if (!process) continue; dataPtr->infoPtr = objPtr; AddEventExec(dataPtr); } STOP_RASTER(Events); return 0; } /***************************** XML LUA Parse **************************************/ #include "tinyxml.h" void XmlElmtCreate(lua_State *L, TiXmlElement *xmlElmt) { TiXmlAttribute *xmlAttr; TiXmlNode *xmlChildNode; int curIndex; lua_newtable(L); // xml node if (xmlElmt == NULL) return; lua_pushstring(L, "tag");// elmt name lua_pushstring(L, xmlElmt->Value()); lua_settable(L, -3); lua_pushstring(L, "attr");// elmt attr lua_newtable(L); for (xmlAttr = xmlElmt->FirstAttribute(), curIndex = 1; xmlAttr; xmlAttr = xmlAttr->Next()) { lua_pushnumber(L, curIndex++); lua_pushstring(L, xmlAttr->Name()); lua_settable(L, -3); lua_pushstring(L, xmlAttr->Name()); lua_pushstring(L, xmlAttr->Value()); lua_settable(L, -3); } lua_settable(L, -3); for (xmlChildNode = xmlElmt->FirstChild(), curIndex = 1; xmlChildNode; xmlChildNode = xmlChildNode->NextSibling()) { if (xmlChildNode->Type() == TiXmlNode::TEXT) { lua_pushnumber(L, curIndex++); lua_pushstring(L, xmlChildNode->Value()); lua_settable(L, -3); } else if (xmlChildNode->Type() == TiXmlNode::ELEMENT) { lua_pushnumber(L, curIndex++); XmlElmtCreate(L, (TiXmlElement *)xmlChildNode); lua_settable(L, -3); } } } BOOL XmlCreate(lua_State *L, char *xmlStr) { TiXmlDocument xmlDoc; TiXmlElement *xmlElmt; if (!xmlStr) return 0; xmlDoc.Parse(xmlStr); xmlElmt = xmlDoc.RootElement(); if (xmlElmt == NULL) return 0; XmlElmtCreate(L, xmlElmt); return 1; } BOOL WORLD::Xml2Lua(lua_State *L, char *buffer) { if (L && buffer) { char *xmlStr = (char *)buffer; if (XmlCreate(L, xmlStr)) return 1; } lua_pushnil(L); return 0; }