From 5088f33f95e17b6056663483afe7533431aec355 Mon Sep 17 00:00:00 2001 From: Darkclainer Date: Sun, 24 May 2020 15:46:08 +0300 Subject: [PATCH 1/3] Convert cp1251 to utf8 and replace CRLF with LF Be aware this can break something, I have no windows nor that IDE we used for unimod, nor I am using cpp now, so I can't test this changes. But using utf8 in sources (or at least in comments) is a standard now (I hope it is!). Whenever my eyes touches this repos my heart bleeding. I love unimod but WHAT IS GOING ON HERE?! I know we were young and stupid, but sources are so awfully treated, I have no doubt that whoever so this just cover her/his face with a hand and made huge sigh. I have used fd, iconv, and sed: fd -t file -E Libs -E bzip2 -e cpp -e md -e h -e txt | while read filename iconv -f cp1251 -t utf8 "$filename" | sed 's/\r$//g' > "../UniMod8/$filename" end --- SendBuffer.cpp | 8 +- UniMod.cpp | 50 +- Waypoints.cpp | 266 +- admin.cpp | 2488 +++++++------- audServer.cpp | 98 +- authManager.cpp | 1580 ++++----- autoServer.cpp | 270 +- bugsAndChips.cpp | 770 ++--- cliUtil.cpp | 866 ++--- clientView.cpp | 382 +-- console.cpp | 660 ++-- defs.cpp | 906 +++--- filesystem.cpp | 1194 +++---- fxBuff.cpp | 626 ++-- gui.cpp | Bin 21868 -> 21870 bytes imageUtil.cpp | 1058 +++--- keys.cpp | 358 +-- libVer.cpp | 844 ++--- lua/useful_objects_for_tower_defense.txt | 39 + ...1\204\320\265\320\275\321\201\320\260.txt" | 39 - map.cpp | 1010 +++--- mapUtil.cpp | 356 +-- net.cpp | 2608 +++++++-------- player.cpp | 868 ++--- player.h | 4 +- polygon.cpp | 218 +- react.cpp | 1282 ++++---- replays.cpp | 2260 ++++++------- score.cpp | 1796 +++++------ spelList.cpp | 1352 ++++---- spellGet.cpp | 1118 +++---- spells.cpp | 708 ++-- sprite.cpp | 150 +- stdafx.cpp | 16 +- stdafx.h | 724 ++--- tiles.cpp | 564 ++-- todo.txt | 164 +- unit.cpp | 790 ++--- unit.h | 2 +- unit2.cpp | 854 ++--- unitExternFunction.cpp | 2 +- util.cpp | 2848 ++++++++--------- windowMsg.cpp | 356 +-- windowUniMod.h | 286 +- windows.cpp | 2094 ++++++------ windowsUniModFunction.cpp | 90 +- 46 files changed, 17511 insertions(+), 17511 deletions(-) create mode 100644 lua/useful_objects_for_tower_defense.txt delete mode 100644 "lua/\320\277\320\276\320\273\320\265\320\267\320\275\321\213\320\265 \320\277\321\200\320\265\320\264\320\274\320\265\321\202\321\213 \320\264\320\273\321\217 \320\264\320\265\321\204\320\265\320\275\321\201\320\260.txt" diff --git a/SendBuffer.cpp b/SendBuffer.cpp index 838e397..da98491 100644 --- a/SendBuffer.cpp +++ b/SendBuffer.cpp @@ -1,5 +1,5 @@ -#include "stdafx.h" - -SendBuffer::SendBuffer() -{ +#include "stdafx.h" + +SendBuffer::SendBuffer() +{ } \ No newline at end of file diff --git a/UniMod.cpp b/UniMod.cpp index f141422..0436265 100644 --- a/UniMod.cpp +++ b/UniMod.cpp @@ -1,25 +1,25 @@ -// UniMod.cpp : Defines the entry point for the DLL application. -// - -#include "stdafx.h" - -lua_State *L=0; -extern void initModLib1(HMODULE hModule); - -BOOL APIENTRY DllMain( HMODULE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved - ) -{ - if (ul_reason_for_call== DLL_PROCESS_ATTACH) - { - initModLib1(hModule); - L=luaL_newstate(); - } - else if ( ul_reason_for_call== DLL_PROCESS_ATTACH) - { - lua_close(L); - } - return TRUE; -} - +// UniMod.cpp : Defines the entry point for the DLL application. +// + +#include "stdafx.h" + +lua_State *L=0; +extern void initModLib1(HMODULE hModule); + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + if (ul_reason_for_call== DLL_PROCESS_ATTACH) + { + initModLib1(hModule); + L=luaL_newstate(); + } + else if ( ul_reason_for_call== DLL_PROCESS_ATTACH) + { + lua_close(L); + } + return TRUE; +} + diff --git a/Waypoints.cpp b/Waypoints.cpp index dc4b74c..6ec79c3 100644 --- a/Waypoints.cpp +++ b/Waypoints.cpp @@ -1,134 +1,134 @@ -#include "stdafx.h" - -waypoint_s *(__cdecl *noxGetWaypointByName) (char const* Name); -waypoint_s *(__cdecl *noxGetWaypointById) (int Id); -waypoint_s *(__cdecl *noxCreateWaypoint) (float X,float Y); -waypoint_s *(__cdecl *noxWaypointNext) (void *Waypoint); -waypoint_s *(*noxGetWaypointList) (); - -namespace -{ - int createWaypointL(lua_State*L) - { - if ((lua_type(L,1)!=LUA_TNUMBER) || (lua_type(L,2)!=LUA_TNUMBER) || (lua_type(L,3)!=LUA_TSTRING)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - float X=lua_tonumber(L,1); float Y=lua_tonumber(L,2); - waypoint_s *P = noxCreateWaypoint(X,Y); - P->flag=P->Id; // - strncpy(P->Name,lua_tostring(L,3),strlen(lua_tostring(L,3))); - lua_pushlightuserdata(L,P); - return 1; - } - int getWaypointL(lua_State*L) - { - if (((lua_type(L,1)==LUA_TSTRING) || (lua_type(L,1)==LUA_TNUMBER)) && (lua_gettop(L)==1)) - { - waypoint_s *P=NULL; - if (lua_type(L,1)==LUA_TNUMBER) - P = noxGetWaypointById(lua_tointeger(L,1)); - else - P = noxGetWaypointByName(lua_tostring(L,1)); - if (P==NULL) - lua_pushnil(L); - else - lua_pushlightuserdata(L,P); - return 1; - } - else if ((lua_type(L,1)==LUA_TLIGHTUSERDATA) && (lua_toboolean(L,2))) - { - waypoint_s *P=(waypoint_s*) lua_touserdata(L,1); - lua_pushnumber(L,P->X); - lua_pushnumber(L,P->Y); - lua_pushnumber(L,P->Id); - lua_pushnumber(L,P->flag); - lua_pushstring(L,P->Name); - return 5; - } - else - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - return 0; - } - - int moveWaypointPosL(lua_State*L) - { - if ((lua_type(L,1)!=LUA_TLIGHTUSERDATA) || (lua_type(L,2)!=LUA_TNUMBER) || (lua_type(L,3)!=LUA_TNUMBER)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - waypoint_s *P = (waypoint_s *)lua_touserdata(L,1); - P->X=lua_tonumber(L,2); - P->Y=lua_tonumber(L,3); - return 1; - } - - - int setWaypointNameL(lua_State*L) - { - if ((lua_type(L,1)!=LUA_TLIGHTUSERDATA) || (lua_type(L,2)!=LUA_TSTRING)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - waypoint_s *P = (waypoint_s *) lua_touserdata(L,1); - strncpy(P->Name,lua_tostring(L,2),strlen(lua_tostring(L,2))); - return 1; - } -/* - int setWaypointFlagL(lua_State*L) - { - if ((lua_type(L,1)!=LUA_TLIGHTUSERDATA) || (lua_type(L,2)!=LUA_TNUMBER)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - waypoint_s *P = (waypoint_s *) lua_touserdata(L,1); - P->flag=lua_tonumber(L,2); - return 1; - } -*/ - int waypointListL(lua_State*L) - { - void *P=noxGetWaypointList(); - if (P==NULL) - { - lua_pushnil(L); - return 1; - } - lua_newtable(L); - int i=1; - while(P!=0) - { - lua_pushinteger(L,i++); - lua_pushlightuserdata(L,P); - lua_settable(L,-3); - P=noxWaypointNext(P); - } - return 1; - } -} - -void waypointsInit() -{ - ASSIGN(noxGetWaypointByName,0x00579E30); - ASSIGN(noxGetWaypointById,0x00579C40); - ASSIGN(noxCreateWaypoint,0x005798F0); - ASSIGN(noxWaypointNext,0x00579870); - ASSIGN(noxGetWaypointList,0x00579860); - - - - registerserver("waypointMove",&moveWaypointPosL); - registerserver("waypointGet",&getWaypointL); - registerserver("waypointSetName",&setWaypointNameL); - registerserver("waypointCreate",&createWaypointL); - //registerserver("waypointSetFlag",&setWaypointFlagL); - registerserver("waypointList",&waypointListL); - +#include "stdafx.h" + +waypoint_s *(__cdecl *noxGetWaypointByName) (char const* Name); +waypoint_s *(__cdecl *noxGetWaypointById) (int Id); +waypoint_s *(__cdecl *noxCreateWaypoint) (float X,float Y); +waypoint_s *(__cdecl *noxWaypointNext) (void *Waypoint); +waypoint_s *(*noxGetWaypointList) (); + +namespace +{ + int createWaypointL(lua_State*L) + { + if ((lua_type(L,1)!=LUA_TNUMBER) || (lua_type(L,2)!=LUA_TNUMBER) || (lua_type(L,3)!=LUA_TSTRING)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + float X=lua_tonumber(L,1); float Y=lua_tonumber(L,2); + waypoint_s *P = noxCreateWaypoint(X,Y); + P->flag=P->Id; //незнаю че это но пусть пока будет так + strncpy(P->Name,lua_tostring(L,3),strlen(lua_tostring(L,3))); + lua_pushlightuserdata(L,P); + return 1; + } + int getWaypointL(lua_State*L) + { + if (((lua_type(L,1)==LUA_TSTRING) || (lua_type(L,1)==LUA_TNUMBER)) && (lua_gettop(L)==1)) + { + waypoint_s *P=NULL; + if (lua_type(L,1)==LUA_TNUMBER) + P = noxGetWaypointById(lua_tointeger(L,1)); + else + P = noxGetWaypointByName(lua_tostring(L,1)); + if (P==NULL) + lua_pushnil(L); + else + lua_pushlightuserdata(L,P); + return 1; + } + else if ((lua_type(L,1)==LUA_TLIGHTUSERDATA) && (lua_toboolean(L,2))) + { + waypoint_s *P=(waypoint_s*) lua_touserdata(L,1); + lua_pushnumber(L,P->X); + lua_pushnumber(L,P->Y); + lua_pushnumber(L,P->Id); + lua_pushnumber(L,P->flag); + lua_pushstring(L,P->Name); + return 5; + } + else + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + return 0; + } + + int moveWaypointPosL(lua_State*L) + { + if ((lua_type(L,1)!=LUA_TLIGHTUSERDATA) || (lua_type(L,2)!=LUA_TNUMBER) || (lua_type(L,3)!=LUA_TNUMBER)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + waypoint_s *P = (waypoint_s *)lua_touserdata(L,1); + P->X=lua_tonumber(L,2); + P->Y=lua_tonumber(L,3); + return 1; + } + + + int setWaypointNameL(lua_State*L) + { + if ((lua_type(L,1)!=LUA_TLIGHTUSERDATA) || (lua_type(L,2)!=LUA_TSTRING)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + waypoint_s *P = (waypoint_s *) lua_touserdata(L,1); + strncpy(P->Name,lua_tostring(L,2),strlen(lua_tostring(L,2))); + return 1; + } +/* + int setWaypointFlagL(lua_State*L) + { + if ((lua_type(L,1)!=LUA_TLIGHTUSERDATA) || (lua_type(L,2)!=LUA_TNUMBER)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + waypoint_s *P = (waypoint_s *) lua_touserdata(L,1); + P->flag=lua_tonumber(L,2); + return 1; + } +*/ + int waypointListL(lua_State*L) + { + void *P=noxGetWaypointList(); + if (P==NULL) + { + lua_pushnil(L); + return 1; + } + lua_newtable(L); + int i=1; + while(P!=0) + { + lua_pushinteger(L,i++); + lua_pushlightuserdata(L,P); + lua_settable(L,-3); + P=noxWaypointNext(P); + } + return 1; + } +} + +void waypointsInit() +{ + ASSIGN(noxGetWaypointByName,0x00579E30); + ASSIGN(noxGetWaypointById,0x00579C40); + ASSIGN(noxCreateWaypoint,0x005798F0); + ASSIGN(noxWaypointNext,0x00579870); + ASSIGN(noxGetWaypointList,0x00579860); + + + + registerserver("waypointMove",&moveWaypointPosL); + registerserver("waypointGet",&getWaypointL); + registerserver("waypointSetName",&setWaypointNameL); + registerserver("waypointCreate",&createWaypointL); + //registerserver("waypointSetFlag",&setWaypointFlagL); + registerserver("waypointList",&waypointListL); + } \ No newline at end of file diff --git a/admin.cpp b/admin.cpp index 91663df..52f6ae6 100644 --- a/admin.cpp +++ b/admin.cpp @@ -1,1245 +1,1245 @@ -#include "stdafx.h" -#include "player.h" -#include "unit.h" -#include -#include -#include -#include -#include -//:004317B0 configLoad(const char*) -//00433290 configSave -extern void replayGuiUpdate(); -extern bool serverStart(int port); -extern void serverClose(); -extern char *(__cdecl *mapGetName)(); -extern DWORD *GameFlags; -extern void tputs(int s,const char *S); -extern int tprintf(int s,const char *Format,...); -extern void send_headers(int f, int status, char *title, char *extra, char *mime, - int length, time_t date); -extern void send_error(int f, int status, char *title, char *extra, char *text); - -void (__cdecl *guiServerOptionsStartGameMB)(); -int (__cdecl *playerKickByIdx)(int playerIdx, int unknownArg); -void (__cdecl *consoleServerMapLoad)(int spaceNumber, int tokensNumber, void* tokens); -int (__cdecl *mapLoadFromFile)(void* mapName); -void *(__cdecl *serverGetGameData)(int N); -void *(__cdecl *serverGetGameDataBySel)(); -int (__cdecl *serverModeIndexByModeFlags)(DWORD Flags); -short *serverLessonLimitArr=0; -byte *serverTimeLimitArr=0; -int *serverInfoChanged; -//__int16 *serverModeChange; -int *mapLoadData; -int (__cdecl *mapLoadFlags)(void* mapLoadData); -void *(__cdecl *serverBanGetList)(); -void (__cdecl *serverBanRemove)(int N); -time_t (__cdecl *_time)(time_t *N); - -void *(__cdecl *memListNext)(void *Item); -void *(__cdecl *noxMapCycleNext)(); -void *(__cdecl *mapLoadName)(char* mapName); -bool (__cdecl *noxMapCycleEnabledCheck)(); -int (__cdecl *loadCfg)(char* fileName, int arg2); -int (__cdecl *saveCfg)(char* fileName); -int (__cdecl *loadBanList)(char* fileName); -int (__cdecl *saveBanList)(char* fileName); -void (__cdecl *flushBanList)(void* ptr); -void (__cdecl *playerGoObserver)(void* playerPtr, byte unk1, byte unk2); - -bool mapNextSameForced=false; -char nextMapOverride[0x16]={0}; -bool isNewGame=false; - -extern void teamCreateDefault(int TeamNumParam, bool notRestrict=false); -extern void httpGetCallback(lua_State *L); - - -//extern unsigned __stdcall httpAuth(void *Data1); - -void *(__cdecl *getConfigData)(); - -extern byte authorisedState[0x20]; -extern char* authorisedLogins[0x20]; -DWORD* currentIP; -unsigned __int16 *currentPort; -extern void AuthProcess(); -extern void updateAuthDBProcess(); - -extern bool specialAuthorisation; - -using namespace std; -char authSendWelcomeMsg[0x20]; - - - - -vector mapCycleCurrentList; -__int16 mapCycleLastModeId; -int mapCycleCurrentPosition; - -extern void netVersionServerRq(int sendTo); - -extern int clientsVersions[0x20]; - -extern void autoexecCli(); - -bool serverRequest(int f,char *path) -{ - int Top=lua_gettop(L); - char *P=0,*E=0,*Cmd=0; - char *Con=NULL; - P=strchr(path,'?'); - if (P==NULL) - { - return false; - } - bool access=false; - lua_getfield(L,LUA_REGISTRYINDEX,"serverFn"); - for (P=strtok_s(P+1,"&",&Con);P!=NULL;P=strtok_s(NULL,"&",&Con)) - { - E=strchr(P,'='); - if (E==NULL) - continue; - if (strncmp(P,"p",E-P)==0) - { - lua_getfield(L,LUA_REGISTRYINDEX,"serverPass"); - if (lua_isnil(L,-1)) - access=true; - else - access=(0==strcmp(lua_tostring(L,-1),E+1)); - lua_pop(L,1); - } - if (strncmp(P,"r",E-P)==0) - { - Cmd=E+1; - } - } - if (Cmd!=NULL) - { - if (!access) - { - const char WrongPass[]="Access denied"; - send_headers(f,403,"/",NULL,"text/plain",strlen(WrongPass),0); - tputs(f,WrongPass); - lua_settop(L,Top); - return true; - } - lua_pushstring(L,Cmd); - if (0!=lua_pcall(L,1,1,0)) - { - TString S; - S="{'err':'"; - S.append(lua_tostring(L,-1)); - S.append("'}"); - send_headers(f,500,"/",NULL,"application/json",S.size(),0); - tputs(f,S.c_str()); - } - else - { - send_headers(f,200,"/",NULL,"application/json",lua_objlen(L,-1),0); - tputs(f,lua_tostring(L,-1)); - } - } - lua_settop(L,Top); - return true; -} -bool needToFormGame=false; - -void doFormGame() -{ - int Top=lua_gettop(L); - bool sameMap = false; - bool dontUseGUIFunc = false; - bool newGame=false; - - lua_getfield(L,LUA_REGISTRYINDEX,"formGameTable"); - if (lua_type(L,Top+1)==LUA_TTABLE) - { - lua_getfield(L,Top+1,"new"); - if (lua_type(L,-1)!=LUA_TNIL) - { - if (0!=lua_toboolean(L,-1)) - { - newGame=true; - } - } - ServerData *Data=(ServerData*)serverGetGameDataBySel(); - strncpy(Data->mapName, mapGetName(),0x8); - Data->gameFlags=(__int16)*GameFlags; - //__int16 GameFlagsTruncated = (__int16)*GameFlags; - //memcpy(Data->fragLimit,GameFlagsTruncated,0x2); - //Data->fragLimit=(__int16)mapCurrentFragLimit((__int16)*GameFlags); - //Data->timeLimitMB=(__int16)mapCurrentTimeLimit((__int16)*GameFlags); - lua_getfield(L,Top+1,"map"); - if (lua_type(L,-1)!=LUA_TNIL) - { - char Buf[16]={0}; - strncpy(Buf,lua_tostring(L,-1),16); - char *P; - P=strstr(Buf,".map"); - if (P!=NULL) - { - *P=0; - } - lua_getfield(L,Top+1,"reload"); - if(strcmp(Buf,mapGetName())==0 && (lua_type(L,-1)!=LUA_TNIL && 0!=lua_toboolean(L,-1))) - { - strncpy(Data->mapName,mapGetName(),8); - sameMap=true; - } - else - { - strncpy(Data->mapName,Buf,8); - sameMap=false; - } - if(strcmp(Buf,mapGetName())==0) - { - dontUseGUIFunc=true; - } - } - else - { - lua_getfield(L,Top+1,"reload"); - if(lua_type(L,-1)!=LUA_TNIL && 0!=lua_toboolean(L,-1)) - { - strncpy(Data->mapName,mapGetName(),8); - sameMap=true; - } - dontUseGUIFunc=true; - } - if(mapLoadFromFile((void*)&Data->mapName)) - { - __int16 availableMode=(__int16)mapLoadFlags(mapLoadData); - lua_getfield(L,Top+1,"mode"); - const char *Mode=lua_tostring(L,-1); - int Index=0; - if (Mode!=NULL) - { - bool modeSet=false; - if (0==strcmpi(Mode,"ctf") && (availableMode&0x20)) - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x20; - modeSet=true; - } - else if (0==strcmpi(Mode,"kotr") && (availableMode&0x10)) - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x10; - modeSet=true; - } - else if ((0==strcmpi(Mode,"highlander") || 0==strcmpi(Mode,"elimination")) && (availableMode&0x400)) - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x400; - modeSet=true; - } - else if ((0==strcmpi(Mode,"gameball") || 0==strcmpi(Mode,"flagball")) && (availableMode&0x40)) - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x40; - modeSet=true; - } - /*else if (0==strcmpi(Mode,"quest")) - { - Data->gameFlags=0x3007; - }*/// , . ... - else if (0==strcmpi(Mode,"arena") && (availableMode&0x100)) - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x100;//arena - modeSet=true; - } - else - { - __int16 currentGameFlags=(__int16)*GameFlags&0x1FF0; - if(availableMode¤tGameFlags) // - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|currentGameFlags; - } - else if(availableMode&0x100) //arena - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x100; - } - else if(availableMode&0x20) //ctf - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x20; - } - else if(availableMode&0x40) //flagball - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x40; - } - else if(availableMode&0x80) //chat - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x80; - } - else if(availableMode&0x400) //elim - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x400; - } - else if(availableMode&0x10) //kotr - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x10; - } - else // - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|currentGameFlags; - } - } - //*serverModeChange=*serverModeChange&0x0E80; - //*serverModeChange=*serverModeChange&Data->gameFlags; - if(modeSet==true && strcmp(Data->mapName,mapGetName())==0) - { - sameMap=true; - } - } - else if(newGame==false) - { - __int16 currentGameFlags=(__int16)*GameFlags&0x1FF0; - if(availableMode¤tGameFlags) // - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|currentGameFlags; - } - else if(availableMode&0x100) //arena - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x100; - } - else if(availableMode&0x20) //ctf - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x20; - } - else if(availableMode&0x40) //flagball - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x40; - } - else if(availableMode&0x80) //chat - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x80; - } - else if(availableMode&0x400) //elim - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x400; - } - else if(availableMode&0x10) //kotr - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x10; - } - else // - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|currentGameFlags; - } - } - - if (newGame==true) - { - - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x80; - if(*GameFlags&0x80) - { - Data->isNew=0; - } - else - Data->isNew=1; - dontUseGUIFunc=false; - if(strcmp(Data->mapName,mapGetName())==0 && availableMode&0x80) - sameMap=true; - //*serverModeChange=*serverModeChange&0x0E80; - //*serverModeChange=*serverModeChange&Data->gameFlags; - } - Index=serverModeIndexByModeFlags(Data->gameFlags); - lua_getfield(L,Top+1,"fraglimit"); - if (lua_type(L,-1)!=LUA_TNIL) - { - Data->fragLimit=lua_tointeger(L,-1); - serverLessonLimitArr[Index]=Data->fragLimit; - *serverInfoChanged=1; - } - - lua_getfield(L,Top+1,"timelimit"); - if (lua_type(L,-1)!=LUA_TNIL) - { - Data->timeLimitMB=lua_tointeger(L,-1); - serverTimeLimitArr[Index]=Data->timeLimitMB; - *serverInfoChanged=1; - } - - - lua_pushnil(L); - lua_setfield(L,LUA_REGISTRYINDEX,"formGameTable"); - - if(mapLoadFlags(mapLoadData)&0x60 && newGame==false) - { - teamCreateDefault(2); - } - else - { - teamCreateDefault(-1); - } - if(sameMap) - { - wchar_t command[5] = L"load"; - wchar_t wMapName[9]={0}; - int *commandPointer=(int*)&command; - int *wMapNamePointer=(int*)&wMapName; - MultiByteToWideChar(CP_ACP, MB_COMPOSITE, Data->mapName, 8, wMapName, 9); - BYTE result[8]={0}; - memcpy(&result[0], &commandPointer, 4); - memcpy(&result[4], &wMapNamePointer, 4); - consoleServerMapLoad(1, 2, (void*)&result); - } - else if(dontUseGUIFunc==false) - { - guiServerOptionsStartGameMB(); - } - } - } - lua_settop(L,Top); -} - - -namespace -{ - vector mapCycleFormListMode(__int16 modeId) - { - string mode; - vector formedMapcycle; - switch(modeId) - { - case 0x80: - mode="[chat]"; - break; - case 0x100: - mode="[deathmatch]"; - break; - case 0x400: - mode="[elimination]"; - break; - case 0x20: - mode="[capture the flag]"; - break; - case 0x40: - mode="[flagball]"; - break; - case 0x10: - mode="[king of the realm]"; - break; - default: - mode="[other]"; - break; - } - ifstream file("mapcycle.txt", ios::in | ios::binary); - if(file.is_open()) - { - file.seekg(0, ios::end); - size_t filesize=file.tellg(); - file.seekg(0, ios::beg); - char searchMode=0; - string fileLine; - while(searchMode<2) - { - getline(file, fileLine); - if(!file.eof()) - { - if(fileLine.size()>0 && fileLine[fileLine.size()-1]=='\r') - fileLine.erase((fileLine.size()-1), 1); // CR . - if(fileLine.size()<=0) // . - { - continue; - } - transform(fileLine.begin(), fileLine.end(), fileLine.begin(), tolower); - if(searchMode==1 && fileLine[0]!='[') - { - fileLine = fileLine.substr(0,13); // .map 13 . . - size_t mapLoc = fileLine.rfind(".map"); - if(mapLoc!=std::string::npos) - fileLine = fileLine.substr(0, mapLoc); // .map. : my.map.m! , - my.map.m.map. . - fileLine = fileLine.substr(0,8); // .map 8 . . - if(mapLoadFromFile((char*)fileLine.c_str()) && mapLoadFlags(mapLoadData)&modeId) // , ... ! - { - fileLine.append(".map"); // .map. - formedMapcycle.push_back(fileLine); // - } - } - else if(searchMode==1) // mode- - { - searchMode++; - break; - } - if(searchMode==0 && fileLine.compare(mode)==0) // , ! ... - searchMode++; - } - else // , - { - searchMode=2; - break; - } - } - } - return formedMapcycle; - } - - void* mapCycleNext() - { - __int16 currentMode = ((__int16)*GameFlags)&0x1FF0; - int nextPosition=mapCycleCurrentPosition+1; - if(currentMode!=mapCycleLastModeId || mapCycleCurrentList.size()<=nextPosition) // , - - { - mapCycleLastModeId=currentMode; - mapCycleCurrentList=mapCycleFormListMode(mapCycleLastModeId); - nextPosition=0; - } - - if(mapCycleCurrentList.size()<=nextPosition) // - , - - { - char* ret = new char[13]; - strcpy(ret, mapGetName()); - strcat(ret, ".map"); - return ret; - } - mapCycleCurrentPosition=nextPosition; // - return (void*)mapCycleCurrentList[nextPosition].c_str(); - // 327 , ... - } - - - int formGame(lua_State *L) - { - lua_settop(L,1); - if (lua_type(L,1)==LUA_TSTRING) - { - lua_newtable(L); - lua_pushvalue(L,1); - lua_setfield(L,-2,"map"); - lua_remove(L,1); - } - if (lua_type(L,1)!=LUA_TTABLE) - { - lua_newtable(L); - lua_pushboolean(L,true); - lua_setfield(L,-2,"reload"); - lua_remove(L,1); - } - if(lua_type(L,1)==LUA_TTABLE) - { - lua_getfield(L,1,"mapcycle"); - if(lua_type(L, -1)!=LUA_TNIL && lua_toboolean(L,-1)!=0) - { - lua_pushstring(L, (char*)mapCycleNext()); - lua_setfield(L, 1, "map"); - } - lua_pop(L,1); - } - lua_setfield(L,LUA_REGISTRYINDEX,"formGameTable"); - needToFormGame=true; - return 0; - } - - - int loadCfgL(lua_State *L) - { - loadCfg("nox.cfg", 1); - return 1; - } - - int saveCfgL(lua_State *L) - { - saveCfg("nox.cfg"); - return 1; - } - - int saveBanListL(lua_State *L) - { - saveBanList("ban.txt"); - return 1; - } - - int loadBanListL(lua_State *L) - { - loadBanList("ban.txt"); - return 1; - } - - int flushBanListL(lua_State *L) - { - flushBanList((void*)0x62F038); - flushBanList((void*)0x62F0C0); - return 1; - } - - int reloadBanListL(lua_State *L) - { - flushBanListL(L); - loadBanList("ban.txt"); - return 1; - } - - int formNextGame(lua_State *L) - { - lua_settop(L,1); - if (lua_type(L,1)==LUA_TSTRING) - { - lua_newtable(L); - lua_pushvalue(L,1); - lua_setfield(L,-2,"map"); - lua_remove(L,1); - } - if (lua_type(L,1)==LUA_TTABLE) - { - lua_getfield(L,1,"disable"); - if (lua_type(L,-1)!=LUA_TNIL) - { - if (0!=lua_toboolean(L,-1)) - { - lua_pushnil(L); - lua_setfield(L,LUA_REGISTRYINDEX,"formNextGameTable"); - return 0; - } - } - lua_remove(L,-1); - } - if (lua_type(L,1)!=LUA_TTABLE) - { - lua_newtable(L); - lua_pushboolean(L,true); - lua_setfield(L,-2,"reload"); - lua_remove(L,1); - } - lua_setfield(L,LUA_REGISTRYINDEX,"formNextGameTable"); - return 0; - } - - bool __cdecl onMapCycleEnabledCheck() - { - lua_getfield(L,LUA_REGISTRYINDEX,"formNextGameTable"); - if (lua_type(L,-1)==LUA_TTABLE) - { - return true; - } - else - return noxMapCycleEnabledCheck(); - } - - void* __cdecl onLoadMapCycle() - { - if(mapNextSameForced) - { - mapNextSameForced=false; - return nextMapOverride; - } - int Top=lua_gettop(L); - bool sameMap = false; - //bool dontUseGUIFunc = false; - bool newGame=false; - void *result=NULL; - lua_getfield(L,LUA_REGISTRYINDEX,"formNextGameTable"); - if (lua_type(L,Top+1)==LUA_TTABLE) - { - lua_getfield(L,Top+1,"new"); - if (lua_type(L,-1)!=LUA_TNIL) - { - if (0!=lua_toboolean(L,-1)) - { - newGame=true; - } - } - ServerData *Data=(ServerData*)serverGetGameDataBySel(); - strncpy(Data->mapName, mapGetName(),0x8); - Data->gameFlags=(__int16)*GameFlags; - //__int16 GameFlagsTruncated = (__int16)*GameFlags; - //memcpy(Data->fragLimit,GameFlagsTruncated,0x2); - //Data->fragLimit=(__int16)mapCurrentFragLimit((__int16)*GameFlags); - //Data->timeLimitMB=(__int16)mapCurrentTimeLimit((__int16)*GameFlags); - lua_getfield(L,Top+1,"map"); - if (lua_type(L,-1)!=LUA_TNIL) - { - char Buf[16]={0}; - strncpy(Buf,lua_tostring(L,-1),16); - char *P; - P=strstr(Buf,".map"); - if (P!=NULL) - { - *P=0; - } - lua_getfield(L,Top+1,"reload"); - if(strcmp(Buf,mapGetName())==0 && (lua_type(L,-1)!=LUA_TNIL && 0!=lua_toboolean(L,-1))) - { - strncpy(Data->mapName,mapGetName(),8); - sameMap=true; - } - else - { - strncpy(Data->mapName,Buf,8); - sameMap=false; - } - if(strcmp(Buf,mapGetName())==0) - { - sameMap=true; - } - } - else - { - lua_getfield(L,Top+1,"reload"); - if(lua_type(L,-1)!=LUA_TNIL && 0!=lua_toboolean(L,-1)) - { - strncpy(Data->mapName,mapGetName(),8); - sameMap=true; - } - //sameMap=true; - } - if(mapLoadFromFile((void*)&Data->mapName)) - { - __int16 availableMode=(__int16)mapLoadFlags(mapLoadData); - lua_getfield(L,Top+1,"mode"); - const char *Mode=lua_tostring(L,-1); - int Index=0; - if (Mode!=NULL) - { - bool modeSet=false; - if (0==strcmpi(Mode,"ctf") && (availableMode&0x20)) - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x20; - modeSet=true; - } - else if (0==strcmpi(Mode,"kotr") && (availableMode&0x10)) - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x10; - modeSet=true; - } - else if ((0==strcmpi(Mode,"highlander") || 0==strcmpi(Mode,"elimination")) && (availableMode&0x400)) - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x400; - modeSet=true; - } - else if ((0==strcmpi(Mode,"gameball") || 0==strcmpi(Mode,"flagball")) && (availableMode&0x40)) - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x40; - modeSet=true; - } - /*else if (0==strcmpi(Mode,"quest")) - { - Data->gameFlags=0x3007; - }*/// , . ... - else if (0==strcmpi(Mode,"arena") && (availableMode&0x100)) - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x100;//arena - modeSet=true; - } - else - { - __int16 currentGameFlags=(__int16)*GameFlags&0x1FF0; - if(availableMode¤tGameFlags) // - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|currentGameFlags; - } - else if(availableMode&0x100) //arena - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x100; - } - else if(availableMode&0x20) //ctf - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x20; - } - else if(availableMode&0x40) //flagball - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x40; - } - else if(availableMode&0x80) //chat - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x80; - } - else if(availableMode&0x400) //elim - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x400; - } - else if(availableMode&0x10) //kotr - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x10; - } - else // - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|currentGameFlags; - } - } - //*serverModeChange=*serverModeChange&0x0E80; - //*serverModeChange=*serverModeChange&Data->gameFlags; - if(modeSet==true && strcmp(Data->mapName,mapGetName())==0) - { - sameMap=true; - } - } - else if(newGame==false) - { - __int16 currentGameFlags=(__int16)*GameFlags&0x1FF0; - if(availableMode¤tGameFlags) // - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|currentGameFlags; - } - else if(availableMode&0x100) //arena - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x100; - } - else if(availableMode&0x20) //ctf - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x20; - } - else if(availableMode&0x40) //flagball - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x40; - } - else if(availableMode&0x80) //chat - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x80; - } - else if(availableMode&0x400) //elim - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x400; - } - else if(availableMode&0x10) //kotr - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x10; - } - else // - { - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|currentGameFlags; - } - } - - if (newGame==true) - { - - Data->gameFlags=Data->gameFlags&0xE00F; - Data->gameFlags=Data->gameFlags|0x80; - if(*GameFlags&0x80) - { - Data->isNew=0; - } - else - Data->isNew=1; - //sameMap=false; - isNewGame=true; - if(strcmp(Data->mapName,mapGetName())==0 && availableMode&0x80) - sameMap=true; - //*serverModeChange=*serverModeChange&0x0E80; - //*serverModeChange=*serverModeChange&Data->gameFlags; - } - Index=serverModeIndexByModeFlags(Data->gameFlags); - lua_getfield(L,Top+1,"fraglimit"); - if (lua_type(L,-1)!=LUA_TNIL) - { - Data->fragLimit=lua_tointeger(L,-1); - serverLessonLimitArr[Index]=Data->fragLimit; - *serverInfoChanged=1; - } - - lua_getfield(L,Top+1,"timelimit"); - if (lua_type(L,-1)!=LUA_TNIL) - { - Data->timeLimitMB=lua_tointeger(L,-1); - serverTimeLimitArr[Index]=Data->timeLimitMB; - *serverInfoChanged=1; - } - - - lua_pushnil(L); - lua_setfield(L,LUA_REGISTRYINDEX,"formNextGameTable"); - - if(mapLoadFlags(mapLoadData)&0x60 && newGame==false) - { - teamCreateDefault(2); - } - else - { - teamCreateDefault(-1); - } - /*if(sameMap) - { - wchar_t command[5] = L"load"; - wchar_t wMapName[9]={0}; - int *commandPointer=(int*)&command; - int *wMapNamePointer=(int*)&wMapName; - MultiByteToWideChar(CP_ACP, MB_COMPOSITE, Data->mapName, 8, wMapName, 9); - BYTE result[8]={0}; - memcpy(&result[0], &commandPointer, 4); - memcpy(&result[4], &wMapNamePointer, 4); - consoleServerMapLoad(1, 2, (void*)&result); - } - else if(dontUseGUIFunc==false) - { - guiServerOptionsStartGameMB(); - }*/ - nextMapOverride[0]='\0'; - strcpy(nextMapOverride, Data->mapName); - strcat(nextMapOverride, ".map"); - result=nextMapOverride; - if(sameMap) - mapNextSameForced=true; - } - else - { - if(noxMapCycleEnabledCheck()) - result=mapCycleNext(); - else - { - mapNextSameForced=true; - return onLoadMapCycle(); - } - - } - } - else - { - if(noxMapCycleEnabledCheck()) - result=mapCycleNext(); - else - { - mapNextSameForced=true; - return onLoadMapCycle(); - } - } - lua_settop(L,Top); - return result; - } - - void onMapLoadName(char* mapName) - { - if(isNewGame) - { - isNewGame=false; - guiServerOptionsStartGameMB(); - } - else - mapLoadName(mapName); - } - - - int banGetList(lua_State *L) - { - lua_createtable(L,5,0); - void *Ptr=serverBanGetList(); - for (int i=1;Ptr!=NULL;Ptr=memListNext(Ptr),i++) - { - char Buf[0x40]={0}; - wcstombs(Buf,((wchar_t*)Ptr)+0x6,0x24-0x6); - lua_pushstring(L,Buf); - lua_rawseti(L,-2,i); - } - return 1; - } - int banRemove(lua_State *L) - { - lua_settop(L,1); - if (lua_type(L,1)==LUA_TSTRING) - { - void *Ptr=serverBanGetList(); - for (int i=0;Ptr!=NULL;Ptr=memListNext(Ptr),i++) - { - char Buf[0x40]={0}; - wcstombs(Buf,((wchar_t*)Ptr)+0x6,0x24-0x6); - if (0==strcmp(Buf,lua_tostring(L,1))) - { - serverBanRemove(i); - return 0; - } - - } - } - else if (lua_type(L,1)==LUA_TNUMBER) - { - serverBanRemove(lua_tointeger(L,1)); - } - else - { - lua_pushstring(L,"wrong args - not a team!"); - lua_error_(L); - } - return 0; - } - - int playerKickUData(lua_State *L) - { - lua_settop(L,1); - if ( - (lua_type(L,1)!=LUA_TLIGHTUSERDATA) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - DWORD *DW=(DWORD*)lua_touserdata(L,1); - if (0==(DW[2] & 0x4)) - { - lua_pushstring(L,"wrong args: unit is not a player!"); - lua_error_(L); - } - void **PP=(void **)(((char*)lua_touserdata(L,1))+0x2EC); - PP=(void**)(((char*)*PP)+0x114); - byte *P=(byte*)(*PP); - byte playerIdx = *((byte*)(P+0x810)); - if(playerIdx==0x1F) - { - lua_pushstring(L,"can't kick the hoster!"); - lua_error_(L); - } - playerKickByIdx((int)playerIdx, 4); - return 0; - } - - int httpServerL(lua_State *L) - { - lua_settop(L,2); - serverClose(); - if (lua_type(L,1)!=LUA_TNIL) - { - int R=serverStart(lua_tointeger(L,1))?1:0; - lua_pushvalue(L,2); - lua_setfield(L,LUA_REGISTRYINDEX,"serverPass"); - - lua_pushboolean(L,R); - } - else - lua_pushboolean(L,0); - return 1; - } - void (__cdecl*guiUpdate)(); - - time_t onEndGame(time_t *TimePtr) - { - int Top=lua_gettop(L); - getServerVar("onEndGame"); - if (!lua_isfunction(L,-1)) - return _time(TimePtr); - lua_pcall(L,0,0,0); - lua_settop(L,Top); - return _time(TimePtr); - } - - void* __cdecl onServerStart() - { - for(byte i=0; i<0x20; i++) - { - authorisedState[i]=0; - if(authorisedLogins[i]!=0 && strcmp(authorisedLogins[i], "")!=0) - delete [] authorisedLogins[i]; - authorisedLogins[i]=""; - authSendWelcomeMsg[i]=0; - } - mapCycleLastModeId=((__int16)*GameFlags)&0x1FF0; - mapCycleCurrentPosition=0; - return getConfigData(); - } - - void __cdecl OnGuiUpdate() - { - autoexecCli(); - guiUpdate(); - httpGetCallback(L); - updateAuthDBProcess(); - if (needToFormGame) - { - needToFormGame=false; - doFormGame(); - } - replayGuiUpdate(); - /*if(replayViewFormGameRequest) - { - replayViewFormGameRequest=false; - replayViewFormGame(); - }*/ - } - - void* onPlayerLeave(byte Index) - { - playerInfoStruct *result = playerGetDataFromIndex(Index); - if(*GameFlags&0x800) - {} - else - { - authorisedState[Index]=0; - if(strcmp(authorisedLogins[Index], "")!=0) - delete [] authorisedLogins[Index]; - authorisedLogins[Index]=""; - clientsVersions[Index]=0; - int Top=lua_gettop(L); - getServerVar("playerOnLeave"); - if (lua_isfunction(L,-1)) - { - bigUnitStruct *Player = getPlayerUDataFromPlayerInfo(result); - lua_pushlightuserdata(L,Player); - if (0!=lua_pcall(L,1,0,0)) - conPrintI(lua_tostring(L,-1)); - } - lua_settop(L,Top); - } - return result; - } - - void* onPlayerJoin(int Index) - { - clientsVersions[Index]=0; - playerInfoStruct *result=playerGetDataFromIndex(Index); - if(Index!=0x1F && specialAuthorisation==true) - { - authorisedState[(byte)Index]=0; // ... (c) Evengard - authorisedLogins[(byte)Index]=""; - playerGoObserver(result, 1, 1); - authSendWelcomeMsg[Index]=30; - - netVersionServerRq(Index); - } - return result; - } - -} -extern "C" void adminInit(lua_State *L); -extern void authInit(lua_State *L); -extern void InjectOffs(DWORD Addr,void *Fn); - -void adminInit(lua_State *L) -{ - ASSIGN(guiServerOptionsStartGameMB,0x00459150); - ASSIGN(serverGetGameData,0x00416590); - ASSIGN(serverGetGameDataBySel,0x004165B0); - ASSIGN(serverBanGetList,0x00416900); - ASSIGN(serverBanRemove,0x00416820); - ASSIGN(memListNext,0x00416910); - ASSIGN(guiUpdate,0x0046B740); - ASSIGN(serverModeIndexByModeFlags,0x00409A70); - ASSIGN(serverLessonLimitArr,0x005D5334); - ASSIGN(serverTimeLimitArr,0x005D5340); - ASSIGN(serverInfoChanged,0x005D5360); - //ASSIGN(serverModeChange,0x0062F0B6); - ASSIGN(consoleServerMapLoad,0x00441910); - ASSIGN(mapLoadFromFile,0x004CFE10);// - ASSIGN(mapLoadName,0x00409D70);// - - ASSIGN(mapLoadData, 0x00974880);// mapLoadFromFile - ASSIGN(mapLoadFlags, 0x004CFFA0);// - ASSIGN(noxMapCycleNext, 0x004D0CF0); - ASSIGN(_time,0x00566BD3); - ASSIGN(noxMapCycleEnabledCheck, 0x004D0D70); - ASSIGN(loadCfg, 0x004317B0); - ASSIGN(saveCfg, 0x00433290); - ASSIGN(loadBanList, 0x004E41B0); - ASSIGN(saveBanList, 0x004E43F0); - ASSIGN(flushBanList, 0x00425760); - ASSIGN(getConfigData, 0x00416640); - ASSIGN(playerGoObserver,0x004E6860); - ASSIGN(currentIP,0x0097EBC4); - ASSIGN(currentPort,0x0097EBC8); - ASSIGN(playerKickByIdx,0x004DEAB0); - - InjectOffs(0x004D280B+1,&onMapCycleEnabledCheck); // . formNextGame - InjectOffs(0x0043E333+1,&OnGuiUpdate); - InjectOffs(0x00413D37+1,&onEndGame); - InjectOffs(0x004D281D+1,&onLoadMapCycle); // - InjectOffs(0x004D283F+1,&onLoadMapCycle); // - InjectOffs(0x004D284F+1,&onMapLoadName); // new=1 formNextGame ( ) - InjectOffs(0x0043AAB9+1,&onServerStart); //Server startup hook - - InjectOffs(0x004DE55E+1,&onPlayerLeave); // - - InjectOffs(0x004DDF6C+1,&onPlayerJoin); // - - - int Top=lua_gettop(L); - if (0!=luaL_loadstring(L, - "local json=require('json'); " - "local f=loadstring; " - "return function (s) " - "s=string.gsub(s,'%%(%x%x)',function (v) return string.char('0x'..v) end); " - "local r=f(s); " - "setfenv(r,getfenv(1)) " - "return json.encode( r() ) end; ")) - { - MessageBox(0,lua_tostring(L,-1),0,0); - luaL_loadstring(L,""); - } - else - { - if (0==lua_pcall(L,0,1,0)) - { - } - else - { - MessageBox(0,lua_tostring(L,-1),0,0); - luaL_loadstring(L,""); - } - } - lua_getfield(L,LUA_REGISTRYINDEX,"server"); - lua_setfenv(L,-2); - lua_setfield(L,LUA_REGISTRYINDEX,"serverFn"); - if (0!=luaL_loadstring(L, - "return function (s) " - "local r=s; " - "setfenv(r,getfenv(1)) " - "return json.encode( r() ) end; ")) - { - MessageBox(0,lua_tostring(L,-1),0,0); - luaL_loadstring(L,""); - } - else - { - if (0==lua_pcall(L,0,1,0)) - { - } - else - { - MessageBox(0,lua_tostring(L,-1),0,0); - luaL_loadstring(L,""); - } - } - lua_getfield(L,LUA_REGISTRYINDEX,"server"); - lua_setfenv(L,-2); - lua_setfield(L,LUA_REGISTRYINDEX,"serverFnSysop"); - registerserver("httpServer",&httpServerL); - registerserver("formGame",&formGame); - registerserver("formNextGame",&formNextGame); - registerserver("banList",&banGetList); - registerserver("banRemove",&banRemove); - registerserver("loadCfg",&loadCfgL); - registerserver("saveCfg",&saveCfgL); - registerserver("loadBanList",&loadBanListL); - registerserver("saveBanList",&saveBanListL); - registerserver("reloadBanList",&reloadBanListL); - registerserver("flushBanList",&flushBanListL); - registerserver("playerKickUData",&playerKickUData); - - authInit(L); - //strcpy((char*)0x005AFA20, "So_Forum"); // - "" - lua_settop(L,Top); +#include "stdafx.h" +#include "player.h" +#include "unit.h" +#include +#include +#include +#include +#include +//:004317B0 configLoad(const char*) +//00433290 configSave +extern void replayGuiUpdate(); +extern bool serverStart(int port); +extern void serverClose(); +extern char *(__cdecl *mapGetName)(); +extern DWORD *GameFlags; +extern void tputs(int s,const char *S); +extern int tprintf(int s,const char *Format,...); +extern void send_headers(int f, int status, char *title, char *extra, char *mime, + int length, time_t date); +extern void send_error(int f, int status, char *title, char *extra, char *text); + +void (__cdecl *guiServerOptionsStartGameMB)(); +int (__cdecl *playerKickByIdx)(int playerIdx, int unknownArg); +void (__cdecl *consoleServerMapLoad)(int spaceNumber, int tokensNumber, void* tokens); +int (__cdecl *mapLoadFromFile)(void* mapName); +void *(__cdecl *serverGetGameData)(int N); +void *(__cdecl *serverGetGameDataBySel)(); +int (__cdecl *serverModeIndexByModeFlags)(DWORD Flags); +short *serverLessonLimitArr=0; +byte *serverTimeLimitArr=0; +int *serverInfoChanged; +//__int16 *serverModeChange; +int *mapLoadData; +int (__cdecl *mapLoadFlags)(void* mapLoadData); +void *(__cdecl *serverBanGetList)(); +void (__cdecl *serverBanRemove)(int N); +time_t (__cdecl *_time)(time_t *N); + +void *(__cdecl *memListNext)(void *Item); +void *(__cdecl *noxMapCycleNext)(); +void *(__cdecl *mapLoadName)(char* mapName); +bool (__cdecl *noxMapCycleEnabledCheck)(); +int (__cdecl *loadCfg)(char* fileName, int arg2); +int (__cdecl *saveCfg)(char* fileName); +int (__cdecl *loadBanList)(char* fileName); +int (__cdecl *saveBanList)(char* fileName); +void (__cdecl *flushBanList)(void* ptr); +void (__cdecl *playerGoObserver)(void* playerPtr, byte unk1, byte unk2); + +bool mapNextSameForced=false; +char nextMapOverride[0x16]={0}; +bool isNewGame=false; + +extern void teamCreateDefault(int TeamNumParam, bool notRestrict=false); +extern void httpGetCallback(lua_State *L); + + +//extern unsigned __stdcall httpAuth(void *Data1); + +void *(__cdecl *getConfigData)(); + +extern byte authorisedState[0x20]; +extern char* authorisedLogins[0x20]; +DWORD* currentIP; +unsigned __int16 *currentPort; +extern void AuthProcess(); +extern void updateAuthDBProcess(); + +extern bool specialAuthorisation; + +using namespace std; +char authSendWelcomeMsg[0x20]; + + + + +vector mapCycleCurrentList; +__int16 mapCycleLastModeId; +int mapCycleCurrentPosition; + +extern void netVersionServerRq(int sendTo); + +extern int clientsVersions[0x20]; + +extern void autoexecCli(); + +bool serverRequest(int f,char *path) +{ + int Top=lua_gettop(L); + char *P=0,*E=0,*Cmd=0; + char *Con=NULL; + P=strchr(path,'?'); + if (P==NULL) + { + return false; + } + bool access=false; + lua_getfield(L,LUA_REGISTRYINDEX,"serverFn"); + for (P=strtok_s(P+1,"&",&Con);P!=NULL;P=strtok_s(NULL,"&",&Con)) + { + E=strchr(P,'='); + if (E==NULL) + continue; + if (strncmp(P,"p",E-P)==0) + { + lua_getfield(L,LUA_REGISTRYINDEX,"serverPass"); + if (lua_isnil(L,-1)) + access=true; + else + access=(0==strcmp(lua_tostring(L,-1),E+1)); + lua_pop(L,1); + } + if (strncmp(P,"r",E-P)==0) + { + Cmd=E+1; + } + } + if (Cmd!=NULL) + { + if (!access) + { + const char WrongPass[]="Access denied"; + send_headers(f,403,"/",NULL,"text/plain",strlen(WrongPass),0); + tputs(f,WrongPass); + lua_settop(L,Top); + return true; + } + lua_pushstring(L,Cmd); + if (0!=lua_pcall(L,1,1,0)) + { + TString S; + S="{'err':'"; + S.append(lua_tostring(L,-1)); + S.append("'}"); + send_headers(f,500,"/",NULL,"application/json",S.size(),0); + tputs(f,S.c_str()); + } + else + { + send_headers(f,200,"/",NULL,"application/json",lua_objlen(L,-1),0); + tputs(f,lua_tostring(L,-1)); + } + } + lua_settop(L,Top); + return true; +} +bool needToFormGame=false; + +void doFormGame() +{ + int Top=lua_gettop(L); + bool sameMap = false; + bool dontUseGUIFunc = false; + bool newGame=false; + + lua_getfield(L,LUA_REGISTRYINDEX,"formGameTable"); + if (lua_type(L,Top+1)==LUA_TTABLE) + { + lua_getfield(L,Top+1,"new"); + if (lua_type(L,-1)!=LUA_TNIL) + { + if (0!=lua_toboolean(L,-1)) + { + newGame=true; + } + } + ServerData *Data=(ServerData*)serverGetGameDataBySel(); + strncpy(Data->mapName, mapGetName(),0x8); + Data->gameFlags=(__int16)*GameFlags; + //__int16 GameFlagsTruncated = (__int16)*GameFlags; + //memcpy(Data->fragLimit,GameFlagsTruncated,0x2); + //Data->fragLimit=(__int16)mapCurrentFragLimit((__int16)*GameFlags); + //Data->timeLimitMB=(__int16)mapCurrentTimeLimit((__int16)*GameFlags); + lua_getfield(L,Top+1,"map"); + if (lua_type(L,-1)!=LUA_TNIL) + { + char Buf[16]={0}; + strncpy(Buf,lua_tostring(L,-1),16); + char *P; + P=strstr(Buf,".map"); + if (P!=NULL) + { + *P=0; + } + lua_getfield(L,Top+1,"reload"); + if(strcmp(Buf,mapGetName())==0 && (lua_type(L,-1)!=LUA_TNIL && 0!=lua_toboolean(L,-1))) + { + strncpy(Data->mapName,mapGetName(),8); + sameMap=true; + } + else + { + strncpy(Data->mapName,Buf,8); + sameMap=false; + } + if(strcmp(Buf,mapGetName())==0) + { + dontUseGUIFunc=true; + } + } + else + { + lua_getfield(L,Top+1,"reload"); + if(lua_type(L,-1)!=LUA_TNIL && 0!=lua_toboolean(L,-1)) + { + strncpy(Data->mapName,mapGetName(),8); + sameMap=true; + } + dontUseGUIFunc=true; + } + if(mapLoadFromFile((void*)&Data->mapName)) + { + __int16 availableMode=(__int16)mapLoadFlags(mapLoadData); + lua_getfield(L,Top+1,"mode"); + const char *Mode=lua_tostring(L,-1); + int Index=0; + if (Mode!=NULL) + { + bool modeSet=false; + if (0==strcmpi(Mode,"ctf") && (availableMode&0x20)) + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x20; + modeSet=true; + } + else if (0==strcmpi(Mode,"kotr") && (availableMode&0x10)) + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x10; + modeSet=true; + } + else if ((0==strcmpi(Mode,"highlander") || 0==strcmpi(Mode,"elimination")) && (availableMode&0x400)) + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x400; + modeSet=true; + } + else if ((0==strcmpi(Mode,"gameball") || 0==strcmpi(Mode,"flagball")) && (availableMode&0x40)) + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x40; + modeSet=true; + } + /*else if (0==strcmpi(Mode,"quest")) + { + Data->gameFlags=0x3007; + }*///От греха, а то грузить напрямую слишком бажно. Лучше уж полностью сервак с нуля пересоздавать... + else if (0==strcmpi(Mode,"arena") && (availableMode&0x100)) + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x100;//arena + modeSet=true; + } + else + { + __int16 currentGameFlags=(__int16)*GameFlags&0x1FF0; + if(availableMode¤tGameFlags) //Если игра поддерживает текущий режим игры + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|currentGameFlags; + } + else if(availableMode&0x100) //arena + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x100; + } + else if(availableMode&0x20) //ctf + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x20; + } + else if(availableMode&0x40) //flagball + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x40; + } + else if(availableMode&0x80) //chat + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x80; + } + else if(availableMode&0x400) //elim + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x400; + } + else if(availableMode&0x10) //kotr + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x10; + } + else //Все остальные пробуем загрузить с текущими флагами + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|currentGameFlags; + } + } + //*serverModeChange=*serverModeChange&0x0E80; + //*serverModeChange=*serverModeChange&Data->gameFlags; + if(modeSet==true && strcmp(Data->mapName,mapGetName())==0) + { + sameMap=true; + } + } + else if(newGame==false) + { + __int16 currentGameFlags=(__int16)*GameFlags&0x1FF0; + if(availableMode¤tGameFlags) //Если игра поддерживает текущий режим игры + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|currentGameFlags; + } + else if(availableMode&0x100) //arena + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x100; + } + else if(availableMode&0x20) //ctf + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x20; + } + else if(availableMode&0x40) //flagball + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x40; + } + else if(availableMode&0x80) //chat + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x80; + } + else if(availableMode&0x400) //elim + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x400; + } + else if(availableMode&0x10) //kotr + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x10; + } + else //Все остальные пробуем загрузить с текущими флагами + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|currentGameFlags; + } + } + + if (newGame==true) + { + + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x80; + if(*GameFlags&0x80) + { + Data->isNew=0; + } + else + Data->isNew=1; + dontUseGUIFunc=false; + if(strcmp(Data->mapName,mapGetName())==0 && availableMode&0x80) + sameMap=true; + //*serverModeChange=*serverModeChange&0x0E80; + //*serverModeChange=*serverModeChange&Data->gameFlags; + } + Index=serverModeIndexByModeFlags(Data->gameFlags); + lua_getfield(L,Top+1,"fraglimit"); + if (lua_type(L,-1)!=LUA_TNIL) + { + Data->fragLimit=lua_tointeger(L,-1); + serverLessonLimitArr[Index]=Data->fragLimit; + *serverInfoChanged=1; + } + + lua_getfield(L,Top+1,"timelimit"); + if (lua_type(L,-1)!=LUA_TNIL) + { + Data->timeLimitMB=lua_tointeger(L,-1); + serverTimeLimitArr[Index]=Data->timeLimitMB; + *serverInfoChanged=1; + } + + + lua_pushnil(L); + lua_setfield(L,LUA_REGISTRYINDEX,"formGameTable"); + + if(mapLoadFlags(mapLoadData)&0x60 && newGame==false) + { + teamCreateDefault(2); + } + else + { + teamCreateDefault(-1); + } + if(sameMap) + { + wchar_t command[5] = L"load"; + wchar_t wMapName[9]={0}; + int *commandPointer=(int*)&command; + int *wMapNamePointer=(int*)&wMapName; + MultiByteToWideChar(CP_ACP, MB_COMPOSITE, Data->mapName, 8, wMapName, 9); + BYTE result[8]={0}; + memcpy(&result[0], &commandPointer, 4); + memcpy(&result[4], &wMapNamePointer, 4); + consoleServerMapLoad(1, 2, (void*)&result); + } + else if(dontUseGUIFunc==false) + { + guiServerOptionsStartGameMB(); + } + } + } + lua_settop(L,Top); +} + + +namespace +{ + vector mapCycleFormListMode(__int16 modeId) + { + string mode; + vector formedMapcycle; + switch(modeId) + { + case 0x80: + mode="[chat]"; + break; + case 0x100: + mode="[deathmatch]"; + break; + case 0x400: + mode="[elimination]"; + break; + case 0x20: + mode="[capture the flag]"; + break; + case 0x40: + mode="[flagball]"; + break; + case 0x10: + mode="[king of the realm]"; + break; + default: + mode="[other]"; + break; + } + ifstream file("mapcycle.txt", ios::in | ios::binary); + if(file.is_open()) + { + file.seekg(0, ios::end); + size_t filesize=file.tellg(); + file.seekg(0, ios::beg); + char searchMode=0; + string fileLine; + while(searchMode<2) + { + getline(file, fileLine); + if(!file.eof()) + { + if(fileLine.size()>0 && fileLine[fileLine.size()-1]=='\r') + fileLine.erase((fileLine.size()-1), 1); // Тут мы CR удаляем. Тот самый атавизм со времён печатных машинок + if(fileLine.size()<=0) //Пустая строчка нам не нужна. + { + continue; + } + transform(fileLine.begin(), fileLine.end(), fileLine.begin(), tolower); + if(searchMode==1 && fileLine[0]!='[') + { + fileLine = fileLine.substr(0,13); // Вместе с .map может быть только 13 символов максимум. Отрезаем всё лишнее. + size_t mapLoc = fileLine.rfind(".map"); + if(mapLoc!=std::string::npos) + fileLine = fileLine.substr(0, mapLoc); // Отрезаем .map. Не именуйте плз карты так: my.map.m! Ну или не прописывайте их в таком виде в мапцикл, а прописывайте по старинке с расширением - my.map.m.map. А не то не загрузится. + fileLine = fileLine.substr(0,8); // А без .map может быть только 8 символов. Опять таки отрезаем лишнее. + if(mapLoadFromFile((char*)fileLine.c_str()) && mapLoadFlags(mapLoadData)&modeId) // Проверка, а валидный ли это вообще файл карты... И нужного ли режима! + { + fileLine.append(".map"); // Аппендим обратно .map. Требуется для собственно загрузчика карт мапцикла + formedMapcycle.push_back(fileLine); // Загоняем в список + } + } + else if(searchMode==1) // Сюда мы падаем только если мы достигли следующего mode-а + { + searchMode++; + break; + } + if(searchMode==0 && fileLine.compare(mode)==0) // Ура, мы нашли наш режим игры! Переходим в режим скана названий мап... + searchMode++; + } + else // Файло кончилось, что получилось то и получилось + { + searchMode=2; + break; + } + } + } + return formedMapcycle; + } + + void* mapCycleNext() + { + __int16 currentMode = ((__int16)*GameFlags)&0x1FF0; + int nextPosition=mapCycleCurrentPosition+1; + if(currentMode!=mapCycleLastModeId || mapCycleCurrentList.size()<=nextPosition) // Если мы достигли конца предварительно сгенеренного списка из файла мапцикла, или же режим игры сменился - перегенерим список мапцикла для текущего режима игры из файла + { + mapCycleLastModeId=currentMode; + mapCycleCurrentList=mapCycleFormListMode(mapCycleLastModeId); + nextPosition=0; + } + + if(mapCycleCurrentList.size()<=nextPosition) // Если несмотря на перегенерирование списка мапцикла мы всё равно достигли его конца - ну чтож, начит мапцикл невалиден - возвращаем текущую карту и умываем руки + { + char* ret = new char[13]; + strcpy(ret, mapGetName()); + strcat(ret, ".map"); + return ret; + } + mapCycleCurrentPosition=nextPosition; // Фиксируем текущий индекс позиции + return (void*)mapCycleCurrentList[nextPosition].c_str(); + // А ведь раньше тут был мегаиндийский код аж на 327 строк, не считая объявлений переменных выше... + } + + + int formGame(lua_State *L) + { + lua_settop(L,1); + if (lua_type(L,1)==LUA_TSTRING) + { + lua_newtable(L); + lua_pushvalue(L,1); + lua_setfield(L,-2,"map"); + lua_remove(L,1); + } + if (lua_type(L,1)!=LUA_TTABLE) + { + lua_newtable(L); + lua_pushboolean(L,true); + lua_setfield(L,-2,"reload"); + lua_remove(L,1); + } + if(lua_type(L,1)==LUA_TTABLE) + { + lua_getfield(L,1,"mapcycle"); + if(lua_type(L, -1)!=LUA_TNIL && lua_toboolean(L,-1)!=0) + { + lua_pushstring(L, (char*)mapCycleNext()); + lua_setfield(L, 1, "map"); + } + lua_pop(L,1); + } + lua_setfield(L,LUA_REGISTRYINDEX,"formGameTable"); + needToFormGame=true; + return 0; + } + + + int loadCfgL(lua_State *L) + { + loadCfg("nox.cfg", 1); + return 1; + } + + int saveCfgL(lua_State *L) + { + saveCfg("nox.cfg"); + return 1; + } + + int saveBanListL(lua_State *L) + { + saveBanList("ban.txt"); + return 1; + } + + int loadBanListL(lua_State *L) + { + loadBanList("ban.txt"); + return 1; + } + + int flushBanListL(lua_State *L) + { + flushBanList((void*)0x62F038); + flushBanList((void*)0x62F0C0); + return 1; + } + + int reloadBanListL(lua_State *L) + { + flushBanListL(L); + loadBanList("ban.txt"); + return 1; + } + + int formNextGame(lua_State *L) + { + lua_settop(L,1); + if (lua_type(L,1)==LUA_TSTRING) + { + lua_newtable(L); + lua_pushvalue(L,1); + lua_setfield(L,-2,"map"); + lua_remove(L,1); + } + if (lua_type(L,1)==LUA_TTABLE) + { + lua_getfield(L,1,"disable"); + if (lua_type(L,-1)!=LUA_TNIL) + { + if (0!=lua_toboolean(L,-1)) + { + lua_pushnil(L); + lua_setfield(L,LUA_REGISTRYINDEX,"formNextGameTable"); + return 0; + } + } + lua_remove(L,-1); + } + if (lua_type(L,1)!=LUA_TTABLE) + { + lua_newtable(L); + lua_pushboolean(L,true); + lua_setfield(L,-2,"reload"); + lua_remove(L,1); + } + lua_setfield(L,LUA_REGISTRYINDEX,"formNextGameTable"); + return 0; + } + + bool __cdecl onMapCycleEnabledCheck() + { + lua_getfield(L,LUA_REGISTRYINDEX,"formNextGameTable"); + if (lua_type(L,-1)==LUA_TTABLE) + { + return true; + } + else + return noxMapCycleEnabledCheck(); + } + + void* __cdecl onLoadMapCycle() + { + if(mapNextSameForced) + { + mapNextSameForced=false; + return nextMapOverride; + } + int Top=lua_gettop(L); + bool sameMap = false; + //bool dontUseGUIFunc = false; + bool newGame=false; + void *result=NULL; + lua_getfield(L,LUA_REGISTRYINDEX,"formNextGameTable"); + if (lua_type(L,Top+1)==LUA_TTABLE) + { + lua_getfield(L,Top+1,"new"); + if (lua_type(L,-1)!=LUA_TNIL) + { + if (0!=lua_toboolean(L,-1)) + { + newGame=true; + } + } + ServerData *Data=(ServerData*)serverGetGameDataBySel(); + strncpy(Data->mapName, mapGetName(),0x8); + Data->gameFlags=(__int16)*GameFlags; + //__int16 GameFlagsTruncated = (__int16)*GameFlags; + //memcpy(Data->fragLimit,GameFlagsTruncated,0x2); + //Data->fragLimit=(__int16)mapCurrentFragLimit((__int16)*GameFlags); + //Data->timeLimitMB=(__int16)mapCurrentTimeLimit((__int16)*GameFlags); + lua_getfield(L,Top+1,"map"); + if (lua_type(L,-1)!=LUA_TNIL) + { + char Buf[16]={0}; + strncpy(Buf,lua_tostring(L,-1),16); + char *P; + P=strstr(Buf,".map"); + if (P!=NULL) + { + *P=0; + } + lua_getfield(L,Top+1,"reload"); + if(strcmp(Buf,mapGetName())==0 && (lua_type(L,-1)!=LUA_TNIL && 0!=lua_toboolean(L,-1))) + { + strncpy(Data->mapName,mapGetName(),8); + sameMap=true; + } + else + { + strncpy(Data->mapName,Buf,8); + sameMap=false; + } + if(strcmp(Buf,mapGetName())==0) + { + sameMap=true; + } + } + else + { + lua_getfield(L,Top+1,"reload"); + if(lua_type(L,-1)!=LUA_TNIL && 0!=lua_toboolean(L,-1)) + { + strncpy(Data->mapName,mapGetName(),8); + sameMap=true; + } + //sameMap=true; + } + if(mapLoadFromFile((void*)&Data->mapName)) + { + __int16 availableMode=(__int16)mapLoadFlags(mapLoadData); + lua_getfield(L,Top+1,"mode"); + const char *Mode=lua_tostring(L,-1); + int Index=0; + if (Mode!=NULL) + { + bool modeSet=false; + if (0==strcmpi(Mode,"ctf") && (availableMode&0x20)) + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x20; + modeSet=true; + } + else if (0==strcmpi(Mode,"kotr") && (availableMode&0x10)) + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x10; + modeSet=true; + } + else if ((0==strcmpi(Mode,"highlander") || 0==strcmpi(Mode,"elimination")) && (availableMode&0x400)) + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x400; + modeSet=true; + } + else if ((0==strcmpi(Mode,"gameball") || 0==strcmpi(Mode,"flagball")) && (availableMode&0x40)) + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x40; + modeSet=true; + } + /*else if (0==strcmpi(Mode,"quest")) + { + Data->gameFlags=0x3007; + }*///От греха, а то грузить напрямую слишком бажно. Лучше уж полностью сервак с нуля пересоздавать... + else if (0==strcmpi(Mode,"arena") && (availableMode&0x100)) + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x100;//arena + modeSet=true; + } + else + { + __int16 currentGameFlags=(__int16)*GameFlags&0x1FF0; + if(availableMode¤tGameFlags) //Если игра поддерживает текущий режим игры + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|currentGameFlags; + } + else if(availableMode&0x100) //arena + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x100; + } + else if(availableMode&0x20) //ctf + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x20; + } + else if(availableMode&0x40) //flagball + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x40; + } + else if(availableMode&0x80) //chat + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x80; + } + else if(availableMode&0x400) //elim + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x400; + } + else if(availableMode&0x10) //kotr + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x10; + } + else //Все остальные пробуем загрузить с текущими флагами + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|currentGameFlags; + } + } + //*serverModeChange=*serverModeChange&0x0E80; + //*serverModeChange=*serverModeChange&Data->gameFlags; + if(modeSet==true && strcmp(Data->mapName,mapGetName())==0) + { + sameMap=true; + } + } + else if(newGame==false) + { + __int16 currentGameFlags=(__int16)*GameFlags&0x1FF0; + if(availableMode¤tGameFlags) //Если игра поддерживает текущий режим игры + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|currentGameFlags; + } + else if(availableMode&0x100) //arena + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x100; + } + else if(availableMode&0x20) //ctf + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x20; + } + else if(availableMode&0x40) //flagball + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x40; + } + else if(availableMode&0x80) //chat + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x80; + } + else if(availableMode&0x400) //elim + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x400; + } + else if(availableMode&0x10) //kotr + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x10; + } + else //Все остальные пробуем загрузить с текущими флагами + { + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|currentGameFlags; + } + } + + if (newGame==true) + { + + Data->gameFlags=Data->gameFlags&0xE00F; + Data->gameFlags=Data->gameFlags|0x80; + if(*GameFlags&0x80) + { + Data->isNew=0; + } + else + Data->isNew=1; + //sameMap=false; + isNewGame=true; + if(strcmp(Data->mapName,mapGetName())==0 && availableMode&0x80) + sameMap=true; + //*serverModeChange=*serverModeChange&0x0E80; + //*serverModeChange=*serverModeChange&Data->gameFlags; + } + Index=serverModeIndexByModeFlags(Data->gameFlags); + lua_getfield(L,Top+1,"fraglimit"); + if (lua_type(L,-1)!=LUA_TNIL) + { + Data->fragLimit=lua_tointeger(L,-1); + serverLessonLimitArr[Index]=Data->fragLimit; + *serverInfoChanged=1; + } + + lua_getfield(L,Top+1,"timelimit"); + if (lua_type(L,-1)!=LUA_TNIL) + { + Data->timeLimitMB=lua_tointeger(L,-1); + serverTimeLimitArr[Index]=Data->timeLimitMB; + *serverInfoChanged=1; + } + + + lua_pushnil(L); + lua_setfield(L,LUA_REGISTRYINDEX,"formNextGameTable"); + + if(mapLoadFlags(mapLoadData)&0x60 && newGame==false) + { + teamCreateDefault(2); + } + else + { + teamCreateDefault(-1); + } + /*if(sameMap) + { + wchar_t command[5] = L"load"; + wchar_t wMapName[9]={0}; + int *commandPointer=(int*)&command; + int *wMapNamePointer=(int*)&wMapName; + MultiByteToWideChar(CP_ACP, MB_COMPOSITE, Data->mapName, 8, wMapName, 9); + BYTE result[8]={0}; + memcpy(&result[0], &commandPointer, 4); + memcpy(&result[4], &wMapNamePointer, 4); + consoleServerMapLoad(1, 2, (void*)&result); + } + else if(dontUseGUIFunc==false) + { + guiServerOptionsStartGameMB(); + }*/ + nextMapOverride[0]='\0'; + strcpy(nextMapOverride, Data->mapName); + strcat(nextMapOverride, ".map"); + result=nextMapOverride; + if(sameMap) + mapNextSameForced=true; + } + else + { + if(noxMapCycleEnabledCheck()) + result=mapCycleNext(); + else + { + mapNextSameForced=true; + return onLoadMapCycle(); + } + + } + } + else + { + if(noxMapCycleEnabledCheck()) + result=mapCycleNext(); + else + { + mapNextSameForced=true; + return onLoadMapCycle(); + } + } + lua_settop(L,Top); + return result; + } + + void onMapLoadName(char* mapName) + { + if(isNewGame) + { + isNewGame=false; + guiServerOptionsStartGameMB(); + } + else + mapLoadName(mapName); + } + + + int banGetList(lua_State *L) + { + lua_createtable(L,5,0); + void *Ptr=serverBanGetList(); + for (int i=1;Ptr!=NULL;Ptr=memListNext(Ptr),i++) + { + char Buf[0x40]={0}; + wcstombs(Buf,((wchar_t*)Ptr)+0x6,0x24-0x6); + lua_pushstring(L,Buf); + lua_rawseti(L,-2,i); + } + return 1; + } + int banRemove(lua_State *L) + { + lua_settop(L,1); + if (lua_type(L,1)==LUA_TSTRING) + { + void *Ptr=serverBanGetList(); + for (int i=0;Ptr!=NULL;Ptr=memListNext(Ptr),i++) + { + char Buf[0x40]={0}; + wcstombs(Buf,((wchar_t*)Ptr)+0x6,0x24-0x6); + if (0==strcmp(Buf,lua_tostring(L,1))) + { + serverBanRemove(i); + return 0; + } + + } + } + else if (lua_type(L,1)==LUA_TNUMBER) + { + serverBanRemove(lua_tointeger(L,1)); + } + else + { + lua_pushstring(L,"wrong args - not a team!"); + lua_error_(L); + } + return 0; + } + + int playerKickUData(lua_State *L) + { + lua_settop(L,1); + if ( + (lua_type(L,1)!=LUA_TLIGHTUSERDATA) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + DWORD *DW=(DWORD*)lua_touserdata(L,1); + if (0==(DW[2] & 0x4)) + { + lua_pushstring(L,"wrong args: unit is not a player!"); + lua_error_(L); + } + void **PP=(void **)(((char*)lua_touserdata(L,1))+0x2EC); + PP=(void**)(((char*)*PP)+0x114); + byte *P=(byte*)(*PP); + byte playerIdx = *((byte*)(P+0x810)); + if(playerIdx==0x1F) + { + lua_pushstring(L,"can't kick the hoster!"); + lua_error_(L); + } + playerKickByIdx((int)playerIdx, 4); + return 0; + } + + int httpServerL(lua_State *L) + { + lua_settop(L,2); + serverClose(); + if (lua_type(L,1)!=LUA_TNIL) + { + int R=serverStart(lua_tointeger(L,1))?1:0; + lua_pushvalue(L,2); + lua_setfield(L,LUA_REGISTRYINDEX,"serverPass"); + + lua_pushboolean(L,R); + } + else + lua_pushboolean(L,0); + return 1; + } + void (__cdecl*guiUpdate)(); + + time_t onEndGame(time_t *TimePtr) + { + int Top=lua_gettop(L); + getServerVar("onEndGame"); + if (!lua_isfunction(L,-1)) + return _time(TimePtr); + lua_pcall(L,0,0,0); + lua_settop(L,Top); + return _time(TimePtr); + } + + void* __cdecl onServerStart() + { + for(byte i=0; i<0x20; i++) + { + authorisedState[i]=0; + if(authorisedLogins[i]!=0 && strcmp(authorisedLogins[i], "")!=0) + delete [] authorisedLogins[i]; + authorisedLogins[i]=""; + authSendWelcomeMsg[i]=0; + } + mapCycleLastModeId=((__int16)*GameFlags)&0x1FF0; + mapCycleCurrentPosition=0; + return getConfigData(); + } + + void __cdecl OnGuiUpdate() + { + autoexecCli(); + guiUpdate(); + httpGetCallback(L); + updateAuthDBProcess(); + if (needToFormGame) + { + needToFormGame=false; + doFormGame(); + } + replayGuiUpdate(); + /*if(replayViewFormGameRequest) + { + replayViewFormGameRequest=false; + replayViewFormGame(); + }*/ + } + + void* onPlayerLeave(byte Index) + { + playerInfoStruct *result = playerGetDataFromIndex(Index); + if(*GameFlags&0x800) + {} + else + { + authorisedState[Index]=0; + if(strcmp(authorisedLogins[Index], "")!=0) + delete [] authorisedLogins[Index]; + authorisedLogins[Index]=""; + clientsVersions[Index]=0; + int Top=lua_gettop(L); + getServerVar("playerOnLeave"); + if (lua_isfunction(L,-1)) + { + bigUnitStruct *Player = getPlayerUDataFromPlayerInfo(result); + lua_pushlightuserdata(L,Player); + if (0!=lua_pcall(L,1,0,0)) + conPrintI(lua_tostring(L,-1)); + } + lua_settop(L,Top); + } + return result; + } + + void* onPlayerJoin(int Index) + { + clientsVersions[Index]=0; + playerInfoStruct *result=playerGetDataFromIndex(Index); + if(Index!=0x1F && specialAuthorisation==true) + { + authorisedState[(byte)Index]=0; // Перестраховщик я какой то... (c) Evengard + authorisedLogins[(byte)Index]=""; + playerGoObserver(result, 1, 1); + authSendWelcomeMsg[Index]=30; + + netVersionServerRq(Index); + } + return result; + } + +} +extern "C" void adminInit(lua_State *L); +extern void authInit(lua_State *L); +extern void InjectOffs(DWORD Addr,void *Fn); + +void adminInit(lua_State *L) +{ + ASSIGN(guiServerOptionsStartGameMB,0x00459150); + ASSIGN(serverGetGameData,0x00416590); + ASSIGN(serverGetGameDataBySel,0x004165B0); + ASSIGN(serverBanGetList,0x00416900); + ASSIGN(serverBanRemove,0x00416820); + ASSIGN(memListNext,0x00416910); + ASSIGN(guiUpdate,0x0046B740); + ASSIGN(serverModeIndexByModeFlags,0x00409A70); + ASSIGN(serverLessonLimitArr,0x005D5334); + ASSIGN(serverTimeLimitArr,0x005D5340); + ASSIGN(serverInfoChanged,0x005D5360); + //ASSIGN(serverModeChange,0x0062F0B6); + ASSIGN(consoleServerMapLoad,0x00441910); + ASSIGN(mapLoadFromFile,0x004CFE10);// функция загрузки карты из файла + ASSIGN(mapLoadName,0x00409D70);// функция загрузки карты из файла - используется при загрузке из мапцикла + ASSIGN(mapLoadData, 0x00974880);// оффсет куда mapLoadFromFile грузит карту + ASSIGN(mapLoadFlags, 0x004CFFA0);// функция получения флагов из загруженного файла + ASSIGN(noxMapCycleNext, 0x004D0CF0); + ASSIGN(_time,0x00566BD3); + ASSIGN(noxMapCycleEnabledCheck, 0x004D0D70); + ASSIGN(loadCfg, 0x004317B0); + ASSIGN(saveCfg, 0x00433290); + ASSIGN(loadBanList, 0x004E41B0); + ASSIGN(saveBanList, 0x004E43F0); + ASSIGN(flushBanList, 0x00425760); + ASSIGN(getConfigData, 0x00416640); + ASSIGN(playerGoObserver,0x004E6860); + ASSIGN(currentIP,0x0097EBC4); + ASSIGN(currentPort,0x0097EBC8); + ASSIGN(playerKickByIdx,0x004DEAB0); + + InjectOffs(0x004D280B+1,&onMapCycleEnabledCheck); //Обход проверки на вкл. мапцикл если использовалась formNextGame + InjectOffs(0x0043E333+1,&OnGuiUpdate); + InjectOffs(0x00413D37+1,&onEndGame); + InjectOffs(0x004D281D+1,&onLoadMapCycle); //Хук на мапцикл + InjectOffs(0x004D283F+1,&onLoadMapCycle); //Хук на мапцикл + InjectOffs(0x004D284F+1,&onMapLoadName); //Поддержка new=1 в formNextGame (а вообще походу костыль) + InjectOffs(0x0043AAB9+1,&onServerStart); //Server startup hook - инициализируем тут свои переменные + InjectOffs(0x004DE55E+1,&onPlayerLeave); //Уход игрока с серва - деавторизуем его + InjectOffs(0x004DDF6C+1,&onPlayerJoin); //Игрок вошёл на сервер - вводим его в обсерв + + int Top=lua_gettop(L); + if (0!=luaL_loadstring(L, + "local json=require('json'); " + "local f=loadstring; " + "return function (s) " + "s=string.gsub(s,'%%(%x%x)',function (v) return string.char('0x'..v) end); " + "local r=f(s); " + "setfenv(r,getfenv(1)) " + "return json.encode( r() ) end; ")) + { + MessageBox(0,lua_tostring(L,-1),0,0); + luaL_loadstring(L,""); + } + else + { + if (0==lua_pcall(L,0,1,0)) + { + } + else + { + MessageBox(0,lua_tostring(L,-1),0,0); + luaL_loadstring(L,""); + } + } + lua_getfield(L,LUA_REGISTRYINDEX,"server"); + lua_setfenv(L,-2); + lua_setfield(L,LUA_REGISTRYINDEX,"serverFn"); + if (0!=luaL_loadstring(L, + "return function (s) " + "local r=s; " + "setfenv(r,getfenv(1)) " + "return json.encode( r() ) end; ")) + { + MessageBox(0,lua_tostring(L,-1),0,0); + luaL_loadstring(L,""); + } + else + { + if (0==lua_pcall(L,0,1,0)) + { + } + else + { + MessageBox(0,lua_tostring(L,-1),0,0); + luaL_loadstring(L,""); + } + } + lua_getfield(L,LUA_REGISTRYINDEX,"server"); + lua_setfenv(L,-2); + lua_setfield(L,LUA_REGISTRYINDEX,"serverFnSysop"); + registerserver("httpServer",&httpServerL); + registerserver("formGame",&formGame); + registerserver("formNextGame",&formNextGame); + registerserver("banList",&banGetList); + registerserver("banRemove",&banRemove); + registerserver("loadCfg",&loadCfgL); + registerserver("saveCfg",&saveCfgL); + registerserver("loadBanList",&loadBanListL); + registerserver("saveBanList",&saveBanListL); + registerserver("reloadBanList",&reloadBanListL); + registerserver("flushBanList",&flushBanListL); + registerserver("playerKickUData",&playerKickUData); + + authInit(L); + //strcpy((char*)0x005AFA20, "So_Forum"); // Смена дефолтной чат-мапы при игре через "локальную" сеть + lua_settop(L,Top); } \ No newline at end of file diff --git a/audServer.cpp b/audServer.cpp index 58c2ee5..720cb80 100644 --- a/audServer.cpp +++ b/audServer.cpp @@ -1,50 +1,50 @@ -#include "stdafx.h" - -int (__cdecl *audMakeSound)(int Snd,noxPoint *Pt,int A,int B); -int (__cdecl *audMakeSyll)(void *Player,int Syll); - - -extern "C" void initAudServer(lua_State *L); -namespace -{ - - int audSound(lua_State *L) - { - int i=1; - if ( - (lua_type(L,i++)!=LUA_TNUMBER) || - (lua_type(L,i++)!=LUA_TNUMBER) || - (lua_type(L,i++)!=LUA_TNUMBER) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - audMakeSound(lua_tointeger(L,1),&noxPoint(lua_tonumber(L,2),lua_tonumber(L,3)),0,0); - return 0; - } -/* - , Cast */ - int audSyll(lua_State *L) - { - int i=1; - if ( - (lua_type(L,i++)!=LUA_TLIGHTUSERDATA) || - (lua_type(L,i++)!=LUA_TNUMBER) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - audMakeSyll(lua_touserdata(L,1),lua_tonumber(L,2)); - return 0; - } -} - -void initAudServer(lua_State *L) -{ - ASSIGN(audMakeSyll,0x004FC960); - ASSIGN(audMakeSound,0x00501A30); - registerserver("soundMake",&audSound); - registerserver("soundSyll",&audSyll); - +#include "stdafx.h" + +int (__cdecl *audMakeSound)(int Snd,noxPoint *Pt,int A,int B); +int (__cdecl *audMakeSyll)(void *Player,int Syll); + + +extern "C" void initAudServer(lua_State *L); +namespace +{ + + int audSound(lua_State *L) + { + int i=1; + if ( + (lua_type(L,i++)!=LUA_TNUMBER) || + (lua_type(L,i++)!=LUA_TNUMBER) || + (lua_type(L,i++)!=LUA_TNUMBER) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + audMakeSound(lua_tointeger(L,1),&noxPoint(lua_tonumber(L,2),lua_tonumber(L,3)),0,0); + return 0; + } +/* не работает - либо таймауты подводят, либо нужно состояние Cast игроку */ + int audSyll(lua_State *L) + { + int i=1; + if ( + (lua_type(L,i++)!=LUA_TLIGHTUSERDATA) || + (lua_type(L,i++)!=LUA_TNUMBER) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + audMakeSyll(lua_touserdata(L,1),lua_tonumber(L,2)); + return 0; + } +} + +void initAudServer(lua_State *L) +{ + ASSIGN(audMakeSyll,0x004FC960); + ASSIGN(audMakeSound,0x00501A30); + registerserver("soundMake",&audSound); + registerserver("soundSyll",&audSyll); + } \ No newline at end of file diff --git a/authManager.cpp b/authManager.cpp index 8492f14..640d995 100644 --- a/authManager.cpp +++ b/authManager.cpp @@ -1,791 +1,791 @@ -#include "stdafx.h" -#include "unit.h" -#include "player.h" -#include -#include -#include -#include -#include -#include -#include "Libs/csha1/SHA1.h" - - -#ifdef WIN32 -#define _CRT_SECURE_NO_WARNINGS - -#include -#include -#include -#include -#pragma comment(lib,"wsock32.lib") -#pragma comment (lib, "Ws2_32.lib") -#define snprintf _snprintf_s -#define S_ISREG(x) (0!=((x) & S_IFREG )) -#define S_ISDIR(x) (0!=((x) & S_IFDIR )) - -#else -#include -#include -#define closesocket close -#endif - -#include -#include -#include -#include -#include -//#include -//#include -//#include "stdafx.h" -using namespace std ; -#define SERVER "Nox UniMod/0.4.1" -#define PROTOCOL "HTTP/1.0" -#define RFC1123FMT "%a, %d %b %Y %H:%M:%S GMT" -#define PORT 80 - - -using namespace std; - -extern byte authorisedState[0x20]; -extern char* authorisedLogins[0x20]; -extern bool specialAuthorisation; // -extern char authSendWelcomeMsg[0x20]; -extern std::pair httpGetInternal(char* uri); - -namespace -{ - queue updateAuthDB; - - map notLoggedIn; - - bool authUpdating=false; - HANDLE authUpdate; - - char* remoteCommand; - int lastAuthResultCode; - bool specialAuthRemote=false; - bool remoteAuthUpdating=false; - HANDLE remoteAuthUpdate; - queue remoteCommandList; - - int lastAuthResultCodeL; - HANDLE remoteAuthLogin; - bool remoteAuthLoggingIn=false; - queue notLoggedInRemote; - - struct sha1hash - { - unsigned char val[20]; - - sha1hash() - { - memset(val, '\0', 20); - } - - sha1hash(const sha1hash& oth) - { - memmove(val, oth.val, 20); - } - - sha1hash(const unsigned char * str) - { - memset(val, '\0', 20); - if (str) - { - strncpy((char*)val, (char*)str, 20); - } - } - - // required for 'map', 'set', etc - bool operator<(const sha1hash& oth) const - { - return strncmp((char*)val , (char*)oth.val, 20) < 0; - } - }; - - - - struct account - { - char login[50]; - unsigned char phash[20]; - bool isActive; - bool isAdmin; - char unused[8]; - }; - - typedef map authMap; - authMap authData; - - - string urlencode(const string &c); - string char2hex( char dec ); - - string urlencode(const string &c) - { - - string escaped=""; - int max = c.length(); - for(int i=0; i>4; - char dig2 = (dec&0x0F); - if ( 0<= dig1 && dig1<= 9) dig1+=48; //0,48inascii - if (10<= dig1 && dig1<=15) dig1+=97-10; //a,97inascii - if ( 0<= dig2 && dig2<= 9) dig2+=48; - if (10<= dig2 && dig2<=15) dig2+=97-10; - - string r; - r.append( &dig1, 1); - r.append( &dig2, 1); - return r; - } - - - unsigned __stdcall authRemoteCommand(void* command) - { - string urlEncode((char*)command); - string urlEncoded=urlencode(urlEncode); - char* resultCommand=new char[strlen(urlEncoded.c_str())+strlen(remoteCommand)+1]; - strcpy(resultCommand, remoteCommand); - strcat(resultCommand, urlEncoded.c_str()); - std::pair res=httpGetInternal((char*) resultCommand); - lastAuthResultCode=res.first; - delete[] res.second; - return 0; - } - - unsigned __stdcall authRemoteLogin(void* command) - { - string urlEncode((char*)command); - string urlEncoded=urlencode(urlEncode); - char* resultCommand=new char[strlen(urlEncoded.c_str())+strlen(remoteCommand)+1]; - strcpy(resultCommand, remoteCommand); - strcat(resultCommand, urlEncoded.c_str()); - std::pair res=httpGetInternal((char*) resultCommand); - lastAuthResultCodeL=res.first; - delete[] res.second; - return 0; - } - - unsigned __stdcall saveAuthData(void* Data) - { - ofstream file("authData.bin", ios::out | ios::trunc | ios::binary); - for (authMap::const_iterator it = authData.begin(); it != authData.end(); ++it) - { - char rawData[100]; - strncpy(rawData, (char*)it->first.val, 20); - memcpy(&rawData[20], &it->second, 80); - char zero=0; - memcpy(&rawData[92], &zero, 8); - file.write(rawData, 100); - } - file.close(); - return true; - } - - bool authRegister(char* login, char* pass) - { - CSHA1 sha; - sha.Update((const unsigned char*)login, strlen(login)); - sha.Final(); - unsigned char lhash[20]; - sha.GetHash(lhash); - sha.Reset(); - sha.Update((const unsigned char*)pass, strlen(pass)); - sha.Final(); - unsigned char phash[20]; - sha.GetHash(phash); - sha.Reset(); - account* newAcc = new account; - memset(newAcc->login, '\0', 50); - strncpy(newAcc->login, login, ((strlen(login)>50)?50:strlen(login))); - strncpy((char*)newAcc->phash, (char*)phash, 20); - newAcc->isActive=true; - newAcc->isAdmin=false; - memset(newAcc->unused, '\0', 8); - pair newPair = pair(sha1hash(lhash), *newAcc); - if(authData.insert(newPair).second) - { - updateAuthDB.push(true); - return true; - } - return false; - } - - bool authLogin(char* login, char* pass) - { - CSHA1 sha; - sha.Update((const unsigned char*)login, strlen(login)); - sha.Final(); - unsigned char lhash[20]; - sha.GetHash(lhash); - sha.Reset(); - if(authData.find(sha1hash(lhash))!=authData.end() && strncmp(authData[sha1hash(lhash)].login, login, 50)==0 && authData[sha1hash(lhash)].isActive==true) - { - sha.Update((const unsigned char*)pass, strlen(pass)); - sha.Final(); - unsigned char phash[20]; - sha.GetHash(phash); - sha.Reset(); - if(strncmp((char*)authData[sha1hash(lhash)].phash, (char*)phash, 20)==0) - return true; - } - return false; - } - - bool authLock(char* login) - { - CSHA1 sha; - sha.Update((const unsigned char*)login, strlen(login)); - sha.Final(); - unsigned char lhash[20]; - sha.GetHash(lhash); - sha.Reset(); - if(authData.find(sha1hash(lhash))!=authData.end() && strncmp(authData[sha1hash(lhash)].login, login, 50)==0) - { - if(authData[sha1hash(lhash)].isActive==true) - authData[sha1hash(lhash)].isActive=false; - else - authData[sha1hash(lhash)].isActive=true; - updateAuthDB.push(true); - return true; - } - return false; - } - - bool authDelete(char* login) - { - CSHA1 sha; - sha.Update((const unsigned char*)login, strlen(login)); - sha.Final(); - unsigned char lhash[20]; - sha.GetHash(lhash); - sha.Reset(); - if(authData.find(sha1hash(lhash))!=authData.end() && strncmp(authData[sha1hash(lhash)].login, login, 50)==0) - { - authMap::iterator it = authData.find(sha1hash(lhash)); - account* acc=&it->second; - //sha1hash* lhash=&it->first; - authData.erase(it); - - //delete acc; - //delete lhash; - updateAuthDB.push(true); - return true; - } - return false; - } - - bool authChangePass(char* login, char* pass) - { - CSHA1 sha; - sha.Update((const unsigned char*)login, strlen(login)); - sha.Final(); - unsigned char lhash[20]; - sha.GetHash(lhash); - sha.Reset(); - if(authData.find(sha1hash(lhash))!=authData.end() && strncmp(authData[sha1hash(lhash)].login, login, 50)==0) - { - sha.Update((const unsigned char*)pass, strlen(pass)); - sha.Final(); - sha.GetHash(authData[sha1hash(lhash)].phash); - sha.Reset(); - updateAuthDB.push(true); - return true; - } - return false; - } - - void authentificate() - { - /*int lastAuthResultCodeL; - HANDLE remoteAuthLogin; - bool remoteAuthLoggingIn=false; - queue notLoggedInRemote;*/ - if(WAIT_OBJECT_0==WaitForSingleObject(remoteAuthLogin, 0) && remoteAuthLoggingIn==true && specialAuthRemote==true) - { - byte playerIdx = notLoggedInRemote.front(); - notLoggedIn.erase(playerIdx); - notLoggedInRemote.pop(); - if(lastAuthResultCodeL==200) - authorisedState[playerIdx]++; - else - { - authorisedState[playerIdx]-=2; - delete [] authorisedLogins[playerIdx]; - authorisedLogins[playerIdx]=""; - } - authSendWelcomeMsg[playerIdx]=-1; - remoteAuthLoggingIn=false; - } - if(notLoggedInRemote.empty()==false && remoteAuthLoggingIn==false && specialAuthRemote==true) - { - byte playerIdx = notLoggedInRemote.front(); - char* command=new char[11+6+5+2+2+strlen(authorisedLogins[playerIdx])+strlen(notLoggedIn[playerIdx])+4+1]; - strcpy(command, "authLogin({login=\""); - strcat(command, authorisedLogins[playerIdx]); - strcat(command, "\",pass=\""); - strcat(command, notLoggedIn[playerIdx]); - strcat(command, "\"})"); - remoteCommandList.push(command); - remoteAuthLogin = (HANDLE)_beginthreadex(NULL, 0, &authRemoteLogin, (void*)command, 0, NULL); - remoteAuthLoggingIn=true; - } - if(notLoggedIn.empty()!=true && specialAuthRemote==false) - { - for (map::const_iterator it = notLoggedIn.begin(); it != notLoggedIn.end(); ++it) - { - if(authLogin(authorisedLogins[it->first], it->second)) - authorisedState[it->first]++; - else - { - authorisedState[it->first]-=2; - delete [] authorisedLogins[it->first]; - authorisedLogins[it->first]=""; - } - authSendWelcomeMsg[it->first]=-1; - delete [] it->second; - } - notLoggedIn.clear(); - } - } - - int authRegisterL(lua_State *L) - { - if (lua_type(L,1)==LUA_TTABLE) - { - char* login; - char* pass; - lua_getfield(L,1,"login"); - if (lua_type(L,-1)!=LUA_TNIL) - { - const char* loginc=lua_tostring(L,-1); - login=new char[strlen(loginc)+1]; - strcpy(login,loginc); - } - else - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - lua_getfield(L,1,"pass"); - if (lua_type(L,-1)!=LUA_TNIL) - { - const char* passc=lua_tostring(L,-1); - pass=new char[strlen(passc)+1]; - strcpy(pass,passc); - } - else - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - if(specialAuthRemote) - { - char *command=new char[14+6+5+2+2+strlen(login)+strlen(pass)+4+1]; - strcpy(command, "authRegister({login=\""); - strcat(command, login); - strcat(command, "\",pass=\""); - strcat(command, pass); - strcat(command, "\"})"); - remoteCommandList.push(command); - } - else if(!authRegister(login, pass)) - { - lua_pushstring(L,"couldn't register"); - lua_error_(L); - } - delete [] login; - delete [] pass; - } - else - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - lua_pushstring(L, "ok"); - return 1; - } - - int authChangePassL(lua_State *L) - { - if (lua_type(L,1)==LUA_TTABLE) - { - char* login; - char* pass; - lua_getfield(L,1,"login"); - if (lua_type(L,-1)!=LUA_TNIL) - { - const char* loginc=lua_tostring(L,-1); - login=new char[strlen(loginc)+1]; - strcpy(login,loginc); - } - else - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - lua_getfield(L,1,"pass"); - if (lua_type(L,-1)!=LUA_TNIL) - { - const char* passc=lua_tostring(L,-1); - pass=new char[strlen(passc)+1]; - strcpy(pass,passc); - } - else - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - if(specialAuthRemote) - { - char *command=new char[16+6+5+2+2+strlen(login)+strlen(pass)+4+1]; - strcpy(command, "authChangePass({login=\""); - strcat(command, login); - strcat(command, "\",pass=\""); - strcat(command, pass); - strcat(command, "\"})"); - remoteCommandList.push(command); - } - else if(!authChangePass(login, pass)) - { - lua_pushstring(L,"couldn't change password"); - lua_error_(L); - } - delete [] login; - delete [] pass; - } - else - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - lua_pushstring(L, "ok"); - return 1; - } - - int authLoginL(lua_State *L) - { - if (lua_type(L,1)==LUA_TTABLE) - { - char* login; - char* pass; - lua_getfield(L,1,"login"); - if (lua_type(L,-1)!=LUA_TNIL) - { - const char* loginc=lua_tostring(L,-1); - login=new char[strlen(loginc)+1]; - strcpy(login,loginc); - } - else - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - lua_getfield(L,1,"pass"); - if (lua_type(L,-1)!=LUA_TNIL) - { - const char* passc=lua_tostring(L,-1); - pass=new char[strlen(passc)+1]; - strcpy(pass,passc); - } - else - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - if(specialAuthRemote) - { - char *command=new char[11+6+5+2+2+strlen(login)+strlen(pass)+4+1]; - strcpy(command, "authLogin({login=\""); - strcat(command, login); - strcat(command, "\",pass=\""); - strcat(command, pass); - strcat(command, "\"})"); - remoteCommandList.push(command); - } - else if(!authLogin(login, pass)) - { - lua_pushstring(L,"couldn't login"); - lua_error_(L); - } - delete [] login; - delete [] pass; - } - else - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - lua_pushstring(L, "ok"); - return 1; - } - - int authLockL(lua_State *L) - { - if (lua_type(L,1)==LUA_TSTRING) - { - char* login; - const char* loginc=lua_tostring(L, 1); - login=new char[strlen(loginc)+1]; - strcpy(login, loginc); - if(specialAuthRemote) - { - char *command=new char[10+strlen(login)+2+1]; - strcpy(command, "authLock(\""); - strcat(command, login); - strcat(command, "\")"); - remoteCommandList.push(command); - } - else - authLock(login); - delete [] login; - } - else - { - lua_pushstring(L,"wrong args"); - lua_error_(L); - } - lua_pushstring(L, "ok"); - return 1; - } - - int authDeleteL(lua_State *L) - { - if (lua_type(L,1)==LUA_TSTRING) - { - char* login; - const char* loginc=lua_tostring(L, 1); - login=new char[strlen(loginc)+1]; - strcpy(login, loginc); - if(specialAuthRemote) - { - char *command=new char[12+strlen(login)+2+1]; - strcpy(command, "authDelete(\""); - strcat(command, login); - strcat(command, "\")"); - remoteCommandList.push(command); - } - else - authDelete(login); - delete [] login; - } - else - { - lua_pushstring(L,"wrong args"); - lua_error_(L); - } - lua_pushstring(L, "ok"); - return 1; - } - - int authToggleL(lua_State *L) - { - if(specialAuthorisation) - { - specialAuthorisation=false; - specialAuthRemote=false; - remoteCommand=NULL; - } - else - specialAuthorisation=true; - if (lua_type(L,1)==LUA_TTABLE && specialAuthorisation==true) - { - lua_getfield(L, 1, "host"); - if(lua_type(L, -1)!=LUA_TSTRING) - { - lua_pushstring(L,"wrong args"); - lua_error_(L); - } - const char* hostc=lua_tostring(L,-1); - char* host=new char[strlen(hostc)+1]; - strcpy(host,hostc); - lua_getfield(L, 1, "port"); - if(lua_type(L, -1)!=LUA_TSTRING && lua_type(L, -1)!=LUA_TNUMBER) - { - lua_pushstring(L,"wrong args"); - lua_error_(L); - } - const char* portc=lua_tostring(L,-1); - char* port=new char[strlen(portc)+1]; - strcpy(port,portc); - lua_getfield(L, 1, "pass"); - bool passProvided=false; - char* pass; - if(lua_type(L, -1)==LUA_TSTRING) - { - passProvided=true; - const char* passc=lua_tostring(L,-1); - pass=new char[strlen(passc)+1]; - strcpy(pass,passc); - } - char* commandString=new char[7+strlen(host)+1+strlen(port)+2+(passProvided?(2+strlen(pass)+1):(0))+2+1]; - strcpy(commandString, "http://"); - strcat(commandString, host); - strcat(commandString, ":"); - strcat(commandString, port); - strcat(commandString, "/?"); - if(passProvided) - { - strcat(commandString, "p="); - strcat(commandString, pass); - strcat(commandString, "&"); - } - strcat(commandString, "r="); - delete [] host; - delete [] port; - if(passProvided) - delete [] pass; - remoteCommand=commandString; - specialAuthRemote=true; - } - return 1; - } - - int playerGetByLogin(lua_State *L) - { - if(lua_type(L, -1)==LUA_TSTRING) - { - const char *S=lua_tostring(L,-1); - bool found=false; - for(void *Pl=playerFirstUnit(); Pl!=0; Pl=playerNextUnit(Pl)) - { - void **PP=(void **)(((char*)Pl)+0x2EC); - PP=(void**)(((char*)*PP)+0x114); - byte *P=(byte*)(*PP); - - byte playerIdx = *((byte*)(P+0x810)); - if(strncmp(authorisedLogins[playerIdx],S, 50)==0) - { - found=true; - lua_pushlightuserdata(L, Pl); - break; - } - } - if(found==false) - { - lua_pushstring(L,"not found!"); - lua_error_(L); - } - } - else - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - return 1; - } -} - -void authInit(lua_State *L) -{ - registerserver("authRegister",&authRegisterL); - registerserver("authLock",&authLockL); - registerserver("authLogin",&authLoginL); - registerserver("authChangePass",&authChangePassL); - registerserver("authToggle",&authToggleL); - registerserver("authDelete",&authDeleteL); - registerserver("playerGetByLogin",&playerGetByLogin); -} -bool initAuthData() -{ - ifstream file("authData.bin", ios::in | ios::binary); - if(file.is_open()) - { - file.seekg(0, ios::end); - size_t filesize=file.tellg(); - for(size_t i=0; (i+100)<=filesize; i+=100) - { - file.seekg(i, ios::beg); - unsigned char *loginhash = new unsigned char[20]; - file.read((char*)loginhash, 20); - file.seekg(i+20, ios::beg); - char logindata[80]; - file.read(logindata, 80); - account *authEntry = new account; - memcpy(authEntry, logindata, 80); - authData.insert(pair(sha1hash(loginhash), *authEntry)); - } - file.close(); - return true; - } - file.close(); - return false; -} - -void updateAuthDBProcess() -{ - if(WAIT_OBJECT_0==WaitForSingleObject(authUpdate, 0) && authUpdating==true) - { - updateAuthDB.pop(); - authUpdating=false; - } - if(updateAuthDB.empty()==false && authUpdating==false) - { - authUpdate = (HANDLE)_beginthreadex(NULL, 0, &saveAuthData, NULL, 0, NULL); - authUpdating=true; - } - authentificate(); - if(specialAuthRemote) - { - if(WAIT_OBJECT_0==WaitForSingleObject(remoteAuthUpdate, 0) && remoteAuthUpdating==true) - { - char buf[200]; - strcpy(buf, remoteCommandList.front()); - strcat(buf, " executed, state: "); - if(lastAuthResultCode==200) - strcat(buf, "success!"); - else - strcat(buf, "error!"); - conPrintI(buf); - delete [] remoteCommandList.front(); - remoteCommandList.pop(); - remoteAuthUpdating=false; - } - if(remoteCommandList.empty()==false && remoteAuthUpdating==false) - { - remoteAuthUpdate = (HANDLE)_beginthreadex(NULL, 0, &authRemoteCommand, (void*)remoteCommandList.front(), 0, NULL); - remoteAuthUpdating=true; - } - } - return; -} - -void authCheckDelayed(byte playerIdx, char* pass) -{ - /*if(specialAuthRemote) - { - char command=new char[11+6+5+2+2+strlen(authorisedLogins[playerIdx])+strlen(pass)+4+1]; - strcpy(command, 'authLogin({login="'); - strcat(command, login); - strcat(command, '", pass="'); - strcat(command, '"})'); - remoteCommandList.push(command); - }*/ - - - - notLoggedIn.insert(pair(playerIdx, pass)); - if(specialAuthRemote) - notLoggedInRemote.push(playerIdx); +#include "stdafx.h" +#include "unit.h" +#include "player.h" +#include +#include +#include +#include +#include +#include +#include "Libs/csha1/SHA1.h" + + +#ifdef WIN32 +#define _CRT_SECURE_NO_WARNINGS + +#include +#include +#include +#include +#pragma comment(lib,"wsock32.lib") +#pragma comment (lib, "Ws2_32.lib") +#define snprintf _snprintf_s +#define S_ISREG(x) (0!=((x) & S_IFREG )) +#define S_ISDIR(x) (0!=((x) & S_IFDIR )) + +#else +#include +#include +#define closesocket close +#endif + +#include +#include +#include +#include +#include +//#include +//#include +//#include "stdafx.h" +using namespace std ; +#define SERVER "Nox UniMod/0.4.1" +#define PROTOCOL "HTTP/1.0" +#define RFC1123FMT "%a, %d %b %Y %H:%M:%S GMT" +#define PORT 80 + + +using namespace std; + +extern byte authorisedState[0x20]; +extern char* authorisedLogins[0x20]; +extern bool specialAuthorisation; //Отключение альтернативной авторизации +extern char authSendWelcomeMsg[0x20]; +extern std::pair httpGetInternal(char* uri); + +namespace +{ + queue updateAuthDB; + + map notLoggedIn; + + bool authUpdating=false; + HANDLE authUpdate; + + char* remoteCommand; + int lastAuthResultCode; + bool specialAuthRemote=false; + bool remoteAuthUpdating=false; + HANDLE remoteAuthUpdate; + queue remoteCommandList; + + int lastAuthResultCodeL; + HANDLE remoteAuthLogin; + bool remoteAuthLoggingIn=false; + queue notLoggedInRemote; + + struct sha1hash + { + unsigned char val[20]; + + sha1hash() + { + memset(val, '\0', 20); + } + + sha1hash(const sha1hash& oth) + { + memmove(val, oth.val, 20); + } + + sha1hash(const unsigned char * str) + { + memset(val, '\0', 20); + if (str) + { + strncpy((char*)val, (char*)str, 20); + } + } + + // required for 'map', 'set', etc + bool operator<(const sha1hash& oth) const + { + return strncmp((char*)val , (char*)oth.val, 20) < 0; + } + }; + + + + struct account + { + char login[50]; + unsigned char phash[20]; + bool isActive; + bool isAdmin; + char unused[8]; + }; + + typedef map authMap; + authMap authData; + + + string urlencode(const string &c); + string char2hex( char dec ); + + string urlencode(const string &c) + { + + string escaped=""; + int max = c.length(); + for(int i=0; i>4; + char dig2 = (dec&0x0F); + if ( 0<= dig1 && dig1<= 9) dig1+=48; //0,48inascii + if (10<= dig1 && dig1<=15) dig1+=97-10; //a,97inascii + if ( 0<= dig2 && dig2<= 9) dig2+=48; + if (10<= dig2 && dig2<=15) dig2+=97-10; + + string r; + r.append( &dig1, 1); + r.append( &dig2, 1); + return r; + } + + + unsigned __stdcall authRemoteCommand(void* command) + { + string urlEncode((char*)command); + string urlEncoded=urlencode(urlEncode); + char* resultCommand=new char[strlen(urlEncoded.c_str())+strlen(remoteCommand)+1]; + strcpy(resultCommand, remoteCommand); + strcat(resultCommand, urlEncoded.c_str()); + std::pair res=httpGetInternal((char*) resultCommand); + lastAuthResultCode=res.first; + delete[] res.second; + return 0; + } + + unsigned __stdcall authRemoteLogin(void* command) + { + string urlEncode((char*)command); + string urlEncoded=urlencode(urlEncode); + char* resultCommand=new char[strlen(urlEncoded.c_str())+strlen(remoteCommand)+1]; + strcpy(resultCommand, remoteCommand); + strcat(resultCommand, urlEncoded.c_str()); + std::pair res=httpGetInternal((char*) resultCommand); + lastAuthResultCodeL=res.first; + delete[] res.second; + return 0; + } + + unsigned __stdcall saveAuthData(void* Data) + { + ofstream file("authData.bin", ios::out | ios::trunc | ios::binary); + for (authMap::const_iterator it = authData.begin(); it != authData.end(); ++it) + { + char rawData[100]; + strncpy(rawData, (char*)it->first.val, 20); + memcpy(&rawData[20], &it->second, 80); + char zero=0; + memcpy(&rawData[92], &zero, 8); + file.write(rawData, 100); + } + file.close(); + return true; + } + + bool authRegister(char* login, char* pass) + { + CSHA1 sha; + sha.Update((const unsigned char*)login, strlen(login)); + sha.Final(); + unsigned char lhash[20]; + sha.GetHash(lhash); + sha.Reset(); + sha.Update((const unsigned char*)pass, strlen(pass)); + sha.Final(); + unsigned char phash[20]; + sha.GetHash(phash); + sha.Reset(); + account* newAcc = new account; + memset(newAcc->login, '\0', 50); + strncpy(newAcc->login, login, ((strlen(login)>50)?50:strlen(login))); + strncpy((char*)newAcc->phash, (char*)phash, 20); + newAcc->isActive=true; + newAcc->isAdmin=false; + memset(newAcc->unused, '\0', 8); + pair newPair = pair(sha1hash(lhash), *newAcc); + if(authData.insert(newPair).second) + { + updateAuthDB.push(true); + return true; + } + return false; + } + + bool authLogin(char* login, char* pass) + { + CSHA1 sha; + sha.Update((const unsigned char*)login, strlen(login)); + sha.Final(); + unsigned char lhash[20]; + sha.GetHash(lhash); + sha.Reset(); + if(authData.find(sha1hash(lhash))!=authData.end() && strncmp(authData[sha1hash(lhash)].login, login, 50)==0 && authData[sha1hash(lhash)].isActive==true) + { + sha.Update((const unsigned char*)pass, strlen(pass)); + sha.Final(); + unsigned char phash[20]; + sha.GetHash(phash); + sha.Reset(); + if(strncmp((char*)authData[sha1hash(lhash)].phash, (char*)phash, 20)==0) + return true; + } + return false; + } + + bool authLock(char* login) + { + CSHA1 sha; + sha.Update((const unsigned char*)login, strlen(login)); + sha.Final(); + unsigned char lhash[20]; + sha.GetHash(lhash); + sha.Reset(); + if(authData.find(sha1hash(lhash))!=authData.end() && strncmp(authData[sha1hash(lhash)].login, login, 50)==0) + { + if(authData[sha1hash(lhash)].isActive==true) + authData[sha1hash(lhash)].isActive=false; + else + authData[sha1hash(lhash)].isActive=true; + updateAuthDB.push(true); + return true; + } + return false; + } + + bool authDelete(char* login) + { + CSHA1 sha; + sha.Update((const unsigned char*)login, strlen(login)); + sha.Final(); + unsigned char lhash[20]; + sha.GetHash(lhash); + sha.Reset(); + if(authData.find(sha1hash(lhash))!=authData.end() && strncmp(authData[sha1hash(lhash)].login, login, 50)==0) + { + authMap::iterator it = authData.find(sha1hash(lhash)); + account* acc=&it->second; + //sha1hash* lhash=&it->first; + authData.erase(it); + + //delete acc; + //delete lhash; + updateAuthDB.push(true); + return true; + } + return false; + } + + bool authChangePass(char* login, char* pass) + { + CSHA1 sha; + sha.Update((const unsigned char*)login, strlen(login)); + sha.Final(); + unsigned char lhash[20]; + sha.GetHash(lhash); + sha.Reset(); + if(authData.find(sha1hash(lhash))!=authData.end() && strncmp(authData[sha1hash(lhash)].login, login, 50)==0) + { + sha.Update((const unsigned char*)pass, strlen(pass)); + sha.Final(); + sha.GetHash(authData[sha1hash(lhash)].phash); + sha.Reset(); + updateAuthDB.push(true); + return true; + } + return false; + } + + void authentificate() + { + /*int lastAuthResultCodeL; + HANDLE remoteAuthLogin; + bool remoteAuthLoggingIn=false; + queue notLoggedInRemote;*/ + if(WAIT_OBJECT_0==WaitForSingleObject(remoteAuthLogin, 0) && remoteAuthLoggingIn==true && specialAuthRemote==true) + { + byte playerIdx = notLoggedInRemote.front(); + notLoggedIn.erase(playerIdx); + notLoggedInRemote.pop(); + if(lastAuthResultCodeL==200) + authorisedState[playerIdx]++; + else + { + authorisedState[playerIdx]-=2; + delete [] authorisedLogins[playerIdx]; + authorisedLogins[playerIdx]=""; + } + authSendWelcomeMsg[playerIdx]=-1; + remoteAuthLoggingIn=false; + } + if(notLoggedInRemote.empty()==false && remoteAuthLoggingIn==false && specialAuthRemote==true) + { + byte playerIdx = notLoggedInRemote.front(); + char* command=new char[11+6+5+2+2+strlen(authorisedLogins[playerIdx])+strlen(notLoggedIn[playerIdx])+4+1]; + strcpy(command, "authLogin({login=\""); + strcat(command, authorisedLogins[playerIdx]); + strcat(command, "\",pass=\""); + strcat(command, notLoggedIn[playerIdx]); + strcat(command, "\"})"); + remoteCommandList.push(command); + remoteAuthLogin = (HANDLE)_beginthreadex(NULL, 0, &authRemoteLogin, (void*)command, 0, NULL); + remoteAuthLoggingIn=true; + } + if(notLoggedIn.empty()!=true && specialAuthRemote==false) + { + for (map::const_iterator it = notLoggedIn.begin(); it != notLoggedIn.end(); ++it) + { + if(authLogin(authorisedLogins[it->first], it->second)) + authorisedState[it->first]++; + else + { + authorisedState[it->first]-=2; + delete [] authorisedLogins[it->first]; + authorisedLogins[it->first]=""; + } + authSendWelcomeMsg[it->first]=-1; + delete [] it->second; + } + notLoggedIn.clear(); + } + } + + int authRegisterL(lua_State *L) + { + if (lua_type(L,1)==LUA_TTABLE) + { + char* login; + char* pass; + lua_getfield(L,1,"login"); + if (lua_type(L,-1)!=LUA_TNIL) + { + const char* loginc=lua_tostring(L,-1); + login=new char[strlen(loginc)+1]; + strcpy(login,loginc); + } + else + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + lua_getfield(L,1,"pass"); + if (lua_type(L,-1)!=LUA_TNIL) + { + const char* passc=lua_tostring(L,-1); + pass=new char[strlen(passc)+1]; + strcpy(pass,passc); + } + else + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + if(specialAuthRemote) + { + char *command=new char[14+6+5+2+2+strlen(login)+strlen(pass)+4+1]; + strcpy(command, "authRegister({login=\""); + strcat(command, login); + strcat(command, "\",pass=\""); + strcat(command, pass); + strcat(command, "\"})"); + remoteCommandList.push(command); + } + else if(!authRegister(login, pass)) + { + lua_pushstring(L,"couldn't register"); + lua_error_(L); + } + delete [] login; + delete [] pass; + } + else + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + lua_pushstring(L, "ok"); + return 1; + } + + int authChangePassL(lua_State *L) + { + if (lua_type(L,1)==LUA_TTABLE) + { + char* login; + char* pass; + lua_getfield(L,1,"login"); + if (lua_type(L,-1)!=LUA_TNIL) + { + const char* loginc=lua_tostring(L,-1); + login=new char[strlen(loginc)+1]; + strcpy(login,loginc); + } + else + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + lua_getfield(L,1,"pass"); + if (lua_type(L,-1)!=LUA_TNIL) + { + const char* passc=lua_tostring(L,-1); + pass=new char[strlen(passc)+1]; + strcpy(pass,passc); + } + else + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + if(specialAuthRemote) + { + char *command=new char[16+6+5+2+2+strlen(login)+strlen(pass)+4+1]; + strcpy(command, "authChangePass({login=\""); + strcat(command, login); + strcat(command, "\",pass=\""); + strcat(command, pass); + strcat(command, "\"})"); + remoteCommandList.push(command); + } + else if(!authChangePass(login, pass)) + { + lua_pushstring(L,"couldn't change password"); + lua_error_(L); + } + delete [] login; + delete [] pass; + } + else + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + lua_pushstring(L, "ok"); + return 1; + } + + int authLoginL(lua_State *L) + { + if (lua_type(L,1)==LUA_TTABLE) + { + char* login; + char* pass; + lua_getfield(L,1,"login"); + if (lua_type(L,-1)!=LUA_TNIL) + { + const char* loginc=lua_tostring(L,-1); + login=new char[strlen(loginc)+1]; + strcpy(login,loginc); + } + else + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + lua_getfield(L,1,"pass"); + if (lua_type(L,-1)!=LUA_TNIL) + { + const char* passc=lua_tostring(L,-1); + pass=new char[strlen(passc)+1]; + strcpy(pass,passc); + } + else + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + if(specialAuthRemote) + { + char *command=new char[11+6+5+2+2+strlen(login)+strlen(pass)+4+1]; + strcpy(command, "authLogin({login=\""); + strcat(command, login); + strcat(command, "\",pass=\""); + strcat(command, pass); + strcat(command, "\"})"); + remoteCommandList.push(command); + } + else if(!authLogin(login, pass)) + { + lua_pushstring(L,"couldn't login"); + lua_error_(L); + } + delete [] login; + delete [] pass; + } + else + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + lua_pushstring(L, "ok"); + return 1; + } + + int authLockL(lua_State *L) + { + if (lua_type(L,1)==LUA_TSTRING) + { + char* login; + const char* loginc=lua_tostring(L, 1); + login=new char[strlen(loginc)+1]; + strcpy(login, loginc); + if(specialAuthRemote) + { + char *command=new char[10+strlen(login)+2+1]; + strcpy(command, "authLock(\""); + strcat(command, login); + strcat(command, "\")"); + remoteCommandList.push(command); + } + else + authLock(login); + delete [] login; + } + else + { + lua_pushstring(L,"wrong args"); + lua_error_(L); + } + lua_pushstring(L, "ok"); + return 1; + } + + int authDeleteL(lua_State *L) + { + if (lua_type(L,1)==LUA_TSTRING) + { + char* login; + const char* loginc=lua_tostring(L, 1); + login=new char[strlen(loginc)+1]; + strcpy(login, loginc); + if(specialAuthRemote) + { + char *command=new char[12+strlen(login)+2+1]; + strcpy(command, "authDelete(\""); + strcat(command, login); + strcat(command, "\")"); + remoteCommandList.push(command); + } + else + authDelete(login); + delete [] login; + } + else + { + lua_pushstring(L,"wrong args"); + lua_error_(L); + } + lua_pushstring(L, "ok"); + return 1; + } + + int authToggleL(lua_State *L) + { + if(specialAuthorisation) + { + specialAuthorisation=false; + specialAuthRemote=false; + remoteCommand=NULL; + } + else + specialAuthorisation=true; + if (lua_type(L,1)==LUA_TTABLE && specialAuthorisation==true) + { + lua_getfield(L, 1, "host"); + if(lua_type(L, -1)!=LUA_TSTRING) + { + lua_pushstring(L,"wrong args"); + lua_error_(L); + } + const char* hostc=lua_tostring(L,-1); + char* host=new char[strlen(hostc)+1]; + strcpy(host,hostc); + lua_getfield(L, 1, "port"); + if(lua_type(L, -1)!=LUA_TSTRING && lua_type(L, -1)!=LUA_TNUMBER) + { + lua_pushstring(L,"wrong args"); + lua_error_(L); + } + const char* portc=lua_tostring(L,-1); + char* port=new char[strlen(portc)+1]; + strcpy(port,portc); + lua_getfield(L, 1, "pass"); + bool passProvided=false; + char* pass; + if(lua_type(L, -1)==LUA_TSTRING) + { + passProvided=true; + const char* passc=lua_tostring(L,-1); + pass=new char[strlen(passc)+1]; + strcpy(pass,passc); + } + char* commandString=new char[7+strlen(host)+1+strlen(port)+2+(passProvided?(2+strlen(pass)+1):(0))+2+1]; + strcpy(commandString, "http://"); + strcat(commandString, host); + strcat(commandString, ":"); + strcat(commandString, port); + strcat(commandString, "/?"); + if(passProvided) + { + strcat(commandString, "p="); + strcat(commandString, pass); + strcat(commandString, "&"); + } + strcat(commandString, "r="); + delete [] host; + delete [] port; + if(passProvided) + delete [] pass; + remoteCommand=commandString; + specialAuthRemote=true; + } + return 1; + } + + int playerGetByLogin(lua_State *L) + { + if(lua_type(L, -1)==LUA_TSTRING) + { + const char *S=lua_tostring(L,-1); + bool found=false; + for(void *Pl=playerFirstUnit(); Pl!=0; Pl=playerNextUnit(Pl)) + { + void **PP=(void **)(((char*)Pl)+0x2EC); + PP=(void**)(((char*)*PP)+0x114); + byte *P=(byte*)(*PP); + + byte playerIdx = *((byte*)(P+0x810)); + if(strncmp(authorisedLogins[playerIdx],S, 50)==0) + { + found=true; + lua_pushlightuserdata(L, Pl); + break; + } + } + if(found==false) + { + lua_pushstring(L,"not found!"); + lua_error_(L); + } + } + else + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + return 1; + } +} + +void authInit(lua_State *L) +{ + registerserver("authRegister",&authRegisterL); + registerserver("authLock",&authLockL); + registerserver("authLogin",&authLoginL); + registerserver("authChangePass",&authChangePassL); + registerserver("authToggle",&authToggleL); + registerserver("authDelete",&authDeleteL); + registerserver("playerGetByLogin",&playerGetByLogin); +} +bool initAuthData() +{ + ifstream file("authData.bin", ios::in | ios::binary); + if(file.is_open()) + { + file.seekg(0, ios::end); + size_t filesize=file.tellg(); + for(size_t i=0; (i+100)<=filesize; i+=100) + { + file.seekg(i, ios::beg); + unsigned char *loginhash = new unsigned char[20]; + file.read((char*)loginhash, 20); + file.seekg(i+20, ios::beg); + char logindata[80]; + file.read(logindata, 80); + account *authEntry = new account; + memcpy(authEntry, logindata, 80); + authData.insert(pair(sha1hash(loginhash), *authEntry)); + } + file.close(); + return true; + } + file.close(); + return false; +} + +void updateAuthDBProcess() +{ + if(WAIT_OBJECT_0==WaitForSingleObject(authUpdate, 0) && authUpdating==true) + { + updateAuthDB.pop(); + authUpdating=false; + } + if(updateAuthDB.empty()==false && authUpdating==false) + { + authUpdate = (HANDLE)_beginthreadex(NULL, 0, &saveAuthData, NULL, 0, NULL); + authUpdating=true; + } + authentificate(); + if(specialAuthRemote) + { + if(WAIT_OBJECT_0==WaitForSingleObject(remoteAuthUpdate, 0) && remoteAuthUpdating==true) + { + char buf[200]; + strcpy(buf, remoteCommandList.front()); + strcat(buf, " executed, state: "); + if(lastAuthResultCode==200) + strcat(buf, "success!"); + else + strcat(buf, "error!"); + conPrintI(buf); + delete [] remoteCommandList.front(); + remoteCommandList.pop(); + remoteAuthUpdating=false; + } + if(remoteCommandList.empty()==false && remoteAuthUpdating==false) + { + remoteAuthUpdate = (HANDLE)_beginthreadex(NULL, 0, &authRemoteCommand, (void*)remoteCommandList.front(), 0, NULL); + remoteAuthUpdating=true; + } + } + return; +} + +void authCheckDelayed(byte playerIdx, char* pass) +{ + /*if(specialAuthRemote) + { + char command=new char[11+6+5+2+2+strlen(authorisedLogins[playerIdx])+strlen(pass)+4+1]; + strcpy(command, 'authLogin({login="'); + strcat(command, login); + strcat(command, '", pass="'); + strcat(command, '"})'); + remoteCommandList.push(command); + }*/ + + + + notLoggedIn.insert(pair(playerIdx, pass)); + if(specialAuthRemote) + notLoggedInRemote.push(playerIdx); } \ No newline at end of file diff --git a/autoServer.cpp b/autoServer.cpp index 1ceb744..7f90414 100644 --- a/autoServer.cpp +++ b/autoServer.cpp @@ -1,136 +1,136 @@ -#include "stdafx.h" - -void (__cdecl *sub_43B4D0) (); // -void (__cdecl *parseGamedataBinPre) (); -int (__cdecl *noxCheckGameFlags) (int); -void (__cdecl *noxSetGameFlags) (int); -void (__cdecl *noxClearGameFlags) (int); - -void (__cdecl *sub_461440)(int); -void (__cdecl *sub_4D6F40)(int); -void (__cdecl *sub_4D6F90)(int); -void (__cdecl *sub_4D6F60)(int); -void (__cdecl *sub_4D6F80)(int); -void (__cdecl *sub_473670)(); -void (__cdecl *sub_472520)(int); -void (__cdecl *sub_43AF50)(int); - -void *dword_748260; - -int *dword_69B55C=(int*)0x0069B55C; -int *noxGameFlags; - -extern void InjectOffs(DWORD Addr,void *Fn); -extern void InjectJumpTo(DWORD Addr,void *Fn); - -namespace -{ - void __declspec(naked) asmHostWhenStart() // - { - __asm - { - mov eax,dword_69B55C - mov [eax+0],1 - push ecx - mov ecx,noxGameFlags - mov eax,[ecx+0] - and eax,0FFFFFFDFh - or eax,10h - mov [ecx],eax - pop ecx - push 2000h - call noxSetGameFlags - push 10000h - call noxSetGameFlags - push 800h - // call noxClearGameFlags - // push 1000000h - call noxClearGameFlags - add esp,0Ch - push 0 - call sub_461440 - push 0 - call sub_4D6F90 - push 0 - call sub_4D6F60 - push 0 - call sub_4D6F80 - call sub_473670 - push 8FCh - call sub_472520 - push 0 - call sub_43AF50 - add esp,18h - call parseGamedataBinPre - call sub_43B4D0 - mov eax,1 - push 004AB14Ch - ret - } - } - - void __cdecl checkAutoSrvFlag(char *str) - { - if (strcmp(str,"-autosrv")==0) - { - InjectJumpTo(0x004AB147,&asmHostWhenStart); - byte OperatorJmps=0xEB; - byte *bt=(byte*)(0x004AB105); - DWORD OldProtect; - VirtualProtect(bt,1,PAGE_EXECUTE_READWRITE,&OldProtect); - memcpy((byte*)bt,&OperatorJmps,1); // - VirtualProtect(bt,1,OldProtect,&OldProtect); - } - if (strcmp(str, "-debug") == 0) - { - *noxGameFlags = *noxGameFlags | 0x1000000; - } - } - - void __declspec(naked) asmCheckAutoSrvFlag() // - { - __asm - { - push ebp - call checkAutoSrvFlag - add esp,4 - sbb eax,eax - sbb eax,0FFFFFFFFh - push 004012B8h - ret - } - } - - - -} - - -void autoServer() -{ - - ASSIGN(sub_43B4D0,0x43B4D0); - - ASSIGN(sub_461440,0x00461440); - ASSIGN(sub_4D6F40,0x4D6F40); - ASSIGN(sub_4D6F90,0x4D6F90); - ASSIGN(sub_4D6F60,0x4D6F60); - ASSIGN(sub_4D6F80,0x4D6F80); - ASSIGN(sub_473670,0x473670); - ASSIGN(sub_472520,0x472520); - ASSIGN(sub_43AF50,0x0043AF50); // - - ASSIGN(dword_748260,0x00748260); - - ASSIGN(parseGamedataBinPre,0x004D1630); - - ASSIGN(noxGameFlags,0x0085B7A0); - ASSIGN(noxCheckGameFlags,0x0040A5C0); - ASSIGN(noxSetGameFlags,0x0040A4D0); - ASSIGN(noxClearGameFlags,0x0040A540); - - - InjectJumpTo(0x004012B3,&asmCheckAutoSrvFlag); - - +#include "stdafx.h" + +void (__cdecl *sub_43B4D0) (); //для хоста +void (__cdecl *parseGamedataBinPre) (); +int (__cdecl *noxCheckGameFlags) (int); +void (__cdecl *noxSetGameFlags) (int); +void (__cdecl *noxClearGameFlags) (int); + +void (__cdecl *sub_461440)(int); +void (__cdecl *sub_4D6F40)(int); +void (__cdecl *sub_4D6F90)(int); +void (__cdecl *sub_4D6F60)(int); +void (__cdecl *sub_4D6F80)(int); +void (__cdecl *sub_473670)(); +void (__cdecl *sub_472520)(int); +void (__cdecl *sub_43AF50)(int); + +void *dword_748260; + +int *dword_69B55C=(int*)0x0069B55C; +int *noxGameFlags; + +extern void InjectOffs(DWORD Addr,void *Fn); +extern void InjectJumpTo(DWORD Addr,void *Fn); + +namespace +{ + void __declspec(naked) asmHostWhenStart() // хостим сервер когда стартует игра + { + __asm + { + mov eax,dword_69B55C + mov [eax+0],1 + push ecx + mov ecx,noxGameFlags + mov eax,[ecx+0] + and eax,0FFFFFFDFh + or eax,10h + mov [ecx],eax + pop ecx + push 2000h + call noxSetGameFlags + push 10000h + call noxSetGameFlags + push 800h + // call noxClearGameFlags + // push 1000000h + call noxClearGameFlags + add esp,0Ch + push 0 + call sub_461440 + push 0 + call sub_4D6F90 + push 0 + call sub_4D6F60 + push 0 + call sub_4D6F80 + call sub_473670 + push 8FCh + call sub_472520 + push 0 + call sub_43AF50 + add esp,18h + call parseGamedataBinPre + call sub_43B4D0 + mov eax,1 + push 004AB14Ch + ret + } + } + + void __cdecl checkAutoSrvFlag(char *str) + { + if (strcmp(str,"-autosrv")==0) + { + InjectJumpTo(0x004AB147,&asmHostWhenStart); + byte OperatorJmps=0xEB; + byte *bt=(byte*)(0x004AB105); + DWORD OldProtect; + VirtualProtect(bt,1,PAGE_EXECUTE_READWRITE,&OldProtect); + memcpy((byte*)bt,&OperatorJmps,1); // убираем заставочки + VirtualProtect(bt,1,OldProtect,&OldProtect); + } + if (strcmp(str, "-debug") == 0) + { + *noxGameFlags = *noxGameFlags | 0x1000000; + } + } + + void __declspec(naked) asmCheckAutoSrvFlag() // флаг проверяем + { + __asm + { + push ebp + call checkAutoSrvFlag + add esp,4 + sbb eax,eax + sbb eax,0FFFFFFFFh + push 004012B8h + ret + } + } + + + +} + + +void autoServer() +{ + + ASSIGN(sub_43B4D0,0x43B4D0); + + ASSIGN(sub_461440,0x00461440); + ASSIGN(sub_4D6F40,0x4D6F40); + ASSIGN(sub_4D6F90,0x4D6F90); + ASSIGN(sub_4D6F60,0x4D6F60); + ASSIGN(sub_4D6F80,0x4D6F80); + ASSIGN(sub_473670,0x473670); + ASSIGN(sub_472520,0x472520); + ASSIGN(sub_43AF50,0x0043AF50); // влияет на видимость игры + + ASSIGN(dword_748260,0x00748260); + + ASSIGN(parseGamedataBinPre,0x004D1630); + + ASSIGN(noxGameFlags,0x0085B7A0); + ASSIGN(noxCheckGameFlags,0x0040A5C0); + ASSIGN(noxSetGameFlags,0x0040A4D0); + ASSIGN(noxClearGameFlags,0x0040A540); + + + InjectJumpTo(0x004012B3,&asmCheckAutoSrvFlag); + + } \ No newline at end of file diff --git a/bugsAndChips.cpp b/bugsAndChips.cpp index 28ec205..1b6fce4 100644 --- a/bugsAndChips.cpp +++ b/bugsAndChips.cpp @@ -1,386 +1,386 @@ -#include "stdafx.h" -#include "unit.h" - -extern void (__cdecl *netClientSend) (int PlrN,int Dir,//1 - - void *Buf,int BufSize); - -extern void (__cdecl *wndShowHide)(void *Wnd,int Hide); - -extern DWORD *frameCounter; - - -void (__cdecl *sub_4C31D0) (int netCode); -void (__cdecl *sub_4C3147)(); -void (__cdecl *sub_4C2BF0)(); -void (__cdecl *cliSummondWndLoad) (); -void (__cdecl *wndSummonCreateList) (void*); - -BYTE *wndSummonUsed; -int wndConjSummonMsg; -int *creatureSummonCommandAll; - - - -struct creatureWhatDo -{ - int commandAll; - int mobNetCode[4]; - int command[4]; -}; - -creatureWhatDo myCreatureList; - - -namespace -{ - void __declspec(naked) asmDeathBallBugGs() // GreatSword - { - __asm - { - call noxUnitSetOwner - add esp,0Ch - cmp [ebx+4],02C2h - jnz exitL - mov eax,[ebx+2DCh] // - mov ecx,frameCounter - mov ecx,[ecx+0] - test eax,eax // 0, - jnz l1 - obnul: - mov [ebx+2DCh],ecx - mov [ebx+2E0h],0 - jmp exitL - l1: // - sub ecx,eax - cmp ecx,4 - ja obnul // 4 - mov ecx,[ebx+2E0h] - inc ecx - mov [ebx+2E0h],ecx - cmp ecx,3 - jna exitL - push ebx - call noxDeleteObject // - add esp,4 - - exitL: - push 004E1C92h - ret - } - } - - void __declspec(naked) asmDeathBallBugSh() // Shield - { - __asm - { - call noxUnitSetOwner - add esp,0Ch - cmp [ebx+4],02C2h - jnz exitL - mov eax,[ebx+2DCh] // - mov ecx,frameCounter - mov ecx,[ecx+0] - test eax,eax // 0, - jnz l1 - obnul: - mov [ebx+2DCh],ecx - mov [ebx+2E0h],0 - jmp exitL - l1: // - sub ecx,eax - cmp ecx,4 - ja obnul // 4 - mov ecx,[ebx+2E0h] - inc ecx - mov [ebx+2E0h],ecx - cmp ecx,3 - jna exitL - push ebx - call noxDeleteObject // - add esp,4 - - exitL: - push 004E1BDEh - ret - } - } - - - - void __declspec(naked) asmConjSummonEnotherCmp() // - { - __asm - { - cmp eax,9 - mov wndConjSummonMsg,eax - jnz l1 - push 004C2B32h - ret - - l1: - xor eax,eax - add esp,10h - retn - } - } - struct creatureCommand - { - BYTE msg; - short netCodeMob; - short whatDo; - }; - - void __cdecl conjSummonDo(int A,void *B) - { - BYTE *M=*((BYTE**)wndSummonUsed); - int Top=lua_gettop(L); - getServerVar("creatureSummonWhatDo"); - if (lua_type(L,-1)==LUA_TNIL) - { - wndSummonCreateList(B); - lua_settop(L,Top); - return; - } - int ForHunt=0; - if (lua_tointeger(L,-1)==1) - ForHunt=1; - creatureCommand P; - P.msg=0x78; - P.netCodeMob=(short)*((BYTE**)M); - int command=0; - if (A==1) - P.whatDo=0; // - else - { - for (int i=0;i<4;i++) - { - if (P.netCodeMob==myCreatureList.mobNetCode[i]) - { - command=myCreatureList.command[i]; - if (command<3) - P.whatDo=4; - else if(command>=4+ForHunt) - P.whatDo=3; - else - P.whatDo=myCreatureList.command[i]+1; - myCreatureList.command[i]=P.whatDo; - } - } - } - netClientSend(0x1F,0,&P,4); - lua_settop(L,Top); - } - - void __declspec(naked) asmConjSummonDo() // - { - __asm - { - add esp,4 - push eax - mov eax,wndConjSummonMsg - cmp eax,9 - jz l1 - push 0 - call conjSummonDo - jmp lex - l1: // - push 1 - call conjSummonDo - - lex: // - add esp,8 - push 004C2BBEh - ret - } - } - - void __cdecl conjSummonCreate(int netCode) - { - for (int i=0;i<4;i++) - { - if (myCreatureList.mobNetCode[i]==0) - { - myCreatureList.mobNetCode[i]=netCode; - myCreatureList.command[i]=myCreatureList.commandAll; - return; - } - } - } - void __declspec(naked) asmConjSummonCreate() // - { - __asm - { - push esi - call conjSummonCreate - add esp,4 - call cliSummondWndLoad - push 0049179Fh - ret - } - } - - void __cdecl ConjSummonDoAll() - { - int c=myCreatureList.commandAll; - for (int i=0;i<4;i++) - myCreatureList.command[i]=c; - if (c==0) - myCreatureList.commandAll=4; - } - void __declspec(naked) asmConjSummonDoAll() // - { - __asm - { - xor eax,eax - mov al,cl - mov [myCreatureList+0],eax - call ConjSummonDoAll - call netClientSend - push 004C2AD1h - ret - } - } - - void __cdecl ConjSummonLoadWnd() - { - myCreatureList.commandAll=4; - for (int i=0;i<4;i++) - { - myCreatureList.command[i]=0; - myCreatureList.mobNetCode[i]=0; - } - } - void __declspec(naked) asmConjSummonLoadWnd() // - { - __asm - { - call wndShowHide - call ConjSummonLoadWnd - push 004C1FA6h - ret - } - } - - void __cdecl ConjSummonDieOrBanish(int netCode) - { - for (int i=0;i<4;i++) - { - if (myCreatureList.mobNetCode[i]==netCode) - myCreatureList.mobNetCode[i]=0; - } - } - void __declspec(naked) asmConjSummonDieOrBanish() // - { - __asm - { - push edi - call ConjSummonDieOrBanish - add esp,4 - call sub_4C31D0 - push 004C314Ch - ret - } - } - void __cdecl fixCastFieball(float *A,float *B) - { - float *X=*((float**)A); - int *XMouse=*((int**)B); - float *Y=X+1; - int *YMouse=XMouse+1; - int cosA=*XMouse-*X; - int sinA=*YMouse-*Y; - float dist=sqrt((float)(cosA^2+sinA^2)); - *A=dist/cosA; - *B=dist/sinA; - } - - void __declspec(naked) asmFixCastFireball() // 0052C7CD - { - __asm - { - // edi - unit - test byte ptr [edi+8],4 // ? - , - jz l1 - /* mov edx,edi - add edx,0x38 - push edx - mov edx,esp - mov ecx,[edi+0x2ec] - mov ecx,[ecx+0x114] - add ecx,0x8ec - push ecx - push esp - push edx - call fixCastFieball - add esp,8 - mov edx,[esp] - mov ecx,[esp+4] - add esp,8 */ - - mov ecx,[edi+0x2ec] - mov ecx,[ecx+0x114] - sub esp,4 - fild [ecx+0x8ec] - fsub [edi+0x38] - fld st // x-x1 - fmul st,st - fstp [esp] - fild [ecx+0x8f0] - fsub [edi+0x3c] - fld st // y-y1 - fmul st,st - fadd [esp] - fsqrt - fld st - fdivp st(2),st - fdivp st(2),st - fstp [esp] //cos - mov edx,[esp] - fstp [esp] //sin - mov ecx,[esp] - add esp,4 - -l1: // exit, , - push 0052C7D9h - ret - } - } -} -extern void InjectOffs(DWORD Addr,void *Fn); -extern void InjectJumpTo(DWORD Addr,void *Fn); - -void topicOverrideInit() -{ - byte nop[2] = { 0x90, 0x90 }; - //InjectData(0x0040C29B, nop, 2); -} - -void bugsInit() -{ - - ASSIGN(wndSummonUsed,0x00716E88); - - ASSIGN(creatureSummonCommandAll,0x005B4080); - - ASSIGN(sub_4C2BF0,0x004C2BF0); - ASSIGN(sub_4C3147,0x004C3147); - ASSIGN(sub_4C31D0,0x004C31D0); - - ASSIGN(wndSummonCreateList,0x004C2560); - ASSIGN(cliSummondWndLoad,0x004C2E50); - - - InjectJumpTo(0x004E1C8A,&asmDeathBallBugGs); - InjectJumpTo(0x004E1BD6,&asmDeathBallBugSh); - - InjectJumpTo(0x004C2BC7,&asmConjSummonEnotherCmp); // - InjectJumpTo(0x004C2BB6,&asmConjSummonDo); // 2 - InjectJumpTo(0x0049179A,&asmConjSummonCreate); - InjectJumpTo(0x004C2ACC,&asmConjSummonDoAll); - InjectJumpTo(0x004C3147,&asmConjSummonDieOrBanish); - InjectJumpTo(0x004C1FA1,&asmConjSummonLoadWnd); - -// InjectJumpTo(0x0052C7CD,&asmFixCastFireball); - - topicOverrideInit(); +#include "stdafx.h" +#include "unit.h" + +extern void (__cdecl *netClientSend) (int PlrN,int Dir,//1 - клиенту + void *Buf,int BufSize); + +extern void (__cdecl *wndShowHide)(void *Wnd,int Hide); + +extern DWORD *frameCounter; + + +void (__cdecl *sub_4C31D0) (int netCode); +void (__cdecl *sub_4C3147)(); +void (__cdecl *sub_4C2BF0)(); +void (__cdecl *cliSummondWndLoad) (); +void (__cdecl *wndSummonCreateList) (void*); + +BYTE *wndSummonUsed; +int wndConjSummonMsg; +int *creatureSummonCommandAll; + + + +struct creatureWhatDo +{ + int commandAll; + int mobNetCode[4]; + int command[4]; +}; + +creatureWhatDo myCreatureList; + + +namespace +{ + void __declspec(naked) asmDeathBallBugGs() // для GreatSword + { + __asm + { + call noxUnitSetOwner + add esp,0Ch + cmp [ebx+4],02C2h + jnz exitL + mov eax,[ebx+2DCh] // теперь это время последнего коллайда + mov ecx,frameCounter + mov ecx,[ecx+0] + test eax,eax // если у нас там 0, то пишем время и выходим + jnz l1 + obnul: + mov [ebx+2DCh],ecx + mov [ebx+2E0h],0 + jmp exitL + l1: // если не ноль то смотрим что и действуем + sub ecx,eax + cmp ecx,4 + ja obnul // если прошло больше 4 кадров + mov ecx,[ebx+2E0h] + inc ecx + mov [ebx+2E0h],ecx + cmp ecx,3 + jna exitL + push ebx + call noxDeleteObject //удаляем наконец + add esp,4 + + exitL: + push 004E1C92h + ret + } + } + + void __declspec(naked) asmDeathBallBugSh() // для Shield + { + __asm + { + call noxUnitSetOwner + add esp,0Ch + cmp [ebx+4],02C2h + jnz exitL + mov eax,[ebx+2DCh] // теперь это время последнего коллайда + mov ecx,frameCounter + mov ecx,[ecx+0] + test eax,eax // если у нас там 0, то пишем время и выходим + jnz l1 + obnul: + mov [ebx+2DCh],ecx + mov [ebx+2E0h],0 + jmp exitL + l1: // если не ноль то смотрим что и действуем + sub ecx,eax + cmp ecx,4 + ja obnul // если прошло больше 4 кадров + mov ecx,[ebx+2E0h] + inc ecx + mov [ebx+2E0h],ecx + cmp ecx,3 + jna exitL + push ebx + call noxDeleteObject //удаляем наконец + add esp,4 + + exitL: + push 004E1BDEh + ret + } + } + + + + void __declspec(naked) asmConjSummonEnotherCmp() // добавляем ПКМ + { + __asm + { + cmp eax,9 + mov wndConjSummonMsg,eax + jnz l1 + push 004C2B32h + ret + + l1: + xor eax,eax + add esp,10h + retn + } + } + struct creatureCommand + { + BYTE msg; + short netCodeMob; + short whatDo; + }; + + void __cdecl conjSummonDo(int A,void *B) + { + BYTE *M=*((BYTE**)wndSummonUsed); + int Top=lua_gettop(L); + getServerVar("creatureSummonWhatDo"); + if (lua_type(L,-1)==LUA_TNIL) + { + wndSummonCreateList(B); + lua_settop(L,Top); + return; + } + int ForHunt=0; + if (lua_tointeger(L,-1)==1) + ForHunt=1; + creatureCommand P; + P.msg=0x78; + P.netCodeMob=(short)*((BYTE**)M); + int command=0; + if (A==1) + P.whatDo=0; // испариться + else + { + for (int i=0;i<4;i++) + { + if (P.netCodeMob==myCreatureList.mobNetCode[i]) + { + command=myCreatureList.command[i]; + if (command<3) + P.whatDo=4; + else if(command>=4+ForHunt) + P.whatDo=3; + else + P.whatDo=myCreatureList.command[i]+1; + myCreatureList.command[i]=P.whatDo; + } + } + } + netClientSend(0x1F,0,&P,4); + lua_settop(L,Top); + } + + void __declspec(naked) asmConjSummonDo() // когда нажали на моба + { + __asm + { + add esp,4 + push eax + mov eax,wndConjSummonMsg + cmp eax,9 + jz l1 + push 0 + call conjSummonDo + jmp lex + l1: // если ПКМ то убиваем моба + push 1 + call conjSummonDo + + lex: // выходим из сабы + add esp,8 + push 004C2BBEh + ret + } + } + + void __cdecl conjSummonCreate(int netCode) + { + for (int i=0;i<4;i++) + { + if (myCreatureList.mobNetCode[i]==0) + { + myCreatureList.mobNetCode[i]=netCode; + myCreatureList.command[i]=myCreatureList.commandAll; + return; + } + } + } + void __declspec(naked) asmConjSummonCreate() // когда создали моба прогоняем его + { + __asm + { + push esi + call conjSummonCreate + add esp,4 + call cliSummondWndLoad + push 0049179Fh + ret + } + } + + void __cdecl ConjSummonDoAll() + { + int c=myCreatureList.commandAll; + for (int i=0;i<4;i++) + myCreatureList.command[i]=c; + if (c==0) + myCreatureList.commandAll=4; + } + void __declspec(naked) asmConjSummonDoAll() // когда отпровляем команду всем + { + __asm + { + xor eax,eax + mov al,cl + mov [myCreatureList+0],eax + call ConjSummonDoAll + call netClientSend + push 004C2AD1h + ret + } + } + + void __cdecl ConjSummonLoadWnd() + { + myCreatureList.commandAll=4; + for (int i=0;i<4;i++) + { + myCreatureList.command[i]=0; + myCreatureList.mobNetCode[i]=0; + } + } + void __declspec(naked) asmConjSummonLoadWnd() // когда заргружается окна все к черту обнуляем + { + __asm + { + call wndShowHide + call ConjSummonLoadWnd + push 004C1FA6h + ret + } + } + + void __cdecl ConjSummonDieOrBanish(int netCode) + { + for (int i=0;i<4;i++) + { + if (myCreatureList.mobNetCode[i]==netCode) + myCreatureList.mobNetCode[i]=0; + } + } + void __declspec(naked) asmConjSummonDieOrBanish() // когда моб сдыхает + { + __asm + { + push edi + call ConjSummonDieOrBanish + add esp,4 + call sub_4C31D0 + push 004C314Ch + ret + } + } + void __cdecl fixCastFieball(float *A,float *B) + { + float *X=*((float**)A); + int *XMouse=*((int**)B); + float *Y=X+1; + int *YMouse=XMouse+1; + int cosA=*XMouse-*X; + int sinA=*YMouse-*Y; + float dist=sqrt((float)(cosA^2+sinA^2)); + *A=dist/cosA; + *B=dist/sinA; + } + + void __declspec(naked) asmFixCastFireball() // 0052C7CD + { + __asm + { + // edi - unit + test byte ptr [edi+8],4 // игрок ли? Мало-ли что, мб у меня параноя + jz l1 + /* mov edx,edi + add edx,0x38 + push edx + mov edx,esp + mov ecx,[edi+0x2ec] + mov ecx,[ecx+0x114] + add ecx,0x8ec + push ecx + push esp + push edx + call fixCastFieball + add esp,8 + mov edx,[esp] + mov ecx,[esp+4] + add esp,8 */ + + mov ecx,[edi+0x2ec] + mov ecx,[ecx+0x114] + sub esp,4 + fild [ecx+0x8ec] + fsub [edi+0x38] + fld st // x-x1 + fmul st,st + fstp [esp] + fild [ecx+0x8f0] + fsub [edi+0x3c] + fld st // y-y1 + fmul st,st + fadd [esp] + fsqrt + fld st + fdivp st(2),st + fdivp st(2),st + fstp [esp] //cos + mov edx,[esp] + fstp [esp] //sin + mov ecx,[esp] + add esp,4 + +l1: // exit, как то блин так и назвал, удивлялся почему нокс закрывается + push 0052C7D9h + ret + } + } +} +extern void InjectOffs(DWORD Addr,void *Fn); +extern void InjectJumpTo(DWORD Addr,void *Fn); + +void topicOverrideInit() +{ + byte nop[2] = { 0x90, 0x90 }; + //InjectData(0x0040C29B, nop, 2); +} + +void bugsInit() +{ + + ASSIGN(wndSummonUsed,0x00716E88); + + ASSIGN(creatureSummonCommandAll,0x005B4080); + + ASSIGN(sub_4C2BF0,0x004C2BF0); + ASSIGN(sub_4C3147,0x004C3147); + ASSIGN(sub_4C31D0,0x004C31D0); + + ASSIGN(wndSummonCreateList,0x004C2560); + ASSIGN(cliSummondWndLoad,0x004C2E50); + + + InjectJumpTo(0x004E1C8A,&asmDeathBallBugGs); + InjectJumpTo(0x004E1BD6,&asmDeathBallBugSh); + + InjectJumpTo(0x004C2BC7,&asmConjSummonEnotherCmp); // делаем возможность ПКМ + InjectJumpTo(0x004C2BB6,&asmConjSummonDo); // ставим вместо списка наши 2 прикольные штуки + InjectJumpTo(0x0049179A,&asmConjSummonCreate); + InjectJumpTo(0x004C2ACC,&asmConjSummonDoAll); + InjectJumpTo(0x004C3147,&asmConjSummonDieOrBanish); + InjectJumpTo(0x004C1FA1,&asmConjSummonLoadWnd); + +// InjectJumpTo(0x0052C7CD,&asmFixCastFireball); + + topicOverrideInit(); } \ No newline at end of file diff --git a/cliUtil.cpp b/cliUtil.cpp index e4efeec..7cdb223 100644 --- a/cliUtil.cpp +++ b/cliUtil.cpp @@ -1,434 +1,434 @@ -#include "stdafx.h" -#include "unit.h" -#include "player.h" -#include - -int (__cdecl *getTTByNameSpriteMB)(void *Key); -int (__cdecl *createTextBubble)(void *BubbleStruct,wchar_t *Str); -void (__cdecl *sub_4738E0) (); - -extern void (__cdecl *netClientSend) (int PlrN,int Dir,//1 - - void *Buf,int BufSize); -extern DWORD (__cdecl *netGetUnitCodeServ)(void *Unit); -extern void (__cdecl *noxGuiDrawCursor) (); -int (__cdecl *mathAnglTo256) (void *xycords); - -void *noxSpriteLast=0; -DWORD *gameFPS=(DWORD*)0x0085B3FC; - -int (__cdecl *netSendClientReady)(); - -extern int (__cdecl *noxCheckGameFlags) (int); - -namespace -{ - bool cliAutoexecExecuted = false; - bool newMapCli = false; - bool onClientQuitServer(int gf) - { - bool result = noxCheckGameFlags(gf); - getClientVar("onCliGameQuit"); - if (lua_isfunction(L,-1)) - lua_pcall(L,0,0,0); - cliAutoexecExecuted = false; - return result; - } - - int onMapLoadCli() - { - newMapCli = true; - return netSendClientReady(); - } - - DWORD *frameCounter=(DWORD*)0x0084EA04; - - int cliTimeoutNextId=1; - struct cliTimeoutListRec - { - int Id; - DWORD Frame; - cliTimeoutListRec(int Id_,DWORD Frame_):Id(Id_),Frame(Frame_) - {} - }; - std::list cliTimeoutList; - int cliSetTimeoutL(lua_State *L) /// 3- - - { - lua_settop(L,3); - if ((lua_type(L,1)!=LUA_TFUNCTION) ||(lua_type(L,2)!=LUA_TNUMBER) - || ((lua_type(L,3)!=LUA_TTABLE) && (lua_type(L,3)!=LUA_TNIL)) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - lua_pushlightuserdata(L,&cliSetTimeoutL);/// - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushinteger(L,cliTimeoutNextId); - lua_pushvalue(L,1); - lua_settable(L,-3); - lua_pushlightuserdata(L,&cliTimeoutNextId);/// - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushinteger(L,cliTimeoutNextId); - lua_pushvalue(L,3); - lua_settable(L,-3); - - - lua_pushinteger(L,cliTimeoutNextId); - - DWORD Time=*frameCounter +(DWORD)lua_tointeger(L,2); - - std::list::iterator I; - for (I=cliTimeoutList.begin();I!=cliTimeoutList.end();I++) - { - if(I->Frame > Time) - break; - } - cliTimeoutList.insert(I,cliTimeoutListRec(cliTimeoutNextId++,Time) ); - return 1; - } - - void __cdecl cliOnEachFrame() - { - DWORD Time=*frameCounter; - int Top=lua_gettop(L); - lua_pushlightuserdata(L,&cliTimeoutNextId);/// - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,&cliSetTimeoutL);/// - lua_gettable(L,LUA_REGISTRYINDEX); - - for (std::list::iterator I=cliTimeoutList.begin();I!=cliTimeoutList.end();) - { - if ( Time < I->Frame ) - break; - lua_pushinteger(L,I->Id); - if (I->Frame <= Time) - { - lua_gettable(L,-2); - if(lua_type(L,-1)==LUA_TFUNCTION) - { - - - lua_pushinteger(L,Time); - lua_pushinteger(L,I->Id); - // - lua_gettable(L,-5); // id,Time,Fn, {Fns},{Args} - if (0!=lua_pcall(L,2,0,0)) - { - const char* errorStr = lua_tostring(L, -1); - char Err[200]; - strcpy(Err, "delayed error: "); - strncat(&Err[strlen(Err)], errorStr, (199 - strlen(Err))); - conPrintI(Err); - lua_pop(L, 1); - } - ///conOutput,env, fn, {Fns},{Args} - /* lua_getfield(L,-2,"conOutput");// conOutput - if (lua_type(L,-1)==LUA_TNIL) // - , ? - { - lua_pop(L,1); - lua_setfield(L,-2,"conOutput"); - lua_pop(L,2); - } - else - lua_pop(L,3); */ - - lua_pushinteger(L,I->Id); // - } - else - lua_pop(L,1); - - } - lua_pushnil(L); - lua_settable(L,-3); // - lua_pushinteger(L,I->Id); - lua_pushnil(L); - lua_settable(L,-4);// - - I=cliTimeoutList.erase(I); - } - lua_settop(L,Top); - } - - - - - - - void __declspec(naked) asmToCliTimer() // - { - __asm - { - call noxGuiDrawCursor - call cliOnEachFrame - push 0x0043E77D - ret - } - } - struct BubblePacket - { - byte PacketType;//+0 - short NetCode;//+1 - byte Dummy;// +3 - short PosX,PosY;//+4 - byte TimeoutSecMB;//+8 - short TimeoutFrames;//+9 0 - - - }; - int cliShowBubble(lua_State *L) /// 3- - - { - lua_settop(L,3); - if ( (!lua_isnumber(L,1)) - || (!lua_isstring(L,2)) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - BubblePacket P; - memset(&P,0,sizeof(P)); - P.NetCode=lua_tointeger(L,1); - int v=lua_tointeger(L,3); - if (v<1 || v>250) - v=2; - P.TimeoutSecMB=v; - wchar_t WBuf[100]; - mbstowcs(WBuf,lua_tostring(L,2),99); - createTextBubble(&P,WBuf); - return 0; - } - //, , [ == ],[==2] - int createBubble(lua_State *L) /// 3- - - { - lua_settop(L,5); - - int i=2; - int x=0,y=0; - short Code=0; - if (lua_isuserdata(L,1)) - { - void *Unit=lua_touserdata(L,1); - if (Unit==0) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - Code=netGetUnitCodeServ(Unit); - }else if ( lua_isnumber(L,1)) - { - x=lua_tointeger(L,1); - y=lua_tointeger(L,2); - i++; - } - else - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - - size_t Len; - const char *S=lua_tolstring(L,i,&Len); - i++; - if (lua_istable(L,i)) - { - i++; - } - int v=lua_tointeger(L,i); - if (v<1 || v>250) - v=2; - if (Len>200) - Len=200; - BYTE Buf[208],*P=Buf; - netUniPacket(upSendBubble,P,Len+6); - - if (Code==0) - *((unsigned short*)P)=x; - else - *((unsigned short*)P)=Code; - P+=2; - *((unsigned short*)P)=y; - P+=2; - *(P++)=v; - memcpy(P,S,Len+1); - P+=Len; - for(bigUnitStruct* Plr=playerFirstUnit();Plr!=0;Plr=playerNextUnit(Plr)) - { - if ((Code!=0)?(i!=3):(i!=4)) - { - bool Skip=true; - lua_pushnil(L); - while (lua_next(L,i-1)!=0) - { - lua_pushlightuserdata(L,Plr); - if (lua_equal(L,-1,-2)) - { - Skip=false; - lua_pop(L,3); - break; - } - lua_pop(L,2); - } - if (Skip) - continue; - } - BYTE *P2=(BYTE*)Plr->unitController; - P2+=0x114;P2=*((BYTE **)P2); - P2+=0x810; - netClientSend(*P2,1,Buf,P-Buf); - } - - return 0; - } - void netOnBubble(BYTE *Packet) - { - - BubblePacket P; - memset(&P,0,sizeof(P)); - P.PosX=*((short*)Packet); - Packet+=2; - P.PosY=*((short*)Packet); - Packet+=2; - if (P.PosY==0) - { - P.NetCode=P.PosX; - P.PosX=0; - } - int v=*(Packet++); - if (v<1 || v>250) - v=2; - P.TimeoutFrames= v * (*gameFPS); - wchar_t WBuf[240]; - mbstowcs(WBuf,(char*)Packet,240); - createTextBubble(&P,WBuf); - } - - - int spriteGetL(lua_State*L) - { - if (lua_type(L,1)!=LUA_TFUNCTION) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - BYTE *P=(BYTE*)noxSpriteLast; // - P=*(BYTE**)(P); - if (P==0) - return 0; - BYTE *P1=P; - while (P!=0) - { - lua_pushvalue(L,1); - lua_pushlightuserdata(L,(void *)P); - lua_pcall(L,1,0,0); - P=*(BYTE**)(P+0x170); - } - return 0; - } - - int spriteGetPosL(lua_State*L) - { - if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) - { - lua_pushstring(L,"wrong args"); - lua_error_(L); - } - BYTE *P=(BYTE*) lua_touserdata(L,1); - lua_pushnumber(L,*((int*)(P+0xC))); - lua_pushnumber(L,*((int*)(P+0x10))); - return 2; - } - - int spriteThingTypeL(lua_State*L) - { - if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) - { - lua_pushstring(L,"wrong args"); - lua_error_(L); - } - BYTE *P=(BYTE*) lua_touserdata(L,1); - lua_pushnumber(L,*((int*)(P+0x6C))); - return 1; - } - - struct xyCoords - { - float x; - float y; - }; - int directL(lua_State*L) - { - if (lua_type(L,1)!=LUA_TNUMBER || - lua_type(L,2)!=LUA_TNUMBER || - lua_type(L,3)!=LUA_TNUMBER || - lua_type(L,4)!=LUA_TNUMBER) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - float x=lua_tonumber(L,1) - lua_tonumber(L,3); - float y=lua_tonumber(L,2) - lua_tonumber(L,4); - xyCoords xy; - xy.x=x; xy.y=y; - int ang=mathAnglTo256(&xy); - lua_pushinteger(L,ang); - return 1; - } - -} - -extern void InjectOffs(DWORD Addr,void *Fn); -extern void InjectJumpTo(DWORD Addr,void *Fn); -extern void InjectAddr(DWORD Addr,void *Fn); -void cliUntilInit() -{ - ASSIGN(getTTByNameSpriteMB,0x044CFC0); - ASSIGN(createTextBubble,0x0048D880); - ASSIGN(sub_4738E0,0x004738E0); - ASSIGN(noxSpriteLast,0x006D3DC0); - ASSIGN(mathAnglTo256,0x00509ED0); // arrrr - ASSIGN(netSendClientReady,0x0043C9F0); - - - - lua_pushlightuserdata(L,&cliSetTimeoutL);/// - lua_newtable(L); - lua_settable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,&cliTimeoutNextId);/// - lua_newtable(L); - lua_settable(L,LUA_REGISTRYINDEX); - - - lua_pushcfunction(L,&cliSetTimeoutL); - // , - // - lua_pushvalue(L,-1); - lua_setfield(L,LUA_REGISTRYINDEX,"cliSetTimeout"); - registerClientVar("cliSetTimeout"); - registerclient("spriteGet",&spriteGetL); - registerclient("cliBubble",&cliShowBubble); - registerserver("createBubble",&createBubble); - registerclient("spriteGetPos",&spriteGetPosL); - registerclient("spriteThingType",&spriteThingTypeL); - registerclient("directGet",&directL); - netRegClientPacket(upSendBubble,&netOnBubble); - - InjectJumpTo(0x0043E778,&asmToCliTimer); - InjectOffs(0x004460C5+1,&onClientQuitServer); - InjectOffs(0x0043E163+1,&onMapLoadCli); - InjectOffs(0x0043DF66+1,&onMapLoadCli); - -} - -void autoexecCli() -{ - if(newMapCli) - { - newMapCli = false; - if(!cliAutoexecExecuted) - if(luaL_loadfile(L, "autoexec_cli.lua")==0) - lua_pcall(L, 0, 0, 0); - cliAutoexecExecuted = true; - getClientVar("onCliMapLoad"); - if (lua_isfunction(L,-1)) - lua_pcall(L,0,0,0); - } +#include "stdafx.h" +#include "unit.h" +#include "player.h" +#include + +int (__cdecl *getTTByNameSpriteMB)(void *Key); +int (__cdecl *createTextBubble)(void *BubbleStruct,wchar_t *Str); +void (__cdecl *sub_4738E0) (); + +extern void (__cdecl *netClientSend) (int PlrN,int Dir,//1 - клиенту + void *Buf,int BufSize); +extern DWORD (__cdecl *netGetUnitCodeServ)(void *Unit); +extern void (__cdecl *noxGuiDrawCursor) (); +int (__cdecl *mathAnglTo256) (void *xycords); + +void *noxSpriteLast=0; +DWORD *gameFPS=(DWORD*)0x0085B3FC; + +int (__cdecl *netSendClientReady)(); + +extern int (__cdecl *noxCheckGameFlags) (int); + +namespace +{ + bool cliAutoexecExecuted = false; + bool newMapCli = false; + bool onClientQuitServer(int gf) + { + bool result = noxCheckGameFlags(gf); + getClientVar("onCliGameQuit"); + if (lua_isfunction(L,-1)) + lua_pcall(L,0,0,0); + cliAutoexecExecuted = false; + return result; + } + + int onMapLoadCli() + { + newMapCli = true; + return netSendClientReady(); + } + + DWORD *frameCounter=(DWORD*)0x0084EA04; + + int cliTimeoutNextId=1; + struct cliTimeoutListRec + { + int Id; + DWORD Frame; + cliTimeoutListRec(int Id_,DWORD Frame_):Id(Id_),Frame(Frame_) + {} + }; + std::list cliTimeoutList; + int cliSetTimeoutL(lua_State *L) /// теперь получает 3-й аргумент - таблицу + { + lua_settop(L,3); + if ((lua_type(L,1)!=LUA_TFUNCTION) ||(lua_type(L,2)!=LUA_TNUMBER) + || ((lua_type(L,3)!=LUA_TTABLE) && (lua_type(L,3)!=LUA_TNIL)) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + lua_pushlightuserdata(L,&cliSetTimeoutL);/// функции + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushinteger(L,cliTimeoutNextId); + lua_pushvalue(L,1); + lua_settable(L,-3); + lua_pushlightuserdata(L,&cliTimeoutNextId);/// сюда положим таблицу + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushinteger(L,cliTimeoutNextId); + lua_pushvalue(L,3); + lua_settable(L,-3); + + + lua_pushinteger(L,cliTimeoutNextId); + + DWORD Time=*frameCounter +(DWORD)lua_tointeger(L,2); + + std::list::iterator I; + for (I=cliTimeoutList.begin();I!=cliTimeoutList.end();I++) + { + if(I->Frame > Time) + break; + } + cliTimeoutList.insert(I,cliTimeoutListRec(cliTimeoutNextId++,Time) ); + return 1; + } + + void __cdecl cliOnEachFrame() + { + DWORD Time=*frameCounter; + int Top=lua_gettop(L); + lua_pushlightuserdata(L,&cliTimeoutNextId);/// таблица аргументов + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,&cliSetTimeoutL);/// таблица функций + lua_gettable(L,LUA_REGISTRYINDEX); + + for (std::list::iterator I=cliTimeoutList.begin();I!=cliTimeoutList.end();) + { + if ( Time < I->Frame ) + break; + lua_pushinteger(L,I->Id); + if (I->Frame <= Time) + { + lua_gettable(L,-2); + if(lua_type(L,-1)==LUA_TFUNCTION) + { + + + lua_pushinteger(L,Time); + lua_pushinteger(L,I->Id); + // таблица с аргументом + lua_gettable(L,-5); // id,Time,Fn, {Fns},{Args} + if (0!=lua_pcall(L,2,0,0)) + { + const char* errorStr = lua_tostring(L, -1); + char Err[200]; + strcpy(Err, "delayed error: "); + strncat(&Err[strlen(Err)], errorStr, (199 - strlen(Err))); + conPrintI(Err); + lua_pop(L, 1); + } + ///conOutput,env, fn, {Fns},{Args} + /* lua_getfield(L,-2,"conOutput");// conOutput функция енв функция + if (lua_type(L,-1)==LUA_TNIL) // если задали другую функцию - то так и оставим, но как ее обнулить? + { + lua_pop(L,1); + lua_setfield(L,-2,"conOutput"); + lua_pop(L,2); + } + else + lua_pop(L,3); */ + + lua_pushinteger(L,I->Id); // чтобы было чего удалять + } + else + lua_pop(L,1); + + } + lua_pushnil(L); + lua_settable(L,-3); // удаляем функцию + lua_pushinteger(L,I->Id); + lua_pushnil(L); + lua_settable(L,-4);// удаляем аргумент + + I=cliTimeoutList.erase(I); + } + lua_settop(L,Top); + } + + + + + + + void __declspec(naked) asmToCliTimer() // вызываем тик + { + __asm + { + call noxGuiDrawCursor + call cliOnEachFrame + push 0x0043E77D + ret + } + } + struct BubblePacket + { + byte PacketType;//+0 + short NetCode;//+1 + byte Dummy;// +3 + short PosX,PosY;//+4 + byte TimeoutSecMB;//+8 + short TimeoutFrames;//+9 если 0 - использвоать в секундах + + }; + int cliShowBubble(lua_State *L) /// теперь получает 3-й аргумент - таблицу + { + lua_settop(L,3); + if ( (!lua_isnumber(L,1)) + || (!lua_isstring(L,2)) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + BubblePacket P; + memset(&P,0,sizeof(P)); + P.NetCode=lua_tointeger(L,1); + int v=lua_tointeger(L,3); + if (v<1 || v>250) + v=2; + P.TimeoutSecMB=v; + wchar_t WBuf[100]; + mbstowcs(WBuf,lua_tostring(L,2),99); + createTextBubble(&P,WBuf); + return 0; + } + //юнит, строка, [таблица кому == всем],[таймаут==2] + int createBubble(lua_State *L) /// теперь получает 3-й аргумент - таблицу + { + lua_settop(L,5); + + int i=2; + int x=0,y=0; + short Code=0; + if (lua_isuserdata(L,1)) + { + void *Unit=lua_touserdata(L,1); + if (Unit==0) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + Code=netGetUnitCodeServ(Unit); + }else if ( lua_isnumber(L,1)) + { + x=lua_tointeger(L,1); + y=lua_tointeger(L,2); + i++; + } + else + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + + size_t Len; + const char *S=lua_tolstring(L,i,&Len); + i++; + if (lua_istable(L,i)) + { + i++; + } + int v=lua_tointeger(L,i); + if (v<1 || v>250) + v=2; + if (Len>200) + Len=200; + BYTE Buf[208],*P=Buf; + netUniPacket(upSendBubble,P,Len+6); + + if (Code==0) + *((unsigned short*)P)=x; + else + *((unsigned short*)P)=Code; + P+=2; + *((unsigned short*)P)=y; + P+=2; + *(P++)=v; + memcpy(P,S,Len+1); + P+=Len; + for(bigUnitStruct* Plr=playerFirstUnit();Plr!=0;Plr=playerNextUnit(Plr)) + { + if ((Code!=0)?(i!=3):(i!=4)) + { + bool Skip=true; + lua_pushnil(L); + while (lua_next(L,i-1)!=0) + { + lua_pushlightuserdata(L,Plr); + if (lua_equal(L,-1,-2)) + { + Skip=false; + lua_pop(L,3); + break; + } + lua_pop(L,2); + } + if (Skip) + continue; + } + BYTE *P2=(BYTE*)Plr->unitController; + P2+=0x114;P2=*((BYTE **)P2); + P2+=0x810; + netClientSend(*P2,1,Buf,P-Buf); + } + + return 0; + } + void netOnBubble(BYTE *Packet) + { + + BubblePacket P; + memset(&P,0,sizeof(P)); + P.PosX=*((short*)Packet); + Packet+=2; + P.PosY=*((short*)Packet); + Packet+=2; + if (P.PosY==0) + { + P.NetCode=P.PosX; + P.PosX=0; + } + int v=*(Packet++); + if (v<1 || v>250) + v=2; + P.TimeoutFrames= v * (*gameFPS); + wchar_t WBuf[240]; + mbstowcs(WBuf,(char*)Packet,240); + createTextBubble(&P,WBuf); + } + + + int spriteGetL(lua_State*L) + { + if (lua_type(L,1)!=LUA_TFUNCTION) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + BYTE *P=(BYTE*)noxSpriteLast; // непотяно все ли спрайты попадут или нет + P=*(BYTE**)(P); + if (P==0) + return 0; + BYTE *P1=P; + while (P!=0) + { + lua_pushvalue(L,1); + lua_pushlightuserdata(L,(void *)P); + lua_pcall(L,1,0,0); + P=*(BYTE**)(P+0x170); + } + return 0; + } + + int spriteGetPosL(lua_State*L) + { + if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) + { + lua_pushstring(L,"wrong args"); + lua_error_(L); + } + BYTE *P=(BYTE*) lua_touserdata(L,1); + lua_pushnumber(L,*((int*)(P+0xC))); + lua_pushnumber(L,*((int*)(P+0x10))); + return 2; + } + + int spriteThingTypeL(lua_State*L) + { + if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) + { + lua_pushstring(L,"wrong args"); + lua_error_(L); + } + BYTE *P=(BYTE*) lua_touserdata(L,1); + lua_pushnumber(L,*((int*)(P+0x6C))); + return 1; + } + + struct xyCoords + { + float x; + float y; + }; + int directL(lua_State*L) + { + if (lua_type(L,1)!=LUA_TNUMBER || + lua_type(L,2)!=LUA_TNUMBER || + lua_type(L,3)!=LUA_TNUMBER || + lua_type(L,4)!=LUA_TNUMBER) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + float x=lua_tonumber(L,1) - lua_tonumber(L,3); + float y=lua_tonumber(L,2) - lua_tonumber(L,4); + xyCoords xy; + xy.x=x; xy.y=y; + int ang=mathAnglTo256(&xy); + lua_pushinteger(L,ang); + return 1; + } + +} + +extern void InjectOffs(DWORD Addr,void *Fn); +extern void InjectJumpTo(DWORD Addr,void *Fn); +extern void InjectAddr(DWORD Addr,void *Fn); +void cliUntilInit() +{ + ASSIGN(getTTByNameSpriteMB,0x044CFC0); + ASSIGN(createTextBubble,0x0048D880); + ASSIGN(sub_4738E0,0x004738E0); + ASSIGN(noxSpriteLast,0x006D3DC0); + ASSIGN(mathAnglTo256,0x00509ED0); // arrrr + ASSIGN(netSendClientReady,0x0043C9F0); + + + + lua_pushlightuserdata(L,&cliSetTimeoutL);/// функции + lua_newtable(L); + lua_settable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,&cliTimeoutNextId);/// значения + lua_newtable(L); + lua_settable(L,LUA_REGISTRYINDEX); + + + lua_pushcfunction(L,&cliSetTimeoutL); + // очень важная функция, ее надо в реестр луа класть + // чтобы нельзя было удалить случайно + lua_pushvalue(L,-1); + lua_setfield(L,LUA_REGISTRYINDEX,"cliSetTimeout"); + registerClientVar("cliSetTimeout"); + registerclient("spriteGet",&spriteGetL); + registerclient("cliBubble",&cliShowBubble); + registerserver("createBubble",&createBubble); + registerclient("spriteGetPos",&spriteGetPosL); + registerclient("spriteThingType",&spriteThingTypeL); + registerclient("directGet",&directL); + netRegClientPacket(upSendBubble,&netOnBubble); + + InjectJumpTo(0x0043E778,&asmToCliTimer); + InjectOffs(0x004460C5+1,&onClientQuitServer); + InjectOffs(0x0043E163+1,&onMapLoadCli); + InjectOffs(0x0043DF66+1,&onMapLoadCli); + +} + +void autoexecCli() +{ + if(newMapCli) + { + newMapCli = false; + if(!cliAutoexecExecuted) + if(luaL_loadfile(L, "autoexec_cli.lua")==0) + lua_pcall(L, 0, 0, 0); + cliAutoexecExecuted = true; + getClientVar("onCliMapLoad"); + if (lua_isfunction(L,-1)) + lua_pcall(L,0,0,0); + } } \ No newline at end of file diff --git a/clientView.cpp b/clientView.cpp index b8a0bfc..f9744ce 100644 --- a/clientView.cpp +++ b/clientView.cpp @@ -1,191 +1,191 @@ -#include "stdafx.h" -#include "unit.h" -BYTE *(__cdecl *playerInfoFromNetCodeCli) (int NetCode); -void (__cdecl *clientCollideOrUse)(void *sprite); -extern BYTE **clientPlayerInfoPtr; -extern DWORD (__cdecl *netGetUnitCodeCli)(void *Sprite); -extern bigUnitStruct *netUnitByCodeServ(DWORD NetCode); - -namespace -{ - int *idPolyp; - int (__cdecl *client_4984B0)(void *sprite); - - void __cdecl onClientUse(void *sprite) - {// - // , , - //clientCollideOrUse(sprite); - if (sprite==NULL) - return; - BYTE Buf[20]; - BYTE *Pt=Buf; - - netUniPacket(upTryUnitUse,Pt,3); -// *(Pt++) = (3 & (*clientPlayerInfoPtr)[0xE60]); // - *((WORD*)Pt)=netGetUnitCodeCli(sprite); - Pt+=2; - netSendServ(Buf,Pt-Buf); - } - -#define or | - int __cdecl clientPick1(BYTE *sprite, - DWORD Class,DWORD SubClass,int TT,int NetCode) /// - { - int Top=lua_gettop(L); - lua_getglobal(L,"clientOnUnitHover"); - if (lua_type(L,-1)==LUA_TFUNCTION) - { - lua_pushinteger(L,TT); - lua_pushinteger(L,NetCode); - lua_pushlightuserdata(L,sprite); - if (0==lua_pcall(L,3,1,0)) - { - int X=lua_tointeger(L,-1); - if (X>0) - { - lua_settop(L,Top); - return 1; - }else if(X<0) - { - lua_settop(L,Top); - return 0; - } - } - } - lua_settop(L,Top); - - if (Class & clMonster) - { - if (0x4000 & SubClass) - return 0; //no target - } - if (0==(Class & (clMonster or clPlayer or clTrigger or clImmobile or clPickup ))) - { - if (TT!=*idPolyp) return 0; - } - if (0==client_4984B0(sprite)) - return 0; - if (Class & clPlayer) - { - BYTE *P=playerInfoFromNetCodeCli(NetCode); - if (P==NULL) return 0; - if (P[0xE60] & 1) return 0; - } - if (Class & clImmobile) - { - if (0== (SubClass & 0x80)) return 0; - } - if (Class & clMonster) - { - if ( 0xA==*((DWORD*)(sprite+0x114))) - return 0; //no target - } - return 1; - } - int __cdecl clientPick2(BYTE *sprite, - DWORD Class,DWORD SubClass,int TT,int NetCode) - /// - { - int Top=lua_gettop(L); - lua_getglobal(L,"clientOnUnitHover"); - if (lua_type(L,-1)==LUA_TFUNCTION) - { - lua_pushinteger(L,TT); - lua_pushinteger(L,NetCode); - lua_pushlightuserdata(L,sprite); - if (0==lua_pcall(L,3,1,0)) - { - int X=lua_tointeger(L,-1); - lua_settop(L,Top); - return X; - } - } - lua_settop(L,Top); - - return 0; - } -#undef or - - void __declspec(naked) clientPick1Pre() - { - __asm{ - push [esi+0x80] - push [esi+0x6C] - push [esi+0x74] - push [esi+0x70] - push esi - call clientPick1 - add esp,0x14 - test eax,eax - jnz l1 - push 0x004773AF - ret - l1: - push 0x00477140 - ret - } - } - void __declspec(naked) clientPick2Pre() - { - __asm{ - push [edi+0x80] - push [edi+0x6C] - push [edi+0x74] - push [edi+0x70] - push edi - call clientPick2 - add esp,0x14 - test eax,eax - jnz l1 - mov eax,[edi+0x70] - test eax, 2|4|0x400000 //lMonster | clPlayer | clImmobile - jz l2 - push 0x0046BE27 - ret - l2: - push 0x0046BF07 - ret - l1: - push eax - push 0x0046C0CA // - ret - } - } - -} -void netOnClientTryUse(BYTE *Start,BYTE *End,BYTE *MyUc,void *Player) // -{ - BYTE *P=Start; - BYTE *PI=*((BYTE**)(MyUc+0x114)); - if (0!=(0x3&PI[0xE60]) ) - return; - if (0!= *((DWORD*)(MyUc+0x118))) - return; - if (0!= *((DWORD*)(MyUc+0x11C))) - return; - bigUnitStruct *Unit=netUnitByCodeServ(*((WORD*)(Start))); - void (__cdecl *Fn)(void *Me,void *Player,int); - if (Unit==NULL) - return; - if (Unit->collideFn!=NULL) - { - ASSIGN(Fn,Unit->collideFn); - Fn(Unit,Player,0); - } - -} - -extern void InjectJumpTo(DWORD Addr,void *Fn); -extern void InjectOffs(DWORD Addr,void *Fn); -void clientViewInit() -{ - ASSIGN(idPolyp,0x006E015C); - ASSIGN(client_4984B0,0x004984B0); - ASSIGN(playerInfoFromNetCodeCli,0x00417040); - ASSIGN(clientCollideOrUse,0x0042E810); - - InjectOffs(0x0042D820+1,onClientUse); - InjectJumpTo(0x004770B6,&clientPick1Pre); - InjectJumpTo(0x0046BE1A,&clientPick2Pre); -} - +#include "stdafx.h" +#include "unit.h" +BYTE *(__cdecl *playerInfoFromNetCodeCli) (int NetCode); +void (__cdecl *clientCollideOrUse)(void *sprite); +extern BYTE **clientPlayerInfoPtr; +extern DWORD (__cdecl *netGetUnitCodeCli)(void *Sprite); +extern bigUnitStruct *netUnitByCodeServ(DWORD NetCode); + +namespace +{ + int *idPolyp; + int (__cdecl *client_4984B0)(void *sprite); + + void __cdecl onClientUse(void *sprite) + {// сюда мы попадаем когда клиент нажал кнопку + //не будем вызывать коллайд, пошлем свой пакет, а сервер пусть разбирается + //clientCollideOrUse(sprite); + if (sprite==NULL) + return; + BYTE Buf[20]; + BYTE *Pt=Buf; + + netUniPacket(upTryUnitUse,Pt,3); +// *(Pt++) = (3 & (*clientPlayerInfoPtr)[0xE60]); // если обсервер или куда нить смотрит + *((WORD*)Pt)=netGetUnitCodeCli(sprite); + Pt+=2; + netSendServ(Buf,Pt-Buf); + } + +#define or | + int __cdecl clientPick1(BYTE *sprite, + DWORD Class,DWORD SubClass,int TT,int NetCode) /// проверяет выделяемость цели + { + int Top=lua_gettop(L); + lua_getglobal(L,"clientOnUnitHover"); + if (lua_type(L,-1)==LUA_TFUNCTION) + { + lua_pushinteger(L,TT); + lua_pushinteger(L,NetCode); + lua_pushlightuserdata(L,sprite); + if (0==lua_pcall(L,3,1,0)) + { + int X=lua_tointeger(L,-1); + if (X>0) + { + lua_settop(L,Top); + return 1; + }else if(X<0) + { + lua_settop(L,Top); + return 0; + } + } + } + lua_settop(L,Top); + + if (Class & clMonster) + { + if (0x4000 & SubClass) + return 0; //no target + } + if (0==(Class & (clMonster or clPlayer or clTrigger or clImmobile or clPickup ))) + { + if (TT!=*idPolyp) return 0; + } + if (0==client_4984B0(sprite)) + return 0; + if (Class & clPlayer) + { + BYTE *P=playerInfoFromNetCodeCli(NetCode); + if (P==NULL) return 0; + if (P[0xE60] & 1) return 0; + } + if (Class & clImmobile) + { + if (0== (SubClass & 0x80)) return 0; + } + if (Class & clMonster) + { + if ( 0xA==*((DWORD*)(sprite+0x114))) + return 0; //no target + } + return 1; + } + int __cdecl clientPick2(BYTE *sprite, + DWORD Class,DWORD SubClass,int TT,int NetCode) + /// определяет какой курсор цели рисовать + { + int Top=lua_gettop(L); + lua_getglobal(L,"clientOnUnitHover"); + if (lua_type(L,-1)==LUA_TFUNCTION) + { + lua_pushinteger(L,TT); + lua_pushinteger(L,NetCode); + lua_pushlightuserdata(L,sprite); + if (0==lua_pcall(L,3,1,0)) + { + int X=lua_tointeger(L,-1); + lua_settop(L,Top); + return X; + } + } + lua_settop(L,Top); + + return 0; + } +#undef or + + void __declspec(naked) clientPick1Pre() + { + __asm{ + push [esi+0x80] + push [esi+0x6C] + push [esi+0x74] + push [esi+0x70] + push esi + call clientPick1 + add esp,0x14 + test eax,eax + jnz l1 + push 0x004773AF + ret + l1: + push 0x00477140 + ret + } + } + void __declspec(naked) clientPick2Pre() + { + __asm{ + push [edi+0x80] + push [edi+0x6C] + push [edi+0x74] + push [edi+0x70] + push edi + call clientPick2 + add esp,0x14 + test eax,eax + jnz l1 + mov eax,[edi+0x70] + test eax, 2|4|0x400000 //сlMonster | clPlayer | clImmobile + jz l2 + push 0x0046BE27 + ret + l2: + push 0x0046BF07 + ret + l1: + push eax + push 0x0046C0CA // устанавливаем иконку + ret + } + } + +} +void netOnClientTryUse(BYTE *Start,BYTE *End,BYTE *MyUc,void *Player) // к серверу пришел пакет +{ + BYTE *P=Start; + BYTE *PI=*((BYTE**)(MyUc+0x114)); + if (0!=(0x3&PI[0xE60]) ) + return; + if (0!= *((DWORD*)(MyUc+0x118))) + return; + if (0!= *((DWORD*)(MyUc+0x11C))) + return; + bigUnitStruct *Unit=netUnitByCodeServ(*((WORD*)(Start))); + void (__cdecl *Fn)(void *Me,void *Player,int); + if (Unit==NULL) + return; + if (Unit->collideFn!=NULL) + { + ASSIGN(Fn,Unit->collideFn); + Fn(Unit,Player,0); + } + +} + +extern void InjectJumpTo(DWORD Addr,void *Fn); +extern void InjectOffs(DWORD Addr,void *Fn); +void clientViewInit() +{ + ASSIGN(idPolyp,0x006E015C); + ASSIGN(client_4984B0,0x004984B0); + ASSIGN(playerInfoFromNetCodeCli,0x00417040); + ASSIGN(clientCollideOrUse,0x0042E810); + + InjectOffs(0x0042D820+1,onClientUse); + InjectJumpTo(0x004770B6,&clientPick1Pre); + InjectJumpTo(0x0046BE1A,&clientPick2Pre); +} + diff --git a/console.cpp b/console.cpp index 8fd6480..f47ee08 100644 --- a/console.cpp +++ b/console.cpp @@ -1,331 +1,331 @@ -#include "stdafx.h" -#include "string" - -struct packetChat -{ - byte pType; - byte unk01,unk02; - byte SomeFlag03; - byte Some08; - - -}; - -struct packetCast -{ - byte pType;// =0x53 - // - DWORD Buf[5]; //+1 - byte X;//+15 - - -}; -extern void *(__cdecl *noxCallWndProc)(void* Window,int Msg,int A,int B); -extern int (__cdecl *noxDrawGetStringSize) (void *FontPtr, const wchar_t*String,int *Width,int *H,int); -extern int (__cdecl *noxSetRectColorMB) (int); -int (__cdecl *consoleParse)(wchar_t*Str,int Mode); -extern bool justDoNoxCmd; -int *dword_69FE50=(int*) 0x69FE50; - -namespace -{ - void __cdecl onPrintConsole(int color,wchar_t* str) - { - int Top=lua_gettop(L); - getServerVar("onConPrint"); - if (lua_isfunction(L,-1)) - { - char conStr[0x208]={0}; - wcstombs(conStr,str,0x208); - lua_pushstring(L,conStr); - lua_pushinteger(L,color); - lua_pcall(L,2,0,0); - } - lua_settop(L,Top); - } - - - - int __declspec(naked) onPrintConsoleTrap() - { - __asm - { - mov eax,[dword_69FE50+0] - mov eax,[eax+0] - push eax - mov eax,[esp+4+8] - push eax - mov eax,[esp+8+4] - push eax - call onPrintConsole - add esp,8 - pop eax - push 450B95h - ret - }; - } - - - int conCur=0; // 0 - , 1 - 1 . . . - int lenStrOld=0; - - int (__cdecl *consoleEditProc)(void* Window,int Msg,int A,int B); - void (__cdecl *consoleProcFn)(); - int __cdecl consoleEditProcNew(void* Window,int Msg,int A,int B) - { - BYTE *P=(BYTE*)Window; - if (Msg==0x15) - { - P=*((BYTE**)(P+0x20));// - if (B==2) // - { - std::wstring stroka((const wchar_t*) P); - int Pos=stroka.size(); - if (A==0x4B+0x80) // 0x4B - - { - if (conCur>0) - conCur--; - return 1; - }else if (A==0x4D+0x80) // - { - if (conCur50 || lastS>luaL_getn(L,-3)) lastS=1; - if (lastS!=lastI) - { - //lastS() lastI [] - lua_pushinteger(L,lastS); - lua_setfield(L,-4,"lastStr"); - } - lua_rawgeti(L,-3,lastS); - if (lua_type(L,-1)!=LUA_TSTRING) // - { - lua_settop(L,Top); - return 1; - } - const char *V=lua_tostring(L,-1); - lua_pop(L,3); - wchar_t *W=(wchar_t*)P; - mbstowcs(W, V,300); - noxCallWndProc(Window,0x401E,(int)(W),-1); - W[strlen(V)]=0;// 0 - conCur=strlen(V); // - lenStrOld=strlen(V); - lua_settop(L,Top); - return 1; - }else if (A==0x1C) // ? - { - int Top=lua_gettop(L); // - char string[300]=""; - wchar_t *W=(wchar_t*)P; - int Len=wcslen(W); - wcstombs(string,W,Len); - lua_getglobal(L,"conStr"); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_newtable(L); - lua_pushvalue(L,-1); - lua_setglobal(L,"conStr"); - } - if (Len==0) - { - lua_settop(L,Top); - consoleProcFn();// - return 1; - } - lua_getfield(L,-1,"lastItem"); // - int lastI=lua_tointeger(L,-1)+1; - if (lastI>50) - lastI=1; - lua_pop(L,1); - lua_pushinteger(L,lastI); - lua_setfield(L,-2,"lastItem"); - - lua_pushstring(L,string); - lua_rawseti(L,-2,lastI-1); - - lua_pushinteger(L,lastI); - lua_setfield(L,-2,"lastStr"); - lua_settop(L,Top); - conCur=0; // - lenStrOld=0; - consoleProcFn();// - return 1; - } - consoleEditProc(Window,Msg,A,B); - stroka=(const wchar_t*)P; - if (lenStrOld0) + conCur--; + return 1; + }else if (A==0x4D+0x80) // вправо + { + if (conCur50 || lastS>luaL_getn(L,-3)) lastS=1; + if (lastS!=lastI) + { + //lastS(старый) lastI [таблица] + lua_pushinteger(L,lastS); + lua_setfield(L,-4,"lastStr"); + } + lua_rawgeti(L,-3,lastS); + if (lua_type(L,-1)!=LUA_TSTRING) // если там не строка а нил например + { + lua_settop(L,Top); + return 1; + } + const char *V=lua_tostring(L,-1); + lua_pop(L,3); + wchar_t *W=(wchar_t*)P; + mbstowcs(W, V,300); + noxCallWndProc(Window,0x401E,(int)(W),-1); + W[strlen(V)]=0;// на всякий случай припишем 0 + conCur=strlen(V); // курсор в конец + lenStrOld=strlen(V); + lua_settop(L,Top); + return 1; + }else if (A==0x1C) // нажали энтер? + { + int Top=lua_gettop(L); // запоминаеем что в начале + char string[300]=""; + wchar_t *W=(wchar_t*)P; + int Len=wcslen(W); + wcstombs(string,W,Len); + lua_getglobal(L,"conStr"); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_newtable(L); + lua_pushvalue(L,-1); + lua_setglobal(L,"conStr"); + } + if (Len==0) + { + lua_settop(L,Top); + consoleProcFn();// Вызываем обработку + return 1; + } + lua_getfield(L,-1,"lastItem"); // достаем последний элемент + int lastI=lua_tointeger(L,-1)+1; + if (lastI>50) + lastI=1; + lua_pop(L,1); + lua_pushinteger(L,lastI); + lua_setfield(L,-2,"lastItem"); + + lua_pushstring(L,string); + lua_rawseti(L,-2,lastI-1); + + lua_pushinteger(L,lastI); + lua_setfield(L,-2,"lastStr"); + lua_settop(L,Top); + conCur=0; // курсор в начало + lenStrOld=0; + consoleProcFn();// Вызываем обработку + return 1; + } + consoleEditProc(Window,Msg,A,B); + stroka=(const wchar_t*)P; + if (lenStrOldOfs)); - ASSIGN(Name,D->TablePtr); - ASSIGN(Fn,D->TablePtr+4); - for (;(*Name)!=0;Fn+=Delta,Name+=Delta) - { - if (*Fn==Ptr) - break; - } - if (*Fn!=0) - { - lua_pushstring(L,(*Name)); - return; - } - if (NULL==Ptr) - { - lua_pushnil(L); - return; - } - /// TODO: - char Buf[32]=""; - sprintf(Buf,"",Ptr); - lua_pushstring(L,Buf); - - } - void dumpRecord(BYTE *B,const DefData *D,lua_State *L) - { - char Buf[16]=""; - switch (D->Type) - { - case 1: - lua_pushinteger(L,*((int*)(B+D->Ofs))); - break; - case 2: - lua_pushinteger(L,B[D->Ofs]); - break; - case 3: - lua_pushnumber(L,*((float*)(B+D->Ofs))); - break; - case 5: /// , - - - case 4: - sprintf(Buf,"0x%08X",*((int*)(B+D->Ofs))); - lua_pushstring(L,Buf); - break; - case 6: - lua_pushinteger(L,*((WORD*)(B+D->Ofs))); - break; - case 7: - { - char *Str=*((char **)(B+D->Ofs)); - if (Str!=NULL) - lua_pushstring(L,Str); - else - lua_pushnil(L); - } - break; - case 8: - { - wchar_t *WStr=*((wchar_t **)(B+D->Ofs)); - if (WStr!=NULL) - { - int Len=wcslen(WStr)+1; - char *Str=new char[Len]; - wcstombs(Str,WStr,Len); - lua_pushstring(L,Str); - delete Str; - } - else - lua_pushnil(L); - } - break; - case 9: // 2 - dumpFnTable(B,D,L,2); - break; - case 10: // 3- - dumpFnTable(B,D,L,3); - break; - case 11: // 4- - dumpFnTable(B,D,L,4); - break; - - default: - lua_pushnil(L); - } - lua_setfield(L,-2,D->LuaStr); - } - void setRecord2(BYTE *B,const DefData *D,int ValueType,const char *Value) - { - char Buf[64]=""; - int LuaType=(D->Type<=6)?LUA_TNUMBER:0; - if (LuaType!=0 && (ValueType!=LuaType)) - { - return; - } - switch (D->Type) - { - case 1: - *((int*)(B+D->Ofs))=*((lua_Number*)Value); - break; - case 2: - B[D->Ofs]=*((lua_Number*)Value);; - break; - case 3: - *((float*)(B+D->Ofs))=*((lua_Number*)Value);; - break; - case 5: /// , - - - case 4: - *((int*)(B+D->Ofs))=*((lua_Number*)Value);; - break; - case 6: - *((WORD*)(B+D->Ofs))=*((lua_Number*)Value);; - break; - case 7: - { - char *Str=*((char **)(B+D->Ofs)); - if (Str!=NULL) - noxFree(Str); - if (ValueType==LUA_TNIL) - { - *((char **)(B+D->Ofs))=0; - } - else - { - *((char **)(B+D->Ofs))=copyString(Value); - } - } - break; - case 8: - { - wchar_t *Str=*((wchar_t **)(B+D->Ofs)); - if (Str!=NULL) - noxFree(Str); - if (ValueType==LUA_TNIL) - { - *((wchar_t **)(B+D->Ofs))=0; - } - else - { - *((wchar_t **)(B+D->Ofs))=copyStringW(Value); - } - } - break; - case 9: // 2 - case 10: // 3- - case 11: // 4- - default: - return; - } - } - void setRecord(BYTE *B,const DefData *D,lua_State *L) - { - char Buf[64]=""; - int LuaType=(D->Type<=6)?LUA_TNUMBER:0; - if (LuaType!=0 && (lua_type(L,3)!=LuaType)) - { - sprintf(Buf,"wrong value for field %s, must be %s",lua_tostring(L,2),luaTypeName[LuaType]); - lua_pushstring(L,Buf); - lua_error(L); - } - switch (D->Type) - { - case 1: - *((int*)(B+D->Ofs))=lua_tointeger(L,3); - break; - case 2: - B[D->Ofs]=lua_tointeger(L,3); - break; - case 3: - *((float*)(B+D->Ofs))=lua_tonumber(L,3); - break; - case 5: /// , - - - case 4: - *((int*)(B+D->Ofs))=lua_tointeger(L,3); - break; - case 6: - *((WORD*)(B+D->Ofs))=lua_tointeger(L,3); - break; - case 7: - { - char *Str=*((char **)(B+D->Ofs)); - if (Str!=NULL) - noxFree(Str); - if (lua_type(L,3)==LUA_TNIL) - { - *((char **)(B+D->Ofs))=0; - } - else - { - *((char **)(B+D->Ofs))=copyString(lua_tostring(L,3)); - } - } - break; - case 8: - { - wchar_t *Str=*((wchar_t **)(B+D->Ofs)); - if (Str!=NULL) - noxFree(Str); - if (lua_type(L,3)==LUA_TNIL) - { - *((wchar_t **)(B+D->Ofs))=0; - } - else - { - *((wchar_t **)(B+D->Ofs))=copyStringW(lua_tostring(L,3)); - } - } - break; - case 9: // 2 - case 10: // 3- - case 11: // 4- - default: - sprintf(Buf,"field %s is not yet supported",lua_tostring(L,2)); - lua_pushstring(L,Buf); - lua_error(L); - } - } - int dumpUnitDef(lua_State *L) - { - lua_settop(L,1); - if (lua_type(L,1)==LUA_TSTRING) - { - lua_pushinteger(L,noxThingTypeByName(lua_tostring(L,-1))); - } - if (lua_type(L,-1)!=LUA_TNUMBER) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - int N=lua_tointeger(L,-1); - BYTE *B=(BYTE*)unitDefGet(N); - if (B==NULL) - return 0; - lua_newtable(L); - for (const DefData *D=ServerDef;D->LuaStr!=0;D++) - { - dumpRecord(B,D,L); - } - B=(BYTE*)spriteDefGet(N); - if (B==NULL) - return 0; - for (const DefData *D=ClientDef;D->LuaStr!=0;D++) - { - dumpRecord(B,D,L); - } - return 1; - } - struct PacketDef - { - BYTE UniHead[UNIPACKET_HEAD]; - int TT; - BYTE ValType; - BYTE ValueLen; - }; - int unitDefSet(lua_State*L) - { - int DefN=0; - if (lua_type(L,2)!=LUA_TSTRING) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - if (lua_type(L,1)==LUA_TSTRING) - { - DefN=noxThingTypeByName(lua_tostring(L,1)); - - }else if (lua_type(L,1)!=LUA_TNUMBER) - DefN=lua_tointeger(L,1); - else - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - BYTE *B=(BYTE*)unitDefGet(DefN); - if (B==NULL) - return 0; - const char *Str=lua_tostring(L,2); - for (const DefData *D=ServerDef;D->LuaStr!=0;D++) - { - if(0==stricmp(D->LuaStr,Str)) - { - setRecord(B,D,L); - break; - } - } - /// TODO: , - /// - - const char *Value=0; - size_t ValueLen=0; - PacketDef Packet; - Packet.TT=DefN; - Packet.ValType=lua_type(L,3); - lua_Number ValueN=0; - if (Packet.ValType==LUA_TFUNCTION) - { - lua_pushvalue(L,lua_upvalueindex(1)); - lua_pushvalue(L,3); - lua_call(L,1,1); - Value=lua_tolstring(L,-1,&ValueLen); - }else if (Packet.ValType==LUA_TNUMBER) - { - ValueN=lua_tonumber(L,3); - Value=(const char*)&ValueN; - ValueLen=sizeof(ValueN); - } - else if (Packet.ValType==LUA_TSTRING) - { - Value=lua_tolstring(L,3,&ValueLen); - ValueLen++; - } - else if (Packet.ValType!=LUA_TNIL) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - - int PackSize=sizeof(Packet)+ValueLen+strlen(Str)+1; - Packet.ValueLen=ValueLen; - - BYTE *Buf=(BYTE*)_alloca(PackSize);// , - memcpy(Buf,&Packet,sizeof(Packet)); - memcpy((char*)Buf+sizeof(Packet),Value,ValueLen); - strcpy((char*)Buf+sizeof(Packet)+ValueLen,Str); - BYTE *P2=Buf; - netUniPacket(upUpdateDef,P2,PackSize); - - netSendAll(Buf,PackSize); - return 1; - } -} - -void netOnUpdateUnitDef(BYTE *Buf,BYTE *End) -{ - PacketDef *Packet=(PacketDef*)Buf; - if (End-Buf < (sizeof(PacketDef)+luaTypeLen[Packet->ValType])) - return ;// - BYTE *B=(BYTE*)spriteDefGet(Packet->TT); - const char *Str=(const char*)(Buf+sizeof(PacketDef)+Packet->ValueLen); - const char *Value=(const char*)(Buf+sizeof(PacketDef) ); - for (const DefData *D=ClientDef;D->LuaStr!=0;D++) - { - if(0==stricmp(D->LuaStr,Str)) - { - setRecord2(B,D,Packet->ValType,Value); - break; - } - } -} - -void unitDefsInit() -{ - ASSIGN(unitDefGet,0x004E3B70); - ASSIGN(spriteDefGet,0x0044CF10); - - int Top=lua_gettop(L); - lua_getglobal(L,"string"); - lua_getfield(L,-1,"dump"); - registerserver("unitDefSet",&unitDefSet,1); - registerserver("unitDefReg",®isterUnitDef); - registerserver("unitDefGet",&dumpUnitDef); - - lua_settop(L,Top); +#include "stdafx.h" + +extern int (__cdecl *noxThingTypeByName)(char const *Name); +void *(__cdecl *unitDefGet)(int N); +void *(__cdecl *spriteDefGet)(int N); +const char *luaTypeName[]= +{ + "nil","boolean","userdata","number","string","table","function", +}; +const int luaTypeLen[]= +{ + 0,1,0,sizeof(lua_Number),0,0,0, +}; +extern void *(__cdecl *noxAlloc)(int Size); +extern void (__cdecl *noxFree)(void *Ptr); +extern char *copyString(const char *Str); +extern wchar_t *copyStringW(const char *Str); +extern void netSendAll(void *Buf,int BufSize); +namespace +{ + struct DefData + { + const char *LuaStr; + int Ofs;/// смещение в юнитдефе + int Type; + /// 1=int + /// 2=byte + /// 3=float + /// 4=hexDword + /// 5=imgId + /// 6=word + /// 7=stringPtr + /// 8=stringWPtr // вайд-строка + /// 9=FnTable 2 // таблицы с 2мя двордами + // 10=FnTable 3 // таблицы с 3мя двордами + // 11=FnTable 4 // таблицы с 4мя двордами + DWORD TablePtr; + }; + int X; + /// данные брать из 005B82B0 unitDefParseTable + const DefData ServerDef[]= + { + {"thingType", 0x00,6}, + {"name", 0x04,7}, + {"menuIcon", 0x0C,5}, + {"class", 0x18,4}, + {"subclass", 0x1C,4}, + {"flags", 0x20,4}, + {"unitXP", 0x2c,3}, + {"unitWorth", 0x30,1}, + {"mass", 0x38,3}, + {"extentType", 0x3C,2}, + {"extentBoxX", 0x48,3}, + {"extentBoxY", 0x4C,3}, + {"capacity", 0x7A,6}, + {"collideFn", 0x8C,11,0x005CA1B8},//unitCollideProcTable + {0}, + }; + // данные из 005A4CF8 spriteDefParseTable + const DefData ClientDef[]= + { + {"prettyName", 0x4,8}, + {"description", 0x8,8}, + {"extentType", 0x14,2}, + {"class", 0x20,4}, + {"subclass", 0x24,4}, + {"flags", 0x28,4}, + {"extentBoxX", 0x4C,3}, + {"extentBoxY", 0x50,3}, + {"clientUpdateFn", 0x64,9,0x005B1BE0},// clientUpdateProcTable + {"menuIcon", 0x74,5}, + {0}, + }; + int registerUnitDef(lua_State *L) + { + lua_settop(L,1); + if (lua_type(L,1)!=LUA_TTABLE) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + lua_pushstring(L,"TODO!"); + lua_error(L); + return 1; + } + void dumpFnTable(BYTE *B,const DefData *D,lua_State *L,const int Delta) + { + char **Name=0; + DWORD *Fn=0; + DWORD Ptr=*((DWORD*)(B+D->Ofs)); + ASSIGN(Name,D->TablePtr); + ASSIGN(Fn,D->TablePtr+4); + for (;(*Name)!=0;Fn+=Delta,Name+=Delta) + { + if (*Fn==Ptr) + break; + } + if (*Fn!=0) + { + lua_pushstring(L,(*Name)); + return; + } + if (NULL==Ptr) + { + lua_pushnil(L); + return; + } + /// TODO: Здесь надо добавить проверку на случай функции из юнимод + char Buf[32]=""; + sprintf(Buf,"",Ptr); + lua_pushstring(L,Buf); + + } + void dumpRecord(BYTE *B,const DefData *D,lua_State *L) + { + char Buf[16]=""; + switch (D->Type) + { + case 1: + lua_pushinteger(L,*((int*)(B+D->Ofs))); + break; + case 2: + lua_pushinteger(L,B[D->Ofs]); + break; + case 3: + lua_pushnumber(L,*((float*)(B+D->Ofs))); + break; + case 5: /// пока просто загружу число, а потом чего-нить придумаю + + case 4: + sprintf(Buf,"0x%08X",*((int*)(B+D->Ofs))); + lua_pushstring(L,Buf); + break; + case 6: + lua_pushinteger(L,*((WORD*)(B+D->Ofs))); + break; + case 7: + { + char *Str=*((char **)(B+D->Ofs)); + if (Str!=NULL) + lua_pushstring(L,Str); + else + lua_pushnil(L); + } + break; + case 8: + { + wchar_t *WStr=*((wchar_t **)(B+D->Ofs)); + if (WStr!=NULL) + { + int Len=wcslen(WStr)+1; + char *Str=new char[Len]; + wcstombs(Str,WStr,Len); + lua_pushstring(L,Str); + delete Str; + } + else + lua_pushnil(L); + } + break; + case 9: //функции на 2 + dumpFnTable(B,D,L,2); + break; + case 10: //функции на 3-е + dumpFnTable(B,D,L,3); + break; + case 11: //функции на 4-е + dumpFnTable(B,D,L,4); + break; + + default: + lua_pushnil(L); + } + lua_setfield(L,-2,D->LuaStr); + } + void setRecord2(BYTE *B,const DefData *D,int ValueType,const char *Value) + { + char Buf[64]=""; + int LuaType=(D->Type<=6)?LUA_TNUMBER:0; + if (LuaType!=0 && (ValueType!=LuaType)) + { + return; + } + switch (D->Type) + { + case 1: + *((int*)(B+D->Ofs))=*((lua_Number*)Value); + break; + case 2: + B[D->Ofs]=*((lua_Number*)Value);; + break; + case 3: + *((float*)(B+D->Ofs))=*((lua_Number*)Value);; + break; + case 5: /// пока просто загружу число, а потом чего-нить придумаю + + case 4: + *((int*)(B+D->Ofs))=*((lua_Number*)Value);; + break; + case 6: + *((WORD*)(B+D->Ofs))=*((lua_Number*)Value);; + break; + case 7: + { + char *Str=*((char **)(B+D->Ofs)); + if (Str!=NULL) + noxFree(Str); + if (ValueType==LUA_TNIL) + { + *((char **)(B+D->Ofs))=0; + } + else + { + *((char **)(B+D->Ofs))=copyString(Value); + } + } + break; + case 8: + { + wchar_t *Str=*((wchar_t **)(B+D->Ofs)); + if (Str!=NULL) + noxFree(Str); + if (ValueType==LUA_TNIL) + { + *((wchar_t **)(B+D->Ofs))=0; + } + else + { + *((wchar_t **)(B+D->Ofs))=copyStringW(Value); + } + } + break; + case 9: //функции на 2 + case 10: //функции на 3-е + case 11: //функции на 4-е + default: + return; + } + } + void setRecord(BYTE *B,const DefData *D,lua_State *L) + { + char Buf[64]=""; + int LuaType=(D->Type<=6)?LUA_TNUMBER:0; + if (LuaType!=0 && (lua_type(L,3)!=LuaType)) + { + sprintf(Buf,"wrong value for field %s, must be %s",lua_tostring(L,2),luaTypeName[LuaType]); + lua_pushstring(L,Buf); + lua_error(L); + } + switch (D->Type) + { + case 1: + *((int*)(B+D->Ofs))=lua_tointeger(L,3); + break; + case 2: + B[D->Ofs]=lua_tointeger(L,3); + break; + case 3: + *((float*)(B+D->Ofs))=lua_tonumber(L,3); + break; + case 5: /// пока просто загружу число, а потом чего-нить придумаю + + case 4: + *((int*)(B+D->Ofs))=lua_tointeger(L,3); + break; + case 6: + *((WORD*)(B+D->Ofs))=lua_tointeger(L,3); + break; + case 7: + { + char *Str=*((char **)(B+D->Ofs)); + if (Str!=NULL) + noxFree(Str); + if (lua_type(L,3)==LUA_TNIL) + { + *((char **)(B+D->Ofs))=0; + } + else + { + *((char **)(B+D->Ofs))=copyString(lua_tostring(L,3)); + } + } + break; + case 8: + { + wchar_t *Str=*((wchar_t **)(B+D->Ofs)); + if (Str!=NULL) + noxFree(Str); + if (lua_type(L,3)==LUA_TNIL) + { + *((wchar_t **)(B+D->Ofs))=0; + } + else + { + *((wchar_t **)(B+D->Ofs))=copyStringW(lua_tostring(L,3)); + } + } + break; + case 9: //функции на 2 + case 10: //функции на 3-е + case 11: //функции на 4-е + default: + sprintf(Buf,"field %s is not yet supported",lua_tostring(L,2)); + lua_pushstring(L,Buf); + lua_error(L); + } + } + int dumpUnitDef(lua_State *L) + { + lua_settop(L,1); + if (lua_type(L,1)==LUA_TSTRING) + { + lua_pushinteger(L,noxThingTypeByName(lua_tostring(L,-1))); + } + if (lua_type(L,-1)!=LUA_TNUMBER) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + int N=lua_tointeger(L,-1); + BYTE *B=(BYTE*)unitDefGet(N); + if (B==NULL) + return 0; + lua_newtable(L); + for (const DefData *D=ServerDef;D->LuaStr!=0;D++) + { + dumpRecord(B,D,L); + } + B=(BYTE*)spriteDefGet(N); + if (B==NULL) + return 0; + for (const DefData *D=ClientDef;D->LuaStr!=0;D++) + { + dumpRecord(B,D,L); + } + return 1; + } + struct PacketDef + { + BYTE UniHead[UNIPACKET_HEAD]; + int TT; + BYTE ValType; + BYTE ValueLen; + }; + int unitDefSet(lua_State*L) + { + int DefN=0; + if (lua_type(L,2)!=LUA_TSTRING) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + if (lua_type(L,1)==LUA_TSTRING) + { + DefN=noxThingTypeByName(lua_tostring(L,1)); + + }else if (lua_type(L,1)!=LUA_TNUMBER) + DefN=lua_tointeger(L,1); + else + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + BYTE *B=(BYTE*)unitDefGet(DefN); + if (B==NULL) + return 0; + const char *Str=lua_tostring(L,2); + for (const DefData *D=ServerDef;D->LuaStr!=0;D++) + { + if(0==stricmp(D->LuaStr,Str)) + { + setRecord(B,D,L); + break; + } + } + /// TODO: стоит проверить, а есть ли такое свойство + ///тут отправляем на клиент и меняем свойства там + + const char *Value=0; + size_t ValueLen=0; + PacketDef Packet; + Packet.TT=DefN; + Packet.ValType=lua_type(L,3); + lua_Number ValueN=0; + if (Packet.ValType==LUA_TFUNCTION) + { + lua_pushvalue(L,lua_upvalueindex(1)); + lua_pushvalue(L,3); + lua_call(L,1,1); + Value=lua_tolstring(L,-1,&ValueLen); + }else if (Packet.ValType==LUA_TNUMBER) + { + ValueN=lua_tonumber(L,3); + Value=(const char*)&ValueN; + ValueLen=sizeof(ValueN); + } + else if (Packet.ValType==LUA_TSTRING) + { + Value=lua_tolstring(L,3,&ValueLen); + ValueLen++; + } + else if (Packet.ValType!=LUA_TNIL) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + + int PackSize=sizeof(Packet)+ValueLen+strlen(Str)+1; + Packet.ValueLen=ValueLen; + + BYTE *Buf=(BYTE*)_alloca(PackSize);// создает переменную в стэке, потому сама по выходе удалится + memcpy(Buf,&Packet,sizeof(Packet)); + memcpy((char*)Buf+sizeof(Packet),Value,ValueLen); + strcpy((char*)Buf+sizeof(Packet)+ValueLen,Str); + BYTE *P2=Buf; + netUniPacket(upUpdateDef,P2,PackSize); + + netSendAll(Buf,PackSize); + return 1; + } +} + +void netOnUpdateUnitDef(BYTE *Buf,BYTE *End) +{ + PacketDef *Packet=(PacketDef*)Buf; + if (End-Buf < (sizeof(PacketDef)+luaTypeLen[Packet->ValType])) + return ;// ошибка в пакете + BYTE *B=(BYTE*)spriteDefGet(Packet->TT); + const char *Str=(const char*)(Buf+sizeof(PacketDef)+Packet->ValueLen); + const char *Value=(const char*)(Buf+sizeof(PacketDef) ); + for (const DefData *D=ClientDef;D->LuaStr!=0;D++) + { + if(0==stricmp(D->LuaStr,Str)) + { + setRecord2(B,D,Packet->ValType,Value); + break; + } + } +} + +void unitDefsInit() +{ + ASSIGN(unitDefGet,0x004E3B70); + ASSIGN(spriteDefGet,0x0044CF10); + + int Top=lua_gettop(L); + lua_getglobal(L,"string"); + lua_getfield(L,-1,"dump"); + registerserver("unitDefSet",&unitDefSet,1); + registerserver("unitDefReg",®isterUnitDef); + registerserver("unitDefGet",&dumpUnitDef); + + lua_settop(L,Top); } \ No newline at end of file diff --git a/filesystem.cpp b/filesystem.cpp index ad0a67d..33eb54b 100644 --- a/filesystem.cpp +++ b/filesystem.cpp @@ -1,598 +1,598 @@ -#include "stdafx.h" -//#include -//#include -#pragma pack(1) - -int (__cdecl *noxWriteToFile)(void *Data,int Size,int Count,void *File); -void* (__cdecl *noxFopen)(char *Name,char *Access); -void (__cdecl *noxFclose)(void *File); -extern void *(__cdecl *noxAlloc)(int Size); -extern char *(__cdecl *mapGetName)(); -extern int (__cdecl *netSendBySock)(int Player,void *Data,int Size, int Type); - -int (__cdecl *mapValidateMB)(char *FileName,DWORD Crc); -DWORD *mapFileSizeServ; -BYTE **mapFileDataServ; - -struct TarBlock -{ - char name[100]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char chksum[8]; - char typeflag; - char linkname[100]; - char magic[8]; - char version[2]; - union - { - struct - { - char uname[32]; - char gname[32]; - char devmajor[8]; - char devminor[8]; - } TarDefault; - struct - { - int Check; - int Size; - void *Data; - TarBlock* nextBlock; - } Info; - }; - char prefix[155]; - char Padding[10]; - - ~TarBlock() - { - if (this->Info.Check==123456) - { - if (this->Info.Data!=0) - delete this->Info.Data; - if (this->Info.nextBlock!=0) - delete this->Info.nextBlock; - } - } - static int __cdecl Comparer(const void *A_,const void *B_) - { - TarBlock *A=*((TarBlock**)A_); - TarBlock *B=*((TarBlock**)B_); - int Ret=strcmp(A->prefix,B->prefix); - if (Ret==0) - Ret=strcmp(A->name,B->name); - return Ret; - } - struct PathSearcherData - { - const char *String; - int StrLen; - }; - static int __cdecl PathSearcher(const void *A_,const void *B_) - { - PathSearcherData *A=((PathSearcherData*)A_); - TarBlock *B=*((TarBlock**)B_); - int Ret; - const char *P=A->String; - int Len=0; - if (Len=strlen(B->prefix)) - { - Ret=strncmp(P,B->prefix,Len); - if (Ret!=0) - return Ret; - P+=Len; - } - Ret=strcmp(P,B->name); - return Ret; - } -}; -#include "bzip2\bzlib.h" -#include -typedef std::vector TarList; -namespace -{ - TarList MapList; // - - TarList GlobalList; - - struct IFile - { - virtual int fread(void *Buf,size_t Size)=0; - virtual DWORD getCrc()=0; - virtual void fclose()=0; - }; - struct BZFile:public IFile - { - BZFILE *Data; - int Fd; - int fread(void *Buf,size_t Size) - { - int Error=0; - int Ret=BZ2_bzread(Data,(char*)Buf,Size); - if (Ret==Size) - return 1; - return 0; - } - BZFile(){ } - ~BZFile(){fclose();} - void fclose() - { - if (Data) {BZ2_bzclose(Data); Data=0;} - } - DWORD getCrc(){ return 0; } - static IFile* fopen(const char *Filename) - { - - BZFile *Ret=new BZFile(); - Ret->Data=BZ2_bzopen(Filename,"r"); - if (Ret->Data==NULL) - { - delete Ret; - return 0; - } - return Ret; - - } - }; - struct TarFile :public IFile - { - FILE *F; - int fread(void *Buf,size_t Size) - { - return ::fread(Buf,Size,1,F); - } - DWORD getCrc(){ return 0; } - TarFile(FILE *F_):F(F_){} - ~TarFile(){ fclose(); } - void fclose() - { - if (F) {::fclose(F);F=0;} - } - static IFile* fopen(const char *Filename) - { - FILE *F=::fopen(Filename,"rb"); - if (F==NULL) - return NULL; - return new TarFile(F); - } - }; - int oct2i(const char*Str) - { - int Ret=0; - const char *P=Str; - for (;*P==' ';) - P++; - for( ;(*P>='0') && *P<='7'; P++) - { - Ret<<=3; - Ret+= (*P - '0'); - } - return Ret; - } - bool readFile(const char *Filename,TarList &SearchList,DWORD *Crc=NULL) - { - if (sizeof(TarBlock)!=512) - return false; - IFile *F=0; -/* if (0==strcmpi(Filename+strlen(Filename)-4,".tar")) - { - F=TarFile::fopen(Filename); - }else*/ /// - if( - (0==strcmpi(Filename+strlen(Filename)-5,".tbz2"))|| - (0==strcmpi(Filename+strlen(Filename)-8,".tar.bz2")) - ) - { - F=BZFile::fopen(Filename); - } - if (F==NULL) - return false; - - TarBlock *Block=new TarBlock,*Start=Block; - bool Error=true; - int FileCount=0; - while(1) - { - if (1!=F->fread(Block,512)) - break; - Block->Info.Size=oct2i(Block->size);/// ! - Block->Info.Data=0; - Block->Info.nextBlock=0; - Block->Info.Check=123456; - char *Name=Block->name; - int nameLen=strlen(Name); - if (nameLen<1) - { - Error=false; - break; // - } - FileCount++; - if (Block->Info.Size==0) - { - if (Name[nameLen-1]!='/') - continue;/// ? - Block->Info.nextBlock=new TarBlock;/// , - Block=Block->Info.nextBlock; - continue; - } - int ReadSize=(Block->Info.Size+0x1FF)&0xFFFFFE00; - BYTE *B=new BYTE[ReadSize]; - Block->Info.Data=B; - if (1!=F->fread(B,ReadSize)) - break;/// - Block->Info.nextBlock=new TarBlock; - Block=Block->Info.nextBlock; - } - if (Crc!=NULL) - *Crc=F->getCrc(); - F->fclose(); - delete F; - if (FileCount>0) - { - SearchList.reserve(FileCount); - TarBlock *N=NULL; - for (TarBlock *P=Start;P!=NULL;P=N) - { - N=P->Info.nextBlock; - P->Info.nextBlock=0; - if (0==*P->name) // - { - delete P; - break; - } - if (123456!=P->Info.Check)// - { - delete P; - break; - } - SearchList.push_back(P);/// - } - qsort(&SearchList.front(),SearchList.size(),sizeof(TarBlock *),TarBlock::Comparer); - } - return !Error; - } - TarBlock* dirSearch(const char *File,TarList *List) - { - if ( (List==NULL) || List->empty() ) - return NULL; - TarBlock::PathSearcherData D={File,strlen(File)}; - TarBlock** Ret=(TarBlock**)bsearch(&D,&List->front(),List->size(),sizeof(TarBlock*), - TarBlock::PathSearcher); - return (Ret!=NULL)?*Ret:NULL; - } - int loadFileL(lua_State*L) - { - if (!lua_isstring(L,1)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - - lua_pushboolean(L, - readFile(lua_tostring(L,1),lua_toboolean(L,2)?GlobalList:MapList) - ?1:0); - return 1; - } - TarBlock *itemByName(const char *P,bool CalledFromCon,char *Buf) - { - if (P==NULL) - return NULL; - if (strlen(P)>200) - return NULL; - TarList *List=&MapList; - - if (!CalledFromCon) - { - if (0==strncmp(P,"map/",4)) - { - P+=4; - }else - List=&GlobalList; - } - else - { - if (*P=='/') P++; - if (0==strncmp(P,"global/",7)) /// /global/ - { - P+=7; - List=&GlobalList; - } - else - { - if (0!=strncmp(P,"map/",4)) /// /map/... - strcpy(Buf,"map/"); /// ... - else - P+=4; - } - } - strcat(Buf,lua_tostring(L,1)); - - return dirSearch(P,List); - } - int bz2Loader(lua_State*L) /// loadfile - { - - const char *P=lua_tostring(L,1); - char Buf[220]=""; - - TarBlock *B=itemByName(P,(lua_objlen(L,lua_upvalueindex(1))!=0),Buf); - - if ( (B==NULL)|| B->Info.Size<=0) - { - lua_pushstring (L," is not a valid lua file"); - lua_concat(L,2); - lua_pushboolean(L,0); - lua_insert(L,1); - return 2; - } - if (0!=luaL_loadbuffer(L,(char*)B->Info.Data,B->Info.Size,Buf)) - { - lua_pushstring (L," is not a valid lua file"); - lua_concat(L,2); - lua_pushboolean(L,0); - lua_insert(L,1); - return 2; - } - return 1; - } - int cliMapSize=0;/// - int CurrentSize;/// - char *MapPath=0; - char *ArchiveName=0; - void **mapFileHandle; - - DWORD servTBZ2Crc; - int servArchiveSize=0; - char servArchiveName[MAX_PATH]=""; - - void *clientOpenFile(char *Name,char *Access) - { - int Size=strlen(Name)+8;// tar.bz2\n - MapPath=new char[Size]; - strcpy(MapPath,Name); - CurrentSize=0; - return noxFopen(Name,Access); - } - void clientWriteChunk(BYTE *Data,int Size,int Count,void *File) - { - if (cliMapSize>0) - { - if (CurrentSize+Size>cliMapSize) - { - int DSize=cliMapSize-CurrentSize; - noxWriteToFile(Data,DSize,Count,File); - Size-=DSize; - Data+=DSize; - cliMapSize=0; - char *P=strrchr(MapPath,'.'); - if (P!=NULL) - { - noxFclose(File);/// File==mapFileHandle - strcpy(P,".tbz2"); - *mapFileHandle=noxFopen(MapPath,"wb"); - } - } - } - CurrentSize+=Size; - if (Size>0) - noxWriteToFile(Data,Size,Count,File); - } - int __cdecl mapValidate(char *Name,DWORD Size) - { - int Ret=mapValidateMB(Name,Size); -/* if (0!=servTBZ2Crc) - { - char Buf[MAX_PATH]=""; - sprintf(Buf,"maps/%s/%s.",Name,Name); - char *P=strrchr(Buf,'.'); - FILE *F=NULL; - strcpy(P,".tbz2"); - F=fopen(Buf,"rb"); - if (F==NULL) - { - strcpy(P,".tar.bz2"); - F=fopen(Buf,"rb"); - } - if (F!=0) - { - int Size=0; - fseek(F,0,SEEK_END); - Size=ftell(F); - fseek(F,0,SEEK_SET); - BYTE *B=new BYTE[Size]; - fread(B,Size,1,F); - DWORD Crc=0xAAAAAAAA; - fclose(F); - { - DWORD *S=(DWORD*)(B); - Size>>=2; - DWORD *E=S+Size; - for(;S!=E;S++) - { - Crc<<=4; - Crc^=*S; - } - servTBZ2Crc=Crc; - } - delete B; - } - }*/ - return Ret; - } - void * __cdecl serverTransferPrepair(int FileSize) - { - servTBZ2Crc=0; - void *Ret; - *servArchiveName=0; - char *Buf=servArchiveName; - sprintf(Buf,"maps/%s/%s.",mapGetName(),mapGetName()); - char *P=strrchr(Buf,'.'); - FILE *F=NULL; - if (P==NULL) - return noxAlloc(FileSize); - strcpy(P,".tbz2"); - F=fopen(Buf,"rb"); - if (F==NULL) - { - strcpy(P,".tar.bz2"); - F=fopen(Buf,"rb"); - } - if (F==NULL) - return noxAlloc(FileSize); - servArchiveSize=0; - fseek(F,0,SEEK_END); - servArchiveSize=ftell(F); - fseek(F,0,SEEK_SET); - Ret=noxAlloc(FileSize+servArchiveSize); - *mapFileSizeServ=FileSize+servArchiveSize; - - BYTE *B=(BYTE*)Ret; - B+=FileSize; - fread(B,servArchiveSize,1,F); - DWORD Crc=0xAAAAAAAA; -/* { - DWORD *S=(DWORD*)(B+FileSize); - Size>>=2; - DWORD *E=S+Size; - for(;S!=E;S++) - { - Crc<<=4; - Crc^=*S; - } - servTBZ2Crc=Crc; - }*/ - fclose(F); - *mapFileDataServ=B; - return Ret; - } - void __cdecl serverTransferStart(int Player,void *Data,int Size,int Mode) - { - BYTE Buf[MAX_PATH+sizeof(int)+4]; - BYTE *P=Buf; - int Len=strlen(servArchiveName); - netUniPacket(upSendArchive,P,sizeof(int)+Len); - *((int*)P)=*mapFileSizeServ-servArchiveSize;/// - P+=4; - memcpy(P,servArchiveName,Len); - P+=Len; - netSendBySock(Player,Buf,P-Buf,Mode); - netSendBySock(Player,Data,Size,Mode); - } -} -bool fsRead(const char *File,void *&Data, size_t &Size) -{ - char Buf[220]=""; - Data=NULL;Size=0; - TarBlock *B = itemByName(File,true,Buf); - if (!B) - return false; - Data=B->Info.Data; - Size=B->Info.Size; - return true; -} -void netOnSendArchive(int Size,char *Name,char *NameE) -{ - cliMapSize=Size;/// - if (ArchiveName) - { - delete ArchiveName; - ArchiveName=0; - } - ArchiveName=new char[NameE-Name+1]; - strncpy(ArchiveName,Name,NameE-Name); - ArchiveName[NameE-Name]=0; -} -void netOnAbortDownload() -{ - if (MapPath) - { - delete MapPath; - MapPath=0; - } - if (ArchiveName) - { - delete ArchiveName; - ArchiveName=0; - } - cliMapSize=0; -} -void mapLoadFilesystem(const char *MapName) -{ - char Buf[200]; - do - { - sprintf(Buf,"maps/%s/%s.tbz2",MapName,MapName); - if (readFile(Buf,MapList)) - break; - sprintf(Buf,"maps/%s/%s.tar.bz2",MapName,MapName); - if (readFile(Buf,MapList)) - break; - return; // - }while (0); - TarBlock *B=dirSearch("server.lua",&MapList); - if (B==NULL) - return; // - if (B->Info.Size>0) - { - int Top=lua_gettop(L); - bool Ok=false; - do - { - if (0!=luaL_loadbuffer(L,(char*)B->Info.Data,B->Info.Size,Buf)) - break; - lua_getfield(L,LUA_REGISTRYINDEX,"server"); - lua_setfenv(L,-2); - if (0!= lua_pcall(L,0,0,0)) - break; - Ok=true; - }while(0); - if (!Ok) - { - conPrintI(lua_tostring(L,-1)); - } - lua_settop(L,Top); - } -} -void mapUnloadFilesystem() -{ - for (TarList::iterator I=MapList.begin();I!=MapList.end();I++) - { - delete (*I); - } - MapList.clear(); -} -extern void InjectOffs(DWORD Addr,void *Fn); -void initFilesystem() -{ -/* - -MSG_USE_MAP , - gameFlags - - -*/ - InjectOffs(0x004AB7FD+1,&clientWriteChunk); - InjectOffs(0x004AB8BC+1,&clientWriteChunk); - InjectOffs(0x004ABD64+1,&clientOpenFile); - InjectOffs(0x0043DEF6+1,&mapValidate); - - InjectOffs(0x0051A0A1+1,&serverTransferPrepair); - - InjectOffs(0x00519AA7+1,&serverTransferStart); - - ASSIGN(mapFileHandle,0x007141D4); - ASSIGN(noxWriteToFile,0x00565A02); - ASSIGN(noxFopen,0x0056586C); - ASSIGN(noxFclose,0x00407533); - ASSIGN(mapValidateMB,0x004CF470); - ASSIGN(mapFileDataServ,0x0081B834); - ASSIGN(mapFileSizeServ,0x0081B838); - - lua_newtable(L);/// - - lua_pushcclosure(L,&bz2Loader,1); - lua_setglobal(L,"bz2Loader"); - lua_register(L,"fileLoad",&loadFileL); - +#include "stdafx.h" +//#include +//#include +#pragma pack(1) + +int (__cdecl *noxWriteToFile)(void *Data,int Size,int Count,void *File); +void* (__cdecl *noxFopen)(char *Name,char *Access); +void (__cdecl *noxFclose)(void *File); +extern void *(__cdecl *noxAlloc)(int Size); +extern char *(__cdecl *mapGetName)(); +extern int (__cdecl *netSendBySock)(int Player,void *Data,int Size, int Type); + +int (__cdecl *mapValidateMB)(char *FileName,DWORD Crc); +DWORD *mapFileSizeServ; +BYTE **mapFileDataServ; + +struct TarBlock +{ + char name[100]; + char mode[8]; + char uid[8]; + char gid[8]; + char size[12]; + char mtime[12]; + char chksum[8]; + char typeflag; + char linkname[100]; + char magic[8]; + char version[2]; + union + { + struct + { + char uname[32]; + char gname[32]; + char devmajor[8]; + char devminor[8]; + } TarDefault; + struct + { + int Check; + int Size; + void *Data; + TarBlock* nextBlock; + } Info; + }; + char prefix[155]; + char Padding[10]; + + ~TarBlock() + { + if (this->Info.Check==123456) + { + if (this->Info.Data!=0) + delete this->Info.Data; + if (this->Info.nextBlock!=0) + delete this->Info.nextBlock; + } + } + static int __cdecl Comparer(const void *A_,const void *B_) + { + TarBlock *A=*((TarBlock**)A_); + TarBlock *B=*((TarBlock**)B_); + int Ret=strcmp(A->prefix,B->prefix); + if (Ret==0) + Ret=strcmp(A->name,B->name); + return Ret; + } + struct PathSearcherData + { + const char *String; + int StrLen; + }; + static int __cdecl PathSearcher(const void *A_,const void *B_) + { + PathSearcherData *A=((PathSearcherData*)A_); + TarBlock *B=*((TarBlock**)B_); + int Ret; + const char *P=A->String; + int Len=0; + if (Len=strlen(B->prefix)) + { + Ret=strncmp(P,B->prefix,Len); + if (Ret!=0) + return Ret; + P+=Len; + } + Ret=strcmp(P,B->name); + return Ret; + } +}; +#include "bzip2\bzlib.h" +#include +typedef std::vector TarList; +namespace +{ + TarList MapList; //туда все куски от карты - выгрузятся вместе с нею + TarList GlobalList; + + struct IFile + { + virtual int fread(void *Buf,size_t Size)=0; + virtual DWORD getCrc()=0; + virtual void fclose()=0; + }; + struct BZFile:public IFile + { + BZFILE *Data; + int Fd; + int fread(void *Buf,size_t Size) + { + int Error=0; + int Ret=BZ2_bzread(Data,(char*)Buf,Size); + if (Ret==Size) + return 1; + return 0; + } + BZFile(){ } + ~BZFile(){fclose();} + void fclose() + { + if (Data) {BZ2_bzclose(Data); Data=0;} + } + DWORD getCrc(){ return 0; } + static IFile* fopen(const char *Filename) + { + + BZFile *Ret=new BZFile(); + Ret->Data=BZ2_bzopen(Filename,"r"); + if (Ret->Data==NULL) + { + delete Ret; + return 0; + } + return Ret; + + } + }; + struct TarFile :public IFile + { + FILE *F; + int fread(void *Buf,size_t Size) + { + return ::fread(Buf,Size,1,F); + } + DWORD getCrc(){ return 0; } + TarFile(FILE *F_):F(F_){} + ~TarFile(){ fclose(); } + void fclose() + { + if (F) {::fclose(F);F=0;} + } + static IFile* fopen(const char *Filename) + { + FILE *F=::fopen(Filename,"rb"); + if (F==NULL) + return NULL; + return new TarFile(F); + } + }; + int oct2i(const char*Str) + { + int Ret=0; + const char *P=Str; + for (;*P==' ';) + P++; + for( ;(*P>='0') && *P<='7'; P++) + { + Ret<<=3; + Ret+= (*P - '0'); + } + return Ret; + } + bool readFile(const char *Filename,TarList &SearchList,DWORD *Crc=NULL) + { + if (sizeof(TarBlock)!=512) + return false; + IFile *F=0; +/* if (0==strcmpi(Filename+strlen(Filename)-4,".tar")) + { + F=TarFile::fopen(Filename); + }else*/ /// тарфайлы были нужны только для тестов + if( + (0==strcmpi(Filename+strlen(Filename)-5,".tbz2"))|| + (0==strcmpi(Filename+strlen(Filename)-8,".tar.bz2")) + ) + { + F=BZFile::fopen(Filename); + } + if (F==NULL) + return false; + + TarBlock *Block=new TarBlock,*Start=Block; + bool Error=true; + int FileCount=0; + while(1) + { + if (1!=F->fread(Block,512)) + break; + Block->Info.Size=oct2i(Block->size);/// число записано В ВОСЬМЕРИЧНОЙ системе! + Block->Info.Data=0; + Block->Info.nextBlock=0; + Block->Info.Check=123456; + char *Name=Block->name; + int nameLen=strlen(Name); + if (nameLen<1) + { + Error=false; + break; //думаю конец архива + } + FileCount++; + if (Block->Info.Size==0) + { + if (Name[nameLen-1]!='/') + continue;/// зачем нам пустой файл? + Block->Info.nextBlock=new TarBlock;/// это директория, пущай будет + Block=Block->Info.nextBlock; + continue; + } + int ReadSize=(Block->Info.Size+0x1FF)&0xFFFFFE00; + BYTE *B=new BYTE[ReadSize]; + Block->Info.Data=B; + if (1!=F->fread(B,ReadSize)) + break;/// ошибка чтения + Block->Info.nextBlock=new TarBlock; + Block=Block->Info.nextBlock; + } + if (Crc!=NULL) + *Crc=F->getCrc(); + F->fclose(); + delete F; + if (FileCount>0) + { + SearchList.reserve(FileCount); + TarBlock *N=NULL; + for (TarBlock *P=Start;P!=NULL;P=N) + { + N=P->Info.nextBlock; + P->Info.nextBlock=0; + if (0==*P->name) // просто финальный + { + delete P; + break; + } + if (123456!=P->Info.Check)// невалидный блок + { + delete P; + break; + } + SearchList.push_back(P);/// складываем все в массив + } + qsort(&SearchList.front(),SearchList.size(),sizeof(TarBlock *),TarBlock::Comparer); + } + return !Error; + } + TarBlock* dirSearch(const char *File,TarList *List) + { + if ( (List==NULL) || List->empty() ) + return NULL; + TarBlock::PathSearcherData D={File,strlen(File)}; + TarBlock** Ret=(TarBlock**)bsearch(&D,&List->front(),List->size(),sizeof(TarBlock*), + TarBlock::PathSearcher); + return (Ret!=NULL)?*Ret:NULL; + } + int loadFileL(lua_State*L) + { + if (!lua_isstring(L,1)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + + lua_pushboolean(L, + readFile(lua_tostring(L,1),lua_toboolean(L,2)?GlobalList:MapList) + ?1:0); + return 1; + } + TarBlock *itemByName(const char *P,bool CalledFromCon,char *Buf) + { + if (P==NULL) + return NULL; + if (strlen(P)>200) + return NULL; + TarList *List=&MapList; + + if (!CalledFromCon) + { + if (0==strncmp(P,"map/",4)) + { + P+=4; + }else + List=&GlobalList; + } + else + { + if (*P=='/') P++; + if (0==strncmp(P,"global/",7)) /// Из карты вызывается глобальные скрипты через /global/ + { + P+=7; + List=&GlobalList; + } + else + { + if (0!=strncmp(P,"map/",4)) /// В карте вызвано как /map/... + strcpy(Buf,"map/"); /// В карте вызвано просто как ... + else + P+=4; + } + } + strcat(Buf,lua_tostring(L,1)); + + return dirSearch(P,List); + } + int bz2Loader(lua_State*L) /// loadfile из архивов + { + + const char *P=lua_tostring(L,1); + char Buf[220]=""; + + TarBlock *B=itemByName(P,(lua_objlen(L,lua_upvalueindex(1))!=0),Buf); + + if ( (B==NULL)|| B->Info.Size<=0) + { + lua_pushstring (L," is not a valid lua file"); + lua_concat(L,2); + lua_pushboolean(L,0); + lua_insert(L,1); + return 2; + } + if (0!=luaL_loadbuffer(L,(char*)B->Info.Data,B->Info.Size,Buf)) + { + lua_pushstring (L," is not a valid lua file"); + lua_concat(L,2); + lua_pushboolean(L,0); + lua_insert(L,1); + return 2; + } + return 1; + } + int cliMapSize=0;/// размер файла карты для клиента + int CurrentSize;/// сколько уже приехало + char *MapPath=0; + char *ArchiveName=0; + void **mapFileHandle; + + DWORD servTBZ2Crc; + int servArchiveSize=0; + char servArchiveName[MAX_PATH]=""; + + void *clientOpenFile(char *Name,char *Access) + { + int Size=strlen(Name)+8;// tar.bz2\n + MapPath=new char[Size]; + strcpy(MapPath,Name); + CurrentSize=0; + return noxFopen(Name,Access); + } + void clientWriteChunk(BYTE *Data,int Size,int Count,void *File) + { + if (cliMapSize>0) + { + if (CurrentSize+Size>cliMapSize) + { + int DSize=cliMapSize-CurrentSize; + noxWriteToFile(Data,DSize,Count,File); + Size-=DSize; + Data+=DSize; + cliMapSize=0; + char *P=strrchr(MapPath,'.'); + if (P!=NULL) + { + noxFclose(File);///по идее всегда File==mapFileHandle + strcpy(P,".tbz2"); + *mapFileHandle=noxFopen(MapPath,"wb"); + } + } + } + CurrentSize+=Size; + if (Size>0) + noxWriteToFile(Data,Size,Count,File); + } + int __cdecl mapValidate(char *Name,DWORD Size) + { + int Ret=mapValidateMB(Name,Size); +/* if (0!=servTBZ2Crc) + { + char Buf[MAX_PATH]=""; + sprintf(Buf,"maps/%s/%s.",Name,Name); + char *P=strrchr(Buf,'.'); + FILE *F=NULL; + strcpy(P,".tbz2"); + F=fopen(Buf,"rb"); + if (F==NULL) + { + strcpy(P,".tar.bz2"); + F=fopen(Buf,"rb"); + } + if (F!=0) + { + int Size=0; + fseek(F,0,SEEK_END); + Size=ftell(F); + fseek(F,0,SEEK_SET); + BYTE *B=new BYTE[Size]; + fread(B,Size,1,F); + DWORD Crc=0xAAAAAAAA; + fclose(F); + { + DWORD *S=(DWORD*)(B); + Size>>=2; + DWORD *E=S+Size; + for(;S!=E;S++) + { + Crc<<=4; + Crc^=*S; + } + servTBZ2Crc=Crc; + } + delete B; + } + }*/ + return Ret; + } + void * __cdecl serverTransferPrepair(int FileSize) + { + servTBZ2Crc=0; + void *Ret; + *servArchiveName=0; + char *Buf=servArchiveName; + sprintf(Buf,"maps/%s/%s.",mapGetName(),mapGetName()); + char *P=strrchr(Buf,'.'); + FILE *F=NULL; + if (P==NULL) + return noxAlloc(FileSize); + strcpy(P,".tbz2"); + F=fopen(Buf,"rb"); + if (F==NULL) + { + strcpy(P,".tar.bz2"); + F=fopen(Buf,"rb"); + } + if (F==NULL) + return noxAlloc(FileSize); + servArchiveSize=0; + fseek(F,0,SEEK_END); + servArchiveSize=ftell(F); + fseek(F,0,SEEK_SET); + Ret=noxAlloc(FileSize+servArchiveSize); + *mapFileSizeServ=FileSize+servArchiveSize; + + BYTE *B=(BYTE*)Ret; + B+=FileSize; + fread(B,servArchiveSize,1,F); + DWORD Crc=0xAAAAAAAA; +/* { + DWORD *S=(DWORD*)(B+FileSize); + Size>>=2; + DWORD *E=S+Size; + for(;S!=E;S++) + { + Crc<<=4; + Crc^=*S; + } + servTBZ2Crc=Crc; + }*/ + fclose(F); + *mapFileDataServ=B; + return Ret; + } + void __cdecl serverTransferStart(int Player,void *Data,int Size,int Mode) + { + BYTE Buf[MAX_PATH+sizeof(int)+4]; + BYTE *P=Buf; + int Len=strlen(servArchiveName); + netUniPacket(upSendArchive,P,sizeof(int)+Len); + *((int*)P)=*mapFileSizeServ-servArchiveSize;/// размер только карты + P+=4; + memcpy(P,servArchiveName,Len); + P+=Len; + netSendBySock(Player,Buf,P-Buf,Mode); + netSendBySock(Player,Data,Size,Mode); + } +} +bool fsRead(const char *File,void *&Data, size_t &Size) +{ + char Buf[220]=""; + Data=NULL;Size=0; + TarBlock *B = itemByName(File,true,Buf); + if (!B) + return false; + Data=B->Info.Data; + Size=B->Info.Size; + return true; +} +void netOnSendArchive(int Size,char *Name,char *NameE) +{ + cliMapSize=Size;/// размер карты + if (ArchiveName) + { + delete ArchiveName; + ArchiveName=0; + } + ArchiveName=new char[NameE-Name+1]; + strncpy(ArchiveName,Name,NameE-Name); + ArchiveName[NameE-Name]=0; +} +void netOnAbortDownload() +{ + if (MapPath) + { + delete MapPath; + MapPath=0; + } + if (ArchiveName) + { + delete ArchiveName; + ArchiveName=0; + } + cliMapSize=0; +} +void mapLoadFilesystem(const char *MapName) +{ + char Buf[200]; + do + { + sprintf(Buf,"maps/%s/%s.tbz2",MapName,MapName); + if (readFile(Buf,MapList)) + break; + sprintf(Buf,"maps/%s/%s.tar.bz2",MapName,MapName); + if (readFile(Buf,MapList)) + break; + return; //не нашли файла + }while (0); + TarBlock *B=dirSearch("server.lua",&MapList); + if (B==NULL) + return; // нету луафайла для сервера + if (B->Info.Size>0) + { + int Top=lua_gettop(L); + bool Ok=false; + do + { + if (0!=luaL_loadbuffer(L,(char*)B->Info.Data,B->Info.Size,Buf)) + break; + lua_getfield(L,LUA_REGISTRYINDEX,"server"); + lua_setfenv(L,-2); + if (0!= lua_pcall(L,0,0,0)) + break; + Ok=true; + }while(0); + if (!Ok) + { + conPrintI(lua_tostring(L,-1)); + } + lua_settop(L,Top); + } +} +void mapUnloadFilesystem() +{ + for (TarList::iterator I=MapList.begin();I!=MapList.end();I++) + { + delete (*I); + } + MapList.clear(); +} +extern void InjectOffs(DWORD Addr,void *Fn); +void initFilesystem() +{ +/* +при смене карты +MSG_USE_MAP приходит всем, клиентам включая сервак +устанавливает в gameFlags флаг необходимости загрузки +затем в главном цикле при проверке флага загружает данные + +*/ + InjectOffs(0x004AB7FD+1,&clientWriteChunk); + InjectOffs(0x004AB8BC+1,&clientWriteChunk); + InjectOffs(0x004ABD64+1,&clientOpenFile); + InjectOffs(0x0043DEF6+1,&mapValidate); + + InjectOffs(0x0051A0A1+1,&serverTransferPrepair); + + InjectOffs(0x00519AA7+1,&serverTransferStart); + + ASSIGN(mapFileHandle,0x007141D4); + ASSIGN(noxWriteToFile,0x00565A02); + ASSIGN(noxFopen,0x0056586C); + ASSIGN(noxFclose,0x00407533); + ASSIGN(mapValidateMB,0x004CF470); + ASSIGN(mapFileDataServ,0x0081B834); + ASSIGN(mapFileSizeServ,0x0081B838); + + lua_newtable(L);/// в эту таблицу будем что-нить класть если ведем глобальный поиск + lua_pushcclosure(L,&bz2Loader,1); + lua_setglobal(L,"bz2Loader"); + lua_register(L,"fileLoad",&loadFileL); + } \ No newline at end of file diff --git a/fxBuff.cpp b/fxBuff.cpp index a84c9c3..70d9b60 100644 --- a/fxBuff.cpp +++ b/fxBuff.cpp @@ -1,314 +1,314 @@ -#include "stdafx.h" -#include "unit.h" -#include "player.h" - -extern void (__cdecl *noxRasterPoint)(int X,int Y); -extern void (__cdecl *noxRasterPointRel)(int X,int Y); -extern void (__cdecl *noxRasterDrawLines)(); - -extern int (__cdecl *noxSetRectColorMB) (int); - -extern DWORD *GameFlags; -FxBuffer_t *FxFirstBuffer=0; -extern BYTE **clientPlayerInfoPtr; - -void FxBuffer_t::getValues(int First,int Len) -{ - // -} -bool FxBuffer_t::delBlock(int Id) // -{ - int State=0; - int Cnt=0; - int Free; - int Start=0; - DWORD *CntPtr=0; - for (FxBuffer_t *Buf=FxFirstBuffer;Buf!=NULL;Buf=Buf->Next) - { - Free=0; - for (DWORD *P=Buf->Data,*E=P + (Buf->Size - Buf->FreeSize) ;PData)) - { - *P=1;// - State=3; - return true;//TODO - } - State=1; - }else if (1==*P) - { - State=1; - } - break; - case 1: // - CntPtr=P; - Cnt=*P; - State=2; - break; - case 2: - if (Cnt>0) - Cnt--; - else - { - State=1; - } - - break; - }//switch - Start +=Buf->Size - Buf->FreeSize; - P++; - } - if (State==2) - { - if (Cnt==0) // - { - Buf->FreeSize+=Free; - } - else if (Cnt>0 && Buf->Next!=0) - { - Buf->FreeSize+=Free; - Buf=Buf->Next; - DWORD *P=Buf->Data; - *P=1; - P++; - *P=Cnt-2; - } - } - } - return false; -} -FxBuffer_t *FxBuffer_t::addBlock(int Size,int *Id) -{ - if (Size<1) - return NULL; - FxBuffer_t *Ret=0; - int FreeSize=0; - int Idx = 0; - Size+=2; - if (FxFirstBuffer==0) - { - FreeSize = (Size + 0xF)&~0xF; - Ret = (FxBuffer_t *)new byte[ 4*FreeSize + sizeof(FxBuffer_t)]; - Ret->Size = FreeSize; - Ret->SelIdx = 0; - Ret->Next = 0; - Ret->FreeSize = FreeSize; - FxFirstBuffer = Ret; - } - else - { - FxBuffer_t *Buf2=0; - for (Ret = FxFirstBuffer;Ret!=NULL && Ret->FreeSize < Size;Ret=Ret->Next) - { - Idx += Ret->Size; - Buf2=Ret; - } - if (Ret==NULL) - { - FreeSize = (Size + 0xF)&~0xF; - Ret = (FxBuffer_t *)new byte[ 4*FreeSize + sizeof(FxBuffer_t)]; - Ret->Size = FreeSize; - Ret->SelIdx = 0; - Ret->Next = 0; - Ret->FreeSize = FreeSize; - Buf2->Next = Ret; - } - } - Idx += Ret->Size - Ret->FreeSize; - Ret->FreeSize -= Size; - Ret->addItem(0); - Ret->addItem(Size-2); - *Id=Idx; - return Ret; -} - -// -void FxBuffer_t::drawBuffers() -{ - int State=0; - int Cnt=0; - int OfsX=0,OfsY=0; - int X1,Y1,X2,Y2; - int Idx=0; - char Stop[sizeof(FxBuffer_t)]={0}; - FxBuffer_t *StopBuf=(FxBuffer_t *)&Stop; - - for (FxBuffer_t *Buf=FxFirstBuffer;Buf!=NULL;Buf=Buf->Next) - { - for (DWORD *P=Buf->Data,*E=P + (Buf->Size - Buf->FreeSize) ;PNext,Base+=db->Size) - { - if ( X1 > Base && X1 < Base + db->Size ) // - { - X1 -=Base; - sp = db->Data; - } - if ( X2 > Base && X2 < Base + db->Size ) // - { - X2 -=Base; - dp = db->Data; - } - } - while ( Cnt-- ) - { - *dp = *sp + Y1; - dp++; - sp++; - if (!Cnt--) - break; - *dp = *sp + Y2; - dp++; - sp++; - - } - State=0; - } - break; - case 15: //line to cursor - X1 = *((int*)(P++)); - State=114; - break; - case 114: - Y1 = *((int*)(P++)); - State=115; - break; - case 115: - if ((*GameFlags&1)==0) //client - { - int *pI=(int*)(*clientPlayerInfoPtr+0x8EC); - X2=*(pI++); - Y2=*pI; - } - else - { - X2=-1; - for (bigUnitStruct *Pl=playerFirstUnit();Pl!=NULL;Pl=playerNextUnit(Pl)) - { - char *Uc=(char *)Pl->unitController; - Uc=*((char **)(Uc+0x114)); - if (Uc[0x810]!=*P) - continue; - int *pI=(int*)(Uc+0x8EC); - X2=*(pI++); - Y2=*pI; - break; - } - } - P++; - if (X2>0) - { - noxRasterPoint(X1 - OfsX,Y1 - OfsY); - noxRasterPoint(X2 - OfsX,Y2 - OfsY); - noxRasterDrawLines(); - } - State=0; - break; - case 16: - default: - P++; - break; - } - } - } +#include "stdafx.h" +#include "unit.h" +#include "player.h" + +extern void (__cdecl *noxRasterPoint)(int X,int Y); +extern void (__cdecl *noxRasterPointRel)(int X,int Y); +extern void (__cdecl *noxRasterDrawLines)(); + +extern int (__cdecl *noxSetRectColorMB) (int); + +extern DWORD *GameFlags; +FxBuffer_t *FxFirstBuffer=0; +extern BYTE **clientPlayerInfoPtr; + +void FxBuffer_t::getValues(int First,int Len) +{ + //еще не готово +} +bool FxBuffer_t::delBlock(int Id) //удаляем блок +{ + int State=0; + int Cnt=0; + int Free; + int Start=0; + DWORD *CntPtr=0; + for (FxBuffer_t *Buf=FxFirstBuffer;Buf!=NULL;Buf=Buf->Next) + { + Free=0; + for (DWORD *P=Buf->Data,*E=P + (Buf->Size - Buf->FreeSize) ;PData)) + { + *P=1;// пропуск + State=3; + return true;//TODO + } + State=1; + }else if (1==*P) + { + State=1; + } + break; + case 1: // грузим счетчик + CntPtr=P; + Cnt=*P; + State=2; + break; + case 2: + if (Cnt>0) + Cnt--; + else + { + State=1; + } + + break; + }//switch + Start +=Buf->Size - Buf->FreeSize; + P++; + } + if (State==2) + { + if (Cnt==0) // съели последний кусок + { + Buf->FreeSize+=Free; + } + else if (Cnt>0 && Buf->Next!=0) + { + Buf->FreeSize+=Free; + Buf=Buf->Next; + DWORD *P=Buf->Data; + *P=1; + P++; + *P=Cnt-2; + } + } + } + return false; +} +FxBuffer_t *FxBuffer_t::addBlock(int Size,int *Id) +{ + if (Size<1) + return NULL; + FxBuffer_t *Ret=0; + int FreeSize=0; + int Idx = 0; + Size+=2; + if (FxFirstBuffer==0) + { + FreeSize = (Size + 0xF)&~0xF; + Ret = (FxBuffer_t *)new byte[ 4*FreeSize + sizeof(FxBuffer_t)]; + Ret->Size = FreeSize; + Ret->SelIdx = 0; + Ret->Next = 0; + Ret->FreeSize = FreeSize; + FxFirstBuffer = Ret; + } + else + { + FxBuffer_t *Buf2=0; + for (Ret = FxFirstBuffer;Ret!=NULL && Ret->FreeSize < Size;Ret=Ret->Next) + { + Idx += Ret->Size; + Buf2=Ret; + } + if (Ret==NULL) + { + FreeSize = (Size + 0xF)&~0xF; + Ret = (FxBuffer_t *)new byte[ 4*FreeSize + sizeof(FxBuffer_t)]; + Ret->Size = FreeSize; + Ret->SelIdx = 0; + Ret->Next = 0; + Ret->FreeSize = FreeSize; + Buf2->Next = Ret; + } + } + Idx += Ret->Size - Ret->FreeSize; + Ret->FreeSize -= Size; + Ret->addItem(0); + Ret->addItem(Size-2); + *Id=Idx; + return Ret; +} + +// еще надо относительно курсора сделать +void FxBuffer_t::drawBuffers() +{ + int State=0; + int Cnt=0; + int OfsX=0,OfsY=0; + int X1,Y1,X2,Y2; + int Idx=0; + char Stop[sizeof(FxBuffer_t)]={0}; + FxBuffer_t *StopBuf=(FxBuffer_t *)&Stop; + + for (FxBuffer_t *Buf=FxFirstBuffer;Buf!=NULL;Buf=Buf->Next) + { + for (DWORD *P=Buf->Data,*E=P + (Buf->Size - Buf->FreeSize) ;PNext,Base+=db->Size) + { + if ( X1 > Base && X1 < Base + db->Size ) // в этом буфере лежит источник + { + X1 -=Base; + sp = db->Data; + } + if ( X2 > Base && X2 < Base + db->Size ) // в этом буфере лежит назначение + { + X2 -=Base; + dp = db->Data; + } + } + while ( Cnt-- ) + { + *dp = *sp + Y1; + dp++; + sp++; + if (!Cnt--) + break; + *dp = *sp + Y2; + dp++; + sp++; + + } + State=0; + } + break; + case 15: //line to cursor + X1 = *((int*)(P++)); + State=114; + break; + case 114: + Y1 = *((int*)(P++)); + State=115; + break; + case 115: + if ((*GameFlags&1)==0) //client + { + int *pI=(int*)(*clientPlayerInfoPtr+0x8EC); + X2=*(pI++); + Y2=*pI; + } + else + { + X2=-1; + for (bigUnitStruct *Pl=playerFirstUnit();Pl!=NULL;Pl=playerNextUnit(Pl)) + { + char *Uc=(char *)Pl->unitController; + Uc=*((char **)(Uc+0x114)); + if (Uc[0x810]!=*P) + continue; + int *pI=(int*)(Uc+0x8EC); + X2=*(pI++); + Y2=*pI; + break; + } + } + P++; + if (X2>0) + { + noxRasterPoint(X1 - OfsX,Y1 - OfsY); + noxRasterPoint(X2 - OfsX,Y2 - OfsY); + noxRasterDrawLines(); + } + State=0; + break; + case 16: + default: + P++; + break; + } + } + } } \ No newline at end of file diff --git a/gui.cpp b/gui.cpp index 1e933aba5c98fa5a5f604c837415d1d56984e2aa..2c0b8a3799693c2a5ebc6d0c54742527131ea835 100644 GIT binary patch delta 15 XcmaE}it*hlMwW~H7yC9cWrYF&Kkx@; delta 13 VcmaF2it)`VMyCJ&HnL=e0st~s2BZK0 diff --git a/imageUtil.cpp b/imageUtil.cpp index bd32b14..b6cc313 100644 --- a/imageUtil.cpp +++ b/imageUtil.cpp @@ -1,530 +1,530 @@ -#include "stdafx.h" -#include -#include "math.h" -extern "C" -{ -#include "png.h" -#include "pngstruct.h" -} - -extern void *(__cdecl *noxAlloc)(int Size); -extern void (__cdecl *noxFree)(void *Ptr); - -struct imgArrayItemAnimRec -{ - int field_0; - void *vbagIdArrPtr; - char vbagIdArrSize; - char field_9; - char isLooped; - char gap_b[1]; - int field_C; -}; - -struct imgArrayItem -{ - char imageName[32]; - char animDirNameMB[32]; - char gap_40[32]; - int imageVbagId;// - - char auxImageType; - char imgFlagsMB; - short field_66; -}; -struct imageH /// gLoadItem -{ - void* dataPtr; - int field_4; - unsigned short vbagId; - // 0x80 - // 0x40 , - - // 2 - 16 - // 3 - RLE (menuBg,BorderCornerUL) - // 7 - 16 , ( ) - // - char typeFlags; - char field_B; -}; -struct Sprite2 -{ - int W,H,dX,dY; - byte Some; -}; - -imgArrayItem **imgArray; // vbag -int *imgArraySize; -int *imgArrayNextId; // vbag ( ) - -namespace -{ - - struct ImgVectorRec - { - imgArrayItem *Items; - int Size; - int Used; - ImgVectorRec(int Size_,void *Data): - Items((imgArrayItem *)Data), - Size(Size_), - Used(0) - { - - } - }; - typedef std::list ImgVectorList; - ImgVectorList imgVector; - - int __cdecl gLoadImgSearchImpl(const char *SearchFor) - { - imgArrayItem *P = *imgArray; - imgArrayItem *E = P + *imgArrayNextId; - for (int i=0;P!=E;P++,i++) - { - if (0==strncmp(P->imageName,SearchFor,sizeof(P->imageName))) - return i; - } - for (ImgVectorList::iterator I=imgVector.begin();I!=imgVector.end();I++) - { - P = I->Items; - E = P + I->Used; - for (int i=0;P!=E;P++,i++) - { - if (0==strncmp(P->imageName,SearchFor,sizeof(P->imageName))) - { - // - return P->imageVbagId; - } - } - } - return 0; - } - void __declspec(naked) gLoadImgSearch() - { - __asm - { - push edx - push eax - call gLoadImgSearchImpl - add esp,4 - pop edx // - test eax,eax - jz l1 - cmp eax,edx - jge l2 - mov edi,eax - push 0x0042F9D0 - ret - l2: - // - pop edi - pop esi - pop ebp - pop ebx - ret - l1: - push 0x0042F9C9 // - ret - } - } - void imgAddImage(const char *Name,void *Data) - { - const int Growth=32; - imgArrayItem *P=0; - for (ImgVectorList::iterator I=imgVector.begin();I!=imgVector.end();I++) - { - if (I->Size>I->Used) - { - P=I->Items + I->Used; - I->Used++; // - break; - } - } - if (P==NULL) /// - { - imgVector.push_back( - ImgVectorRec(Growth,malloc(Growth*sizeof(imgArrayItem) )) - ); - P=imgVector.back().Items; - imgVector.back().Used=1;/// - } - memset(P,0,sizeof(*P)); - strncpy(P->imageName,Name,sizeof(P->imageName)); - P->imageVbagId=(int)Data; - } - struct PngData - { - png_structp png_ptr; - png_infop info_ptr; - - png_bytep *row_pointers; - int width; - int height; - int color; - }; - struct PngReadData - { - void *Buf; - void *Current; - void *End; - PngReadData(void *Ptr,int Size):Buf(Ptr),Current(Ptr),End((char*)Ptr+Size){} - }; - bool imgPngStart(PngData *png,PngReadData *readData); - void imgPngFinish(PngData *png); - /// args: srcPath[,imgName=srcPath /*[,imgType=2]*/ ] - int imgLoadImage(lua_State*L) - { - lua_settop(L,3); - if (!lua_isstring(L,1)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - - imageH *H= (imageH *)noxAlloc(sizeof(imageH)); - const char *imgName=lua_tostring(L,2); - if (imgName==NULL) - imgName=lua_tostring(L,1); - imgAddImage(imgName,H); - - Sprite2 *SpritePtr=NULL; - - png_structp png_ptr; - png_infop info_ptr; - - - PngData png; - size_t Size; - void *Data; - if (!fsRead(lua_tostring(L,1),Data,Size)) - return 0; - PngReadData readData(Data,Size); - - if (!imgPngStart(&png,&readData)) - { - return 0; - } - int Width=png.width; - int Height=png.height; - - bool useAlpha=(png.color==PNG_COLOR_TYPE_RGBA); - int imgType=(useAlpha?3:2); - int BlockSize=0; - if (useAlpha) - BlockSize=sizeof(Sprite2) + 3 * Width * Height; - // A/C ( 6xWxH) - else - BlockSize=sizeof(Sprite2) + 2 * Width * Height ; - H->dataPtr=noxAlloc(BlockSize); - H->typeFlags=0x80 | imgType;// , 2 - H->vbagId=1;// - SpritePtr=(Sprite2*)H->dataPtr; - SpritePtr->W=Width; - SpritePtr->H=Height; - SpritePtr->dX=0; - SpritePtr->dY=0; - SpritePtr->Some=0; - short *P=(short*)(((byte*)H->dataPtr)+sizeof(Sprite2)); -//#define RGB2(r,g,b) ((((r)&0x1F)<<11)|(((g)&0x3F)<<5)|((b)&0x1F)) -#define RGB4(r,g,b,a) ((((r)>>3)<<11)|(((g)>>3)<<6)|(((b)>>3)<<1)|((a?1:0))) -#define RGB3(r,g,b) ((((r)>>3)<<11)|(((g)>>2)<<5)|((b)>>3)) - if (useAlpha) - { - for (int j=0;j0 && PP!=NULL) - { - *PP=Counter; - Counter=0; - } - PP=(Byte*)P; - if (Src[3]<0x40) - State=emSkip; - else if ( Src[3]> 0xC0) - State=emPlain; - else - State=emTrans; - - *(PP++)=State; - *PP=0; - P++; - i--; - continue; - } - else if (State==emSkip) - { - if (Src[3]<0x40) - { - if ( ++Counter==255) - State=emUnk; - Src+=4; - continue; - } - State=emUnk; - i--; - } - else if (State==emPlain) - { - if (Src[3]>0xC0) - { - if ( ++Counter==255) - State=emUnk; - *(P++)=RGB3(Src[0],Src[1],Src[2]); - Src+=4; - continue; - } - State=emUnk; - i--; - } - else if (State==emTrans) - { - if ( (Src[3]>0x40) && Src[3]<0xC0) - { - if ( ++Counter==255) - State=emUnk; - *(P++)=RGB4(Src[0],Src[1],Src[2],Src[3]); - Src+=4; - continue; - } - State=emUnk; - i--; - } - } - if (Counter>0 && PP!=NULL) - *PP=Counter; - } - } - else - { - for (int j=0;jio_ptr; - if (readData==NULL) - return; - if (Size > (char*)readData->End - (char*)readData->Current) // , - return; - memcpy(Data,readData->Current,Size); - readData->Current=((char*)readData->Current)+Size; - } - void* PNGCAPI pngMyMalloc(png_structp png_ptr, png_size_t Size) - { - return malloc(Size); - } - void pngMyFree(png_structp png_ptr, void *Ptr) - { - return free(Ptr); - } - bool imgPngStart(PngData *png,PngReadData *readData) - { - png_structp &png_ptr=png->png_ptr; - png_infop &info_ptr=png->info_ptr; - png_uint_32 width, height; - int bit_depth, color_type, interlace_type; - memset(png,0,sizeof(*png)); - - /* Create and initialize the png_struct with the desired error handler - * functions. If you want to use the default stderr and longjump method, - * you can supply NULL for the last three parameters. We also supply the - * the compiler header file version, so that we know if the application - * was compiled with a compatible version of the library. REQUIRED - */ - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,&error_fn, &warn_fn); - if (png_ptr == NULL) - { - return (ERROR); - } - try - { - - png_set_mem_fn(png_ptr,NULL,pngMyMalloc,pngMyFree); - /* Allocate/initialize the memory for image information. REQUIRED. */ - info_ptr = png_create_info_struct(png_ptr); - - if (info_ptr == NULL) - { - png_destroy_read_struct(&png_ptr, NULL, NULL); - return (ERROR); - } - - /* Set error handling if you are using the setjmp/longjmp method (this is - * the normal method of doing things with libpng). REQUIRED unless you - * set up your own error handlers in the png_create_read_struct() earlier. - */ - - /* if (setjmp(png_jmpbuf(png_ptr))) - { - // Free all of the memory associated with the png_ptr and info_ptr - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - // If we get here, we had a problem reading the file - return (ERROR); - } - _CrtCheckMemory();*/ - - - /* If you are using replacement read functions, instead of calling - * png_init_io() here you would call: - */ - png_set_read_fn(png_ptr, readData, &read_fn); - - /* The call to png_read_info() gives us all of the information from the - * PNG file before the first IDAT (image data chunk). REQUIRED - */ - png_read_info(png_ptr, info_ptr); - - png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, - &interlace_type, NULL, NULL); - - png->width=width; - png->height=height; - png->color=color_type; - /* Set up the data transformations you want. Note that these are all - * optional. Only call them if you want/need them. Many of the - * transformations only work on specific types of images, and many - * are mutually exclusive. - */ - - /* Tell libpng to strip 16 bit/color files down to 8 bits/color */ - png_set_strip_16(png_ptr); - - /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single - * byte into separate bytes (useful for paletted and grayscale images). - */ - png_set_packing(png_ptr); - - /* Expand paletted colors into true RGB triplets */ - if (color_type == PNG_COLOR_TYPE_PALETTE) - png_set_palette_to_rgb(png_ptr); - - /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ - if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) - png_set_expand_gray_1_2_4_to_8(png_ptr); - - /* Expand paletted or RGB images with transparency to full alpha channels - * so the data will be available as RGBA quartets. - */ - // if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) - // png_set_tRNS_to_alpha(png_ptr); - - - /* Add filler (or alpha) byte (before/after each RGB triplet) */ - //png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE); - - - /* Turn on interlace handling. REQUIRED if you are not using - * png_read_image(). To see how to handle interlacing passes, - * see the png_read_row() method below: - */ - int number_passes = png_set_interlace_handling(png_ptr); - - /* Allocate the memory to hold the image using the fields of info_ptr. */ - - /* The easiest way to read the image: */ - png_bytep *row_pointers= (png_bytep *)malloc(sizeof(png_bytep)*height); - - /* Clear the pointer array */ - for (int row = 0; row < height; row++) - { - row_pointers[row] = (png_bytep)malloc( png_get_rowbytes(png_ptr,info_ptr)); //(png_bytep) png_malloc(png_ptr, png_get_rowbytes(png_ptr,info_ptr)); - } - int dataSize=32 + png_get_rowbytes(png_ptr,info_ptr); - png_bytep Data=(png_bytep )malloc( dataSize); - memset(Data,0,dataSize); - -// png_read_image(png_ptr, row_pointers); - for (int pass = 0; pass < number_passes; pass++) - { - for (int y = 0; y < height; y++) - { - png_read_row(png_ptr, row_pointers[y] , NULL);//row_pointers[y] - } - } - - png->row_pointers=row_pointers; - } - catch(const char *S) - { - _CrtCheckMemory(); - conPrintI(S); - } - return 1; - } - void imgPngFinish(PngData *png) - { - png_structp &png_ptr(png->png_ptr); - png_infop &info_ptr(png->info_ptr); - - try - { - png_bytep *row_pointers=png->row_pointers; - int height=png->height; - - for (int row = 0; row < height; row++) - { - free(row_pointers[row]); - } - free(row_pointers); - - /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */ - png_read_end(png_ptr, info_ptr); - - /* At this point you have read the entire image */ - - /* Clean up after the read, and free any memory allocated - REQUIRED */ - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - } - catch (const char *S) - { - conPrintI(S); - } - memset(png,0,sizeof(*png)); - } - -} - -extern void InjectJumpTo(DWORD Addr,void *Fn); - -void ImageUtilInit() -{ - ASSIGN(imgArray,0x00694868); - ASSIGN(imgArraySize,0x0069486C ); - ASSIGN(imgArrayNextId,0x00694870); - - InjectJumpTo(0x0042F982,gLoadImgSearch); - registerclient("imgLoad",imgLoadImage); // - +#include "stdafx.h" +#include +#include "math.h" +extern "C" +{ +#include "png.h" +#include "pngstruct.h" +} + +extern void *(__cdecl *noxAlloc)(int Size); +extern void (__cdecl *noxFree)(void *Ptr); + +struct imgArrayItemAnimRec +{ + int field_0; + void *vbagIdArrPtr; + char vbagIdArrSize; + char field_9; + char isLooped; + char gap_b[1]; + int field_C; +}; + +struct imgArrayItem +{ + char imageName[32]; + char animDirNameMB[32]; + char gap_40[32]; + int imageVbagId;// для собственных картинок - тут указатель + char auxImageType; + char imgFlagsMB; + short field_66; +}; +struct imageH /// указатель на эту структуру возвращает gLoadItem +{ + void* dataPtr; + int field_4; + unsigned short vbagId; + // 0x80 значит загружено + // 0x40 хз, остальные - тип изображения + // 2 - обычный 16битный растр цветов + // 3 - RLE популярный с прозрачностью вроде (menuBg,BorderCornerUL) + // 7 - 16битный растр цветов с предобработкой, отключен (не может быть нарисован) + // + char typeFlags; + char field_B; +}; +struct Sprite2 +{ + int W,H,dX,dY; + byte Some; +}; + +imgArrayItem **imgArray; //указатель на массив vbag +int *imgArraySize; +int *imgArrayNextId; // фактический размер массива vbag (создается нами) + +namespace +{ + + struct ImgVectorRec + { + imgArrayItem *Items; + int Size; + int Used; + ImgVectorRec(int Size_,void *Data): + Items((imgArrayItem *)Data), + Size(Size_), + Used(0) + { + + } + }; + typedef std::list ImgVectorList; + ImgVectorList imgVector; + + int __cdecl gLoadImgSearchImpl(const char *SearchFor) + { + imgArrayItem *P = *imgArray; + imgArrayItem *E = P + *imgArrayNextId; + for (int i=0;P!=E;P++,i++) + { + if (0==strncmp(P->imageName,SearchFor,sizeof(P->imageName))) + return i; + } + for (ImgVectorList::iterator I=imgVector.begin();I!=imgVector.end();I++) + { + P = I->Items; + E = P + I->Used; + for (int i=0;P!=E;P++,i++) + { + if (0==strncmp(P->imageName,SearchFor,sizeof(P->imageName))) + { + //нашли + return P->imageVbagId; + } + } + } + return 0; + } + void __declspec(naked) gLoadImgSearch() + { + __asm + { + push edx + push eax + call gLoadImgSearchImpl + add esp,4 + pop edx // количество спрайтов в вбаге + test eax,eax + jz l1 + cmp eax,edx + jge l2 + mov edi,eax + push 0x0042F9D0 + ret + l2: + // случай когда кастом + pop edi + pop esi + pop ebp + pop ebx + ret + l1: + push 0x0042F9C9 // случай когда не найдено + ret + } + } + void imgAddImage(const char *Name,void *Data) + { + const int Growth=32; + imgArrayItem *P=0; + for (ImgVectorList::iterator I=imgVector.begin();I!=imgVector.end();I++) + { + if (I->Size>I->Used) + { + P=I->Items + I->Used; + I->Used++; // сейчас добавим + break; + } + } + if (P==NULL) /// надо добавить новых + { + imgVector.push_back( + ImgVectorRec(Growth,malloc(Growth*sizeof(imgArrayItem) )) + ); + P=imgVector.back().Items; + imgVector.back().Used=1;/// сейчас добавим + } + memset(P,0,sizeof(*P)); + strncpy(P->imageName,Name,sizeof(P->imageName)); + P->imageVbagId=(int)Data; + } + struct PngData + { + png_structp png_ptr; + png_infop info_ptr; + + png_bytep *row_pointers; + int width; + int height; + int color; + }; + struct PngReadData + { + void *Buf; + void *Current; + void *End; + PngReadData(void *Ptr,int Size):Buf(Ptr),Current(Ptr),End((char*)Ptr+Size){} + }; + bool imgPngStart(PngData *png,PngReadData *readData); + void imgPngFinish(PngData *png); + /// args: srcPath[,imgName=srcPath /*[,imgType=2]*/ ] + int imgLoadImage(lua_State*L) + { + lua_settop(L,3); + if (!lua_isstring(L,1)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + + imageH *H= (imageH *)noxAlloc(sizeof(imageH)); + const char *imgName=lua_tostring(L,2); + if (imgName==NULL) + imgName=lua_tostring(L,1); + imgAddImage(imgName,H); + + Sprite2 *SpritePtr=NULL; + + png_structp png_ptr; + png_infop info_ptr; + + + PngData png; + size_t Size; + void *Data; + if (!fsRead(lua_tostring(L,1),Data,Size)) + return 0; + PngReadData readData(Data,Size); + + if (!imgPngStart(&png,&readData)) + { + return 0; + } + int Width=png.width; + int Height=png.height; + + bool useAlpha=(png.color==PNG_COLOR_TYPE_RGBA); + int imgType=(useAlpha?3:2); + int BlockSize=0; + if (useAlpha) + BlockSize=sizeof(Sprite2) + 3 * Width * Height; + // предполагаю что не будет через один A/C (в худшем случае размер будет 6xWxH) + else + BlockSize=sizeof(Sprite2) + 2 * Width * Height ; + H->dataPtr=noxAlloc(BlockSize); + H->typeFlags=0x80 | imgType;// загружено в указатель формат, 2 + H->vbagId=1;// для примера + SpritePtr=(Sprite2*)H->dataPtr; + SpritePtr->W=Width; + SpritePtr->H=Height; + SpritePtr->dX=0; + SpritePtr->dY=0; + SpritePtr->Some=0; + short *P=(short*)(((byte*)H->dataPtr)+sizeof(Sprite2)); +//#define RGB2(r,g,b) ((((r)&0x1F)<<11)|(((g)&0x3F)<<5)|((b)&0x1F)) +#define RGB4(r,g,b,a) ((((r)>>3)<<11)|(((g)>>3)<<6)|(((b)>>3)<<1)|((a?1:0))) +#define RGB3(r,g,b) ((((r)>>3)<<11)|(((g)>>2)<<5)|((b)>>3)) + if (useAlpha) + { + for (int j=0;j0 && PP!=NULL) + { + *PP=Counter; + Counter=0; + } + PP=(Byte*)P; + if (Src[3]<0x40) + State=emSkip; + else if ( Src[3]> 0xC0) + State=emPlain; + else + State=emTrans; + + *(PP++)=State; + *PP=0; + P++; + i--; + continue; + } + else if (State==emSkip) + { + if (Src[3]<0x40) + { + if ( ++Counter==255) + State=emUnk; + Src+=4; + continue; + } + State=emUnk; + i--; + } + else if (State==emPlain) + { + if (Src[3]>0xC0) + { + if ( ++Counter==255) + State=emUnk; + *(P++)=RGB3(Src[0],Src[1],Src[2]); + Src+=4; + continue; + } + State=emUnk; + i--; + } + else if (State==emTrans) + { + if ( (Src[3]>0x40) && Src[3]<0xC0) + { + if ( ++Counter==255) + State=emUnk; + *(P++)=RGB4(Src[0],Src[1],Src[2],Src[3]); + Src+=4; + continue; + } + State=emUnk; + i--; + } + } + if (Counter>0 && PP!=NULL) + *PP=Counter; + } + } + else + { + for (int j=0;jio_ptr; + if (readData==NULL) + return; + if (Size > (char*)readData->End - (char*)readData->Current) // слишком много, столько нет + return; + memcpy(Data,readData->Current,Size); + readData->Current=((char*)readData->Current)+Size; + } + void* PNGCAPI pngMyMalloc(png_structp png_ptr, png_size_t Size) + { + return malloc(Size); + } + void pngMyFree(png_structp png_ptr, void *Ptr) + { + return free(Ptr); + } + bool imgPngStart(PngData *png,PngReadData *readData) + { + png_structp &png_ptr=png->png_ptr; + png_infop &info_ptr=png->info_ptr; + png_uint_32 width, height; + int bit_depth, color_type, interlace_type; + memset(png,0,sizeof(*png)); + + /* Create and initialize the png_struct with the desired error handler + * functions. If you want to use the default stderr and longjump method, + * you can supply NULL for the last three parameters. We also supply the + * the compiler header file version, so that we know if the application + * was compiled with a compatible version of the library. REQUIRED + */ + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,&error_fn, &warn_fn); + if (png_ptr == NULL) + { + return (ERROR); + } + try + { + + png_set_mem_fn(png_ptr,NULL,pngMyMalloc,pngMyFree); + /* Allocate/initialize the memory for image information. REQUIRED. */ + info_ptr = png_create_info_struct(png_ptr); + + if (info_ptr == NULL) + { + png_destroy_read_struct(&png_ptr, NULL, NULL); + return (ERROR); + } + + /* Set error handling if you are using the setjmp/longjmp method (this is + * the normal method of doing things with libpng). REQUIRED unless you + * set up your own error handlers in the png_create_read_struct() earlier. + */ + + /* if (setjmp(png_jmpbuf(png_ptr))) + { + // Free all of the memory associated with the png_ptr and info_ptr + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + // If we get here, we had a problem reading the file + return (ERROR); + } + _CrtCheckMemory();*/ + + + /* If you are using replacement read functions, instead of calling + * png_init_io() here you would call: + */ + png_set_read_fn(png_ptr, readData, &read_fn); + + /* The call to png_read_info() gives us all of the information from the + * PNG file before the first IDAT (image data chunk). REQUIRED + */ + png_read_info(png_ptr, info_ptr); + + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, + &interlace_type, NULL, NULL); + + png->width=width; + png->height=height; + png->color=color_type; + /* Set up the data transformations you want. Note that these are all + * optional. Only call them if you want/need them. Many of the + * transformations only work on specific types of images, and many + * are mutually exclusive. + */ + + /* Tell libpng to strip 16 bit/color files down to 8 bits/color */ + png_set_strip_16(png_ptr); + + /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single + * byte into separate bytes (useful for paletted and grayscale images). + */ + png_set_packing(png_ptr); + + /* Expand paletted colors into true RGB triplets */ + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb(png_ptr); + + /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ + if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) + png_set_expand_gray_1_2_4_to_8(png_ptr); + + /* Expand paletted or RGB images with transparency to full alpha channels + * so the data will be available as RGBA quartets. + */ + // if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) + // png_set_tRNS_to_alpha(png_ptr); + + + /* Add filler (or alpha) byte (before/after each RGB triplet) */ + //png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE); + + + /* Turn on interlace handling. REQUIRED if you are not using + * png_read_image(). To see how to handle interlacing passes, + * see the png_read_row() method below: + */ + int number_passes = png_set_interlace_handling(png_ptr); + + /* Allocate the memory to hold the image using the fields of info_ptr. */ + + /* The easiest way to read the image: */ + png_bytep *row_pointers= (png_bytep *)malloc(sizeof(png_bytep)*height); + + /* Clear the pointer array */ + for (int row = 0; row < height; row++) + { + row_pointers[row] = (png_bytep)malloc( png_get_rowbytes(png_ptr,info_ptr)); //(png_bytep) png_malloc(png_ptr, png_get_rowbytes(png_ptr,info_ptr)); + } + int dataSize=32 + png_get_rowbytes(png_ptr,info_ptr); + png_bytep Data=(png_bytep )malloc( dataSize); + memset(Data,0,dataSize); + +// png_read_image(png_ptr, row_pointers); + for (int pass = 0; pass < number_passes; pass++) + { + for (int y = 0; y < height; y++) + { + png_read_row(png_ptr, row_pointers[y] , NULL);//row_pointers[y] + } + } + + png->row_pointers=row_pointers; + } + catch(const char *S) + { + _CrtCheckMemory(); + conPrintI(S); + } + return 1; + } + void imgPngFinish(PngData *png) + { + png_structp &png_ptr(png->png_ptr); + png_infop &info_ptr(png->info_ptr); + + try + { + png_bytep *row_pointers=png->row_pointers; + int height=png->height; + + for (int row = 0; row < height; row++) + { + free(row_pointers[row]); + } + free(row_pointers); + + /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */ + png_read_end(png_ptr, info_ptr); + + /* At this point you have read the entire image */ + + /* Clean up after the read, and free any memory allocated - REQUIRED */ + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + } + catch (const char *S) + { + conPrintI(S); + } + memset(png,0,sizeof(*png)); + } + +} + +extern void InjectJumpTo(DWORD Addr,void *Fn); + +void ImageUtilInit() +{ + ASSIGN(imgArray,0x00694868); + ASSIGN(imgArraySize,0x0069486C ); + ASSIGN(imgArrayNextId,0x00694870); + + InjectJumpTo(0x0042F982,gLoadImgSearch); + registerclient("imgLoad",imgLoadImage); // грузить динамически изображение + } \ No newline at end of file diff --git a/keys.cpp b/keys.cpp index bcd2b56..88d5902 100644 --- a/keys.cpp +++ b/keys.cpp @@ -1,180 +1,180 @@ -#include "stdafx.h" - -#define ASSIGN(X,Y) *((DWORD*)&X)=(DWORD)Y; - - -/// -void (__cdecl *keyNextSpell) (); -void (__cdecl *keyPrevSpell) (); -void (__cdecl *keyResetSpell) (); - -int (__cdecl *sub_4160F0)(int A,int B);/// B - -void (__cdecl *sub_4160D0)(int A);/// -void (__cdecl *wnd_452D80)(int A,int B);/// A - ? B - 100 -DWORD (__cdecl *get_57AF20)(); - -void (__cdecl *drawSpellIcons) (keyPack *Keys); -void (__cdecl *keyUpdateRow) (int N); -void (__cdecl *clientStoreLastButton) (int N); - -DWORD *dw_6D4918,*dw_6D492C; - -keyPack *noxKeyPack; - -extern void InjectJumpTo(DWORD Addr,void *Fn); - -namespace -{ - void __cdecl myKeyNextSpell() - { - if ((*dw_6D4918)!=0 || (*dw_6D492C)!=0 )return; - if (0!=get_57AF20()) return; - lua_getglobal(L,"keyOnNext"); - if(lua_type(L,-1)!=LUA_TFUNCTION) - { - lua_pop(L,1);return; - } - if(0!=lua_pcall(L,0,0,0)) - lua_pop(L,1); - } - void __cdecl myKeyPrevSpell() - { - if ((*dw_6D4918)!=0 || (*dw_6D492C)!=0 )return; - if (0!=get_57AF20()) return; - lua_getglobal(L,"keyOnPrev"); - if(lua_type(L,-1)!=LUA_TFUNCTION) - { - lua_pop(L,1);return; - } - if(0!=lua_pcall(L,0,0,0)) - lua_pop(L,1); - } - int keyRowSelectL(lua_State*L) - { - if(lua_isnil(L,1)) - { - lua_pushinteger(L,noxKeyPack->selectedRow); - return 1; - } - int r=lua_tointeger(L,1)-1; - if(r<0) r=0; - if(r>4) r=4; - clientStoreLastButton(-1); - keyUpdateRow(noxKeyPack->selectedRow=r); - lua_pushinteger(L,r+1); - return 1; - } - int keyGetRowL(lua_State*L) - { - int r=lua_tointeger(L,1)-1; - if((r<0)||(r>4)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - lua_newtable(L); - for(int i=0;i<5;i++) - { - lua_pushinteger(L,noxKeyPack->Spells[r*5 + i ].Spell); - lua_rawseti(L,-2,i+1); - } - return 1; - } - int keySetRowL(lua_State*L) - { - if ( - (lua_type(L,1)!=LUA_TTABLE)|| - (lua_type(L,2)!=LUA_TNUMBER) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - int r=lua_tointeger(L,2)-1; - if((r<0)||(r>4)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - lua_pushnil(L); - int i=0; - while(lua_next(L,1)) - { - noxKeyPack->Spells[r*5 + i ].Spell=lua_tointeger(L,-1); - lua_pop(L,1); - i++; - if(i==5) break; - } - return 0; - } - int myKeySelectedRow=4; - void __cdecl myKeyResetSpell() - { - if ((*dw_6D4918)!=0 || (*dw_6D492C)!=0 )return; -/* lua_getglobal(L,"keyOnReset"); - if(lua_type(L,-1)!=LUA_TFUNCTION) - lua_pop(L,1); - else - { - if(0!=lua_pcall(L,0,1,0)) - lua_pop(L,1); - if(lua_toboolean(L,-1)) - { - lua_pop(L,1); - drawSpellIcons(noxKeyPack); - return; - } - lua_pop(L,1); - }*/ - - if (sub_4160F0(7, *((DWORD*)0x85B3FC)>>1 )==0) - { - myKeySelectedRow++; - if(myKeySelectedRow<5) - { - noxKeyPack->selectedRow=4; - myKeySelectedRow=4; - return; - } - } - else - myKeySelectedRow=0; - noxKeyPack->selectedRow=myKeySelectedRow; - noxKeyPack->keyRowPtr=noxKeyPack->keyRowPtr + 5 * noxKeyPack->selectedRow; - sub_4160D0(7); - wnd_452D80(0x31E,100);// ? 0x31E - drawSpellIcons(noxKeyPack); - } - int myFixKeyFn(lua_State*L) - { - InjectJumpTo(0x4604F0,&myKeyNextSpell); - InjectJumpTo(0x460540,&myKeyPrevSpell); - InjectJumpTo(0x460590,&myKeyResetSpell); - return 0; - } -} - - - -void keysInit() -{ - ASSIGN(keyNextSpell,0x4604F0); - ASSIGN(keyPrevSpell,0x460540); - ASSIGN(keyResetSpell,0x460590); - ASSIGN(noxKeyPack, *((DWORD*)0x5A7968) ); - ASSIGN(get_57AF20,0x57AF20); - ASSIGN(clientStoreLastButton,0x45DAD0); - ASSIGN(dw_6D4918,0x6D4918); - ASSIGN(dw_6D492C,0x6D492C); - ASSIGN(sub_4160F0,0x4160F0); - ASSIGN(sub_4160D0,0x4160D0); - ASSIGN(wnd_452D80,0x452D80); - ASSIGN(get_57AF20,0x57AF20); - ASSIGN(drawSpellIcons,0x45DDF0); - ASSIGN(keyUpdateRow,0x45E110); - registerclient("keyLoad",&myFixKeyFn); - registerclient("keyRowSet",&keySetRowL); - registerclient("keyRowGet",&keyGetRowL); - registerclient("keyRowSel",&keyRowSelectL); - +#include "stdafx.h" + +#define ASSIGN(X,Y) *((DWORD*)&X)=(DWORD)Y; + + +/// Просто чтобы знать +void (__cdecl *keyNextSpell) (); +void (__cdecl *keyPrevSpell) (); +void (__cdecl *keyResetSpell) (); + +int (__cdecl *sub_4160F0)(int A,int B);/// B - небольшой интервал +void (__cdecl *sub_4160D0)(int A);/// непонятного действия +void (__cdecl *wnd_452D80)(int A,int B);/// A - код рисунка? B - почти всегда 100 +DWORD (__cdecl *get_57AF20)(); + +void (__cdecl *drawSpellIcons) (keyPack *Keys); +void (__cdecl *keyUpdateRow) (int N); +void (__cdecl *clientStoreLastButton) (int N); + +DWORD *dw_6D4918,*dw_6D492C; + +keyPack *noxKeyPack; + +extern void InjectJumpTo(DWORD Addr,void *Fn); + +namespace +{ + void __cdecl myKeyNextSpell() + { + if ((*dw_6D4918)!=0 || (*dw_6D492C)!=0 )return; + if (0!=get_57AF20()) return; + lua_getglobal(L,"keyOnNext"); + if(lua_type(L,-1)!=LUA_TFUNCTION) + { + lua_pop(L,1);return; + } + if(0!=lua_pcall(L,0,0,0)) + lua_pop(L,1); + } + void __cdecl myKeyPrevSpell() + { + if ((*dw_6D4918)!=0 || (*dw_6D492C)!=0 )return; + if (0!=get_57AF20()) return; + lua_getglobal(L,"keyOnPrev"); + if(lua_type(L,-1)!=LUA_TFUNCTION) + { + lua_pop(L,1);return; + } + if(0!=lua_pcall(L,0,0,0)) + lua_pop(L,1); + } + int keyRowSelectL(lua_State*L) + { + if(lua_isnil(L,1)) + { + lua_pushinteger(L,noxKeyPack->selectedRow); + return 1; + } + int r=lua_tointeger(L,1)-1; + if(r<0) r=0; + if(r>4) r=4; + clientStoreLastButton(-1); + keyUpdateRow(noxKeyPack->selectedRow=r); + lua_pushinteger(L,r+1); + return 1; + } + int keyGetRowL(lua_State*L) + { + int r=lua_tointeger(L,1)-1; + if((r<0)||(r>4)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + lua_newtable(L); + for(int i=0;i<5;i++) + { + lua_pushinteger(L,noxKeyPack->Spells[r*5 + i ].Spell); + lua_rawseti(L,-2,i+1); + } + return 1; + } + int keySetRowL(lua_State*L) + { + if ( + (lua_type(L,1)!=LUA_TTABLE)|| + (lua_type(L,2)!=LUA_TNUMBER) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + int r=lua_tointeger(L,2)-1; + if((r<0)||(r>4)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + lua_pushnil(L); + int i=0; + while(lua_next(L,1)) + { + noxKeyPack->Spells[r*5 + i ].Spell=lua_tointeger(L,-1); + lua_pop(L,1); + i++; + if(i==5) break; + } + return 0; + } + int myKeySelectedRow=4; + void __cdecl myKeyResetSpell() + { + if ((*dw_6D4918)!=0 || (*dw_6D492C)!=0 )return; +/* lua_getglobal(L,"keyOnReset"); + if(lua_type(L,-1)!=LUA_TFUNCTION) + lua_pop(L,1); + else + { + if(0!=lua_pcall(L,0,1,0)) + lua_pop(L,1); + if(lua_toboolean(L,-1)) + { + lua_pop(L,1); + drawSpellIcons(noxKeyPack); + return; + } + lua_pop(L,1); + }*/ + + if (sub_4160F0(7, *((DWORD*)0x85B3FC)>>1 )==0) + { + myKeySelectedRow++; + if(myKeySelectedRow<5) + { + noxKeyPack->selectedRow=4; + myKeySelectedRow=4; + return; + } + } + else + myKeySelectedRow=0; + noxKeyPack->selectedRow=myKeySelectedRow; + noxKeyPack->keyRowPtr=noxKeyPack->keyRowPtr + 5 * noxKeyPack->selectedRow; + sub_4160D0(7); + wnd_452D80(0x31E,100);//может это звук? 0x31E было + drawSpellIcons(noxKeyPack); + } + int myFixKeyFn(lua_State*L) + { + InjectJumpTo(0x4604F0,&myKeyNextSpell); + InjectJumpTo(0x460540,&myKeyPrevSpell); + InjectJumpTo(0x460590,&myKeyResetSpell); + return 0; + } +} + + + +void keysInit() +{ + ASSIGN(keyNextSpell,0x4604F0); + ASSIGN(keyPrevSpell,0x460540); + ASSIGN(keyResetSpell,0x460590); + ASSIGN(noxKeyPack, *((DWORD*)0x5A7968) ); + ASSIGN(get_57AF20,0x57AF20); + ASSIGN(clientStoreLastButton,0x45DAD0); + ASSIGN(dw_6D4918,0x6D4918); + ASSIGN(dw_6D492C,0x6D492C); + ASSIGN(sub_4160F0,0x4160F0); + ASSIGN(sub_4160D0,0x4160D0); + ASSIGN(wnd_452D80,0x452D80); + ASSIGN(get_57AF20,0x57AF20); + ASSIGN(drawSpellIcons,0x45DDF0); + ASSIGN(keyUpdateRow,0x45E110); + registerclient("keyLoad",&myFixKeyFn); + registerclient("keyRowSet",&keySetRowL); + registerclient("keyRowGet",&keyGetRowL); + registerclient("keyRowSel",&keyRowSelectL); + } \ No newline at end of file diff --git a/libVer.cpp b/libVer.cpp index 019690c..97b4cf2 100644 --- a/libVer.cpp +++ b/libVer.cpp @@ -1,422 +1,422 @@ -#include "stdafx.h" -#include "unit.h" - -#include -#include -#include -#include -#include - -extern void injectCon(); -extern "C" void __cdecl onNetPacket(BYTE *&BufStart,BYTE *E); -extern "C" void __cdecl onNetPacket2(BYTE *&BufStart,BYTE *E, BYTE *MyPlayer, BYTE *MyUc); -extern "C" int __cdecl playerOnTrySpell(bigUnitStruct *Unit,byte *Uc,spellPacket *Pckt); -extern "C" void conSendToServer(const char *Cmd); - -extern void luaAddonsLoad(); - -void* conAddr=NULL; - -bool justDoNoxCmd=false; - -bool conDelayed=true; - -char requirepatch_prevmode[7]; - -namespace -{ - void __declspec(naked) netOnCli() - { - __asm - { - jb b - a: - push 0x4942B5 - retn - b: - push ebp - push ebx - lea eax, [esp+8-4] - push eax - call onNetPacket - add esp, 8 - pop ebp - cmp ebp, ebx - jnb a - push 0x48EAA8 - retn - } - } - - void __declspec(naked) netOnServ() - { - __asm - { - jb b - a: - push 0x51CE4E - retn - b: - mov ecx, [esp+2Ch] - push esi - push edi - push ebp - lea eax, [esp+0Ch-4] - push ecx - push eax - call onNetPacket2 - add esp, 10h - pop esi - cmp esi, [esp+2Ch] - jnb a - push 0x51BBA1 - retn - } - } - - void __declspec(naked) MyOnTryCastSpell() - { - __asm - { - push esi - push edi - push ebp - call playerOnTrySpell - add esp, 0Ch - xor edi, edi - cmp eax, 0 - jnz a - push 0x51C121 - retn - a: - js b - inc edi - b: - push 0x51C19C - retn - } - } - - int delayedConL(lua_State *L) - { - int top; - const char *errorstr; - char* Dest; - - lua_rawgeti(L, 2, 1); - if (lua_pcall(L, 0, 0, 0)) - { - top = lua_gettop(L); - errorstr = (const char *)lua_tolstring(L, top, 0); - Dest = new char[strlen(errorstr)+10]; - strcpy(Dest, "Error: "); - strncat(Dest, errorstr, strlen(errorstr)); - conPrintI(Dest); - } - return 0; - } - - void __declspec(naked) FixMeBack() - { - int data[4]; - int bt[1]; - data[0]=0x40FF43; - data[1]=0x40FEF6; - data[2]=0x40FEEC; - data[3]=0x40FF00; - bt[0]=0x40FF48; - DWORD OldProtect; - VirtualProtect((byte*)bt[0],0x10,PAGE_EXECUTE_READWRITE,&OldProtect); - memcpy((byte*)bt[0],data,0x10); - VirtualProtect((byte*)bt[0],0x10,OldProtect,&OldProtect); - __asm - { - retn; - } - } - - - - void __declspec(naked) InitMe() - { - FixMeBack(); - luaL_openlibs(L); - - // Loading custom lua addons here - luaAddonsLoad(); - - lua_pushcclosure(L, delayedConL, 0); - lua_setfield(L, LUA_REGISTRYINDEX, "delayedCon"); - injectCon(); - - __asm - { - push 0x401C70; - retn; - } - } - -} - -extern void InjectOffs(DWORD Addr,void *Fn); -extern void InjectJumpTo(DWORD Addr,void *Fn); -extern void InjectAddr(DWORD Addr,void *Fn); -extern void InjectData(DWORD offset, byte* buff, size_t size); - - -HRESULT __stdcall CoCreateInstanceNox(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv) -{ - HRESULT res = CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv); - - static bool isWolapiPatched = false; - //static byte wolapiclsid[16] = { 0xF5, 0xBA, 0xD3, 0x4D, 0x79, 0x75, 0xD1, 0x11, 0xB1, 0xC6, 0x00, 0x60, 0x97, 0x17, 0x65, 0x56 }; - if (/*memcmp(wolapiclsid, &rclsid, 16) == 0*/isWolapiPatched == false) - { - HMODULE hProcessModule[100]; - DWORD dwReturn; - DWORD dwModuleNb; - char BaseName[MAX_PATH]; - - EnumProcessModules(GetCurrentProcess(), hProcessModule, sizeof(hProcessModule), &dwReturn); - - dwModuleNb = dwReturn / sizeof(HMODULE); - - for (DWORD i = 0; i < dwModuleNb; i++) - { - GetModuleBaseName(GetCurrentProcess(), hProcessModule[i], BaseName, sizeof(BaseName)); - for (int i = 0; i < strlen(BaseName); i++) - { - char BaseNameC = BaseName[i]; - BaseName[i] = tolower(BaseNameC); - } - if (strcmp(BaseName, "wolapi.dll") == 0) - { - DWORD patchaddr = (DWORD)hProcessModule[i] + 0x116AC; - byte nops[2] = { 0x90, 0x90 }; - InjectData(patchaddr, nops, 2); - isWolapiPatched = true; - break; - } - } - } - - return res; -} - -void initModLib1(HMODULE hModule) -{ - void* MyModule = (void*)hModule; - void* addr = (char*)InitMe + (int)MyModule - (0x36D0FF58 - 0x36900000 + (int)MyModule); - byte *bt=(byte*)(0x40FF54); - DWORD OldProtect; - VirtualProtect(bt,0x4,PAGE_EXECUTE_READWRITE,&OldProtect); - memcpy((byte*)bt,&addr,0x4); - VirtualProtect(bt,0x4,OldProtect,&OldProtect); - InjectJumpTo(0x48EAA2, netOnCli); - InjectJumpTo(0x494296, netOnCli); - InjectJumpTo(0x51BB9B, netOnServ); - InjectJumpTo(0x51CE48, netOnServ); - InjectAddr(0x51CF08, MyOnTryCastSpell); - - void* cciaddr = (void*)CoCreateInstanceNox; - InjectData(0x581448, (byte*)&cciaddr, sizeof(&cciaddr)); -} - -void __cdecl initModLib2() -{ - conAddr = (void*)0x443C86; -} - -extern "C" int conDoCmd(char *Cmd,bool &PrintNil); -int conDoCmd(char *Cmd,bool &PrintNil) -{ - int gf = ~*GameFlags & 1; - int top = lua_gettop(L); - const char* mode; - if(!gf) - mode="server"; - else - mode="client"; - - int topLoad = lua_gettop(L); - - bool repatch_needed = false; - - if (strncmp(requirepatch_prevmode, mode, 7) != 0) - { - repatch_needed = true; - strncpy(requirepatch_prevmode, mode, 7); - } - - if (repatch_needed) - { - lua_getfield(L, LUA_REGISTRYINDEX, "require.lua"); - if (lua_isfunction(L, -1)) - { - lua_getfield(L, LUA_REGISTRYINDEX, mode); - lua_setfenv(L, -2); - int err = lua_pcall(L, 0, 0, 0); - if (err != 0) - { - const char* errorMsg = lua_tostring(L, -1); - MessageBoxA(NULL, errorMsg, "LUA load error! The file won't be loaded!", MB_OK); - return 0; - } - //lua_pushstring(L, "require.lua"); - //lua_pushstring(L, mode); - //lua_settable(L, LUA_REGISTRYINDEX); - } - } - - lua_settop(L, topLoad); - - lua_getfield(L, LUA_REGISTRYINDEX, mode); - - lua_getfield(L, LUA_GLOBALSINDEX, "conInput"); - if ( lua_type(L, -1) == LUA_TFUNCTION ) - { - lua_pushstring(L, Cmd); - int errcode = lua_pcall(L, 1, 1, 0); - if (!errcode) - errcode = lua_tointeger(L, -1); - lua_settop(L, top); - return errcode; - } - int statuscode = luaL_loadstring(L, Cmd); - int errcode = statuscode; - if(statuscode==3) - { - int cmdLength = strlen(Cmd); - bool allMatched = false; - char* cmdPointer; - for(cmdPointer = Cmd; strchr("_ABCDEFGHIJKLMNOPQRSTUVWXUZabcdefghijklmnopqrstuvwxyz1234567890", *cmdPointer); cmdPointer++) - { - if(cmdPointer==(Cmd+cmdLength)) - break; - } - if(cmdPointer==(Cmd+cmdLength)) - { - lua_getfield(L, LUA_GLOBALSINDEX, "tostring"); - lua_getfield(L, top + 1, Cmd); - if(lua_type(L, -1)) - { - if (lua_pcall(L, 1, 1, 0)) - { - errcode = 1; - } - else - { - const char* returnString = lua_tolstring(L, -1, 0); - char Dest[200]; - strcpy(Dest, " = "); - strncat(&Dest[strlen(Dest)], returnString, (199-strlen(Dest))); - Dest[199] = 0; - conPrintI(Dest); - errcode = 0; - } - } - else - PrintNil = true; - } - } - else - { - if(!statuscode) - { - lua_pushvalue(L, top + 1); - lua_setfenv(L, -2); - if(conDelayed) - { - const char* timeoutFunc; - if(!gf) - timeoutFunc="setTimeout"; - else - timeoutFunc="cliSetTimeout"; - lua_getfield(L, LUA_REGISTRYINDEX, timeoutFunc); - lua_getfield(L, LUA_REGISTRYINDEX, "delayedCon"); - lua_pushinteger(L, 0); - lua_createtable(L, 0, 0); - lua_pushvalue(L, -5); - lua_rawseti(L, -2, 1); - errcode = lua_pcall(L, 3, 0, 0); - if(errcode) - { - int newTop = lua_gettop(L); - const char* errorStr = lua_tolstring(L, newTop, 0); - char Dest[200]; - strcpy(Dest, "Adv error: "); - strncat(&Dest[strlen(Dest)], errorStr, (199-strlen(Dest))); - conPrintI(Dest); - } - } - else - { - errcode=lua_pcall(L, 0, 0, 0); - if(errcode) - { - int newTop = lua_gettop(L); - const char* errorStr = lua_tolstring(L, newTop, 0); - char Dest[200]; - strcpy(Dest, "error: "); - strncat(&Dest[strlen(Dest)], errorStr, (199-strlen(Dest))); - conPrintI(Dest); - } - } - } - lua_settop(L, top); - } - return errcode; -} - -void onComCmd2(); - -DWORD __cdecl onConCmd(wchar_t *A,DWORD B) // TODO: TO REIMPLEMENT FROM ASM!!! -{ - int cmdResult = 0; - int result; - char Dest[0xC8]; - - bool printNil=false; - if (justDoNoxCmd) - { - cmdResult = 1; - } - else - { - int length = wcslen(A); - if ( length+1 >= 0xC8 ) - return 0; - wcstombs(Dest, A, 0xC7); - Dest[0xC7] = 0; - if (*GameFlags) // - { - cmdResult = conDoCmd(Dest, printNil); // TODO: Implement conDoCmd - } - else - { - cmdResult = 1; - } - } - if (cmdResult) - { - __asm - { - push B - push A - push onConCmd_GOBACK - sub esp,0x88 - jmp conAddr - onConCmd_GOBACK: - add esp,8 - mov result,eax - } - if(printNil && !result && !justDoNoxCmd) - { - conPrintI(" = nil"); - } - //result = ((int (__cdecl *)(unsigned __int32, unsigned __int32))conAddr)((unsigned __int32)A, B); - } - else - result = 1; - return result; -} +#include "stdafx.h" +#include "unit.h" + +#include +#include +#include +#include +#include + +extern void injectCon(); +extern "C" void __cdecl onNetPacket(BYTE *&BufStart,BYTE *E); +extern "C" void __cdecl onNetPacket2(BYTE *&BufStart,BYTE *E, BYTE *MyPlayer, BYTE *MyUc); +extern "C" int __cdecl playerOnTrySpell(bigUnitStruct *Unit,byte *Uc,spellPacket *Pckt); +extern "C" void conSendToServer(const char *Cmd); + +extern void luaAddonsLoad(); + +void* conAddr=NULL; + +bool justDoNoxCmd=false; + +bool conDelayed=true; + +char requirepatch_prevmode[7]; + +namespace +{ + void __declspec(naked) netOnCli() + { + __asm + { + jb b + a: + push 0x4942B5 + retn + b: + push ebp + push ebx + lea eax, [esp+8-4] + push eax + call onNetPacket + add esp, 8 + pop ebp + cmp ebp, ebx + jnb a + push 0x48EAA8 + retn + } + } + + void __declspec(naked) netOnServ() + { + __asm + { + jb b + a: + push 0x51CE4E + retn + b: + mov ecx, [esp+2Ch] + push esi + push edi + push ebp + lea eax, [esp+0Ch-4] + push ecx + push eax + call onNetPacket2 + add esp, 10h + pop esi + cmp esi, [esp+2Ch] + jnb a + push 0x51BBA1 + retn + } + } + + void __declspec(naked) MyOnTryCastSpell() + { + __asm + { + push esi + push edi + push ebp + call playerOnTrySpell + add esp, 0Ch + xor edi, edi + cmp eax, 0 + jnz a + push 0x51C121 + retn + a: + js b + inc edi + b: + push 0x51C19C + retn + } + } + + int delayedConL(lua_State *L) + { + int top; + const char *errorstr; + char* Dest; + + lua_rawgeti(L, 2, 1); + if (lua_pcall(L, 0, 0, 0)) + { + top = lua_gettop(L); + errorstr = (const char *)lua_tolstring(L, top, 0); + Dest = new char[strlen(errorstr)+10]; + strcpy(Dest, "Error: "); + strncat(Dest, errorstr, strlen(errorstr)); + conPrintI(Dest); + } + return 0; + } + + void __declspec(naked) FixMeBack() + { + int data[4]; + int bt[1]; + data[0]=0x40FF43; + data[1]=0x40FEF6; + data[2]=0x40FEEC; + data[3]=0x40FF00; + bt[0]=0x40FF48; + DWORD OldProtect; + VirtualProtect((byte*)bt[0],0x10,PAGE_EXECUTE_READWRITE,&OldProtect); + memcpy((byte*)bt[0],data,0x10); + VirtualProtect((byte*)bt[0],0x10,OldProtect,&OldProtect); + __asm + { + retn; + } + } + + + + void __declspec(naked) InitMe() + { + FixMeBack(); + luaL_openlibs(L); + + // Loading custom lua addons here + luaAddonsLoad(); + + lua_pushcclosure(L, delayedConL, 0); + lua_setfield(L, LUA_REGISTRYINDEX, "delayedCon"); + injectCon(); + + __asm + { + push 0x401C70; + retn; + } + } + +} + +extern void InjectOffs(DWORD Addr,void *Fn); +extern void InjectJumpTo(DWORD Addr,void *Fn); +extern void InjectAddr(DWORD Addr,void *Fn); +extern void InjectData(DWORD offset, byte* buff, size_t size); + + +HRESULT __stdcall CoCreateInstanceNox(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv) +{ + HRESULT res = CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv); + + static bool isWolapiPatched = false; + //static byte wolapiclsid[16] = { 0xF5, 0xBA, 0xD3, 0x4D, 0x79, 0x75, 0xD1, 0x11, 0xB1, 0xC6, 0x00, 0x60, 0x97, 0x17, 0x65, 0x56 }; + if (/*memcmp(wolapiclsid, &rclsid, 16) == 0*/isWolapiPatched == false) + { + HMODULE hProcessModule[100]; + DWORD dwReturn; + DWORD dwModuleNb; + char BaseName[MAX_PATH]; + + EnumProcessModules(GetCurrentProcess(), hProcessModule, sizeof(hProcessModule), &dwReturn); + + dwModuleNb = dwReturn / sizeof(HMODULE); + + for (DWORD i = 0; i < dwModuleNb; i++) + { + GetModuleBaseName(GetCurrentProcess(), hProcessModule[i], BaseName, sizeof(BaseName)); + for (int i = 0; i < strlen(BaseName); i++) + { + char BaseNameC = BaseName[i]; + BaseName[i] = tolower(BaseNameC); + } + if (strcmp(BaseName, "wolapi.dll") == 0) + { + DWORD patchaddr = (DWORD)hProcessModule[i] + 0x116AC; + byte nops[2] = { 0x90, 0x90 }; + InjectData(patchaddr, nops, 2); + isWolapiPatched = true; + break; + } + } + } + + return res; +} + +void initModLib1(HMODULE hModule) +{ + void* MyModule = (void*)hModule; + void* addr = (char*)InitMe + (int)MyModule - (0x36D0FF58 - 0x36900000 + (int)MyModule); + byte *bt=(byte*)(0x40FF54); + DWORD OldProtect; + VirtualProtect(bt,0x4,PAGE_EXECUTE_READWRITE,&OldProtect); + memcpy((byte*)bt,&addr,0x4); + VirtualProtect(bt,0x4,OldProtect,&OldProtect); + InjectJumpTo(0x48EAA2, netOnCli); + InjectJumpTo(0x494296, netOnCli); + InjectJumpTo(0x51BB9B, netOnServ); + InjectJumpTo(0x51CE48, netOnServ); + InjectAddr(0x51CF08, MyOnTryCastSpell); + + void* cciaddr = (void*)CoCreateInstanceNox; + InjectData(0x581448, (byte*)&cciaddr, sizeof(&cciaddr)); +} + +void __cdecl initModLib2() +{ + conAddr = (void*)0x443C86; +} + +extern "C" int conDoCmd(char *Cmd,bool &PrintNil); +int conDoCmd(char *Cmd,bool &PrintNil) +{ + int gf = ~*GameFlags & 1; + int top = lua_gettop(L); + const char* mode; + if(!gf) + mode="server"; + else + mode="client"; + + int topLoad = lua_gettop(L); + + bool repatch_needed = false; + + if (strncmp(requirepatch_prevmode, mode, 7) != 0) + { + repatch_needed = true; + strncpy(requirepatch_prevmode, mode, 7); + } + + if (repatch_needed) + { + lua_getfield(L, LUA_REGISTRYINDEX, "require.lua"); + if (lua_isfunction(L, -1)) + { + lua_getfield(L, LUA_REGISTRYINDEX, mode); + lua_setfenv(L, -2); + int err = lua_pcall(L, 0, 0, 0); + if (err != 0) + { + const char* errorMsg = lua_tostring(L, -1); + MessageBoxA(NULL, errorMsg, "LUA load error! The file won't be loaded!", MB_OK); + return 0; + } + //lua_pushstring(L, "require.lua"); + //lua_pushstring(L, mode); + //lua_settable(L, LUA_REGISTRYINDEX); + } + } + + lua_settop(L, topLoad); + + lua_getfield(L, LUA_REGISTRYINDEX, mode); + + lua_getfield(L, LUA_GLOBALSINDEX, "conInput"); + if ( lua_type(L, -1) == LUA_TFUNCTION ) + { + lua_pushstring(L, Cmd); + int errcode = lua_pcall(L, 1, 1, 0); + if (!errcode) + errcode = lua_tointeger(L, -1); + lua_settop(L, top); + return errcode; + } + int statuscode = luaL_loadstring(L, Cmd); + int errcode = statuscode; + if(statuscode==3) + { + int cmdLength = strlen(Cmd); + bool allMatched = false; + char* cmdPointer; + for(cmdPointer = Cmd; strchr("_ABCDEFGHIJKLMNOPQRSTUVWXUZabcdefghijklmnopqrstuvwxyz1234567890", *cmdPointer); cmdPointer++) + { + if(cmdPointer==(Cmd+cmdLength)) + break; + } + if(cmdPointer==(Cmd+cmdLength)) + { + lua_getfield(L, LUA_GLOBALSINDEX, "tostring"); + lua_getfield(L, top + 1, Cmd); + if(lua_type(L, -1)) + { + if (lua_pcall(L, 1, 1, 0)) + { + errcode = 1; + } + else + { + const char* returnString = lua_tolstring(L, -1, 0); + char Dest[200]; + strcpy(Dest, " = "); + strncat(&Dest[strlen(Dest)], returnString, (199-strlen(Dest))); + Dest[199] = 0; + conPrintI(Dest); + errcode = 0; + } + } + else + PrintNil = true; + } + } + else + { + if(!statuscode) + { + lua_pushvalue(L, top + 1); + lua_setfenv(L, -2); + if(conDelayed) + { + const char* timeoutFunc; + if(!gf) + timeoutFunc="setTimeout"; + else + timeoutFunc="cliSetTimeout"; + lua_getfield(L, LUA_REGISTRYINDEX, timeoutFunc); + lua_getfield(L, LUA_REGISTRYINDEX, "delayedCon"); + lua_pushinteger(L, 0); + lua_createtable(L, 0, 0); + lua_pushvalue(L, -5); + lua_rawseti(L, -2, 1); + errcode = lua_pcall(L, 3, 0, 0); + if(errcode) + { + int newTop = lua_gettop(L); + const char* errorStr = lua_tolstring(L, newTop, 0); + char Dest[200]; + strcpy(Dest, "Adv error: "); + strncat(&Dest[strlen(Dest)], errorStr, (199-strlen(Dest))); + conPrintI(Dest); + } + } + else + { + errcode=lua_pcall(L, 0, 0, 0); + if(errcode) + { + int newTop = lua_gettop(L); + const char* errorStr = lua_tolstring(L, newTop, 0); + char Dest[200]; + strcpy(Dest, "error: "); + strncat(&Dest[strlen(Dest)], errorStr, (199-strlen(Dest))); + conPrintI(Dest); + } + } + } + lua_settop(L, top); + } + return errcode; +} + +void onComCmd2(); + +DWORD __cdecl onConCmd(wchar_t *A,DWORD B) // TODO: TO REIMPLEMENT FROM ASM!!! +{ + int cmdResult = 0; + int result; + char Dest[0xC8]; + + bool printNil=false; + if (justDoNoxCmd) + { + cmdResult = 1; + } + else + { + int length = wcslen(A); + if ( length+1 >= 0xC8 ) + return 0; + wcstombs(Dest, A, 0xC7); + Dest[0xC7] = 0; + if (*GameFlags) // Закладка выпилена + { + cmdResult = conDoCmd(Dest, printNil); // TODO: Implement conDoCmd + } + else + { + cmdResult = 1; + } + } + if (cmdResult) + { + __asm + { + push B + push A + push onConCmd_GOBACK + sub esp,0x88 + jmp conAddr + onConCmd_GOBACK: + add esp,8 + mov result,eax + } + if(printNil && !result && !justDoNoxCmd) + { + conPrintI(" = nil"); + } + //result = ((int (__cdecl *)(unsigned __int32, unsigned __int32))conAddr)((unsigned __int32)A, B); + } + else + result = 1; + return result; +} diff --git a/lua/useful_objects_for_tower_defense.txt b/lua/useful_objects_for_tower_defense.txt new file mode 100644 index 0000000..82dd6cd --- /dev/null +++ b/lua/useful_objects_for_tower_defense.txt @@ -0,0 +1,39 @@ +== +карта war03b +или wiz05a +== +==желательно +monument1 +fairyjar +immobilefairyjar +outdoortraderarmorrack1 +vandegrafsmall +teepeeshelvesfull1 +wizardworkstation2c +ogrepostskull1 +== +DunMirMilestone - круглая тумба + +statuevictory2s - статуя с мечем разных цветов +statuevictory3s +statuevictory4s +windmill1 +statuevase4s -- статуя с вазой + +sackchestlarge2 +gear2 - ремень+колесо варианты 1-4 с разными углами + +torchpole -- палка с факелом + +cinderbin1 - жаровня большая (ящик углей) +bellows1 - меха + +rotatingspikes +- нежелательно +column7 - колонна тонкая но высокая, с тенью +dunmirflamebasinlit - тумба с огнем +dunmiraltar1 - просто тумба +wishingwell +anvil1 +cauldronanimated +cr 'traderquiverrack' diff --git "a/lua/\320\277\320\276\320\273\320\265\320\267\320\275\321\213\320\265 \320\277\321\200\320\265\320\264\320\274\320\265\321\202\321\213 \320\264\320\273\321\217 \320\264\320\265\321\204\320\265\320\275\321\201\320\260.txt" "b/lua/\320\277\320\276\320\273\320\265\320\267\320\275\321\213\320\265 \320\277\321\200\320\265\320\264\320\274\320\265\321\202\321\213 \320\264\320\273\321\217 \320\264\320\265\321\204\320\265\320\275\321\201\320\260.txt" deleted file mode 100644 index 8bc5a1a..0000000 --- "a/lua/\320\277\320\276\320\273\320\265\320\267\320\275\321\213\320\265 \320\277\321\200\320\265\320\264\320\274\320\265\321\202\321\213 \320\264\320\273\321\217 \320\264\320\265\321\204\320\265\320\275\321\201\320\260.txt" +++ /dev/null @@ -1,39 +0,0 @@ -== - war03b - wiz05a -== -== -monument1 -fairyjar -immobilefairyjar -outdoortraderarmorrack1 -vandegrafsmall -teepeeshelvesfull1 -wizardworkstation2c -ogrepostskull1 -== -DunMirMilestone - - -statuevictory2s - -statuevictory3s -statuevictory4s -windmill1 -statuevase4s -- - -sackchestlarge2 -gear2 - + 1-4 - -torchpole -- - -cinderbin1 - ( ) -bellows1 - - -rotatingspikes -- -column7 - , -dunmirflamebasinlit - -dunmiraltar1 - -wishingwell -anvil1 -cauldronanimated -cr 'traderquiverrack' diff --git a/map.cpp b/map.cpp index e6c8921..d975524 100644 --- a/map.cpp +++ b/map.cpp @@ -1,505 +1,505 @@ -#include "stdafx.h" -#include "unit.h" - -struct wallBreakable_s -{ - wallBreakable_s *next; - wallRec *wall; -}; - -extern void *(__cdecl *noxAlloc)(int Size); -int getTileByName(const char*); -wallRec *(__cdecl *noxGetWallAtPt)(int x,int y); -int (__cdecl *noxWallTileByName)(const char *Name); -wallRec *(__cdecl *noxWallCreateAt)(int x,int y); -void (__cdecl *noxMapDelWallAtPt)(int x,int y); -int (__cdecl *mapTraceRay)(noxRect *Ray,int arg4,int arg8,int Flags); -// arg4,arg8 - ret structs [0],[4] - some vals -void (__cdecl *netWallCreate)(void *PrevCmd,wallRec *Wall,int newWall,int tileName,int facing, int vari); -int (__cdecl *noxMapGetMaxVari) (int,int,int); - -void (__cdecl *noxWallSecretBlock_410760) (void*); -//newWall=1 , 0 - - -DWORD *wallNextBreakableId; -wallBreakable_s const *(*noxGetFirstBreakableList)();//0x00410870 -void (__cdecl *noxWallBreackableListAdd)(wallRec * Wall);/// -void (__cdecl *noxWallBreackableListRemove)(void const * WallList);/// - , - -extern void printI(const char *S); -extern void conPrintI(const char *S); -char *(__cdecl *mapGetName)(); - -DWORD (__cdecl *scriptPopValue)(); -void (__cdecl *scriptPushValue)(DWORD X); -char **scriptKey; // -DWORD (__cdecl *mapWaypoint)(); -void (__cdecl *mapInitialize)(); - - -bigUnitStruct **scriptCallerUnit; -bigUnitStruct **scriptTriggerUnit; - -extern void mapUnloadFilesystem(); -extern void mapUnloadUtil(); -extern void mapLoadFilesystem(const char *); -extern void mapLoadSpells(); - -int *wallNextSecretId=(int*)0x68957C; - - -namespace { - DWORD myWaypoint() - { - DWORD Idx=scriptPopValue(); - char *S=scriptKey[Idx]; - if (*S!='>') - { - scriptPushValue(Idx); - return mapWaypoint(); - } - S++; - int T=lua_gettop(L); - if (*scriptCallerUnit) - { - void *Parent=unitDamageFindParent(*scriptCallerUnit); - if (Parent) - lua_pushlightuserdata(L,Parent); - else - lua_pushnil(L); - lua_pushlightuserdata(L,*scriptCallerUnit); - - - } - else - { - lua_pushnil(L); - lua_pushnil(L); - } - if (*scriptTriggerUnit) - lua_pushlightuserdata(L,*scriptTriggerUnit); - else - lua_pushnil(L); - - lua_getfield(L,LUA_REGISTRYINDEX,"server");// - lua_pushstring(L,S); - lua_gettable(L,-2); - lua_remove(L,-2); - if (lua_type(L,-1)==LUA_TFUNCTION) - { - lua_getfield(L,LUA_REGISTRYINDEX,"server");// - lua_setfenv(L,-2); - - lua_pushvalue(L,-4);//parent - lua_pushvalue(L,-4);//caller - lua_pushvalue(L,-4);//trigger - if (0!=lua_pcall(L,3,0,0)) - { - conPrintI(lua_tostring(L,-1)); - } - } - else - { - lua_pop(L,1); - lua_setglobal(L,"scriptTrigger"); - lua_setglobal(L,"scriptCaller"); - lua_setglobal(L,"scriptParent"); - bool Ok=false; - Ok= ( 0==luaL_loadstring(L,S) ); - if (Ok) - { - lua_getfield(L,LUA_REGISTRYINDEX,"server");// - lua_setfenv(L,-2); - } - - if ( (!Ok) || 0!=lua_pcall(L,0,0,0) ) - { - conPrintI(lua_tostring(L,-1)); - conPrintI(S); - } - } - lua_settop(L,T); - scriptPushValue(Idx); - return 1; - - } - int mapGetNameL(lua_State*L) - { - lua_pushstring(L,mapGetName()); - return 1; - } - void wallSecretListUpdate(wallRec *P) - { - wallSecret_s *WS=(wallSecret_s*) noxAlloc(0x20); - P->doorPtr=(int)WS; - WS->X=P->posX; - WS->Y=P->posY; - WS->wallRec_Ptr=(int)P; - WS->bitAuto=1; - WS->timeToClose=3; - WS->timeToOpen=6; - P->wallId=(*wallNextSecretId)++; - noxWallSecretBlock_410760((void*)WS); - } - - void wallBreakListUpdate(wallRec *P) - { - bool Add=(P->wallFlags&8); - wallBreakable_s const *W=noxGetFirstBreakableList(); - for( ;W!=NULL;W=W->next) - { - if(W->wall==P) - { - if (Add) - { -// conPrintI("wall already in breaklist"); - return;/// - } - else - { -// conPrintI("wall removed from breaklist"); - noxWallBreackableListRemove(W); - return; - } - } - } - if (!Add) - { -// conPrintI("wall not in breaklist"); - return; // - } -// conPrintI("wall appended to breaklist"); - noxWallBreackableListAdd(P); - } - - int getTileByName(const char* TileName) - { - char *mapFirstTile=0; - ASSIGN(mapFirstTile,0x865C20); - int i=0; - while(i<74) - { - char *TileNameN = (i++ * 0x302C) + mapFirstTile; - if (strcmpi(TileName,TileNameN)==0) - return i-1; - } - return -1; - } - - int mapInfoL(lua_State *L) - { - if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - wallRec *P=(wallRec*)lua_touserdata(L,1); - lua_newtable(L); - lua_pushinteger(L,P->tileName); - lua_setfield(L,-2,"tile"); - lua_pushinteger(L,P->posX); - lua_setfield(L,-2,"x"); - lua_pushinteger(L,P->posY); - lua_setfield(L,-2,"y"); - lua_pushinteger(L,P->Dir); - lua_setfield(L,-2,"dir"); - lua_pushinteger(L,P->wallFlags); - lua_setfield(L,-2,"flags"); - lua_pushinteger(L,P->variation); - lua_setfield(L,-2,"vari"); - lua_pushinteger(L,P->unk3); - lua_setfield(L,-2,"unk3"); - lua_pushinteger(L,P->HP); - lua_setfield(L,-2,"hp"); - return 1; - } - - int getWallAtPtL(lua_State *L) - { - if(lua_type(L,1)==LUA_TTABLE) - { - lua_rawgeti(L,1,1); - lua_rawgeti(L,1,2); - lua_remove(L,1); - lua_insert(L,1); - lua_insert(L,1); - } - if ((lua_type(L,1)!=LUA_TNUMBER)||(lua_type(L,2)!=LUA_TNUMBER)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - int x=lua_tointeger(L,1),y=lua_tointeger(L,2); - x=(x-x%23)/23;y=(y-y%23)/23; - wallRec *P=noxGetWallAtPt(x,y); - if(P==NULL) - { - lua_pushnil(L); - return 1; - } else - { - lua_pushlightuserdata(L,P); - return 1; - } - } - - int setWallAtPtL(lua_State *L) - { - int tileName; - if(lua_type(L,1)==LUA_TNUMBER) - tileName=lua_tointeger(L,1); - else if(lua_type(L,1)==LUA_TSTRING) - tileName=getTileByName(lua_tostring(L,1)); - else - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - if ((lua_type(L,2)!=LUA_TNUMBER)||(lua_type(L,3)!=LUA_TNUMBER)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - int x=lua_tointeger(L,2),y=lua_tointeger(L,3); - x=(x-x%23)/23;y=(y-y%23)/23; - - //lua_settop(L,6);///tile,x,y,facing,flags,vari,[3],[7] - if ((lua_tointeger(L,1)<0) || (tileName<0)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - wallRec *P=noxGetWallAtPt(x,y); - if(P==NULL) - { -// lua_pushstring(L,"there is no wall there!"); -// lua_error_(L); - P=noxWallCreateAt(x,y); - } - P->Dir =lua_tointeger(L,4); - P->tileName=tileName; - P->variation=lua_tointeger(L,6); - P->unk3=lua_tointeger(L,7); - P->wallFlags=lua_tointeger(L,5); - P->HP=lua_tointeger(L,8); - if(P->HP==0) - P->HP=255; - if (P->wallFlags&8) - { - P->wallId=(*wallNextBreakableId)++; - } - if (P->wallFlags & 4) - wallSecretListUpdate(P); - netWallCreate(NULL,P,1,P->tileName,P->Dir,P->variation); - BYTE Buf[256],*Out=Buf; - int Size=sizeof(*P)+2; - netUniPacket(upWallChanged,Out,Size); - memcpy(Out,P,sizeof(*P)); - netSendAll(Buf,Size); - if (P==NULL) - lua_pushnil(L); - else - lua_pushlightuserdata(L,P); - return 1; - } - int mapDelWallAtPtL(lua_State *L) - { - if(lua_type(L,1)==LUA_TTABLE) - { - lua_rawgeti(L,1,1); - lua_rawgeti(L,1,2); - lua_remove(L,1); - lua_insert(L,1); - lua_insert(L,1); - } - if ((lua_type(L,1)!=LUA_TNUMBER)||(lua_type(L,2)!=LUA_TNUMBER)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - int x=lua_tointeger(L,1),y=lua_tointeger(L,2); - x=(x-x%23)/23;y=(y-y%23)/23; - noxMapDelWallAtPt(x,y); - //TODO: - - return 1; - } - /* - x1,y1,x2,y2,flags->ret,x,y - */ - int mapTraceRayL(lua_State *L) - { - int i=1; - if ( - (lua_type(L,i++)!=LUA_TNUMBER) || - (lua_type(L,i++)!=LUA_TNUMBER) || - (lua_type(L,i++)!=LUA_TNUMBER) || - (lua_type(L,i++)!=LUA_TNUMBER) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - i=1; - noxRect T; - T.X1=lua_tonumber(L,i++); - T.Y1=lua_tonumber(L,i++); - T.X2=lua_tonumber(L,i++); - T.Y2=lua_tonumber(L,i++); - int Flags=lua_tointeger(L,i++); - struct {int A;int B;} Ret4; - i=mapTraceRay(&T,(int)&Ret4,0,Flags); - lua_pushboolean(L,i); - lua_pushlightuserdata(L,(void*)Ret4.A); - lua_pushlightuserdata(L,(void*)Ret4.B); - return 3; - } - int mapGetTileByNameL(lua_State *L) - { - if ((lua_type(L,1)!=LUA_TSTRING) || (lua_gettop(L)!=1)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - int Tile = getTileByName(lua_tostring(L,1)); - if (Tile<0) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - else - { - lua_pushinteger(L,Tile); - } - return 1; - } - - int mapGetNameByTileL(lua_State *L) - { - if ((lua_type(L,1)!=LUA_TNUMBER) || (lua_gettop(L)!=1) || (lua_tointeger(L,1)>80)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - char *mapFirstTile=0; - ASSIGN(mapFirstTile,0x00865C20); - char* Tile = (lua_tointeger(L,1) * 0x302C) + mapFirstTile; - lua_pushstring(L,Tile); - return 1; - } - - int mapMaxVariL(lua_State *L) - { - if (lua_type(L,1)!=LUA_TNUMBER || lua_type(L,2)!=LUA_TNUMBER) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - int tile=lua_tointeger(L,1); - int dir=lua_tointeger(L,2); - if (tile<0 || dir<0) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - lua_pushinteger(L,noxMapGetMaxVari(tile,dir,0)); - return 1; - } - - DWORD *mapDoInitialize; - bool firstRun=true; -} -void __cdecl onLoadLevel() /// (???) -{ - /// ? - if(0==*mapDoInitialize) - return; - if (firstRun) - firstRun=false; - else - { - mapUnloadUtil(); - mapUnloadFilesystem(); - } - - mapInitialize(); - int Top=lua_gettop(L); - do - { - getServerVar("onMapLoad"); - if (!lua_isfunction(L,-1)) - break; - lua_pcall(L,0,0,0); - lua_settop(L,Top); - } - while(0); - mapLoadFilesystem(mapGetName()); - mapLoadSpells(); -} -extern DWORD *GameFlags; -void netOnWallChanged(wallRec *newData) -{ - char Buf[280]; - - int x=newData->posX,y=newData->posY; - sprintf(Buf,"wall at %d %d",x,y); - conPrintI(Buf); - - wallRec *P=noxGetWallAtPt(x,y); - if (P==NULL) - { - P=noxWallCreateAt(x,y); - if (newData->wallFlags & 4) - wallSecretListUpdate(P); - } - if (P==NULL) - return; - P->wallId=newData->wallId; - P->wallFlags=newData->wallFlags; - wallBreakListUpdate(P); -} -extern void InjectOffs(DWORD Addr,void *Fn); -extern void InjectAddr(DWORD Addr,void *Fn); -void mapInit() -{ - ASSIGN(scriptCallerUnit,0x00979720); - ASSIGN(scriptTriggerUnit,0x00979724); - - ASSIGN(mapInitialize,0x004FC590); - ASSIGN(mapDoInitialize,0x00753908); - InjectOffs(0x004D2D31+1,onLoadLevel); - - ASSIGN(scriptPopValue,0x00507250); - ASSIGN(scriptPushValue,0x00507230); - ASSIGN(scriptKey,0x0097BB40); - ASSIGN(mapWaypoint,0x00514800); - InjectAddr(0x005C3244,myWaypoint); - - ASSIGN(noxGetWallAtPt,0x410580); - ASSIGN(noxWallCreateAt,0x410250); - ASSIGN(noxWallTileByName,0x410D60); - ASSIGN(noxMapDelWallAtPt,0x410430); - ASSIGN(mapTraceRay,0x535250); - ASSIGN(netWallCreate,0x4FFE80); - ASSIGN(mapGetName,0x409B40); - ASSIGN(noxMapGetMaxVari,0x410DD0); - - ASSIGN(noxWallBreackableListAdd,0x00410840); - ASSIGN(noxWallBreackableListRemove,0x00410890); - ASSIGN(noxGetFirstBreakableList,0x00410870); - - ASSIGN(noxWallSecretBlock_410760,0x410760); - - ASSIGN(wallNextBreakableId,0x00689574); - - registerserver("mapGet",&getWallAtPtL); - registerserver("mapInfo",&mapInfoL); - registerserver("mapSet",&setWallAtPtL); - registerserver("mapDel",&mapDelWallAtPtL); - registerserver("mapTraceRay",&mapTraceRayL); - registerserver("mapTileByName",&mapGetTileByNameL); - - registerclient("mapMaxVari",&mapMaxVariL); - registerclient("mapNameByTile",&mapGetNameByTileL); - registerclient("mapGetName",&mapGetNameL); -} - +#include "stdafx.h" +#include "unit.h" + +struct wallBreakable_s +{ + wallBreakable_s *next; + wallRec *wall; +}; + +extern void *(__cdecl *noxAlloc)(int Size); +int getTileByName(const char*); +wallRec *(__cdecl *noxGetWallAtPt)(int x,int y); +int (__cdecl *noxWallTileByName)(const char *Name); +wallRec *(__cdecl *noxWallCreateAt)(int x,int y); +void (__cdecl *noxMapDelWallAtPt)(int x,int y); +int (__cdecl *mapTraceRay)(noxRect *Ray,int arg4,int arg8,int Flags); +// arg4,arg8 - ret structs [0],[4] - some vals +void (__cdecl *netWallCreate)(void *PrevCmd,wallRec *Wall,int newWall,int tileName,int facing, int vari); +int (__cdecl *noxMapGetMaxVari) (int,int,int); + +void (__cdecl *noxWallSecretBlock_410760) (void*); +//newWall=1 если новая стена, 0 - если модифицирована старая + +DWORD *wallNextBreakableId; +wallBreakable_s const *(*noxGetFirstBreakableList)();//0x00410870 +void (__cdecl *noxWallBreackableListAdd)(wallRec * Wall);/// Добавляем в список разрушимых стен +void (__cdecl *noxWallBreackableListRemove)(void const * WallList);/// Аргумент - блок, Удаляем из списка + +extern void printI(const char *S); +extern void conPrintI(const char *S); +char *(__cdecl *mapGetName)(); + +DWORD (__cdecl *scriptPopValue)(); +void (__cdecl *scriptPushValue)(DWORD X); +char **scriptKey; // все строчки лежат там +DWORD (__cdecl *mapWaypoint)(); +void (__cdecl *mapInitialize)(); + + +bigUnitStruct **scriptCallerUnit; +bigUnitStruct **scriptTriggerUnit; + +extern void mapUnloadFilesystem(); +extern void mapUnloadUtil(); +extern void mapLoadFilesystem(const char *); +extern void mapLoadSpells(); + +int *wallNextSecretId=(int*)0x68957C; + + +namespace { + DWORD myWaypoint() + { + DWORD Idx=scriptPopValue(); + char *S=scriptKey[Idx]; + if (*S!='>') + { + scriptPushValue(Idx); + return mapWaypoint(); + } + S++; + int T=lua_gettop(L); + if (*scriptCallerUnit) + { + void *Parent=unitDamageFindParent(*scriptCallerUnit); + if (Parent) + lua_pushlightuserdata(L,Parent); + else + lua_pushnil(L); + lua_pushlightuserdata(L,*scriptCallerUnit); + + + } + else + { + lua_pushnil(L); + lua_pushnil(L); + } + if (*scriptTriggerUnit) + lua_pushlightuserdata(L,*scriptTriggerUnit); + else + lua_pushnil(L); + + lua_getfield(L,LUA_REGISTRYINDEX,"server");// смена контекста + lua_pushstring(L,S); + lua_gettable(L,-2); + lua_remove(L,-2); + if (lua_type(L,-1)==LUA_TFUNCTION) + { + lua_getfield(L,LUA_REGISTRYINDEX,"server");// смена контекста + lua_setfenv(L,-2); + + lua_pushvalue(L,-4);//parent + lua_pushvalue(L,-4);//caller + lua_pushvalue(L,-4);//trigger + if (0!=lua_pcall(L,3,0,0)) + { + conPrintI(lua_tostring(L,-1)); + } + } + else + { + lua_pop(L,1); + lua_setglobal(L,"scriptTrigger"); + lua_setglobal(L,"scriptCaller"); + lua_setglobal(L,"scriptParent"); + bool Ok=false; + Ok= ( 0==luaL_loadstring(L,S) ); + if (Ok) + { + lua_getfield(L,LUA_REGISTRYINDEX,"server");// смена контекста + lua_setfenv(L,-2); + } + + if ( (!Ok) || 0!=lua_pcall(L,0,0,0) ) + { + conPrintI(lua_tostring(L,-1)); + conPrintI(S); + } + } + lua_settop(L,T); + scriptPushValue(Idx); + return 1; + + } + int mapGetNameL(lua_State*L) + { + lua_pushstring(L,mapGetName()); + return 1; + } + void wallSecretListUpdate(wallRec *P) + { + wallSecret_s *WS=(wallSecret_s*) noxAlloc(0x20); + P->doorPtr=(int)WS; + WS->X=P->posX; + WS->Y=P->posY; + WS->wallRec_Ptr=(int)P; + WS->bitAuto=1; + WS->timeToClose=3; + WS->timeToOpen=6; + P->wallId=(*wallNextSecretId)++; + noxWallSecretBlock_410760((void*)WS); + } + + void wallBreakListUpdate(wallRec *P) + { + bool Add=(P->wallFlags&8); + wallBreakable_s const *W=noxGetFirstBreakableList(); + for( ;W!=NULL;W=W->next) + { + if(W->wall==P) + { + if (Add) + { +// conPrintI("wall already in breaklist"); + return;/// Уже есть + } + else + { +// conPrintI("wall removed from breaklist"); + noxWallBreackableListRemove(W); + return; + } + } + } + if (!Add) + { +// conPrintI("wall not in breaklist"); + return; // И так нету + } +// conPrintI("wall appended to breaklist"); + noxWallBreackableListAdd(P); + } + + int getTileByName(const char* TileName) + { + char *mapFirstTile=0; + ASSIGN(mapFirstTile,0x865C20); + int i=0; + while(i<74) + { + char *TileNameN = (i++ * 0x302C) + mapFirstTile; + if (strcmpi(TileName,TileNameN)==0) + return i-1; + } + return -1; + } + + int mapInfoL(lua_State *L) + { + if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + wallRec *P=(wallRec*)lua_touserdata(L,1); + lua_newtable(L); + lua_pushinteger(L,P->tileName); + lua_setfield(L,-2,"tile"); + lua_pushinteger(L,P->posX); + lua_setfield(L,-2,"x"); + lua_pushinteger(L,P->posY); + lua_setfield(L,-2,"y"); + lua_pushinteger(L,P->Dir); + lua_setfield(L,-2,"dir"); + lua_pushinteger(L,P->wallFlags); + lua_setfield(L,-2,"flags"); + lua_pushinteger(L,P->variation); + lua_setfield(L,-2,"vari"); + lua_pushinteger(L,P->unk3); + lua_setfield(L,-2,"unk3"); + lua_pushinteger(L,P->HP); + lua_setfield(L,-2,"hp"); + return 1; + } + + int getWallAtPtL(lua_State *L) + { + if(lua_type(L,1)==LUA_TTABLE) + { + lua_rawgeti(L,1,1); + lua_rawgeti(L,1,2); + lua_remove(L,1); + lua_insert(L,1); + lua_insert(L,1); + } + if ((lua_type(L,1)!=LUA_TNUMBER)||(lua_type(L,2)!=LUA_TNUMBER)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + int x=lua_tointeger(L,1),y=lua_tointeger(L,2); + x=(x-x%23)/23;y=(y-y%23)/23; + wallRec *P=noxGetWallAtPt(x,y); + if(P==NULL) + { + lua_pushnil(L); + return 1; + } else + { + lua_pushlightuserdata(L,P); + return 1; + } + } + + int setWallAtPtL(lua_State *L) + { + int tileName; + if(lua_type(L,1)==LUA_TNUMBER) + tileName=lua_tointeger(L,1); + else if(lua_type(L,1)==LUA_TSTRING) + tileName=getTileByName(lua_tostring(L,1)); + else + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + if ((lua_type(L,2)!=LUA_TNUMBER)||(lua_type(L,3)!=LUA_TNUMBER)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + int x=lua_tointeger(L,2),y=lua_tointeger(L,3); + x=(x-x%23)/23;y=(y-y%23)/23; + + //lua_settop(L,6);///tile,x,y,facing,flags,vari,[3],[7] + if ((lua_tointeger(L,1)<0) || (tileName<0)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + wallRec *P=noxGetWallAtPt(x,y); + if(P==NULL) + { +// lua_pushstring(L,"there is no wall there!"); +// lua_error_(L); + P=noxWallCreateAt(x,y); + } + P->Dir =lua_tointeger(L,4); + P->tileName=tileName; + P->variation=lua_tointeger(L,6); + P->unk3=lua_tointeger(L,7); + P->wallFlags=lua_tointeger(L,5); + P->HP=lua_tointeger(L,8); + if(P->HP==0) + P->HP=255; + if (P->wallFlags&8) + { + P->wallId=(*wallNextBreakableId)++; + } + if (P->wallFlags & 4) + wallSecretListUpdate(P); + netWallCreate(NULL,P,1,P->tileName,P->Dir,P->variation); + BYTE Buf[256],*Out=Buf; + int Size=sizeof(*P)+2; + netUniPacket(upWallChanged,Out,Size); + memcpy(Out,P,sizeof(*P)); + netSendAll(Buf,Size); + if (P==NULL) + lua_pushnil(L); + else + lua_pushlightuserdata(L,P); + return 1; + } + int mapDelWallAtPtL(lua_State *L) + { + if(lua_type(L,1)==LUA_TTABLE) + { + lua_rawgeti(L,1,1); + lua_rawgeti(L,1,2); + lua_remove(L,1); + lua_insert(L,1); + lua_insert(L,1); + } + if ((lua_type(L,1)!=LUA_TNUMBER)||(lua_type(L,2)!=LUA_TNUMBER)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + int x=lua_tointeger(L,1),y=lua_tointeger(L,2); + x=(x-x%23)/23;y=(y-y%23)/23; + noxMapDelWallAtPt(x,y); + //TODO: - хорошо бы обновить клиентский список разрушимых стен + return 1; + } + /* + x1,y1,x2,y2,flags->ret,x,y + */ + int mapTraceRayL(lua_State *L) + { + int i=1; + if ( + (lua_type(L,i++)!=LUA_TNUMBER) || + (lua_type(L,i++)!=LUA_TNUMBER) || + (lua_type(L,i++)!=LUA_TNUMBER) || + (lua_type(L,i++)!=LUA_TNUMBER) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + i=1; + noxRect T; + T.X1=lua_tonumber(L,i++); + T.Y1=lua_tonumber(L,i++); + T.X2=lua_tonumber(L,i++); + T.Y2=lua_tonumber(L,i++); + int Flags=lua_tointeger(L,i++); + struct {int A;int B;} Ret4; + i=mapTraceRay(&T,(int)&Ret4,0,Flags); + lua_pushboolean(L,i); + lua_pushlightuserdata(L,(void*)Ret4.A); + lua_pushlightuserdata(L,(void*)Ret4.B); + return 3; + } + int mapGetTileByNameL(lua_State *L) + { + if ((lua_type(L,1)!=LUA_TSTRING) || (lua_gettop(L)!=1)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + int Tile = getTileByName(lua_tostring(L,1)); + if (Tile<0) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + else + { + lua_pushinteger(L,Tile); + } + return 1; + } + + int mapGetNameByTileL(lua_State *L) + { + if ((lua_type(L,1)!=LUA_TNUMBER) || (lua_gettop(L)!=1) || (lua_tointeger(L,1)>80)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + char *mapFirstTile=0; + ASSIGN(mapFirstTile,0x00865C20); + char* Tile = (lua_tointeger(L,1) * 0x302C) + mapFirstTile; + lua_pushstring(L,Tile); + return 1; + } + + int mapMaxVariL(lua_State *L) + { + if (lua_type(L,1)!=LUA_TNUMBER || lua_type(L,2)!=LUA_TNUMBER) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + int tile=lua_tointeger(L,1); + int dir=lua_tointeger(L,2); + if (tile<0 || dir<0) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + lua_pushinteger(L,noxMapGetMaxVari(tile,dir,0)); + return 1; + } + + DWORD *mapDoInitialize; + bool firstRun=true; +} +void __cdecl onLoadLevel() /// вызывается при загрузке левела (сервером???) +{ + /// Сервером или клиентом? + if(0==*mapDoInitialize) + return; + if (firstRun) + firstRun=false; + else + { + mapUnloadUtil(); + mapUnloadFilesystem(); + } + + mapInitialize(); + int Top=lua_gettop(L); + do + { + getServerVar("onMapLoad"); + if (!lua_isfunction(L,-1)) + break; + lua_pcall(L,0,0,0); + lua_settop(L,Top); + } + while(0); + mapLoadFilesystem(mapGetName()); + mapLoadSpells(); +} +extern DWORD *GameFlags; +void netOnWallChanged(wallRec *newData) +{ + char Buf[280]; + + int x=newData->posX,y=newData->posY; + sprintf(Buf,"wall at %d %d",x,y); + conPrintI(Buf); + + wallRec *P=noxGetWallAtPt(x,y); + if (P==NULL) + { + P=noxWallCreateAt(x,y); + if (newData->wallFlags & 4) + wallSecretListUpdate(P); + } + if (P==NULL) + return; + P->wallId=newData->wallId; + P->wallFlags=newData->wallFlags; + wallBreakListUpdate(P); +} +extern void InjectOffs(DWORD Addr,void *Fn); +extern void InjectAddr(DWORD Addr,void *Fn); +void mapInit() +{ + ASSIGN(scriptCallerUnit,0x00979720); + ASSIGN(scriptTriggerUnit,0x00979724); + + ASSIGN(mapInitialize,0x004FC590); + ASSIGN(mapDoInitialize,0x00753908); + InjectOffs(0x004D2D31+1,onLoadLevel); + + ASSIGN(scriptPopValue,0x00507250); + ASSIGN(scriptPushValue,0x00507230); + ASSIGN(scriptKey,0x0097BB40); + ASSIGN(mapWaypoint,0x00514800); + InjectAddr(0x005C3244,myWaypoint); + + ASSIGN(noxGetWallAtPt,0x410580); + ASSIGN(noxWallCreateAt,0x410250); + ASSIGN(noxWallTileByName,0x410D60); + ASSIGN(noxMapDelWallAtPt,0x410430); + ASSIGN(mapTraceRay,0x535250); + ASSIGN(netWallCreate,0x4FFE80); + ASSIGN(mapGetName,0x409B40); + ASSIGN(noxMapGetMaxVari,0x410DD0); + + ASSIGN(noxWallBreackableListAdd,0x00410840); + ASSIGN(noxWallBreackableListRemove,0x00410890); + ASSIGN(noxGetFirstBreakableList,0x00410870); + + ASSIGN(noxWallSecretBlock_410760,0x410760); + + ASSIGN(wallNextBreakableId,0x00689574); + + registerserver("mapGet",&getWallAtPtL); + registerserver("mapInfo",&mapInfoL); + registerserver("mapSet",&setWallAtPtL); + registerserver("mapDel",&mapDelWallAtPtL); + registerserver("mapTraceRay",&mapTraceRayL); + registerserver("mapTileByName",&mapGetTileByNameL); + + registerclient("mapMaxVari",&mapMaxVariL); + registerclient("mapNameByTile",&mapGetNameByTileL); + registerclient("mapGetName",&mapGetNameL); +} + diff --git a/mapUtil.cpp b/mapUtil.cpp index 4869f7a..9c398de 100644 --- a/mapUtil.cpp +++ b/mapUtil.cpp @@ -1,179 +1,179 @@ -#include "stdafx.h" -#include "direct.h" - -extern "C" void mapUtilInit(lua_State*L); -/* -Mode -0=wb -1=rb -2=r+b -CodeType -0x13=MapEncoding -*/ -bool (__cdecl *cryptOpen)(const char *Filename,int Mode,int CodeType); -void (__cdecl *cryptClose)(); -int (__cdecl *fileReadWrite)(void *DstBuf, size_t DstSize); -int (__cdecl *genWriteMapMB)(char *Path,int Type); -char *(__cdecl *getGameFolder)(); - -void **noxWallGlobalList=(void**)0x0075396C; -/* - : -DWORD Sign;//FADEFACE -DWORD Crc; -DWORD Var1; -DWORD Var2; - - -Section -{ -byte NameLen; -byte Name[]; -DWORD SectionCrcORSize; -} -*/ -namespace -{ -/* - - int mapDecode(lua_State*L) - { - lua_settop(L,2); - if ( - lua_type(L,1)!=LUA_TSTRING || - (lua_type(L,2)!=LUA_TSTRING) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - FILE *G=fopen(lua_tostring(L,1),"rb"); - if (G==NULL) - { - lua_pushstring(L,"mapDecode: unable to open src file!"); - lua_error_(L); - } - fseek(G,0,SEEK_END); - int FileSize=ftell(G); - fclose(G); - - if (!cryptOpen(lua_tostring(L,1),1,0x13)) - { - lua_pushstring(L,"mapDecode: unable to open src file!"); - lua_error_(L); - } - FILE *F=fopen(lua_tostring(L,2),"wb"); - if (F==NULL) - { - lua_pushstring(L,"mapDecode: unable to open src file!"); - lua_error_(L); - } - int Remain=FileSize; - int X; - const int BufSize=1024; - char Buf[BufSize]={0}; - while(Remain>0) - { - int BlockSize=Remain>BufSize?BufSize:Remain; - if (0==fileReadWrite(Buf,BlockSize)) - { - lua_pushstring(L,"mapDecode: read error!"); - lua_error_(L); - } - fwrite(Buf,BlockSize,1,F); - Remain-=BlockSize; - } - fclose(F); - cryptClose(); - return 0; - - } - int mapEncode(lua_State*L) - { - lua_settop(L,2); - if ( - lua_type(L,1)!=LUA_TSTRING || - (lua_type(L,2)!=LUA_TSTRING) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - FILE *F=fopen(lua_tostring(L,1),"rb"); - if (F==NULL) - { - lua_pushstring(L,"mapEncode: unable to open src file!"); - lua_error_(L); - } - if (!cryptOpen(lua_tostring(L,2),0,0x13)) - { - lua_pushstring(L,"mapEncode: unable to open dst file!"); - lua_error_(L); - } - - fseek(F,0,SEEK_END); - int FileSize=ftell(F); - fseek(F,0,SEEK_SET); - int Remain=FileSize; - int X; - const int BufSize=1024; - char Buf[BufSize]={0}; - while(Remain>0) - { - int BlockSize=Remain>BufSize?BufSize:Remain; - if (1!=fread(Buf,BlockSize,1,F)) - { - lua_pushstring(L,"mapEncode: write error!"); - lua_error_(L); - } - if (0==fileReadWrite(Buf,BlockSize)) - { - lua_pushstring(L,"mapEncode: write error!"); - lua_error_(L); - } - Remain-=BlockSize; - } - fclose(F); - cryptClose(); - return 0; - - } -*/ - int mapSave(lua_State*L) - { - lua_settop(L,1); - if ( - lua_type(L,1)!=LUA_TSTRING - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - char Buf[60]; - sprintf(Buf,"%s\\Maps\\%s",getGameFolder(),lua_tostring(L,1)); - _mkdir(Buf); - sprintf(Buf,"%s\\Maps\\%s\\%s.map",getGameFolder(),lua_tostring(L,1),lua_tostring(L,1)); - wallRec *Wall=*((wallRec**)(noxWallGlobalList)); - *noxWallGlobalList=(void*)0; - lua_pushboolean(L,genWriteMapMB(Buf,1)); - *noxWallGlobalList=(wallRec*)Wall; - return 1; - - } -} -void mapUtilInit(lua_State*L) -{ - ASSIGN(cryptOpen,0x00426910); - ASSIGN(cryptClose,0x004269F0); - ASSIGN(fileReadWrite,0x00426AC0); - ASSIGN(genWriteMapMB,0x0051E010); - ASSIGN(getGameFolder,0x00409E10); - -/* lua_pushcfunction(L,&mapDecode); - lua_setglobal(L,"mapDecode"); - - lua_pushcfunction(L,&mapEncode); - lua_setglobal(L,"mapEncode"); -*/ - registerserver("mapSave",&mapSave); +#include "stdafx.h" +#include "direct.h" + +extern "C" void mapUtilInit(lua_State*L); +/* +Mode +0=wb +1=rb +2=r+b +CodeType +0x13=MapEncoding +*/ +bool (__cdecl *cryptOpen)(const char *Filename,int Mode,int CodeType); +void (__cdecl *cryptClose)(); +int (__cdecl *fileReadWrite)(void *DstBuf, size_t DstSize); +int (__cdecl *genWriteMapMB)(char *Path,int Type); +char *(__cdecl *getGameFolder)(); + +void **noxWallGlobalList=(void**)0x0075396C; +/* +Формат файла: +DWORD Sign;//FADEFACE +DWORD Crc; +DWORD Var1; +DWORD Var2; +затем разделы + +Section +{ +byte NameLen; +byte Name[]; +DWORD SectionCrcORSize; +} +*/ +namespace +{ +/* +Тестовые функции для шифрования файлов + int mapDecode(lua_State*L) + { + lua_settop(L,2); + if ( + lua_type(L,1)!=LUA_TSTRING || + (lua_type(L,2)!=LUA_TSTRING) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + FILE *G=fopen(lua_tostring(L,1),"rb"); + if (G==NULL) + { + lua_pushstring(L,"mapDecode: unable to open src file!"); + lua_error_(L); + } + fseek(G,0,SEEK_END); + int FileSize=ftell(G); + fclose(G); + + if (!cryptOpen(lua_tostring(L,1),1,0x13)) + { + lua_pushstring(L,"mapDecode: unable to open src file!"); + lua_error_(L); + } + FILE *F=fopen(lua_tostring(L,2),"wb"); + if (F==NULL) + { + lua_pushstring(L,"mapDecode: unable to open src file!"); + lua_error_(L); + } + int Remain=FileSize; + int X; + const int BufSize=1024; + char Buf[BufSize]={0}; + while(Remain>0) + { + int BlockSize=Remain>BufSize?BufSize:Remain; + if (0==fileReadWrite(Buf,BlockSize)) + { + lua_pushstring(L,"mapDecode: read error!"); + lua_error_(L); + } + fwrite(Buf,BlockSize,1,F); + Remain-=BlockSize; + } + fclose(F); + cryptClose(); + return 0; + + } + int mapEncode(lua_State*L) + { + lua_settop(L,2); + if ( + lua_type(L,1)!=LUA_TSTRING || + (lua_type(L,2)!=LUA_TSTRING) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + FILE *F=fopen(lua_tostring(L,1),"rb"); + if (F==NULL) + { + lua_pushstring(L,"mapEncode: unable to open src file!"); + lua_error_(L); + } + if (!cryptOpen(lua_tostring(L,2),0,0x13)) + { + lua_pushstring(L,"mapEncode: unable to open dst file!"); + lua_error_(L); + } + + fseek(F,0,SEEK_END); + int FileSize=ftell(F); + fseek(F,0,SEEK_SET); + int Remain=FileSize; + int X; + const int BufSize=1024; + char Buf[BufSize]={0}; + while(Remain>0) + { + int BlockSize=Remain>BufSize?BufSize:Remain; + if (1!=fread(Buf,BlockSize,1,F)) + { + lua_pushstring(L,"mapEncode: write error!"); + lua_error_(L); + } + if (0==fileReadWrite(Buf,BlockSize)) + { + lua_pushstring(L,"mapEncode: write error!"); + lua_error_(L); + } + Remain-=BlockSize; + } + fclose(F); + cryptClose(); + return 0; + + } +*/ + int mapSave(lua_State*L) + { + lua_settop(L,1); + if ( + lua_type(L,1)!=LUA_TSTRING + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + char Buf[60]; + sprintf(Buf,"%s\\Maps\\%s",getGameFolder(),lua_tostring(L,1)); + _mkdir(Buf); + sprintf(Buf,"%s\\Maps\\%s\\%s.map",getGameFolder(),lua_tostring(L,1),lua_tostring(L,1)); + wallRec *Wall=*((wallRec**)(noxWallGlobalList)); + *noxWallGlobalList=(void*)0; + lua_pushboolean(L,genWriteMapMB(Buf,1)); + *noxWallGlobalList=(wallRec*)Wall; + return 1; + + } +} +void mapUtilInit(lua_State*L) +{ + ASSIGN(cryptOpen,0x00426910); + ASSIGN(cryptClose,0x004269F0); + ASSIGN(fileReadWrite,0x00426AC0); + ASSIGN(genWriteMapMB,0x0051E010); + ASSIGN(getGameFolder,0x00409E10); + +/* lua_pushcfunction(L,&mapDecode); + lua_setglobal(L,"mapDecode"); + + lua_pushcfunction(L,&mapEncode); + lua_setglobal(L,"mapEncode"); +*/ + registerserver("mapSave",&mapSave); } \ No newline at end of file diff --git a/net.cpp b/net.cpp index 9bc3382..f22197e 100644 --- a/net.cpp +++ b/net.cpp @@ -1,1304 +1,1304 @@ -#include "stdafx.h" -#include "unit.h" -#include "player.h" -#include -#include - -int UnimodVersion=010601;/// 00.06.01 - -void (__cdecl *netClientSend) (int PlrN,int Dir,//1 - - void *Buf,int BufSize); -// Bool - - -extern sprite_s *(__cdecl *spriteLoadAdd) (int thingType,int coordX,int coordY); -extern void (__cdecl *spriteDeleteStatic)(sprite_s *Sprite); - -sprite_s *(__cdecl *netSpriteByCodeHi)(int netCode);// -sprite_s *(__cdecl *netSpriteByCodeLo)(int netCode);// - -void (__cdecl *netSendMsgInform2)(int id, void *data); -void (__cdecl *netSendPointFx)(int PacketIdx,noxPoint* Pt); -void (__cdecl *netSendRayFx)(int PacketIdx,noxRectInt* Rc); -void (__cdecl *netPriMsg)(void *PlayerUnit,char *String,int Flag); - -DWORD (__cdecl *netGetUnitCodeServ)(void *Unit); -DWORD (__cdecl *netGetUnitCodeCli)(void *Sprite); - -void (__cdecl *netReportCharges) (int playerIdx, void *weapon, int a,int b); - -void *(__cdecl *netGetUnitByExtent)(DWORD NetCode);/// ( )playerGoObserver - -void (__cdecl *netSendShieldFx)(void *Unit,noxPoint* From); -void (__cdecl *netSendExplosionFx)(noxPoint* Pt,int count); - -extern "C" void conSendToServer(const char *Cmd); -extern "C" int conDoCmd(char *Cmd,bool &PrintNil); - -extern void netOnTileChanged(BYTE *Buf,BYTE *End); -extern void netOnUpdateUnitDef(BYTE *Buf,BYTE *BufEnd); -extern int (__cdecl *consoleParse)(wchar_t*Str,int Mode); - -int (__cdecl *netSendBySock)(int Player,void *Data,int Size, int Type); - -byte authorisedState[0x20]; -char *authorisedLogins[0x20]; - -playerInfoStruct **playerSysop=(playerInfoStruct**)0x0069D720; - -//char *temp; // - -extern void authCheckDelayed(byte playerIdx, char* pass); - -extern char authSendWelcomeMsg[0x20]; - -int (__cdecl *netCreatePlayerStartPacket)(void* Dst, void* playerInfo); -void *(__cdecl *playerCheckDuplicateNames)(void* playerInfo); - -int clientsVersions[0x20]; - -extern bool replayPacketHandler(BYTE *&BufStart, BYTE *&E, bool &found); - -bigUnitStruct *netUnitByCodeServ(DWORD NetCode) -{ - if (NetCode & 0x8000) - return (bigUnitStruct *)netGetUnitByExtent(NetCode&0x7FFF); - return 0; -} -void netSendServ(void *Buf,int BufSize) -{ - netClientSend(0x1F,0,Buf,BufSize);// , -} -void netSendNotOne(void *Buf,int BufSize,void *One) /// -{ - for(bigUnitStruct* Plr=playerFirstUnit();Plr!=0;Plr=playerNextUnit(Plr)) - { - BYTE *P2=(BYTE*)Plr->unitController; - if (P2==One) - continue; - P2+=0x114;P2=*((BYTE **)P2); - P2+=0x810; - netClientSend(*P2,1,Buf,BufSize); - } -} -void netSendAll(void *Buf,int BufSize) -{ - for(bigUnitStruct* Plr=playerFirstUnit();Plr!=0;Plr=playerNextUnit(Plr)) - { - BYTE *P2=(BYTE*)Plr->unitController; - P2+=0x114;P2=*((BYTE **)P2); - P2+=0x810; - netClientSend(*P2,1,Buf,BufSize); - } - -} -void conSendToServer(const char *Src) -{ - return; - BYTE Buf[255],*P=Buf; - size_t Size=strlen(Src)+1; - - if (Size>0 && Size<255) - { - netUniPacket(upLuaRq,P,Size); - memcpy(P,Src,Size); - netSendServ(Buf,Size+P-Buf); - } - -} - -void netSendChatMessage(char *sendChat, int sendTo, short sendFrom=0, bool fakeSystemMessage=false) -{ - if(sendFrom==0 && fakeSystemMessage==false) - { - DWORD *DW=(DWORD*)getPlayerUDataFromPlayerIdx(0x1F); - if (0==(DW[2] & 0x4)) - { - return; - } - BYTE *unit=(BYTE*)getPlayerUDataFromPlayerIdx(0x1F); - void **PP=(void **)(((char*)unit)+0x2EC); - PP=(void**)(((char*)*PP)+0x114); - byte *P=(byte*)(*PP); - sendFrom=*((short*)(P+0x80C)); - - } - short netCode=0; - if(fakeSystemMessage==false) - netCode = sendFrom; - byte sendChatPacketHeader[0xB] = {0xA8, 0x2, 0x0, 0x2, 0x72, 0x0B, 0x7D, 0x0B, 0x5, 0x0, 0x0}; - byte *sendChatPacket=new byte[strlen(sendChat)+0xB+1]; - memcpy(sendChatPacket, sendChatPacketHeader, 0xB); - memcpy(&sendChatPacket[0xB], sendChat, strlen(sendChat)); - sendChatPacket[0x8]=strlen(sendChat)+1; - *((short*)(sendChatPacket+1)) = netCode; - //memcpy(&sendChatPacket[0x1], &netCode, 2); - sendChatPacket[0xB+strlen(sendChat)]=0x0; - if(sendTo<0 || sendTo>31) - { - netSendAll(sendChatPacket,strlen(sendChat)+0xB+1); - } - else - { - netClientSend(sendTo,1,sendChatPacket,strlen(sendChat)+0xB+1); - } - delete [] sendChatPacket; - return; -} - -bool specialAuthorisation=false; // -namespace { - - BYTE *fakePlayerInputPacket(BYTE* BufStart) - { - BYTE *P=BufStart; - if(P[1]<10) - { - BufStart+=P[1]+2; - return BufStart; - } - else - { - const BYTE replace[12]={0x3f, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x81, 0x01, 0x00, 0x00, 0x00, 0x81}; - if(P[1]>10) - BufStart+=(P[1]+2)-12; - memcpy(BufStart, replace, 12); - return BufStart; - } - } - - int sendToServer(lua_State *L) - { - const char *S=lua_tostring(L,1); - if (S) - conSendToServer(S); - return 0; - } - int netGetCodeServL(lua_State *L) - { - if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - void *P=lua_touserdata(L,1); - if (P==0) - { - lua_pushnil(L);return 1; - } - lua_pushinteger(L,netGetUnitCodeServ(P)); - return 1; - } - int netReportChargesL(lua_State *L) - { - if ( - (lua_type(L,1)!=LUA_TLIGHTUSERDATA) || - (lua_type(L,2)!=LUA_TLIGHTUSERDATA)|| - (lua_type(L,3)!=LUA_TNUMBER)|| - (lua_type(L,4)!=LUA_TNUMBER)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - bigUnitStruct *Plr=(bigUnitStruct *)lua_touserdata(L,1); - BYTE *P2=(BYTE*)Plr->unitController; - P2+=0x114;P2=*((BYTE **)P2); - P2+=0x810; - netReportCharges(*P2,lua_touserdata(L,2),lua_tointeger(L,3),lua_tointeger(L,4)); - return 0; - } - - - int netPointFx(lua_State *L) - { - lua_settop(L,3); - if ((lua_type(L,-3)!=LUA_TNUMBER)|| - (lua_type(L,-2)!=LUA_TNUMBER)|| - (lua_type(L,-1)!=LUA_TNUMBER)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - noxPoint P(lua_tonumber(L,-2),lua_tonumber(L,-1)); - int Code=lua_tointeger(L,-3); - // - netMsgNames - // +0x27 - // - // 0xA0-,0xA3 - - netSendPointFx(Code,&P); - return 0; - } - int netRayFx(lua_State *L) - { - lua_settop(L,5); - - if ((lua_type(L,-5)!=LUA_TNUMBER)|| - (lua_type(L,-4)!=LUA_TNUMBER)|| - (lua_type(L,-3)!=LUA_TNUMBER)|| - (lua_type(L,-2)!=LUA_TNUMBER)|| - (lua_type(L,-1)!=LUA_TNUMBER)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - noxRectInt R(lua_tointeger(L,-4),lua_tointeger(L,-3), - lua_tointeger(L,-2),lua_tointeger(L,-1)); - int Code=lua_tointeger(L,-5); - // - netMsgNames - // +0x27 - // :11,14,15,16,19,20 - 0x9F - // - // - netSendRayFx(Code,&R); - return 0; - } - int netShieldFx(lua_State *L) - { - lua_settop(L,3); - if (lua_type(L,-3)!=LUA_TLIGHTUSERDATA) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - - noxPoint Pt(lua_tonumber(L,-2),lua_tonumber(L,-1)); - netSendShieldFx(lua_touserdata(L,-3),&Pt); - return 0; - } - - - int netExplosionFx(lua_State *L) - { - if ((lua_type(L,1)!=LUA_TNUMBER)|| - (lua_type(L,2)!=LUA_TNUMBER)|| - (lua_type(L,3)!=LUA_TNUMBER)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - int count=lua_tonumber(L,1); - if (count>255) - count%=255; - noxPoint Pt(lua_tonumber(L,2),lua_tonumber(L,3)); - netSendExplosionFx(&Pt,count); - return 0; - } - - int netRename(lua_State *L) - { - - if ( - (lua_type(L,1)!=LUA_TLIGHTUSERDATA || lua_type(L,2)!=LUA_TSTRING) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - DWORD *DW=(DWORD*)lua_touserdata(L,1); - if (0==(DW[2] & 0x4)) - { - lua_pushstring(L,"wrong args: unit is not a player!"); - lua_error_(L); - } - char RP[0x81]; - memset(&RP,0,sizeof(RP)); - BYTE *unit=(BYTE*)lua_touserdata(L,1); - void **PP=(void **)(((char*)unit)+0x2EC); - PP=(void**)(((char*)*PP)+0x114); - byte *P=(byte*)(*PP); - mbstowcs((wchar_t*)(P+0x1260), lua_tostring(L, 2), 0x18); - mbstowcs((wchar_t*)(P+0x889), lua_tostring(L, 2), 0x18); - mbstowcs((wchar_t*)(P+0x8E2), "\0\0", 0x2); - playerCheckDuplicateNames(P); - netCreatePlayerStartPacket(&RP,P); - //memcpy(&RP.NameMB, (wchar_t*)(P+0x1260), (sizeof(wchar_t)*0x30)); - netSendAll(&RP,sizeof(RP)); - return 0; - } - int netFake(lua_State *L) - /// , - { - if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - - struct { - BYTE Pckt; - USHORT Code; - } B={0xE8,netGetUnitCodeServ(lua_touserdata(L,-1))}; - - netSendAll(&B,sizeof(B)); - - return 0; - } - - // . - // : , , - int playerDeathL(lua_State *L) - { - if (lua_type(L, 1) != LUA_TLIGHTUSERDATA) - { - lua_pushstring(L, "wrong args: arg1 != userdata"); - lua_error_(L); - } - void *victim = (bigUnitStruct *) lua_touserdata(L, 1); - void *attacker = NULL; - if (!lua_isnil(L, 2)) { attacker = lua_touserdata(L, 2); } - void *assist = NULL; - if (!lua_isnil(L, 3)) { assist = lua_touserdata(L, 3); } - - struct - { - USHORT unused; //2 - USHORT _attack; //4 - USHORT _unknown1; //6 - USHORT _victim; //8 - USHORT _unknown2; //10 - } S = {0, netGetUnitCodeServ(attacker), 0, netGetUnitCodeServ(victim), netGetUnitCodeServ(assist)}; - - netSendMsgInform2(0xE, &S); - return 0; - } - - // ( ) . - // : (1 - 31), - int netSendMessageBoxL(lua_State *L) - { - if (lua_type(L, 1) != LUA_TNUMBER) - { - lua_pushstring(L, "wrong args: arg1 != int"); - lua_error_(L); - } - if (lua_type(L, 2) != LUA_TSTRING) - { - lua_pushstring(L, "wrong args: arg2 != string"); - lua_error_(L); - } - - int plrId = (int) lua_tonumber(L, 1); - if (plrId < 0 || plrId > 31) - { - lua_pushstring(L, "wrong args: arg1 is not a valid player index"); - lua_error_(L); - } - const char* text = lua_tostring(L, 2); - int textlen = strlen(text); - - struct - { - BYTE packetID; - BYTE zero1; - BYTE zero2; - BYTE msgType; - DWORD zero3; - WORD msgLength; - BYTE zero4; - } packetHeader = { 0xA8, 0, 0, 0x12, 0, textlen + 1, 0 }; - - byte *packetData = new byte[textlen + 12]; // 0 - memcpy(packetData, &packetHeader, 11); - memcpy(&packetData[11], text, textlen); - packetData[11 + textlen] = 0; - netClientSend(plrId, 1, packetData, textlen + 12); - delete [] packetData; - return 0; - } - - // PARTICLEFX - // : 5, 1, 1, 10, 2, 0 - 10 - - /* - - fx 0: " ": (, , , , ) - fx 1: "": (, , , , ) - fx 2: "?": (, , , , ) - fx 3: "": (, , , , ) - (16 ). - fx 4: "" fx 0 - fx 5: "?": (, , , , ) - fx 6: , - */ - int netTestParticleL(lua_State *L) - { - for (int i = 1; i <= 5; i++) - { - if (lua_type(L, i) != LUA_TNUMBER) - { - lua_pushstring(L, "wrong args: arg != int"); - lua_error_(L); - } - } - - BYTE fxtype = (BYTE) lua_tonumber(L, 1); - WORD arg1 = (WORD) lua_tonumber(L, 2); - WORD arg2 = (WORD) lua_tonumber(L, 3); - WORD arg3 = (WORD) lua_tonumber(L, 4); - WORD netCode = (WORD) lua_tonumber(L, 5); - //float arg4 = (float) lua_tonumber(L, 6); - - struct - { - BYTE packetID; - BYTE fxType; - WORD word1; - WORD word2; - WORD word3; - WORD word4; // holder - DWORD dword; - } packetHeader = { 0x7C, fxtype, arg1, arg2, arg3, netCode, 0 }; - - netSendAll(&packetHeader, 14); - return 0; - } - - // - int netTestIntensityL(lua_State *L) - { - if (lua_type(L, 1) != LUA_TNUMBER) - { - lua_pushstring(L, "wrong args: arg1 != int"); - lua_error_(L); - } - if (lua_type(L, 2) != LUA_TNUMBER) - { - lua_pushstring(L, "wrong args: arg2 != int"); - lua_error_(L); - } - - WORD netcode = (WORD) lua_tonumber(L, 1); - float intensity = (float) lua_tonumber(L, 2); - - struct - { - BYTE packetID; - WORD sprite; - float intens; - } packetHeader = { 0x5D, netcode, intensity }; - - netSendAll(&packetHeader, 14); - return 0; - } - - // - int netTestColorL(lua_State *L) - { - for (int i = 1; i <= 4; i++) - { - if (lua_type(L, i) != LUA_TNUMBER) - { - lua_pushstring(L, "wrong args: arg != int"); - lua_error_(L); - } - } - - WORD netcode = (WORD) lua_tonumber(L, 1); - BYTE cR = (BYTE) lua_tonumber(L, 2); - BYTE cG = (BYTE) lua_tonumber(L, 3); - BYTE cB = (BYTE) lua_tonumber(L, 4); - - struct - { - BYTE packetID; - WORD sprite; - BYTE R; - BYTE G; - BYTE B; - } packetHeader = { 0x5C, netcode, cR, cG, cB }; - - netSendAll(&packetHeader, 6); - return 0; - } - - int netOnRespL(lua_State *L) - { - bigUnitStruct *Plr=(bigUnitStruct *)lua_touserdata(L,1); - char Buf[280]; - sprintf(Buf,"cli %p %s%s",Plr,(lua_tointeger(L,2)==0)?"error:":"ok:",lua_tostring(L,3) ); - conPrintI(Buf); - return 0; - } - int netDoReq(lua_State *L)/// - { - BYTE Buf[255],*P=Buf; - size_t Size; - const char *Src=lua_tolstring(L,1,&Size); - if (Size>0 && Size<255) - { - Size++; - netUniPacket(upLuaRq,P,Size); - memcpy(P,Src,Size-1); - netSendAll(Buf,Size+P-Buf); - } - else - { - lua_pushstring(L,"wrong: string too long (max 255)!"); - lua_error_(L); - } - return 0; - } - int netDoDelayed(lua_State *L) - { - int n=lua_gettop(L); - lua_pushvalue(L,lua_upvalueindex(1));/// - lua_pushvalue(L,lua_upvalueindex(2));// fn - lua_pushinteger(L,0); // 0 - time - lua_newtable(L); - for (int i=1;i<=n;i++) - { - lua_pushvalue(L,i); - lua_rawseti(L,-2,i); //{"string"} - } - lua_call(L,3,0); - return 0; - } - - void netLuaRq(BYTE *P,BYTE *End) - { - return; // - BYTE Buf[255],*Pt=Buf; - size_t Size; - const char *Src; - bool Ok=true; - int From = lua_gettop(L); /// - End[-1]=0; - sprintf((char*)Buf,"cmd: %s",P); - conPrintI((char*)Buf); - - if (0!=luaL_loadstring(L,(char*)P)) - { - Ok=false; - } - if (Ok && (0!=lua_pcall(L,0,1,0)) ) - { - Ok=false; - } - Src=lua_tolstring(L,-1,&Size); - if (Size<255) - { - netUniPacket(upLuaResp,Pt,Size+1); - *(Pt++)=Ok?1:0; - if (Src==NULL) - *Pt=0; - else - memcpy(Pt,Src,Size); - netSendServ(Buf,Size+Pt-Buf); - } - lua_settop(L,From); - - } - void netDelStatic(BYTE *Start,BYTE *End) - { - int Code=*((int*)(Start+0)); - if (0==(Code&0x8000)) // - return; - sprite_s *S=netSpriteByCodeHi(Code); - BYTE* P=(BYTE *)S; - *((int *)(P+0x80))|=0x8000; - if (S) - spriteDeleteStatic(S); - } - void netMoveStatic(BYTE *Start,BYTE *End) - { - int Code=*((int*)(Start+0)); - //TODO: - } - - void netNewStatic(BYTE *Start,BYTE *End) - { - BYTE *S= - (BYTE *)spriteLoadAdd( *((int*)(Start+0)), - (*((float*)(Start+4))), - (*((float*)(Start+8)))); - DWORD *Code=(DWORD *)(S+0x80); - if (*Code!=*((DWORD*)(Start+0x0C)) ) - Code++; - } - int netDoPrintConsole(const char *Src,BYTE *pli,int color, bool crop=false) - { - BYTE Buf[259],*P=Buf; - size_t Size; - Size=strlen(Src); - char* NextSrc = new char[Size+1]; - memset(NextSrc, 0, (Size+1)); - if (Size>0 && Size<200) - { - } - else if(crop) - { - Size=199; - strncpy(NextSrc, &Src[199], (Size+1)); - } - else - { - return 1; - } - Size++; - netUniPacket(upSendPrintToCli,P,Size+4); - memcpy(P,&color,4); - P+=4; - memcpy(P,Src,Size); - char* zero="\0"; - strncpy((char*)&P[199], zero, 1); - pli+=0x810; - netClientSend(*pli,1,Buf,Size+P-Buf); - pli-=0x810; - if(crop && strlen(NextSrc)>0) - netDoPrintConsole(NextSrc, pli, color, crop); - delete [] NextSrc; - return 0; - } - - int netDoPrintConsoleL(lua_State *L) - { - if (lua_type(L,1)!=LUA_TLIGHTUSERDATA || lua_type(L,2)!=LUA_TSTRING) - { - lua_pushstring(L,"wrong args"); - lua_error_(L); - } - BYTE *P=(BYTE*)lua_touserdata(L,1); - int unitClass=*(P+8); - if ((unitClass & clPlayer)==0) - { - lua_pushstring(L,"wrong args"); - lua_error_(L); - } - P+=0x2EC; - P=*((BYTE**)P); - P+=0x114; - P=*((BYTE**)P); - int color=lua_tointeger(L,3); - if (color==NULL || color<0 || color>16) - color=2; - int res = netDoPrintConsole(lua_tostring(L,2),P,color); - if(res==1) - { - lua_pushstring(L,"wrong: string too long (max 255)!"); - lua_error_(L); - } - return 0; - } - - void netPrintConsole(BYTE *P,BYTE *End) - { - int color=(int)*P; - P+=4; - char *Str=(char*)P; - conSetNextColor(color); - conPrintI(Str); - } - void netOnVersionRq(BYTE *Start,BYTE *End,bigUnitStruct* Plr) - { - if (End-Start<4) - return;// - - BYTE *P2=(BYTE*)Plr->unitController; - P2+=0x114;P2=*((BYTE **)P2); - P2+=0x810; - int Top= lua_gettop(L); - int OtherVersion=*((int*)Start); - clientsVersions[*P2]=OtherVersion; - if (floor((double)(UnimodVersion/100))>floor((double)(OtherVersion/100))) - { - getServerVar("serverOnClientVersionWrong"); - if (lua_type(L,-1)==LUA_TFUNCTION) - { - lua_pushinteger(L,OtherVersion); - lua_pushinteger(L,UnimodVersion); - lua_pushinteger(L,*P2); - lua_pushlightuserdata(L,Plr); - lua_pcall(L,4,0,0); - } - } - const char *Src; - size_t Size=0; - if (End-Start>4) - { - do - { - if (0!=luaL_loadbuffer(L,(char*)Start+4,End-Start-4,"netOnVersion")) - break; - lua_getfield(L,LUA_REGISTRYINDEX,"server"); - lua_setfenv(L,-2); - lua_pcall(L,0,1,0); - } while(0); - Src=lua_tolstring(L,-1,&Size); - if (Size>200) - Size=200; - if (Src==NULL) - Size=0; - } - BYTE Buf[255],*Pt=Buf; - netUniPacket(upVersionResp,Pt,Size+4); - *((int*)Pt)=UnimodVersion; - Pt+=4; - if (Size>0) - { - memcpy(Pt,Src,Size); - Pt+=Size; - } - netClientSend(*P2,1,Buf,Pt-Buf); - lua_settop(L,Top); - } - void netOnVersionResp(BYTE *Start,BYTE *End) - { - if (End-Start<4) - return;// - - int Top= lua_gettop(L); - int OtherVersion=*((int*)Start); - - getClientVar("clientOnServerVersion"); - if (lua_type(L,-1)==LUA_TFUNCTION) - { - lua_pushinteger(L,OtherVersion); - lua_pushinteger(L,UnimodVersion); - if (End-Start<4) - lua_pushnil(L); - else - { - lua_pushlstring(L,(char*)Start+4,End-Start-4); - } - lua_pcall(L,3,0,0); - } - lua_settop(L,Top); - } - - void netOnVersionServerRq(BYTE *Start,BYTE *End) - { - BYTE Buf[255],*Pt=Buf; - netUniPacket(upVersionRq,Pt,4); - *((int*)Pt)=UnimodVersion; - Pt+=4; - netSendServ(Buf,Pt-Buf); - } - - - - int netVersionRq(lua_State*L) - { - lua_settop(L,1); - size_t Size; - const char *Src=lua_tolstring(L,1,&Size); - if (Size>200) - Size=200; - if (Src==NULL) - Size=0; - BYTE Buf[255],*Pt=Buf; - netUniPacket(upVersionRq,Pt,Size+4); - *((int*)Pt)=UnimodVersion; - Pt+=4; - if (Size>0) - { - memcpy(Pt,Src,Size); - Pt+=Size; - } - netSendServ(Buf,Pt-Buf); - return 0; - } - int netGetVersion(lua_State*L) - { - lua_pushinteger(L,UnimodVersion); - return 1; - } - int netSendFx(lua_State*L) - { - lua_pushstring(L,"not implemented yet"); - lua_error(L); - return 1; - } - void sysopMyTrap(wchar_t*Str,int Mode) - { - bool UniComplete=false;// true - // 1 - int Len = wcslen(Str); - char* Cmd = new char[Len+1]; - wcstombs(Cmd,Str,Len+1); - lua_getfield(L,LUA_REGISTRYINDEX,"serverFnSysop"); - int success = luaL_loadstring(L, Cmd); - if(success==0) - UniComplete=true; - if (UniComplete==false) - { - consoleParse(Str,Mode); - return; - } - lua_pcall(L, 1, 1, 0); - char* result=(char*)lua_tostring(L, -1); - delete[] Cmd; - bigUnitStruct *unit = getPlayerUDataFromPlayerInfo(*playerSysop); - if(unit==0) - return; - DWORD *DW=(DWORD*)unit; - if (0==(unit->Class & clPlayer)) - { - return; - } - byte *P2=(byte*)(((ucPlayer*)unit->unitController)->playerInfo); - char *BuffS = new char[strlen(result)+10]; - memset(BuffS, 0, strlen(result)+10); - sprintf(BuffS,"sysop> %s",result); - netDoPrintConsole(BuffS,P2,14, true); - delete[] BuffS; - } -} - -void netVersionServerRq(int sendTo) -{ - BYTE Buf[255],*Pt=Buf; - netUniPacket(upVersionServerRq,Pt,0); - netClientSend(sendTo,1,Buf,Pt-Buf); -} -/* */ - ClientMap_s ClientRegMap; - ServerMap_s ServerRegMap; - -void netRegClientPacket(uniPacket_e Event,netClientFn_s Fn) -{ - ClientRegMap.insert(std::make_pair(Event,Fn)); -} -void netRegServPacket(uniPacket_e Event,netServFn_s Fn) -{ - ServerRegMap.insert(std::make_pair(Event,Fn)); -} -extern "C" void __cdecl onNetPacket(BYTE *&BufStart,BYTE *E); - - - -void netUniPacket(uniPacket_e Code,BYTE *&Data,int Size)/// -{ - *(Data++)=0xF8;// - *(Data++)=Size+1; - *(Data++)=(BYTE)Code; -} -extern void netOnWallChanged(wallRec *newData); -extern void netOnSendArchive(int Size,char *Name,char *NameE); -extern void netOnAbortDownload(); -void __cdecl onNetPacket(BYTE *&BufStart,BYTE *E)/// -{ - bool found=true; - // ! - found=true! ! - while(found) - { - found=false; - replayPacketHandler(BufStart, E, found); // false - BYTE *P=BufStart; - if (*P==186) - netOnAbortDownload(); -/* if(*P==0x2B) // . , , . - { - struct ServerData -{ - char mapName[8]; - char gap[1]; - char gameName[10]; - char gap_13[5]; - int field_18[5]; - DWORD weaponRestrictions; - DWORD armorRestrictions; - __int16 gameFlags; - __int16 fragLimit; - char timeLimitMB; - char isNew; -}; - extern int *mapFrameTime_6F9838; -extern void *(__cdecl *serverGetGameDataBySel)(); -extern char *(__cdecl *mapGetName)(); - P=P+0x25; - ServerData *Data=(ServerData*)serverGetGameDataBySel(); - char* mapName2 = mapGetName(); - char* mapName = Data->mapName; - mapName2 = mapGetName(); - - }*/ // For testing purposes only - else if (*P==0xF8)/// - {F8,<>, } - { - P++; - BufStart+=2+*(P++);// - found=true; - - char Buf[60]; - sprintf(Buf,"Unipacket cli %x",*P); - conPrintI(Buf); - - switch (*(P++)) - { - case upWallChanged: - netOnWallChanged((wallRec*)P); - break; - /*case upLuaRq: - netLuaRq(P,BufStart); - break;*/ // - case upNewStatic: - netNewStatic(P,BufStart); - break; - case upDelStatic: - netDelStatic(P,BufStart); - break; - case upMoveStatic: - netMoveStatic(P,BufStart); - break; - case upUpdateDef: - netOnUpdateUnitDef(P-UNIPACKET_HEAD,BufStart); - break; - case upSendArchive: - netOnSendArchive( *((int*)P),(char*)P+sizeof(int),(char*)BufStart); - break; - case upChangeTile: - netOnTileChanged(P,BufStart); - break; - case upVersionResp: - netOnVersionResp(P,BufStart); - break; - case upVersionServerRq: - netOnVersionServerRq(P,BufStart); - break; - case upSendPrintToCli: - netPrintConsole(P,BufStart); - break; - default: - { - ClientMap_s::const_iterator I=ClientRegMap.find(P[-1]); - if (I!=ClientRegMap.end()) - I->second(P); - } - }; - } - } -} -extern void spellServDoCustom(int SpellArr[5],bool OnSelf,BYTE *MyPlayer,BYTE *MyUc); - -extern void netOnClientTryUse(BYTE *Start,BYTE *End,BYTE *MyUc,void *Player); -extern "C" void __cdecl onNetPacket2(BYTE *&BufStart,BYTE *E, - BYTE *MyPlayer, /// bigUnitStruct - BYTE *MyUc)/// -{ - bool found=true; - // ! - found=true! ! - while(found) - { - found=false; - BYTE *P=BufStart; - if (*P==0x3F && specialAuthorisation==true) - { - void **PP=(void **)(((char*)MyPlayer)+0x2EC); - PP=(void**)(((char*)*PP)+0x114); - byte *P1=(byte*)(*PP); - byte playerIdx = *((byte*)(P1+0x810)); - if(playerIdx!=0x1F) // - switch(authorisedState[playerIdx]) - { - case 0: // - - case 1: // , - case 2: // , - case 3: // , , - BufStart=fakePlayerInputPacket(BufStart); - // - break; - case 4: // , - // - - break; - } - } - else if(*P==0xA8 && specialAuthorisation==true) - { - - void **PP=(void **)(((char*)MyPlayer)+0x2EC); - PP=(void**)(((char*)*PP)+0x114); - byte *Pl=(byte*)(*PP); - byte playerIdx = *((byte*)(Pl+0x810)); - char *authCmd="//auth "; - int cmdTokenL=0; - if(strncmp((char*)&P[0xB], authCmd, ((BufStart[0x8]>strlen(authCmd))?(strlen(authCmd)):(BufStart[0x8])))==0) - cmdTokenL=strlen(authCmd); - if(playerIdx!=0x1F && authorisedState[playerIdx]>=0 && authorisedState[playerIdx]<4) - { - switch(authorisedState[playerIdx]) - { - case 0: - case 3: - BufStart+=BufStart[0x8]+0xB; - found=true; - break; - case 1: - // - { - char *login=NULL; - login = new char[P[0x8]-cmdTokenL]; - strncpy(login, (char*)&P[0xB+cmdTokenL], P[0x8]-cmdTokenL); - authorisedLogins[playerIdx]=login; - authorisedState[playerIdx]++; - authSendWelcomeMsg[playerIdx]=-1; - BufStart+=BufStart[0x8]+0xB; - found=true; - login = NULL; - } - break; - case 2: - { - //char *data=NULL; - //data = new char[P[0x8]+1]; - char* pass = new char[P[0x8]-cmdTokenL]; - //memcpy(data, &playerIdx, 1); - //strncpy(&data[1], (char*)&P[0xB], P[0x8]); - strncpy(pass, (char*)&P[0xB+cmdTokenL], P[0x8]-cmdTokenL); - - // http - - // TEMPORARY! - //temp=data; - // TEMPORARY! END - authorisedState[playerIdx]++; - authSendWelcomeMsg[playerIdx]=-1; - authCheckDelayed(playerIdx, pass); - BufStart+=BufStart[0x8]+0xB; - found=true; - //data = NULL; - pass=NULL; - } - break; - /*case 3: - { - BufStart+=BufStart[0x8]+0xB; - - // TEMPORARY! - if(strcmp(&temp[1], "password")==0) - authorisedState[playerIdx]++; - else - authorisedState[playerIdx]-=2; - // TEMPORARY! END - } - break;*/ - } - } - if(cmdTokenL>0 && found==false) - { - BufStart+=BufStart[0x8]+0xB; - found=true; - } - } - else if(*P==0xBB && specialAuthorisation==true && ((char)P[0x4])>0) - { - - void **PP=(void **)(((char*)MyPlayer)+0x2EC); - PP=(void**)(((char*)*PP)+0x114); - byte *Pl=(byte*)(*PP); - byte playerIdx = *((byte*)(Pl+0x810)); - char *authCmd=" //auth "; - int cmdTokenL=0; - char *command = new char[BufStart[0x4]]; - wcstombs(command,((wchar_t*)&BufStart[0x5]),BufStart[0x4]); - if(strncmp((char*)command, authCmd, ((BufStart[0x4]>strlen(authCmd))?(strlen(authCmd)):(BufStart[0x4])))==0) - cmdTokenL=strlen(authCmd); - if(playerIdx!=0x1F && authorisedState[playerIdx]>=0 && authorisedState[playerIdx]<4 && cmdTokenL==strlen(authCmd)) - { - switch(authorisedState[playerIdx]) - { - case 0: - case 3: - BufStart+=BufStart[0x4]*2+0x7; - found=true; - break; - case 1: - // - { - char *login=NULL; - login = new char[P[0x4]-cmdTokenL]; - strncpy(login, (char*)&command[cmdTokenL], P[0x4]-cmdTokenL); - authorisedLogins[playerIdx]=login; - authorisedState[playerIdx]++; - authSendWelcomeMsg[playerIdx]=-1; - BufStart+=BufStart[0x4]*2+0x7; - found=true; - login = NULL; - } - break; - case 2: - { - //char *data=NULL; - //data = new char[P[0x8]+1]; - //char* pass = new char[P[0x8]-cmdTokenL]; - //memcpy(data, &playerIdx, 1); - //strncpy(&data[1], (char*)&P[0xB], P[0x8]); - //strncpy(pass, (char*)&P[0xB+cmdTokenL], P[0x8]-cmdTokenL); - char* pass = new char[P[0x4]-cmdTokenL]; - strncpy(pass, (char*)&command[cmdTokenL], P[0x4]-cmdTokenL); - // http - - // TEMPORARY! - //temp=data; - // TEMPORARY! END - authorisedState[playerIdx]++; - authSendWelcomeMsg[playerIdx]=-1; - authCheckDelayed(playerIdx, pass); - BufStart+=BufStart[0x4]*2+0x7; - found=true; - //data = NULL; - pass=NULL; - } - break; - /*case 3: - { - BufStart+=BufStart[0x8]+0xB; - - // TEMPORARY! - if(strcmp(&temp[1], "password")==0) - authorisedState[playerIdx]++; - else - authorisedState[playerIdx]-=2; - // TEMPORARY! END - } - break;*/ - } - } - if(cmdTokenL>0 && found==false) - { - BufStart+=BufStart[0x4]*2+0x7; - found=true; - } - } - else if (*P==0xF8)/// - {F8,<>, } - { - P++; - int BufSize=*(P++); - BufStart+=2+BufSize;// - found=true; - BufSize--;// - - char Buf[60]; - sprintf(Buf,"Unipacket serv %x",*P); - conPrintI(Buf); - - switch (*(P++)) - { - case upLuaResp: //TODO: - lua_getglobal(L,"netOnResp"); - if (lua_type(L,-1)==LUA_TFUNCTION) - { - lua_pushlightuserdata(L,MyPlayer); - lua_pushinteger(L,*(P++)); - lua_pushlstring(L,(char*)P,BufSize-1); - lua_pcall(L,3,0,0); - } - break; - /*case upLuaRq: - char Buf[200];bool Unused; - strncpy(Buf,(char *)P,199);Buf[199]=0; - conDoCmd(Buf,Unused); - sprintf(Buf,"cmd %s",P); - conPrintI(Buf); - break;*/ // - case upTryUnitUse: - netOnClientTryUse(P,BufStart,MyUc,MyPlayer); - break; - case upVersionRq: - netOnVersionRq(P,BufStart,(bigUnitStruct*)MyPlayer); - break; - default: - { - ServerMap_s::const_iterator I=ServerRegMap.find(P[-1]); - if (I!=ServerRegMap.end()) - I->second(P,MyPlayer,MyUc); - } - } - //return; - } else if (*P==0x79) // TRY_SPELL - { - if ( *((DWORD*)(P+1)) > 0x100 ) /// "" - - { - spellServDoCustom((int*)(P+1),(P[15])!=0,MyPlayer,MyUc); - found=true; - BufStart+=0x16; - } - } - else if (*P==0x72) // - { // 7 {BYTE pkt, USHORT Obj,X,Y;} - char Buf[80]; - USHORT V=toShort(P+1); - netUnitByCodeServ(V); - sprintf(Buf,"72 %x (%d,%d)",V,toShort(P+3),toShort(P+5) ); - conPrintI(Buf); - - } - } -} -extern void InjectJumpTo(DWORD Addr,void *Fn); -extern void InjectOffs(DWORD Addr,void *Fn); -int sendChat(lua_State* L) -{ - if(lua_isstring(L, 2) && lua_isnumber(L, 1)) - { - bool fakeSys=false; - if(lua_isnumber(L, 4)) - { - fakeSys = (bool)lua_tonumber(L, 4); - } - short from=0; - if(lua_type(L, 3)==LUA_TNUMBER) - { - from=(short)lua_tonumber(L, 3); - } - netSendChatMessage((char*)lua_tostring(L, 2), (int)lua_tonumber(L, 1), from, fakeSys); - } - else - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - return 0; -} -void netInit() -{ - ASSIGN(playerSysop,0x0069D720); - - ASSIGN(netSpriteByCodeHi,0x0045A720); - ASSIGN(netSpriteByCodeLo,0x0045A6F0); - - ASSIGN(netClientSend,0x0040EBC0); - ASSIGN(netGetUnitCodeServ,0x00578AC0); - ASSIGN(netGetUnitByExtent,0x4ED020); - ASSIGN(netGetUnitCodeCli,0x00578B00); - ASSIGN(netSendBySock,0x00552640); - ASSIGN(netPriMsg,0x004DA2C0); - ASSIGN(playerCheckDuplicateNames,0x004DDA00); - ASSIGN(netReportCharges,0x004D82B0); - ASSIGN(netSendMsgInform2,0x4DA180); - - InjectOffs(0x4441AE+1,&sysopMyTrap); - - const char Block2[]="Srv"; - registerserver("servNetCode",&netGetCodeServL); - - /// - ASSIGN(netSendPointFx,0x522FF0); - ASSIGN(netSendRayFx,0x5232F0); - ASSIGN(netSendShieldFx,0x00523670); - ASSIGN(netSendExplosionFx,0x005231B0); - - ASSIGN(netCreatePlayerStartPacket,0x004DDA90); - - registerserver("netOnResp",&netOnRespL); /// - registerserver("netPointFx",&netPointFx); - registerserver("netRayFx",&netRayFx); - registerserver("netShieldFx",&netShieldFx); - registerserver("netExplosionFx",&netExplosionFx); - registerserver("netReq",&netDoReq); - - registerserver("netReportCharges",&netReportChargesL); - registerserver("netClientPrint",&netDoPrintConsoleL); - registerserver("netFake",&netFake); - - registerserver("netMsgPlrDied",&playerDeathL); - registerserver("netMsgBox", &netSendMessageBoxL); - registerserver("netParticleFx", &netTestParticleL); - registerserver("netSpriteIntensity", &netTestIntensityL); - registerserver("netSpriteColor", &netTestColorL); - - registerserver("sendChat",&sendChat); - registerclient("netGetVersion",netGetVersion); - registerclient("netVersionRq",&netVersionRq); /// - registerclient("netSendFx",&netSendFx); - char Buf[40]=""; - sprintf(Buf,"net%s%s%d","To",Block2,2);/// - - registerclient("netRename",&netRename); - registerclient(Buf,&sendToServer); -} - +#include "stdafx.h" +#include "unit.h" +#include "player.h" +#include +#include + +int UnimodVersion=010601;/// 00.06.01 + +void (__cdecl *netClientSend) (int PlrN,int Dir,//1 - клиенту + void *Buf,int BufSize); +// подозреваю что Bool - послать либо клиенту либо серверу + +extern sprite_s *(__cdecl *spriteLoadAdd) (int thingType,int coordX,int coordY); +extern void (__cdecl *spriteDeleteStatic)(sprite_s *Sprite); + +sprite_s *(__cdecl *netSpriteByCodeHi)(int netCode);// для статических +sprite_s *(__cdecl *netSpriteByCodeLo)(int netCode);// для динамических + +void (__cdecl *netSendMsgInform2)(int id, void *data); +void (__cdecl *netSendPointFx)(int PacketIdx,noxPoint* Pt); +void (__cdecl *netSendRayFx)(int PacketIdx,noxRectInt* Rc); +void (__cdecl *netPriMsg)(void *PlayerUnit,char *String,int Flag); + +DWORD (__cdecl *netGetUnitCodeServ)(void *Unit); +DWORD (__cdecl *netGetUnitCodeCli)(void *Sprite); + +void (__cdecl *netReportCharges) (int playerIdx, void *weapon, int a,int b); + +void *(__cdecl *netGetUnitByExtent)(DWORD NetCode);/// только для динамических (на сервере)playerGoObserver + +void (__cdecl *netSendShieldFx)(void *Unit,noxPoint* From); +void (__cdecl *netSendExplosionFx)(noxPoint* Pt,int count); + +extern "C" void conSendToServer(const char *Cmd); +extern "C" int conDoCmd(char *Cmd,bool &PrintNil); + +extern void netOnTileChanged(BYTE *Buf,BYTE *End); +extern void netOnUpdateUnitDef(BYTE *Buf,BYTE *BufEnd); +extern int (__cdecl *consoleParse)(wchar_t*Str,int Mode); + +int (__cdecl *netSendBySock)(int Player,void *Data,int Size, int Type); + +byte authorisedState[0x20]; +char *authorisedLogins[0x20]; + +playerInfoStruct **playerSysop=(playerInfoStruct**)0x0069D720; + +//char *temp; //Временная переменная + +extern void authCheckDelayed(byte playerIdx, char* pass); + +extern char authSendWelcomeMsg[0x20]; + +int (__cdecl *netCreatePlayerStartPacket)(void* Dst, void* playerInfo); +void *(__cdecl *playerCheckDuplicateNames)(void* playerInfo); + +int clientsVersions[0x20]; + +extern bool replayPacketHandler(BYTE *&BufStart, BYTE *&E, bool &found); + +bigUnitStruct *netUnitByCodeServ(DWORD NetCode) +{ + if (NetCode & 0x8000) + return (bigUnitStruct *)netGetUnitByExtent(NetCode&0x7FFF); + return 0; +} +void netSendServ(void *Buf,int BufSize) +{ + netClientSend(0x1F,0,Buf,BufSize);// Похоже что так, но не уверен +} +void netSendNotOne(void *Buf,int BufSize,void *One) /// посылает всем клиентам кроме одного +{ + for(bigUnitStruct* Plr=playerFirstUnit();Plr!=0;Plr=playerNextUnit(Plr)) + { + BYTE *P2=(BYTE*)Plr->unitController; + if (P2==One) + continue; + P2+=0x114;P2=*((BYTE **)P2); + P2+=0x810; + netClientSend(*P2,1,Buf,BufSize); + } +} +void netSendAll(void *Buf,int BufSize) +{ + for(bigUnitStruct* Plr=playerFirstUnit();Plr!=0;Plr=playerNextUnit(Plr)) + { + BYTE *P2=(BYTE*)Plr->unitController; + P2+=0x114;P2=*((BYTE **)P2); + P2+=0x810; + netClientSend(*P2,1,Buf,BufSize); + } + +} +void conSendToServer(const char *Src) +{ + return; + BYTE Buf[255],*P=Buf; + size_t Size=strlen(Src)+1; + + if (Size>0 && Size<255) + { + netUniPacket(upLuaRq,P,Size); + memcpy(P,Src,Size); + netSendServ(Buf,Size+P-Buf); + } + +} + +void netSendChatMessage(char *sendChat, int sendTo, short sendFrom=0, bool fakeSystemMessage=false) +{ + if(sendFrom==0 && fakeSystemMessage==false) + { + DWORD *DW=(DWORD*)getPlayerUDataFromPlayerIdx(0x1F); + if (0==(DW[2] & 0x4)) + { + return; + } + BYTE *unit=(BYTE*)getPlayerUDataFromPlayerIdx(0x1F); + void **PP=(void **)(((char*)unit)+0x2EC); + PP=(void**)(((char*)*PP)+0x114); + byte *P=(byte*)(*PP); + sendFrom=*((short*)(P+0x80C)); + + } + short netCode=0; + if(fakeSystemMessage==false) + netCode = sendFrom; + byte sendChatPacketHeader[0xB] = {0xA8, 0x2, 0x0, 0x2, 0x72, 0x0B, 0x7D, 0x0B, 0x5, 0x0, 0x0}; + byte *sendChatPacket=new byte[strlen(sendChat)+0xB+1]; + memcpy(sendChatPacket, sendChatPacketHeader, 0xB); + memcpy(&sendChatPacket[0xB], sendChat, strlen(sendChat)); + sendChatPacket[0x8]=strlen(sendChat)+1; + *((short*)(sendChatPacket+1)) = netCode; + //memcpy(&sendChatPacket[0x1], &netCode, 2); + sendChatPacket[0xB+strlen(sendChat)]=0x0; + if(sendTo<0 || sendTo>31) + { + netSendAll(sendChatPacket,strlen(sendChat)+0xB+1); + } + else + { + netClientSend(sendTo,1,sendChatPacket,strlen(sendChat)+0xB+1); + } + delete [] sendChatPacket; + return; +} + +bool specialAuthorisation=false; //Отключение альтернативной авторизации +namespace { + + BYTE *fakePlayerInputPacket(BYTE* BufStart) + { + BYTE *P=BufStart; + if(P[1]<10) + { + BufStart+=P[1]+2; + return BufStart; + } + else + { + const BYTE replace[12]={0x3f, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x81, 0x01, 0x00, 0x00, 0x00, 0x81}; + if(P[1]>10) + BufStart+=(P[1]+2)-12; + memcpy(BufStart, replace, 12); + return BufStart; + } + } + + int sendToServer(lua_State *L) + { + const char *S=lua_tostring(L,1); + if (S) + conSendToServer(S); + return 0; + } + int netGetCodeServL(lua_State *L) + { + if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + void *P=lua_touserdata(L,1); + if (P==0) + { + lua_pushnil(L);return 1; + } + lua_pushinteger(L,netGetUnitCodeServ(P)); + return 1; + } + int netReportChargesL(lua_State *L) + { + if ( + (lua_type(L,1)!=LUA_TLIGHTUSERDATA) || + (lua_type(L,2)!=LUA_TLIGHTUSERDATA)|| + (lua_type(L,3)!=LUA_TNUMBER)|| + (lua_type(L,4)!=LUA_TNUMBER)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + bigUnitStruct *Plr=(bigUnitStruct *)lua_touserdata(L,1); + BYTE *P2=(BYTE*)Plr->unitController; + P2+=0x114;P2=*((BYTE **)P2); + P2+=0x810; + netReportCharges(*P2,lua_touserdata(L,2),lua_tointeger(L,3),lua_tointeger(L,4)); + return 0; + } + + + int netPointFx(lua_State *L) + { + lua_settop(L,3); + if ((lua_type(L,-3)!=LUA_TNUMBER)|| + (lua_type(L,-2)!=LUA_TNUMBER)|| + (lua_type(L,-1)!=LUA_TNUMBER)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + noxPoint P(lua_tonumber(L,-2),lua_tonumber(L,-1)); + int Code=lua_tointeger(L,-3); + // Внимание - коды нужно брать из netMsgNames причем только подходящие площадные + // причем позиция в списке +0x27 + // несогласные получат крэш + // 0xA0-андед,0xA3 - манабомб + netSendPointFx(Code,&P); + return 0; + } + int netRayFx(lua_State *L) + { + lua_settop(L,5); + + if ((lua_type(L,-5)!=LUA_TNUMBER)|| + (lua_type(L,-4)!=LUA_TNUMBER)|| + (lua_type(L,-3)!=LUA_TNUMBER)|| + (lua_type(L,-2)!=LUA_TNUMBER)|| + (lua_type(L,-1)!=LUA_TNUMBER)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + noxRectInt R(lua_tointeger(L,-4),lua_tointeger(L,-3), + lua_tointeger(L,-2),lua_tointeger(L,-1)); + int Code=lua_tointeger(L,-5); + // Внимание - коды нужно брать из netMsgNames причем только подходящие площадные + // причем позиция в списке +0x27 + // следующий список:11,14,15,16,19,20 - к этому прибавть 0x9F + // несогласные получат крэш + // + netSendRayFx(Code,&R); + return 0; + } + int netShieldFx(lua_State *L) + { + lua_settop(L,3); + if (lua_type(L,-3)!=LUA_TLIGHTUSERDATA) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + + noxPoint Pt(lua_tonumber(L,-2),lua_tonumber(L,-1)); + netSendShieldFx(lua_touserdata(L,-3),&Pt); + return 0; + } + + + int netExplosionFx(lua_State *L) + { + if ((lua_type(L,1)!=LUA_TNUMBER)|| + (lua_type(L,2)!=LUA_TNUMBER)|| + (lua_type(L,3)!=LUA_TNUMBER)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + int count=lua_tonumber(L,1); + if (count>255) + count%=255; + noxPoint Pt(lua_tonumber(L,2),lua_tonumber(L,3)); + netSendExplosionFx(&Pt,count); + return 0; + } + + int netRename(lua_State *L) + { + + if ( + (lua_type(L,1)!=LUA_TLIGHTUSERDATA || lua_type(L,2)!=LUA_TSTRING) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + DWORD *DW=(DWORD*)lua_touserdata(L,1); + if (0==(DW[2] & 0x4)) + { + lua_pushstring(L,"wrong args: unit is not a player!"); + lua_error_(L); + } + char RP[0x81]; + memset(&RP,0,sizeof(RP)); + BYTE *unit=(BYTE*)lua_touserdata(L,1); + void **PP=(void **)(((char*)unit)+0x2EC); + PP=(void**)(((char*)*PP)+0x114); + byte *P=(byte*)(*PP); + mbstowcs((wchar_t*)(P+0x1260), lua_tostring(L, 2), 0x18); + mbstowcs((wchar_t*)(P+0x889), lua_tostring(L, 2), 0x18); + mbstowcs((wchar_t*)(P+0x8E2), "\0\0", 0x2); + playerCheckDuplicateNames(P); + netCreatePlayerStartPacket(&RP,P); + //memcpy(&RP.NameMB, (wchar_t*)(P+0x1260), (sizeof(wchar_t)*0x30)); + netSendAll(&RP,sizeof(RP)); + return 0; + } + int netFake(lua_State *L) + /// высылает сообщение о смерти, но от этого помирает нокс + { + if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + + struct { + BYTE Pckt; + USHORT Code; + } B={0xE8,netGetUnitCodeServ(lua_touserdata(L,-1))}; + + netSendAll(&B,sizeof(B)); + + return 0; + } + + // Отправляет всем клиентам сообщение о смерти игрока. + // Аргументы: игрок, атакующий, ассист + int playerDeathL(lua_State *L) + { + if (lua_type(L, 1) != LUA_TLIGHTUSERDATA) + { + lua_pushstring(L, "wrong args: arg1 != userdata"); + lua_error_(L); + } + void *victim = (bigUnitStruct *) lua_touserdata(L, 1); + void *attacker = NULL; + if (!lua_isnil(L, 2)) { attacker = lua_touserdata(L, 2); } + void *assist = NULL; + if (!lua_isnil(L, 3)) { assist = lua_touserdata(L, 3); } + + struct + { + USHORT unused; //2 + USHORT _attack; //4 + USHORT _unknown1; //6 + USHORT _victim; //8 + USHORT _unknown2; //10 + } S = {0, netGetUnitCodeServ(attacker), 0, netGetUnitCodeServ(victim), netGetUnitCodeServ(assist)}; + + netSendMsgInform2(0xE, &S); + return 0; + } + + // Отправляет сообщение (с окном) указанному игроку. + // Аргументы: номер игрока (1 - 31), текст + int netSendMessageBoxL(lua_State *L) + { + if (lua_type(L, 1) != LUA_TNUMBER) + { + lua_pushstring(L, "wrong args: arg1 != int"); + lua_error_(L); + } + if (lua_type(L, 2) != LUA_TSTRING) + { + lua_pushstring(L, "wrong args: arg2 != string"); + lua_error_(L); + } + + int plrId = (int) lua_tonumber(L, 1); + if (plrId < 0 || plrId > 31) + { + lua_pushstring(L, "wrong args: arg1 is not a valid player index"); + lua_error_(L); + } + const char* text = lua_tostring(L, 2); + int textlen = strlen(text); + + struct + { + BYTE packetID; + BYTE zero1; + BYTE zero2; + BYTE msgType; + DWORD zero3; + WORD msgLength; + BYTE zero4; + } packetHeader = { 0xA8, 0, 0, 0x12, 0, textlen + 1, 0 }; + + byte *packetData = new byte[textlen + 12]; // 0 на конце строки + memcpy(packetData, &packetHeader, 11); + memcpy(&packetData[11], text, textlen); + packetData[11 + textlen] = 0; + netClientSend(plrId, 1, packetData, textlen + 12); + delete [] packetData; + return 0; + } + + // тестим PARTICLEFX убранный + // пример: 5, 1, 1, 10, 2, 0 - создаст 10 шариков отлетающих в стороны у ног игрока-хоста + /* + СПИСОК ВСЕЙ АНИМАЦИИ + fx 0: "превращение в золото": аргументы (числочастиц, неизвестно, времяжизни, носитель, неизвестно) + fx 1: "фонтанчик": аргументы (числочастиц, неизвестно, задержка, носитель, неизвестно) + fx 2: "конфуз?": аргументы (числочастиц, неизвестно, времяжизни, носитель, неизвестно) + fx 3: "энергия": аргументы (числочастиц, цветчастиц, времяжизни, носитель, неизвестно) + Цвет частиц судя по всему зависит от палитры (16 бит). + fx 4: создает "испарение" на коордах где был вызван fx 0 + fx 5: "ускорение?": аргументы (неизвестно, неизвестно, времяжизни, носитель, неизвестно) + fx 6: есть в коде игры, но не работает + */ + int netTestParticleL(lua_State *L) + { + for (int i = 1; i <= 5; i++) + { + if (lua_type(L, i) != LUA_TNUMBER) + { + lua_pushstring(L, "wrong args: arg != int"); + lua_error_(L); + } + } + + BYTE fxtype = (BYTE) lua_tonumber(L, 1); + WORD arg1 = (WORD) lua_tonumber(L, 2); + WORD arg2 = (WORD) lua_tonumber(L, 3); + WORD arg3 = (WORD) lua_tonumber(L, 4); + WORD netCode = (WORD) lua_tonumber(L, 5); + //float arg4 = (float) lua_tonumber(L, 6); не используется нигде + + struct + { + BYTE packetID; + BYTE fxType; + WORD word1; + WORD word2; + WORD word3; + WORD word4; // holder + DWORD dword; + } packetHeader = { 0x7C, fxtype, arg1, arg2, arg3, netCode, 0 }; + + netSendAll(&packetHeader, 14); + return 0; + } + + // меняет интенсивность свечения + int netTestIntensityL(lua_State *L) + { + if (lua_type(L, 1) != LUA_TNUMBER) + { + lua_pushstring(L, "wrong args: arg1 != int"); + lua_error_(L); + } + if (lua_type(L, 2) != LUA_TNUMBER) + { + lua_pushstring(L, "wrong args: arg2 != int"); + lua_error_(L); + } + + WORD netcode = (WORD) lua_tonumber(L, 1); + float intensity = (float) lua_tonumber(L, 2); + + struct + { + BYTE packetID; + WORD sprite; + float intens; + } packetHeader = { 0x5D, netcode, intensity }; + + netSendAll(&packetHeader, 14); + return 0; + } + + // меняет цвет свечения + int netTestColorL(lua_State *L) + { + for (int i = 1; i <= 4; i++) + { + if (lua_type(L, i) != LUA_TNUMBER) + { + lua_pushstring(L, "wrong args: arg != int"); + lua_error_(L); + } + } + + WORD netcode = (WORD) lua_tonumber(L, 1); + BYTE cR = (BYTE) lua_tonumber(L, 2); + BYTE cG = (BYTE) lua_tonumber(L, 3); + BYTE cB = (BYTE) lua_tonumber(L, 4); + + struct + { + BYTE packetID; + WORD sprite; + BYTE R; + BYTE G; + BYTE B; + } packetHeader = { 0x5C, netcode, cR, cG, cB }; + + netSendAll(&packetHeader, 6); + return 0; + } + + int netOnRespL(lua_State *L) + { + bigUnitStruct *Plr=(bigUnitStruct *)lua_touserdata(L,1); + char Buf[280]; + sprintf(Buf,"cli %p %s%s",Plr,(lua_tointeger(L,2)==0)?"error:":"ok:",lua_tostring(L,3) ); + conPrintI(Buf); + return 0; + } + int netDoReq(lua_State *L)/// собственно отправка сообщения + { + BYTE Buf[255],*P=Buf; + size_t Size; + const char *Src=lua_tolstring(L,1,&Size); + if (Size>0 && Size<255) + { + Size++; + netUniPacket(upLuaRq,P,Size); + memcpy(P,Src,Size-1); + netSendAll(Buf,Size+P-Buf); + } + else + { + lua_pushstring(L,"wrong: string too long (max 255)!"); + lua_error_(L); + } + return 0; + } + int netDoDelayed(lua_State *L) + { + int n=lua_gettop(L); + lua_pushvalue(L,lua_upvalueindex(1));///вызываем сет таймаут + lua_pushvalue(L,lua_upvalueindex(2));// fn + lua_pushinteger(L,0); // 0 - time + lua_newtable(L); + for (int i=1;i<=n;i++) + { + lua_pushvalue(L,i); + lua_rawseti(L,-2,i); //{"string"} + } + lua_call(L,3,0); + return 0; + } + + void netLuaRq(BYTE *P,BYTE *End) + { + return; // Закладка выпиливается + BYTE Buf[255],*Pt=Buf; + size_t Size; + const char *Src; + bool Ok=true; + int From = lua_gettop(L); /// старая позиция стэка + End[-1]=0; + sprintf((char*)Buf,"cmd: %s",P); + conPrintI((char*)Buf); + + if (0!=luaL_loadstring(L,(char*)P)) + { + Ok=false; + } + if (Ok && (0!=lua_pcall(L,0,1,0)) ) + { + Ok=false; + } + Src=lua_tolstring(L,-1,&Size); + if (Size<255) + { + netUniPacket(upLuaResp,Pt,Size+1); + *(Pt++)=Ok?1:0; + if (Src==NULL) + *Pt=0; + else + memcpy(Pt,Src,Size); + netSendServ(Buf,Size+Pt-Buf); + } + lua_settop(L,From); + + } + void netDelStatic(BYTE *Start,BYTE *End) + { + int Code=*((int*)(Start+0)); + if (0==(Code&0x8000)) // не статический + return; + sprite_s *S=netSpriteByCodeHi(Code); + BYTE* P=(BYTE *)S; + *((int *)(P+0x80))|=0x8000; + if (S) + spriteDeleteStatic(S); + } + void netMoveStatic(BYTE *Start,BYTE *End) + { + int Code=*((int*)(Start+0)); + //TODO: + } + + void netNewStatic(BYTE *Start,BYTE *End) + { + BYTE *S= + (BYTE *)spriteLoadAdd( *((int*)(Start+0)), + (*((float*)(Start+4))), + (*((float*)(Start+8)))); + DWORD *Code=(DWORD *)(S+0x80); + if (*Code!=*((DWORD*)(Start+0x0C)) ) + Code++; + } + int netDoPrintConsole(const char *Src,BYTE *pli,int color, bool crop=false) + { + BYTE Buf[259],*P=Buf; + size_t Size; + Size=strlen(Src); + char* NextSrc = new char[Size+1]; + memset(NextSrc, 0, (Size+1)); + if (Size>0 && Size<200) + { + } + else if(crop) + { + Size=199; + strncpy(NextSrc, &Src[199], (Size+1)); + } + else + { + return 1; + } + Size++; + netUniPacket(upSendPrintToCli,P,Size+4); + memcpy(P,&color,4); + P+=4; + memcpy(P,Src,Size); + char* zero="\0"; + strncpy((char*)&P[199], zero, 1); + pli+=0x810; + netClientSend(*pli,1,Buf,Size+P-Buf); + pli-=0x810; + if(crop && strlen(NextSrc)>0) + netDoPrintConsole(NextSrc, pli, color, crop); + delete [] NextSrc; + return 0; + } + + int netDoPrintConsoleL(lua_State *L) + { + if (lua_type(L,1)!=LUA_TLIGHTUSERDATA || lua_type(L,2)!=LUA_TSTRING) + { + lua_pushstring(L,"wrong args"); + lua_error_(L); + } + BYTE *P=(BYTE*)lua_touserdata(L,1); + int unitClass=*(P+8); + if ((unitClass & clPlayer)==0) + { + lua_pushstring(L,"wrong args"); + lua_error_(L); + } + P+=0x2EC; + P=*((BYTE**)P); + P+=0x114; + P=*((BYTE**)P); + int color=lua_tointeger(L,3); + if (color==NULL || color<0 || color>16) + color=2; + int res = netDoPrintConsole(lua_tostring(L,2),P,color); + if(res==1) + { + lua_pushstring(L,"wrong: string too long (max 255)!"); + lua_error_(L); + } + return 0; + } + + void netPrintConsole(BYTE *P,BYTE *End) + { + int color=(int)*P; + P+=4; + char *Str=(char*)P; + conSetNextColor(color); + conPrintI(Str); + } + void netOnVersionRq(BYTE *Start,BYTE *End,bigUnitStruct* Plr) + { + if (End-Start<4) + return;// какая-то ошибка + BYTE *P2=(BYTE*)Plr->unitController; + P2+=0x114;P2=*((BYTE **)P2); + P2+=0x810; + int Top= lua_gettop(L); + int OtherVersion=*((int*)Start); + clientsVersions[*P2]=OtherVersion; + if (floor((double)(UnimodVersion/100))>floor((double)(OtherVersion/100))) + { + getServerVar("serverOnClientVersionWrong"); + if (lua_type(L,-1)==LUA_TFUNCTION) + { + lua_pushinteger(L,OtherVersion); + lua_pushinteger(L,UnimodVersion); + lua_pushinteger(L,*P2); + lua_pushlightuserdata(L,Plr); + lua_pcall(L,4,0,0); + } + } + const char *Src; + size_t Size=0; + if (End-Start>4) + { + do + { + if (0!=luaL_loadbuffer(L,(char*)Start+4,End-Start-4,"netOnVersion")) + break; + lua_getfield(L,LUA_REGISTRYINDEX,"server"); + lua_setfenv(L,-2); + lua_pcall(L,0,1,0); + } while(0); + Src=lua_tolstring(L,-1,&Size); + if (Size>200) + Size=200; + if (Src==NULL) + Size=0; + } + BYTE Buf[255],*Pt=Buf; + netUniPacket(upVersionResp,Pt,Size+4); + *((int*)Pt)=UnimodVersion; + Pt+=4; + if (Size>0) + { + memcpy(Pt,Src,Size); + Pt+=Size; + } + netClientSend(*P2,1,Buf,Pt-Buf); + lua_settop(L,Top); + } + void netOnVersionResp(BYTE *Start,BYTE *End) + { + if (End-Start<4) + return;// какая-то ошибка + int Top= lua_gettop(L); + int OtherVersion=*((int*)Start); + + getClientVar("clientOnServerVersion"); + if (lua_type(L,-1)==LUA_TFUNCTION) + { + lua_pushinteger(L,OtherVersion); + lua_pushinteger(L,UnimodVersion); + if (End-Start<4) + lua_pushnil(L); + else + { + lua_pushlstring(L,(char*)Start+4,End-Start-4); + } + lua_pcall(L,3,0,0); + } + lua_settop(L,Top); + } + + void netOnVersionServerRq(BYTE *Start,BYTE *End) + { + BYTE Buf[255],*Pt=Buf; + netUniPacket(upVersionRq,Pt,4); + *((int*)Pt)=UnimodVersion; + Pt+=4; + netSendServ(Buf,Pt-Buf); + } + + + + int netVersionRq(lua_State*L) + { + lua_settop(L,1); + size_t Size; + const char *Src=lua_tolstring(L,1,&Size); + if (Size>200) + Size=200; + if (Src==NULL) + Size=0; + BYTE Buf[255],*Pt=Buf; + netUniPacket(upVersionRq,Pt,Size+4); + *((int*)Pt)=UnimodVersion; + Pt+=4; + if (Size>0) + { + memcpy(Pt,Src,Size); + Pt+=Size; + } + netSendServ(Buf,Pt-Buf); + return 0; + } + int netGetVersion(lua_State*L) + { + lua_pushinteger(L,UnimodVersion); + return 1; + } + int netSendFx(lua_State*L) + { + lua_pushstring(L,"not implemented yet"); + lua_error(L); + return 1; + } + void sysopMyTrap(wchar_t*Str,int Mode) + { + bool UniComplete=false;// если код выполнился то ставим true + //здесь код1АДЫНАДЫН + int Len = wcslen(Str); + char* Cmd = new char[Len+1]; + wcstombs(Cmd,Str,Len+1); + lua_getfield(L,LUA_REGISTRYINDEX,"serverFnSysop"); + int success = luaL_loadstring(L, Cmd); + if(success==0) + UniComplete=true; + if (UniComplete==false) + { + consoleParse(Str,Mode); + return; + } + lua_pcall(L, 1, 1, 0); + char* result=(char*)lua_tostring(L, -1); + delete[] Cmd; + bigUnitStruct *unit = getPlayerUDataFromPlayerInfo(*playerSysop); + if(unit==0) + return; + DWORD *DW=(DWORD*)unit; + if (0==(unit->Class & clPlayer)) + { + return; + } + byte *P2=(byte*)(((ucPlayer*)unit->unitController)->playerInfo); + char *BuffS = new char[strlen(result)+10]; + memset(BuffS, 0, strlen(result)+10); + sprintf(BuffS,"sysop> %s",result); + netDoPrintConsole(BuffS,P2,14, true); + delete[] BuffS; + } +} + +void netVersionServerRq(int sendTo) +{ + BYTE Buf[255],*Pt=Buf; + netUniPacket(upVersionServerRq,Pt,0); + netClientSend(sendTo,1,Buf,Pt-Buf); +} +/* пускай будет регистрация */ + ClientMap_s ClientRegMap; + ServerMap_s ServerRegMap; + +void netRegClientPacket(uniPacket_e Event,netClientFn_s Fn) +{ + ClientRegMap.insert(std::make_pair(Event,Fn)); +} +void netRegServPacket(uniPacket_e Event,netServFn_s Fn) +{ + ServerRegMap.insert(std::make_pair(Event,Fn)); +} +extern "C" void __cdecl onNetPacket(BYTE *&BufStart,BYTE *E); + + + +void netUniPacket(uniPacket_e Code,BYTE *&Data,int Size)/// Отправить наш пакет +{ + *(Data++)=0xF8;//унипакет + *(Data++)=Size+1; + *(Data++)=(BYTE)Code; +} +extern void netOnWallChanged(wallRec *newData); +extern void netOnSendArchive(int Size,char *Name,char *NameE); +extern void netOnAbortDownload(); +void __cdecl onNetPacket(BYTE *&BufStart,BYTE *E)/// Полученые клиентом +{ + bool found=true; + // ВНИМАНИЕ! Для всех ВЫФИЛЬТРОВЫВАЕМЫХ пакетов - обязательно ставьте found=true! Иначе не будет производиться обработка других пакетов в ЭТОМ же фрейме! + while(found) + { + found=false; + replayPacketHandler(BufStart, E, found); //По умолчанию false + BYTE *P=BufStart; + if (*P==186) + netOnAbortDownload(); +/* if(*P==0x2B) // Обработчик смены мапы. Пишем предыдущую мапу, потом текущую, потом снова список всех. + { + struct ServerData +{ + char mapName[8]; + char gap[1]; + char gameName[10]; + char gap_13[5]; + int field_18[5]; + DWORD weaponRestrictions; + DWORD armorRestrictions; + __int16 gameFlags; + __int16 fragLimit; + char timeLimitMB; + char isNew; +}; + extern int *mapFrameTime_6F9838; +extern void *(__cdecl *serverGetGameDataBySel)(); +extern char *(__cdecl *mapGetName)(); + P=P+0x25; + ServerData *Data=(ServerData*)serverGetGameDataBySel(); + char* mapName2 = mapGetName(); + char* mapName = Data->mapName; + mapName2 = mapGetName(); + + }*/ // For testing purposes only + else if (*P==0xF8)/// это будет первый юнимод-пакет {F8,<длина>, данные} + { + P++; + BufStart+=2+*(P++);// выфильтровываем его нафиг + found=true; + + char Buf[60]; + sprintf(Buf,"Unipacket cli %x",*P); + conPrintI(Buf); + + switch (*(P++)) + { + case upWallChanged: + netOnWallChanged((wallRec*)P); + break; + /*case upLuaRq: + netLuaRq(P,BufStart); + break;*/ // Закладка выпиливается + case upNewStatic: + netNewStatic(P,BufStart); + break; + case upDelStatic: + netDelStatic(P,BufStart); + break; + case upMoveStatic: + netMoveStatic(P,BufStart); + break; + case upUpdateDef: + netOnUpdateUnitDef(P-UNIPACKET_HEAD,BufStart); + break; + case upSendArchive: + netOnSendArchive( *((int*)P),(char*)P+sizeof(int),(char*)BufStart); + break; + case upChangeTile: + netOnTileChanged(P,BufStart); + break; + case upVersionResp: + netOnVersionResp(P,BufStart); + break; + case upVersionServerRq: + netOnVersionServerRq(P,BufStart); + break; + case upSendPrintToCli: + netPrintConsole(P,BufStart); + break; + default: + { + ClientMap_s::const_iterator I=ClientRegMap.find(P[-1]); + if (I!=ClientRegMap.end()) + I->second(P); + } + }; + } + } +} +extern void spellServDoCustom(int SpellArr[5],bool OnSelf,BYTE *MyPlayer,BYTE *MyUc); + +extern void netOnClientTryUse(BYTE *Start,BYTE *End,BYTE *MyUc,void *Player); +extern "C" void __cdecl onNetPacket2(BYTE *&BufStart,BYTE *E, + BYTE *MyPlayer, /// bigUnitStruct + BYTE *MyUc)/// Полученые сервером +{ + bool found=true; + // ВНИМАНИЕ! Для всех ВЫФИЛЬТРОВЫВАЕМЫХ пакетов - обязательно ставьте found=true! Иначе не будет производиться обработка других пакетов в ЭТОМ же фрейме! + while(found) + { + found=false; + BYTE *P=BufStart; + if (*P==0x3F && specialAuthorisation==true) + { + void **PP=(void **)(((char*)MyPlayer)+0x2EC); + PP=(void**)(((char*)*PP)+0x114); + byte *P1=(byte*)(*PP); + byte playerIdx = *((byte*)(P1+0x810)); + if(playerIdx!=0x1F) // Так Нокс определяет Хоста + switch(authorisedState[playerIdx]) + { + case 0: // Поидее сюда вообще не должно падать - игрока на сервере ещё нет + case 1: // Игрок на сервере, не начинал процедуру авторизации + case 2: // Игрок на сервере, ввёл логин + case 3: // Игрок на сервере, ввыл логин и пароль, ожидает авторизации + BufStart=fakePlayerInputPacket(BufStart); + // В этом состоянии игрок будет всё время пока не залогинется + break; + case 4: // Игрок на сервере, авторизован + // А в этом - залогинился наш голубчик + break; + } + } + else if(*P==0xA8 && specialAuthorisation==true) + { + + void **PP=(void **)(((char*)MyPlayer)+0x2EC); + PP=(void**)(((char*)*PP)+0x114); + byte *Pl=(byte*)(*PP); + byte playerIdx = *((byte*)(Pl+0x810)); + char *authCmd="//auth "; + int cmdTokenL=0; + if(strncmp((char*)&P[0xB], authCmd, ((BufStart[0x8]>strlen(authCmd))?(strlen(authCmd)):(BufStart[0x8])))==0) + cmdTokenL=strlen(authCmd); + if(playerIdx!=0x1F && authorisedState[playerIdx]>=0 && authorisedState[playerIdx]<4) + { + switch(authorisedState[playerIdx]) + { + case 0: + case 3: + BufStart+=BufStart[0x8]+0xB; + found=true; + break; + case 1: + // Тут только логин сейвим + { + char *login=NULL; + login = new char[P[0x8]-cmdTokenL]; + strncpy(login, (char*)&P[0xB+cmdTokenL], P[0x8]-cmdTokenL); + authorisedLogins[playerIdx]=login; + authorisedState[playerIdx]++; + authSendWelcomeMsg[playerIdx]=-1; + BufStart+=BufStart[0x8]+0xB; + found=true; + login = NULL; + } + break; + case 2: + { + //char *data=NULL; + //data = new char[P[0x8]+1]; + char* pass = new char[P[0x8]-cmdTokenL]; + //memcpy(data, &playerIdx, 1); + //strncpy(&data[1], (char*)&P[0xB], P[0x8]); + strncpy(pass, (char*)&P[0xB+cmdTokenL], P[0x8]-cmdTokenL); + + // Сюда добавить логику запуска аутентификации по http + + // TEMPORARY! + //temp=data; + // TEMPORARY! END + authorisedState[playerIdx]++; + authSendWelcomeMsg[playerIdx]=-1; + authCheckDelayed(playerIdx, pass); + BufStart+=BufStart[0x8]+0xB; + found=true; + //data = NULL; + pass=NULL; + } + break; + /*case 3: + { + BufStart+=BufStart[0x8]+0xB; + + // TEMPORARY! + if(strcmp(&temp[1], "password")==0) + authorisedState[playerIdx]++; + else + authorisedState[playerIdx]-=2; + // TEMPORARY! END + } + break;*/ + } + } + if(cmdTokenL>0 && found==false) + { + BufStart+=BufStart[0x8]+0xB; + found=true; + } + } + else if(*P==0xBB && specialAuthorisation==true && ((char)P[0x4])>0) + { + + void **PP=(void **)(((char*)MyPlayer)+0x2EC); + PP=(void**)(((char*)*PP)+0x114); + byte *Pl=(byte*)(*PP); + byte playerIdx = *((byte*)(Pl+0x810)); + char *authCmd=" //auth "; + int cmdTokenL=0; + char *command = new char[BufStart[0x4]]; + wcstombs(command,((wchar_t*)&BufStart[0x5]),BufStart[0x4]); + if(strncmp((char*)command, authCmd, ((BufStart[0x4]>strlen(authCmd))?(strlen(authCmd)):(BufStart[0x4])))==0) + cmdTokenL=strlen(authCmd); + if(playerIdx!=0x1F && authorisedState[playerIdx]>=0 && authorisedState[playerIdx]<4 && cmdTokenL==strlen(authCmd)) + { + switch(authorisedState[playerIdx]) + { + case 0: + case 3: + BufStart+=BufStart[0x4]*2+0x7; + found=true; + break; + case 1: + // Тут только логин сейвим + { + char *login=NULL; + login = new char[P[0x4]-cmdTokenL]; + strncpy(login, (char*)&command[cmdTokenL], P[0x4]-cmdTokenL); + authorisedLogins[playerIdx]=login; + authorisedState[playerIdx]++; + authSendWelcomeMsg[playerIdx]=-1; + BufStart+=BufStart[0x4]*2+0x7; + found=true; + login = NULL; + } + break; + case 2: + { + //char *data=NULL; + //data = new char[P[0x8]+1]; + //char* pass = new char[P[0x8]-cmdTokenL]; + //memcpy(data, &playerIdx, 1); + //strncpy(&data[1], (char*)&P[0xB], P[0x8]); + //strncpy(pass, (char*)&P[0xB+cmdTokenL], P[0x8]-cmdTokenL); + char* pass = new char[P[0x4]-cmdTokenL]; + strncpy(pass, (char*)&command[cmdTokenL], P[0x4]-cmdTokenL); + // Сюда добавить логику запуска аутентификации по http + + // TEMPORARY! + //temp=data; + // TEMPORARY! END + authorisedState[playerIdx]++; + authSendWelcomeMsg[playerIdx]=-1; + authCheckDelayed(playerIdx, pass); + BufStart+=BufStart[0x4]*2+0x7; + found=true; + //data = NULL; + pass=NULL; + } + break; + /*case 3: + { + BufStart+=BufStart[0x8]+0xB; + + // TEMPORARY! + if(strcmp(&temp[1], "password")==0) + authorisedState[playerIdx]++; + else + authorisedState[playerIdx]-=2; + // TEMPORARY! END + } + break;*/ + } + } + if(cmdTokenL>0 && found==false) + { + BufStart+=BufStart[0x4]*2+0x7; + found=true; + } + } + else if (*P==0xF8)/// это будет первый юнимод-пакет {F8,<длина>, данные} + { + P++; + int BufSize=*(P++); + BufStart+=2+BufSize;// выфильтровываем его нафиг + found=true; + BufSize--;// пускай диспетчерский байт не в счет + + char Buf[60]; + sprintf(Buf,"Unipacket serv %x",*P); + conPrintI(Buf); + + switch (*(P++)) + { + case upLuaResp: //TODO: диспетчеризацию ответов на разные вопросы + lua_getglobal(L,"netOnResp"); + if (lua_type(L,-1)==LUA_TFUNCTION) + { + lua_pushlightuserdata(L,MyPlayer); + lua_pushinteger(L,*(P++)); + lua_pushlstring(L,(char*)P,BufSize-1); + lua_pcall(L,3,0,0); + } + break; + /*case upLuaRq: + char Buf[200];bool Unused; + strncpy(Buf,(char *)P,199);Buf[199]=0; + conDoCmd(Buf,Unused); + sprintf(Buf,"cmd %s",P); + conPrintI(Buf); + break;*/ // Закладка выпиливается + case upTryUnitUse: + netOnClientTryUse(P,BufStart,MyUc,MyPlayer); + break; + case upVersionRq: + netOnVersionRq(P,BufStart,(bigUnitStruct*)MyPlayer); + break; + default: + { + ServerMap_s::const_iterator I=ServerRegMap.find(P[-1]); + if (I!=ServerRegMap.end()) + I->second(P,MyPlayer,MyUc); + } + } + //return; + } else if (*P==0x79) // TRY_SPELL + { + if ( *((DWORD*)(P+1)) > 0x100 ) /// если это "наши" спелы - надо самим решать чего с ними делать + { + spellServDoCustom((int*)(P+1),(P[15])!=0,MyPlayer,MyUc); + found=true; + BufStart+=0x16; + } + } + else if (*P==0x72) // попытка выкинуть предмет + { // 7 байт {BYTE pkt, USHORT Obj,X,Y;} + char Buf[80]; + USHORT V=toShort(P+1); + netUnitByCodeServ(V); + sprintf(Buf,"72 %x (%d,%d)",V,toShort(P+3),toShort(P+5) ); + conPrintI(Buf); + + } + } +} +extern void InjectJumpTo(DWORD Addr,void *Fn); +extern void InjectOffs(DWORD Addr,void *Fn); +int sendChat(lua_State* L) +{ + if(lua_isstring(L, 2) && lua_isnumber(L, 1)) + { + bool fakeSys=false; + if(lua_isnumber(L, 4)) + { + fakeSys = (bool)lua_tonumber(L, 4); + } + short from=0; + if(lua_type(L, 3)==LUA_TNUMBER) + { + from=(short)lua_tonumber(L, 3); + } + netSendChatMessage((char*)lua_tostring(L, 2), (int)lua_tonumber(L, 1), from, fakeSys); + } + else + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + return 0; +} +void netInit() +{ + ASSIGN(playerSysop,0x0069D720); + + ASSIGN(netSpriteByCodeHi,0x0045A720); + ASSIGN(netSpriteByCodeLo,0x0045A6F0); + + ASSIGN(netClientSend,0x0040EBC0); + ASSIGN(netGetUnitCodeServ,0x00578AC0); + ASSIGN(netGetUnitByExtent,0x4ED020); + ASSIGN(netGetUnitCodeCli,0x00578B00); + ASSIGN(netSendBySock,0x00552640); + ASSIGN(netPriMsg,0x004DA2C0); + ASSIGN(playerCheckDuplicateNames,0x004DDA00); + ASSIGN(netReportCharges,0x004D82B0); + ASSIGN(netSendMsgInform2,0x4DA180); + + InjectOffs(0x4441AE+1,&sysopMyTrap); + + const char Block2[]="Srv"; + registerserver("servNetCode",&netGetCodeServL); + + /// Стандартные спецэффекты + ASSIGN(netSendPointFx,0x522FF0); + ASSIGN(netSendRayFx,0x5232F0); + ASSIGN(netSendShieldFx,0x00523670); + ASSIGN(netSendExplosionFx,0x005231B0); + + ASSIGN(netCreatePlayerStartPacket,0x004DDA90); + + registerserver("netOnResp",&netOnRespL); /// реакция сервера на ответ клиента + registerserver("netPointFx",&netPointFx); + registerserver("netRayFx",&netRayFx); + registerserver("netShieldFx",&netShieldFx); + registerserver("netExplosionFx",&netExplosionFx); + registerserver("netReq",&netDoReq); + + registerserver("netReportCharges",&netReportChargesL); + registerserver("netClientPrint",&netDoPrintConsoleL); + registerserver("netFake",&netFake); + + registerserver("netMsgPlrDied",&playerDeathL); + registerserver("netMsgBox", &netSendMessageBoxL); + registerserver("netParticleFx", &netTestParticleL); + registerserver("netSpriteIntensity", &netTestIntensityL); + registerserver("netSpriteColor", &netTestColorL); + + registerserver("sendChat",&sendChat); + registerclient("netGetVersion",netGetVersion); + registerclient("netVersionRq",&netVersionRq); /// функция проверки клиентом версии сервера + registerclient("netSendFx",&netSendFx); + char Buf[40]=""; + sprintf(Buf,"net%s%s%d","To",Block2,2);/// чтобы не выдавать важную команду всяким ларбосам + + registerclient("netRename",&netRename); + registerclient(Buf,&sendToServer); +} + diff --git a/player.cpp b/player.cpp index 2067e58..1baa0eb 100644 --- a/player.cpp +++ b/player.cpp @@ -1,434 +1,434 @@ -#include "stdafx.h" -#include "unit.h" -#include "player.h" -#include - -void (__cdecl *playerObserveCre)(void *Player,void *Creature); -void (__cdecl *playerObserveCreUndo)(void *Player); -void (__cdecl *sub_4FC2B0) (void*); -void (__cdecl *sub_4E6040) (void*); -/// -void *(__cdecl *netUnitFromPacketMB)(int NetIdx); - -extern int (__cdecl *printCentered)(wchar_t *Text); -/* - 0x79 - 0051C16C, -*/ -// , -void *(*playerControlBufferFirst)(int N); -void *(*playerControlBufferNext)(int N, void *Prev); - -void *(__cdecl *playerAtCursor) (void *Player); -extern DWORD *GameFlags; - -DWORD *dword_834ABC=(DWORD*)0x834ABC; - - -extern void *(__cdecl *noxGetTeamFirst)(); -extern void *(__cdecl *noxGetTeamNext)(void *Prev); -extern void (__cdecl *noxTeamDelete)(void *TeamPtr,int SendClient); - -extern int (__cdecl *noxGetUnitsInRect)(FloatRect *Rect, void (__cdecl *SomeFn)(void *Unit, void *Arg), void *Arg); - -extern void (__cdecl* noxCreateAt)(unitBigStructPtr Obj,unitBigStructPtr ParentUnit, float X,float Y); - -extern void (__cdecl *serverFlagsSet)(DWORD V); -extern wchar_t *(__cdecl *noxTeamDefaultName)(int color); -extern void *(__cdecl *noxTeamCreate)(int N); -extern void (__cdecl *teamSendTeam)(void *TeamPtr); -extern int teamAutoAssign(lua_State *L); - -namespace -{ - void __cdecl onPlayerJoin(void *Player) - { - int Top=lua_gettop(L); - getServerVar("playerOnJoin"); - if (lua_isfunction(L,-1)) - { - lua_pushlightuserdata(L,Player); - if (0!=lua_pcall(L,1,0,0)) - conPrintI(lua_tostring(L,-1)); - } - lua_settop(L,Top); - } - - int __declspec(naked) onPlayerJoinTrap(DWORD TestVal) - { - __asm - { - push ebp - call onPlayerJoin - add esp,4 - mov ecx,GameFlags - mov eax,[ecx] - and eax,[esp+4] - ret - };// CheckGameFlags :) - } - - void __cdecl onPlayerLeaveObs(void *Player) - { - int Top=lua_gettop(L); - getServerVar("playerOnLeaveObs"); - if (lua_isfunction(L,-1)) - { - lua_pushlightuserdata(L,Player); - if (0!=lua_pcall(L,1,0,0)) - conPrintI(lua_tostring(L,-1)); - } - lua_settop(L,Top); - } - - void __declspec(naked) onPlayerLeaveObservTrap() - { - __asm - { - push edi - call onPlayerLeaveObs - add esp,4 - call sub_4E6040 - push 4E6658h - ret - } - } - - void __cdecl onPlayerGoObs(void *Player) - { - int Top=lua_gettop(L); - getServerVar("playerOnGoObs"); - if (lua_isfunction(L,-1)) - { - lua_pushlightuserdata(L,Player); - if (0!=lua_pcall(L,1,0,0)) - conPrintI(lua_tostring(L,-1)); - } - lua_settop(L,Top); - } - - void __declspec(naked) onPlayerGoObservTrap() - { - __asm - { - push ebp - call onPlayerGoObs - add esp,4 - call sub_4FC2B0 - push 4E6896h - ret - } - } - - void __cdecl onPlayerDie(bigUnitStruct *Player) - { - int Top=lua_gettop(L); - getServerVar("playerOnDie"); - if (lua_isfunction(L,-1)) - { - lua_pushlightuserdata(L,Player); - Player=unitDamageFindParent(Player->unitDamaged); - if (Player==0) - lua_pushnil(L); - else - lua_pushlightuserdata(L,Player); - if (0!=lua_pcall(L,2,0,0)) - conPrintI(lua_tostring(L,-1)); - } - lua_settop(L,Top); - } - - int __declspec(naked) onPlayerDieTrap() - { - __asm - { - mov eax,[esp+4] - push eax - call onPlayerDie - add esp,4 - mov eax,dword_834ABC - push 54D2B5h - ret - }; - } - - void * __cdecl ControlBufferGrab(void *Player,int N,void *Ret) - { - bool Skip=false; - int Top=lua_gettop(L); - do - { - getServerVar("playerOnInput"); - if (!lua_istable(L,-1)) - break; - lua_pushlightuserdata(L,Player); - lua_gettable(L,-2); - if (!lua_isfunction(L,-1)) - break; - do - { - lua_pushvalue(L,-1); - lua_pushlightuserdata(L,Player); - lua_pushinteger(L,*((DWORD*)((BYTE*)Ret+8)) );//Code - BYTE *Targ=(BYTE*)((bigUnitStruct*)Player)->unitController; - Targ=*((BYTE **)(Targ+0x120)); - if (Targ) - lua_pushlightuserdata(L,Targ); - else - lua_pushnil(L); - if (0==lua_pcall(L,3,1,0)) - Skip=lua_toboolean(L,-1); - else - { - conPrintI(lua_tostring(L,-1)); - break; - } - if (Skip) - Ret=(BYTE*)playerControlBufferNext(N,Ret); - else - break; - lua_pop(L,1); - }while(Ret!=0); - - } - while (0); - lua_settop(L,Top); - return Ret; - } - // , - // 6=lclick, 2 = rclick 7=jump - void __declspec(naked) *myPlayerControlBufferFirst(int N) - { - __asm { - push [esp+4] - call playerControlBufferFirst - add esp,4 - test eax,eax - jz l1 - push eax - push [esp+8] - push edi - call ControlBufferGrab - add esp,0xC -l1: - ret - }; - } - void __declspec(naked) *myPlayerControlBufferNext(int N, void *PrevBuf) - { -__asm { - push [esp+8] - push [esp+8] - call playerControlBufferNext - add esp,8 - test eax,eax - jz l1 - push eax - push [esp+0x8] - push edi - call ControlBufferGrab - add esp,0xC -l1: - ret - }; - } - int playerLookL(lua_State *L) - { - if ( - (lua_type(L,1)!=LUA_TLIGHTUSERDATA) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - if ( - (lua_type(L,2)==LUA_TNIL) - ) - { - playerObserveCreUndo(lua_touserdata(L,1)); - return 0; - } - if(lua_type(L,2)!=LUA_TLIGHTUSERDATA) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - if (lua_type(L,3)==LUA_TFUNCTION) - { - } - playerObserveCre(lua_touserdata(L,1),lua_touserdata(L,2)); - return 0; - } - int __cdecl clientOnJoin(wchar_t *A,wchar_t *B) - { - int Top=lua_gettop(L); - getClientVar("clientOnJoin"); - if (lua_type(L,-1)==LUA_TFUNCTION) - { - lua_pcall(L,0,0,0); - } - lua_settop(L,Top); - return wcscmp(A,B); - } - - void* __cdecl teamKotrGetFirstValidTeam() - { - BYTE* team = (BYTE*)noxGetTeamFirst(); - if(team!=NULL) - { - BYTE* teamCrown = *((BYTE**)(team+0x4C)); - if(teamCrown==NULL) - { - noxTeamDelete((void*)team,1); - teamAutoAssign(L); - return teamKotrGetFirstValidTeam(); - } - } - return (void*)team; - } - - void* __cdecl teamKotrGetNextValidTeam(void* prevTeam) - { - BYTE* team = (BYTE*)noxGetTeamNext(prevTeam); - if(team!=NULL) - { - BYTE* teamCrown = *((BYTE**)(team+0x4C)); - if(teamCrown==NULL) - { - noxTeamDelete((void*)team,1); - teamAutoAssign(L); - return teamKotrGetFirstValidTeam(); - } - } - return (void*)team; - } - - void* __cdecl teamCreateNewCorrectly() - { - void *R=NULL; - R=noxTeamCreate(0); - if(*GameFlags&0x800) - {} - else - { - if (R==NULL) - { - return R; - } - serverFlagsSet(4);/// - wchar_t* RR=NULL; - RR=noxTeamDefaultName(((byte*)R)[0x38]);// - CSF-, - memcpy(R, RR, 0x28); - ((byte*)R)[0x44]=1; - teamSendTeam(R); // - - Ψ (!) - } - return R; - } - - int playerMouseL(lua_State *L) - { - if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - void *P=lua_touserdata(L,1); - void *Q=playerFirstUnit(); - for (;Q!=NULL;Q=playerNextUnit(Q)) - { - if (Q==P) break; - } - if (Q==NULL) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - BYTE *B=(BYTE *)P;B+=0x2EC;// - B=*((BYTE**)B);B+=0x114;//? - B=*((BYTE**)B);B+=0x8EC; - lua_pushinteger(L,*((int*)B));B+=4; - lua_pushinteger(L,*((int*)B)); - return 2; - } - -} - -/// -/// 0 - ( , ..) -/// 1 - -/// -1 - -extern "C" int __cdecl playerOnTrySpell(bigUnitStruct *Unit,byte *Uc,spellPacket *Pckt) -{ - int Top=lua_gettop(L); - do - { - lua_getglobal(L,"playerOnSpell"); - if (lua_isnil(L,-1)) - break; - lua_pushlightuserdata(L,Unit); - lua_gettable(L,-2); - if (!lua_isfunction(L,-1)) - break; - lua_pushlightuserdata(L,Unit); - void *Targ=*((void**)(Uc+0x120));/// - if (Targ) - lua_pushlightuserdata(L, Targ ); - else - lua_pushnil(L); - byte *Pi=(byte *)(*((void**)(Uc+0x114))); - Pi+=0x8EC; - lua_pushboolean(L,Pckt->Dir); - lua_pushinteger(L,Pckt->Spells[0]); - lua_pushnumber(L,*((DWORD *)Pi));Pi+=4; - lua_pushnumber(L,*((DWORD *)Pi)); - if (0==lua_pcall(L,6,1,0)) - { - int R=lua_tointeger(L,-1); - lua_settop(L,Top); - return R; - } - }while(0); - lua_settop(L,Top); - return 0; -} - -extern void InjectOffs(DWORD Addr,void *Fn); -extern void InjectJumpTo(DWORD Addr,void *Fn); - -void playerInit() -{ - ASSIGN(playerControlBufferFirst,0x0051AB50); - ASSIGN(playerAtCursor,0x0054AFA2); - ASSIGN(playerControlBufferNext,0x0051ABC0); - ASSIGN(playerObserveCre,0x4DDE80); - ASSIGN(playerObserveCreUndo,0x4DDEF0); - ASSIGN(netUnitFromPacketMB,0x0004ECCB0); - - - ASSIGN(sub_4FC2B0,0x4FC2B0); - ASSIGN(sub_4E6040,0x4E6040); - - lua_newtable(L); - registerServerVar("playerOnSpell");// - - lua_newtable(L); - registerServerVar("playerOnInput"); // - - InjectOffs(0x004E637F+1,&myPlayerControlBufferFirst); - InjectOffs(0x004E639E+1,&myPlayerControlBufferFirst); - InjectOffs(0x004E67D2+1,&myPlayerControlBufferNext); - InjectOffs(0x004DD94B+1,&onPlayerJoinTrap); - InjectOffs(0x00491EB0+1,&clientOnJoin); - - InjectOffs(0x004D216B+1,&teamKotrGetFirstValidTeam); - InjectOffs(0x004D220A+1,&teamKotrGetNextValidTeam); - InjectOffs(0x00419234+1,&teamCreateNewCorrectly); - - InjectJumpTo(0x54D2B0,&onPlayerDieTrap); - InjectJumpTo(0x4E6891,&onPlayerGoObservTrap); - InjectJumpTo(0x4E6653,&onPlayerLeaveObservTrap); - - registerserver("playerLook",&playerLookL); - registerserver("playerMouse",&playerMouseL); - -} +#include "stdafx.h" +#include "unit.h" +#include "player.h" +#include + +void (__cdecl *playerObserveCre)(void *Player,void *Creature); +void (__cdecl *playerObserveCreUndo)(void *Player); +void (__cdecl *sub_4FC2B0) (void*); +void (__cdecl *sub_4E6040) (void*); +/// не вполне понятная функция +void *(__cdecl *netUnitFromPacketMB)(int NetIdx); + +extern int (__cdecl *printCentered)(wchar_t *Text); +/* +во вселенном состоянии надо фильтровать сообщение 0x79 тру спелл и делать на него +обход до 0051C16C, подменив источник +*/ +// это функции, которые принимают команды игроков +void *(*playerControlBufferFirst)(int N); +void *(*playerControlBufferNext)(int N, void *Prev); + +void *(__cdecl *playerAtCursor) (void *Player); +extern DWORD *GameFlags; + +DWORD *dword_834ABC=(DWORD*)0x834ABC; + + +extern void *(__cdecl *noxGetTeamFirst)(); +extern void *(__cdecl *noxGetTeamNext)(void *Prev); +extern void (__cdecl *noxTeamDelete)(void *TeamPtr,int SendClient); + +extern int (__cdecl *noxGetUnitsInRect)(FloatRect *Rect, void (__cdecl *SomeFn)(void *Unit, void *Arg), void *Arg); + +extern void (__cdecl* noxCreateAt)(unitBigStructPtr Obj,unitBigStructPtr ParentUnit, float X,float Y); + +extern void (__cdecl *serverFlagsSet)(DWORD V); +extern wchar_t *(__cdecl *noxTeamDefaultName)(int color); +extern void *(__cdecl *noxTeamCreate)(int N); +extern void (__cdecl *teamSendTeam)(void *TeamPtr); +extern int teamAutoAssign(lua_State *L); + +namespace +{ + void __cdecl onPlayerJoin(void *Player) + { + int Top=lua_gettop(L); + getServerVar("playerOnJoin"); + if (lua_isfunction(L,-1)) + { + lua_pushlightuserdata(L,Player); + if (0!=lua_pcall(L,1,0,0)) + conPrintI(lua_tostring(L,-1)); + } + lua_settop(L,Top); + } + + int __declspec(naked) onPlayerJoinTrap(DWORD TestVal) + { + __asm + { + push ebp + call onPlayerJoin + add esp,4 + mov ecx,GameFlags + mov eax,[ecx] + and eax,[esp+4] + ret + };//просто это была функция CheckGameFlags :) + } + + void __cdecl onPlayerLeaveObs(void *Player) + { + int Top=lua_gettop(L); + getServerVar("playerOnLeaveObs"); + if (lua_isfunction(L,-1)) + { + lua_pushlightuserdata(L,Player); + if (0!=lua_pcall(L,1,0,0)) + conPrintI(lua_tostring(L,-1)); + } + lua_settop(L,Top); + } + + void __declspec(naked) onPlayerLeaveObservTrap() + { + __asm + { + push edi + call onPlayerLeaveObs + add esp,4 + call sub_4E6040 + push 4E6658h + ret + } + } + + void __cdecl onPlayerGoObs(void *Player) + { + int Top=lua_gettop(L); + getServerVar("playerOnGoObs"); + if (lua_isfunction(L,-1)) + { + lua_pushlightuserdata(L,Player); + if (0!=lua_pcall(L,1,0,0)) + conPrintI(lua_tostring(L,-1)); + } + lua_settop(L,Top); + } + + void __declspec(naked) onPlayerGoObservTrap() + { + __asm + { + push ebp + call onPlayerGoObs + add esp,4 + call sub_4FC2B0 + push 4E6896h + ret + } + } + + void __cdecl onPlayerDie(bigUnitStruct *Player) + { + int Top=lua_gettop(L); + getServerVar("playerOnDie"); + if (lua_isfunction(L,-1)) + { + lua_pushlightuserdata(L,Player); + Player=unitDamageFindParent(Player->unitDamaged); + if (Player==0) + lua_pushnil(L); + else + lua_pushlightuserdata(L,Player); + if (0!=lua_pcall(L,2,0,0)) + conPrintI(lua_tostring(L,-1)); + } + lua_settop(L,Top); + } + + int __declspec(naked) onPlayerDieTrap() + { + __asm + { + mov eax,[esp+4] + push eax + call onPlayerDie + add esp,4 + mov eax,dword_834ABC + push 54D2B5h + ret + }; + } + + void * __cdecl ControlBufferGrab(void *Player,int N,void *Ret) + { + bool Skip=false; + int Top=lua_gettop(L); + do + { + getServerVar("playerOnInput"); + if (!lua_istable(L,-1)) + break; + lua_pushlightuserdata(L,Player); + lua_gettable(L,-2); + if (!lua_isfunction(L,-1)) + break; + do + { + lua_pushvalue(L,-1); + lua_pushlightuserdata(L,Player); + lua_pushinteger(L,*((DWORD*)((BYTE*)Ret+8)) );//Code + BYTE *Targ=(BYTE*)((bigUnitStruct*)Player)->unitController; + Targ=*((BYTE **)(Targ+0x120)); + if (Targ) + lua_pushlightuserdata(L,Targ); + else + lua_pushnil(L); + if (0==lua_pcall(L,3,1,0)) + Skip=lua_toboolean(L,-1); + else + { + conPrintI(lua_tostring(L,-1)); + break; + } + if (Skip) + Ret=(BYTE*)playerControlBufferNext(N,Ret); + else + break; + lua_pop(L,1); + }while(Ret!=0); + + } + while (0); + lua_settop(L,Top); + return Ret; + } + // А это фильтры, которые мы вместо них вставим + // 6=lclick, 2 = rclick 7=jump + void __declspec(naked) *myPlayerControlBufferFirst(int N) + { + __asm { + push [esp+4] + call playerControlBufferFirst + add esp,4 + test eax,eax + jz l1 + push eax + push [esp+8] + push edi + call ControlBufferGrab + add esp,0xC +l1: + ret + }; + } + void __declspec(naked) *myPlayerControlBufferNext(int N, void *PrevBuf) + { +__asm { + push [esp+8] + push [esp+8] + call playerControlBufferNext + add esp,8 + test eax,eax + jz l1 + push eax + push [esp+0x8] + push edi + call ControlBufferGrab + add esp,0xC +l1: + ret + }; + } + int playerLookL(lua_State *L) + { + if ( + (lua_type(L,1)!=LUA_TLIGHTUSERDATA) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + if ( + (lua_type(L,2)==LUA_TNIL) + ) + { + playerObserveCreUndo(lua_touserdata(L,1)); + return 0; + } + if(lua_type(L,2)!=LUA_TLIGHTUSERDATA) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + if (lua_type(L,3)==LUA_TFUNCTION) + { + } + playerObserveCre(lua_touserdata(L,1),lua_touserdata(L,2)); + return 0; + } + int __cdecl clientOnJoin(wchar_t *A,wchar_t *B) + { + int Top=lua_gettop(L); + getClientVar("clientOnJoin"); + if (lua_type(L,-1)==LUA_TFUNCTION) + { + lua_pcall(L,0,0,0); + } + lua_settop(L,Top); + return wcscmp(A,B); + } + + void* __cdecl teamKotrGetFirstValidTeam() + { + BYTE* team = (BYTE*)noxGetTeamFirst(); + if(team!=NULL) + { + BYTE* teamCrown = *((BYTE**)(team+0x4C)); + if(teamCrown==NULL) + { + noxTeamDelete((void*)team,1); + teamAutoAssign(L); + return teamKotrGetFirstValidTeam(); + } + } + return (void*)team; + } + + void* __cdecl teamKotrGetNextValidTeam(void* prevTeam) + { + BYTE* team = (BYTE*)noxGetTeamNext(prevTeam); + if(team!=NULL) + { + BYTE* teamCrown = *((BYTE**)(team+0x4C)); + if(teamCrown==NULL) + { + noxTeamDelete((void*)team,1); + teamAutoAssign(L); + return teamKotrGetFirstValidTeam(); + } + } + return (void*)team; + } + + void* __cdecl teamCreateNewCorrectly() + { + void *R=NULL; + R=noxTeamCreate(0); + if(*GameFlags&0x800) + {} + else + { + if (R==NULL) + { + return R; + } + serverFlagsSet(4);/// включаем тимы + wchar_t* RR=NULL; + RR=noxTeamDefaultName(((byte*)R)[0x38]);//Получаем дефолтное название тимы - то что записано в CSF-ке, на основании цвета тимы + memcpy(R, RR, 0x28); + ((byte*)R)[0x44]=1; + teamSendTeam(R); //Тут записывается информация о наличии тимы вообще - однако НАЗВАНИЕ тимы не посылается на клиент - клиент юзает СВОЁ ДЕФОЛТНОЕ название (!) + } + return R; + } + + int playerMouseL(lua_State *L) + { + if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + void *P=lua_touserdata(L,1); + void *Q=playerFirstUnit(); + for (;Q!=NULL;Q=playerNextUnit(Q)) + { + if (Q==P) break; + } + if (Q==NULL) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + BYTE *B=(BYTE *)P;B+=0x2EC;//контроллер + B=*((BYTE**)B);B+=0x114;//плэеринфо? + B=*((BYTE**)B);B+=0x8EC; + lua_pushinteger(L,*((int*)B));B+=4; + lua_pushinteger(L,*((int*)B)); + return 2; + } + +} + +/// Вызывается перед попыткой колдовать спелл +/// если 0 - все как обычно (проверки на чат, на саммон и т.п.) +/// если 1 - колдуем +/// если -1 - нет +extern "C" int __cdecl playerOnTrySpell(bigUnitStruct *Unit,byte *Uc,spellPacket *Pckt) +{ + int Top=lua_gettop(L); + do + { + lua_getglobal(L,"playerOnSpell"); + if (lua_isnil(L,-1)) + break; + lua_pushlightuserdata(L,Unit); + lua_gettable(L,-2); + if (!lua_isfunction(L,-1)) + break; + lua_pushlightuserdata(L,Unit); + void *Targ=*((void**)(Uc+0x120));/// текущая цель игрока + if (Targ) + lua_pushlightuserdata(L, Targ ); + else + lua_pushnil(L); + byte *Pi=(byte *)(*((void**)(Uc+0x114))); + Pi+=0x8EC; + lua_pushboolean(L,Pckt->Dir); + lua_pushinteger(L,Pckt->Spells[0]); + lua_pushnumber(L,*((DWORD *)Pi));Pi+=4; + lua_pushnumber(L,*((DWORD *)Pi)); + if (0==lua_pcall(L,6,1,0)) + { + int R=lua_tointeger(L,-1); + lua_settop(L,Top); + return R; + } + }while(0); + lua_settop(L,Top); + return 0; +} + +extern void InjectOffs(DWORD Addr,void *Fn); +extern void InjectJumpTo(DWORD Addr,void *Fn); + +void playerInit() +{ + ASSIGN(playerControlBufferFirst,0x0051AB50); + ASSIGN(playerAtCursor,0x0054AFA2); + ASSIGN(playerControlBufferNext,0x0051ABC0); + ASSIGN(playerObserveCre,0x4DDE80); + ASSIGN(playerObserveCreUndo,0x4DDEF0); + ASSIGN(netUnitFromPacketMB,0x0004ECCB0); + + + ASSIGN(sub_4FC2B0,0x4FC2B0); + ASSIGN(sub_4E6040,0x4E6040); + + lua_newtable(L); + registerServerVar("playerOnSpell");//сюда кладем реакции на спеллы плеера + + lua_newtable(L); + registerServerVar("playerOnInput"); // сюда реакции на действия плеера + + InjectOffs(0x004E637F+1,&myPlayerControlBufferFirst); + InjectOffs(0x004E639E+1,&myPlayerControlBufferFirst); + InjectOffs(0x004E67D2+1,&myPlayerControlBufferNext); + InjectOffs(0x004DD94B+1,&onPlayerJoinTrap); + InjectOffs(0x00491EB0+1,&clientOnJoin); + + InjectOffs(0x004D216B+1,&teamKotrGetFirstValidTeam); + InjectOffs(0x004D220A+1,&teamKotrGetNextValidTeam); + InjectOffs(0x00419234+1,&teamCreateNewCorrectly); + + InjectJumpTo(0x54D2B0,&onPlayerDieTrap); + InjectJumpTo(0x4E6891,&onPlayerGoObservTrap); + InjectJumpTo(0x4E6653,&onPlayerLeaveObservTrap); + + registerserver("playerLook",&playerLookL); + registerserver("playerMouse",&playerMouseL); + +} diff --git a/player.h b/player.h index fd4e669..3d8ae05 100644 --- a/player.h +++ b/player.h @@ -104,8 +104,8 @@ struct playerInfoStruct }; -extern bigUnitStruct* (__cdecl *playerFirstUnit)(); /// -extern bigUnitStruct* (__cdecl *playerNextUnit)(void* Prev); /// +extern bigUnitStruct* (__cdecl *playerFirstUnit)(); ///возвращает первый юнит сетевого игрока +extern bigUnitStruct* (__cdecl *playerNextUnit)(void* Prev); /// Возвращает следующего сетевого игрока extern bigUnitStruct* getPlayerUDataFromPlayerInfo(playerInfoStruct *addr); extern bigUnitStruct* getPlayerUDataFromPlayerIdx(int idx); diff --git a/polygon.cpp b/polygon.cpp index 921afc8..b1fbb0b 100644 --- a/polygon.cpp +++ b/polygon.cpp @@ -1,110 +1,110 @@ -#include "stdafx.h" - -polygon_s *(__cdecl *noxPolygonGetByIdx) (int Idx); -polygonAngle_s *(__cdecl *noxPolygonAngleGetByNum) (int Idx); - -int *noxNextPolygonIdx; -int *noxNextPolygonAngleNum; - -namespace -{ - - int polygonGetByIdxL(lua_State *L) - { - if (lua_type(L,1)!=LUA_TNUMBER) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - int idx=lua_tointeger(L,1); - if (idx>*noxNextPolygonIdx-1) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - lua_pushlightuserdata(L,(void*)noxPolygonGetByIdx(idx)); - return 1; - } - - int polygonInfoL(lua_State *L) - { - if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - polygon_s *P=(polygon_s*)lua_touserdata(L,1); - lua_newtable(L); - lua_pushinteger(L,P->polygonIdx); - lua_setfield(L,-2,"idx"); - lua_pushinteger(L,P->posX1); - lua_setfield(L,-2,"posX1"); - lua_pushinteger(L,P->posX2); - lua_setfield(L,-2,"posX2"); - lua_pushinteger(L,P->posY1); - lua_setfield(L,-2,"posY1"); - lua_pushinteger(L,P->posY2); - lua_setfield(L,-2,"posY2"); - lua_pushstring(L,P->Name); - lua_setfield(L,-2,"name"); - lua_pushinteger(L,P->color); - lua_setfield(L,-2,"color"); - lua_pushinteger(L,P->kolvoUglov); - lua_setfield(L,-2,"kolvoUglov"); - lua_pushinteger(L,P->minimapGroup); - lua_setfield(L,-2,"minimapGroup"); - BYTE *A=(BYTE*)P->strucCoordinat; - lua_newtable(L); - int i=0; - for (;ikolvoUglov;i++) - { - lua_newtable(L); - polygonAngle_s *Ang=noxPolygonAngleGetByNum(*(A+i*4)); - lua_pushinteger(L,Ang->numAngle); - lua_rawseti(L,-2,1); - lua_pushinteger(L,Ang->posX); - lua_rawseti(L,-2,2); - lua_pushinteger(L,Ang->posY); - lua_rawseti(L,-2,3); - lua_rawseti(L,-2,(P->kolvoUglov)-i); - } - lua_setfield(L,-2,"tCord"); - return 1; - } - - int polygonSetAttrL(lua_State*L) - { - if (lua_type(L,1)!=LUA_TLIGHTUSERDATA || lua_type(L,2)!=LUA_TTABLE) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - polygon_s *P=(polygon_s *) lua_touserdata(L,1); - lua_getfield(L,2,"name"); - if (lua_type(L,-1)==LUA_TSTRING) - conPrintI(lua_tostring(L,-1)); - return 0; - } - - - - - -} - -void polygonInit() -{ - - ASSIGN(noxPolygonGetByIdx,0x004214A0); // - ASSIGN(noxPolygonAngleGetByNum,0x00421030); - - ASSIGN(noxNextPolygonIdx,0x00595BC0); // // ( ) - ASSIGN(noxNextPolygonAngleNum,0x00595BC4); // - - - - registerserver("polygonInfo",&polygonInfoL); - registerserver("polygonGetByIdx",&polygonGetByIdxL); - registerserver("polygonSetAttr",&polygonSetAttrL); - +#include "stdafx.h" + +polygon_s *(__cdecl *noxPolygonGetByIdx) (int Idx); +polygonAngle_s *(__cdecl *noxPolygonAngleGetByNum) (int Idx); + +int *noxNextPolygonIdx; +int *noxNextPolygonAngleNum; + +namespace +{ + + int polygonGetByIdxL(lua_State *L) + { + if (lua_type(L,1)!=LUA_TNUMBER) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + int idx=lua_tointeger(L,1); + if (idx>*noxNextPolygonIdx-1) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + lua_pushlightuserdata(L,(void*)noxPolygonGetByIdx(idx)); + return 1; + } + + int polygonInfoL(lua_State *L) + { + if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + polygon_s *P=(polygon_s*)lua_touserdata(L,1); + lua_newtable(L); + lua_pushinteger(L,P->polygonIdx); + lua_setfield(L,-2,"idx"); + lua_pushinteger(L,P->posX1); + lua_setfield(L,-2,"posX1"); + lua_pushinteger(L,P->posX2); + lua_setfield(L,-2,"posX2"); + lua_pushinteger(L,P->posY1); + lua_setfield(L,-2,"posY1"); + lua_pushinteger(L,P->posY2); + lua_setfield(L,-2,"posY2"); + lua_pushstring(L,P->Name); + lua_setfield(L,-2,"name"); + lua_pushinteger(L,P->color); + lua_setfield(L,-2,"color"); + lua_pushinteger(L,P->kolvoUglov); + lua_setfield(L,-2,"kolvoUglov"); + lua_pushinteger(L,P->minimapGroup); + lua_setfield(L,-2,"minimapGroup"); + BYTE *A=(BYTE*)P->strucCoordinat; + lua_newtable(L); + int i=0; + for (;ikolvoUglov;i++) + { + lua_newtable(L); + polygonAngle_s *Ang=noxPolygonAngleGetByNum(*(A+i*4)); + lua_pushinteger(L,Ang->numAngle); + lua_rawseti(L,-2,1); + lua_pushinteger(L,Ang->posX); + lua_rawseti(L,-2,2); + lua_pushinteger(L,Ang->posY); + lua_rawseti(L,-2,3); + lua_rawseti(L,-2,(P->kolvoUglov)-i); + } + lua_setfield(L,-2,"tCord"); + return 1; + } + + int polygonSetAttrL(lua_State*L) + { + if (lua_type(L,1)!=LUA_TLIGHTUSERDATA || lua_type(L,2)!=LUA_TTABLE) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + polygon_s *P=(polygon_s *) lua_touserdata(L,1); + lua_getfield(L,2,"name"); + if (lua_type(L,-1)==LUA_TSTRING) + conPrintI(lua_tostring(L,-1)); + return 0; + } + + + + + +} + +void polygonInit() +{ + + ASSIGN(noxPolygonGetByIdx,0x004214A0); // функции + ASSIGN(noxPolygonAngleGetByNum,0x00421030); + + ASSIGN(noxNextPolygonIdx,0x00595BC0); // переменные // содержит идкс следующего (еще не существующего полигона) + ASSIGN(noxNextPolygonAngleNum,0x00595BC4); // номер следующего угла + + + + registerserver("polygonInfo",&polygonInfoL); + registerserver("polygonGetByIdx",&polygonGetByIdxL); + registerserver("polygonSetAttr",&polygonSetAttrL); + } \ No newline at end of file diff --git a/react.cpp b/react.cpp index 06a7d69..742e9e0 100644 --- a/react.cpp +++ b/react.cpp @@ -1,642 +1,642 @@ -#include "stdafx.h" -#include "unit.h" - -#define ASSIGN2(A,B) *((void**)&(A))=(B); - -extern int (__cdecl *spellAccept)(int SpellType,void *Caster,void *CasterMB2,void *Carrier, - SpellTargetBlock *Block,int Power); - -int (__cdecl *monsterGetVoice)(void* Monster); // -creatureAction* (__cdecl *monsterActionPush)(void *Unit,int ActionType); -void (__cdecl *monsterActionPop)(void *Unit); -void (__cdecl *noxReportComplete)(void *Unit); -void printI(const char *S); -void (__cdecl *noxMonsterCallDieFn) (void *Unit); -namespace -{ - void (unitFlyActivate)(int SpellType,void *Owner,void *Source,void *Carrier, - SpellTargetBlock *Block,int Power) - { - int Top=lua_gettop(L); - do - { - lua_getglobal(L,"unitFlyActivate"); - if (!lua_istable(L,-1)) - break; - lua_pushlightuserdata(L,Carrier); - lua_gettable(L,-2); - if (!lua_isfunction(L,-1)) - break; - lua_pushinteger(L,SpellType); - lua_pushlightuserdata(L,Owner); - lua_pushlightuserdata(L,Source); - lua_pushlightuserdata(L,Carrier); - lua_pushnumber(L,Block->targX); - lua_pushnumber(L,Block->targY); - lua_pushinteger(L,Power); - lua_pcall(L,7,0,0); - lua_settop(L,Top); - return; - } - while(0); - lua_settop(L,Top); - spellAccept(SpellType,Owner,Source,Carrier,Block,Power); - } - - int hookMonsterMeleeAttack(void* Unit) - { - int voice = monsterGetVoice(Unit); - int Top=lua_gettop(L); - do - { - lua_getglobal(L,"monsterAttackSuccess"); - if (!lua_istable(L,-1)) - break; - lua_pushlightuserdata(L,Unit); - lua_gettable(L,-2); - if (!lua_isfunction(L,-1)) - break; - lua_pushlightuserdata(L,Unit); - lua_pcall(L,1,0,0); - lua_settop(L,Top); - return voice; - } - while(0); - lua_settop(L,Top); - return voice; // - } - - int __cdecl reactUse(bigUnitStruct *User,bigUnitStruct *Thing) - { - lua_pushlightuserdata(L,&reactUse); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,Thing); - lua_gettable(L,-2); - if(lua_type(L,-1)!=LUA_TFUNCTION) - { - lua_pop(L,2); - return 0; - } - lua_pushlightuserdata(L,User); - lua_pushlightuserdata(L,Thing); - void **P=(void **)(Thing->useFnData); - if(*P==NULL) - lua_pushnil(L); - else - lua_pushlightuserdata(L,*P); - if(0!=lua_pcall(L,3,1,0)) - { - printI("Error calling react"); - lua_pop(L,2); - return 0; - } - int R=lua_toboolean(L,-1); - lua_pop(L,2); - return R; - } - int setOnUseL(lua_State *L) - { - if ( - (lua_type(L,1)!=LUA_TLIGHTUSERDATA)|| - (lua_type(L,2)!=LUA_TFUNCTION) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - lua_pushvalue(L,1); - /// , - lua_pushvalue(L,2); - lua_settable(L,lua_upvalueindex(2)); - bigUnitStruct *Unit=(bigUnitStruct *)lua_touserdata(L,1); - Unit->useFnPtr=&reactUse; - return 0; - } - int unitSetAction(lua_State*L) - { - if ( - (lua_type(L,1)!=LUA_TLIGHTUSERDATA)|| - (lua_type(L,2)!=LUA_TNUMBER) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - void *P=monsterActionPush(lua_touserdata(L,1),lua_tointeger(L,2)); - lua_pushlightuserdata(L,P); - return 1; - } - int unitActionPop(lua_State*L) - { - if ( - (lua_type(L,1)!=LUA_TLIGHTUSERDATA) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - monsterActionPop(lua_touserdata(L,1)); - return 0; - } - void __cdecl unitReportComplete(bigUnitStruct *Unit) - { - lua_pushlightuserdata(L,&unitReportComplete); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,Unit); - lua_gettable(L,-2); - lua_pushlightuserdata(L,Unit); - lua_pushnil(L); - lua_settable(L,-4);// , - if(lua_type(L,-1)!=LUA_TFUNCTION) - { - noxReportComplete(Unit); - lua_pop(L,2); - return; - } - lua_pushlightuserdata(L,Unit); - if(0!=lua_pcall(L,1,1,0)) - { - lua_pop(L,2); - return; - } - lua_pop(L,2); - return; - } - int setOnCompleteL(lua_State *L) - { - if ( - (lua_type(L,1)!=LUA_TLIGHTUSERDATA)|| - (lua_type(L,2)!=LUA_TFUNCTION) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - lua_pushvalue(L,1); - /// , - lua_pushvalue(L,2); - lua_settable(L,lua_upvalueindex(1)); - return 0; - } - int callPtr2L(lua_State *L) - { - if ( - (lua_type(L,1)!=LUA_TNUMBER)|| - (0==lua_tointeger(L,1) ) || - (lua_type(L,2)!=LUA_TLIGHTUSERDATA)|| - (lua_type(L,3)!=LUA_TLIGHTUSERDATA) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - void *(__cdecl *Fn)(void *A,void *B); - Fn=(void *(__cdecl *)(void *,void *))lua_tointeger(L,1); - lua_pushlightuserdata(L,Fn(lua_touserdata(L,2),lua_touserdata(L,3))); - return 1; - } - void __cdecl dieFn(bigUnitStruct *Me); - - - int unitSetDieFnL(lua_State*L) - { - if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - if(lua_type(L,2)!=LUA_TFUNCTION)/// - { - lua_pushvalue(L,1); - lua_gettable(L,lua_upvalueindex(1)); - if(lua_type(L,-1)!=LUA_TLIGHTUSERDATA) - { - lua_pushstring(L,"wrong arg: can't remove die handler - it doesn't exist!"); - lua_error_(L); - } - bigUnitStruct *P=(bigUnitStruct *)lua_touserdata(L,1); - P->dieFnPtr=lua_touserdata(L,-1); - lua_pop(L,1); - lua_pushvalue(L,1); - lua_pushnil(L); - lua_settable(L,lua_upvalueindex(1)); - return 0; - } - bigUnitStruct *P=(bigUnitStruct *)lua_touserdata(L,1); - lua_pushvalue(L,1); - lua_pushlightuserdata(L,P->dieFnPtr); - lua_settable(L,lua_upvalueindex(1));/// - lua_pushvalue(L,1); - lua_pushvalue(L,2); - lua_settable(L,lua_upvalueindex(2));/// - P->dieFnPtr=&dieFn; - return 0; - } - - void __cdecl dieFn(bigUnitStruct *Me) - { - lua_pushlightuserdata(L,&dieFn); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,(void*)Me); - lua_gettable(L,-2); - if(lua_type(L,-1)!=LUA_TFUNCTION) - { - lua_pop(L,1); - return; - } - - lua_pushlightuserdata(L, Me); - bigUnitStruct *Unit=unitDamageFindParent(Me->unitDamaged); - if (Unit==0) - lua_pushnil(L); - else - lua_pushlightuserdata(L, (void*)Unit); - - if(0!=lua_pcall(L,2,1,0))/// BUGBUG , - /// - - { - conPrintI(lua_tostring(L,-1)); - lua_pop(L,1); - lua_pushnil(L); - } - lua_pushlightuserdata(L,&unitSetDieFnL); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,(void*)Me); - lua_gettable(L,-2); - if(lua_type(L,-1)!=LUA_TLIGHTUSERDATA) - { - lua_pop(L,4);/// - - - - return; - } - void (__cdecl *Old)(void *); - Old=(void (__cdecl *)(void *))lua_touserdata(L,-1); - - Me->dieFnPtr=(void*)Old; - - lua_pushlightuserdata(L,Me); - lua_pushnil(L); - lua_settable(L,-4);// - if ( (Old!=NULL) && (0==lua_toboolean(L,-3))) - { - Old(Me); - } - lua_pop(L,4);/// - return; - } - void __cdecl collideFn(bigUnitStruct *Me,bigUnitStruct *Him,noxPoint *Pt); - - - int unitSetCollideFnL(lua_State*L) - { - if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - if(lua_type(L,2)!=LUA_TFUNCTION)/// - { - lua_pushvalue(L,1); - lua_gettable(L,lua_upvalueindex(1)); - if(lua_type(L,-1)!=LUA_TLIGHTUSERDATA) - { - lua_pushstring(L,"wrong arg: can't remove collide handler - it doesn't exist!"); - lua_error_(L); - } - bigUnitStruct *P=(bigUnitStruct *)lua_touserdata(L,1); - P->collideFn=lua_touserdata(L,-1); - lua_pop(L,1); - lua_pushvalue(L,1); - lua_pushnil(L); - lua_settable(L,lua_upvalueindex(1)); - return 0; - } - bigUnitStruct *P=(bigUnitStruct *)lua_touserdata(L,1); - lua_pushvalue(L,1); - lua_pushlightuserdata(L,P->collideFn); - lua_settable(L,lua_upvalueindex(1));/// - lua_pushvalue(L,1); - lua_pushvalue(L,2); - lua_settable(L,lua_upvalueindex(2));/// - P->collideFn=&collideFn; - return 0; - } - - void __cdecl collideFn(bigUnitStruct *Me,bigUnitStruct *Him,noxPoint *Pt) - { - lua_pushlightuserdata(L,&collideFn); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,Me); - lua_gettable(L,-2); - if(lua_type(L,-1)!=LUA_TFUNCTION) - { - lua_pop(L,1); - return; - } - lua_pushlightuserdata(L,Me); - if(Him==0) - lua_pushnil(L); - else - lua_pushlightuserdata(L,Him); - lua_pushnumber(L,Pt->X); - lua_pushnumber(L,Pt->Y); - if(0!=lua_pcall(L,4,0,0)) - { lua_pop(L,2); return;} - lua_pop(L,1);/// - return; - } - int unitSetAnyFnL(lua_State*L,int Ofs,void *newAddr) - { - if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - if(lua_type(L,2)!=LUA_TFUNCTION)/// - { - lua_pushvalue(L,1); - lua_gettable(L,lua_upvalueindex(1)); - if(lua_type(L,-1)!=LUA_TLIGHTUSERDATA) - { - lua_pushstring(L,"wrong arg: can't remove handler - it doesn't exist!"); - lua_error_(L); - } - BYTE* P=(BYTE *)lua_touserdata(L,1); - P+=Ofs; - *((void **)P)=lua_touserdata(L,-1); - lua_pop(L,1); - lua_pushvalue(L,1); - lua_pushnil(L); - lua_settable(L,lua_upvalueindex(1)); - return 0; - } - BYTE* P=(BYTE *)lua_touserdata(L,1); - P+=Ofs; - lua_pushvalue(L,1); - lua_pushlightuserdata(L,*((void **)P)); - lua_settable(L,lua_upvalueindex(1));/// - lua_pushvalue(L,1); - lua_pushvalue(L,2); - lua_settable(L,lua_upvalueindex(2));/// - *((void **)P)=newAddr; - return 0; - } - void initFn(lua_State*L,const char *Name,lua_CFunction luaFn,void *Fn) - { - lua_newtable(L);// - lua_pushlightuserdata(L,luaFn); - lua_pushvalue(L,-2); - lua_settable(L,LUA_REGISTRYINDEX); - lua_newtable(L);// - lua_pushlightuserdata(L,Fn); - lua_pushvalue(L,-2); - lua_settable(L,LUA_REGISTRYINDEX); - lua_pushcclosure(L,luaFn,2); - lua_setglobal(L,Name); - - } - int unitSetDropL(lua_State*L); - int __cdecl dropFn(void *Him,void *Me,noxPoint* Pt) - { - lua_pushlightuserdata(L,&dropFn); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,Me); - lua_gettable(L,-2); - if(lua_type(L,-1)!=LUA_TFUNCTION) - { - lua_pop(L,1); - return 0; - } - lua_pushlightuserdata(L,Me); - if(Him==0) - lua_pushnil(L); - else - lua_pushlightuserdata(L,Him); - lua_pushnumber(L,Pt->X); - lua_pushnumber(L,Pt->Y); - if(0!=lua_pcall(L,4,1,0)) - { lua_pop(L,2); return 0;} - - lua_pushlightuserdata(L,unitSetDropL); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,Me); - lua_gettable(L,-2); - if(lua_type(L,-1)!=LUA_TLIGHTUSERDATA) - { - lua_pop(L,4);/// - - - - return 1; - } - int (__cdecl* fn) (void *Him,void *Me,noxPoint* Pt); - ASSIGN2(fn,lua_touserdata(L,-1)); - int ret=1; - if((fn!=NULL)&&(0==lua_toboolean(L,-3))) - { - ret=fn(Him,Me,Pt); - } - lua_pop(L,4);/// - return ret; - } - int unitSetDropL(lua_State*L) - { - return unitSetAnyFnL(L,0x2C8,&dropFn); - } - int unitSetDamageL(lua_State*L); - int __cdecl damageFn(void *Me,void *Him,void *By,int Value,int Type) - { - lua_pushlightuserdata(L,&damageFn); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,Me); - lua_gettable(L,-2); - if(lua_type(L,-1)!=LUA_TFUNCTION) - { - lua_pop(L,1); - return 0; - } - lua_pushlightuserdata(L,Me); - if(Him==0) - lua_pushnil(L); - else - lua_pushlightuserdata(L,Him); - if(By==0) - lua_pushnil(L); - else - lua_pushlightuserdata(L,By); - lua_pushnumber(L,Value); - lua_pushnumber(L,Type); - if(0!=lua_pcall(L,5,2,0)) - { lua_pop(L,2); return 0;} - - lua_pushlightuserdata(L,unitSetDamageL); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,Me); - lua_gettable(L,-2); - if(lua_type(L,-1)!=LUA_TLIGHTUSERDATA) - { - lua_pop(L,5);/// - - ? - - - return 1; - } - int (__cdecl* fn) (void *Him,void *Me,void *By,int Val,int Type); - ASSIGN2(fn,lua_touserdata(L,-1)); - int ret=1; - if (lua_isnumber(L,-3)) - Value=lua_tointeger(L,-3); - if ((fn!=NULL) && (0==lua_toboolean(L,-4))) - { - ret=fn(Me,Him,By,Value,Type); - } - lua_pop(L,5);/// - return ret; - } - int unitSetDamageL(lua_State*L) - { - return unitSetAnyFnL(L,0x2CC,&damageFn); - } - - // UPDATE , 1 - - int unitSetUpdateL(lua_State*L); - void __cdecl updateFn(bigUnitStruct *Me) - { - lua_pushlightuserdata(L,&updateFn); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,Me); - lua_gettable(L,-2); - if(lua_type(L,-1)!=LUA_TFUNCTION) - { - lua_pop(L,1); - return; - } - lua_pushlightuserdata(L,Me); - if (0!=lua_pcall(L,1,0,0)) return; - - lua_pushlightuserdata(L,&unitSetUpdateL); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,Me); - lua_gettable(L,-2); - if(lua_type(L,-1)!=LUA_TLIGHTUSERDATA) - { - lua_pop(L,4);/// - - - - return; - } - /* - void (__cdecl *Old)(void *); - Old=(void (__cdecl *)(void *))lua_touserdata(L,-1); - - Me->onUpdateFn = (void*)Old; - - lua_pushlightuserdata(L,Me); - lua_pushnil(L); - lua_settable(L,-4);// - if ( (Old!=NULL) && (0==lua_toboolean(L,-3))) - { - Old(Me); - } - lua_pop(L,4);/// - */ - return; - } - int unitSetUpdateL(lua_State*L) - { - return unitSetAnyFnL(L,0x2E8,&updateFn); - } - - int unitSetPickupL(lua_State*L); - int __cdecl pickupFn(void *Him,void *Me,void *A,void *B) - { - lua_pushlightuserdata(L,&pickupFn); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,Me); - lua_gettable(L,-2); - if(lua_type(L,-1)!=LUA_TFUNCTION) - { - lua_pop(L,1); - return 0; - } - lua_pushlightuserdata(L,Me); - if(Him==0) - lua_pushnil(L); - else - lua_pushlightuserdata(L,Him); - lua_pushlightuserdata(L,A); - lua_pushlightuserdata(L,B); - if(0!=lua_pcall(L,4,1,0)) - { lua_pop(L,2); return 0;} - - lua_pushlightuserdata(L,unitSetPickupL); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,Me); - lua_gettable(L,-2); - if(lua_type(L,-1)!=LUA_TLIGHTUSERDATA) - { - lua_pop(L,4);/// - - - - return 1; - } - int (__cdecl* fn) (void *Him,void *Me,void *A,void *B); - ASSIGN2(fn,lua_touserdata(L,-1)); - int ret=1; - if((fn!=NULL)&&(0==lua_toboolean(L,-3))) - { - ret=fn(Him,Me,A,B); - } - lua_pop(L,4);/// - return ret; - } - int unitSetPickupL(lua_State*L) - { - return unitSetAnyFnL(L,0x2C4,&pickupFn); - } - - void __declspec(naked) asmOnDieMonster() // , unitOnDie - { - __asm - { - mov eax,[esi+2D4h] - test eax,eax - jz l1 - call eax - add esp,4 - push esi - - l1: - call noxMonsterCallDieFn - push 0x4EE6AA - ret - } - } - -} -extern void InjectJumpTo(DWORD Addr,void *Fn); -extern void InjectOffs(DWORD Addr,void *Fn); -void reactInit() -{ - InjectOffs(0x004E96D5+1,&unitFlyActivate); - InjectOffs(0x005324FA+1,&hookMonsterMeleeAttack); - InjectJumpTo(0x4EE6A5,&asmOnDieMonster); - - ASSIGN(monsterActionPop,0x0050A160); - ASSIGN(monsterActionPush,0x0050A260); - ASSIGN(noxReportComplete,0x544FF0); - ASSIGN(noxMonsterCallDieFn,0x50A3D0); - ASSIGN(monsterGetVoice,0x424300); - void** V=(void **)(0x5BFEC8+0x204); - *V=&unitReportComplete; - - - initFn(L,"unitOnComplete",&setOnCompleteL,&unitReportComplete); - initFn(L,"unitOnUse",&setOnUseL,&reactUse); - initFn(L,"unitOnDie",&unitSetDieFnL,&dieFn); - initFn(L,"unitOnPickup",&unitSetPickupL,&pickupFn); - initFn(L,"unitOnDrop",&unitSetDropL,&dropFn); - initFn(L,"unitOnDamage",&unitSetDamageL,&damageFn); - initFn(L,"unitOnUpdate",&unitSetUpdateL,&updateFn); - initFn(L,"unitOnCollide",&unitSetCollideFnL,&collideFn); - - registerserver("unitSetAction",&unitSetAction); - registerserver("unitActionPop",&unitActionPop); - - lua_newtable(L); - registerServerVar("unitFlyActivate"); - - lua_newtable(L); - registerServerVar("monsterAttackSuccess"); - - registerserver("ptrCall2",&callPtr2L); +#include "stdafx.h" +#include "unit.h" + +#define ASSIGN2(A,B) *((void**)&(A))=(B); + +extern int (__cdecl *spellAccept)(int SpellType,void *Caster,void *CasterMB2,void *Carrier, + SpellTargetBlock *Block,int Power); + +int (__cdecl *monsterGetVoice)(void* Monster); // вообще птр возвращается +creatureAction* (__cdecl *monsterActionPush)(void *Unit,int ActionType); +void (__cdecl *monsterActionPop)(void *Unit); +void (__cdecl *noxReportComplete)(void *Unit); +void printI(const char *S); +void (__cdecl *noxMonsterCallDieFn) (void *Unit); +namespace +{ + void (unitFlyActivate)(int SpellType,void *Owner,void *Source,void *Carrier, + SpellTargetBlock *Block,int Power) + { + int Top=lua_gettop(L); + do + { + lua_getglobal(L,"unitFlyActivate"); + if (!lua_istable(L,-1)) + break; + lua_pushlightuserdata(L,Carrier); + lua_gettable(L,-2); + if (!lua_isfunction(L,-1)) + break; + lua_pushinteger(L,SpellType); + lua_pushlightuserdata(L,Owner); + lua_pushlightuserdata(L,Source); + lua_pushlightuserdata(L,Carrier); + lua_pushnumber(L,Block->targX); + lua_pushnumber(L,Block->targY); + lua_pushinteger(L,Power); + lua_pcall(L,7,0,0); + lua_settop(L,Top); + return; + } + while(0); + lua_settop(L,Top); + spellAccept(SpellType,Owner,Source,Carrier,Block,Power); + } + + int hookMonsterMeleeAttack(void* Unit) + { + int voice = monsterGetVoice(Unit); + int Top=lua_gettop(L); + do + { + lua_getglobal(L,"monsterAttackSuccess"); + if (!lua_istable(L,-1)) + break; + lua_pushlightuserdata(L,Unit); + lua_gettable(L,-2); + if (!lua_isfunction(L,-1)) + break; + lua_pushlightuserdata(L,Unit); + lua_pcall(L,1,0,0); + lua_settop(L,Top); + return voice; + } + while(0); + lua_settop(L,Top); + return voice; // хук был поставлен на эту функцию + } + + int __cdecl reactUse(bigUnitStruct *User,bigUnitStruct *Thing) + { + lua_pushlightuserdata(L,&reactUse); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,Thing); + lua_gettable(L,-2); + if(lua_type(L,-1)!=LUA_TFUNCTION) + { + lua_pop(L,2); + return 0; + } + lua_pushlightuserdata(L,User); + lua_pushlightuserdata(L,Thing); + void **P=(void **)(Thing->useFnData); + if(*P==NULL) + lua_pushnil(L); + else + lua_pushlightuserdata(L,*P); + if(0!=lua_pcall(L,3,1,0)) + { + printI("Error calling react"); + lua_pop(L,2); + return 0; + } + int R=lua_toboolean(L,-1); + lua_pop(L,2); + return R; + } + int setOnUseL(lua_State *L) + { + if ( + (lua_type(L,1)!=LUA_TLIGHTUSERDATA)|| + (lua_type(L,2)!=LUA_TFUNCTION) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + lua_pushvalue(L,1); + ///Здесь неплохо бы зарегить уничтожение объекта, чтобы таблица не росла + lua_pushvalue(L,2); + lua_settable(L,lua_upvalueindex(2)); + bigUnitStruct *Unit=(bigUnitStruct *)lua_touserdata(L,1); + Unit->useFnPtr=&reactUse; + return 0; + } + int unitSetAction(lua_State*L) + { + if ( + (lua_type(L,1)!=LUA_TLIGHTUSERDATA)|| + (lua_type(L,2)!=LUA_TNUMBER) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + void *P=monsterActionPush(lua_touserdata(L,1),lua_tointeger(L,2)); + lua_pushlightuserdata(L,P); + return 1; + } + int unitActionPop(lua_State*L) + { + if ( + (lua_type(L,1)!=LUA_TLIGHTUSERDATA) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + monsterActionPop(lua_touserdata(L,1)); + return 0; + } + void __cdecl unitReportComplete(bigUnitStruct *Unit) + { + lua_pushlightuserdata(L,&unitReportComplete); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,Unit); + lua_gettable(L,-2); + lua_pushlightuserdata(L,Unit); + lua_pushnil(L); + lua_settable(L,-4);// сразу удалим, чтобы не получить рекурсию + if(lua_type(L,-1)!=LUA_TFUNCTION) + { + noxReportComplete(Unit); + lua_pop(L,2); + return; + } + lua_pushlightuserdata(L,Unit); + if(0!=lua_pcall(L,1,1,0)) + { + lua_pop(L,2); + return; + } + lua_pop(L,2); + return; + } + int setOnCompleteL(lua_State *L) + { + if ( + (lua_type(L,1)!=LUA_TLIGHTUSERDATA)|| + (lua_type(L,2)!=LUA_TFUNCTION) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + lua_pushvalue(L,1); + ///Здесь неплохо бы зарегить уничтожение объекта, чтобы таблица не росла + lua_pushvalue(L,2); + lua_settable(L,lua_upvalueindex(1)); + return 0; + } + int callPtr2L(lua_State *L) + { + if ( + (lua_type(L,1)!=LUA_TNUMBER)|| + (0==lua_tointeger(L,1) ) || + (lua_type(L,2)!=LUA_TLIGHTUSERDATA)|| + (lua_type(L,3)!=LUA_TLIGHTUSERDATA) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + void *(__cdecl *Fn)(void *A,void *B); + Fn=(void *(__cdecl *)(void *,void *))lua_tointeger(L,1); + lua_pushlightuserdata(L,Fn(lua_touserdata(L,2),lua_touserdata(L,3))); + return 1; + } + void __cdecl dieFn(bigUnitStruct *Me); + + + int unitSetDieFnL(lua_State*L) + { + if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + if(lua_type(L,2)!=LUA_TFUNCTION)/// удаляем нафиг наш обработчик + { + lua_pushvalue(L,1); + lua_gettable(L,lua_upvalueindex(1)); + if(lua_type(L,-1)!=LUA_TLIGHTUSERDATA) + { + lua_pushstring(L,"wrong arg: can't remove die handler - it doesn't exist!"); + lua_error_(L); + } + bigUnitStruct *P=(bigUnitStruct *)lua_touserdata(L,1); + P->dieFnPtr=lua_touserdata(L,-1); + lua_pop(L,1); + lua_pushvalue(L,1); + lua_pushnil(L); + lua_settable(L,lua_upvalueindex(1)); + return 0; + } + bigUnitStruct *P=(bigUnitStruct *)lua_touserdata(L,1); + lua_pushvalue(L,1); + lua_pushlightuserdata(L,P->dieFnPtr); + lua_settable(L,lua_upvalueindex(1));/// запишем в таблицу + lua_pushvalue(L,1); + lua_pushvalue(L,2); + lua_settable(L,lua_upvalueindex(2));/// запишем в таблицу что нам вызывать + P->dieFnPtr=&dieFn; + return 0; + } + + void __cdecl dieFn(bigUnitStruct *Me) + { + lua_pushlightuserdata(L,&dieFn); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,(void*)Me); + lua_gettable(L,-2); + if(lua_type(L,-1)!=LUA_TFUNCTION) + { + lua_pop(L,1); + return; + } + + lua_pushlightuserdata(L, Me); + bigUnitStruct *Unit=unitDamageFindParent(Me->unitDamaged); + if (Unit==0) + lua_pushnil(L); + else + lua_pushlightuserdata(L, (void*)Unit); + + if(0!=lua_pcall(L,2,1,0))/// BUGBUG косяк в том, что если внутри функции удалить + /// объект - то там еще старое значение + { + conPrintI(lua_tostring(L,-1)); + lua_pop(L,1); + lua_pushnil(L); + } + lua_pushlightuserdata(L,&unitSetDieFnL); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,(void*)Me); + lua_gettable(L,-2); + if(lua_type(L,-1)!=LUA_TLIGHTUSERDATA) + { + lua_pop(L,4);/// что достали - таблица - результат функции- таблица + return; + } + void (__cdecl *Old)(void *); + Old=(void (__cdecl *)(void *))lua_touserdata(L,-1); + + Me->dieFnPtr=(void*)Old; + + lua_pushlightuserdata(L,Me); + lua_pushnil(L); + lua_settable(L,-4);// Удаляем себя из таблицы + if ( (Old!=NULL) && (0==lua_toboolean(L,-3))) + { + Old(Me); + } + lua_pop(L,4);/// удаляем таблицу + return; + } + void __cdecl collideFn(bigUnitStruct *Me,bigUnitStruct *Him,noxPoint *Pt); + + + int unitSetCollideFnL(lua_State*L) + { + if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + if(lua_type(L,2)!=LUA_TFUNCTION)/// удаляем нафиг наш обработчик + { + lua_pushvalue(L,1); + lua_gettable(L,lua_upvalueindex(1)); + if(lua_type(L,-1)!=LUA_TLIGHTUSERDATA) + { + lua_pushstring(L,"wrong arg: can't remove collide handler - it doesn't exist!"); + lua_error_(L); + } + bigUnitStruct *P=(bigUnitStruct *)lua_touserdata(L,1); + P->collideFn=lua_touserdata(L,-1); + lua_pop(L,1); + lua_pushvalue(L,1); + lua_pushnil(L); + lua_settable(L,lua_upvalueindex(1)); + return 0; + } + bigUnitStruct *P=(bigUnitStruct *)lua_touserdata(L,1); + lua_pushvalue(L,1); + lua_pushlightuserdata(L,P->collideFn); + lua_settable(L,lua_upvalueindex(1));/// запишем в таблицу + lua_pushvalue(L,1); + lua_pushvalue(L,2); + lua_settable(L,lua_upvalueindex(2));/// запишем в таблицу что нам вызывать + P->collideFn=&collideFn; + return 0; + } + + void __cdecl collideFn(bigUnitStruct *Me,bigUnitStruct *Him,noxPoint *Pt) + { + lua_pushlightuserdata(L,&collideFn); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,Me); + lua_gettable(L,-2); + if(lua_type(L,-1)!=LUA_TFUNCTION) + { + lua_pop(L,1); + return; + } + lua_pushlightuserdata(L,Me); + if(Him==0) + lua_pushnil(L); + else + lua_pushlightuserdata(L,Him); + lua_pushnumber(L,Pt->X); + lua_pushnumber(L,Pt->Y); + if(0!=lua_pcall(L,4,0,0)) + { lua_pop(L,2); return;} + lua_pop(L,1);/// удаляем таблицу + return; + } + int unitSetAnyFnL(lua_State*L,int Ofs,void *newAddr) + { + if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + if(lua_type(L,2)!=LUA_TFUNCTION)/// удаляем нафиг наш обработчик + { + lua_pushvalue(L,1); + lua_gettable(L,lua_upvalueindex(1)); + if(lua_type(L,-1)!=LUA_TLIGHTUSERDATA) + { + lua_pushstring(L,"wrong arg: can't remove handler - it doesn't exist!"); + lua_error_(L); + } + BYTE* P=(BYTE *)lua_touserdata(L,1); + P+=Ofs; + *((void **)P)=lua_touserdata(L,-1); + lua_pop(L,1); + lua_pushvalue(L,1); + lua_pushnil(L); + lua_settable(L,lua_upvalueindex(1)); + return 0; + } + BYTE* P=(BYTE *)lua_touserdata(L,1); + P+=Ofs; + lua_pushvalue(L,1); + lua_pushlightuserdata(L,*((void **)P)); + lua_settable(L,lua_upvalueindex(1));/// запишем в таблицу + lua_pushvalue(L,1); + lua_pushvalue(L,2); + lua_settable(L,lua_upvalueindex(2));/// запишем в таблицу что нам вызывать + *((void **)P)=newAddr; + return 0; + } + void initFn(lua_State*L,const char *Name,lua_CFunction luaFn,void *Fn) + { + lua_newtable(L);// для замененных функций + lua_pushlightuserdata(L,luaFn); + lua_pushvalue(L,-2); + lua_settable(L,LUA_REGISTRYINDEX); + lua_newtable(L);// для старых функций + lua_pushlightuserdata(L,Fn); + lua_pushvalue(L,-2); + lua_settable(L,LUA_REGISTRYINDEX); + lua_pushcclosure(L,luaFn,2); + lua_setglobal(L,Name); + + } + int unitSetDropL(lua_State*L); + int __cdecl dropFn(void *Him,void *Me,noxPoint* Pt) + { + lua_pushlightuserdata(L,&dropFn); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,Me); + lua_gettable(L,-2); + if(lua_type(L,-1)!=LUA_TFUNCTION) + { + lua_pop(L,1); + return 0; + } + lua_pushlightuserdata(L,Me); + if(Him==0) + lua_pushnil(L); + else + lua_pushlightuserdata(L,Him); + lua_pushnumber(L,Pt->X); + lua_pushnumber(L,Pt->Y); + if(0!=lua_pcall(L,4,1,0)) + { lua_pop(L,2); return 0;} + + lua_pushlightuserdata(L,unitSetDropL); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,Me); + lua_gettable(L,-2); + if(lua_type(L,-1)!=LUA_TLIGHTUSERDATA) + { + lua_pop(L,4);/// что достали - таблица - результат функции- таблица + return 1; + } + int (__cdecl* fn) (void *Him,void *Me,noxPoint* Pt); + ASSIGN2(fn,lua_touserdata(L,-1)); + int ret=1; + if((fn!=NULL)&&(0==lua_toboolean(L,-3))) + { + ret=fn(Him,Me,Pt); + } + lua_pop(L,4);/// удаляем таблицу + return ret; + } + int unitSetDropL(lua_State*L) + { + return unitSetAnyFnL(L,0x2C8,&dropFn); + } + int unitSetDamageL(lua_State*L); + int __cdecl damageFn(void *Me,void *Him,void *By,int Value,int Type) + { + lua_pushlightuserdata(L,&damageFn); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,Me); + lua_gettable(L,-2); + if(lua_type(L,-1)!=LUA_TFUNCTION) + { + lua_pop(L,1); + return 0; + } + lua_pushlightuserdata(L,Me); + if(Him==0) + lua_pushnil(L); + else + lua_pushlightuserdata(L,Him); + if(By==0) + lua_pushnil(L); + else + lua_pushlightuserdata(L,By); + lua_pushnumber(L,Value); + lua_pushnumber(L,Type); + if(0!=lua_pcall(L,5,2,0)) + { lua_pop(L,2); return 0;} + + lua_pushlightuserdata(L,unitSetDamageL); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,Me); + lua_gettable(L,-2); + if(lua_type(L,-1)!=LUA_TLIGHTUSERDATA) + { + lua_pop(L,5);/// что достали - таблица - вызывать си? - дамак - таблица + return 1; + } + int (__cdecl* fn) (void *Him,void *Me,void *By,int Val,int Type); + ASSIGN2(fn,lua_touserdata(L,-1)); + int ret=1; + if (lua_isnumber(L,-3)) + Value=lua_tointeger(L,-3); + if ((fn!=NULL) && (0==lua_toboolean(L,-4))) + { + ret=fn(Me,Him,By,Value,Type); + } + lua_pop(L,5);/// удаляем таблицу + return ret; + } + int unitSetDamageL(lua_State*L) + { + return unitSetAnyFnL(L,0x2CC,&damageFn); + } + + // обработчик UPDATE функции, передает 1 аргумент - юнит + int unitSetUpdateL(lua_State*L); + void __cdecl updateFn(bigUnitStruct *Me) + { + lua_pushlightuserdata(L,&updateFn); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,Me); + lua_gettable(L,-2); + if(lua_type(L,-1)!=LUA_TFUNCTION) + { + lua_pop(L,1); + return; + } + lua_pushlightuserdata(L,Me); + if (0!=lua_pcall(L,1,0,0)) return; + + lua_pushlightuserdata(L,&unitSetUpdateL); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,Me); + lua_gettable(L,-2); + if(lua_type(L,-1)!=LUA_TLIGHTUSERDATA) + { + lua_pop(L,4);/// что достали - таблица - результат функции- таблица + return; + } + /* + void (__cdecl *Old)(void *); + Old=(void (__cdecl *)(void *))lua_touserdata(L,-1); + + Me->onUpdateFn = (void*)Old; + + lua_pushlightuserdata(L,Me); + lua_pushnil(L); + lua_settable(L,-4);// Удаляем себя из таблицы + if ( (Old!=NULL) && (0==lua_toboolean(L,-3))) + { + Old(Me); + } + lua_pop(L,4);/// удаляем таблицу + */ + return; + } + int unitSetUpdateL(lua_State*L) + { + return unitSetAnyFnL(L,0x2E8,&updateFn); + } + + int unitSetPickupL(lua_State*L); + int __cdecl pickupFn(void *Him,void *Me,void *A,void *B) + { + lua_pushlightuserdata(L,&pickupFn); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,Me); + lua_gettable(L,-2); + if(lua_type(L,-1)!=LUA_TFUNCTION) + { + lua_pop(L,1); + return 0; + } + lua_pushlightuserdata(L,Me); + if(Him==0) + lua_pushnil(L); + else + lua_pushlightuserdata(L,Him); + lua_pushlightuserdata(L,A); + lua_pushlightuserdata(L,B); + if(0!=lua_pcall(L,4,1,0)) + { lua_pop(L,2); return 0;} + + lua_pushlightuserdata(L,unitSetPickupL); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,Me); + lua_gettable(L,-2); + if(lua_type(L,-1)!=LUA_TLIGHTUSERDATA) + { + lua_pop(L,4);/// что достали - таблица - результат функции- таблица + return 1; + } + int (__cdecl* fn) (void *Him,void *Me,void *A,void *B); + ASSIGN2(fn,lua_touserdata(L,-1)); + int ret=1; + if((fn!=NULL)&&(0==lua_toboolean(L,-3))) + { + ret=fn(Him,Me,A,B); + } + lua_pop(L,4);/// удаляем таблицу + return ret; + } + int unitSetPickupL(lua_State*L) + { + return unitSetAnyFnL(L,0x2C4,&pickupFn); + } + + void __declspec(naked) asmOnDieMonster() // Важная хрень, что бы unitOnDie для мобов вызывался + { + __asm + { + mov eax,[esi+2D4h] + test eax,eax + jz l1 + call eax + add esp,4 + push esi + + l1: + call noxMonsterCallDieFn + push 0x4EE6AA + ret + } + } + +} +extern void InjectJumpTo(DWORD Addr,void *Fn); +extern void InjectOffs(DWORD Addr,void *Fn); +void reactInit() +{ + InjectOffs(0x004E96D5+1,&unitFlyActivate); + InjectOffs(0x005324FA+1,&hookMonsterMeleeAttack); + InjectJumpTo(0x4EE6A5,&asmOnDieMonster); + + ASSIGN(monsterActionPop,0x0050A160); + ASSIGN(monsterActionPush,0x0050A260); + ASSIGN(noxReportComplete,0x544FF0); + ASSIGN(noxMonsterCallDieFn,0x50A3D0); + ASSIGN(monsterGetVoice,0x424300); + void** V=(void **)(0x5BFEC8+0x204); + *V=&unitReportComplete; + + + initFn(L,"unitOnComplete",&setOnCompleteL,&unitReportComplete); + initFn(L,"unitOnUse",&setOnUseL,&reactUse); + initFn(L,"unitOnDie",&unitSetDieFnL,&dieFn); + initFn(L,"unitOnPickup",&unitSetPickupL,&pickupFn); + initFn(L,"unitOnDrop",&unitSetDropL,&dropFn); + initFn(L,"unitOnDamage",&unitSetDamageL,&damageFn); + initFn(L,"unitOnUpdate",&unitSetUpdateL,&updateFn); + initFn(L,"unitOnCollide",&unitSetCollideFnL,&collideFn); + + registerserver("unitSetAction",&unitSetAction); + registerserver("unitActionPop",&unitActionPop); + + lua_newtable(L); + registerServerVar("unitFlyActivate"); + + lua_newtable(L); + registerServerVar("monsterAttackSuccess"); + + registerserver("ptrCall2",&callPtr2L); } \ No newline at end of file diff --git a/replays.cpp b/replays.cpp index c714b45..53fa818 100644 --- a/replays.cpp +++ b/replays.cpp @@ -1,1131 +1,1131 @@ -#include "stdafx.h" -#include "unit.h" -#include -#include -#include -#include -#include -#define REPLAY_VERSION 1 -#define REPLAY_PLAYERSTART_SIZE 0x81 -typedef unsigned int u_int; - - -using namespace std; - -bool replayIsNewPacket=false; -bool replayIsNewMap=false; -void* origClientPacketHandlerEnd; -void* origClientPacketHandlerPointer; -int origClientPacketHandlerSize; -byte* lastEntry; -int lastEntrySize=0; - - - -// -bool (__cdecl *noxReplayStartSave)(const char* filename); -void (__cdecl *noxReplayStopSave)(); -bool (__cdecl *noxReplayStartView)(const char* filename); -void (__cdecl *noxReplayStopView)(); -void (__cdecl *sub_470A80)(); -int *mapFrameTime_6F9838; -int (__cdecl *noxNewSessionStart)(); -extern void *(__cdecl *serverGetGameDataBySel)(); -extern void *(__cdecl *serverGetGameData)(int N); -extern char *(__cdecl *mapGetName)(); -extern void teamCreateDefault(int TeamNumParam, bool notRestrict=false); -extern void (__cdecl *consoleServerMapLoad)(int spaceNumber, int tokensNumber, void* tokens); -extern void (__cdecl *guiServerOptionsStartGameMB)(); -extern int (__cdecl *serverModeIndexByModeFlags)(DWORD Flags); -extern short *serverLessonLimitArr; -extern byte *serverTimeLimitArr; -extern int *serverInfoChanged; -extern int (__cdecl *noxCheckGameFlags) (int); -extern void (__cdecl *playerGoObserver)(void* playerPtr, byte unk1, byte unk2); -extern bigUnitStruct* (__cdecl *playerFirstUnit)(); /// -extern bigUnitStruct* (__cdecl *playerNextUnit)(void* Prev); /// -void* (__cdecl *playerInfoFirst)(); -void* (__cdecl *playerInfoNext)(void* Prev); -int (__cdecl *initGame)(); -extern DWORD *GameFlags; -extern int (__cdecl *netCreatePlayerStartPacket)(void* Dst, void* playerInfo); -int (__cdecl *deletePlayer)(int netCode); -extern BYTE *(__cdecl *playerInfoFromNetCodeCli) (int NetCode); -void* (__cdecl *netOnPacketRecvCli)(int plrId, void* listPtr, int listSize); -extern int (__cdecl *playerKickByIdx)(int playerIdx, int unknownArg); -extern void* getPlayerUDataFromPlayerIdx(int idx); -extern bigUnitStruct *netUnitByCodeServ(DWORD NetCode); -bigUnitStruct* (__cdecl *unitCreateByThingType)(int thingType); - -ServerData replayViewFormGameData; - -enum replayEntries -{ - REPLAY_HEADER, - REPLAY_FRAME, -}; - -struct replayFileHeader -{ - byte entryType; //default: (byte)REPLAY_HEADER - u_int fileVersion; //default: REPLAY_VERSION - u_int fileFramesCount; - char mapName[8]; - __int16 mapMode; - __int16 mapFragLimit; - byte mapTimeLimit; - byte mapPlayersQuantity; - // Followed by a dynamic-sized array of playerStarts packets of players on the map -}; - -struct replayFileFrame -{ - byte entryType; //default: (byte)REPLAY_FRAME - u_int frameId; - u_int frameSize; - // Followed by a dynamic-sized array of bytes with frame data -}; - -// replayView block - - - -namespace -{ - struct replayViewLoadMapStruct - { - char mapName[8]; - __int16 mapMode; - __int16 mapFragLimit; - byte mapTimeLimit; - }; - - bool replayViewEnabled=false; - bool replayViewFormGameRequired=false; - bool replayViewFrameDispatched=false; - bool replayViewRestoreHoster=false; - bool replayViewRestoreHosterFinalize=false; - int replayViewSpeedFactor=0; - int replayViewSpeedFactorCount=0; - map replayViewFakeNetCodes; - u_int replayViewFrameSize=0; - byte* replayViewFrame=NULL; - u_int replayViewFrameCount=0; - u_int replayViewSafeSuspendFrames=0; - replayViewLoadMapStruct replayViewLoadMap; - byte* replayViewHosterData=NULL; - ifstream replayView; - - bool replayViewReadData(); - void replayViewKickAllButHoster(); - - void replayViewStop() - { - *GameFlags=(*GameFlags)|0x1; - replayViewEnabled=false; - replayViewFormGameRequired=false; - replayViewSafeSuspendFrames=0; - if(replayViewFrame!=NULL) - { - delete [] replayViewFrame; - replayViewFrame=NULL; - replayViewFrameSize=0; - } - replayViewFrameDispatched=false; - replayView.close(); - replayView.clear(); - replayViewKickAllButHoster(); - replayViewRestoreHoster=true; - replayViewRestoreHosterFinalize=false; - replayViewFakeNetCodes.clear(); - } - - bool replayViewStart(const char* fileName) - { - replayViewStop(); - replayViewRestoreHoster=false; - for(byte* P=(byte*)playerInfoFirst(); P!=NULL; P=(byte*)playerInfoNext(P)) - { - byte playerIdx = *((byte*)(P+0x810)); - if(playerIdx==0x1F) - { - replayViewHosterData = new byte[REPLAY_PLAYERSTART_SIZE]; - netCreatePlayerStartPacket(replayViewHosterData, P); - } - //REPLAY_PLAYERSTART_SIZE - - } - if(replayViewHosterData==NULL) - { - replayViewStop(); - return false; - } - replayView.open(fileName, ios::in | ios::binary); - if(!replayView.is_open()) - { - replayViewStop(); - return false; - } - char fileType[4]; - replayView.read(fileType, 4); - if(replayView.eof() && 0!=strncmp(fileType, "bnru", 4)) - { - replayViewStop(); - return false; - } - - replayViewEnabled=true; - replayViewSafeSuspendFrames=0; - return true; - } - - bool replayViewReadData() - { - u_int packetSize=0; - /*char packetIndicator[6]; - replayView.read(packetIndicator, 5);*/ - replayView.read((char*)&packetSize, sizeof(packetSize)); - if(replayView.eof()) - { - replayViewStop(); - return false; - } - packetSize-=sizeof(packetSize); - u_int currentPosition=replayView.tellg(); - byte packetEntry; - replayView.read((char*)&packetEntry, 1); - if(replayView.eof()) - { - replayViewStop(); - return false; - } - replayView.seekg((u_int)replayView.tellg()-1, ios::beg); - switch(packetEntry) - { - case REPLAY_HEADER: - { - replayFileHeader packetHeader; - replayView.read((char*)&packetHeader, sizeof(packetHeader)); - if(packetHeader.fileVersion>REPLAY_VERSION || replayView.eof()) - { - // Unsupported replay file version - replayViewStop(); - return false; - } - replayViewFrameCount = packetHeader.fileFramesCount; - strncpy(replayViewLoadMap.mapName, packetHeader.mapName, 8); - replayViewLoadMap.mapMode = packetHeader.mapMode; - replayViewLoadMap.mapFragLimit = packetHeader.mapFragLimit; - replayViewLoadMap.mapTimeLimit = packetHeader.mapTimeLimit; - replayViewFrameSize = REPLAY_PLAYERSTART_SIZE*packetHeader.mapPlayersQuantity; - replayViewFrame = new byte[replayViewFrameSize]; - replayView.read((char*)replayViewFrame, replayViewFrameSize); - if(replayView.eof()) - { - replayViewStop(); - return false; - } - replayViewFormGameRequired=true; - replayViewFrameDispatched=true; - } - break; - case REPLAY_FRAME: - { - replayFileFrame packetHeader; - replayView.read((char*)&packetHeader, sizeof(packetHeader)); - if(replayView.eof()) - { - replayViewStop(); - return false; - } - replayViewFrameSize = packetHeader.frameSize; - replayViewFrameDispatched=true; - if(replayViewFrameSize>0) - { - replayViewFrame = new byte[replayViewFrameSize]; - replayView.read((char*)replayViewFrame, replayViewFrameSize); - if(replayView.eof()) - { - replayViewStop(); - return false; - } - } - } - break; - default: - replayView.seekg(currentPosition+packetSize, ios::beg); - } - if((currentPosition+packetSize)!=replayView.tellg()) - { - // File probably corrupted - replayViewStop(); - return false; - } - //replayView.read(packetIndicator, 3); - return true; - } - - void replayViewKickAllButHoster() - { - void* player=playerFirstUnit(); - while(player!=NULL) - { - void **PP=(void **)(((char*)player)+0x2EC); - PP=(void**)(((char*)*PP)+0x114); - byte *P=(byte*)(*PP); - byte playerIdx = *((byte*)(P+0x810)); - if(playerIdx!=0x1F) - { - playerKickByIdx((int)playerIdx, 4); - } - player=playerNextUnit(player); - } - } - - void replayViewLoadFrame(BYTE **frameBuffer, int *size) - { - if(replayViewEnabled) - { - if(replayViewSafeSuspendFrames==0 && replayViewFormGameRequired==false) - { - byte* unitedFrame=NULL; - u_int unitedSize=0; - if(replayViewSpeedFactor<0 && replayViewSpeedFactorCount==0) - replayViewSpeedFactorCount=replayViewSpeedFactor-2; - if(replayViewSpeedFactorCount<0) - { - replayViewSpeedFactorCount++; - if(replayViewSpeedFactorCount<-1) - replayViewFrameDispatched=true; - } - int speedFactor=replayViewSpeedFactor+1; - do - { - speedFactor--; - while(replayViewFrameDispatched==false) - { - if(!replayViewReadData() || replayViewSafeSuspendFrames>0) - { - return; - } - } - replayViewFrameDispatched=false; - u_int unitedSizeBefore=unitedSize; - unitedSize+=replayViewFrameSize; - if(unitedSize>0 && unitedSizeBefore!=unitedSize) - { - unitedFrame=(byte*)realloc(unitedFrame, unitedSize); - memcpy(&unitedFrame[unitedSizeBefore], replayViewFrame, replayViewFrameSize); - } - } - while(speedFactor>0); - *GameFlags=(*GameFlags)^0x1; - *size = unitedSize; - *frameBuffer = unitedFrame; - - } - else - replayViewSafeSuspendFrames--; - *GameFlags=(*GameFlags)|0x1; - } - if(replayViewRestoreHoster) - { - if(replayViewHosterData!=NULL) - { - *size = REPLAY_PLAYERSTART_SIZE; - *frameBuffer = replayViewHosterData; - replayViewRestoreHosterFinalize=true; - } - replayViewRestoreHoster=false; - } - } - - void replayViewFinalizeFrame() - { - if(replayViewEnabled && replayViewFrameDispatched==false) - { - if(replayViewFrame!=NULL) - { - delete[] replayViewFrame; - replayViewFrame=NULL; - replayViewFrameSize=0; - } - } - if(replayViewRestoreHosterFinalize) - { - delete [] replayViewHosterData; - replayViewHosterData=NULL; - replayViewRestoreHosterFinalize=false; - } - } - - void replayViewFormGame() - { - if(replayViewFormGameRequired && replayViewEnabled) - { - *GameFlags=(*GameFlags)|0x1; - ServerData *Data=(ServerData*)serverGetGameDataBySel(); - strncpy(Data->mapName, replayViewLoadMap.mapName, 8); - Data->gameFlags = replayViewLoadMap.mapMode|0xe00f; - Data->fragLimit = replayViewLoadMap.mapFragLimit; - Data->timeLimitMB = replayViewLoadMap.mapTimeLimit; - bool sameMap=false; - if(strcmp(Data->mapName,mapGetName())==0) - { - sameMap=true; - } - - int Index=serverModeIndexByModeFlags(Data->gameFlags); - serverLessonLimitArr[Index]=Data->fragLimit; - serverTimeLimitArr[Index]=Data->timeLimitMB; - *serverInfoChanged=1; - - if(Data->isNew!=1 && Data->gameFlags&0x60) - { - teamCreateDefault(2); - } - else - { - teamCreateDefault(-1); - } - if(sameMap) - { - wchar_t command[5] = L"load"; - wchar_t wMapName[9]={0}; - int *commandPointer=(int*)&command; - int *wMapNamePointer=(int*)&wMapName; - MultiByteToWideChar(CP_ACP, MB_COMPOSITE, Data->mapName, 8, wMapName, 9); - BYTE result[8]={0}; - memcpy(&result[0], &commandPointer, 4); - memcpy(&result[4], &wMapNamePointer, 4); - consoleServerMapLoad(1, 2, (void*)&result); - } - else - { - guiServerOptionsStartGameMB(); - } - replayViewSafeSuspendFrames=30; - replayViewFormGameRequired=false; - } - } - - void replayViewEachFrame() - { - - } - - int replayViewSimulateClient(int gf) - { - if((replayViewEnabled && replayViewSafeSuspendFrames==0) || replayViewRestoreHosterFinalize) - { - return 0; - } - return noxCheckGameFlags(gf); - } - - int replayViewFakeNetcode(int oldNetCode) - { - if(replayViewEnabled) - { - int newNetCode=oldNetCode; - if(replayViewFakeNetCodes.count(oldNetCode)!=0) - newNetCode = replayViewFakeNetCodes[oldNetCode]; - return newNetCode; - } - else - return oldNetCode; - } - - int replayViewFakeNetcodeCreate(int thingType, int oldNetCode) - { - if(replayViewEnabled && replayViewSafeSuspendFrames==0 && replayViewFormGameRequired==false) - { - int newNetCode=oldNetCode; - if(replayViewFakeNetCodes.count(oldNetCode)!=0) - newNetCode = replayViewFakeNetCodes[oldNetCode]; - else if(thingType!=0) - { - u_int currentPosition=replayView.tellg(); - bigUnitStruct* unit = unitCreateByThingType(thingType); - newNetCode = unit->netCode; - replayViewFakeNetCodes[oldNetCode]=newNetCode; - } - return newNetCode; - } - else - return oldNetCode; - } - - int replayViewStopL(lua_State* L) - { - replayViewStop(); - return 0; - } - - int replayViewStartL(lua_State* L) - { - if(lua_type(L, -1)==LUA_TSTRING) - replayViewStart(lua_tostring(L, 1)); - else - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - return 0; - } - - int replayViewSpeedL(lua_State* L) - { - if(lua_type(L, -1)==LUA_TNUMBER) - { - int coef = lua_tonumber(L, 1); - if(coef>=-10 && coef<=10) - { - replayViewSpeedFactor=coef; - } - else - { - lua_pushstring(L,"wrong args: value out of bounds!"); - lua_error_(L); - } - } - else - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - return 0; - } - - - //replaySave block - bool replaySaveEnabled=false; - bool replaySaveFrameSaved=false; - u_int replaySaveDropFrame=0; - char* replaySaveFileName = NULL; - byte* replaySaveHeader = NULL; - u_int replaySaveHeaderSize=0; - ofstream replaySave; - u_int replaySaveFrameCount=0; - u_int replaySavePreviousMapLocation=0; - byte* replaySaveFramePackets=NULL; - byte* replaySaveFramePacketsSeeker=NULL; - byte* replaySaveFramePacketsEnd=NULL; - byte* replaySaveFramePayload=NULL; - u_int replaySaveFramePayloadSize=0; - byte* replaySaveFrameBaseAddress=NULL; - - bool replaySaveWriteData(replayEntries type, void* payload=NULL, u_int size=0); - - void replaySaveStop(bool resetFileName=true) - { - if(resetFileName && replaySaveFileName!=NULL) - { - delete [] replaySaveFileName; - replaySaveFileName=NULL; - replaySaveEnabled=false; - } - if(replaySave.is_open()) - { - replaySaveWriteData(REPLAY_HEADER); - } - replaySaveFrameCount=0; - if(replaySaveHeader!=NULL) - { - delete [] replaySaveHeader; - replaySaveHeader=NULL; - } - replaySaveDropFrame=0; - replaySaveHeaderSize=0; - replaySaveFrameBaseAddress=NULL; - replaySaveFrameSaved=false; - replaySave.close(); - replaySave.clear(); - } - - bool replaySaveStart(const char* fileName=NULL, unsigned int fileNameLength=0) - { - if(fileNameLength>0) - { - if(replaySaveFileName!=NULL) - { - replaySaveStop(); - } - else - replaySaveStop(!replaySaveEnabled); - replaySaveFileName = new char[fileNameLength+1]; - memset(replaySaveFileName, 0, fileNameLength+1); - strncpy(replaySaveFileName, fileName, fileNameLength); - } - else - replaySaveStop(!replaySaveEnabled); - string fileNameFull="replays/"; - TIME_ZONE_INFORMATION tz; - SYSTEMTIME time; - GetLocalTime(&time); - GetTimeZoneInformation(&tz); - char timeZone[7]; - if(tz.Bias==0) - strcpy(timeZone, "Z"); - else - { - char symbol=(tz.Bias>0)?('-'):('+'); - u_int tzHours = floor((long double)(abs(tz.Bias)/60)); - u_int tzMinutes = abs(tz.Bias)%60; - sprintf(timeZone, "%c%02u.%02u", symbol, tzHours, tzMinutes); - } - char timeStamp[30]; - // ISO 8601 ( ) - sprintf(timeStamp, "%04i-%02i-%02iT%02i.%02i.%02i.%03i%s", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, time.wMilliseconds, timeZone); - if(strlen(replaySaveFileName)>0) - { - fileNameFull.append(replaySaveFileName); - fileNameFull.append("_"); - } - fileNameFull.append(timeStamp); - fileNameFull.append("_"); - fileNameFull.append(mapGetName()); - fileNameFull.append(".nru"); - replaySave.open(fileNameFull.c_str(), ios::out | ios::trunc | ios::binary); - if(!replaySave.is_open()) - { - replaySaveStop(); - return false; - } - replaySave.write("bnru", 4); // , , - if(!replaySave.is_open()) - { - replaySaveStop(); - return false; - } - replaySaveEnabled=true; - replaySaveFrameCount=0; - replaySaveWriteData(REPLAY_HEADER); - return true; - } - - void replaySaveWriteFrameCount() - { - u_int currentPosition=replaySave.tellp(); - u_int offset=4+1+sizeof(u_int); - replaySave.seekp(offset, ios::beg); - replaySave.write((const char*)&replaySaveFrameCount, sizeof(u_int)); - replaySave.seekp(currentPosition, ios::beg); - } - - - bool replaySaveWriteData(replayEntries type, void* payload, u_int size) - { - if(!replaySave.is_open()) - { - replaySaveStop(); - return false; - } - - - u_int totalLength=0; - byte* packet; - switch(type) - { - case REPLAY_HEADER: - { - // . - if(replaySaveHeader==NULL) - { - byte* playersList=NULL; - byte playersListQuantity=0; - for(void* P=playerInfoFirst(); P!=NULL; P=playerInfoNext(P)) - { - playersListQuantity+=1; - playersList=(byte*)realloc(playersList, playersListQuantity*REPLAY_PLAYERSTART_SIZE); - netCreatePlayerStartPacket(&playersList[(playersListQuantity-1)*REPLAY_PLAYERSTART_SIZE], P); - //REPLAY_PLAYERSTART_SIZE - - } - - // - replayFileHeader* packetHelper = new replayFileHeader; - memset(packetHelper, 0, sizeof(packetHelper)); - packetHelper->entryType=REPLAY_HEADER; - packetHelper->fileVersion=REPLAY_VERSION; - packetHelper->fileFramesCount=replaySaveFrameCount; - strncpy(packetHelper->mapName, mapGetName(),8); - packetHelper->mapMode=(__int16)*GameFlags&0x1FF0; - int Index=serverModeIndexByModeFlags(*GameFlags); - packetHelper->mapFragLimit=serverLessonLimitArr[Index]; - packetHelper->mapTimeLimit=serverTimeLimitArr[Index]; - packetHelper->mapPlayersQuantity=playersListQuantity; - replaySaveHeaderSize=sizeof(replayFileHeader)+playersListQuantity*REPLAY_PLAYERSTART_SIZE; - replaySaveHeader = new byte[replaySaveHeaderSize]; - memcpy(replaySaveHeader, packetHelper, sizeof(replayFileHeader)); - memcpy(&replaySaveHeader[sizeof(replayFileHeader)], playersList, playersListQuantity*REPLAY_PLAYERSTART_SIZE); - // - realloc(playersList, 0); - delete [] packetHelper; - } - else - { - replayFileHeader* packetHelper = (replayFileHeader*)replaySaveHeader; - packetHelper->fileFramesCount=replaySaveFrameCount; - } - - // . - packet=new byte[replaySaveHeaderSize]; - memset(packet, 0, replaySaveHeaderSize); - memcpy(packet, replaySaveHeader, replaySaveHeaderSize); - totalLength+=replaySaveHeaderSize; // - - - } - break; - case REPLAY_FRAME: - { - // - replayFileFrame* packetHelper = new replayFileFrame; - memset(packetHelper, 0, sizeof(packetHelper)); - packetHelper->entryType=REPLAY_FRAME; - packetHelper->frameId=replaySaveFrameCount; - packetHelper->frameSize = size; - - // . - packet=new byte[sizeof(replayFileFrame)+size]; - memset(packet, 0, sizeof(replayFileFrame)+size); - memcpy(packet, packetHelper, sizeof(replayFileFrame)); - memcpy(&packet[sizeof(replayFileFrame)], payload, size); - totalLength+=sizeof(replayFileFrame)+size; - - // - delete [] packetHelper; - } - break; - } - u_int relocate=0; - if(type==REPLAY_HEADER) - { - relocate=replaySave.tellp(); - if(relocate>4) - replaySave.seekp(4, ios::beg); - } - /*char packetIndicator[6]; - strncpy(packetIndicator,"start", 5); - replaySave.write(packetIndicator, 5);*/ - totalLength+=sizeof(totalLength); - replaySave.write((const char*)&totalLength, sizeof(totalLength)); - replaySave.write((const char*)packet, totalLength-sizeof(totalLength)); - /*strncpy(packetIndicator,"end", 3); - replaySave.write(packetIndicator, 3);*/ - if(type==REPLAY_HEADER && relocate>4) - { - replaySave.seekp(relocate, ios::beg); - } - delete [] packet; - } - - void replaySaveAddFramePayload(byte* payload, int size) - { - if(size>0) - { - replaySaveFramePayload=(byte*)realloc(replaySaveFramePayload, replaySaveFramePayloadSize+size); - byte* pointer=replaySaveFramePayload+replaySaveFramePayloadSize; - memset(pointer, 0, size); - memcpy(pointer, payload, size); - } - replaySaveFramePayloadSize+=size; - } - - bool replaySaveFullFrame(BYTE *BufStart, int size) - { - if(replaySaveEnabled) - { - // , . . "" . - if(size>0) - { - replaySaveFramePackets = new byte[size]; - memcpy(replaySaveFramePackets, BufStart, size); - } - replaySaveFramePacketsSeeker=replaySaveFramePackets; - replaySaveFramePacketsEnd=replaySaveFramePackets+size; - replaySaveFrameCount++; - replaySaveFrameBaseAddress=BufStart; - - return true; - } - return false; - } - - bool replaySavePacketChecker(byte* packet, int size) - { - // , . - byte *P = packet; - bool allowed=true; // - false - // . . - if(*P==0x2B) - { - // - allowed=false; - replaySaveDropFrame=5; // , - replaySaveStart(); // ( ). - . replaySaveStart. . - } - if(*P==0x6C) - { - allowed=false; - } - if(*P==0x6D) - { - allowed=false; - } - if(allowed) - { - replaySaveAddFramePayload(packet, size); - } - return true; - } - - bool replaySavePacketHandler(BYTE *&BufStart, BYTE *&E, bool &found) - { - if(replaySaveEnabled) - { - // - - . BufStart , . - u_int size=BufStart-replaySaveFrameBaseAddress; - if(size>0 && (replaySaveFramePacketsSeeker+size)<=replaySaveFramePacketsEnd) - { - byte* packet = new byte[size]; - memcpy(packet, replaySaveFramePacketsSeeker, size); - replaySavePacketChecker(packet, size); - delete [] packet; - replaySaveFramePacketsSeeker+=size; - } - replaySaveFrameBaseAddress=BufStart; - return true; - } - return false; - } - - bool replaySaveFinalizeFrame() - { - if(replaySaveEnabled) - { - // - -. . - if(replaySaveFramePacketsSeeker<=replaySaveFramePacketsEnd) - { - u_int size=replaySaveFramePacketsEnd-replaySaveFramePacketsSeeker; - replaySaveFrameBaseAddress=NULL; - if(size>0) - { - byte* packet = new byte[size]; - memcpy(packet, replaySaveFramePacketsSeeker, size); - replaySaveFramePacketsSeeker=replaySaveFramePacketsEnd; - replaySavePacketChecker(packet, size); - } - // ( ) - . . - if(replaySaveDropFrame==0) - replaySaveWriteData(REPLAY_FRAME, replaySaveFramePayload, replaySaveFramePayloadSize); - else - replaySaveDropFrame--; - replaySaveFrameSaved = true; - // - replaySaveFramePayloadSize=0; - if(replaySaveFramePayload!=NULL) - { - realloc(replaySaveFramePayload, 0); - replaySaveFramePayload=NULL; - } - if(replaySaveFramePackets!=NULL) - { - delete [] replaySaveFramePackets; - replaySaveFramePackets=NULL; - } - replaySaveFramePacketsSeeker=NULL; - replaySaveFramePacketsEnd=NULL; - } - return true; - } - return false; - } - - void replaySaveZeroFrame() - { - if(replaySaveEnabled && replaySaveDropFrame==0) - { - if(replaySaveFrameSaved) - { - replaySaveFrameSaved=false; - } - else - { - replaySaveWriteData(REPLAY_FRAME); - } - } - } - - int replaySaveStopL(lua_State* L) // - { - replaySaveStop(); - return 0; - } - - int replaySaveStartL(lua_State* L) // - { - if(lua_type(L, -1)==LUA_TSTRING) - { - const char *S=lua_tostring(L,-1); - if(replaySaveStart(S, strlen(S))) - return 0; - else - { - lua_pushstring(L,"file save error!"); - lua_error_(L); - } - } - else - { - if(replaySaveStart()) - return 0; - else - { - lua_pushstring(L,"file save error!"); - lua_error_(L); - } - } - return 0; - } - - //common replay block - - // netOnPacketRecvCli. - void clientPacketHandlerEnd(void* BufStart, int size, int edx, int ecx, int eax, void* returnFunction) - { - returnFunction = origClientPacketHandlerEnd; - BufStart = origClientPacketHandlerPointer; - size = origClientPacketHandlerSize; - replaySaveFinalizeFrame(); - replayViewFinalizeFrame(); - } - - //internal - - . . - void __declspec(naked) clientPacketHandlerEndTrap() - { - __asm - { - push 0 - push eax - push ecx - push edx - push 0 - push 0 - call clientPacketHandlerEnd - pop edx - pop ecx - mov [esp+16+4], edx - mov [esp+16+4+4], ecx - pop edx - pop ecx - pop eax - ret - } - } - - // netOnPacketRecvCli. , - void* __cdecl replayInterceptClientPackets(void* noxOrigClientPacketHandlerEnd, BYTE *BufStart, int size) //! onPacketRecvCli! - { - origClientPacketHandlerEnd=noxOrigClientPacketHandlerEnd; // return-. - origClientPacketHandlerPointer=BufStart; - origClientPacketHandlerSize=size; - replaySaveFullFrame(BufStart, size); - replayViewLoadFrame(&BufStart, &size); - return &clientPacketHandlerEndTrap; // return- onNetPacketCli. - } - - //internal - void __cdecl packetHandlerBegin() - { - //replayIsNewPacket=true; - sub_470A80(); - } - - //internal - . - void __declspec(naked) clientPacketHandlerBeginTrap() - { - __asm - { - push eax - push ebp - mov eax, [esp+0x1748+4+8] // return- - push eax - call replayInterceptClientPackets - mov [esp+0x1748+4+8+4], eax // return- onNetPacketCli. - pop eax - pop ebp - pop eax - lea ebx, [eax+ebp] - mov [esp+0x1748+4-0x1704], ebx // call - 1748h. - -1704h. . +4 ( ret) - mov [esp+0x1748+4+0x8], ebp // - mov [esp+0x1748+4+0xC], eax // - call packetHandlerBegin - ret - } - } -} -void replayGuiUpdate() -{ - replaySaveZeroFrame(); - replayViewFormGame(); -} - -//onNetPacket . -bool replayPacketHandler(BYTE *&BufStart, BYTE *&E, bool &found) -{ - replaySavePacketHandler(BufStart, E, found); - return true; -} - -void __cdecl replayQuitGame() -{ - replaySaveStop(); - replayViewStop(); - // - noxReplayStopSave(); -} - -void replayEachFrame() -{ - replayViewEachFrame(); -} - -int __cdecl replayOnSpriteRequest(int oldNetCode) -{ - //return replayViewFakeNetcode(oldNetCode); - return oldNetCode; -} - -int __cdecl replayOnSpriteCreate(int thingType, int oldNetCode) -{ - //return replayViewFakeNetcodeCreate(thingType, oldNetCode); - return oldNetCode; -} - -void __declspec(naked) replayOnSpriteRequestTrap() -{ - __asm - { - mov eax, [esp+4] - push eax - call replayOnSpriteRequest - add esp, 4 - mov [esp+4], eax - mov eax, 0x006D3DC0 - mov eax, [eax] - test eax,eax - push 0x0045A6F7 - ret - } -} - -void __declspec(naked) replayOnSpriteCreateTrap() -{ - __asm - { - push esi - mov esi, [esp+8+8] - push eax - mov eax, [esp+8+4+4] - push esi - push eax - call replayOnSpriteCreate - add esp,8 - mov esi,eax - pop eax - mov [esp+8+8],esi - push 0x0048E976 - ret - } -} - -void replayNullSub() -{ - return; -} - -extern "C" void replayInit(lua_State *L); - - -extern void InjectOffs(DWORD Addr,void *Fn); -extern void InjectJumpTo(DWORD Addr,void *Fn); - -void replayInit(lua_State *L) -{ - /* - //Blocked for now - ASSIGN(noxReplayStartSave, 0x004D3370); - ASSIGN(noxReplayStopSave, 0x004D33B0); - ASSIGN(noxReplayStartView, 0x004D34C0); - ASSIGN(noxReplayStopView, 0x004D3530); - - ASSIGN(sub_470A80, 0x00470A80); - - ASSIGN(mapFrameTime_6F9838, 0x006F9838); - //ASSIGN(initGame, 0x00435CC0); - ASSIGN(deletePlayer, 0x004DE7C0); - - ASSIGN(playerInfoFirst, 0x00416EA0); - ASSIGN(playerInfoNext, 0x00416EE0); - - ASSIGN(netOnPacketRecvCli, 0x0048EA70); - - ASSIGN(unitCreateByThingType, 0x004E3450); - - InjectOffs(0x0048EA9B+1, clientPacketHandlerBeginTrap); - //InjectOffs(0x004018EF+1, replayStartSave); - InjectOffs(0x004D3219+1, replayQuitGame); - - InjectOffs(0x004908CF+1, replayViewSimulateClient); - InjectOffs(0x00491D63+1, replayViewSimulateClient); - //InjectOffs(0x0048EB87+1, replayViewSimulateClient); - //InjectOffs(0x0048EBAA+1, replayViewSimulateClient); - InjectOffs(0x0048F2E7+1, replayViewSimulateClient); - InjectOffs(0x0048F46A+1, replayViewSimulateClient); - InjectOffs(0x0048F694+1, replayViewSimulateClient); - //InjectOffs(0x0048FA27+1, replayViewSimulateClient); - //InjectOffs(0x0048FA49+1, replayViewSimulateClient); - InjectOffs(0x0048FC39+1, replayViewSimulateClient); - InjectOffs(0x0048FC67+1, replayViewSimulateClient); - InjectOffs(0x0048FCB5+1, replayViewSimulateClient); - InjectOffs(0x004903C6+1, replayViewSimulateClient); - InjectOffs(0x004908CF+1, replayViewSimulateClient); - InjectOffs(0x00490A1B+1, replayViewSimulateClient); - InjectOffs(0x00490D39+1, replayViewSimulateClient); - InjectOffs(0x00490E23+1, replayViewSimulateClient); - InjectOffs(0x00490F9F+1, replayViewSimulateClient); - InjectOffs(0x0049127A+1, replayViewSimulateClient); - InjectOffs(0x00491592+1, replayViewSimulateClient); - //InjectOffs(0x00491A3A+1, replayViewSimulateClient); - InjectOffs(0x0049302F+1, replayViewSimulateClient); - //InjectOffs(0x00493B3A+1, replayViewSimulateClient); - InjectOffs(0x00493BB5+1, replayViewSimulateClient); - - InjectOffs(0x0048E9F9+1, replayNullSub);*/ -/* //Blocked permanently - InjectOffs(0x00491D63+1, replayViewSimulateClient); - - InjectOffs(0x00409DE6+1, replaySaveNewMapLoading); - InjectOffs(0x00491EED+1, replaySavePlayerLeaving); - -*/ - - //registerserver("replayStartSave",&replayStartSaveL); - //registerserver("replayStopSave",&replayStopSaveL); - - -/* //Blocked for now - registerserver("replayViewStart",&replayViewStartL); - registerserver("replayViewStop",&replayViewStopL); - registerserver("replayViewSpeed",&replayViewSpeedL); - - registerclient("replaySaveStart",&replaySaveStartL); - registerclient("replaySaveStop",&replaySaveStopL); - - - //registerserver("replayStopView",&replayStopViewL); - - - InjectJumpTo(0x0045A6F0, &replayOnSpriteRequestTrap); - InjectJumpTo(0x0048E971, &replayOnSpriteCreateTrap);*/ +#include "stdafx.h" +#include "unit.h" +#include +#include +#include +#include +#include +#define REPLAY_VERSION 1 +#define REPLAY_PLAYERSTART_SIZE 0x81 +typedef unsigned int u_int; + + +using namespace std; + +bool replayIsNewPacket=false; +bool replayIsNewMap=false; +void* origClientPacketHandlerEnd; +void* origClientPacketHandlerPointer; +int origClientPacketHandlerSize; +byte* lastEntry; +int lastEntrySize=0; + + + +// импорты из Нокса +bool (__cdecl *noxReplayStartSave)(const char* filename); +void (__cdecl *noxReplayStopSave)(); +bool (__cdecl *noxReplayStartView)(const char* filename); +void (__cdecl *noxReplayStopView)(); +void (__cdecl *sub_470A80)(); +int *mapFrameTime_6F9838; +int (__cdecl *noxNewSessionStart)(); +extern void *(__cdecl *serverGetGameDataBySel)(); +extern void *(__cdecl *serverGetGameData)(int N); +extern char *(__cdecl *mapGetName)(); +extern void teamCreateDefault(int TeamNumParam, bool notRestrict=false); +extern void (__cdecl *consoleServerMapLoad)(int spaceNumber, int tokensNumber, void* tokens); +extern void (__cdecl *guiServerOptionsStartGameMB)(); +extern int (__cdecl *serverModeIndexByModeFlags)(DWORD Flags); +extern short *serverLessonLimitArr; +extern byte *serverTimeLimitArr; +extern int *serverInfoChanged; +extern int (__cdecl *noxCheckGameFlags) (int); +extern void (__cdecl *playerGoObserver)(void* playerPtr, byte unk1, byte unk2); +extern bigUnitStruct* (__cdecl *playerFirstUnit)(); ///возвращает первый юнит сетевого игрока +extern bigUnitStruct* (__cdecl *playerNextUnit)(void* Prev); /// Возвращает следующего сетевого игрока +void* (__cdecl *playerInfoFirst)(); +void* (__cdecl *playerInfoNext)(void* Prev); +int (__cdecl *initGame)(); +extern DWORD *GameFlags; +extern int (__cdecl *netCreatePlayerStartPacket)(void* Dst, void* playerInfo); +int (__cdecl *deletePlayer)(int netCode); +extern BYTE *(__cdecl *playerInfoFromNetCodeCli) (int NetCode); +void* (__cdecl *netOnPacketRecvCli)(int plrId, void* listPtr, int listSize); +extern int (__cdecl *playerKickByIdx)(int playerIdx, int unknownArg); +extern void* getPlayerUDataFromPlayerIdx(int idx); +extern bigUnitStruct *netUnitByCodeServ(DWORD NetCode); +bigUnitStruct* (__cdecl *unitCreateByThingType)(int thingType); + +ServerData replayViewFormGameData; + +enum replayEntries +{ + REPLAY_HEADER, + REPLAY_FRAME, +}; + +struct replayFileHeader +{ + byte entryType; //default: (byte)REPLAY_HEADER + u_int fileVersion; //default: REPLAY_VERSION + u_int fileFramesCount; + char mapName[8]; + __int16 mapMode; + __int16 mapFragLimit; + byte mapTimeLimit; + byte mapPlayersQuantity; + // Followed by a dynamic-sized array of playerStarts packets of players on the map +}; + +struct replayFileFrame +{ + byte entryType; //default: (byte)REPLAY_FRAME + u_int frameId; + u_int frameSize; + // Followed by a dynamic-sized array of bytes with frame data +}; + +// replayView block + + + +namespace +{ + struct replayViewLoadMapStruct + { + char mapName[8]; + __int16 mapMode; + __int16 mapFragLimit; + byte mapTimeLimit; + }; + + bool replayViewEnabled=false; + bool replayViewFormGameRequired=false; + bool replayViewFrameDispatched=false; + bool replayViewRestoreHoster=false; + bool replayViewRestoreHosterFinalize=false; + int replayViewSpeedFactor=0; + int replayViewSpeedFactorCount=0; + map replayViewFakeNetCodes; + u_int replayViewFrameSize=0; + byte* replayViewFrame=NULL; + u_int replayViewFrameCount=0; + u_int replayViewSafeSuspendFrames=0; + replayViewLoadMapStruct replayViewLoadMap; + byte* replayViewHosterData=NULL; + ifstream replayView; + + bool replayViewReadData(); + void replayViewKickAllButHoster(); + + void replayViewStop() + { + *GameFlags=(*GameFlags)|0x1; + replayViewEnabled=false; + replayViewFormGameRequired=false; + replayViewSafeSuspendFrames=0; + if(replayViewFrame!=NULL) + { + delete [] replayViewFrame; + replayViewFrame=NULL; + replayViewFrameSize=0; + } + replayViewFrameDispatched=false; + replayView.close(); + replayView.clear(); + replayViewKickAllButHoster(); + replayViewRestoreHoster=true; + replayViewRestoreHosterFinalize=false; + replayViewFakeNetCodes.clear(); + } + + bool replayViewStart(const char* fileName) + { + replayViewStop(); + replayViewRestoreHoster=false; + for(byte* P=(byte*)playerInfoFirst(); P!=NULL; P=(byte*)playerInfoNext(P)) + { + byte playerIdx = *((byte*)(P+0x810)); + if(playerIdx==0x1F) + { + replayViewHosterData = new byte[REPLAY_PLAYERSTART_SIZE]; + netCreatePlayerStartPacket(replayViewHosterData, P); + } + //REPLAY_PLAYERSTART_SIZE - размер пакета + } + if(replayViewHosterData==NULL) + { + replayViewStop(); + return false; + } + replayView.open(fileName, ios::in | ios::binary); + if(!replayView.is_open()) + { + replayViewStop(); + return false; + } + char fileType[4]; + replayView.read(fileType, 4); + if(replayView.eof() && 0!=strncmp(fileType, "bnru", 4)) + { + replayViewStop(); + return false; + } + + replayViewEnabled=true; + replayViewSafeSuspendFrames=0; + return true; + } + + bool replayViewReadData() + { + u_int packetSize=0; + /*char packetIndicator[6]; + replayView.read(packetIndicator, 5);*/ + replayView.read((char*)&packetSize, sizeof(packetSize)); + if(replayView.eof()) + { + replayViewStop(); + return false; + } + packetSize-=sizeof(packetSize); + u_int currentPosition=replayView.tellg(); + byte packetEntry; + replayView.read((char*)&packetEntry, 1); + if(replayView.eof()) + { + replayViewStop(); + return false; + } + replayView.seekg((u_int)replayView.tellg()-1, ios::beg); + switch(packetEntry) + { + case REPLAY_HEADER: + { + replayFileHeader packetHeader; + replayView.read((char*)&packetHeader, sizeof(packetHeader)); + if(packetHeader.fileVersion>REPLAY_VERSION || replayView.eof()) + { + // Unsupported replay file version + replayViewStop(); + return false; + } + replayViewFrameCount = packetHeader.fileFramesCount; + strncpy(replayViewLoadMap.mapName, packetHeader.mapName, 8); + replayViewLoadMap.mapMode = packetHeader.mapMode; + replayViewLoadMap.mapFragLimit = packetHeader.mapFragLimit; + replayViewLoadMap.mapTimeLimit = packetHeader.mapTimeLimit; + replayViewFrameSize = REPLAY_PLAYERSTART_SIZE*packetHeader.mapPlayersQuantity; + replayViewFrame = new byte[replayViewFrameSize]; + replayView.read((char*)replayViewFrame, replayViewFrameSize); + if(replayView.eof()) + { + replayViewStop(); + return false; + } + replayViewFormGameRequired=true; + replayViewFrameDispatched=true; + } + break; + case REPLAY_FRAME: + { + replayFileFrame packetHeader; + replayView.read((char*)&packetHeader, sizeof(packetHeader)); + if(replayView.eof()) + { + replayViewStop(); + return false; + } + replayViewFrameSize = packetHeader.frameSize; + replayViewFrameDispatched=true; + if(replayViewFrameSize>0) + { + replayViewFrame = new byte[replayViewFrameSize]; + replayView.read((char*)replayViewFrame, replayViewFrameSize); + if(replayView.eof()) + { + replayViewStop(); + return false; + } + } + } + break; + default: + replayView.seekg(currentPosition+packetSize, ios::beg); + } + if((currentPosition+packetSize)!=replayView.tellg()) + { + // File probably corrupted + replayViewStop(); + return false; + } + //replayView.read(packetIndicator, 3); + return true; + } + + void replayViewKickAllButHoster() + { + void* player=playerFirstUnit(); + while(player!=NULL) + { + void **PP=(void **)(((char*)player)+0x2EC); + PP=(void**)(((char*)*PP)+0x114); + byte *P=(byte*)(*PP); + byte playerIdx = *((byte*)(P+0x810)); + if(playerIdx!=0x1F) + { + playerKickByIdx((int)playerIdx, 4); + } + player=playerNextUnit(player); + } + } + + void replayViewLoadFrame(BYTE **frameBuffer, int *size) + { + if(replayViewEnabled) + { + if(replayViewSafeSuspendFrames==0 && replayViewFormGameRequired==false) + { + byte* unitedFrame=NULL; + u_int unitedSize=0; + if(replayViewSpeedFactor<0 && replayViewSpeedFactorCount==0) + replayViewSpeedFactorCount=replayViewSpeedFactor-2; + if(replayViewSpeedFactorCount<0) + { + replayViewSpeedFactorCount++; + if(replayViewSpeedFactorCount<-1) + replayViewFrameDispatched=true; + } + int speedFactor=replayViewSpeedFactor+1; + do + { + speedFactor--; + while(replayViewFrameDispatched==false) + { + if(!replayViewReadData() || replayViewSafeSuspendFrames>0) + { + return; + } + } + replayViewFrameDispatched=false; + u_int unitedSizeBefore=unitedSize; + unitedSize+=replayViewFrameSize; + if(unitedSize>0 && unitedSizeBefore!=unitedSize) + { + unitedFrame=(byte*)realloc(unitedFrame, unitedSize); + memcpy(&unitedFrame[unitedSizeBefore], replayViewFrame, replayViewFrameSize); + } + } + while(speedFactor>0); + *GameFlags=(*GameFlags)^0x1; + *size = unitedSize; + *frameBuffer = unitedFrame; + + } + else + replayViewSafeSuspendFrames--; + *GameFlags=(*GameFlags)|0x1; + } + if(replayViewRestoreHoster) + { + if(replayViewHosterData!=NULL) + { + *size = REPLAY_PLAYERSTART_SIZE; + *frameBuffer = replayViewHosterData; + replayViewRestoreHosterFinalize=true; + } + replayViewRestoreHoster=false; + } + } + + void replayViewFinalizeFrame() + { + if(replayViewEnabled && replayViewFrameDispatched==false) + { + if(replayViewFrame!=NULL) + { + delete[] replayViewFrame; + replayViewFrame=NULL; + replayViewFrameSize=0; + } + } + if(replayViewRestoreHosterFinalize) + { + delete [] replayViewHosterData; + replayViewHosterData=NULL; + replayViewRestoreHosterFinalize=false; + } + } + + void replayViewFormGame() + { + if(replayViewFormGameRequired && replayViewEnabled) + { + *GameFlags=(*GameFlags)|0x1; + ServerData *Data=(ServerData*)serverGetGameDataBySel(); + strncpy(Data->mapName, replayViewLoadMap.mapName, 8); + Data->gameFlags = replayViewLoadMap.mapMode|0xe00f; + Data->fragLimit = replayViewLoadMap.mapFragLimit; + Data->timeLimitMB = replayViewLoadMap.mapTimeLimit; + bool sameMap=false; + if(strcmp(Data->mapName,mapGetName())==0) + { + sameMap=true; + } + + int Index=serverModeIndexByModeFlags(Data->gameFlags); + serverLessonLimitArr[Index]=Data->fragLimit; + serverTimeLimitArr[Index]=Data->timeLimitMB; + *serverInfoChanged=1; + + if(Data->isNew!=1 && Data->gameFlags&0x60) + { + teamCreateDefault(2); + } + else + { + teamCreateDefault(-1); + } + if(sameMap) + { + wchar_t command[5] = L"load"; + wchar_t wMapName[9]={0}; + int *commandPointer=(int*)&command; + int *wMapNamePointer=(int*)&wMapName; + MultiByteToWideChar(CP_ACP, MB_COMPOSITE, Data->mapName, 8, wMapName, 9); + BYTE result[8]={0}; + memcpy(&result[0], &commandPointer, 4); + memcpy(&result[4], &wMapNamePointer, 4); + consoleServerMapLoad(1, 2, (void*)&result); + } + else + { + guiServerOptionsStartGameMB(); + } + replayViewSafeSuspendFrames=30; + replayViewFormGameRequired=false; + } + } + + void replayViewEachFrame() + { + + } + + int replayViewSimulateClient(int gf) + { + if((replayViewEnabled && replayViewSafeSuspendFrames==0) || replayViewRestoreHosterFinalize) + { + return 0; + } + return noxCheckGameFlags(gf); + } + + int replayViewFakeNetcode(int oldNetCode) + { + if(replayViewEnabled) + { + int newNetCode=oldNetCode; + if(replayViewFakeNetCodes.count(oldNetCode)!=0) + newNetCode = replayViewFakeNetCodes[oldNetCode]; + return newNetCode; + } + else + return oldNetCode; + } + + int replayViewFakeNetcodeCreate(int thingType, int oldNetCode) + { + if(replayViewEnabled && replayViewSafeSuspendFrames==0 && replayViewFormGameRequired==false) + { + int newNetCode=oldNetCode; + if(replayViewFakeNetCodes.count(oldNetCode)!=0) + newNetCode = replayViewFakeNetCodes[oldNetCode]; + else if(thingType!=0) + { + u_int currentPosition=replayView.tellg(); + bigUnitStruct* unit = unitCreateByThingType(thingType); + newNetCode = unit->netCode; + replayViewFakeNetCodes[oldNetCode]=newNetCode; + } + return newNetCode; + } + else + return oldNetCode; + } + + int replayViewStopL(lua_State* L) + { + replayViewStop(); + return 0; + } + + int replayViewStartL(lua_State* L) + { + if(lua_type(L, -1)==LUA_TSTRING) + replayViewStart(lua_tostring(L, 1)); + else + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + return 0; + } + + int replayViewSpeedL(lua_State* L) + { + if(lua_type(L, -1)==LUA_TNUMBER) + { + int coef = lua_tonumber(L, 1); + if(coef>=-10 && coef<=10) + { + replayViewSpeedFactor=coef; + } + else + { + lua_pushstring(L,"wrong args: value out of bounds!"); + lua_error_(L); + } + } + else + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + return 0; + } + + + //replaySave block + bool replaySaveEnabled=false; + bool replaySaveFrameSaved=false; + u_int replaySaveDropFrame=0; + char* replaySaveFileName = NULL; + byte* replaySaveHeader = NULL; + u_int replaySaveHeaderSize=0; + ofstream replaySave; + u_int replaySaveFrameCount=0; + u_int replaySavePreviousMapLocation=0; + byte* replaySaveFramePackets=NULL; + byte* replaySaveFramePacketsSeeker=NULL; + byte* replaySaveFramePacketsEnd=NULL; + byte* replaySaveFramePayload=NULL; + u_int replaySaveFramePayloadSize=0; + byte* replaySaveFrameBaseAddress=NULL; + + bool replaySaveWriteData(replayEntries type, void* payload=NULL, u_int size=0); + + void replaySaveStop(bool resetFileName=true) + { + if(resetFileName && replaySaveFileName!=NULL) + { + delete [] replaySaveFileName; + replaySaveFileName=NULL; + replaySaveEnabled=false; + } + if(replaySave.is_open()) + { + replaySaveWriteData(REPLAY_HEADER); + } + replaySaveFrameCount=0; + if(replaySaveHeader!=NULL) + { + delete [] replaySaveHeader; + replaySaveHeader=NULL; + } + replaySaveDropFrame=0; + replaySaveHeaderSize=0; + replaySaveFrameBaseAddress=NULL; + replaySaveFrameSaved=false; + replaySave.close(); + replaySave.clear(); + } + + bool replaySaveStart(const char* fileName=NULL, unsigned int fileNameLength=0) + { + if(fileNameLength>0) + { + if(replaySaveFileName!=NULL) + { + replaySaveStop(); + } + else + replaySaveStop(!replaySaveEnabled); + replaySaveFileName = new char[fileNameLength+1]; + memset(replaySaveFileName, 0, fileNameLength+1); + strncpy(replaySaveFileName, fileName, fileNameLength); + } + else + replaySaveStop(!replaySaveEnabled); + string fileNameFull="replays/"; + TIME_ZONE_INFORMATION tz; + SYSTEMTIME time; + GetLocalTime(&time); + GetTimeZoneInformation(&tz); + char timeZone[7]; + if(tz.Bias==0) + strcpy(timeZone, "Z"); + else + { + char symbol=(tz.Bias>0)?('-'):('+'); + u_int tzHours = floor((long double)(abs(tz.Bias)/60)); + u_int tzMinutes = abs(tz.Bias)%60; + sprintf(timeZone, "%c%02u.%02u", symbol, tzHours, tzMinutes); + } + char timeStamp[30]; + // Почти ISO 8601 (к сожалению двоеточия в имени файлов не допустимы) + sprintf(timeStamp, "%04i-%02i-%02iT%02i.%02i.%02i.%03i%s", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, time.wMilliseconds, timeZone); + if(strlen(replaySaveFileName)>0) + { + fileNameFull.append(replaySaveFileName); + fileNameFull.append("_"); + } + fileNameFull.append(timeStamp); + fileNameFull.append("_"); + fileNameFull.append(mapGetName()); + fileNameFull.append(".nru"); + replaySave.open(fileNameFull.c_str(), ios::out | ios::trunc | ios::binary); + if(!replaySave.is_open()) + { + replaySaveStop(); + return false; + } + replaySave.write("bnru", 4); // Ставим метку формата, заодно тестируем, работает ли запись + if(!replaySave.is_open()) + { + replaySaveStop(); + return false; + } + replaySaveEnabled=true; + replaySaveFrameCount=0; + replaySaveWriteData(REPLAY_HEADER); + return true; + } + + void replaySaveWriteFrameCount() + { + u_int currentPosition=replaySave.tellp(); + u_int offset=4+1+sizeof(u_int); + replaySave.seekp(offset, ios::beg); + replaySave.write((const char*)&replaySaveFrameCount, sizeof(u_int)); + replaySave.seekp(currentPosition, ios::beg); + } + + + bool replaySaveWriteData(replayEntries type, void* payload, u_int size) + { + if(!replaySave.is_open()) + { + replaySaveStop(); + return false; + } + + + u_int totalLength=0; + byte* packet; + switch(type) + { + case REPLAY_HEADER: + { + // Готовим данные. Для определения размеров + if(replaySaveHeader==NULL) + { + byte* playersList=NULL; + byte playersListQuantity=0; + for(void* P=playerInfoFirst(); P!=NULL; P=playerInfoNext(P)) + { + playersListQuantity+=1; + playersList=(byte*)realloc(playersList, playersListQuantity*REPLAY_PLAYERSTART_SIZE); + netCreatePlayerStartPacket(&playersList[(playersListQuantity-1)*REPLAY_PLAYERSTART_SIZE], P); + //REPLAY_PLAYERSTART_SIZE - размер пакета + } + + // Формируем заголовок пакета + replayFileHeader* packetHelper = new replayFileHeader; + memset(packetHelper, 0, sizeof(packetHelper)); + packetHelper->entryType=REPLAY_HEADER; + packetHelper->fileVersion=REPLAY_VERSION; + packetHelper->fileFramesCount=replaySaveFrameCount; + strncpy(packetHelper->mapName, mapGetName(),8); + packetHelper->mapMode=(__int16)*GameFlags&0x1FF0; + int Index=serverModeIndexByModeFlags(*GameFlags); + packetHelper->mapFragLimit=serverLessonLimitArr[Index]; + packetHelper->mapTimeLimit=serverTimeLimitArr[Index]; + packetHelper->mapPlayersQuantity=playersListQuantity; + replaySaveHeaderSize=sizeof(replayFileHeader)+playersListQuantity*REPLAY_PLAYERSTART_SIZE; + replaySaveHeader = new byte[replaySaveHeaderSize]; + memcpy(replaySaveHeader, packetHelper, sizeof(replayFileHeader)); + memcpy(&replaySaveHeader[sizeof(replayFileHeader)], playersList, playersListQuantity*REPLAY_PLAYERSTART_SIZE); + // Зачистка временных данных + realloc(playersList, 0); + delete [] packetHelper; + } + else + { + replayFileHeader* packetHelper = (replayFileHeader*)replaySaveHeader; + packetHelper->fileFramesCount=replaySaveFrameCount; + } + + // Подготовка данных завершена. Формируем сам пакет + packet=new byte[replaySaveHeaderSize]; + memset(packet, 0, replaySaveHeaderSize); + memcpy(packet, replaySaveHeader, replaySaveHeaderSize); + totalLength+=replaySaveHeaderSize; // финальный размер пакета + + + } + break; + case REPLAY_FRAME: + { + // Формируем заголовок пакета + replayFileFrame* packetHelper = new replayFileFrame; + memset(packetHelper, 0, sizeof(packetHelper)); + packetHelper->entryType=REPLAY_FRAME; + packetHelper->frameId=replaySaveFrameCount; + packetHelper->frameSize = size; + + // Подготовка данных завершена. Формируем сам пакет + packet=new byte[sizeof(replayFileFrame)+size]; + memset(packet, 0, sizeof(replayFileFrame)+size); + memcpy(packet, packetHelper, sizeof(replayFileFrame)); + memcpy(&packet[sizeof(replayFileFrame)], payload, size); + totalLength+=sizeof(replayFileFrame)+size; + + // Зачистка временных данных + delete [] packetHelper; + } + break; + } + u_int relocate=0; + if(type==REPLAY_HEADER) + { + relocate=replaySave.tellp(); + if(relocate>4) + replaySave.seekp(4, ios::beg); + } + /*char packetIndicator[6]; + strncpy(packetIndicator,"start", 5); + replaySave.write(packetIndicator, 5);*/ + totalLength+=sizeof(totalLength); + replaySave.write((const char*)&totalLength, sizeof(totalLength)); + replaySave.write((const char*)packet, totalLength-sizeof(totalLength)); + /*strncpy(packetIndicator,"end", 3); + replaySave.write(packetIndicator, 3);*/ + if(type==REPLAY_HEADER && relocate>4) + { + replaySave.seekp(relocate, ios::beg); + } + delete [] packet; + } + + void replaySaveAddFramePayload(byte* payload, int size) + { + if(size>0) + { + replaySaveFramePayload=(byte*)realloc(replaySaveFramePayload, replaySaveFramePayloadSize+size); + byte* pointer=replaySaveFramePayload+replaySaveFramePayloadSize; + memset(pointer, 0, size); + memcpy(pointer, payload, size); + } + replaySaveFramePayloadSize+=size; + } + + bool replaySaveFullFrame(BYTE *BufStart, int size) + { + if(replaySaveEnabled) + { + // Сохраняем весь фрейм в буффер, потом от него будем отрезать попакетно. Заодно сейвим в файл инфу о новом фрейме. Нужно чтоб в реплей не попали "лишние" пакеты. + if(size>0) + { + replaySaveFramePackets = new byte[size]; + memcpy(replaySaveFramePackets, BufStart, size); + } + replaySaveFramePacketsSeeker=replaySaveFramePackets; + replaySaveFramePacketsEnd=replaySaveFramePackets+size; + replaySaveFrameCount++; + replaySaveFrameBaseAddress=BufStart; + + return true; + } + return false; + } + + bool replaySavePacketChecker(byte* packet, int size) + { + // Здесь мы просто проверим, пихать ли этот пакет в реплей или ну его нафиг. + byte *P = packet; + bool allowed=true; //Если пакет проверку не проходит - false + // Тут осуществлять проверку пакета на вносимость в реплей. На коды пакетов. + if(*P==0x2B) + { + // Обработка смены мапы + allowed=false; + replaySaveDropFrame=5; // Дропаем фреймы, что на стыке двух файлов + replaySaveStart(); //Рестарт процесса происходит (для записи в новый файл). Заметьте - без стопа. Стоп обрабатывается в самом начале replaySaveStart. Эксплиситный стоп нуже для финализации всего процесса. + } + if(*P==0x6C) + { + allowed=false; + } + if(*P==0x6D) + { + allowed=false; + } + if(allowed) + { + replaySaveAddFramePayload(packet, size); + } + return true; + } + + bool replaySavePacketHandler(BYTE *&BufStart, BYTE *&E, bool &found) + { + if(replaySaveEnabled) + { + // Анализ пакетов - отрезаем по-пакетно от общего буфера фрейма. BufStart после анализа пакета самим обработчиком сдвигается вперёд, что позволяет нам засечь пакет. + u_int size=BufStart-replaySaveFrameBaseAddress; + if(size>0 && (replaySaveFramePacketsSeeker+size)<=replaySaveFramePacketsEnd) + { + byte* packet = new byte[size]; + memcpy(packet, replaySaveFramePacketsSeeker, size); + replaySavePacketChecker(packet, size); + delete [] packet; + replaySaveFramePacketsSeeker+=size; + } + replaySaveFrameBaseAddress=BufStart; + return true; + } + return false; + } + + bool replaySaveFinalizeFrame() + { + if(replaySaveEnabled) + { + // Анализ последнего пакета - отрезаем по-пакетно. Вызов в самм конце обработчика пакетов. + if(replaySaveFramePacketsSeeker<=replaySaveFramePacketsEnd) + { + u_int size=replaySaveFramePacketsEnd-replaySaveFramePacketsSeeker; + replaySaveFrameBaseAddress=NULL; + if(size>0) + { + byte* packet = new byte[size]; + memcpy(packet, replaySaveFramePacketsSeeker, size); + replaySaveFramePacketsSeeker=replaySaveFramePacketsEnd; + replaySavePacketChecker(packet, size); + } + // Финализируем фрейм (пишем в файл) - если не надо дропать фрейм. Фрейм дропается на стыке между двумя файлами. + if(replaySaveDropFrame==0) + replaySaveWriteData(REPLAY_FRAME, replaySaveFramePayload, replaySaveFramePayloadSize); + else + replaySaveDropFrame--; + replaySaveFrameSaved = true; + // Зачищаем + replaySaveFramePayloadSize=0; + if(replaySaveFramePayload!=NULL) + { + realloc(replaySaveFramePayload, 0); + replaySaveFramePayload=NULL; + } + if(replaySaveFramePackets!=NULL) + { + delete [] replaySaveFramePackets; + replaySaveFramePackets=NULL; + } + replaySaveFramePacketsSeeker=NULL; + replaySaveFramePacketsEnd=NULL; + } + return true; + } + return false; + } + + void replaySaveZeroFrame() + { + if(replaySaveEnabled && replaySaveDropFrame==0) + { + if(replaySaveFrameSaved) + { + replaySaveFrameSaved=false; + } + else + { + replaySaveWriteData(REPLAY_FRAME); + } + } + } + + int replaySaveStopL(lua_State* L) //обёртка для ЛУА + { + replaySaveStop(); + return 0; + } + + int replaySaveStartL(lua_State* L) //обёртка для ЛУА + { + if(lua_type(L, -1)==LUA_TSTRING) + { + const char *S=lua_tostring(L,-1); + if(replaySaveStart(S, strlen(S))) + return 0; + else + { + lua_pushstring(L,"file save error!"); + lua_error_(L); + } + } + else + { + if(replaySaveStart()) + return 0; + else + { + lua_pushstring(L,"file save error!"); + lua_error_(L); + } + } + return 0; + } + + //common replay block + + //Самый конец netOnPacketRecvCli. + void clientPacketHandlerEnd(void* BufStart, int size, int edx, int ecx, int eax, void* returnFunction) + { + returnFunction = origClientPacketHandlerEnd; + BufStart = origClientPacketHandlerPointer; + size = origClientPacketHandlerSize; + replaySaveFinalizeFrame(); + replayViewFinalizeFrame(); + } + + //internal - что-то из области чёрной магии. Сам уже не помню что. + void __declspec(naked) clientPacketHandlerEndTrap() + { + __asm + { + push 0 + push eax + push ecx + push edx + push 0 + push 0 + call clientPacketHandlerEnd + pop edx + pop ecx + mov [esp+16+4], edx + mov [esp+16+4+4], ecx + pop edx + pop ecx + pop eax + ret + } + } + + // Самое начало netOnPacketRecvCli. Адрес возврата, начало обрабатываемого буфера и размер + void* __cdecl replayInterceptClientPackets(void* noxOrigClientPacketHandlerEnd, BYTE *BufStart, int size) //Внимание! Модификация переменных функции приведёт к изменению оных в onPacketRecvCli! + { + origClientPacketHandlerEnd=noxOrigClientPacketHandlerEnd; // Здесь адрес старого return-а. + origClientPacketHandlerPointer=BufStart; + origClientPacketHandlerSize=size; + replaySaveFullFrame(BufStart, size); + replayViewLoadFrame(&BufStart, &size); + return &clientPacketHandlerEndTrap; // Подмена return-а из onNetPacketCli. + } + + //internal + void __cdecl packetHandlerBegin() + { + //replayIsNewPacket=true; + sub_470A80(); + } + + //internal - тож чёрная магия. + void __declspec(naked) clientPacketHandlerBeginTrap() + { + __asm + { + push eax + push ebp + mov eax, [esp+0x1748+4+8] // Вытаскиваем адрес стандартного return-а + push eax + call replayInterceptClientPackets + mov [esp+0x1748+4+8+4], eax // Подмена return-а из onNetPacketCli. + pop eax + pop ebp + pop eax + lea ebx, [eax+ebp] + mov [esp+0x1748+4-0x1704], ebx //Последняя позиция в стеке перед call - 1748h. Позиция в стеке переменной - -1704h. Соотв. +4 (адрес возврата по ret) + mov [esp+0x1748+4+0x8], ebp //Аналогично предыдущему + mov [esp+0x1748+4+0xC], eax //Аналогично предыдущему + call packetHandlerBegin + ret + } + } +} +void replayGuiUpdate() +{ + replaySaveZeroFrame(); + replayViewFormGame(); +} + +//onNetPacket для реплеев. +bool replayPacketHandler(BYTE *&BufStart, BYTE *&E, bool &found) +{ + replaySavePacketHandler(BufStart, E, found); + return true; +} + +void __cdecl replayQuitGame() +{ + replaySaveStop(); + replayViewStop(); + // + noxReplayStopSave(); +} + +void replayEachFrame() +{ + replayViewEachFrame(); +} + +int __cdecl replayOnSpriteRequest(int oldNetCode) +{ + //return replayViewFakeNetcode(oldNetCode); + return oldNetCode; +} + +int __cdecl replayOnSpriteCreate(int thingType, int oldNetCode) +{ + //return replayViewFakeNetcodeCreate(thingType, oldNetCode); + return oldNetCode; +} + +void __declspec(naked) replayOnSpriteRequestTrap() +{ + __asm + { + mov eax, [esp+4] + push eax + call replayOnSpriteRequest + add esp, 4 + mov [esp+4], eax + mov eax, 0x006D3DC0 + mov eax, [eax] + test eax,eax + push 0x0045A6F7 + ret + } +} + +void __declspec(naked) replayOnSpriteCreateTrap() +{ + __asm + { + push esi + mov esi, [esp+8+8] + push eax + mov eax, [esp+8+4+4] + push esi + push eax + call replayOnSpriteCreate + add esp,8 + mov esi,eax + pop eax + mov [esp+8+8],esi + push 0x0048E976 + ret + } +} + +void replayNullSub() +{ + return; +} + +extern "C" void replayInit(lua_State *L); + + +extern void InjectOffs(DWORD Addr,void *Fn); +extern void InjectJumpTo(DWORD Addr,void *Fn); + +void replayInit(lua_State *L) +{ + /* + //Blocked for now + ASSIGN(noxReplayStartSave, 0x004D3370); + ASSIGN(noxReplayStopSave, 0x004D33B0); + ASSIGN(noxReplayStartView, 0x004D34C0); + ASSIGN(noxReplayStopView, 0x004D3530); + + ASSIGN(sub_470A80, 0x00470A80); + + ASSIGN(mapFrameTime_6F9838, 0x006F9838); + //ASSIGN(initGame, 0x00435CC0); + ASSIGN(deletePlayer, 0x004DE7C0); + + ASSIGN(playerInfoFirst, 0x00416EA0); + ASSIGN(playerInfoNext, 0x00416EE0); + + ASSIGN(netOnPacketRecvCli, 0x0048EA70); + + ASSIGN(unitCreateByThingType, 0x004E3450); + + InjectOffs(0x0048EA9B+1, clientPacketHandlerBeginTrap); + //InjectOffs(0x004018EF+1, replayStartSave); + InjectOffs(0x004D3219+1, replayQuitGame); + + InjectOffs(0x004908CF+1, replayViewSimulateClient); + InjectOffs(0x00491D63+1, replayViewSimulateClient); + //InjectOffs(0x0048EB87+1, replayViewSimulateClient); + //InjectOffs(0x0048EBAA+1, replayViewSimulateClient); + InjectOffs(0x0048F2E7+1, replayViewSimulateClient); + InjectOffs(0x0048F46A+1, replayViewSimulateClient); + InjectOffs(0x0048F694+1, replayViewSimulateClient); + //InjectOffs(0x0048FA27+1, replayViewSimulateClient); + //InjectOffs(0x0048FA49+1, replayViewSimulateClient); + InjectOffs(0x0048FC39+1, replayViewSimulateClient); + InjectOffs(0x0048FC67+1, replayViewSimulateClient); + InjectOffs(0x0048FCB5+1, replayViewSimulateClient); + InjectOffs(0x004903C6+1, replayViewSimulateClient); + InjectOffs(0x004908CF+1, replayViewSimulateClient); + InjectOffs(0x00490A1B+1, replayViewSimulateClient); + InjectOffs(0x00490D39+1, replayViewSimulateClient); + InjectOffs(0x00490E23+1, replayViewSimulateClient); + InjectOffs(0x00490F9F+1, replayViewSimulateClient); + InjectOffs(0x0049127A+1, replayViewSimulateClient); + InjectOffs(0x00491592+1, replayViewSimulateClient); + //InjectOffs(0x00491A3A+1, replayViewSimulateClient); + InjectOffs(0x0049302F+1, replayViewSimulateClient); + //InjectOffs(0x00493B3A+1, replayViewSimulateClient); + InjectOffs(0x00493BB5+1, replayViewSimulateClient); + + InjectOffs(0x0048E9F9+1, replayNullSub);*/ +/* //Blocked permanently + InjectOffs(0x00491D63+1, replayViewSimulateClient); + + InjectOffs(0x00409DE6+1, replaySaveNewMapLoading); + InjectOffs(0x00491EED+1, replaySavePlayerLeaving); + +*/ + + //registerserver("replayStartSave",&replayStartSaveL); + //registerserver("replayStopSave",&replayStopSaveL); + + +/* //Blocked for now + registerserver("replayViewStart",&replayViewStartL); + registerserver("replayViewStop",&replayViewStopL); + registerserver("replayViewSpeed",&replayViewSpeedL); + + registerclient("replaySaveStart",&replaySaveStartL); + registerclient("replaySaveStop",&replaySaveStopL); + + + //registerserver("replayStopView",&replayStopViewL); + + + InjectJumpTo(0x0045A6F0, &replayOnSpriteRequestTrap); + InjectJumpTo(0x0048E971, &replayOnSpriteCreateTrap);*/ } \ No newline at end of file diff --git a/score.cpp b/score.cpp index 34a0513..5dd3808 100644 --- a/score.cpp +++ b/score.cpp @@ -1,899 +1,899 @@ -#include "stdafx.h" -#include "unit.h" -#include "player.h" -#include -#include -#include "winsock2.h" - -extern void *(__cdecl *serverGetGameDataBySel)(); - -/* - / .. -*/ -extern DWORD *GameFlags; -extern int playersListL(lua_State *L); -void teamCreateDefault(int TeamNum, bool notRestrict); -int minTeams=2; -bool restrictTeams=false; -int (__cdecl *netReportScore)(void *Player); -void (__cdecl *playerAddFragDeathmatch)(void *Victim,void *Attacker,void *A,void *B); - -int (__cdecl *noxTeamCanPlayGame)(); // .. - -void *(__cdecl *netCommonByCode)(int NetCode); - -void *(__cdecl *noxGetTeamFirst)(); -void *(__cdecl *noxGetTeamNext)(void *Prev); -void *(__cdecl *noxGetTeamByN)(int N); -void (__cdecl *netSendTeamFrags)(void *Team,int Frags); - -void *(__cdecl *noxTeamCreate)(int N); -void (__cdecl *noxCreateAtImpl)(int TeamID, void* Common, bool wasInTeam, int netCode, int unknown); -void (__cdecl *noxTeamChange)(void* Common, void* teamPtr, int netCode, int unknown); -void (__cdecl *noxTeamDelete)(void *TeamPtr,int SendClient); -void (__cdecl *teamSendTeam)(void *TeamPtr); -void (__cdecl *noxTeamUpdate)(void *newName, void *TeamPtr); -void (__cdecl *serverFlagsSet)(DWORD V); -void (__cdecl *serverFlagsClear)(DWORD V); -wchar_t *(__cdecl *noxTeamDefaultName)(int color); -extern byte authorisedState[0x20]; -extern char* authorisedLogins[0x20]; - -void* noxNetStructList; - -namespace -{ - - int scoreFragLimitL(lua_State*L) - { - ServerData* servdata = (ServerData*)serverGetGameDataBySel(); - unsigned int fraglimit = servdata->fragLimit; - lua_pushnumber(L, fraglimit); - return 1; - } - - int scoreTimeLimitL(lua_State*L) - { - ServerData* servdata = (ServerData*)serverGetGameDataBySel(); - unsigned int timelimit = servdata->timeLimitMB; - lua_pushnumber(L, timelimit); - return 1; - } - - struct pTeam - { - char name[20]; - char gap_14[20]; - __int16 nameLastChar; - char gap_2a[2]; - int firstAllyTeam; - int membersCount; - int teamFrags; - char teamColorNMB; - char teamId; - char teamId2; - char gap_3b[1]; - void* somePtr; - int field_40; - int haveNameMB; - int flagPtr; - int field_4C; - }; - - - int teamCanPlayGameImpl() // - { - int Top=lua_gettop(L); - getServerVar("teamCanStart"); - int Ret=0; - if (lua_type(L,-1)!=LUA_TNIL) - Ret=(lua_toboolean(L,-1))?2:1; - lua_settop(L,Top); - return Ret; - } - - int __declspec(naked) teamCanPlayGame() - { - __asm - { - call teamCanPlayGameImpl - test eax,eax - jz l1 - dec eax - ret -l1: - push ebx - push edi - push 4 - xor ebx,ebx - push 0x0040A8A6 - ret - }; - } - - int noxTeamNumber() - { - int i=0; - for (pTeam *Test=(pTeam *)noxGetTeamFirst();Test!=NULL;Test=(pTeam *)noxGetTeamNext(Test)) - { - i++; - } - return i; - } - int teamGet(lua_State *L) - { - lua_settop(L,2); - if ((lua_type(L,1)==LUA_TNUMBER) || (lua_type(L,1)==LUA_TLIGHTUSERDATA)) - { - pTeam *Team=0; - if ((lua_type(L,1)==LUA_TNUMBER)) - Team=(pTeam *)noxGetTeamByN(lua_tointeger(L,1)); - else - Team=(pTeam *)lua_touserdata(L,1); - if (!Team) - { - lua_pushnil(L); - return 1; - } - lua_newtable(L); - lua_pushinteger(L,Team->teamId); - lua_setfield(L,-2,"id"); - char TeamName[0x20]={0}; - wcstombs(TeamName,(wchar_t*)Team,0x14); - lua_pushstring(L,TeamName); - lua_setfield(L,-2,"name"); - lua_pushinteger(L,Team->teamColorNMB); - lua_setfield(L,-2,"color"); - lua_pushinteger(L,Team->membersCount); - lua_setfield(L,-2,"membersCount"); - lua_pushinteger(L,Team->teamFrags); - lua_setfield(L,-2,"score"); - if ( lua_toboolean(L,2)==1) /// - { - lua_pushlightuserdata(L,Team); - lua_setfield(L,-2,"teamPtr"); - if (Team->somePtr) - lua_pushlightuserdata(L,Team->somePtr); - else - lua_pushnil(L); - lua_setfield(L,-2,"flagPtr"); - } - - return 1; - } - lua_newtable(L); - pTeam *Test=(pTeam *)noxGetTeamFirst(); - for (int i=1;Test!=NULL;Test=(pTeam *)noxGetTeamNext(Test),i++) - { - //lua_pushinteger(L,Test->teamId); - //lua_pushvalue(L,2); - pTeam *Team=Test; - if (!Team) - { - lua_pushnil(L); - return 1; - } - lua_newtable(L); - lua_pushinteger(L,Team->teamId); - lua_setfield(L,-2,"id"); - char TeamName[0x20]={0}; - wcstombs(TeamName,(wchar_t*)Team,0x14); - lua_pushstring(L,TeamName); - lua_setfield(L,-2,"name"); - lua_pushinteger(L,Team->teamColorNMB); - lua_setfield(L,-2,"color"); - lua_pushinteger(L,Team->membersCount); - lua_setfield(L,-2,"membersCount"); - lua_pushinteger(L,Team->teamFrags); - lua_setfield(L,-2,"score"); - if ( lua_toboolean(L,2)==1) /// - { - lua_pushlightuserdata(L,Team); - lua_setfield(L,-2,"teamPtr"); - if (Team->somePtr) - lua_pushlightuserdata(L,Team->somePtr); - else - lua_pushnil(L); - lua_setfield(L,-2,"flagPtr"); - } - lua_pushinteger(L,i); - lua_pushvalue(L,-2); - lua_settable(L,3);/// - lua_settop(L,3);//2 + 1 - } - return 1; - } - - int playerGetByName(lua_State *L) - { - if(lua_type(L, -1)==LUA_TSTRING) - { - const char *S=lua_tostring(L,-1); - bool found=false; - for(void *Pl=playerFirstUnit(); Pl!=0; Pl=playerNextUnit(Pl)) - { - void **PP=(void **)(((char*)Pl)+0x2EC); - PP=(void**)(((char*)*PP)+0x114); - byte *P=(byte*)(*PP); - char Name[0x50]={0}; - wcstombs(Name,((wchar_t*)(P+0x1260)),0x50); - if(strcmp(Name,S)==0) - { - found=true; - lua_pushlightuserdata(L, Pl); - break; - } - } - if(found==false) - { - lua_pushstring(L,"not found!"); - lua_error_(L); - } - } - else - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - return 1; - } - - int playerGetByWOL(lua_State *L) - { - if(lua_type(L, -1)==LUA_TSTRING) - { - const char *S=lua_tostring(L,-1); - bool found=false; - for(void *Pl=playerFirstUnit(); Pl!=0; Pl=playerNextUnit(Pl)) - { - void **PP=(void **)(((char*)Pl)+0x2EC); - PP=(void**)(((char*)*PP)+0x114); - byte *P=(byte*)(*PP); - char WOL[0x20]={0}; - strncpy(WOL,((char*)(P+0x830)),0x20); - if(strcmp(WOL,S)==0) - { - found=true; - lua_pushlightuserdata(L, Pl); - break; - } - } - if(found==false) - { - lua_pushstring(L,"not found!"); - lua_error_(L); - } - } - else - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - return 1; - } - - int playerInfo(lua_State *L) - { - lua_settop(L,1); - if ( - (lua_type(L,1)!=LUA_TLIGHTUSERDATA) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - DWORD *DW=(DWORD*)lua_touserdata(L,1); - if (0==(DW[2] & 0x4)) - { - lua_pushstring(L,"wrong args: unit is not a player!"); - lua_error_(L); - } - BYTE *unit=(BYTE*)lua_touserdata(L,1); - void **PP=(void **)(((char*)unit)+0x2EC); - PP=(void**)(((char*)*PP)+0x114); - byte *P=(byte*)(*PP); - lua_newtable(L); - lua_pushinteger(L,*((short*)(P+0x864))); - lua_setfield(L,-2,"ping"); - lua_pushinteger(L,*((int*)(P+0x858))); - lua_setfield(L,-2,"score"); - lua_pushinteger(L,(*((int*)(P+0xE60)))&0x1); - lua_setfield(L,-2,"isObserver"); - char Name[0x50]={0}; - wcstombs(Name,((wchar_t*)(P+0x1260)),0x50); - lua_pushstring(L,Name); - lua_setfield(L,-2,"name"); - char WOL[0x20]={0}; - strncpy(WOL,((char*)(P+0x830)),0x20); - lua_pushstring(L,WOL); - lua_setfield(L,-2,"wol"); - byte idx = *((byte*)(P+0x810)); - lua_pushinteger(L,idx); - lua_setfield(L,-2,"idx"); - void* netStructListPlayer; - if(idx<0x1F) - { - netStructListPlayer=(byte*)noxNetStructList+(1+idx)*4; - BYTE* addrStruct = *((BYTE**)netStructListPlayer); - in_addr* address=(in_addr*)(addrStruct+8); - lua_pushstring(L,inet_ntoa(*address)); - } - else - lua_pushstring(L,"127.0.0.1"); - lua_setfield(L,-2,"ip"); - int Class=*((byte*)(P+0x8CB)); - lua_pushinteger(L,Class); - lua_setfield(L,-2,"class"); - if (Class==0) - lua_pushstring(L,"WAR"); - else if (Class==1) - lua_pushstring(L,"WIZ"); - else if (Class==2) - lua_pushstring(L,"CON"); - else - lua_pushstring(L,"UNK"); - - lua_setfield(L,-2,"className"); - - int NetCode=*((short*)(P+0x80C)); - byte *Common=(byte *)netCommonByCode(NetCode); - lua_pushinteger(L,NetCode); - lua_setfield(L,-2,"netcode"); - byte playerIdx = *((byte*)(P+0x810)); - if(authorisedState[playerIdx]==4) - lua_pushstring(L,authorisedLogins[playerIdx]); - else - lua_pushstring(L,""); - lua_setfield(L,-2,"login"); - int TeamId=*((int*)(unit+0x34)); - byte *Team=NULL; - if (TeamId>0) - { - Team=(byte *)noxGetTeamByN(TeamId); - } - if (Team!=NULL) - { - lua_pushinteger(L,TeamId); - lua_setfield(L,-2,"teamId"); - wcstombs(Name,(wchar_t*)Team,0x14); - lua_pushstring(L,Name); - lua_setfield(L,-2,"teamName"); - lua_pushinteger(L,*((int *)(Team+0x34))); - lua_setfield(L,-2,"teamScore"); - - } - - return 1; - } - void *teamGetByLua(lua_State *L) - { - if ( - (lua_type(L,1)!=LUA_TLIGHTUSERDATA) && - (lua_type(L,1)!=LUA_TNUMBER) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - void *Team=0; - if (lua_type(L,1)==LUA_TLIGHTUSERDATA) - { - Team=lua_touserdata(L,1); - void *Test=noxGetTeamFirst(); - for (;Test!=NULL;Test=noxGetTeamNext(Test)) - { - if (Test==Team) - break; - } - if (Test==NULL) - { - lua_pushstring(L,"wrong args - not a team!"); - lua_error_(L); - } - } - else - { - Team=noxGetTeamByN(lua_tointeger(L,1)); - if (Team==NULL) - { - lua_pushstring(L,"wrong args: wrong team N!"); - lua_error_(L); - } - } - return Team; - } - int teamDelete(lua_State *L) - { - void* teamPtr=teamGetByLua(L); - bool allowDelete=true; - if(restrictTeams==true) - { - for(int i=1; i<=minTeams; i++) - { - void* TeamTest=noxGetTeamByN(i); - if(TeamTest==teamPtr) - { - allowDelete=false; - break; - } - } - } - if(allowDelete==true) - noxTeamDelete(teamPtr,1); - else - { - lua_pushstring(L,"Can't delete first teams on that map!"); - lua_error_(L); - } - void *Test=noxGetTeamFirst(); - if (Test==NULL) - serverFlagsClear(4);/// - - return 0; - } - - int teamCreateDefaultL(lua_State *L) - { - int param=0; - bool param2=false; - if (lua_type(L,1)==LUA_TNUMBER) - { - lua_newtable(L); - lua_pushvalue(L,1); - lua_setfield(L,-2,"limit"); - lua_remove(L,1); - } - if(lua_type(L,1)==LUA_TTABLE) - { - lua_getfield(L,1,"limit"); - if (lua_type(L,-1)==LUA_TNUMBER) - { - param=lua_tointeger(L,-1); - } - lua_getfield(L,1,"norestrict"); - if (lua_type(L,-1)!=LUA_TNIL) - { - param2=lua_toboolean(L,-1); - } - } - teamCreateDefault(param, param2); - return 0; - } - int teamCreate(lua_State *L) - { - void *R=NULL; - lua_settop(L,2); - int id=0; - if (lua_type(L,1)==LUA_TTABLE) - { - lua_getfield(L,1,"id"); - id=lua_tointeger(L,-1); - } - bool newTeam=false; - if (id>0) - { - R=noxGetTeamByN(id); - } - else - { - newTeam=true; - R=noxTeamCreate(id); - } - if (R==NULL) - { - lua_pushnil(L); - return 1; - } - serverFlagsSet(4);/// - wchar_t* RR=NULL; - bool RRR=false;// - if (lua_type(L,1)==LUA_TTABLE) - { - lua_getfield(L,1,"color"); - if (!lua_isnil(L,-1)) - { - ((byte*)R)[0x38]=lua_tointeger(L,-1); - } - lua_getfield(L,1,"name"); - const char *S=lua_tostring(L,-1); - if (S) - { - mbstowcs((wchar_t*)R,S,0x14); - RR = (wchar_t*)R; - ((byte*)R)[0x44]=1; - RRR=true; - } - else if(newTeam==true) - { - RR=noxTeamDefaultName(((byte*)R)[0x38]);// - CSF-, - memcpy(R, RR, 0x28); - ((byte*)R)[0x44]=1; - } - } - else if(newTeam==true) - { - RR=noxTeamDefaultName(((byte*)R)[0x38]);// - CSF-, - memcpy(R, RR, 0x28); - ((byte*)R)[0x44]=1; - } - teamSendTeam(R); // - - Ψ (!) - if(RRR==true) - noxTeamUpdate(RR, R); // - , , - lua_pushlightuserdata(L,R); - return 1; - } - - int teamScore(lua_State *L) - { - void *Team=teamGetByLua(L); - - int *Ret=(int *)(((char*)Team)+0x34); - lua_settop(L,2); - lua_pushinteger(L,*Ret); - if (lua_type(L,2)!=LUA_TNIL) - { - *Ret=lua_tointeger(L,2); - netSendTeamFrags(Team,*Ret); - } - return 1; - } - int teamName(lua_State *L) - { - void *Team=teamGetByLua(L); - - return 1; - } - int playerScore(lua_State *L) - { - if ( - (lua_type(L,1)!=LUA_TLIGHTUSERDATA) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - DWORD *DW=(DWORD*)lua_touserdata(L,1); - if (0==(DW[2] & 0x4)) - { - lua_pushstring(L,"wrong args: unit is not a player!"); - lua_error_(L); - } - void **P=(void **)(((char*)lua_touserdata(L,1))+0x2EC); - P=(void**)(((char*)*P)+0x114); - int *Ret=(int *)(((char*)*P)+0x858); - lua_settop(L,2); - lua_pushinteger(L,*Ret); - if (lua_type(L,2)!=LUA_TNIL) - { - *Ret=lua_tointeger(L,2); - netReportScore(lua_touserdata(L,1)); - } - return 1; - } - - int teamAssign(lua_State *L) - { - if (lua_type(L,1)==LUA_TTABLE) - { - lua_getfield(L,1,"team"); - if ( - (lua_type(L,-1)!=LUA_TLIGHTUSERDATA) && - (lua_type(L,-1)!=LUA_TNUMBER) - ) - { - lua_pushstring(L,"wrong team args!"); - lua_error_(L); - } - pTeam *Team=0; - if (lua_type(L,-1)==LUA_TLIGHTUSERDATA) - { - Team=(pTeam*)lua_touserdata(L,-1); - void *Test=noxGetTeamFirst(); - for (;Test!=NULL;Test=noxGetTeamNext(Test)) - { - if (Test==Team) - break; - } - if (Test==NULL) - { - lua_pushstring(L,"wrong args - not a team!"); - lua_error_(L); - } - } - else - { - Team=(pTeam*)noxGetTeamByN(lua_tointeger(L,-1)); - if (Team==NULL) - { - lua_pushstring(L,"wrong args: wrong team N!"); - lua_error_(L); - } - } - lua_getfield(L,1,"player"); - if ( - (lua_type(L,-1)!=LUA_TLIGHTUSERDATA) - ) - { - lua_pushstring(L,"wrong player args!"); - lua_error_(L); - } - DWORD *DW=(DWORD*)lua_touserdata(L,-1); - if (0==(DW[2] & 0x4)) - { - lua_pushstring(L,"wrong args: unit is not a player!"); - lua_error_(L); - } - void **PP=(void **)(((char*)lua_touserdata(L,-1))+0x2EC); - PP=(void**)(((char*)*PP)+0x114); - byte *P=(byte*)(*PP); - if(((*((short*)(P+0xE60)))&0x1)==1) - { - lua_pushstring(L,"wrong args: player is observer!"); - lua_error_(L); - } - int NetCode=*((short*)(P+0x80C)); - byte *Common=(byte *)netCommonByCode(NetCode); - int TeamId=*(Common+4); - void *TeamTest=NULL; - TeamTest=(byte *)noxGetTeamByN(TeamId); - if(TeamTest!=NULL) - { - noxTeamChange((void*) Common, (void*) Team, NetCode, 1); - } - else - { - noxCreateAtImpl(Team->teamId, (void*)Common, 1, NetCode, 1); - } - } - return 1; - } - - - void __cdecl onDeathmatchFrag(void *Victim,void *Attacker,void *A,void *B) - { - int Top=lua_gettop(L); - do - { - getServerVar("onDeathmatchFrag"); - if (!lua_isfunction(L,-1)) - break; - if (Victim==NULL) - lua_pushnil(L); - else - lua_pushlightuserdata(L,Victim); - - if (Attacker==NULL) - lua_pushnil(L); - else - lua_pushlightuserdata(L,Attacker); - - if (A==NULL) - lua_pushnil(L); - else - lua_pushlightuserdata(L,A); - - if (B==NULL) - lua_pushnil(L); - else - lua_pushlightuserdata(L,B); - lua_pcall(L,4,1,0); - if (lua_type(L,-1)==LUA_TNIL || - (lua_type(L,-1)==LUA_TBOOLEAN && (0==lua_toboolean(L,-1))) - ) - break; - lua_settop(L,Top); - return; - } - while(0); - lua_settop(L,Top); - playerAddFragDeathmatch(Victim,Attacker,A,B); - } -} - -int teamAutoAssign(lua_State *L) -{ - playersListL(L); //1 - table - if(lua_type(L, -1)==LUA_TTABLE) - { - std::deque players; - int i=1; - while(true) - { - lua_pushinteger(L, i); - lua_gettable(L, -2); - if(lua_type(L, -1)!=LUA_TLIGHTUSERDATA) - break; - players.push_back(lua_touserdata(L, -1)); - i++; - lua_remove(L, -1); - } - lua_remove(L,-1); - random_shuffle(players.begin(), players.end()); - std::deque teamsList; - if(noxGetTeamFirst()==NULL) - return 1; - teamsList.push_back(noxGetTeamFirst()); - while(true) - { - if(noxGetTeamNext(teamsList.back())!=NULL) - teamsList.push_back(noxGetTeamNext(teamsList.back())); - else - break; - } - random_shuffle(teamsList.begin(), teamsList.end()); - while(!players.empty()) - { - std::deque teams(teamsList); - if(teams.empty()==true) - break; - for (pTeam *Team=(pTeam*)teams.front();Team!=NULL;Team=(pTeam*)teams.front()) - { - /*lua_newtable(L); - lua_pushlightuserdata(L, Team); - lua_setfield(L, -2, "team"); - lua_pushlightuserdata(L, players.front()); - lua_setfield(L, -2, "player");*/ - void **PP=(void **)(((char*)players.front())+0x2EC); - PP=(void**)(((char*)*PP)+0x114); - byte *P=(byte*)(*PP); - if(((*((short*)(P+0xE60)))&0x1)==0) // - { - int NetCode=*((short*)(P+0x80C)); - byte *Common=(byte *)netCommonByCode(NetCode); - int TeamId=*(Common+4); - void *TeamTest=NULL; - TeamTest=(byte *)noxGetTeamByN(TeamId); - if(TeamTest!=NULL) - { - noxTeamChange((void*) Common, (void*) Team, NetCode, 1); - } - else - { - noxCreateAtImpl(Team->teamId, (void*)Common, 1, NetCode, 1); - } - } - players.pop_front(); - teams.pop_front(); - if(players.empty()) - break; - if(teams.empty()) - break; - } - } - } - return 1; -} - -extern int httpGet(lua_State *L); - -extern void InjectOffs(DWORD Addr,void *Fn); -extern void InjectJumpTo(DWORD Addr,void *Fn); - -extern "C" void scoreInit(lua_State *L); - -void scoreInit(lua_State *L) -{ - ASSIGN(serverFlagsClear,0x00417D70); - ASSIGN(serverFlagsSet,0x00417D50); - - ASSIGN(netReportScore,0x004D8EF0); - ASSIGN(noxTeamCanPlayGame,0x0040A8A0); - ASSIGN(playerAddFragDeathmatch,0x0054D980); - ASSIGN(noxGetTeamFirst,0x00418B10); - ASSIGN(noxGetTeamNext,0x00418B60); - ASSIGN(noxGetTeamByN,0x00418AB0); - ASSIGN(netSendTeamFrags,0x00419090); - ASSIGN(noxTeamCreate,0x004186D0); - ASSIGN(noxTeamDelete,0x00418F20); - ASSIGN(noxTeamUpdate,0x00418CD0); - ASSIGN(noxCreateAtImpl,0x004191D0); - ASSIGN(noxTeamChange,0x004196D0); - ASSIGN(teamSendTeam,0x004184D0); - ASSIGN(netCommonByCode,0x00418C80); - - ASSIGN(noxTeamDefaultName,0x00418C20); - ASSIGN(noxNetStructList, 0x0097EC60); - - - - InjectJumpTo(0x0040A8A0,teamCanPlayGame); - InjectOffs(0x0054D588+1,onDeathmatchFrag); - registerserver("playerScore",&playerScore); - registerserver("teamScore",&teamScore); - registerserver("teamGet",&teamGet); - registerserver("teamCreateDefault",&teamCreateDefaultL); - registerserver("teamCreate",&teamCreate); - registerserver("teamDelete",&teamDelete); - registerserver("teamAssign",&teamAssign); - registerserver("teamAutoAssign",&teamAutoAssign); - registerclient("playerInfo",&playerInfo); - registerclient("playerGetByName",&playerGetByName); - registerclient("playerGetByWOL",&playerGetByWOL); - registerclient("httpGet",&httpGet); - - registerclient("scoreFragLimit", &scoreFragLimitL); - registerclient("scoreTimeLimit", &scoreTimeLimitL); - -} -void teamCreateDefault(int minTeamsParam=0, bool doNotSetRestriction=false) -{ - if(minTeamsParam>0 && minTeamsParam<17) - { - minTeams=minTeamsParam; - if(doNotSetRestriction==false) - restrictTeams=true; - } - else if(minTeamsParam<0) - { - minTeams=2; - restrictTeams=false; - return; - } - for(int i=1; i<=minTeams; i++) - { - if(noxGetTeamByN(i)==NULL) - { - void *R=NULL; - R=noxTeamCreate(0); - serverFlagsSet(4);/// - wchar_t* RR=NULL; - RR=noxTeamDefaultName(((byte*)R)[0x38]);// - CSF-, - memcpy(R, RR, 0x28); - ((byte*)R)[0x44]=1; - teamSendTeam(R); - } - } - if(noxTeamNumber()>minTeams) - { - void *Test=noxGetTeamFirst(); - for(int i=1;Test!=NULL;Test=noxGetTeamNext(Test)) - { - if(i>minTeams) - { - noxTeamDelete(Test,1); - } - i++; - } - return; - }/* - while(noxTeamNumber()<2) - { - void *R=NULL; - R=noxTeamCreate(0); - serverFlagsSet(4);/// - wchar_t* RR=NULL; - RR=noxTeamDefaultName(((byte*)R)[0x38]);// - CSF-, - memcpy(R, RR, 0x28); - ((byte*)R)[0x44]=1; - teamSendTeam(R); - }*/ - return; - /* - for(int i=8;i>0;i--) - { - void* Team=NULL; - Team=noxGetTeamByN(i); - if(Team!=NULL) - { - noxTeamDelete(Team,1); - } - if(i==3) - { - serverFlagsClear(4); - } - if(i<3) - { - void *R=NULL; - R=noxTeamCreate(i); - serverFlagsSet(4); - char teamName[0x14]={0}; - itoa(i,teamName,10); - mbstowcs((wchar_t*)R,teamName,0x14); - wchar_t* RR = (wchar_t*)R; - ((byte*)R)[0x44]=1; - teamSendTeam(R); - noxTeamUpdate(RR, R); - } - }*/ - +#include "stdafx.h" +#include "unit.h" +#include "player.h" +#include +#include +#include "winsock2.h" + +extern void *(__cdecl *serverGetGameDataBySel)(); + +/* +Здесь начисление/получение фрагов и т.п. +*/ +extern DWORD *GameFlags; +extern int playersListL(lua_State *L); +void teamCreateDefault(int TeamNum, bool notRestrict); +int minTeams=2; +bool restrictTeams=false; +int (__cdecl *netReportScore)(void *Player); +void (__cdecl *playerAddFragDeathmatch)(void *Victim,void *Attacker,void *A,void *B); + +int (__cdecl *noxTeamCanPlayGame)(); // есть ли достаточно игроков в команде и т.п. + +void *(__cdecl *netCommonByCode)(int NetCode); + +void *(__cdecl *noxGetTeamFirst)(); +void *(__cdecl *noxGetTeamNext)(void *Prev); +void *(__cdecl *noxGetTeamByN)(int N); +void (__cdecl *netSendTeamFrags)(void *Team,int Frags); + +void *(__cdecl *noxTeamCreate)(int N); +void (__cdecl *noxCreateAtImpl)(int TeamID, void* Common, bool wasInTeam, int netCode, int unknown); +void (__cdecl *noxTeamChange)(void* Common, void* teamPtr, int netCode, int unknown); +void (__cdecl *noxTeamDelete)(void *TeamPtr,int SendClient); +void (__cdecl *teamSendTeam)(void *TeamPtr); +void (__cdecl *noxTeamUpdate)(void *newName, void *TeamPtr); +void (__cdecl *serverFlagsSet)(DWORD V); +void (__cdecl *serverFlagsClear)(DWORD V); +wchar_t *(__cdecl *noxTeamDefaultName)(int color); +extern byte authorisedState[0x20]; +extern char* authorisedLogins[0x20]; + +void* noxNetStructList; + +namespace +{ + + int scoreFragLimitL(lua_State*L) + { + ServerData* servdata = (ServerData*)serverGetGameDataBySel(); + unsigned int fraglimit = servdata->fragLimit; + lua_pushnumber(L, fraglimit); + return 1; + } + + int scoreTimeLimitL(lua_State*L) + { + ServerData* servdata = (ServerData*)serverGetGameDataBySel(); + unsigned int timelimit = servdata->timeLimitMB; + lua_pushnumber(L, timelimit); + return 1; + } + + struct pTeam + { + char name[20]; + char gap_14[20]; + __int16 nameLastChar; + char gap_2a[2]; + int firstAllyTeam; + int membersCount; + int teamFrags; + char teamColorNMB; + char teamId; + char teamId2; + char gap_3b[1]; + void* somePtr; + int field_40; + int haveNameMB; + int flagPtr; + int field_4C; + }; + + + int teamCanPlayGameImpl() // чтобы можно было + { + int Top=lua_gettop(L); + getServerVar("teamCanStart"); + int Ret=0; + if (lua_type(L,-1)!=LUA_TNIL) + Ret=(lua_toboolean(L,-1))?2:1; + lua_settop(L,Top); + return Ret; + } + + int __declspec(naked) teamCanPlayGame() + { + __asm + { + call teamCanPlayGameImpl + test eax,eax + jz l1 + dec eax + ret +l1: + push ebx + push edi + push 4 + xor ebx,ebx + push 0x0040A8A6 + ret + }; + } + + int noxTeamNumber() + { + int i=0; + for (pTeam *Test=(pTeam *)noxGetTeamFirst();Test!=NULL;Test=(pTeam *)noxGetTeamNext(Test)) + { + i++; + } + return i; + } + int teamGet(lua_State *L) + { + lua_settop(L,2); + if ((lua_type(L,1)==LUA_TNUMBER) || (lua_type(L,1)==LUA_TLIGHTUSERDATA)) + { + pTeam *Team=0; + if ((lua_type(L,1)==LUA_TNUMBER)) + Team=(pTeam *)noxGetTeamByN(lua_tointeger(L,1)); + else + Team=(pTeam *)lua_touserdata(L,1); + if (!Team) + { + lua_pushnil(L); + return 1; + } + lua_newtable(L); + lua_pushinteger(L,Team->teamId); + lua_setfield(L,-2,"id"); + char TeamName[0x20]={0}; + wcstombs(TeamName,(wchar_t*)Team,0x14); + lua_pushstring(L,TeamName); + lua_setfield(L,-2,"name"); + lua_pushinteger(L,Team->teamColorNMB); + lua_setfield(L,-2,"color"); + lua_pushinteger(L,Team->membersCount); + lua_setfield(L,-2,"membersCount"); + lua_pushinteger(L,Team->teamFrags); + lua_setfield(L,-2,"score"); + if ( lua_toboolean(L,2)==1) /// если хотят юзердат + { + lua_pushlightuserdata(L,Team); + lua_setfield(L,-2,"teamPtr"); + if (Team->somePtr) + lua_pushlightuserdata(L,Team->somePtr); + else + lua_pushnil(L); + lua_setfield(L,-2,"flagPtr"); + } + + return 1; + } + lua_newtable(L); + pTeam *Test=(pTeam *)noxGetTeamFirst(); + for (int i=1;Test!=NULL;Test=(pTeam *)noxGetTeamNext(Test),i++) + { + //lua_pushinteger(L,Test->teamId); + //lua_pushvalue(L,2); + pTeam *Team=Test; + if (!Team) + { + lua_pushnil(L); + return 1; + } + lua_newtable(L); + lua_pushinteger(L,Team->teamId); + lua_setfield(L,-2,"id"); + char TeamName[0x20]={0}; + wcstombs(TeamName,(wchar_t*)Team,0x14); + lua_pushstring(L,TeamName); + lua_setfield(L,-2,"name"); + lua_pushinteger(L,Team->teamColorNMB); + lua_setfield(L,-2,"color"); + lua_pushinteger(L,Team->membersCount); + lua_setfield(L,-2,"membersCount"); + lua_pushinteger(L,Team->teamFrags); + lua_setfield(L,-2,"score"); + if ( lua_toboolean(L,2)==1) /// если хотят юзердат + { + lua_pushlightuserdata(L,Team); + lua_setfield(L,-2,"teamPtr"); + if (Team->somePtr) + lua_pushlightuserdata(L,Team->somePtr); + else + lua_pushnil(L); + lua_setfield(L,-2,"flagPtr"); + } + lua_pushinteger(L,i); + lua_pushvalue(L,-2); + lua_settable(L,3);/// это таблица + lua_settop(L,3);//2 + 1 + } + return 1; + } + + int playerGetByName(lua_State *L) + { + if(lua_type(L, -1)==LUA_TSTRING) + { + const char *S=lua_tostring(L,-1); + bool found=false; + for(void *Pl=playerFirstUnit(); Pl!=0; Pl=playerNextUnit(Pl)) + { + void **PP=(void **)(((char*)Pl)+0x2EC); + PP=(void**)(((char*)*PP)+0x114); + byte *P=(byte*)(*PP); + char Name[0x50]={0}; + wcstombs(Name,((wchar_t*)(P+0x1260)),0x50); + if(strcmp(Name,S)==0) + { + found=true; + lua_pushlightuserdata(L, Pl); + break; + } + } + if(found==false) + { + lua_pushstring(L,"not found!"); + lua_error_(L); + } + } + else + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + return 1; + } + + int playerGetByWOL(lua_State *L) + { + if(lua_type(L, -1)==LUA_TSTRING) + { + const char *S=lua_tostring(L,-1); + bool found=false; + for(void *Pl=playerFirstUnit(); Pl!=0; Pl=playerNextUnit(Pl)) + { + void **PP=(void **)(((char*)Pl)+0x2EC); + PP=(void**)(((char*)*PP)+0x114); + byte *P=(byte*)(*PP); + char WOL[0x20]={0}; + strncpy(WOL,((char*)(P+0x830)),0x20); + if(strcmp(WOL,S)==0) + { + found=true; + lua_pushlightuserdata(L, Pl); + break; + } + } + if(found==false) + { + lua_pushstring(L,"not found!"); + lua_error_(L); + } + } + else + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + return 1; + } + + int playerInfo(lua_State *L) + { + lua_settop(L,1); + if ( + (lua_type(L,1)!=LUA_TLIGHTUSERDATA) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + DWORD *DW=(DWORD*)lua_touserdata(L,1); + if (0==(DW[2] & 0x4)) + { + lua_pushstring(L,"wrong args: unit is not a player!"); + lua_error_(L); + } + BYTE *unit=(BYTE*)lua_touserdata(L,1); + void **PP=(void **)(((char*)unit)+0x2EC); + PP=(void**)(((char*)*PP)+0x114); + byte *P=(byte*)(*PP); + lua_newtable(L); + lua_pushinteger(L,*((short*)(P+0x864))); + lua_setfield(L,-2,"ping"); + lua_pushinteger(L,*((int*)(P+0x858))); + lua_setfield(L,-2,"score"); + lua_pushinteger(L,(*((int*)(P+0xE60)))&0x1); + lua_setfield(L,-2,"isObserver"); + char Name[0x50]={0}; + wcstombs(Name,((wchar_t*)(P+0x1260)),0x50); + lua_pushstring(L,Name); + lua_setfield(L,-2,"name"); + char WOL[0x20]={0}; + strncpy(WOL,((char*)(P+0x830)),0x20); + lua_pushstring(L,WOL); + lua_setfield(L,-2,"wol"); + byte idx = *((byte*)(P+0x810)); + lua_pushinteger(L,idx); + lua_setfield(L,-2,"idx"); + void* netStructListPlayer; + if(idx<0x1F) + { + netStructListPlayer=(byte*)noxNetStructList+(1+idx)*4; + BYTE* addrStruct = *((BYTE**)netStructListPlayer); + in_addr* address=(in_addr*)(addrStruct+8); + lua_pushstring(L,inet_ntoa(*address)); + } + else + lua_pushstring(L,"127.0.0.1"); + lua_setfield(L,-2,"ip"); + int Class=*((byte*)(P+0x8CB)); + lua_pushinteger(L,Class); + lua_setfield(L,-2,"class"); + if (Class==0) + lua_pushstring(L,"WAR"); + else if (Class==1) + lua_pushstring(L,"WIZ"); + else if (Class==2) + lua_pushstring(L,"CON"); + else + lua_pushstring(L,"UNK"); + + lua_setfield(L,-2,"className"); + + int NetCode=*((short*)(P+0x80C)); + byte *Common=(byte *)netCommonByCode(NetCode); + lua_pushinteger(L,NetCode); + lua_setfield(L,-2,"netcode"); + byte playerIdx = *((byte*)(P+0x810)); + if(authorisedState[playerIdx]==4) + lua_pushstring(L,authorisedLogins[playerIdx]); + else + lua_pushstring(L,""); + lua_setfield(L,-2,"login"); + int TeamId=*((int*)(unit+0x34)); + byte *Team=NULL; + if (TeamId>0) + { + Team=(byte *)noxGetTeamByN(TeamId); + } + if (Team!=NULL) + { + lua_pushinteger(L,TeamId); + lua_setfield(L,-2,"teamId"); + wcstombs(Name,(wchar_t*)Team,0x14); + lua_pushstring(L,Name); + lua_setfield(L,-2,"teamName"); + lua_pushinteger(L,*((int *)(Team+0x34))); + lua_setfield(L,-2,"teamScore"); + + } + + return 1; + } + void *teamGetByLua(lua_State *L) + { + if ( + (lua_type(L,1)!=LUA_TLIGHTUSERDATA) && + (lua_type(L,1)!=LUA_TNUMBER) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + void *Team=0; + if (lua_type(L,1)==LUA_TLIGHTUSERDATA) + { + Team=lua_touserdata(L,1); + void *Test=noxGetTeamFirst(); + for (;Test!=NULL;Test=noxGetTeamNext(Test)) + { + if (Test==Team) + break; + } + if (Test==NULL) + { + lua_pushstring(L,"wrong args - not a team!"); + lua_error_(L); + } + } + else + { + Team=noxGetTeamByN(lua_tointeger(L,1)); + if (Team==NULL) + { + lua_pushstring(L,"wrong args: wrong team N!"); + lua_error_(L); + } + } + return Team; + } + int teamDelete(lua_State *L) + { + void* teamPtr=teamGetByLua(L); + bool allowDelete=true; + if(restrictTeams==true) + { + for(int i=1; i<=minTeams; i++) + { + void* TeamTest=noxGetTeamByN(i); + if(TeamTest==teamPtr) + { + allowDelete=false; + break; + } + } + } + if(allowDelete==true) + noxTeamDelete(teamPtr,1); + else + { + lua_pushstring(L,"Can't delete first teams on that map!"); + lua_error_(L); + } + void *Test=noxGetTeamFirst(); + if (Test==NULL) + serverFlagsClear(4);/// выключаем тимы + + return 0; + } + + int teamCreateDefaultL(lua_State *L) + { + int param=0; + bool param2=false; + if (lua_type(L,1)==LUA_TNUMBER) + { + lua_newtable(L); + lua_pushvalue(L,1); + lua_setfield(L,-2,"limit"); + lua_remove(L,1); + } + if(lua_type(L,1)==LUA_TTABLE) + { + lua_getfield(L,1,"limit"); + if (lua_type(L,-1)==LUA_TNUMBER) + { + param=lua_tointeger(L,-1); + } + lua_getfield(L,1,"norestrict"); + if (lua_type(L,-1)!=LUA_TNIL) + { + param2=lua_toboolean(L,-1); + } + } + teamCreateDefault(param, param2); + return 0; + } + int teamCreate(lua_State *L) + { + void *R=NULL; + lua_settop(L,2); + int id=0; + if (lua_type(L,1)==LUA_TTABLE) + { + lua_getfield(L,1,"id"); + id=lua_tointeger(L,-1); + } + bool newTeam=false; + if (id>0) + { + R=noxGetTeamByN(id); + } + else + { + newTeam=true; + R=noxTeamCreate(id); + } + if (R==NULL) + { + lua_pushnil(L); + return 1; + } + serverFlagsSet(4);/// включаем тимы + wchar_t* RR=NULL; + bool RRR=false;//Флаг посылать ли на КЛИЕНТ имя тимы + if (lua_type(L,1)==LUA_TTABLE) + { + lua_getfield(L,1,"color"); + if (!lua_isnil(L,-1)) + { + ((byte*)R)[0x38]=lua_tointeger(L,-1); + } + lua_getfield(L,1,"name"); + const char *S=lua_tostring(L,-1); + if (S) + { + mbstowcs((wchar_t*)R,S,0x14); + RR = (wchar_t*)R; + ((byte*)R)[0x44]=1; + RRR=true; + } + else if(newTeam==true) + { + RR=noxTeamDefaultName(((byte*)R)[0x38]);//Получаем дефолтное название тимы - то что записано в CSF-ке, на основании цвета тимы + memcpy(R, RR, 0x28); + ((byte*)R)[0x44]=1; + } + } + else if(newTeam==true) + { + RR=noxTeamDefaultName(((byte*)R)[0x38]);//Получаем дефолтное название тимы - то что записано в CSF-ке, на основании цвета тимы + memcpy(R, RR, 0x28); + ((byte*)R)[0x44]=1; + } + teamSendTeam(R); //Тут записывается информация о наличии тимы вообще - однако НАЗВАНИЕ тимы не посылается на клиент - клиент юзает СВОЁ ДЕФОЛТНОЕ название (!) + if(RRR==true) + noxTeamUpdate(RR, R); //Обновление ИМЕНИ тимы на клиентах - после чего имя тимы у клиентов уже не дефолтное, а именно то, что пришло с сервера + lua_pushlightuserdata(L,R); + return 1; + } + + int teamScore(lua_State *L) + { + void *Team=teamGetByLua(L); + + int *Ret=(int *)(((char*)Team)+0x34); + lua_settop(L,2); + lua_pushinteger(L,*Ret); + if (lua_type(L,2)!=LUA_TNIL) + { + *Ret=lua_tointeger(L,2); + netSendTeamFrags(Team,*Ret); + } + return 1; + } + int teamName(lua_State *L) + { + void *Team=teamGetByLua(L); + + return 1; + } + int playerScore(lua_State *L) + { + if ( + (lua_type(L,1)!=LUA_TLIGHTUSERDATA) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + DWORD *DW=(DWORD*)lua_touserdata(L,1); + if (0==(DW[2] & 0x4)) + { + lua_pushstring(L,"wrong args: unit is not a player!"); + lua_error_(L); + } + void **P=(void **)(((char*)lua_touserdata(L,1))+0x2EC); + P=(void**)(((char*)*P)+0x114); + int *Ret=(int *)(((char*)*P)+0x858); + lua_settop(L,2); + lua_pushinteger(L,*Ret); + if (lua_type(L,2)!=LUA_TNIL) + { + *Ret=lua_tointeger(L,2); + netReportScore(lua_touserdata(L,1)); + } + return 1; + } + + int teamAssign(lua_State *L) + { + if (lua_type(L,1)==LUA_TTABLE) + { + lua_getfield(L,1,"team"); + if ( + (lua_type(L,-1)!=LUA_TLIGHTUSERDATA) && + (lua_type(L,-1)!=LUA_TNUMBER) + ) + { + lua_pushstring(L,"wrong team args!"); + lua_error_(L); + } + pTeam *Team=0; + if (lua_type(L,-1)==LUA_TLIGHTUSERDATA) + { + Team=(pTeam*)lua_touserdata(L,-1); + void *Test=noxGetTeamFirst(); + for (;Test!=NULL;Test=noxGetTeamNext(Test)) + { + if (Test==Team) + break; + } + if (Test==NULL) + { + lua_pushstring(L,"wrong args - not a team!"); + lua_error_(L); + } + } + else + { + Team=(pTeam*)noxGetTeamByN(lua_tointeger(L,-1)); + if (Team==NULL) + { + lua_pushstring(L,"wrong args: wrong team N!"); + lua_error_(L); + } + } + lua_getfield(L,1,"player"); + if ( + (lua_type(L,-1)!=LUA_TLIGHTUSERDATA) + ) + { + lua_pushstring(L,"wrong player args!"); + lua_error_(L); + } + DWORD *DW=(DWORD*)lua_touserdata(L,-1); + if (0==(DW[2] & 0x4)) + { + lua_pushstring(L,"wrong args: unit is not a player!"); + lua_error_(L); + } + void **PP=(void **)(((char*)lua_touserdata(L,-1))+0x2EC); + PP=(void**)(((char*)*PP)+0x114); + byte *P=(byte*)(*PP); + if(((*((short*)(P+0xE60)))&0x1)==1) + { + lua_pushstring(L,"wrong args: player is observer!"); + lua_error_(L); + } + int NetCode=*((short*)(P+0x80C)); + byte *Common=(byte *)netCommonByCode(NetCode); + int TeamId=*(Common+4); + void *TeamTest=NULL; + TeamTest=(byte *)noxGetTeamByN(TeamId); + if(TeamTest!=NULL) + { + noxTeamChange((void*) Common, (void*) Team, NetCode, 1); + } + else + { + noxCreateAtImpl(Team->teamId, (void*)Common, 1, NetCode, 1); + } + } + return 1; + } + + + void __cdecl onDeathmatchFrag(void *Victim,void *Attacker,void *A,void *B) + { + int Top=lua_gettop(L); + do + { + getServerVar("onDeathmatchFrag"); + if (!lua_isfunction(L,-1)) + break; + if (Victim==NULL) + lua_pushnil(L); + else + lua_pushlightuserdata(L,Victim); + + if (Attacker==NULL) + lua_pushnil(L); + else + lua_pushlightuserdata(L,Attacker); + + if (A==NULL) + lua_pushnil(L); + else + lua_pushlightuserdata(L,A); + + if (B==NULL) + lua_pushnil(L); + else + lua_pushlightuserdata(L,B); + lua_pcall(L,4,1,0); + if (lua_type(L,-1)==LUA_TNIL || + (lua_type(L,-1)==LUA_TBOOLEAN && (0==lua_toboolean(L,-1))) + ) + break; + lua_settop(L,Top); + return; + } + while(0); + lua_settop(L,Top); + playerAddFragDeathmatch(Victim,Attacker,A,B); + } +} + +int teamAutoAssign(lua_State *L) +{ + playersListL(L); //1 - table + if(lua_type(L, -1)==LUA_TTABLE) + { + std::deque players; + int i=1; + while(true) + { + lua_pushinteger(L, i); + lua_gettable(L, -2); + if(lua_type(L, -1)!=LUA_TLIGHTUSERDATA) + break; + players.push_back(lua_touserdata(L, -1)); + i++; + lua_remove(L, -1); + } + lua_remove(L,-1); + random_shuffle(players.begin(), players.end()); + std::deque teamsList; + if(noxGetTeamFirst()==NULL) + return 1; + teamsList.push_back(noxGetTeamFirst()); + while(true) + { + if(noxGetTeamNext(teamsList.back())!=NULL) + teamsList.push_back(noxGetTeamNext(teamsList.back())); + else + break; + } + random_shuffle(teamsList.begin(), teamsList.end()); + while(!players.empty()) + { + std::deque teams(teamsList); + if(teams.empty()==true) + break; + for (pTeam *Team=(pTeam*)teams.front();Team!=NULL;Team=(pTeam*)teams.front()) + { + /*lua_newtable(L); + lua_pushlightuserdata(L, Team); + lua_setfield(L, -2, "team"); + lua_pushlightuserdata(L, players.front()); + lua_setfield(L, -2, "player");*/ + void **PP=(void **)(((char*)players.front())+0x2EC); + PP=(void**)(((char*)*PP)+0x114); + byte *P=(byte*)(*PP); + if(((*((short*)(P+0xE60)))&0x1)==0) //Проверка на обсерв + { + int NetCode=*((short*)(P+0x80C)); + byte *Common=(byte *)netCommonByCode(NetCode); + int TeamId=*(Common+4); + void *TeamTest=NULL; + TeamTest=(byte *)noxGetTeamByN(TeamId); + if(TeamTest!=NULL) + { + noxTeamChange((void*) Common, (void*) Team, NetCode, 1); + } + else + { + noxCreateAtImpl(Team->teamId, (void*)Common, 1, NetCode, 1); + } + } + players.pop_front(); + teams.pop_front(); + if(players.empty()) + break; + if(teams.empty()) + break; + } + } + } + return 1; +} + +extern int httpGet(lua_State *L); + +extern void InjectOffs(DWORD Addr,void *Fn); +extern void InjectJumpTo(DWORD Addr,void *Fn); + +extern "C" void scoreInit(lua_State *L); + +void scoreInit(lua_State *L) +{ + ASSIGN(serverFlagsClear,0x00417D70); + ASSIGN(serverFlagsSet,0x00417D50); + + ASSIGN(netReportScore,0x004D8EF0); + ASSIGN(noxTeamCanPlayGame,0x0040A8A0); + ASSIGN(playerAddFragDeathmatch,0x0054D980); + ASSIGN(noxGetTeamFirst,0x00418B10); + ASSIGN(noxGetTeamNext,0x00418B60); + ASSIGN(noxGetTeamByN,0x00418AB0); + ASSIGN(netSendTeamFrags,0x00419090); + ASSIGN(noxTeamCreate,0x004186D0); + ASSIGN(noxTeamDelete,0x00418F20); + ASSIGN(noxTeamUpdate,0x00418CD0); + ASSIGN(noxCreateAtImpl,0x004191D0); + ASSIGN(noxTeamChange,0x004196D0); + ASSIGN(teamSendTeam,0x004184D0); + ASSIGN(netCommonByCode,0x00418C80); + + ASSIGN(noxTeamDefaultName,0x00418C20); + ASSIGN(noxNetStructList, 0x0097EC60); + + + + InjectJumpTo(0x0040A8A0,teamCanPlayGame); + InjectOffs(0x0054D588+1,onDeathmatchFrag); + registerserver("playerScore",&playerScore); + registerserver("teamScore",&teamScore); + registerserver("teamGet",&teamGet); + registerserver("teamCreateDefault",&teamCreateDefaultL); + registerserver("teamCreate",&teamCreate); + registerserver("teamDelete",&teamDelete); + registerserver("teamAssign",&teamAssign); + registerserver("teamAutoAssign",&teamAutoAssign); + registerclient("playerInfo",&playerInfo); + registerclient("playerGetByName",&playerGetByName); + registerclient("playerGetByWOL",&playerGetByWOL); + registerclient("httpGet",&httpGet); + + registerclient("scoreFragLimit", &scoreFragLimitL); + registerclient("scoreTimeLimit", &scoreTimeLimitL); + +} +void teamCreateDefault(int minTeamsParam=0, bool doNotSetRestriction=false) +{ + if(minTeamsParam>0 && minTeamsParam<17) + { + minTeams=minTeamsParam; + if(doNotSetRestriction==false) + restrictTeams=true; + } + else if(minTeamsParam<0) + { + minTeams=2; + restrictTeams=false; + return; + } + for(int i=1; i<=minTeams; i++) + { + if(noxGetTeamByN(i)==NULL) + { + void *R=NULL; + R=noxTeamCreate(0); + serverFlagsSet(4);/// включаем тимы + wchar_t* RR=NULL; + RR=noxTeamDefaultName(((byte*)R)[0x38]);//Получаем дефолтное название тимы - то что записано в CSF-ке, на основании цвета тимы + memcpy(R, RR, 0x28); + ((byte*)R)[0x44]=1; + teamSendTeam(R); + } + } + if(noxTeamNumber()>minTeams) + { + void *Test=noxGetTeamFirst(); + for(int i=1;Test!=NULL;Test=noxGetTeamNext(Test)) + { + if(i>minTeams) + { + noxTeamDelete(Test,1); + } + i++; + } + return; + }/* + while(noxTeamNumber()<2) + { + void *R=NULL; + R=noxTeamCreate(0); + serverFlagsSet(4);/// включаем тимы + wchar_t* RR=NULL; + RR=noxTeamDefaultName(((byte*)R)[0x38]);//Получаем дефолтное название тимы - то что записано в CSF-ке, на основании цвета тимы + memcpy(R, RR, 0x28); + ((byte*)R)[0x44]=1; + teamSendTeam(R); + }*/ + return; + /* + for(int i=8;i>0;i--) + { + void* Team=NULL; + Team=noxGetTeamByN(i); + if(Team!=NULL) + { + noxTeamDelete(Team,1); + } + if(i==3) + { + serverFlagsClear(4); + } + if(i<3) + { + void *R=NULL; + R=noxTeamCreate(i); + serverFlagsSet(4); + char teamName[0x14]={0}; + itoa(i,teamName,10); + mbstowcs((wchar_t*)R,teamName,0x14); + wchar_t* RR = (wchar_t*)R; + ((byte*)R)[0x44]=1; + teamSendTeam(R); + noxTeamUpdate(RR, R); + } + }*/ + } \ No newline at end of file diff --git a/spelList.cpp b/spelList.cpp index e9c3b68..f9c0149 100644 --- a/spelList.cpp +++ b/spelList.cpp @@ -1,677 +1,677 @@ -#include "stdafx.h" - -extern BYTE *spellDefPtr; -BYTE **clientPlayerInfoPtr; -int (__cdecl *spellGetValidMB)(int Spell); -void *(__cdecl *gLoadImg)(const char *Name); - -void (__cdecl *drawSetTextColor)(DWORD Color); -void (__cdecl *drawGetStringSize)(void *FontPtr,const wchar_t*String, - int *W,int *H,DWORD Flags); -void (__cdecl *drawString)(void *FontPtr,const wchar_t*String,int X,int Y); -void (__cdecl *drawUpdateMB)(int A,int B); -void (__cdecl *wndSetTooltip)(void *Wnd, const wchar_t *Str); -void (__cdecl *netSpellRewardCli)(int Spell, int newLevel,int ShowBook, int AddToBar); - -int (__cdecl *audSyllStartSpeak)(int SpellN);/// - - -extern DWORD __cdecl mySpellGetFlags(int Spell); -extern int __cdecl mySpellIsEnabled(int Spell); -extern const wchar_t * __cdecl mySpellLoadName(int Spell); - -DWORD *guiSpellListedNumbers;// - - 3 - -DWORD *bookWndState; -DWORD *bookIsMonster; -DWORD *bookColorNormal; -DWORD *bookColorDisabled; -DWORD *bookSpellSelected; - -DWORD *bookSpellDnDType; /// - -DWORD *bookSpellNumberDnD;/// - -int *bookSelSpell;/// - -int *bookPagesList;/// -int *bookLineHeight; -int *bookListHidden;/// - -int *bookListTotalCount;/// - -int mySelectedSpell;/// - -/* -0100 0000 - -0200 0000 - (1) -0400 0000 - (2) - -*/ -/* -bookSpellList - , , -spellData - , , , - - - 0x100 - - mySelectedSpell - - : -- DnD -- -- -- -- -- -- - - -*/ - -namespace -{ - void *myDragIcon=NULL;/// - int nextSpellIndex=0x101; /// - - bool spellIsSummon(int Spell) - { - //sfCreature - DWORD F=mySpellGetFlags(Spell); - const wchar_t *Name=mySpellLoadName(Spell); - Name++; - return (Spell >=75) && (Spell<114); - } - int __cdecl mySpellReward(int Spell,BYTE *PlayerInfo,int PlayerClass) - /// 1 - /// 0 - ( ) - { - int Top=lua_gettop(L); - getClientVar("bookSpellList"); - if (PlayerClass==0) // - Spell+=ABIL_TO_SPELL; - int i,n=lua_objlen(L,-1); - for (i=1;i<=n+1;i++) - { - lua_rawgeti(L,-1,i); - if (lua_tointeger(L,-1)==Spell) - break; - lua_settop(L,Top+1); - } - if (i==n+1) - { - lua_rawseti(L,-2,i); // - - lua_pushinteger(L,Spell); - } - getClientVar("spellData"); - lua_pushinteger(L,Spell); - lua_gettable(L,-2); - if (lua_type(L,-1)==LUA_TNUMBER)/// - - { - /// todo - - } - else - { - lua_getfield(L,-1,"level"); - lua_pushinteger(L,lua_tointeger(L,-1)+1); - lua_getfield(L,-3,"level"); - } - lua_settop(L,Top); - return 1; - } - void __declspec(naked) mySpellRewardPre() - // - // - // - { - __asm - { - pop eax // - push ebx // - push ebp // - call mySpellReward - add esp,0xC - cmp ebp,0x22 - jnz l1 - mov ecx,eax /// - push 0x0045D0D4 - ret -l1: - test eax,eax - jz l2 - cmp [esp+0x1C],edi // - - jz l2 - push 0x0045D117 // - ret -l2: - push 0x0045D139 // - ret - }; - } - - void drawDefAbil(int Spell,int plrClass,int X,int Y) - { - } - void drawDefCreature(int Spell,int plrClass,int X,int Y) - { - drawSetTextColor( - ((2==plrClass) && !mySpellIsEnabled(Spell))? // - *bookColorDisabled: - *bookColorNormal - ); - const wchar_t *Name=mySpellLoadName(Spell); - int W=0; - drawGetStringSize(NULL,Name,&W,NULL,0x80); - drawString(NULL,Name,X-W/2,Y); - } - - void drawDefSpell(int Spell,int plrClass,int X,int Y) - { - drawSetTextColor( - !mySpellIsEnabled(Spell)? - *bookColorDisabled: - *bookColorNormal - ); - const wchar_t *Name=mySpellLoadName(Spell); - int W=0; - drawGetStringSize(NULL,Name,&W,NULL,0x80); - drawString(NULL,Name,X-W/2,Y); - } - void drawUniItem(int X,int Y,bool isCreatures) - { - int i=-1; - lua_getfield(L,i--,"flags"); - DWORD Flags=lua_tointeger(L,-1); - if ( (0!=Flags&sfCreature) ^ isCreatures ) - return; - DWORD Color=*bookColorNormal; - lua_getfield(L,i--,"color"); - if (lua_type(L,-1)==LUA_TNUMBER) - Color=lua_tointeger(L,-1); - lua_getfield(L,i--,"disabled"); - drawSetTextColor( - 0!=lua_toboolean(L,-1)? - *bookColorDisabled: - Color - ); - wchar_t Name[120]; - size_t Len=0; - lua_getfield(L,i--,"name"); - const char *NameS=lua_tolstring(L,-1,&Len); - if (Len!=0) - { - if (Len>119) - Len=119; - mbstowcs(Name,NameS,120); - Name[Len]=0; - } - else - wcscpy(Name,L"(wrong)"); - int W=0; - drawGetStringSize(NULL,Name,&W,NULL,0x80); - drawString(NULL,Name,X-W/2,Y); - } - void drawSpellList(int PageN,int LinesPerPage,int X,int Y) - { /// - int Top=lua_gettop(L); - getClientVar("bookSpellList"); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return; - } - bool isCreatures=(1==*bookWndState); - - int Count=lua_objlen(L,-1);// - *bookListTotalCount=Count; - *bookPagesList=1 + (Count+LinesPerPage)/LinesPerPage; - *bookListHidden=0; - int i=1+PageN*LinesPerPage*2,right=i+LinesPerPage; - if (i+2*LinesPerPagekeyRowPtr[KeyN].Spell=NewSpell; - BYTE *P=(BYTE*)KeyPack->spellWndItemMB[KeyN]; - if (NewSpell<0x100) - { - if (P!=NULL) - wndSetTooltip(P+24,spellLoadName(NewSpell)); - if (clientPlayerInfoPtr!=0) - drawUpdateMB(794,100);/// , - return; - } - // - int Top=lua_gettop(L); - lua_pushlightuserdata(L,&getSpellForDnD); - - lua_gettable(L,LUA_REGISTRYINDEX);/// - lua_getfield(L,-1,"name"); - size_t Len; - const char *S=lua_tolstring(L,-1,&Len); - wchar_t Buf[200]=L"(Uni spell)"; - if (Len>0) - mbstowcs(Buf,S,min(Len,199)); - wndSetTooltip(P+24,Buf); - if (clientPlayerInfoPtr!=0) - drawUpdateMB(794,100);/// , - - lua_settop(L,Top); - return; - }*/ - void __declspec(naked) getAbilForDnDPre() - { - __asm{ - push 2 - push ecx - call getSpellForDnD - add esp,8 - mov ecx,eax - push 0x0045B85D - ret - }; - } - void __declspec(naked) getCreaForDnDPre() - { - __asm{ - push 3 - push ecx - call getSpellForDnD - add esp,8 - push 0x0045B85D - ret - }; - } - void __declspec(naked) getSpellForDnDPre() - { - __asm{ - push 1 - push ecx - call getSpellForDnD - add esp,8 - push 0x0045B85D - ret - }; - } - void __declspec(naked) drawSpellListPre() - { - __asm{ - push [esp+0x22C-0x214] - push [esp+0x230-0x218] - push ecx - push esi - call drawSpellList - add esp,0x10 - push 0x0045C78D - ret - } - } - - void onSpellStart(BYTE *Packet) - { - audSyllStartSpeak(*((DWORD*)Packet)); - } - void onSpellSync(BYTE *Packet) - { - DWORD StartIdx=*((DWORD *)(Packet)); - } -} -extern void InjectJumpTo(DWORD Addr,void *Fn); -extern void InjectOffs(DWORD Addr,void *Fn); -extern void InjectAddr(DWORD Addr,void *Fn); - -void mapLoadSpells() -{ - int Top=lua_gettop(L); - int plrClass=(*clientPlayerInfoPtr)[0x8CB]; - luaL_loadstring(L, - "local l={...}; " - "table.sort(l[1]," - "function (a,b) " - "return spellInfo(a).name < spellInfo(b).name " - "end)" - ); - lua_getfield(L,LUA_REGISTRYINDEX,"client"); - lua_setfenv(L,-2); - getClientVar("bookSpellList"); - int Cnt=1; - lua_pushinteger(L,0x101); - lua_rawseti(L,-2,Cnt++); - lua_pushinteger(L,0x102); - lua_rawseti(L,-2,Cnt++); - - if (plrClass != 0) - { - for (int i=0;i success - if (0==luaL_loadstring(L, - "local me,tx,ty=... \n" - "local x,y = unitPos(me) \n" - "if not mapTraceRay(x,y,tx,ty,5) then return false end \n" - "soundMake(0x28,tx,ty) " // - "netPointFx(0x89,tx,ty) " -// "soundSyll(me,1) " - "local r=createObject('waterbarrel',tx,ty) \n" - "unitDecay(r,600) return true")) - { - lua_setfield(L,-2,"servOnStart"); - } - else - { - conPrintI(lua_tostring(L,-1)); - lua_pop(L,1); - } - lua_settable(L,-3); - lua_settop(L,Top); -} -void spellGetInit(); - -void spellListInit() -{ - ASSIGN(audSyllStartSpeak,0x0049BB80); - - ASSIGN(clientPlayerInfoPtr,0x00853BB0); - ASSIGN(spellGetValidMB,0x00424B50); - - ASSIGN(bookPagesList,0x006D3F30); - - ASSIGN(bookIsMonster,0x006D3EEC); - ASSIGN(bookWndState,0x006D3EE8); - ASSIGN(bookColorNormal,0x006D3EF4); - ASSIGN(bookColorDisabled,0x006D3EF8); - ASSIGN(bookSpellSelected,0x006D417C); - ASSIGN(bookSelSpell,0x006D3F28); - - ASSIGN(bookSpellNumberDnD,0x006E037C); - ASSIGN(bookSpellDnDType,0x006E0380); - - ASSIGN(bookLineHeight,0x006D3E14); - ASSIGN(bookListTotalCount,0x006D4168); - ASSIGN(bookListHidden,0x006D416C); - - ASSIGN(drawSetTextColor,0x00434390); - ASSIGN(drawGetStringSize,0x0043F840); - ASSIGN(drawString,0x0043F6E0); - ASSIGN(drawUpdateMB,0x00452D80); - ASSIGN(wndSetTooltip,0x0046B000); - ASSIGN(gLoadImg,0x0042F970); - - ASSIGN(guiSpellListedNumbers,0x006D3F44); - - ASSIGN(spellDefPtr,0x00663EF0); - bool useMySpells=false; - if (useMySpells) - { - //////// - /// 0045DCA0 - , - - /// - - - /// .. - InjectJumpTo(0x0045ADF0,myBookUpdateList); - ///// / - InjectJumpTo(0x0045BE60,drawSpellListPre); - InjectJumpTo(0x0045B76A,getAbilForDnDPre); - InjectJumpTo(0x0045B801,getCreaForDnDPre); - InjectJumpTo(0x0045B83A,getSpellForDnDPre); - //InjectJumpTo(0x0045DC40,mySpellKeyPackSetSpell); - - /// - /// +74 - - InjectOffs(0x0045D0C1+1,&mySpellRewardPre); - - -// InjectOffs(0x004778E6+1,&getAbilIconForDnDPre); -// InjectOffs(0x004778FA+1,&getSpellIconForDnDPre); - - InjectAddr(0x0045B93E+1,&mySelectedSpell);// bookMoveToPage - InjectAddr(0x0045B2A7+1,&mySelectedSpell);// bookLeftProc - InjectAddr(0x0045B2D6+1,&mySelectedSpell);// bookLeftProc - InjectAddr(0x0045B103+2,&mySelectedSpell);// bookRightProc - InjectAddr(0x0045B177+2,&mySelectedSpell);// bookRightProc - InjectAddr(0x0045B18C+2,&mySelectedSpell);// bookRightProc - - InjectJumpTo(0x0045C005,mySpellSelectOnePre); // - - InjectJumpTo(0x0045FE6F,(void*)0x0045FE81); - - spellGetInit(); - - netRegClientPacket(upSpellStart,onSpellStart); - netRegClientPacket(upSpellSync,onSpellSync); - - //InjectJumpTo(0x0045C3A2,); - } - lua_createtable(L,256,0); - for (int i=1;i=75) && (Spell<114); + } + int __cdecl mySpellReward(int Spell,BYTE *PlayerInfo,int PlayerClass) + /// надлежит вернуть 1 если спелл добавляется + /// 0 - если не добавляется (например уже был) + { + int Top=lua_gettop(L); + getClientVar("bookSpellList"); + if (PlayerClass==0) // конверсия абилок в спеллы + Spell+=ABIL_TO_SPELL; + int i,n=lua_objlen(L,-1); + for (i=1;i<=n+1;i++) + { + lua_rawgeti(L,-1,i); + if (lua_tointeger(L,-1)==Spell) + break; + lua_settop(L,Top+1); + } + if (i==n+1) + { + lua_rawseti(L,-2,i); // спелла небыло - добавляем + lua_pushinteger(L,Spell); + } + getClientVar("spellData"); + lua_pushinteger(L,Spell); + lua_gettable(L,-2); + if (lua_type(L,-1)==LUA_TNUMBER)/// Либо тут число - левел спелла + { + /// todo - повысить уровень + } + else + { + lua_getfield(L,-1,"level"); + lua_pushinteger(L,lua_tointeger(L,-1)+1); + lua_getfield(L,-3,"level"); + } + lua_settop(L,Top); + return 1; + } + void __declspec(naked) mySpellRewardPre() + // вызывается когда клиент получает новый СТАНДАРТНЫЙ спелл + // Здесь может быть интересным только возможность НЕ ДАТЬ спелл игроку + // если мы уже его давали + { + __asm + { + pop eax // достаем адрес возврата + push ebx // кладем игрока + push ebp // кладем спелл + call mySpellReward + add esp,0xC + cmp ebp,0x22 + jnz l1 + mov ecx,eax /// добавляем трап + push 0x0045D0D4 + ret +l1: + test eax,eax + jz l2 + cmp [esp+0x1C],edi // параметр - открыть книгу или нет + jz l2 + push 0x0045D117 // показываем книгу + ret +l2: + push 0x0045D139 // ничего не показываем + ret + }; + } + + void drawDefAbil(int Spell,int plrClass,int X,int Y) + { + } + void drawDefCreature(int Spell,int plrClass,int X,int Y) + { + drawSetTextColor( + ((2==plrClass) && !mySpellIsEnabled(Spell))? // если конж + *bookColorDisabled: + *bookColorNormal + ); + const wchar_t *Name=mySpellLoadName(Spell); + int W=0; + drawGetStringSize(NULL,Name,&W,NULL,0x80); + drawString(NULL,Name,X-W/2,Y); + } + + void drawDefSpell(int Spell,int plrClass,int X,int Y) + { + drawSetTextColor( + !mySpellIsEnabled(Spell)? + *bookColorDisabled: + *bookColorNormal + ); + const wchar_t *Name=mySpellLoadName(Spell); + int W=0; + drawGetStringSize(NULL,Name,&W,NULL,0x80); + drawString(NULL,Name,X-W/2,Y); + } + void drawUniItem(int X,int Y,bool isCreatures) + { + int i=-1; + lua_getfield(L,i--,"flags"); + DWORD Flags=lua_tointeger(L,-1); + if ( (0!=Flags&sfCreature) ^ isCreatures ) + return; + DWORD Color=*bookColorNormal; + lua_getfield(L,i--,"color"); + if (lua_type(L,-1)==LUA_TNUMBER) + Color=lua_tointeger(L,-1); + lua_getfield(L,i--,"disabled"); + drawSetTextColor( + 0!=lua_toboolean(L,-1)? + *bookColorDisabled: + Color + ); + wchar_t Name[120]; + size_t Len=0; + lua_getfield(L,i--,"name"); + const char *NameS=lua_tolstring(L,-1,&Len); + if (Len!=0) + { + if (Len>119) + Len=119; + mbstowcs(Name,NameS,120); + Name[Len]=0; + } + else + wcscpy(Name,L"(wrong)"); + int W=0; + drawGetStringSize(NULL,Name,&W,NULL,0x80); + drawString(NULL,Name,X-W/2,Y); + } + void drawSpellList(int PageN,int LinesPerPage,int X,int Y) + { /// В этой функции может быть существенная потеря быстродействия + int Top=lua_gettop(L); + getClientVar("bookSpellList"); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return; + } + bool isCreatures=(1==*bookWndState); + + int Count=lua_objlen(L,-1);// сколько спеллов нам известно + *bookListTotalCount=Count; + *bookPagesList=1 + (Count+LinesPerPage)/LinesPerPage; + *bookListHidden=0; + int i=1+PageN*LinesPerPage*2,right=i+LinesPerPage; + if (i+2*LinesPerPagekeyRowPtr[KeyN].Spell=NewSpell; + BYTE *P=(BYTE*)KeyPack->spellWndItemMB[KeyN]; + if (NewSpell<0x100) + { + if (P!=NULL) + wndSetTooltip(P+24,spellLoadName(NewSpell)); + if (clientPlayerInfoPtr!=0) + drawUpdateMB(794,100);/// магические числа, не знаю почему такие + return; + } + //особый случай + int Top=lua_gettop(L); + lua_pushlightuserdata(L,&getSpellForDnD); + + lua_gettable(L,LUA_REGISTRYINDEX);/// запишем выбранный спелл + lua_getfield(L,-1,"name"); + size_t Len; + const char *S=lua_tolstring(L,-1,&Len); + wchar_t Buf[200]=L"(Uni spell)"; + if (Len>0) + mbstowcs(Buf,S,min(Len,199)); + wndSetTooltip(P+24,Buf); + if (clientPlayerInfoPtr!=0) + drawUpdateMB(794,100);/// магические числа, не знаю почему такие + + lua_settop(L,Top); + return; + }*/ + void __declspec(naked) getAbilForDnDPre() + { + __asm{ + push 2 + push ecx + call getSpellForDnD + add esp,8 + mov ecx,eax + push 0x0045B85D + ret + }; + } + void __declspec(naked) getCreaForDnDPre() + { + __asm{ + push 3 + push ecx + call getSpellForDnD + add esp,8 + push 0x0045B85D + ret + }; + } + void __declspec(naked) getSpellForDnDPre() + { + __asm{ + push 1 + push ecx + call getSpellForDnD + add esp,8 + push 0x0045B85D + ret + }; + } + void __declspec(naked) drawSpellListPre() + { + __asm{ + push [esp+0x22C-0x214] + push [esp+0x230-0x218] + push ecx + push esi + call drawSpellList + add esp,0x10 + push 0x0045C78D + ret + } + } + + void onSpellStart(BYTE *Packet) + { + audSyllStartSpeak(*((DWORD*)Packet)); + } + void onSpellSync(BYTE *Packet) + { + DWORD StartIdx=*((DWORD *)(Packet)); + } +} +extern void InjectJumpTo(DWORD Addr,void *Fn); +extern void InjectOffs(DWORD Addr,void *Fn); +extern void InjectAddr(DWORD Addr,void *Fn); + +void mapLoadSpells() +{ + int Top=lua_gettop(L); + int plrClass=(*clientPlayerInfoPtr)[0x8CB]; + luaL_loadstring(L, + "local l={...}; " + "table.sort(l[1]," + "function (a,b) " + "return spellInfo(a).name < spellInfo(b).name " + "end)" + ); + lua_getfield(L,LUA_REGISTRYINDEX,"client"); + lua_setfenv(L,-2); + getClientVar("bookSpellList"); + int Cnt=1; + lua_pushinteger(L,0x101); + lua_rawseti(L,-2,Cnt++); + lua_pushinteger(L,0x102); + lua_rawseti(L,-2,Cnt++); + + if (plrClass != 0) + { + for (int i=0;i success + if (0==luaL_loadstring(L, + "local me,tx,ty=... \n" + "local x,y = unitPos(me) \n" + "if not mapTraceRay(x,y,tx,ty,5) then return false end \n" + "soundMake(0x28,tx,ty) " // звук срабатывания ловушки + "netPointFx(0x89,tx,ty) " +// "soundSyll(me,1) " + "local r=createObject('waterbarrel',tx,ty) \n" + "unitDecay(r,600) return true")) + { + lua_setfield(L,-2,"servOnStart"); + } + else + { + conPrintI(lua_tostring(L,-1)); + lua_pop(L,1); + } + lua_settable(L,-3); + lua_settop(L,Top); +} +void spellGetInit(); + +void spellListInit() +{ + ASSIGN(audSyllStartSpeak,0x0049BB80); + + ASSIGN(clientPlayerInfoPtr,0x00853BB0); + ASSIGN(spellGetValidMB,0x00424B50); + + ASSIGN(bookPagesList,0x006D3F30); + + ASSIGN(bookIsMonster,0x006D3EEC); + ASSIGN(bookWndState,0x006D3EE8); + ASSIGN(bookColorNormal,0x006D3EF4); + ASSIGN(bookColorDisabled,0x006D3EF8); + ASSIGN(bookSpellSelected,0x006D417C); + ASSIGN(bookSelSpell,0x006D3F28); + + ASSIGN(bookSpellNumberDnD,0x006E037C); + ASSIGN(bookSpellDnDType,0x006E0380); + + ASSIGN(bookLineHeight,0x006D3E14); + ASSIGN(bookListTotalCount,0x006D4168); + ASSIGN(bookListHidden,0x006D416C); + + ASSIGN(drawSetTextColor,0x00434390); + ASSIGN(drawGetStringSize,0x0043F840); + ASSIGN(drawString,0x0043F6E0); + ASSIGN(drawUpdateMB,0x00452D80); + ASSIGN(wndSetTooltip,0x0046B000); + ASSIGN(gLoadImg,0x0042F970); + + ASSIGN(guiSpellListedNumbers,0x006D3F44); + + ASSIGN(spellDefPtr,0x00663EF0); + bool useMySpells=false; + if (useMySpells) + { + //////// драгдроп + /// 0045DCA0 - там функция, которая вызывается при попытки бросить спелл куда-либо + /// - соответственно ее править если надо кидать спеллы в другие окна + + ///обновляет и считает сколько есть спелов и т.п. + InjectJumpTo(0x0045ADF0,myBookUpdateList); + ///// рисование списка спеллов/кричей + InjectJumpTo(0x0045BE60,drawSpellListPre); + InjectJumpTo(0x0045B76A,getAbilForDnDPre); + InjectJumpTo(0x0045B801,getCreaForDnDPre); + InjectJumpTo(0x0045B83A,getSpellForDnDPre); + //InjectJumpTo(0x0045DC40,mySpellKeyPackSetSpell); + + /// иконка в просмотре отдельной книги за конжа и мага + /// кричи идут как спеллы +74 + + InjectOffs(0x0045D0C1+1,&mySpellRewardPre); + + +// InjectOffs(0x004778E6+1,&getAbilIconForDnDPre); +// InjectOffs(0x004778FA+1,&getSpellIconForDnDPre); + + InjectAddr(0x0045B93E+1,&mySelectedSpell);//пусть bookMoveToPage листает нашу переменную + InjectAddr(0x0045B2A7+1,&mySelectedSpell);//пусть bookLeftProc листает нашу переменную + InjectAddr(0x0045B2D6+1,&mySelectedSpell);//пусть bookLeftProc листает нашу переменную + InjectAddr(0x0045B103+2,&mySelectedSpell);//пусть bookRightProc листает нашу переменную + InjectAddr(0x0045B177+2,&mySelectedSpell);//пусть bookRightProc листает нашу переменную + InjectAddr(0x0045B18C+2,&mySelectedSpell);//пусть bookRightProc листает нашу переменную + + InjectJumpTo(0x0045C005,mySpellSelectOnePre); // джамп на установку виртуального спела в режиме одного объекта + + InjectJumpTo(0x0045FE6F,(void*)0x0045FE81); + + spellGetInit(); + + netRegClientPacket(upSpellStart,onSpellStart); + netRegClientPacket(upSpellSync,onSpellSync); + + //InjectJumpTo(0x0045C3A2,); + } + lua_createtable(L,256,0); + for (int i=1;i - -BYTE *spellDefPtr=0; -extern void *(__cdecl *gLoadImg)(const char *Name); -extern int mySelectedSpell;// , -extern float (__cdecl *getFloatByName)(const char *Name); - -void *(__cdecl *spellAbilGetIcon)(int Spell,int Enabled); - -DWORD __cdecl mySpellGetFlags(int Spell) -{ - DWORD Ret=0; - int Top=lua_gettop(L); - if (Spell==0x100) - { - getClientVar("bookSpellList"); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return 0; - } - lua_pushinteger(L,mySelectedSpell+1); - lua_gettable(L,-2); - Spell=lua_tointeger(L,-1); - lua_settop(L,Top); - } - if (Spell<0x100) - { - Ret=*((DWORD*)(spellDefPtr + 0x10 + Spell*0x50)); - return Ret; - } - getClientVar("spellData"); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return 0; - } - lua_pushinteger(L,Spell); - lua_gettable(L,-2); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return 0; - } - lua_getfield(L,-1,"flags"); - Ret=lua_tointeger(L,-1); - lua_settop(L,Top); - return Ret; -} -int __cdecl mySpellIsEnabled(int Spell) -{ - int Ret=0; - int Top=lua_gettop(L); - if (Spell==0x100) - { - getClientVar("bookSpellList"); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return 0; - } - lua_pushinteger(L,mySelectedSpell+1); - lua_gettable(L,-2); - Spell=lua_tointeger(L,-1); - lua_settop(L,Top); - } - getClientVar("spellData"); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return 0; - } - lua_pushinteger(L,Spell); - lua_gettable(L,-2); - if (lua_type(L,-1)!=LUA_TTABLE) - { - if (lua_type(L,-1)==LUA_TNUMBER) - Ret=*((int*)(spellDefPtr + 0x14 + Spell*0x50)); - lua_settop(L,Top); - return Ret; - } - - lua_getfield(L,-1,"disabled"); - Ret=(0==lua_toboolean(L,-1) )?0:1; - lua_settop(L,Top); - return Ret; -} -const wchar_t* __cdecl mySpellLoadName(int Spell) -{ - const wchar_t* Ret=0; - int Top=lua_gettop(L); - if (Spell==0x100) - { - getClientVar("bookSpellList"); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return 0; - } - lua_pushinteger(L,mySelectedSpell+1); - lua_gettable(L,-2); - Spell=lua_tointeger(L,-1); - lua_settop(L,Top); - } - if (Spell<0x100) - { - if (Spell<0 || Spell>ABIL_TO_SPELL ) - return L"(null)"; - if (0==*((int**)(spellDefPtr + 0x18 + Spell*0x50))) - return L"(not set)"; - return *((wchar_t**)(spellDefPtr + 0x0 + Spell*0x50)); - } - getClientVar("spellData"); - lua_pushinteger(L,Spell); - lua_gettable(L,-2); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return L"(wrong)"; - } - lua_getfield(L,-1,"name"); - static wchar_t Buf[200]=L"";/// .... - size_t Len=0; - const char *S=lua_tolstring(L,-1,&Len); - if (Len>0) - { - mbstowcs(Buf,S,min(Len,199)); - Ret=Buf; - } - else - Ret=L"(null)"; - lua_settop(L,Top); - return Ret; -} -namespace -{ - DWORD __cdecl mySpellHaveFlags(int Spell,DWORD Flags) - { - return ((mySpellGetFlags(Spell) & Flags) == 0)?0:1; - } - const wchar_t* __cdecl mySpellLoadDesc(int Spell) - { - const wchar_t* Ret=0; - int Top=lua_gettop(L); - if (Spell==0x100) - { - getClientVar("bookSpellList"); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return 0; - } - lua_pushinteger(L,mySelectedSpell+1); - lua_gettable(L,-2); - Spell=lua_tointeger(L,-1); - lua_settop(L,Top); - } - if (Spell<0x100) - { - if (Spell<0 || Spell>ABIL_TO_SPELL ) - return L"(null)"; - wchar_t *Ret=*((wchar_t**)(spellDefPtr + 0x4 + Spell*0x50)); - if (Ret==NULL) - Ret=L"(null)"; - return Ret; - } - getClientVar("spellData"); - lua_pushinteger(L,Spell); - lua_gettable(L,-2); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return L"(wrong)"; - } - lua_getfield(L,-1,"description"); - static wchar_t Buf[200]=L"";/// .... - size_t Len=0; - const char *S=lua_tolstring(L,-1,&Len); - if (Len>0) - { - mbstowcs(Buf,S,min(Len,199)); - Ret=Buf; - } - else - Ret=L"(null)"; - lua_settop(L,Top); - return Ret; - } - int __cdecl mySpellManaCost(int Spell,int Type)//1=ok 2=trap - { - int Ret=0; - int Top=lua_gettop(L); - if (Spell==0x100) - { - getClientVar("bookSpellList"); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return 0; - } - lua_pushinteger(L,mySelectedSpell+1); - lua_gettable(L,-2); - Spell=lua_tointeger(L,-1); - lua_settop(L,Top); - } - if (Spell<0x100) - { - if (Spell>=0 || SpellABIL_TO_SPELL ) - return Ret; - return *((void**)(spellDefPtr + 0x8 + Spell*0x50)); - } - getClientVar("spellData"); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return Ret; - } - lua_pushinteger(L,Spell); - lua_gettable(L,-2); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return NULL; - } - - lua_getfield(L,-1,"icon"); - if (lua_type(L,-1)==LUA_TLIGHTUSERDATA) - Ret=lua_touserdata(L,-1); - else - { - if (lua_type(L,-1)==LUA_TNUMBER) - Ret=mySpellLoadIcon(lua_tointeger(L,-1) ); - else if (lua_type(L,-1)==LUA_TSTRING) - Ret=gLoadImg(lua_tostring(L,-1)); - if (Ret!=0) - { - lua_pushlightuserdata(L,Ret); - lua_setfield(L,-3,"icon"); - } - } - lua_settop(L,Top); - return Ret; - } - - BYTE *mySpellSyllList(int Spell) // - { - int Top=lua_gettop(L); - BYTE Ret[10]={0}; - if (Spell==0x100) - { - getClientVar("bookSpellList"); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return Ret; - } - lua_pushinteger(L,mySelectedSpell+1); - lua_gettable(L,-2); - Spell=lua_tointeger(L,-1); - lua_settop(L,Top); - } - - if (Spell<0x100) - { - if (Spell<0 || Spell>ABIL_TO_SPELL ) - return Ret; - return (spellDefPtr + 0x1C + Spell*0x50); - } - getClientVar("spellData"); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return Ret; - } - lua_pushinteger(L,Spell); - lua_gettable(L,-2); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return Ret; - } - - lua_getfield(L,-1,"syll"); - if (lua_type(L,-1)==LUA_TSTRING) - { - const char *S=lua_tostring(L,-1); - if (S!=NULL) - { - - for (BYTE *B=Ret;*S!=0;S++,B++) - { - if (*S>='0' && *S<='9') - *B=*S-'0'; - } - } - } - lua_settop(L,Top); - return Ret; - } - - void *__cdecl myAbilLoadIcon(int Spell,int Recently) - { - void *Ret=0; - int Top=lua_gettop(L); - if (Spell==0x100) - { - getClientVar("bookSpellList"); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return 0; - } - lua_pushinteger(L,mySelectedSpell+1); - lua_gettable(L,-2); - Spell=lua_tointeger(L,-1); - lua_settop(L,Top); - } - - if (Spell<0x100) - { - return spellAbilGetIcon(Spell,Recently); - } - getClientVar("spellData"); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return NULL; - } - lua_pushinteger(L,Spell); - lua_gettable(L,-2); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return NULL; - } - - lua_getfield(L,-1,"icon"); - if (lua_type(L,-1)==LUA_TLIGHTUSERDATA) - Ret=lua_touserdata(L,-1); - else - { - if (lua_type(L,-1)==LUA_TNUMBER) - Ret=mySpellLoadIcon(lua_tointeger(L,-1) ); - else if (lua_type(L,-1)==LUA_TSTRING) - Ret=gLoadImg(lua_tostring(L,-1)); - if (Ret!=0) - { - lua_pushlightuserdata(L,Ret); - lua_setfield(L,-3,"icon"); - } - } - lua_settop(L,Top); - return Ret; - } - void *__cdecl mySpellLoadIconH(int Spell) - { - void *Ret=spellAbilGetIcon(2,1); - int Top=lua_gettop(L); - if (Spell==0x100) - { - getClientVar("bookSpellList"); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return Ret; - } - lua_pushinteger(L,mySelectedSpell+1); - lua_gettable(L,-2); - Spell=lua_tointeger(L,-1); - lua_settop(L,Top); - } - - if (Spell<0x100) - { - if (Spell<0 || Spell>ABIL_TO_SPELL ) - return Ret; - return *((void**)(spellDefPtr + 0x0C + Spell*0x50)); - } - getClientVar("spellData"); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return Ret; - } - lua_pushinteger(L,Spell); - lua_gettable(L,-2); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return Ret; - } - lua_getfield(L,-1,"iconH"); - if (lua_type(L,-1)==LUA_TLIGHTUSERDATA) - Ret=lua_touserdata(L,-1); - else - { - if (lua_type(L,-1)==LUA_TNUMBER) - Ret=mySpellLoadIconH(lua_tointeger(L,-1) ); - else if (lua_type(L,-1)==LUA_TSTRING) - Ret=gLoadImg(lua_tostring(L,-1)); - if (Ret!=0) - { - lua_pushlightuserdata(L,Ret); - lua_setfield(L,-3,"iconH"); - } - } - lua_settop(L,Top); - return Ret; - } - // - int spellInfo(lua_State *L) - { - if (lua_type(L,1)!=LUA_TNUMBER && lua_type(L,1)!=LUA_TSTRING) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - int Spell=lua_tointeger(L,1); - lua_newtable(L); - int Top=lua_gettop(L); - if (Spell==0x100) - { - getClientVar("bookSpellList"); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return 0; - } - lua_pushinteger(L,mySelectedSpell+1); - lua_gettable(L,-2); - Spell=lua_tointeger(L,-1); - lua_settop(L,Top); - } - if (Spell>0x100) - { - getClientVar("spellData"); - lua_pushinteger(L,Spell); - lua_gettable(L,-2); - if (!lua_isnil(L,-1)) - { - lua_pushnil(L); - while(lua_next(L,-2)!=0) - { - lua_pushvalue(L,-2); - lua_insert(L,-2); - lua_settable(L,-6); // value,key,key,src,spellData,dst - } - } - lua_pop(L,3); - return 1; - } - char Name[60]; - const wchar_t *WName=mySpellLoadName(Spell); - if (WName!=NULL) - { - wcstombs(Name,WName,wcslen(WName));; - lua_pushstring(L,Name); - lua_setfield(L,-2,"name"); - } - lua_pushnumber(L,mySpellGetFlags(Spell)); - lua_setfield(L,-2,"flags"); - - return 1; - } -} -extern void InjectJumpTo(DWORD Addr,void *Fn); -extern void InjectOffs(DWORD Addr,void *Fn); -extern void InjectAddr(DWORD Addr,void *Fn); -void spellGetInit() -{ - - //ASSIGN(spellDefPtr,0x00663EF0); - ASSIGN(spellAbilGetIcon,0x00425310); - - /// -- - InjectOffs(0x0045CB5C+1,&myAbilLoadIcon); - - // - InjectJumpTo(0x00424A50,&mySpellHaveFlags); - InjectJumpTo(0x00424A70,&mySpellGetFlags); - InjectJumpTo(0x00424A90,&mySpellLoadIcon); // - InjectJumpTo(0x00424AB0,&mySpellLoadIconH); // - InjectJumpTo(0x00424930,&mySpellLoadName); // - InjectJumpTo(0x00424A30,&mySpellLoadDesc); // - InjectJumpTo(0x004249A0,&mySpellManaCost); // - InjectJumpTo(0x00424A20,&mySpellSyllList); // - InjectJumpTo(0x00424B70,&mySpellIsEnabled);// - - // - InjectAddr(0x0049BBC0,(void*)0x2964A151); - InjectAddr(0x0049BBC4,(void*)0xC0850071); - InjectAddr(0x0049BBD4,(void*)0xFFFFFFFF); - InjectAddr(0x0049BC70,(void*)0x39FFFFFF); - InjectAddr(0x0049BB80,(void*)0x0424448B); - InjectAddr(0x0049BB88,(void*)0x64A30084); - InjectAddr(0x0049BBB0,(void*)0x64A3C033); - InjectAddr(0x0049BBB4,(void*)0xC3007129); -// InjectAddr(0x0049BBB0,(void*)0x296405C4); - - - registerclient("spellInfo",spellInfo); +#include "stdafx.h" +#include + +BYTE *spellDefPtr=0; +extern void *(__cdecl *gLoadImg)(const char *Name); +extern int mySelectedSpell;// спелл, выбранный в книге в данный момент +extern float (__cdecl *getFloatByName)(const char *Name); + +void *(__cdecl *spellAbilGetIcon)(int Spell,int Enabled); + +DWORD __cdecl mySpellGetFlags(int Spell) +{ + DWORD Ret=0; + int Top=lua_gettop(L); + if (Spell==0x100) + { + getClientVar("bookSpellList"); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return 0; + } + lua_pushinteger(L,mySelectedSpell+1); + lua_gettable(L,-2); + Spell=lua_tointeger(L,-1); + lua_settop(L,Top); + } + if (Spell<0x100) + { + Ret=*((DWORD*)(spellDefPtr + 0x10 + Spell*0x50)); + return Ret; + } + getClientVar("spellData"); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return 0; + } + lua_pushinteger(L,Spell); + lua_gettable(L,-2); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return 0; + } + lua_getfield(L,-1,"flags"); + Ret=lua_tointeger(L,-1); + lua_settop(L,Top); + return Ret; +} +int __cdecl mySpellIsEnabled(int Spell) +{ + int Ret=0; + int Top=lua_gettop(L); + if (Spell==0x100) + { + getClientVar("bookSpellList"); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return 0; + } + lua_pushinteger(L,mySelectedSpell+1); + lua_gettable(L,-2); + Spell=lua_tointeger(L,-1); + lua_settop(L,Top); + } + getClientVar("spellData"); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return 0; + } + lua_pushinteger(L,Spell); + lua_gettable(L,-2); + if (lua_type(L,-1)!=LUA_TTABLE) + { + if (lua_type(L,-1)==LUA_TNUMBER) + Ret=*((int*)(spellDefPtr + 0x14 + Spell*0x50)); + lua_settop(L,Top); + return Ret; + } + + lua_getfield(L,-1,"disabled"); + Ret=(0==lua_toboolean(L,-1) )?0:1; + lua_settop(L,Top); + return Ret; +} +const wchar_t* __cdecl mySpellLoadName(int Spell) +{ + const wchar_t* Ret=0; + int Top=lua_gettop(L); + if (Spell==0x100) + { + getClientVar("bookSpellList"); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return 0; + } + lua_pushinteger(L,mySelectedSpell+1); + lua_gettable(L,-2); + Spell=lua_tointeger(L,-1); + lua_settop(L,Top); + } + if (Spell<0x100) + { + if (Spell<0 || Spell>ABIL_TO_SPELL ) + return L"(null)"; + if (0==*((int**)(spellDefPtr + 0x18 + Spell*0x50))) + return L"(not set)"; + return *((wchar_t**)(spellDefPtr + 0x0 + Spell*0x50)); + } + getClientVar("spellData"); + lua_pushinteger(L,Spell); + lua_gettable(L,-2); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return L"(wrong)"; + } + lua_getfield(L,-1,"name"); + static wchar_t Buf[200]=L"";/// ох ненадежная идея эти статики.... + size_t Len=0; + const char *S=lua_tolstring(L,-1,&Len); + if (Len>0) + { + mbstowcs(Buf,S,min(Len,199)); + Ret=Buf; + } + else + Ret=L"(null)"; + lua_settop(L,Top); + return Ret; +} +namespace +{ + DWORD __cdecl mySpellHaveFlags(int Spell,DWORD Flags) + { + return ((mySpellGetFlags(Spell) & Flags) == 0)?0:1; + } + const wchar_t* __cdecl mySpellLoadDesc(int Spell) + { + const wchar_t* Ret=0; + int Top=lua_gettop(L); + if (Spell==0x100) + { + getClientVar("bookSpellList"); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return 0; + } + lua_pushinteger(L,mySelectedSpell+1); + lua_gettable(L,-2); + Spell=lua_tointeger(L,-1); + lua_settop(L,Top); + } + if (Spell<0x100) + { + if (Spell<0 || Spell>ABIL_TO_SPELL ) + return L"(null)"; + wchar_t *Ret=*((wchar_t**)(spellDefPtr + 0x4 + Spell*0x50)); + if (Ret==NULL) + Ret=L"(null)"; + return Ret; + } + getClientVar("spellData"); + lua_pushinteger(L,Spell); + lua_gettable(L,-2); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return L"(wrong)"; + } + lua_getfield(L,-1,"description"); + static wchar_t Buf[200]=L"";/// ох ненадежная идея эти статики.... + size_t Len=0; + const char *S=lua_tolstring(L,-1,&Len); + if (Len>0) + { + mbstowcs(Buf,S,min(Len,199)); + Ret=Buf; + } + else + Ret=L"(null)"; + lua_settop(L,Top); + return Ret; + } + int __cdecl mySpellManaCost(int Spell,int Type)//1=ok 2=trap + { + int Ret=0; + int Top=lua_gettop(L); + if (Spell==0x100) + { + getClientVar("bookSpellList"); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return 0; + } + lua_pushinteger(L,mySelectedSpell+1); + lua_gettable(L,-2); + Spell=lua_tointeger(L,-1); + lua_settop(L,Top); + } + if (Spell<0x100) + { + if (Spell>=0 || SpellABIL_TO_SPELL ) + return Ret; + return *((void**)(spellDefPtr + 0x8 + Spell*0x50)); + } + getClientVar("spellData"); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return Ret; + } + lua_pushinteger(L,Spell); + lua_gettable(L,-2); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return NULL; + } + + lua_getfield(L,-1,"icon"); + if (lua_type(L,-1)==LUA_TLIGHTUSERDATA) + Ret=lua_touserdata(L,-1); + else + { + if (lua_type(L,-1)==LUA_TNUMBER) + Ret=mySpellLoadIcon(lua_tointeger(L,-1) ); + else if (lua_type(L,-1)==LUA_TSTRING) + Ret=gLoadImg(lua_tostring(L,-1)); + if (Ret!=0) + { + lua_pushlightuserdata(L,Ret); + lua_setfield(L,-3,"icon"); + } + } + lua_settop(L,Top); + return Ret; + } + + BYTE *mySpellSyllList(int Spell) // возвращает последовательность для показа слогов + { + int Top=lua_gettop(L); + BYTE Ret[10]={0}; + if (Spell==0x100) + { + getClientVar("bookSpellList"); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return Ret; + } + lua_pushinteger(L,mySelectedSpell+1); + lua_gettable(L,-2); + Spell=lua_tointeger(L,-1); + lua_settop(L,Top); + } + + if (Spell<0x100) + { + if (Spell<0 || Spell>ABIL_TO_SPELL ) + return Ret; + return (spellDefPtr + 0x1C + Spell*0x50); + } + getClientVar("spellData"); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return Ret; + } + lua_pushinteger(L,Spell); + lua_gettable(L,-2); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return Ret; + } + + lua_getfield(L,-1,"syll"); + if (lua_type(L,-1)==LUA_TSTRING) + { + const char *S=lua_tostring(L,-1); + if (S!=NULL) + { + + for (BYTE *B=Ret;*S!=0;S++,B++) + { + if (*S>='0' && *S<='9') + *B=*S-'0'; + } + } + } + lua_settop(L,Top); + return Ret; + } + + void *__cdecl myAbilLoadIcon(int Spell,int Recently) + { + void *Ret=0; + int Top=lua_gettop(L); + if (Spell==0x100) + { + getClientVar("bookSpellList"); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return 0; + } + lua_pushinteger(L,mySelectedSpell+1); + lua_gettable(L,-2); + Spell=lua_tointeger(L,-1); + lua_settop(L,Top); + } + + if (Spell<0x100) + { + return spellAbilGetIcon(Spell,Recently); + } + getClientVar("spellData"); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return NULL; + } + lua_pushinteger(L,Spell); + lua_gettable(L,-2); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return NULL; + } + + lua_getfield(L,-1,"icon"); + if (lua_type(L,-1)==LUA_TLIGHTUSERDATA) + Ret=lua_touserdata(L,-1); + else + { + if (lua_type(L,-1)==LUA_TNUMBER) + Ret=mySpellLoadIcon(lua_tointeger(L,-1) ); + else if (lua_type(L,-1)==LUA_TSTRING) + Ret=gLoadImg(lua_tostring(L,-1)); + if (Ret!=0) + { + lua_pushlightuserdata(L,Ret); + lua_setfield(L,-3,"icon"); + } + } + lua_settop(L,Top); + return Ret; + } + void *__cdecl mySpellLoadIconH(int Spell) + { + void *Ret=spellAbilGetIcon(2,1); + int Top=lua_gettop(L); + if (Spell==0x100) + { + getClientVar("bookSpellList"); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return Ret; + } + lua_pushinteger(L,mySelectedSpell+1); + lua_gettable(L,-2); + Spell=lua_tointeger(L,-1); + lua_settop(L,Top); + } + + if (Spell<0x100) + { + if (Spell<0 || Spell>ABIL_TO_SPELL ) + return Ret; + return *((void**)(spellDefPtr + 0x0C + Spell*0x50)); + } + getClientVar("spellData"); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return Ret; + } + lua_pushinteger(L,Spell); + lua_gettable(L,-2); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return Ret; + } + lua_getfield(L,-1,"iconH"); + if (lua_type(L,-1)==LUA_TLIGHTUSERDATA) + Ret=lua_touserdata(L,-1); + else + { + if (lua_type(L,-1)==LUA_TNUMBER) + Ret=mySpellLoadIconH(lua_tointeger(L,-1) ); + else if (lua_type(L,-1)==LUA_TSTRING) + Ret=gLoadImg(lua_tostring(L,-1)); + if (Ret!=0) + { + lua_pushlightuserdata(L,Ret); + lua_setfield(L,-3,"iconH"); + } + } + lua_settop(L,Top); + return Ret; + } + // возвращает в луа инфу о спелле + int spellInfo(lua_State *L) + { + if (lua_type(L,1)!=LUA_TNUMBER && lua_type(L,1)!=LUA_TSTRING) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + int Spell=lua_tointeger(L,1); + lua_newtable(L); + int Top=lua_gettop(L); + if (Spell==0x100) + { + getClientVar("bookSpellList"); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return 0; + } + lua_pushinteger(L,mySelectedSpell+1); + lua_gettable(L,-2); + Spell=lua_tointeger(L,-1); + lua_settop(L,Top); + } + if (Spell>0x100) + { + getClientVar("spellData"); + lua_pushinteger(L,Spell); + lua_gettable(L,-2); + if (!lua_isnil(L,-1)) + { + lua_pushnil(L); + while(lua_next(L,-2)!=0) + { + lua_pushvalue(L,-2); + lua_insert(L,-2); + lua_settable(L,-6); // value,key,key,src,spellData,dst + } + } + lua_pop(L,3); + return 1; + } + char Name[60]; + const wchar_t *WName=mySpellLoadName(Spell); + if (WName!=NULL) + { + wcstombs(Name,WName,wcslen(WName));; + lua_pushstring(L,Name); + lua_setfield(L,-2,"name"); + } + lua_pushnumber(L,mySpellGetFlags(Spell)); + lua_setfield(L,-2,"flags"); + + return 1; + } +} +extern void InjectJumpTo(DWORD Addr,void *Fn); +extern void InjectOffs(DWORD Addr,void *Fn); +extern void InjectAddr(DWORD Addr,void *Fn); +void spellGetInit() +{ + + //ASSIGN(spellDefPtr,0x00663EF0); + ASSIGN(spellAbilGetIcon,0x00425310); + + /// абилки в просмотре отдельной книги за воина -- потом поправить + InjectOffs(0x0045CB5C+1,&myAbilLoadIcon); + + // проверка на наличие флагов в спелле + InjectJumpTo(0x00424A50,&mySpellHaveFlags); + InjectJumpTo(0x00424A70,&mySpellGetFlags); + InjectJumpTo(0x00424A90,&mySpellLoadIcon); // правим функцию обычной иконки + InjectJumpTo(0x00424AB0,&mySpellLoadIconH); // и подсвеченной иконки + InjectJumpTo(0x00424930,&mySpellLoadName); // правим функцию определения имени спелла + InjectJumpTo(0x00424A30,&mySpellLoadDesc); // и описания + InjectJumpTo(0x004249A0,&mySpellManaCost); // и цены в мане + InjectJumpTo(0x00424A20,&mySpellSyllList); // правим функцию показа слогов + InjectJumpTo(0x00424B70,&mySpellIsEnabled);// и разрешенности + + // правим произношение на длинные номера спелов + InjectAddr(0x0049BBC0,(void*)0x2964A151); + InjectAddr(0x0049BBC4,(void*)0xC0850071); + InjectAddr(0x0049BBD4,(void*)0xFFFFFFFF); + InjectAddr(0x0049BC70,(void*)0x39FFFFFF); + InjectAddr(0x0049BB80,(void*)0x0424448B); + InjectAddr(0x0049BB88,(void*)0x64A30084); + InjectAddr(0x0049BBB0,(void*)0x64A3C033); + InjectAddr(0x0049BBB4,(void*)0xC3007129); +// InjectAddr(0x0049BBB0,(void*)0x296405C4); + + + registerclient("spellInfo",spellInfo); } \ No newline at end of file diff --git a/spells.cpp b/spells.cpp index 359f0e2..4a983b2 100644 --- a/spells.cpp +++ b/spells.cpp @@ -1,355 +1,355 @@ -#include "stdafx.h" -#include "unit.h" - -int (__cdecl *spellAccept)(int SpellType,void *Caster,void *CasterMB2,void *Carrier, - SpellTargetBlock *Block,int Power); -int (__cdecl *spellGetPower)(int Spell,void *Caster); -// -void (__cdecl *spellCancelDurSpell)(int Spell,void *Caster); -// - -void (__cdecl *spellBuffOff)(void *Target,int BuffN); -int (__cdecl *spellDefHasFlags)(int Spell,DWORD Flags); -void (__cdecl *createSpellFly)(void *Caster,void *Target,int Spell); -void (__cdecl *applyToTarget)(void *Target,int Buff,int Delay,int SpellPower); -int (__cdecl *myCastSpellByUser)(int Spell, void *Caster, SpellTargetBlock *TargetBlock); -// -extern int (__cdecl *audSyllStartSpeak)(int SpellN); -extern bigUnitStruct **unitCreatedList; -extern DWORD *GameFlags; -namespace -{ - - int buffApplyL(lua_State*L) - { - if (lua_type(L,1)!=LUA_TLIGHTUSERDATA || lua_type(L,2)!=LUA_TNUMBER || lua_type(L,3)!=LUA_TNUMBER) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - int Buff=lua_tointeger(L,2); - if (Buff<0 || Buff>31) - return 0; - int delay=lua_tointeger(L,3); - if (delay<0) - return 0; - applyToTarget(lua_touserdata(L,1),Buff,delay,5); - return 0; - } - /// - ( ) - /// - - - int myCastSpellByUserPlayer(int Spell, void *Caster, SpellTargetBlock *TargetBlock) - { - bool check=true; - if (*GameFlags & 0x1000!=0) // - return myCastSpellByUser(Spell, Caster, TargetBlock); - if(spellDefHasFlags(Spell,0x200400)==1 && Spell!=34 && (Spell<75 || Spell>114)) - { - if(Caster!=TargetBlock->target && spellDefHasFlags(Spell,0x600)==1) - check=false; - if(Caster==TargetBlock->target && spellDefHasFlags(Spell,0x600)==0) - check=false; - } - if(check) - return myCastSpellByUser(Spell, Caster, TargetBlock); - else - { - // - return 1; - } - } - int myCastSpellByUserMob(int Spell, void *Caster, SpellTargetBlock *TargetBlock) - { - int R,Top=lua_gettop(L); - - lua_getglobal(L,"unitOnCastList"); - lua_pushlightuserdata(L,Caster); - if (lua_type(L,-2)!=LUA_TNIL) - lua_gettable(L,-2); - - if (spellDefHasFlags(Spell,0x20)) - { - spellBuffOff(Caster,0x00); - spellBuffOff(Caster,0x17); - spellCancelDurSpell(0x43,Caster);// - } - if ( - spellDefHasFlags(Spell,0x04) &&// - TargetBlock->target!=Caster // - ) - { - createSpellFly(Caster,TargetBlock->target,Spell); - -// - if (lua_type(L,-1)==LUA_TFUNCTION) - { - bigUnitStruct *B=*unitCreatedList; - for (;B!=NULL;B=(bigUnitStruct *)B->nextUnit) - { - if (B->parentUnit!=Caster) - continue; // - if (B->thingType!=0x3BB) - continue; // - break;/// 99% , .. - } - if (B) // - - { - lua_pushinteger(L,Spell); - lua_pushlightuserdata(L,Caster); - lua_pushlightuserdata(L,TargetBlock->target); - lua_pushlightuserdata(L,B); - lua_pushnumber(L,TargetBlock->targX); - lua_pushnumber(L,TargetBlock->targY); - lua_pcall(L,6,0,0); - } - } - R=1; - } - else - { - R=spellAccept(Spell,Caster,Caster,Caster, - TargetBlock, spellGetPower(Spell,Caster)); - lua_pushinteger(L,Spell); - lua_pushlightuserdata(L,Caster); - lua_pushlightuserdata(L,TargetBlock->target); - lua_pushnil(L); - lua_pushnumber(L,TargetBlock->targX); - lua_pushnumber(L,TargetBlock->targY); - lua_pcall(L,6,0,0); - - } - lua_settop(L,Top); - return R; - } - int spellBuff(lua_State *L) - { - return 0; - } - int spellApplyL(lua_State *L) - { - /// ,,, [,X,Y,[SpellPower=3], ] - if ( - (lua_type(L,1)!=LUA_TLIGHTUSERDATA)|| - (lua_type(L,2)!=LUA_TNUMBER)|| - (lua_type(L,3)!=LUA_TLIGHTUSERDATA) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - void *Targ=lua_touserdata(L,1); - int Type=lua_tointeger(L,2); - void *Carrier=lua_touserdata(L,3); - void *Source=0,*Thru=0; - SpellTargetBlock Bk; - int i=4; - if (lua_type(L,i)==LUA_TLIGHTUSERDATA) - Source=lua_touserdata(L,i); - i++; - if (lua_type(L,i)==LUA_TNUMBER) - { - Bk.targX=lua_tonumber(L,i); - i++; - if(lua_type(L,i)!=LUA_TNUMBER) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - Bk.targY=lua_tonumber(L,i); - i++; - } - else - { - BYTE *B=(BYTE *)Targ; - if(Targ!=NULL) - { - if (( 0!=(0x4 & B[8]) )) - { - B+=0x2EC;// - B=*((BYTE**)B);B+=0x114;// - B=*((BYTE**)B);B+=0x8EC; - Bk.targX=*((int*)B);B+=4; - Bk.targY=*((int*)B); - } - else - { - B+=0x38; - Bk.targX=*((float*)B);B+=4; - Bk.targY=*((float*)B); - } - } - else - { - Bk.targX=Bk.targY=0; - } - - } - int Power=3; - if (lua_type(L,i)==LUA_TNUMBER) - { - Power=lua_tointeger(L,i); - i++; - } - if (lua_type(L,i)==LUA_TLIGHTUSERDATA) - Thru=lua_touserdata(L,i); - if(Thru==NULL) - Thru=Source; - if(Source==NULL) - { - Source=Thru=Carrier; - } - Bk.target=Targ; - int R=spellAccept(Type,Source,Thru,Carrier,&Bk,Power); - lua_pushinteger(L,R); - return 1; - } - int spellSync(lua_State *L) - { - int Top=lua_gettop(L); - byte Buf[250],*P=Buf; - int Size; - P+=UNIPACKET_HEAD; - Size=0; - - getClientVar("spellData"); - lua_pushnil(L); - SendBuffer Out; - while (0!=lua_next(L,-2)) - { - if (lua_type(L,-2)!=LUA_TNUMBER) - { - lua_pop(L,1); - continue; - } - int Spell=lua_tointeger(L,-2); - *((DWORD*)P)=Spell; - if (lua_type(L,-1)==LUA_TNUMBER) - { - } - netUniPacket(upSpellSync,P,Size); - netSendNotOne(Buf,P-Buf,NULL); /// - } - lua_settop(L,Top); - return 0; - } -} -extern void InjectOffs(DWORD Addr,void *Fn); -extern void (__cdecl *netPriMsg)(void *PlayerUnit,char *String,int Flag); -extern DWORD *GameFlags; -/// -/// netReportSpellStat -void spellServDoCustom(int SpellArr[5],bool OnSelf,BYTE *MyPlayer,BYTE *MyUc) -{ - int Top=lua_gettop(L); - getClientVar("spellData"); - lua_pushinteger(L,SpellArr[0]); - lua_gettable(L,-2); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return; - } - lua_getfield(L,Top+2,"mana"); - int ManaCost=lua_tointeger(L,-1); - char TextBuf[80]=""; - BYTE *PlayerInfo=*((BYTE**)(MyUc+0x114)); - do - { - if ( 1 & *((DWORD*)(PlayerInfo+0xE60))) - { - lua_getfield(L,Top+2,"mayObserver"); - if (0==lua_toboolean(L,-1)) - { - netPriMsg(MyPlayer,"GeneralPrint:NoSpellWarningGeneral",0); - break; - } - } else if ( 2 & *((DWORD*)(PlayerInfo+0xE60))) - { - lua_getfield(L,Top+2,"mayPosessed"); - if (0==lua_toboolean(L,-1)) - { - netPriMsg(MyPlayer,"GeneralPrint:ConjureNoSpellWarning1",0); - break; - } - } - if ( 0x80 & *GameFlags) - { - lua_getfield(L,Top+2,"mayInChat"); - if (0==lua_toboolean(L,-1)) - { - break; - } - } - BYTE *Target=*((BYTE**)(MyUc+0x120)); - lua_newtable(L); /// - .. - lua_getfield(L,Top+2,"flags"); - lua_getfield(L,Top+2,"servOnStart"); - int X=lua_type(L,-1); - if (lua_type(L,-1)!=LUA_TFUNCTION) - { - sprintf(TextBuf,"Unimod: 'spellData[0x%x].servOnStart' not a function",SpellArr[0]); - conPrintI(TextBuf); - break; - } - lua_getfield(L,LUA_REGISTRYINDEX,"server"); - lua_setfenv(L,-2); - if (lua_tointeger(L,-2) & 0x20) /// - - { - if (Target!=NULL) - { - if ( 0x10000000 & (*(DWORD*)(Target+0x154)) ) /// - - { - break; - } - } - } - else - { - lua_pushlightuserdata(L,MyPlayer); - lua_pushnumber(L,*((int*)(PlayerInfo+0x8EC))); // x - lua_pushnumber(L,*((int*)(PlayerInfo+0x8F0))); // y - if (Target) lua_pushlightuserdata(L,Target); - else lua_pushnil(L); - lua_pushvalue(L,-7); // data - if (0!=lua_pcall(L,5,1,0))// player,targX,targY,targetUnit,data -> success - { - conPrintI(lua_tostring(L,-1)); - } - if (0!=lua_toboolean(L,-1)) // - { - /// , .. - - byte Buf[10],*P=Buf; - netUniPacket(upSpellStart,P,sizeof(DWORD)); - *((DWORD*)P)=SpellArr[0]; - netSendNotOne(Buf,P-Buf,MyUc); /// - } - } - } while(0); - lua_settop(L,Top); -} - - -void spellsInit() -{ - ASSIGN(spellAccept,0x004FD400); - ASSIGN(spellGetPower,0x004FE7B0); - ASSIGN(spellCancelDurSpell,0x004FEB10); - ASSIGN(spellBuffOff,0x004FF5B0); - ASSIGN(spellDefHasFlags,0x00424A50); - ASSIGN(createSpellFly,0x004FDDA0); - - ASSIGN(applyToTarget,0x004FF380); - - ASSIGN(myCastSpellByUser,0x004FDD20); - - InjectOffs(0x00541337+1,&myCastSpellByUserMob); - InjectOffs(0x004FB425+1,&myCastSpellByUserPlayer); - - registerserver("spellSync",&spellSync); - registerserver("spellApply",&spellApplyL); - registerserver("spellBuff",&spellBuff); - registerserver("buffApply",&buffApplyL); - - lua_newtable(L);// - registerServerVar("unitOnCastList"); +#include "stdafx.h" +#include "unit.h" + +int (__cdecl *spellAccept)(int SpellType,void *Caster,void *CasterMB2,void *Carrier, + SpellTargetBlock *Block,int Power); +int (__cdecl *spellGetPower)(int Spell,void *Caster); +// выключает спелл постоянного действия +void (__cdecl *spellCancelDurSpell)(int Spell,void *Caster); +// снимает какой-либо бафф +void (__cdecl *spellBuffOff)(void *Target,int BuffN); +int (__cdecl *spellDefHasFlags)(int Spell,DWORD Flags); +void (__cdecl *createSpellFly)(void *Caster,void *Target,int Spell); +void (__cdecl *applyToTarget)(void *Target,int Buff,int Delay,int SpellPower); +int (__cdecl *myCastSpellByUser)(int Spell, void *Caster, SpellTargetBlock *TargetBlock); +// +extern int (__cdecl *audSyllStartSpeak)(int SpellN); +extern bigUnitStruct **unitCreatedList; +extern DWORD *GameFlags; +namespace +{ + + int buffApplyL(lua_State*L) + { + if (lua_type(L,1)!=LUA_TLIGHTUSERDATA || lua_type(L,2)!=LUA_TNUMBER || lua_type(L,3)!=LUA_TNUMBER) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + int Buff=lua_tointeger(L,2); + if (Buff<0 || Buff>31) + return 0; + int delay=lua_tointeger(L,3); + if (delay<0) + return 0; + applyToTarget(lua_touserdata(L,1),Buff,delay,5); + return 0; + } + /// колдует спелл кем-то (списано с нокса) + /// когда моб чего-нить колдует - мы об этом узнаем + int myCastSpellByUserPlayer(int Spell, void *Caster, SpellTargetBlock *TargetBlock) + { + bool check=true; + if (*GameFlags & 0x1000!=0) // если ноксквест то нафги проверку + return myCastSpellByUser(Spell, Caster, TargetBlock); + if(spellDefHasFlags(Spell,0x200400)==1 && Spell!=34 && (Spell<75 || Spell>114)) + { + if(Caster!=TargetBlock->target && spellDefHasFlags(Spell,0x600)==1) + check=false; + if(Caster==TargetBlock->target && spellDefHasFlags(Spell,0x600)==0) + check=false; + } + if(check) + return myCastSpellByUser(Spell, Caster, TargetBlock); + else + { + // Здесь можно будет заодно кикать или банить нарушителя + return 1; + } + } + int myCastSpellByUserMob(int Spell, void *Caster, SpellTargetBlock *TargetBlock) + { + int R,Top=lua_gettop(L); + + lua_getglobal(L,"unitOnCastList"); + lua_pushlightuserdata(L,Caster); + if (lua_type(L,-2)!=LUA_TNIL) + lua_gettable(L,-2); + + if (spellDefHasFlags(Spell,0x20)) + { + spellBuffOff(Caster,0x00); + spellBuffOff(Caster,0x17); + spellCancelDurSpell(0x43,Caster);//выключаем щит + } + if ( + spellDefHasFlags(Spell,0x04) &&// нужно делать муху + TargetBlock->target!=Caster // мы не в себя колдуем + ) + { + createSpellFly(Caster,TargetBlock->target,Spell); + +//Ща мы найдем эту муху пока она не улетела + if (lua_type(L,-1)==LUA_TFUNCTION) + { + bigUnitStruct *B=*unitCreatedList; + for (;B!=NULL;B=(bigUnitStruct *)B->nextUnit) + { + if (B->parentUnit!=Caster) + continue; // не наша + if (B->thingType!=0x3BB) + continue; // не муха + break;/// 99% что она вообще первая в списке, т.к. ее только что создали + } + if (B) // если муху не нашли - так считаем что не сколдовалось + { + lua_pushinteger(L,Spell); + lua_pushlightuserdata(L,Caster); + lua_pushlightuserdata(L,TargetBlock->target); + lua_pushlightuserdata(L,B); + lua_pushnumber(L,TargetBlock->targX); + lua_pushnumber(L,TargetBlock->targY); + lua_pcall(L,6,0,0); + } + } + R=1; + } + else + { + R=spellAccept(Spell,Caster,Caster,Caster, + TargetBlock, spellGetPower(Spell,Caster)); + lua_pushinteger(L,Spell); + lua_pushlightuserdata(L,Caster); + lua_pushlightuserdata(L,TargetBlock->target); + lua_pushnil(L); + lua_pushnumber(L,TargetBlock->targX); + lua_pushnumber(L,TargetBlock->targY); + lua_pcall(L,6,0,0); + + } + lua_settop(L,Top); + return R; + } + int spellBuff(lua_State *L) + { + return 0; + } + int spellApplyL(lua_State *L) + { + /// Кому,Чего,Чем, [ОтКого,ГдеX,ГдеY,[SpellPower=3], Промежуточный] + if ( + (lua_type(L,1)!=LUA_TLIGHTUSERDATA)|| + (lua_type(L,2)!=LUA_TNUMBER)|| + (lua_type(L,3)!=LUA_TLIGHTUSERDATA) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + void *Targ=lua_touserdata(L,1); + int Type=lua_tointeger(L,2); + void *Carrier=lua_touserdata(L,3); + void *Source=0,*Thru=0; + SpellTargetBlock Bk; + int i=4; + if (lua_type(L,i)==LUA_TLIGHTUSERDATA) + Source=lua_touserdata(L,i); + i++; + if (lua_type(L,i)==LUA_TNUMBER) + { + Bk.targX=lua_tonumber(L,i); + i++; + if(lua_type(L,i)!=LUA_TNUMBER) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + Bk.targY=lua_tonumber(L,i); + i++; + } + else + { + BYTE *B=(BYTE *)Targ; + if(Targ!=NULL) + { + if (( 0!=(0x4 & B[8]) )) + { + B+=0x2EC;//контроллер + B=*((BYTE**)B);B+=0x114;//плэеринфо + B=*((BYTE**)B);B+=0x8EC; + Bk.targX=*((int*)B);B+=4; + Bk.targY=*((int*)B); + } + else + { + B+=0x38; + Bk.targX=*((float*)B);B+=4; + Bk.targY=*((float*)B); + } + } + else + { + Bk.targX=Bk.targY=0; + } + + } + int Power=3; + if (lua_type(L,i)==LUA_TNUMBER) + { + Power=lua_tointeger(L,i); + i++; + } + if (lua_type(L,i)==LUA_TLIGHTUSERDATA) + Thru=lua_touserdata(L,i); + if(Thru==NULL) + Thru=Source; + if(Source==NULL) + { + Source=Thru=Carrier; + } + Bk.target=Targ; + int R=spellAccept(Type,Source,Thru,Carrier,&Bk,Power); + lua_pushinteger(L,R); + return 1; + } + int spellSync(lua_State *L) + { + int Top=lua_gettop(L); + byte Buf[250],*P=Buf; + int Size; + P+=UNIPACKET_HEAD; + Size=0; + + getClientVar("spellData"); + lua_pushnil(L); + SendBuffer Out; + while (0!=lua_next(L,-2)) + { + if (lua_type(L,-2)!=LUA_TNUMBER) + { + lua_pop(L,1); + continue; + } + int Spell=lua_tointeger(L,-2); + *((DWORD*)P)=Spell; + if (lua_type(L,-1)==LUA_TNUMBER) + { + } + netUniPacket(upSpellSync,P,Size); + netSendNotOne(Buf,P-Buf,NULL); /// посылает всем клиентам кроме одного + } + lua_settop(L,Top); + return 0; + } +} +extern void InjectOffs(DWORD Addr,void *Fn); +extern void (__cdecl *netPriMsg)(void *PlayerUnit,char *String,int Flag); +extern DWORD *GameFlags; +/// для кастомной ловушки надо будет просто юзать другой спелл +/// Еще надо разослать netReportSpellStat всем вокруг +void spellServDoCustom(int SpellArr[5],bool OnSelf,BYTE *MyPlayer,BYTE *MyUc) +{ + int Top=lua_gettop(L); + getClientVar("spellData"); + lua_pushinteger(L,SpellArr[0]); + lua_gettable(L,-2); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return; + } + lua_getfield(L,Top+2,"mana"); + int ManaCost=lua_tointeger(L,-1); + char TextBuf[80]=""; + BYTE *PlayerInfo=*((BYTE**)(MyUc+0x114)); + do + { + if ( 1 & *((DWORD*)(PlayerInfo+0xE60))) + { + lua_getfield(L,Top+2,"mayObserver"); + if (0==lua_toboolean(L,-1)) + { + netPriMsg(MyPlayer,"GeneralPrint:NoSpellWarningGeneral",0); + break; + } + } else if ( 2 & *((DWORD*)(PlayerInfo+0xE60))) + { + lua_getfield(L,Top+2,"mayPosessed"); + if (0==lua_toboolean(L,-1)) + { + netPriMsg(MyPlayer,"GeneralPrint:ConjureNoSpellWarning1",0); + break; + } + } + if ( 0x80 & *GameFlags) + { + lua_getfield(L,Top+2,"mayInChat"); + if (0==lua_toboolean(L,-1)) + { + break; + } + } + BYTE *Target=*((BYTE**)(MyUc+0x120)); + lua_newtable(L); /// внутренние данные спела - для продолжительных и т.п. + lua_getfield(L,Top+2,"flags"); + lua_getfield(L,Top+2,"servOnStart"); + int X=lua_type(L,-1); + if (lua_type(L,-1)!=LUA_TFUNCTION) + { + sprintf(TextBuf,"Unimod: 'spellData[0x%x].servOnStart' not a function",SpellArr[0]); + conPrintI(TextBuf); + break; + } + lua_getfield(L,LUA_REGISTRYINDEX,"server"); + lua_setfenv(L,-2); + if (lua_tointeger(L,-2) & 0x20) /// Наш спелл имеет цель - надо делать муху + { + if (Target!=NULL) + { + if ( 0x10000000 & (*(DWORD*)(Target+0x154)) ) /// цель защищена от магии - ничего не делаем + { + break; + } + } + } + else + { + lua_pushlightuserdata(L,MyPlayer); + lua_pushnumber(L,*((int*)(PlayerInfo+0x8EC))); // x + lua_pushnumber(L,*((int*)(PlayerInfo+0x8F0))); // y + if (Target) lua_pushlightuserdata(L,Target); + else lua_pushnil(L); + lua_pushvalue(L,-7); // data + if (0!=lua_pcall(L,5,1,0))// player,targX,targY,targetUnit,data -> success + { + conPrintI(lua_tostring(L,-1)); + } + if (0!=lua_toboolean(L,-1)) //спелл удался + { + /// надо сохранить данные, отнять ману и т.п. + + byte Buf[10],*P=Buf; + netUniPacket(upSpellStart,P,sizeof(DWORD)); + *((DWORD*)P)=SpellArr[0]; + netSendNotOne(Buf,P-Buf,MyUc); /// посылает всем клиентам кроме одного + } + } + } while(0); + lua_settop(L,Top); +} + + +void spellsInit() +{ + ASSIGN(spellAccept,0x004FD400); + ASSIGN(spellGetPower,0x004FE7B0); + ASSIGN(spellCancelDurSpell,0x004FEB10); + ASSIGN(spellBuffOff,0x004FF5B0); + ASSIGN(spellDefHasFlags,0x00424A50); + ASSIGN(createSpellFly,0x004FDDA0); + + ASSIGN(applyToTarget,0x004FF380); + + ASSIGN(myCastSpellByUser,0x004FDD20); + + InjectOffs(0x00541337+1,&myCastSpellByUserMob); + InjectOffs(0x004FB425+1,&myCastSpellByUserPlayer); + + registerserver("spellSync",&spellSync); + registerserver("spellApply",&spellApplyL); + registerserver("spellBuff",&spellBuff); + registerserver("buffApply",&buffApplyL); + + lua_newtable(L);// в таблицу будем класть интересных нам мобов + registerServerVar("unitOnCastList"); } \ No newline at end of file diff --git a/sprite.cpp b/sprite.cpp index cd8ca90..50c13f5 100644 --- a/sprite.cpp +++ b/sprite.cpp @@ -1,76 +1,76 @@ -#include "stdafx.h" - -sprite_s *(__cdecl *spriteLoadAdd) (int thingType,int coordX,int coordY); -void (__cdecl *spriteDeleteStatic)(sprite_s *Sprite); - -void (__cdecl *drawImage)(void *ImgH,int X,int Y); - -extern int (__cdecl *noxDrawGetStringSize) (int FontPtr, wchar_t *String,int *Width,int,int); -extern void (__cdecl *drawString)(void *FontPtr,const wchar_t*String,int X,int Y); -extern tileDef_s *tileDefs; - -namespace -{ -/* - -*/ - void customSpriteDraw(void *DrawData,void *Sprite) - { - - } - - int drawTileImage(lua_State *L) - { - lua_settop(L,4); - int i=1; - if ( - (lua_type(L,i++)!=LUA_TNUMBER)|| - (lua_type(L,i++)!=LUA_TNUMBER)|| - (lua_type(L,i++)!=LUA_TNUMBER)|| - (lua_type(L,i++)!=LUA_TNUMBER) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - void **imageH=0;/// - imageH=(void **)tileDefs[lua_tointeger(L,1)].ImgPtr; - if (imageH==NULL) - return 0; - if ((imageH[lua_tointeger(L,2)])==NULL) - return 0; - drawImage(imageH,lua_tointeger(L,3),lua_tointeger(L,4)); - return 0; - } - int tileGetImage(lua_State *L) - { - lua_settop(L,2); - int i=1; - if ( - (lua_type(L,i++)!=LUA_TNUMBER)|| - (lua_type(L,i++)!=LUA_TNUMBER) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - void **imageH=0;/// - imageH=(void **)tileDefs[lua_tointeger(L,1)].ImgPtr; - if (imageH==NULL) - return 0; - void *Ret=imageH[lua_tointeger(L,2)]; - if (Ret==NULL) - return 0; - lua_pushlightuserdata(L,Ret); - return 1; - } -} -void spriteInit() -{ - ASSIGN(spriteLoadAdd,0x0045A360); - ASSIGN(spriteDeleteStatic,0x0045A4E0); - ASSIGN(drawImage,0x0047D2C0); - registerclient("tileDraw",&drawTileImage); - registerclient("tileImage",&tileGetImage); - +#include "stdafx.h" + +sprite_s *(__cdecl *spriteLoadAdd) (int thingType,int coordX,int coordY); +void (__cdecl *spriteDeleteStatic)(sprite_s *Sprite); + +void (__cdecl *drawImage)(void *ImgH,int X,int Y); + +extern int (__cdecl *noxDrawGetStringSize) (int FontPtr, wchar_t *String,int *Width,int,int); +extern void (__cdecl *drawString)(void *FontPtr,const wchar_t*String,int X,int Y); +extern tileDef_s *tileDefs; + +namespace +{ +/* +надо продумать способ отрисовки спрайтов с кастомными переменными +*/ + void customSpriteDraw(void *DrawData,void *Sprite) + { + + } + + int drawTileImage(lua_State *L) + { + lua_settop(L,4); + int i=1; + if ( + (lua_type(L,i++)!=LUA_TNUMBER)|| + (lua_type(L,i++)!=LUA_TNUMBER)|| + (lua_type(L,i++)!=LUA_TNUMBER)|| + (lua_type(L,i++)!=LUA_TNUMBER) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + void **imageH=0;/// тут бы проверок + imageH=(void **)tileDefs[lua_tointeger(L,1)].ImgPtr; + if (imageH==NULL) + return 0; + if ((imageH[lua_tointeger(L,2)])==NULL) + return 0; + drawImage(imageH,lua_tointeger(L,3),lua_tointeger(L,4)); + return 0; + } + int tileGetImage(lua_State *L) + { + lua_settop(L,2); + int i=1; + if ( + (lua_type(L,i++)!=LUA_TNUMBER)|| + (lua_type(L,i++)!=LUA_TNUMBER) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + void **imageH=0;/// тут бы проверок + imageH=(void **)tileDefs[lua_tointeger(L,1)].ImgPtr; + if (imageH==NULL) + return 0; + void *Ret=imageH[lua_tointeger(L,2)]; + if (Ret==NULL) + return 0; + lua_pushlightuserdata(L,Ret); + return 1; + } +} +void spriteInit() +{ + ASSIGN(spriteLoadAdd,0x0045A360); + ASSIGN(spriteDeleteStatic,0x0045A4E0); + ASSIGN(drawImage,0x0047D2C0); + registerclient("tileDraw",&drawTileImage); + registerclient("tileImage",&tileGetImage); + } \ No newline at end of file diff --git a/stdafx.cpp b/stdafx.cpp index 9583498..126f65d 100644 --- a/stdafx.cpp +++ b/stdafx.cpp @@ -1,8 +1,8 @@ -// stdafx.cpp : source file that includes just the standard includes -// Inject.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file +// stdafx.cpp : source file that includes just the standard includes +// Inject.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/stdafx.h b/stdafx.h index bac538e..4cc7793 100644 --- a/stdafx.h +++ b/stdafx.h @@ -1,362 +1,362 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#pragma once - -#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. -#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. -#endif -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#include - -typedef unsigned char byte; -typedef unsigned short WORD; -#pragma pack(1) - -extern "C" -{ -#include "lauxlib.h" -#include "lualib.h" -} - -extern lua_State *L; -typedef std::string TString; -typedef unsigned char byte; - -enum uniPacket_e -{ - upVersionRq=1, - upVersionResp, - - upWallChanged=5, - upStaticCreated, - upLuaRq, - upLuaResp, - upNewStatic, - upDelStatic, - upMoveStatic, - upUpdateDef, /// unitDef - upTryUnitUse, /// - upNotifyUnitUse,/// , - - upSendArchive, /// , - upChangeTile, /// - upSpellStart,/// - upSpellSync, /// - upSendBubble,/// - upSendPrintToCli,// - upVersionServerRq, // -}; -// -void netUniPacket(uniPacket_e Code,BYTE *&Data,int Size); -#define UNIPACKET_HEAD (3) - -#define ABIL_TO_SPELL (0x89) - -struct noxPoint -{ - float X; - float Y; - noxPoint(float x,float y):X(x),Y(y){} -}; -struct noxRect -{ - float X1; - float Y1; - float X2; - float Y2; - noxRect():X1(0),Y1(0),X2(0),Y2(0){} - noxRect(float x1,float y1, float x2,float y2):X1(x1),Y1(y1),X2(x2),Y2(y2){} -}; -struct noxRectInt -{ - int X1; - int Y1; - int X2; - int Y2; - noxRectInt(int x1,int y1, int x2,int y2):X1(x1),Y1(y1),X2(x2),Y2(y2){} -}; - -struct wallRec -{ - BYTE Dir; - BYTE tileName; - BYTE variation; - BYTE unk3; - BYTE wallFlags; - BYTE posX; - BYTE posY; - BYTE HP; - BYTE field_8; /// ? - BYTE gap_9[1];/// ? - USHORT wallId; - BYTE gap_c[4]; /// ? - int wallMapPtr; /// - - int nextWall; /// - - int mapYPtr; /// - - int doorPtr; /// ? - int field_20; -}; - -struct wallSecret_s -{ - int NextWallSecret_s; - int X; - int Y; - int wallRec_Ptr; - int timeToClose; - BYTE timeToOpen; - BYTE bitAuto; - BYTE chetchickOpen; - BYTE field_17; - int ChetchickClose; - int field_1c; -}; - -struct waypoint_s -{ - int Id; - int flag; - float X; - float Y; - char Name[256]; - -}; - -struct SpellTargetBlock -{ - void *target; - float targX,targY; -}; -typedef void * unitBigStructPtr; - -struct ServerData -{ - char mapName[8]; - char gap[1]; - char gameName[10]; - char gap_13[5]; - int field_18[5]; - DWORD weaponRestrictions; - DWORD armorRestrictions; - __int16 gameFlags; - unsigned __int16 fragLimit; - unsigned char timeLimitMB; - char isNew; -}; - -#define ASSIGN(X,Y) *((DWORD*)&(X))=((DWORD)(Y)); -DWORD uniCalcJump(DWORD From,void *To); - -extern void printI(const char *S); - -extern void conSetNextColor(int C); // . -extern void conPrintI(const char *S); -extern DWORD *GameFlags; - -void netSendAll(void *Buf,int BufSize); /// -void netSendNotOne(void *Buf,int BufSize,void *One); /// -void netSendServ(void *Buf,int BufSize);/// - -USHORT inline toShort(BYTE *X){return *((USHORT*)X);} -void inline fromShort(BYTE *&P,USHORT X){*((USHORT *)P)=X;P+=2;} - -struct spellPacket -{ - byte Pckt; - DWORD Spells[5]; - byte Dir;// 0= 1= -}; -struct FloatRect -{ - float left,top,right,bottom; - FloatRect(float l,float t,float r,float b):left(l),top(t),right(r),bottom(b){} -}; -void lua_error_(lua_State *L); - -struct ParseAttrib; -/// - -extern bool fsRead(const char *File,void *&Data, size_t &Size); - -/// - -extern void *(__cdecl *noxAlloc)(int Size); -extern void (__cdecl *noxFree)(void *Ptr); - -/// -typedef void (*netClientFn_s) (BYTE *Packet); -typedef void (*netServFn_s) (BYTE *Packet,BYTE *MyPlayer,BYTE *MyUc); -extern void netRegClientPacket(uniPacket_e Event,netClientFn_s Fn); -extern void netRegServPacket(uniPacket_e Event,netServFn_s Fn); -extern void parseAttr(lua_State *L,int KeyIdx,int ValIdx,void *Struct,const ParseAttrib *Attrs); - -inline void registerclient(const char *FnName,lua_CFunction Fn,int UpSize=0) -{ - lua_pushcclosure(L, Fn,UpSize); - lua_getfield(L,LUA_REGISTRYINDEX,"client"); - lua_pushvalue(L,-2); - lua_setfield(L,-2,FnName); - lua_pop(L,2);// -} -inline void registerserver(const char *FnName,lua_CFunction Fn,int UpSize=0) -{ - lua_pushcclosure(L, Fn,UpSize); - lua_getfield(L,LUA_REGISTRYINDEX,"server"); - lua_pushvalue(L,-2); - lua_setfield(L,-2,FnName); - lua_pop(L,2);// -} -inline void registerServerVar(const char *VarName) -{ - lua_getfield(L,LUA_REGISTRYINDEX,"server"); - lua_pushvalue(L,-2); - lua_setfield(L,-2,VarName); - lua_pop(L,2);// -} -inline void registerClientVar(const char *VarName) -{ - lua_getfield(L,LUA_REGISTRYINDEX,"client"); - lua_pushvalue(L,-2); - lua_setfield(L,-2,VarName); - lua_pop(L,2);// -} -inline void getServerVar(const char *VarName) -{ - lua_getfield(L,LUA_REGISTRYINDEX,"server"); - lua_getfield(L,-1,VarName); - lua_remove(L,-2); -} -inline void getClientVar(const char *VarName) -{ - lua_getfield(L,LUA_REGISTRYINDEX,"client"); - lua_getfield(L,-1,VarName); - lua_remove(L,-2); -} -struct sprite_s -{ - void *x; -}; -struct keyState -{ - int Spell; - int Direction; -}; -struct keyPack -{ - keyState Spells[25]; - int selectedRow; - keyState *keyRowPtr; - void *someWnd_D0; - void *spellWndItemMB[5]; - void *spellIconMB[5]; - int field_FC; -}; - - -enum spellFlags -{ - sfNeedFly = 4, - sfRemoveShieldEtc = 0x20, - sfCreature=0x0 -}; - -struct tileDef_s -{ - char Name[32]; - void *ImgPtr; - DWORD Flags; - DWORD doDamage; - short sizeMB; - short param2E; - DWORD colorMB; - byte tileSizeX; - byte tileSizeY; - char More[6]; -}; - -struct polygonAngle_s -{ - int numAngle; - float posX; - float posY; - int isCreated; -}; - - -struct polygon_s -{ - int filed_0; - char Name[76]; - int polygonIdx; - int field_54; - int posX1; - int posY1; - int posX2; - int posY2; - int color; - void *strucCoordinat; - int scriptFunction; - int field_74; - int field_78; - int field_7C; - short kolvoUglov; - short minimapGroup; - int field_84; - int field_88; -}; - -class SendBuffer /// -{ -public: - SendBuffer(); - - byte *RecvComplete(size_t &Len);// NULL - - void Write(byte *Data,size_t &Len); // - void WriteLuaVar(lua_State *L,bool Float=false); -}; -struct ParseAttrib /// -{ - const char *name; - int ofs; - int type; - /* - 1 int - +2 string - +3 color - +4 wstring - 5 bitfield (A=TablePtr) - */ - int argA; - void *argB; -}; -struct FxBuffer_t -{ - FxBuffer_t *Next; - int Size; - int FreeSize; - int SelIdx; - DWORD Data[]; - FxBuffer_t(int Sz):Next(0),Size(Sz){} - ~FxBuffer_t(){ if(Next) delete Next; } - void getValues(int First,int Len); /// - void addItem(int Val){((int*)Data)[SelIdx++]=Val;} - void addItemD(DWORD Val){Data[SelIdx++]=Val;} - - static FxBuffer_t *addBlock(int Size,int *Id); // , - static bool delBlock(int Id); // - static void drawBuffers(); -}; -extern const int *noxScreenX; -extern const int *noxScreenY; - -#include -typedef std::map ClientMap_s; -typedef std::map ServerMap_s; - - -#define goto wtf \ No newline at end of file +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include + +typedef unsigned char byte; +typedef unsigned short WORD; +#pragma pack(1) + +extern "C" +{ +#include "lauxlib.h" +#include "lualib.h" +} + +extern lua_State *L; +typedef std::string TString; +typedef unsigned char byte; + +enum uniPacket_e +{ + upVersionRq=1, + upVersionResp, + + upWallChanged=5, + upStaticCreated, + upLuaRq, + upLuaResp, + upNewStatic, + upDelStatic, + upMoveStatic, + upUpdateDef, /// сервер хочет изменить свойства unitDef + upTryUnitUse, /// клиент хочет ИСПОЛЬЗОВАТЬ предмет + upNotifyUnitUse,/// сервер сообщает, что кто-то использует предмет + upSendArchive, /// сервер сообщает, что вместе с картой придет еще и архив + upChangeTile, /// сервер меняет тайл + upSpellStart,/// сервер сообщает старт спелла + upSpellSync, /// сервер сообщаем всем свежий список спелов + upSendBubble,/// сервер хочет создать чат + upSendPrintToCli,// сервер присылает консоли строку + upVersionServerRq, //сервер запрашивает клиентскую версию юнимода +}; +// приписать к буферу наш заголовок для отправки +void netUniPacket(uniPacket_e Code,BYTE *&Data,int Size); +#define UNIPACKET_HEAD (3) + +#define ABIL_TO_SPELL (0x89) + +struct noxPoint +{ + float X; + float Y; + noxPoint(float x,float y):X(x),Y(y){} +}; +struct noxRect +{ + float X1; + float Y1; + float X2; + float Y2; + noxRect():X1(0),Y1(0),X2(0),Y2(0){} + noxRect(float x1,float y1, float x2,float y2):X1(x1),Y1(y1),X2(x2),Y2(y2){} +}; +struct noxRectInt +{ + int X1; + int Y1; + int X2; + int Y2; + noxRectInt(int x1,int y1, int x2,int y2):X1(x1),Y1(y1),X2(x2),Y2(y2){} +}; + +struct wallRec +{ + BYTE Dir; + BYTE tileName; + BYTE variation; + BYTE unk3; + BYTE wallFlags; + BYTE posX; + BYTE posY; + BYTE HP; + BYTE field_8; /// ? + BYTE gap_9[1];/// ? + USHORT wallId; + BYTE gap_c[4]; /// ? + int wallMapPtr; /// указатель на сегмент карты - НЕ ТРОГАТЬ + int nextWall; /// указатель на след стену - НЕ ТРОГАТЬ + int mapYPtr; /// указатель на следующую вертикальную стену - НЕ ТРОГАТЬ + int doorPtr; /// ? кажется здесь указатель на прилепленую дверь + int field_20; +}; + +struct wallSecret_s +{ + int NextWallSecret_s; + int X; + int Y; + int wallRec_Ptr; + int timeToClose; + BYTE timeToOpen; + BYTE bitAuto; + BYTE chetchickOpen; + BYTE field_17; + int ChetchickClose; + int field_1c; +}; + +struct waypoint_s +{ + int Id; + int flag; + float X; + float Y; + char Name[256]; + +}; + +struct SpellTargetBlock +{ + void *target; + float targX,targY; +}; +typedef void * unitBigStructPtr; + +struct ServerData +{ + char mapName[8]; + char gap[1]; + char gameName[10]; + char gap_13[5]; + int field_18[5]; + DWORD weaponRestrictions; + DWORD armorRestrictions; + __int16 gameFlags; + unsigned __int16 fragLimit; + unsigned char timeLimitMB; + char isNew; +}; + +#define ASSIGN(X,Y) *((DWORD*)&(X))=((DWORD)(Y)); +DWORD uniCalcJump(DWORD From,void *To); + +extern void printI(const char *S); + +extern void conSetNextColor(int C); // устанавливает цвет след. сообщения консоли +extern void conPrintI(const char *S); +extern DWORD *GameFlags; + +void netSendAll(void *Buf,int BufSize); /// посылает всем клиентам +void netSendNotOne(void *Buf,int BufSize,void *One); /// посылает всем клиентам кроме одного +void netSendServ(void *Buf,int BufSize);/// посылает серверу + +USHORT inline toShort(BYTE *X){return *((USHORT*)X);} +void inline fromShort(BYTE *&P,USHORT X){*((USHORT *)P)=X;P+=2;} + +struct spellPacket +{ + byte Pckt; + DWORD Spells[5]; + byte Dir;// 0= обычный 1= на себя +}; +struct FloatRect +{ + float left,top,right,bottom; + FloatRect(float l,float t,float r,float b):left(l),top(t),right(r),bottom(b){} +}; +void lua_error_(lua_State *L); + +struct ParseAttrib; +/// функция для доступа к данным архивов - в последствии через нее надо провести все +extern bool fsRead(const char *File,void *&Data, size_t &Size); + +/// Функции выделения ноксо-памяти +extern void *(__cdecl *noxAlloc)(int Size); +extern void (__cdecl *noxFree)(void *Ptr); + +/// Функция для регистрации пакетов клиенту и серверу +typedef void (*netClientFn_s) (BYTE *Packet); +typedef void (*netServFn_s) (BYTE *Packet,BYTE *MyPlayer,BYTE *MyUc); +extern void netRegClientPacket(uniPacket_e Event,netClientFn_s Fn); +extern void netRegServPacket(uniPacket_e Event,netServFn_s Fn); +extern void parseAttr(lua_State *L,int KeyIdx,int ValIdx,void *Struct,const ParseAttrib *Attrs); + +inline void registerclient(const char *FnName,lua_CFunction Fn,int UpSize=0) +{ + lua_pushcclosure(L, Fn,UpSize); + lua_getfield(L,LUA_REGISTRYINDEX,"client"); + lua_pushvalue(L,-2); + lua_setfield(L,-2,FnName); + lua_pop(L,2);// копию замыкания и таблицу +} +inline void registerserver(const char *FnName,lua_CFunction Fn,int UpSize=0) +{ + lua_pushcclosure(L, Fn,UpSize); + lua_getfield(L,LUA_REGISTRYINDEX,"server"); + lua_pushvalue(L,-2); + lua_setfield(L,-2,FnName); + lua_pop(L,2);// копию замыкания и таблицу +} +inline void registerServerVar(const char *VarName) +{ + lua_getfield(L,LUA_REGISTRYINDEX,"server"); + lua_pushvalue(L,-2); + lua_setfield(L,-2,VarName); + lua_pop(L,2);// копию переменной и таблицу +} +inline void registerClientVar(const char *VarName) +{ + lua_getfield(L,LUA_REGISTRYINDEX,"client"); + lua_pushvalue(L,-2); + lua_setfield(L,-2,VarName); + lua_pop(L,2);// копию переменной и таблицу +} +inline void getServerVar(const char *VarName) +{ + lua_getfield(L,LUA_REGISTRYINDEX,"server"); + lua_getfield(L,-1,VarName); + lua_remove(L,-2); +} +inline void getClientVar(const char *VarName) +{ + lua_getfield(L,LUA_REGISTRYINDEX,"client"); + lua_getfield(L,-1,VarName); + lua_remove(L,-2); +} +struct sprite_s +{ + void *x; +}; +struct keyState +{ + int Spell; + int Direction; +}; +struct keyPack +{ + keyState Spells[25]; + int selectedRow; + keyState *keyRowPtr; + void *someWnd_D0; + void *spellWndItemMB[5]; + void *spellIconMB[5]; + int field_FC; +}; + + +enum spellFlags +{ + sfNeedFly = 4, + sfRemoveShieldEtc = 0x20, + sfCreature=0x0 +}; + +struct tileDef_s +{ + char Name[32]; + void *ImgPtr; + DWORD Flags; + DWORD doDamage; + short sizeMB; + short param2E; + DWORD colorMB; + byte tileSizeX; + byte tileSizeY; + char More[6]; +}; + +struct polygonAngle_s +{ + int numAngle; + float posX; + float posY; + int isCreated; +}; + + +struct polygon_s +{ + int filed_0; + char Name[76]; + int polygonIdx; + int field_54; + int posX1; + int posY1; + int posX2; + int posY2; + int color; + void *strucCoordinat; + int scriptFunction; + int field_74; + int field_78; + int field_7C; + short kolvoUglov; + short minimapGroup; + int field_84; + int field_88; +}; + +class SendBuffer /// Предназначен для передачи по сети больших кусков +{ +public: + SendBuffer(); + + byte *RecvComplete(size_t &Len);// Вернет не NULL если приехали данные + + void Write(byte *Data,size_t &Len); // отправит буфер по кускам + void WriteLuaVar(lua_State *L,bool Float=false); +}; +struct ParseAttrib /// для всяких парсеров всяких структур +{ + const char *name; + int ofs; + int type; + /* + 1 int + +2 string + +3 color + +4 wstring + 5 bitfield (A=TablePtr) + */ + int argA; + void *argB; +}; +struct FxBuffer_t +{ + FxBuffer_t *Next; + int Size; + int FreeSize; + int SelIdx; + DWORD Data[]; + FxBuffer_t(int Sz):Next(0),Size(Sz){} + ~FxBuffer_t(){ if(Next) delete Next; } + void getValues(int First,int Len); /// для запроса по сети + void addItem(int Val){((int*)Data)[SelIdx++]=Val;} + void addItemD(DWORD Val){Data[SelIdx++]=Val;} + + static FxBuffer_t *addBlock(int Size,int *Id); //начинаем добавлять элементы, возвращаем айди + static bool delBlock(int Id); //удаляем блок + static void drawBuffers(); +}; +extern const int *noxScreenX; +extern const int *noxScreenY; + +#include +typedef std::map ClientMap_s; +typedef std::map ServerMap_s; + + +#define goto wtf юзать гоуту нельзя \ No newline at end of file diff --git a/tiles.cpp b/tiles.cpp index 50b8d7f..5188b35 100644 --- a/tiles.cpp +++ b/tiles.cpp @@ -1,283 +1,283 @@ -#include "stdafx.h" - -struct TileOne -{ - int image; - int vari; - int a,b; - TileOne *subTilePtr; -}; -struct TilePair -{ - DWORD flags; - TileOne left,right; -}; -tileDef_s *tileDefs; -TilePair ***tileRowData; -int *tileForceRedrawMB; - -void (__cdecl *tileFreeSubtiles)(void *tileOne);// tileOne -TileOne* (__cdecl *tileListAddNew)(int A,int B,int C,int D);/// Subtile - -bool (__cdecl *tileCheckImageVari)(int Vari); - -#define NOX_TILES_COUNT (0xB0) -namespace -{ - const char *tileNameByN(int N) - { - if (N<0 || N>=NOX_TILES_COUNT) - return NULL; - return tileDefs[N].Name; - }; - int tileGetName(lua_State*L) - { - lua_settop(L,1); - const char *R=tileNameByN(lua_tointeger(L,1)); - if (R==NULL) - lua_pushnil(L); - else - lua_pushstring(L,R); - return 1; - } - int tileMaxVari(lua_State*L) - { - int T=lua_tonumber(L,1); - if (T<0 || T>=NOX_TILES_COUNT) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - // , - // 0051D570 tileCheckImageVari - lua_pushinteger(L,tileDefs[T].tileSizeX*tileDefs[T].tileSizeY); - return 1; - } - int tileGet(lua_State*L) - { - lua_settop(L,2); - int x=lua_tointeger(L,1); - int y=lua_tointeger(L,2); - x/=46; - y/=23; - int right=y&1; - y>>=1; - if (x<0 || x>0x7F || y<0 || y>0x7F) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - TilePair *tp=((*tileRowData)[x])+y; - TileOne *One=0; - if (right==1) - { - if(tp->flags&2) - { - One=&tp->right; - } - } - else - { - if (tp->flags&1) - { - One=&tp->left; - } - } - if (One==NULL) - { - lua_pushnil(L); - return 1; - } - lua_newtable(L); - int i=1; - for (;One!=NULL;One=One->subTilePtr) - { - lua_pushinteger(L,One->image); - lua_rawseti(L,-2,i++); - lua_pushinteger(L,One->vari); - lua_rawseti(L,-2,i++); - lua_pushinteger(L,One->a); - lua_rawseti(L,-2,i++); - lua_pushinteger(L,One->b); - lua_rawseti(L,-2,i++); - } - return 1; - } - int tileSet2(lua_State*L) - { - lua_settop(L,3); - int x=lua_tointeger(L,1); - int y=lua_tointeger(L,2); - if (x<0 || y<0 || lua_type(L,3)!=LUA_TTABLE) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - int N=luaL_getn(L,3); - if (0!=(N&3))/// - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - if (N>4*6) - { - lua_pushstring(L,"wrong args - too many subtiles!"); - lua_error_(L); - } - x/=46; - y/=23; - int right=y&1; - y>>=1; - TilePair *tp=((*tileRowData)[x])+y; - TileOne *One=NULL; - if (right==1) - { - One=&tp->right; - tp->flags|=2; - } - else - { - One=&tp->left; - tp->flags|=1; - } - if (One==NULL) - { - lua_pushstring(L,"Unknown error!"); - lua_error_(L); - } - TileOne *Prev=NULL; - for (int i=1;isubTilePtr=One; - } - if (One==NULL) break; // - lua_rawgeti(L,3,i++); - One->image=lua_tointeger(L,-1); - lua_rawgeti(L,3,i++); - One->vari=lua_tointeger(L,-1); - lua_rawgeti(L,3,i++); - One->a=lua_tointeger(L,-1); - lua_rawgeti(L,3,i++); - One->b=lua_tointeger(L,-1); - lua_pop(L,4); - - Prev=One; - One=One->subTilePtr; - } - if (One!=0 && Prev!=NULL) - { - tileFreeSubtiles(Prev); - } - *tileForceRedrawMB=1; /// - return 0; - } - int tileSet(lua_State*L) - { - lua_settop(L,3); - int x=lua_tointeger(L,1); - int y=lua_tointeger(L,2); - if (x<0 || y<0 || lua_type(L,3)!=LUA_TTABLE) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - int N=luaL_getn(L,3); - if (0!=(N&3))/// - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - - BYTE B[80]; - BYTE *P=B; - if (4+1+(N*2)>80) - { - lua_pushstring(L,"wrong args - too many subtiles!"); - lua_error_(L); - } - netUniPacket(upChangeTile,P,4+1+(N*2) ); - *((short*)P)=x; - *((short*)P+1)=y; - P+=4; - *(P++)=0; - *(P++)=0;/// - - *(P++)=N; - short *S=(short*)P; - for (int i=1;i<=N;i++,S++) - { - lua_rawgeti(L,3,i); - *S=lua_tointeger(L,-1); - lua_pop(L,1); - } - netSendAll(B,((BYTE*)S)-B); - return 0; - } -} -void netOnTileChanged(BYTE *Buf,BYTE *End) -{ - if (End-Buf<=5) - return; - int i=0; - int x=*((short*)Buf+0),y=*((short*)Buf+1),N=Buf[4]; - x/=46; - y/=23; - int right=y&1; - y>>=1; - TilePair *tp=((*tileRowData)[x])+y; - TileOne *One=NULL; - if (right==1) - { - One=&tp->right; - tp->flags|=2; - } - else - { - One=&tp->left; - tp->flags|=1; - } - if (One==NULL) return;// - - BYTE *P=Buf; - P+=6; - N=*(P++); - short *S=(short*)P; - TileOne *Prev=NULL; - for (int i=0;isubTilePtr=One; - } - if (One==NULL) break; // - One->image=*(S++); - One->vari=*(S++); - One->a=*(S++); - One->b=*(S++); - Prev=One; - One=One->subTilePtr; - } - if (One!=0 && Prev!=NULL) - { - tileFreeSubtiles(Prev); - } - *tileForceRedrawMB=1; /// -} - -void tilesInit() -{ - ASSIGN(tileFreeSubtiles,0x00422200) - ASSIGN(tileListAddNew,0x00422160); - ASSIGN(tileDefs,0x008632E0); - ASSIGN(tileRowData,0x0085B7C0 ); - ASSIGN(tileForceRedrawMB,0x006F7A78); - ASSIGN(tileCheckImageVari,0x0051D570); - - registerserver("tileGet",tileGet); - registerserver("tileSet",tileSet); - registerserver("tileSet2",tileSet2); - registerclient("tileGetName",tileGetName); - registerclient("tileMaxVari",tileMaxVari); +#include "stdafx.h" + +struct TileOne +{ + int image; + int vari; + int a,b; + TileOne *subTilePtr; +}; +struct TilePair +{ + DWORD flags; + TileOne left,right; +}; +tileDef_s *tileDefs; +TilePair ***tileRowData; +int *tileForceRedrawMB; + +void (__cdecl *tileFreeSubtiles)(void *tileOne);// получает точно tileOne +TileOne* (__cdecl *tileListAddNew)(int A,int B,int C,int D);/// возможно Subtile + +bool (__cdecl *tileCheckImageVari)(int Vari); + +#define NOX_TILES_COUNT (0xB0) +namespace +{ + const char *tileNameByN(int N) + { + if (N<0 || N>=NOX_TILES_COUNT) + return NULL; + return tileDefs[N].Name; + }; + int tileGetName(lua_State*L) + { + lua_settop(L,1); + const char *R=tileNameByN(lua_tointeger(L,1)); + if (R==NULL) + lua_pushnil(L); + else + lua_pushstring(L,R); + return 1; + } + int tileMaxVari(lua_State*L) + { + int T=lua_tonumber(L,1); + if (T<0 || T>=NOX_TILES_COUNT) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + // ПОКА НЕ ЗНАЮ КАК ВЫЯСНИТЬ, + // надо ботать 0051D570 tileCheckImageVari + lua_pushinteger(L,tileDefs[T].tileSizeX*tileDefs[T].tileSizeY); + return 1; + } + int tileGet(lua_State*L) + { + lua_settop(L,2); + int x=lua_tointeger(L,1); + int y=lua_tointeger(L,2); + x/=46; + y/=23; + int right=y&1; + y>>=1; + if (x<0 || x>0x7F || y<0 || y>0x7F) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + TilePair *tp=((*tileRowData)[x])+y; + TileOne *One=0; + if (right==1) + { + if(tp->flags&2) + { + One=&tp->right; + } + } + else + { + if (tp->flags&1) + { + One=&tp->left; + } + } + if (One==NULL) + { + lua_pushnil(L); + return 1; + } + lua_newtable(L); + int i=1; + for (;One!=NULL;One=One->subTilePtr) + { + lua_pushinteger(L,One->image); + lua_rawseti(L,-2,i++); + lua_pushinteger(L,One->vari); + lua_rawseti(L,-2,i++); + lua_pushinteger(L,One->a); + lua_rawseti(L,-2,i++); + lua_pushinteger(L,One->b); + lua_rawseti(L,-2,i++); + } + return 1; + } + int tileSet2(lua_State*L) + { + lua_settop(L,3); + int x=lua_tointeger(L,1); + int y=lua_tointeger(L,2); + if (x<0 || y<0 || lua_type(L,3)!=LUA_TTABLE) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + int N=luaL_getn(L,3); + if (0!=(N&3))/// должно быть кратное четырем количество полей + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + if (N>4*6) + { + lua_pushstring(L,"wrong args - too many subtiles!"); + lua_error_(L); + } + x/=46; + y/=23; + int right=y&1; + y>>=1; + TilePair *tp=((*tileRowData)[x])+y; + TileOne *One=NULL; + if (right==1) + { + One=&tp->right; + tp->flags|=2; + } + else + { + One=&tp->left; + tp->flags|=1; + } + if (One==NULL) + { + lua_pushstring(L,"Unknown error!"); + lua_error_(L); + } + TileOne *Prev=NULL; + for (int i=1;isubTilePtr=One; + } + if (One==NULL) break; // вдруг при добавлении облом вышел + lua_rawgeti(L,3,i++); + One->image=lua_tointeger(L,-1); + lua_rawgeti(L,3,i++); + One->vari=lua_tointeger(L,-1); + lua_rawgeti(L,3,i++); + One->a=lua_tointeger(L,-1); + lua_rawgeti(L,3,i++); + One->b=lua_tointeger(L,-1); + lua_pop(L,4); + + Prev=One; + One=One->subTilePtr; + } + if (One!=0 && Prev!=NULL) + { + tileFreeSubtiles(Prev); + } + *tileForceRedrawMB=1; /// Тут надо послать на перерисовку экрана + return 0; + } + int tileSet(lua_State*L) + { + lua_settop(L,3); + int x=lua_tointeger(L,1); + int y=lua_tointeger(L,2); + if (x<0 || y<0 || lua_type(L,3)!=LUA_TTABLE) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + int N=luaL_getn(L,3); + if (0!=(N&3))/// должно быть кратное четырем количество полей + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + + BYTE B[80]; + BYTE *P=B; + if (4+1+(N*2)>80) + { + lua_pushstring(L,"wrong args - too many subtiles!"); + lua_error_(L); + } + netUniPacket(upChangeTile,P,4+1+(N*2) ); + *((short*)P)=x; + *((short*)P+1)=y; + P+=4; + *(P++)=0; + *(P++)=0;/// туда мы еще чего-нить запишем + *(P++)=N; + short *S=(short*)P; + for (int i=1;i<=N;i++,S++) + { + lua_rawgeti(L,3,i); + *S=lua_tointeger(L,-1); + lua_pop(L,1); + } + netSendAll(B,((BYTE*)S)-B); + return 0; + } +} +void netOnTileChanged(BYTE *Buf,BYTE *End) +{ + if (End-Buf<=5) + return; + int i=0; + int x=*((short*)Buf+0),y=*((short*)Buf+1),N=Buf[4]; + x/=46; + y/=23; + int right=y&1; + y>>=1; + TilePair *tp=((*tileRowData)[x])+y; + TileOne *One=NULL; + if (right==1) + { + One=&tp->right; + tp->flags|=2; + } + else + { + One=&tp->left; + tp->flags|=1; + } + if (One==NULL) return;// какая-то аццкая ошибка + BYTE *P=Buf; + P+=6; + N=*(P++); + short *S=(short*)P; + TileOne *Prev=NULL; + for (int i=0;isubTilePtr=One; + } + if (One==NULL) break; // вдруг при добавлении облом вышел + One->image=*(S++); + One->vari=*(S++); + One->a=*(S++); + One->b=*(S++); + Prev=One; + One=One->subTilePtr; + } + if (One!=0 && Prev!=NULL) + { + tileFreeSubtiles(Prev); + } + *tileForceRedrawMB=1; /// Тут надо послать на перерисовку экрана +} + +void tilesInit() +{ + ASSIGN(tileFreeSubtiles,0x00422200) + ASSIGN(tileListAddNew,0x00422160); + ASSIGN(tileDefs,0x008632E0); + ASSIGN(tileRowData,0x0085B7C0 ); + ASSIGN(tileForceRedrawMB,0x006F7A78); + ASSIGN(tileCheckImageVari,0x0051D570); + + registerserver("tileGet",tileGet); + registerserver("tileSet",tileSet); + registerserver("tileSet2",tileSet2); + registerclient("tileGetName",tileGetName); + registerclient("tileMaxVari",tileMaxVari); } \ No newline at end of file diff --git a/todo.txt b/todo.txt index 1383cc7..ed8e3ec 100644 --- a/todo.txt +++ b/todo.txt @@ -1,82 +1,82 @@ -> : - + "2" - - + "3" - RLE - + vbag - + - - ( ) - - ( ) - -> : - - - - ( ) - + / playerMouse - + - printSetOutput - , - -+> wndCreate - + Wdd - + AutoId - + ChildClick = ParentFn + Id - -+> - + - + - + A/B - -> - - - - - - - -> - + - - SaveList ( ) - -> - - - - store - -?> - -?> - -+> - -> - + - + - - - - IP - + - -> unitDef - -? - -> - - - - - - - - unitDef - -?> - - vbag - -> \ - - VBAG - -> - + ( ) - - + - - ( ) - + , (" " ) - + , / ( ), ( , - ) - - - - , : , , , , , , , - - , : : , , , ( - ), (WIZ,CON,WAR ), - - - ( ) - - , ( " " " ") - , - - + , - . . - - (nox.cfg) - - (nox.cfg) - + onDeathmatchFrag - + number playerScore([number New]) +> Загрузка картинок: + + доделать примитивное чтение в формате "2" - без прозрачности + + разобрался с форматом "3" - RLE с прозрачностью и полупрозрачностью + + связь между номерами vbag и спрайтами + + виртуальные изображения + - полупрозрачность (осталось проверить) + - использование цветов игрока в изображениях (пока не буду делать) + +> Редактор: + - сделать быстрое локальное обновление тайлов + - рисование линий и прямоугольников (для выделения например) + + Загрузка / задание тайла по playerMouse + + принт для текущего буфера + printSetOutput - задает куда печатать, при вызове по таймауту уходит обратно в принт + ++> wndCreate + + создание через Wdd для обоих веток + + AutoId для дочерних контролов + + ChildClick = ParentFn + Id + ++> Создать диалог тайла + + имя тайла + + вариция + + значения A/B + +> кастомные спеллы + - исследовать режим клика для спеллов частично + - синхронизация списка спеллов + - вызов кастомной функции на клиенте по спеллу + +> Улучшить диалог тайла + + Список сабтайлов + - SaveList (сохраняемый на диск) + +> Очистка при смене карты + - проверить таймауты + - использовать store для сохраняемого + +?> буффер для фоновой передачи блока данных + +?> поправить звуки через фиктивный массив + ++> исполнение команд + +> извлечь + + состав команд + + имена игроков + - статус обсервер + - IP игроков + + Пинг + +> создание unitDef + -? синхронизация для клиентов при рантайм добавлении + +> синхронизация + - общее добавление функций + - добавление модификаторов предметов + - добавление спеллов + - добавление unitDef + +?> кастомный тайлы + - связь между номерами vbag и спрайтами + +> кастомные анимации\ + - детализовать хранение анимаций в VBAG + +> Сетевая автоиризация + + Команда для получения банлиста (список текущих забаненых) - желательно дамп в файл + + Команда для разбана + - Команда для лочания сервера на пароль (этой команды нет в консоле) + + Команда, которая переведёт сервер в режим чата ("Новая игра" в окне настроек сервера) + + Команда, которая позволит добавлять/убавлять команды (делать больше двух или отключать их вовсе), а так же настраивать их (их название, цвет и прочее - а ля АдминТулз) + - переименование команды + - Команда, которая сделает дамп в файл следующих данных: название сервера, ИП сервера, название текущей карты, текущий режим игры, текущее количество фрагов, текущее количество времени до окончания текущей карты, список и название команд с количеством участников в каждой, количество участников в обсерве + - Команда, которая дампнет в файл следующу инфу: список игроков со следующей инфой: имя игрока, ИП игрока, количество фрагов игрока, принадлежность игрока к команде (если в обсерве - то вместо команды помечать что он в обсерве), класс игрока (WIZ,CON,WAR которые), пинг игрока + - Хук сразу после загрузки карты - которая бы запускал мою функцию (или файл) + - Хук, запускающийся сразу после конца карты (когда показывается текст "Такой то научил вас" или "Вы победили") - тоже, который бы запускал мою функцию или файл + - Оверрайд загрузки карты по мапсайклу на карту+режим игры, указанные в отдельном файле - если такой файл существует. Само собой после его выполнения оный файл удалять. + - Команда для принудительного сохранения всех настроек игры в файл (nox.cfg) + - Команда для принудительного перечитывания всех настроек игры из конфигурационного файла (nox.cfg) и применения его настроек + + хук на фраг onDeathmatchFrag + + функция модификации счета number playerScore([number New]) diff --git a/unit.cpp b/unit.cpp index 09cb5e6..b5c9043 100644 --- a/unit.cpp +++ b/unit.cpp @@ -1,396 +1,396 @@ -#include "stdafx.h" -#include "unit.h" -#include -#include "player.h" - -void (__cdecl *unitSetFollow)(bigUnitStruct* Me,void *Him); -void (__cdecl *unitBecomePet)(bigUnitStruct* Me,void *Him); -void (__cdecl *noxFrozen) (bigUnitStruct* Unit,int Num); -void (__cdecl *noxUnFrozen) (bigUnitStruct* Unit,int Num); -void (__cdecl *unitMove)(bigUnitStruct *Who,noxPoint *Pt); -void (__cdecl *unitActivate) (bigUnitStruct *Unit); -void (__cdecl *dropAllItems)(bigUnitStruct*Unit); -void (__cdecl *noxUnitHunt) (bigUnitStruct *Unit); -void (__cdecl *noxAgressionLevel) (bigUnitStruct *Unit,float *level); -void (__cdecl *noxMirrorShot) (bigUnitStruct *Shot,void *); -int (__cdecl *noxUnitTestBuff) (bigUnitStruct *Unit,int buffN); - -void (__cdecl *inventoryPut)(bigUnitStruct *Who,bigUnitStruct *What,int A); - -/// -bigUnitStruct **unitCreatedList; - -extern const char *(__cdecl *noxThingNameByType)(int Type); -extern int (__cdecl *noxGetUnitsInRect)(FloatRect *Rect, void (__cdecl *SomeFn)(void *Unit, void *Arg), void *Arg); - -struct UnitAndEye_s -{ - float unitX,unitY; - float unitViewX,unitViewY; -}; - -int (__cdecl *noxUnknown535250)(UnitAndEye_s *Ptr,int Unk1,int Unk2,int Unk3);//bool -void (__cdecl *unitSetDecayTime)(void *Unit,int Time);//bool -void (__cdecl *noxDeleteUnit)(void *Unit); - -void* (__cdecl *noxUnitDefByName)(const char *Name);// - -void (__cdecl* noxCreateAt)(unitBigStructPtr Obj,unitBigStructPtr ParentUnit, float X,float Y); - -namespace -{ - - int getUnitCoordL(lua_State *L) - { - if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - bigUnitStruct *Unit=(bigUnitStruct*)lua_touserdata(L,1); - if(Unit==NULL) - return 0; - lua_pushnumber(L,Unit->unitX); - lua_pushnumber(L,Unit->unitY); - return 2; - } - void unitPickImpl(void *Unit, void *L_) - { - void **LL=(void **)L_; - *LL=Unit; - } - int unitPickL(lua_State *L) - { - if ( - (lua_type(L,1)!=LUA_TNUMBER)|| - (lua_type(L,2)!=LUA_TNUMBER)|| - (lua_type(L,3)!=LUA_TNUMBER) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - void *P=0; - float x=lua_tonumber(L,1),y=lua_tonumber(L,2),d=lua_tonumber(L,3); - if (d<=0) - d=1; - noxGetUnitsInRect( - &FloatRect(x-d,y-d,x+d,y+d) - ,&unitPickImpl,&P); - if (P) - lua_pushlightuserdata(L,P); - else - lua_pushnil(L); - return 1; - } - int createObjectL(lua_State *L) - { - if ( - (lua_type(L,1)!=LUA_TSTRING)|| - (lua_type(L,2)!=LUA_TNUMBER)|| - (lua_type(L,3)!=LUA_TNUMBER) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - bigUnitStruct *T= - (bigUnitStruct *)objectCreateByName(lua_tostring(L,1)); - if (!T) - return 0; - noxCreateAt(T,0,lua_tonumber(L,2),lua_tonumber(L,3)); - if (T->Class & clImmobile) - { - BYTE Buf[256],*Out=Buf; - int Size=16; - netUniPacket(upNewStatic,Out,Size); - memcpy(Out,&T->thingType,4);Out+=4; - memcpy(Out,&T->unitX,4);Out+=4; - memcpy(Out,&T->unitY,4);Out+=4; - memcpy(Out,&T->netCode,4);Out+=4; - netSendAll(Buf,Out-Buf); - } - lua_pushlightuserdata(L,T); - return 1; - } - int createObjectIn(lua_State *L) - { - if ( - (lua_type(L,1)!=LUA_TSTRING)|| - (lua_type(L,2)!=LUA_TLIGHTUSERDATA) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - bigUnitStruct *T= - (bigUnitStruct *)objectCreateByName(lua_tostring(L,1)); - if (!T) - return 0; - inventoryPut((bigUnitStruct*)lua_touserdata(L,2),T,1); - lua_pushlightuserdata(L,T); - return 1; - } - int deleteUnitL(lua_State *L) - { - if ((lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - bigUnitStruct *P=(bigUnitStruct*)lua_touserdata(L,1); - if(P!=0) - { - if (P->Class & clImmobile) - { - BYTE Buf[256],*Out=Buf; - int Size=4; - netUniPacket(upDelStatic,Out,Size); - memcpy(Out,&P->netCode,4);Out+=4; - netSendAll(Buf,Out-Buf); - } - noxDeleteObject(P); - } - return 0; - } - int unitSetFollowL(lua_State*L) - { - if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA)||(lua_type(L,2)!=LUA_TLIGHTUSERDATA) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - bigUnitStruct *P1,*P2; - P1=(bigUnitStruct*)lua_touserdata(L,1);P2=(bigUnitStruct*)lua_touserdata(L,2); - if(P1==0 || P2==0) - return 0; - unitSetFollow(P1,P2); - return 0; - } - int unitBecomePetL(lua_State*L) - { - if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA)||(lua_type(L,2)!=LUA_TLIGHTUSERDATA) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - bigUnitStruct *P1,*P2; - P1=(bigUnitStruct*)lua_touserdata(L,1);P2=(bigUnitStruct*)lua_touserdata(L,2); - if(P1==0 || P2==0) - return 0; - unitBecomePet(P2,P1);/// - return 0; - } - - int unitHuntL(lua_State*L) - { - if (lua_type(L,1)!=LUA_TLIGHTUSERDATA ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - noxUnitHunt((bigUnitStruct*)lua_touserdata(L,1)); - return 0; - } - - int unitCopyUcL(lua_State*L) - { - if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - BYTE *P=(BYTE*)lua_touserdata(L,1); - int TT=*((WORD*)(P+0x4)); - if(TT==0) - return 0; -// char D[100]; -/// wsprintf(D,"tt:%x",TT); -// printI(D); - const char*Name=noxThingNameByType(TT); -// wsprintf(D,"tname:%s",Name); -// printI(D); -// return 0; - BYTE *UnitDef=(BYTE*)noxUnitDefByName(Name); - int DataSize=*((int*)(UnitDef+0xC4)); - void *Data=noxAlloc(DataSize); - memcpy(Data,*((void**)(P+0x2EC)),DataSize); - lua_pushlightuserdata(L,Data); - return 1; - } - int unitDecayL(lua_State*L) - { /// - if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) || - (lua_type(L,2)!=LUA_TNUMBER) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - unitSetDecayTime(lua_touserdata(L,1),lua_tointeger(L,2)); - return 0; - } - int unitMoveL(lua_State*L) - { /// - if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) || - (lua_type(L,2)!=LUA_TNUMBER) || - (lua_type(L,3)!=LUA_TNUMBER) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - noxPoint Pt(lua_tonumber(L,2),lua_tonumber(L,3)); - unitMove((bigUnitStruct*)lua_touserdata(L,1),&Pt); - return 0; - } - - int unitFreezL(lua_State*L) - { - if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - noxFrozen((bigUnitStruct*)lua_touserdata(L,1),1); - return 1; - } - - int unitAgressionLevel(lua_State*L) - { - if (lua_type(L,1)!=LUA_TLIGHTUSERDATA || lua_type(L,2)!=LUA_TNUMBER) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - float lev=lua_tonumber(L,2); - if (lev<0 || lev>1) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - noxAgressionLevel((bigUnitStruct*)lua_touserdata(L,1),&lev); - return 0; - } - - int unitUnFreezL(lua_State*L) - { - if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - noxUnFrozen((bigUnitStruct*)lua_touserdata(L,1),1); - return 1; - } - int unitDropAll(lua_State*L) - { - if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - dropAllItems((bigUnitStruct*)lua_touserdata(L,1)); - return 1; - } - int unitInventoryPut(lua_State*L) - { - if ( - (lua_type(L,1)!=LUA_TLIGHTUSERDATA)|| - (lua_type(L,2)!=LUA_TLIGHTUSERDATA) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - inventoryPut((bigUnitStruct*)lua_touserdata(L,1),(bigUnitStruct*)lua_touserdata(L,2),1); - return 0; - } - int unitSpeedL(lua_State*L) - { - if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - bigUnitStruct *P=(bigUnitStruct*)lua_touserdata(L,1); - lua_pushnumber(L,P->velX); - lua_pushnumber(L,P->velY); - if (lua_gettop(L)<5) - { - return 2; - } - if( (lua_type(L,2)!=LUA_TNUMBER) || - (lua_type(L,3)!=LUA_TNUMBER) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - if((lua_gettop(L)>5)&& lua_toboolean(L,4)) - { - float a=lua_tonumber(L,3),v=lua_tonumber(L,2); - P->velX=v*a; - P->velY=-v*a; - } - else - { - P->velX=lua_tonumber(L,2); - P->velY=lua_tonumber(L,3); - } - unitActivate(P); - return 2; - } - - int unitTestBuff(lua_State*L) - { - if ((lua_type(L,1)!=LUA_TLIGHTUSERDATA)|| - (lua_type(L,2)!=LUA_TNUMBER)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - if (noxUnitTestBuff((bigUnitStruct*)lua_touserdata(L,1),lua_tonumber(L,2))==1) - lua_pushboolean(L,true); - else - lua_pushboolean(L,false); - return 1; - } -} -float (__cdecl *getFloatByName)(const char *Name); -void unitInit() -{ - ASSIGN(getFloatByName,0x00419D40); - ASSIGN(unitCreatedList,0x00750710); - ASSIGN(unitSetFollow,0x5158C0); - ASSIGN(unitBecomePet,0x4E7B00); - ASSIGN(noxUnknown535250,0x535250); - ASSIGN(unitSetDecayTime,0x00511660); - ASSIGN(noxUnitDefByName,0x004E3830); - ASSIGN(noxCreateAt,0x004DAA50); - ASSIGN(unitMove,0x004E7010); - ASSIGN(unitActivate,0x00537610); - ASSIGN(noxFrozen,0x004E79C0); - ASSIGN(noxUnFrozen,0x004E7A60); - ASSIGN(inventoryPut,0x004F3070); - ASSIGN(dropAllItems,0x004EDA40); - ASSIGN(noxUnitHunt,0x5449D0); - ASSIGN(noxAgressionLevel,0x00515980); - ASSIGN(noxMirrorShot,0x004E0A70); - ASSIGN(noxUnitTestBuff,0x004FF350); - - registerserver("unitSetFollow",&unitSetFollowL); - registerserver("unitBecomePet",&unitBecomePetL); - registerserver("unitDecay",&unitDecayL); - registerserver("unitDelete",&deleteUnitL); - registerserver("unitCopyUc",&unitCopyUcL); - registerserver("createObject",&createObjectL); - registerserver("unitPos",&getUnitCoordL); - registerserver("unitFreeze",&unitFreezL); - registerserver("unitUnFreeze",&unitUnFreezL); - registerserver("unitPick",&unitPickL); - registerserver("unitHunt",&unitHuntL); - registerserver("unitSetAgression",&unitAgressionLevel); - registerserver("unitTestBuff",&unitTestBuff); - - registerserver("unitMove",&unitMoveL); - registerserver("unitSpeed",&unitSpeedL); - registerserver("unitDropAll",&unitDropAll); - registerserver("unitInventoryPut",&unitInventoryPut); - registerserver("createObjectIn",&createObjectIn); +#include "stdafx.h" +#include "unit.h" +#include +#include "player.h" + +void (__cdecl *unitSetFollow)(bigUnitStruct* Me,void *Him); +void (__cdecl *unitBecomePet)(bigUnitStruct* Me,void *Him); +void (__cdecl *noxFrozen) (bigUnitStruct* Unit,int Num); +void (__cdecl *noxUnFrozen) (bigUnitStruct* Unit,int Num); +void (__cdecl *unitMove)(bigUnitStruct *Who,noxPoint *Pt); +void (__cdecl *unitActivate) (bigUnitStruct *Unit); +void (__cdecl *dropAllItems)(bigUnitStruct*Unit); +void (__cdecl *noxUnitHunt) (bigUnitStruct *Unit); +void (__cdecl *noxAgressionLevel) (bigUnitStruct *Unit,float *level); +void (__cdecl *noxMirrorShot) (bigUnitStruct *Shot,void *); +int (__cdecl *noxUnitTestBuff) (bigUnitStruct *Unit,int buffN); + +void (__cdecl *inventoryPut)(bigUnitStruct *Who,bigUnitStruct *What,int A); + +/// список созданных в текущем кадре на сервере +bigUnitStruct **unitCreatedList; + +extern const char *(__cdecl *noxThingNameByType)(int Type); +extern int (__cdecl *noxGetUnitsInRect)(FloatRect *Rect, void (__cdecl *SomeFn)(void *Unit, void *Arg), void *Arg); + +struct UnitAndEye_s +{ + float unitX,unitY; + float unitViewX,unitViewY; +}; + +int (__cdecl *noxUnknown535250)(UnitAndEye_s *Ptr,int Unk1,int Unk2,int Unk3);//bool +void (__cdecl *unitSetDecayTime)(void *Unit,int Time);//bool +void (__cdecl *noxDeleteUnit)(void *Unit); + +void* (__cdecl *noxUnitDefByName)(const char *Name);//Возвращает юнитдеф + +void (__cdecl* noxCreateAt)(unitBigStructPtr Obj,unitBigStructPtr ParentUnit, float X,float Y); + +namespace +{ + + int getUnitCoordL(lua_State *L) + { + if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + bigUnitStruct *Unit=(bigUnitStruct*)lua_touserdata(L,1); + if(Unit==NULL) + return 0; + lua_pushnumber(L,Unit->unitX); + lua_pushnumber(L,Unit->unitY); + return 2; + } + void unitPickImpl(void *Unit, void *L_) + { + void **LL=(void **)L_; + *LL=Unit; + } + int unitPickL(lua_State *L) + { + if ( + (lua_type(L,1)!=LUA_TNUMBER)|| + (lua_type(L,2)!=LUA_TNUMBER)|| + (lua_type(L,3)!=LUA_TNUMBER) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + void *P=0; + float x=lua_tonumber(L,1),y=lua_tonumber(L,2),d=lua_tonumber(L,3); + if (d<=0) + d=1; + noxGetUnitsInRect( + &FloatRect(x-d,y-d,x+d,y+d) + ,&unitPickImpl,&P); + if (P) + lua_pushlightuserdata(L,P); + else + lua_pushnil(L); + return 1; + } + int createObjectL(lua_State *L) + { + if ( + (lua_type(L,1)!=LUA_TSTRING)|| + (lua_type(L,2)!=LUA_TNUMBER)|| + (lua_type(L,3)!=LUA_TNUMBER) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + bigUnitStruct *T= + (bigUnitStruct *)objectCreateByName(lua_tostring(L,1)); + if (!T) + return 0; + noxCreateAt(T,0,lua_tonumber(L,2),lua_tonumber(L,3)); + if (T->Class & clImmobile) + { + BYTE Buf[256],*Out=Buf; + int Size=16; + netUniPacket(upNewStatic,Out,Size); + memcpy(Out,&T->thingType,4);Out+=4; + memcpy(Out,&T->unitX,4);Out+=4; + memcpy(Out,&T->unitY,4);Out+=4; + memcpy(Out,&T->netCode,4);Out+=4; + netSendAll(Buf,Out-Buf); + } + lua_pushlightuserdata(L,T); + return 1; + } + int createObjectIn(lua_State *L) + { + if ( + (lua_type(L,1)!=LUA_TSTRING)|| + (lua_type(L,2)!=LUA_TLIGHTUSERDATA) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + bigUnitStruct *T= + (bigUnitStruct *)objectCreateByName(lua_tostring(L,1)); + if (!T) + return 0; + inventoryPut((bigUnitStruct*)lua_touserdata(L,2),T,1); + lua_pushlightuserdata(L,T); + return 1; + } + int deleteUnitL(lua_State *L) + { + if ((lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + bigUnitStruct *P=(bigUnitStruct*)lua_touserdata(L,1); + if(P!=0) + { + if (P->Class & clImmobile) + { + BYTE Buf[256],*Out=Buf; + int Size=4; + netUniPacket(upDelStatic,Out,Size); + memcpy(Out,&P->netCode,4);Out+=4; + netSendAll(Buf,Out-Buf); + } + noxDeleteObject(P); + } + return 0; + } + int unitSetFollowL(lua_State*L) + { + if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA)||(lua_type(L,2)!=LUA_TLIGHTUSERDATA) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + bigUnitStruct *P1,*P2; + P1=(bigUnitStruct*)lua_touserdata(L,1);P2=(bigUnitStruct*)lua_touserdata(L,2); + if(P1==0 || P2==0) + return 0; + unitSetFollow(P1,P2); + return 0; + } + int unitBecomePetL(lua_State*L) + { + if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA)||(lua_type(L,2)!=LUA_TLIGHTUSERDATA) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + bigUnitStruct *P1,*P2; + P1=(bigUnitStruct*)lua_touserdata(L,1);P2=(bigUnitStruct*)lua_touserdata(L,2); + if(P1==0 || P2==0) + return 0; + unitBecomePet(P2,P1);/// Вызывается наоборот + return 0; + } + + int unitHuntL(lua_State*L) + { + if (lua_type(L,1)!=LUA_TLIGHTUSERDATA ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + noxUnitHunt((bigUnitStruct*)lua_touserdata(L,1)); + return 0; + } + + int unitCopyUcL(lua_State*L) + { + if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + BYTE *P=(BYTE*)lua_touserdata(L,1); + int TT=*((WORD*)(P+0x4)); + if(TT==0) + return 0; +// char D[100]; +/// wsprintf(D,"tt:%x",TT); +// printI(D); + const char*Name=noxThingNameByType(TT); +// wsprintf(D,"tname:%s",Name); +// printI(D); +// return 0; + BYTE *UnitDef=(BYTE*)noxUnitDefByName(Name); + int DataSize=*((int*)(UnitDef+0xC4)); + void *Data=noxAlloc(DataSize); + memcpy(Data,*((void**)(P+0x2EC)),DataSize); + lua_pushlightuserdata(L,Data); + return 1; + } + int unitDecayL(lua_State*L) + { /// добавить в список распада + if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) || + (lua_type(L,2)!=LUA_TNUMBER) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + unitSetDecayTime(lua_touserdata(L,1),lua_tointeger(L,2)); + return 0; + } + int unitMoveL(lua_State*L) + { /// добавить в список распада + if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) || + (lua_type(L,2)!=LUA_TNUMBER) || + (lua_type(L,3)!=LUA_TNUMBER) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + noxPoint Pt(lua_tonumber(L,2),lua_tonumber(L,3)); + unitMove((bigUnitStruct*)lua_touserdata(L,1),&Pt); + return 0; + } + + int unitFreezL(lua_State*L) + { + if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + noxFrozen((bigUnitStruct*)lua_touserdata(L,1),1); + return 1; + } + + int unitAgressionLevel(lua_State*L) + { + if (lua_type(L,1)!=LUA_TLIGHTUSERDATA || lua_type(L,2)!=LUA_TNUMBER) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + float lev=lua_tonumber(L,2); + if (lev<0 || lev>1) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + noxAgressionLevel((bigUnitStruct*)lua_touserdata(L,1),&lev); + return 0; + } + + int unitUnFreezL(lua_State*L) + { + if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + noxUnFrozen((bigUnitStruct*)lua_touserdata(L,1),1); + return 1; + } + int unitDropAll(lua_State*L) + { + if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + dropAllItems((bigUnitStruct*)lua_touserdata(L,1)); + return 1; + } + int unitInventoryPut(lua_State*L) + { + if ( + (lua_type(L,1)!=LUA_TLIGHTUSERDATA)|| + (lua_type(L,2)!=LUA_TLIGHTUSERDATA) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + inventoryPut((bigUnitStruct*)lua_touserdata(L,1),(bigUnitStruct*)lua_touserdata(L,2),1); + return 0; + } + int unitSpeedL(lua_State*L) + { + if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + bigUnitStruct *P=(bigUnitStruct*)lua_touserdata(L,1); + lua_pushnumber(L,P->velX); + lua_pushnumber(L,P->velY); + if (lua_gettop(L)<5) + { + return 2; + } + if( (lua_type(L,2)!=LUA_TNUMBER) || + (lua_type(L,3)!=LUA_TNUMBER) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + if((lua_gettop(L)>5)&& lua_toboolean(L,4)) + { + float a=lua_tonumber(L,3),v=lua_tonumber(L,2); + P->velX=v*a; + P->velY=-v*a; + } + else + { + P->velX=lua_tonumber(L,2); + P->velY=lua_tonumber(L,3); + } + unitActivate(P); + return 2; + } + + int unitTestBuff(lua_State*L) + { + if ((lua_type(L,1)!=LUA_TLIGHTUSERDATA)|| + (lua_type(L,2)!=LUA_TNUMBER)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + if (noxUnitTestBuff((bigUnitStruct*)lua_touserdata(L,1),lua_tonumber(L,2))==1) + lua_pushboolean(L,true); + else + lua_pushboolean(L,false); + return 1; + } +} +float (__cdecl *getFloatByName)(const char *Name); +void unitInit() +{ + ASSIGN(getFloatByName,0x00419D40); + ASSIGN(unitCreatedList,0x00750710); + ASSIGN(unitSetFollow,0x5158C0); + ASSIGN(unitBecomePet,0x4E7B00); + ASSIGN(noxUnknown535250,0x535250); + ASSIGN(unitSetDecayTime,0x00511660); + ASSIGN(noxUnitDefByName,0x004E3830); + ASSIGN(noxCreateAt,0x004DAA50); + ASSIGN(unitMove,0x004E7010); + ASSIGN(unitActivate,0x00537610); + ASSIGN(noxFrozen,0x004E79C0); + ASSIGN(noxUnFrozen,0x004E7A60); + ASSIGN(inventoryPut,0x004F3070); + ASSIGN(dropAllItems,0x004EDA40); + ASSIGN(noxUnitHunt,0x5449D0); + ASSIGN(noxAgressionLevel,0x00515980); + ASSIGN(noxMirrorShot,0x004E0A70); + ASSIGN(noxUnitTestBuff,0x004FF350); + + registerserver("unitSetFollow",&unitSetFollowL); + registerserver("unitBecomePet",&unitBecomePetL); + registerserver("unitDecay",&unitDecayL); + registerserver("unitDelete",&deleteUnitL); + registerserver("unitCopyUc",&unitCopyUcL); + registerserver("createObject",&createObjectL); + registerserver("unitPos",&getUnitCoordL); + registerserver("unitFreeze",&unitFreezL); + registerserver("unitUnFreeze",&unitUnFreezL); + registerserver("unitPick",&unitPickL); + registerserver("unitHunt",&unitHuntL); + registerserver("unitSetAgression",&unitAgressionLevel); + registerserver("unitTestBuff",&unitTestBuff); + + registerserver("unitMove",&unitMoveL); + registerserver("unitSpeed",&unitSpeedL); + registerserver("unitDropAll",&unitDropAll); + registerserver("unitInventoryPut",&unitInventoryPut); + registerserver("createObjectIn",&createObjectIn); } \ No newline at end of file diff --git a/unit.h b/unit.h index 94e44e1..e16eb9a 100644 --- a/unit.h +++ b/unit.h @@ -285,7 +285,7 @@ enum unitFlags }; extern bigUnitStruct *(__cdecl* objectCreateByName)(char const *ObjName); -extern bigUnitStruct *(__cdecl *unitDamageFindParent) (bigUnitStruct *Unit); // +extern bigUnitStruct *(__cdecl *unitDamageFindParent) (bigUnitStruct *Unit); // кто источник урона extern void (__cdecl *noxUnitSetOwner) (bigUnitStruct *NewOwner,bigUnitStruct *Owner); extern void (__cdecl *noxUnitDelete) (bigUnitStruct *Unit); extern void (__cdecl *noxDeleteObject)(bigUnitStruct *Unit); \ No newline at end of file diff --git a/unit2.cpp b/unit2.cpp index 31af535..9cd11bb 100644 --- a/unit2.cpp +++ b/unit2.cpp @@ -1,428 +1,428 @@ -#include "stdafx.h" -#include "unit.h" - -short (__cdecl *unitGetHP)(void *U); -void (__cdecl *unitSetHP)(void *U, int New); -short (__cdecl *unitGetMaxHP)(void *U); -void (__cdecl *unitSetMaxHP)(void *U, int New); -void (__cdecl *modifSetItemAttrs)(void *U,void *Enchs[5]); -int (__cdecl *modifGetIdByName)(const char *Name); -void *(__cdecl *modifGetDescById)(int Id); -int (__cdecl *servInventoryPlace)(void* A, void* B, int report, int unkn); - -extern void *(__cdecl *noxAlloc)(int Size); -extern void *(__cdecl *noxCAlloc)(int NumElements,int Size); - - -//ASSIGN(,0x); - -namespace -{ - struct EnchantDesc - { - char *namePtr; - int attrId; - void *commentText; - void *commentText2; - void *attribText; - int worth; - int color; - int allowedWeapon; - int allowedArmor; - int allowedPosition; - void *attackEffectFn; - int attackEffectParamFloat; - int attackEffectParamDword; - void *attackPrehitEffectFn; - float attackPrehitEffectParamFloat; - int attackPrehitEffectParamDword; - int attackPredamageEffectFn; - float attackPredamageEffectParamFloat; - int attackPredamageEffectParamDword; - int defendEffectFn; - int defendEffectParamFloat; - int defendEffectParamDword; - void *unknownHandlerPtr; - float defendCollideEffectParamFloat; - int defendCollideEffectParamDword; - void *updateEffectFn; - float updateEffectParamFloat; - int updateEffectParamDword; - void *engageFn; - void *disengageFn; - int engageEffectParamFloat; - int engageEffectParamDword; - float disengageEffectParamFloat; - int disengageEffectParamDword; - EnchantDesc *nextModif; - EnchantDesc *prevModif; - }; - EnchantDesc **modifLists; - - int *modifCount; - - ParseAttrib enchOffs[]= - { - {"name",0x00,2}, - {"tooltip",0x08,4}, - {"text",0x0C,4}, - {"identifyText",0x10,4}, - {"color",0x18,3}, - //{"effectPrehitLvl", - {0,0,0} - }; - int itemMakeEnchant(lua_State*L); - - void __cdecl engageFn(EnchantDesc *Me, bigUnitStruct *Owner, bigUnitStruct *Item) - { - int Top=lua_gettop(L); - lua_pushlightuserdata(L,&itemMakeEnchant); - lua_gettable(L,LUA_REGISTRYINDEX); - do - { - lua_pushlightuserdata(L,Me); - lua_gettable(L,-2); - if (!lua_istable(L,-1)) - break; - lua_getfield(L,-1,"effectEngage"); - if (!lua_isfunction(L,-1)) - break; - lua_pushvalue(L, -2); - lua_pushlightuserdata(L, Owner); - lua_pushlightuserdata(L, Item); - if (0 != lua_pcall(L, 3, 0, 0)) - { - const char *S=lua_tostring(L,-1); - break; - } - }while(0); - lua_settop(L,Top); - } - - void __cdecl disengageFn(EnchantDesc *Me, bigUnitStruct *Owner, bigUnitStruct *Item) - { - int Top=lua_gettop(L); - lua_pushlightuserdata(L,&itemMakeEnchant); - lua_gettable(L,LUA_REGISTRYINDEX); - do - { - lua_pushlightuserdata(L,Me); - lua_gettable(L,-2); - if (!lua_istable(L,-1)) - break; - lua_getfield(L,-1,"effectDisengage"); - if (!lua_isfunction(L,-1)) - break; - lua_pushvalue(L,-2); - lua_pushlightuserdata(L, Owner); - lua_pushlightuserdata(L, Item); - if (0 != lua_pcall(L, 3, 0, 0)) - { - const char *S=lua_tostring(L,-1); - break; - } - }while(0); - lua_settop(L,Top); - } - - // , . - // : , , , - void __cdecl attackPrehitFn(EnchantDesc *Me, bigUnitStruct *Weapon, bigUnitStruct *Owner, bigUnitStruct *Target, float *Damage) - { - int Top=lua_gettop(L); - lua_pushlightuserdata(L,&itemMakeEnchant); - lua_gettable(L,LUA_REGISTRYINDEX); - do - { - lua_pushlightuserdata(L,Me); - lua_gettable(L,-2); - if (!lua_istable(L,-1)) - break; - lua_getfield(L,-1,"effectPrehit"); - if (!lua_isfunction(L,-1)) - break; - lua_pushvalue(L,-2); - lua_pushlightuserdata(L,Weapon); - lua_pushlightuserdata(L,Owner); - lua_pushlightuserdata(L,Target); - if (0!=lua_pcall(L,4,0,0)) - { - break; - } - } while(0); - lua_settop(L,Top); - } - - // , . - // : , , , - // , - void __cdecl attackManualFn(EnchantDesc *Me, bigUnitStruct *Weapon, bigUnitStruct *Owner, void *Zero, float *Damage) - { - int Top=lua_gettop(L); - lua_pushlightuserdata(L, &itemMakeEnchant); - lua_gettable(L, LUA_REGISTRYINDEX); - do - { - lua_pushlightuserdata(L, Me); - lua_gettable(L, -2); - if (!lua_istable(L, -1)) - break; - lua_getfield(L, -1, "effectAttack"); - if (!lua_isfunction(L, -1)) - break; - lua_pushvalue(L, -2); - lua_pushlightuserdata(L, Weapon); - lua_pushlightuserdata(L, Owner); - lua_pushnumber(L, *Damage); - if (lua_pcall(L, 4, 1, 0) == 0) - { - if (!lua_isnil(L, -1)) - { - *Damage = (float) lua_tonumber(L, -1); - } - } - } while(0); - lua_settop(L,Top); - } - - // , /. - // : , , - void __cdecl updateArmorFn(EnchantDesc *Me, bigUnitStruct *Armor, int zero) - { - int Top=lua_gettop(L); - lua_pushlightuserdata(L, &itemMakeEnchant); - lua_gettable(L, LUA_REGISTRYINDEX); - do - { - lua_pushlightuserdata(L, Me); - lua_gettable(L, -2); - if (!lua_istable(L, -1)) - break; - lua_getfield(L, -1, "effectUpdate"); - if (!lua_isfunction(L, -1)) - break; - lua_pushvalue(L, -2); - lua_pushlightuserdata(L, Armor); - lua_pushlightuserdata(L, Armor->prevInventoryObj); - if (lua_pcall(L, 3, 0, 0) != 0) - { - break; - } - } while(0); - lua_settop(L,Top); - } - - // . - - int itemMakeEnchant(lua_State*L) - { - if ( - (lua_type(L,1)!=LUA_TTABLE) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - lua_settop(L,1); - lua_pushnil(L); - EnchantDesc *Ench=(EnchantDesc *)noxCAlloc(1,0x90); - while (lua_next(L,1)!=0) - { - lua_pushvalue(L,-2); - lua_pushvalue(L,-2); - parseAttr(L,4,5,Ench,enchOffs); - lua_settop(L,2); - } - lua_getfield(L,1,"effectEngage"); - if (lua_isfunction(L,-1)) - { - Ench->engageFn=&engageFn; - } - lua_getfield(L,1,"effectDisengage"); - if (lua_isfunction(L,-1)) - { - Ench->disengageFn=&disengageFn; - } - lua_getfield(L,1,"effectPrehit"); - if (lua_isfunction(L,-1)) - { - Ench->attackPrehitEffectFn=&attackPrehitFn; - } - lua_getfield(L,1,"effectAttack"); - if (lua_isfunction(L,-1)) - { - Ench->attackEffectFn=&attackManualFn; - } - lua_getfield(L,1,"effectUpdate"); - if (lua_isfunction(L,-1)) - { - Ench->updateEffectFn=&updateArmorFn; - } - lua_settop(L,2); - - Ench->attrId=(*modifCount)++; - EnchantDesc *&Next=modifLists[0]; - - Ench->prevModif=NULL; - Ench->nextModif=Next; - if (Next) - Next->prevModif=Ench; - Next=Ench; - - lua_pushlightuserdata(L,&itemMakeEnchant); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,Ench); - lua_pushvalue(L,1); - lua_settable(L,-3); - lua_settop(L,1); - return 1; - } - int itemEnchants(lua_State*L) - { - if ( - (lua_type(L,1)!=LUA_TLIGHTUSERDATA) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - bigUnitStruct *B=(bigUnitStruct*)lua_touserdata(L,1); - if (B==NULL || (0==B->Class & (clWeapon|clArmor|clWand) ) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - lua_settop(L,1+4); - EnchantDesc **Src=(EnchantDesc**)B->unkFn2B0DataPtr; - lua_createtable(L,5,0); - if (Src!=NULL) - { - for (int i=1;i<=4;Src++,i++) - { - if (NULL == *Src || *Src==((void *)0xFFFFFFFFLL) || (*Src)->namePtr==NULL) - lua_pushstring(L,""); - else - lua_pushstring(L,(*Src)->namePtr); - lua_rawseti(L,-2,i); - } - } - void *Enchants[5]={0,0,0,0,0}; - bool Set=false; - for (int i=2;i<=5;i++) - { - if (!lua_isnil(L,i)) - { - Set=true; - size_t Len; - const char *S=lua_tolstring(L,i,&Len); - Enchants[i-2]=NULL; - if (S!=NULL && Len>0) - { - int Id=modifGetIdByName(S); - if (Id) - Enchants[i-2]=modifGetDescById(Id); - } - } - } - if (Set) - modifSetItemAttrs(B,&Enchants[0]); - return 1; - } - - // - int unitHP(lua_State*L) - { - if ( - (lua_type(L,1)!=LUA_TLIGHTUSERDATA) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - void *P=lua_touserdata(L,1); - if (P==NULL) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - lua_pushinteger(L,(short) unitGetHP(P)); - if (!lua_isnil(L,2)) - { - int New = (int) lua_tonumber(L,2); - unitSetHP(P,New<1?1:New); - } - return 1; - } - - // . : 1, 2, 3, , - int unitDamageL(lua_State *L) - { - if ((lua_type(L, 1) != LUA_TLIGHTUSERDATA)) - { - lua_pushstring(L, "wrong args: arg1 != userdata"); - lua_error_(L); - } - bigUnitStruct *victim = (bigUnitStruct *) lua_touserdata(L, 1); - if (victim == NULL) - { - lua_pushstring(L, "wrong args: arg1 is nil"); - lua_error_(L); - } - void *attacker = NULL; - if (!lua_isnil(L, 2)) { attacker = lua_touserdata(L, 2); } - void *dealtBy = NULL; - if (!lua_isnil(L, 3)) { dealtBy = lua_touserdata(L, 3); } - if (!lua_isnil(L, 4) && !lua_isnil(L, 5)) - { - int damage = (int) lua_tonumber(L, 4); - int dmgType = (int) lua_tonumber(L, 5); - victim->damageFnPtr(victim, attacker, dealtBy, damage, dmgType); - } - return 0; - } - - // unitInventoryPut - // userdata, integer - int unitPlaceInvL(lua_State *L) - { - if ((lua_type(L, 1) != LUA_TLIGHTUSERDATA)) - { - lua_pushstring(L, "wrong args: arg1 is not userdata"); - lua_error_(L); - } - void* whotake = lua_touserdata(L, 1); - if ((lua_type(L, 2) != LUA_TLIGHTUSERDATA)) - { - lua_pushstring(L, "wrong args: arg2 is not userdata"); - lua_error_(L); - } - void *toplace = lua_touserdata(L, 2); - - int result = servInventoryPlace(whotake, toplace, 1, 1); - lua_pushinteger(L, result); - return 1; - } -} - -void unit2Init() -{ - ASSIGN(unitGetHP,0x004EE780); - ASSIGN(unitSetHP,0x004E4560); - ASSIGN(unitGetMaxHP, 0x4EE7A0); - ASSIGN(unitSetMaxHP, 0x4EE7C0); - ASSIGN(modifSetItemAttrs,0x004E4990); - ASSIGN(modifGetDescById,0x00413330); - ASSIGN(modifGetIdByName,0x00413290); - ASSIGN(servInventoryPlace, 0x4F36F0); - ASSIGN(modifLists,0x00611C54); - ASSIGN(modifCount,0x00611C60); - - registerserver("unitHP",&unitHP); - registerserver("itemEnchants",&itemEnchants); - registerserver("itemMakeEnchant",&itemMakeEnchant); - registerserver("unitDamage",&unitDamageL); - registerserver("unitInventoryPlace",&unitPlaceInvL); - - lua_pushlightuserdata(L,&itemMakeEnchant); - lua_newtable(L); - lua_settable(L,LUA_REGISTRYINDEX); +#include "stdafx.h" +#include "unit.h" + +short (__cdecl *unitGetHP)(void *U); +void (__cdecl *unitSetHP)(void *U, int New); +short (__cdecl *unitGetMaxHP)(void *U); +void (__cdecl *unitSetMaxHP)(void *U, int New); +void (__cdecl *modifSetItemAttrs)(void *U,void *Enchs[5]); +int (__cdecl *modifGetIdByName)(const char *Name); +void *(__cdecl *modifGetDescById)(int Id); +int (__cdecl *servInventoryPlace)(void* A, void* B, int report, int unkn); + +extern void *(__cdecl *noxAlloc)(int Size); +extern void *(__cdecl *noxCAlloc)(int NumElements,int Size); + + +//ASSIGN(,0x); + +namespace +{ + struct EnchantDesc + { + char *namePtr; + int attrId; + void *commentText; + void *commentText2; + void *attribText; + int worth; + int color; + int allowedWeapon; + int allowedArmor; + int allowedPosition; + void *attackEffectFn; + int attackEffectParamFloat; + int attackEffectParamDword; + void *attackPrehitEffectFn; + float attackPrehitEffectParamFloat; + int attackPrehitEffectParamDword; + int attackPredamageEffectFn; + float attackPredamageEffectParamFloat; + int attackPredamageEffectParamDword; + int defendEffectFn; + int defendEffectParamFloat; + int defendEffectParamDword; + void *unknownHandlerPtr; + float defendCollideEffectParamFloat; + int defendCollideEffectParamDword; + void *updateEffectFn; + float updateEffectParamFloat; + int updateEffectParamDword; + void *engageFn; + void *disengageFn; + int engageEffectParamFloat; + int engageEffectParamDword; + float disengageEffectParamFloat; + int disengageEffectParamDword; + EnchantDesc *nextModif; + EnchantDesc *prevModif; + }; + EnchantDesc **modifLists; + + int *modifCount; + + ParseAttrib enchOffs[]= + { + {"name",0x00,2}, + {"tooltip",0x08,4}, + {"text",0x0C,4}, + {"identifyText",0x10,4}, + {"color",0x18,3}, + //{"effectPrehitLvl", + {0,0,0} + }; + int itemMakeEnchant(lua_State*L); + + void __cdecl engageFn(EnchantDesc *Me, bigUnitStruct *Owner, bigUnitStruct *Item) + { + int Top=lua_gettop(L); + lua_pushlightuserdata(L,&itemMakeEnchant); + lua_gettable(L,LUA_REGISTRYINDEX); + do + { + lua_pushlightuserdata(L,Me); + lua_gettable(L,-2); + if (!lua_istable(L,-1)) + break; + lua_getfield(L,-1,"effectEngage"); + if (!lua_isfunction(L,-1)) + break; + lua_pushvalue(L, -2); + lua_pushlightuserdata(L, Owner); + lua_pushlightuserdata(L, Item); + if (0 != lua_pcall(L, 3, 0, 0)) + { + const char *S=lua_tostring(L,-1); + break; + } + }while(0); + lua_settop(L,Top); + } + + void __cdecl disengageFn(EnchantDesc *Me, bigUnitStruct *Owner, bigUnitStruct *Item) + { + int Top=lua_gettop(L); + lua_pushlightuserdata(L,&itemMakeEnchant); + lua_gettable(L,LUA_REGISTRYINDEX); + do + { + lua_pushlightuserdata(L,Me); + lua_gettable(L,-2); + if (!lua_istable(L,-1)) + break; + lua_getfield(L,-1,"effectDisengage"); + if (!lua_isfunction(L,-1)) + break; + lua_pushvalue(L,-2); + lua_pushlightuserdata(L, Owner); + lua_pushlightuserdata(L, Item); + if (0 != lua_pcall(L, 3, 0, 0)) + { + const char *S=lua_tostring(L,-1); + break; + } + }while(0); + lua_settop(L,Top); + } + + // Функция, вызываемая каждый раз при ПОПАДАНИИ атаки зачарованным оружием. + // Вызывает луа обработчик с аргументами: указатель на чар, указатель на оружие, указатель на владельца, указатель на цель + void __cdecl attackPrehitFn(EnchantDesc *Me, bigUnitStruct *Weapon, bigUnitStruct *Owner, bigUnitStruct *Target, float *Damage) + { + int Top=lua_gettop(L); + lua_pushlightuserdata(L,&itemMakeEnchant); + lua_gettable(L,LUA_REGISTRYINDEX); + do + { + lua_pushlightuserdata(L,Me); + lua_gettable(L,-2); + if (!lua_istable(L,-1)) + break; + lua_getfield(L,-1,"effectPrehit"); + if (!lua_isfunction(L,-1)) + break; + lua_pushvalue(L,-2); + lua_pushlightuserdata(L,Weapon); + lua_pushlightuserdata(L,Owner); + lua_pushlightuserdata(L,Target); + if (0!=lua_pcall(L,4,0,0)) + { + break; + } + } while(0); + lua_settop(L,Top); + } + + // Функция, вызываемая каждый раз при НАЧАЛЕ атаки зачарованным оружием. + // Вызывает луа обработчик с аргументами: указатель на чар, указатель на оружие, указатель на владельца, урон + // Если имеется выходное значение, устанавливает его как множитель урона + void __cdecl attackManualFn(EnchantDesc *Me, bigUnitStruct *Weapon, bigUnitStruct *Owner, void *Zero, float *Damage) + { + int Top=lua_gettop(L); + lua_pushlightuserdata(L, &itemMakeEnchant); + lua_gettable(L, LUA_REGISTRYINDEX); + do + { + lua_pushlightuserdata(L, Me); + lua_gettable(L, -2); + if (!lua_istable(L, -1)) + break; + lua_getfield(L, -1, "effectAttack"); + if (!lua_isfunction(L, -1)) + break; + lua_pushvalue(L, -2); + lua_pushlightuserdata(L, Weapon); + lua_pushlightuserdata(L, Owner); + lua_pushnumber(L, *Damage); + if (lua_pcall(L, 4, 1, 0) == 0) + { + if (!lua_isnil(L, -1)) + { + *Damage = (float) lua_tonumber(L, -1); + } + } + } while(0); + lua_settop(L,Top); + } + + // Функция, вызываемая каждый тик для брони в инвентаре у монстра/игрока. + // Вызывает луа обработчик с аргументами: указатель на чар, указатель на броню, указатель на владельца + void __cdecl updateArmorFn(EnchantDesc *Me, bigUnitStruct *Armor, int zero) + { + int Top=lua_gettop(L); + lua_pushlightuserdata(L, &itemMakeEnchant); + lua_gettable(L, LUA_REGISTRYINDEX); + do + { + lua_pushlightuserdata(L, Me); + lua_gettable(L, -2); + if (!lua_istable(L, -1)) + break; + lua_getfield(L, -1, "effectUpdate"); + if (!lua_isfunction(L, -1)) + break; + lua_pushvalue(L, -2); + lua_pushlightuserdata(L, Armor); + lua_pushlightuserdata(L, Armor->prevInventoryObj); + if (lua_pcall(L, 3, 0, 0) != 0) + { + break; + } + } while(0); + lua_settop(L,Top); + } + + // Создает пользовательский энчант. Аргумент - таблица + int itemMakeEnchant(lua_State*L) + { + if ( + (lua_type(L,1)!=LUA_TTABLE) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + lua_settop(L,1); + lua_pushnil(L); + EnchantDesc *Ench=(EnchantDesc *)noxCAlloc(1,0x90); + while (lua_next(L,1)!=0) + { + lua_pushvalue(L,-2); + lua_pushvalue(L,-2); + parseAttr(L,4,5,Ench,enchOffs); + lua_settop(L,2); + } + lua_getfield(L,1,"effectEngage"); + if (lua_isfunction(L,-1)) + { + Ench->engageFn=&engageFn; + } + lua_getfield(L,1,"effectDisengage"); + if (lua_isfunction(L,-1)) + { + Ench->disengageFn=&disengageFn; + } + lua_getfield(L,1,"effectPrehit"); + if (lua_isfunction(L,-1)) + { + Ench->attackPrehitEffectFn=&attackPrehitFn; + } + lua_getfield(L,1,"effectAttack"); + if (lua_isfunction(L,-1)) + { + Ench->attackEffectFn=&attackManualFn; + } + lua_getfield(L,1,"effectUpdate"); + if (lua_isfunction(L,-1)) + { + Ench->updateEffectFn=&updateArmorFn; + } + lua_settop(L,2); + + Ench->attrId=(*modifCount)++; + EnchantDesc *&Next=modifLists[0]; + + Ench->prevModif=NULL; + Ench->nextModif=Next; + if (Next) + Next->prevModif=Ench; + Next=Ench; + + lua_pushlightuserdata(L,&itemMakeEnchant); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,Ench); + lua_pushvalue(L,1); + lua_settable(L,-3); + lua_settop(L,1); + return 1; + } + int itemEnchants(lua_State*L) + { + if ( + (lua_type(L,1)!=LUA_TLIGHTUSERDATA) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + bigUnitStruct *B=(bigUnitStruct*)lua_touserdata(L,1); + if (B==NULL || (0==B->Class & (clWeapon|clArmor|clWand) ) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + lua_settop(L,1+4); + EnchantDesc **Src=(EnchantDesc**)B->unkFn2B0DataPtr; + lua_createtable(L,5,0); + if (Src!=NULL) + { + for (int i=1;i<=4;Src++,i++) + { + if (NULL == *Src || *Src==((void *)0xFFFFFFFFLL) || (*Src)->namePtr==NULL) + lua_pushstring(L,""); + else + lua_pushstring(L,(*Src)->namePtr); + lua_rawseti(L,-2,i); + } + } + void *Enchants[5]={0,0,0,0,0}; + bool Set=false; + for (int i=2;i<=5;i++) + { + if (!lua_isnil(L,i)) + { + Set=true; + size_t Len; + const char *S=lua_tolstring(L,i,&Len); + Enchants[i-2]=NULL; + if (S!=NULL && Len>0) + { + int Id=modifGetIdByName(S); + if (Id) + Enchants[i-2]=modifGetDescById(Id); + } + } + } + if (Set) + modifSetItemAttrs(B,&Enchants[0]); + return 1; + } + + // возвращает или устанавливает здоровье + int unitHP(lua_State*L) + { + if ( + (lua_type(L,1)!=LUA_TLIGHTUSERDATA) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + void *P=lua_touserdata(L,1); + if (P==NULL) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + lua_pushinteger(L,(short) unitGetHP(P)); + if (!lua_isnil(L,2)) + { + int New = (int) lua_tonumber(L,2); + unitSetHP(P,New<1?1:New); + } + return 1; + } + + // наносит урон обьекту. аргументы: ю1, ю2, ю3, урон, тип урона + int unitDamageL(lua_State *L) + { + if ((lua_type(L, 1) != LUA_TLIGHTUSERDATA)) + { + lua_pushstring(L, "wrong args: arg1 != userdata"); + lua_error_(L); + } + bigUnitStruct *victim = (bigUnitStruct *) lua_touserdata(L, 1); + if (victim == NULL) + { + lua_pushstring(L, "wrong args: arg1 is nil"); + lua_error_(L); + } + void *attacker = NULL; + if (!lua_isnil(L, 2)) { attacker = lua_touserdata(L, 2); } + void *dealtBy = NULL; + if (!lua_isnil(L, 3)) { dealtBy = lua_touserdata(L, 3); } + if (!lua_isnil(L, 4) && !lua_isnil(L, 5)) + { + int damage = (int) lua_tonumber(L, 4); + int dmgType = (int) lua_tonumber(L, 5); + victim->damageFnPtr(victim, attacker, dealtBy, damage, dmgType); + } + return 0; + } + + // исправленная версия unitInventoryPut + // принимает два аргумента userdata, возвращает integer результат + int unitPlaceInvL(lua_State *L) + { + if ((lua_type(L, 1) != LUA_TLIGHTUSERDATA)) + { + lua_pushstring(L, "wrong args: arg1 is not userdata"); + lua_error_(L); + } + void* whotake = lua_touserdata(L, 1); + if ((lua_type(L, 2) != LUA_TLIGHTUSERDATA)) + { + lua_pushstring(L, "wrong args: arg2 is not userdata"); + lua_error_(L); + } + void *toplace = lua_touserdata(L, 2); + + int result = servInventoryPlace(whotake, toplace, 1, 1); + lua_pushinteger(L, result); + return 1; + } +} + +void unit2Init() +{ + ASSIGN(unitGetHP,0x004EE780); + ASSIGN(unitSetHP,0x004E4560); + ASSIGN(unitGetMaxHP, 0x4EE7A0); + ASSIGN(unitSetMaxHP, 0x4EE7C0); + ASSIGN(modifSetItemAttrs,0x004E4990); + ASSIGN(modifGetDescById,0x00413330); + ASSIGN(modifGetIdByName,0x00413290); + ASSIGN(servInventoryPlace, 0x4F36F0); + ASSIGN(modifLists,0x00611C54); + ASSIGN(modifCount,0x00611C60); + + registerserver("unitHP",&unitHP); + registerserver("itemEnchants",&itemEnchants); + registerserver("itemMakeEnchant",&itemMakeEnchant); + registerserver("unitDamage",&unitDamageL); + registerserver("unitInventoryPlace",&unitPlaceInvL); + + lua_pushlightuserdata(L,&itemMakeEnchant); + lua_newtable(L); + lua_settable(L,LUA_REGISTRYINDEX); } \ No newline at end of file diff --git a/unitExternFunction.cpp b/unitExternFunction.cpp index 54c35f8..fca7db0 100644 --- a/unitExternFunction.cpp +++ b/unitExternFunction.cpp @@ -2,7 +2,7 @@ #include "unit.h" bigUnitStruct* (__cdecl* objectCreateByName)(char const *ObjName); -bigUnitStruct *(__cdecl *unitDamageFindParent) (bigUnitStruct *Unit); // +bigUnitStruct *(__cdecl *unitDamageFindParent) (bigUnitStruct *Unit); // кто источник урона void (__cdecl *noxUnitSetOwner) (bigUnitStruct *NewOwner,bigUnitStruct *Owner); void (__cdecl *noxUnitDelete) (bigUnitStruct *Unit); void (__cdecl *noxDeleteObject)(bigUnitStruct *Unit); diff --git a/util.cpp b/util.cpp index 3b3f3d1..aa31ba3 100644 --- a/util.cpp +++ b/util.cpp @@ -1,1425 +1,1425 @@ -#include "stdafx.h" -#include -#include -#include -#include -/* -: -+) -) -+.) -+) / ( ) - -E -+1) -+2) -) -+3) , -4) / -+5) - --) , , --) ) -+) , 300 1 ... - -*/ - -#define AddCodeLine(a,b) conPrintI(a) - -typedef unsigned int u_int; -void *(__cdecl *noxCAlloc)(int NumElements,int Size); -void *(__cdecl *noxAlloc)(int Size); -void (__cdecl *noxFree)(void *Ptr); - -int (__cdecl *consolePrint)(int Color, wchar_t *Text); -extern bool serverUpdate(); -extern char authSendWelcomeMsg[0x20]; -extern void netSendChatMessage(char *sendChat, int sendTo, short sendFrom=0, bool fakeSystemMessage=false); -extern byte authorisedState[0x20]; -extern bool specialAuthorisation; // - -u_int hostIdx = 0x1F; - -extern void replayEachFrame(); - -char* gameDirectory; - -int (__cdecl *initWindowedModeNox)(int param1, int param2, int param3); - -float* frameLimiterSetting; - -int (__cdecl *j_time)(); - -void(__cdecl *consoleTokenCipher)(wchar_t* source, wchar_t* dest); - -using namespace std; - -wchar_t* tokenParseFixup(wchar_t* Dest, wchar_t* Source) -{ - return wcsncpy(Dest, Source, 31); -} - -void tokenParseCipherFixup(wchar_t* Source, wchar_t* Dest) -{ - wchar_t adjustedToken[32]; - adjustedToken[31] = L'\0'; - tokenParseFixup(adjustedToken, Source); - consoleTokenCipher(adjustedToken, Dest); -} - -int frameLimiter(lua_State* L) -{ - byte* bt = (byte*)(0x0043E2F3+1); - byte* bt2 = (byte*)(0x004AB609+1); - if(lua_type(L,1)==LUA_TNUMBER) - { - float limiterFPS = (float)lua_tonumber(L,1); - *frameLimiterSetting = 1000 / limiterFPS; - // Begin of Black Shaman - float* frameLimiterSetting2 = (float*)0x00594498; - *frameLimiterSetting2 = *frameLimiterSetting/1000; - int *frameCounterTest=(int*)0x0062F1D0; - int *frameCounterTest2=(int*)0x0084EA04; - int *frameCounterTest3=(int*)0x0062F1C8; - *frameCounterTest = *frameCounterTest2; - *frameCounterTest3 = j_time(); - - DWORD OldProtect; - VirtualProtect(bt,1,PAGE_EXECUTE_READWRITE,&OldProtect); - *bt=(byte)limiterFPS; - VirtualProtect(bt,1,OldProtect,&OldProtect); - - VirtualProtect(bt2,1,PAGE_EXECUTE_READWRITE,&OldProtect); - *bt2=(byte)limiterFPS; - VirtualProtect(bt2,1,OldProtect,&OldProtect); - - // End of Black Shaman - } - lua_pushnumber(L, *bt); - return 1; -} - -string getGameDirectory() -{ - u_int size = GetFullPathName(gameDirectory, 0, NULL, NULL); - char* buf = new char[size]; - GetFullPathName(gameDirectory, size, buf, NULL); - string result = buf; - return result; -} - -int getGameDirectoryL(lua_State *L) -{ - lua_pushstring(L, getGameDirectory().c_str()); - return 1; -} - -string getNormalizedPath(const char* path) -{ - u_int size = GetFullPathName(path, 0, NULL, NULL); - char* buf = new char[size]; - SetCurrentDirectory(getGameDirectory().c_str()); - GetFullPathName(path, size, buf, NULL); - string result = buf; - delete [] buf; - return result; -} - -int getNormalizedPathL(lua_State *L) -{ - if (lua_type(L,1)==LUA_TSTRING) - { - lua_pushstring(L, getNormalizedPath(lua_tostring(L, 1)).c_str()); - return 1; - } - else - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } -} - -bool isDirectory(string dirName) -{ - DWORD attribs = GetFileAttributes(dirName.c_str()); - if (attribs == INVALID_FILE_ATTRIBUTES) - { - return false; - } - return (attribs & FILE_ATTRIBUTE_DIRECTORY); -} - -map getDirectoryListing(const char* path) -{ - //string directoryPath = getNormalizedPath(path); - string directoryPath = path; - map results; - if(isDirectory(directoryPath)) - { - string directoryPathSearch = directoryPath; - WIN32_FIND_DATA ffd; - HANDLE hFind = INVALID_HANDLE_VALUE; - directoryPathSearch.append("\\*"); - directoryPathSearch=getNormalizedPath(directoryPathSearch.c_str()); - hFind = FindFirstFile(directoryPathSearch.c_str(), &ffd); - do - { - /*string filePath = directoryPath; - filePath.append("\\"); - filePath.append(ffd.cFileName); - bool directory = isDirectory(getNormalizedPath(filePath.c_str()));*/ - results.insert(pair(results.size()+1, ffd)); - } - while(FindNextFile(hFind, &ffd) != 0); - } - return results; -} - -int getDirectoryListingL(lua_State *L) -{ - if (lua_type(L,1)==LUA_TSTRING) - { - string directoryPath = getNormalizedPath(lua_tostring(L, 1)); - map listing = getDirectoryListing(directoryPath.c_str()); - if(listing.size()>0) - { - lua_settop(L,2); - lua_newtable(L); - for (map::const_iterator iter = listing.begin(); iter != listing.end(); ++iter) - { - string filePath = directoryPath; - filePath.append("\\"); - filePath.append(iter->second.cFileName); - bool directory = isDirectory(getNormalizedPath(filePath.c_str())); - LARGE_INTEGER filesize; - filesize.HighPart=iter->second.nFileSizeHigh; - filesize.LowPart=iter->second.nFileSizeLow; - lua_newtable(L); - - lua_pushstring(L,iter->second.cFileName); - lua_setfield(L,-2,"name"); - lua_pushboolean(L,directory); - lua_setfield(L,-2,"directory"); - lua_pushinteger(L,filesize.QuadPart); - lua_setfield(L,-2,"size"); - - lua_pushinteger(L,iter->first); - lua_pushvalue(L,-2); - lua_settable(L,3); - lua_settop(L,3); - } - return 1; - } - else - { - lua_pushstring(L,"not a directory!"); - lua_error_(L); - } - - } - else - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } -} - - -char *copyString(const char *Str) -{ - if (Str==NULL) - return NULL; - char *Ret=(char*)noxAlloc(strlen(Str)+1); - strcpy(Ret,Str); - return Ret; -} -wchar_t *copyStringW(const char *Str) -{ - if (Str==NULL) - return NULL; - wchar_t *Ret=(wchar_t *)noxAlloc(2*(strlen(Str)+1)); - mbstowcs(Ret,Str,strlen(Str)+1); - return Ret; -} -namespace -{ - int lastConColor=2; -} -void conSetNextColor(int C) -{ - lastConColor=C; -} -void conPrintI(const char *S) -{ - wchar_t Buf[200]; - if(200==mbstowcs(Buf,S,200)) - return; - consolePrint(lastConColor,Buf);//3-white - if (lastConColor!=2) - lastConColor=2; -}; -int (__cdecl *printCentered)(wchar_t *Text); -void printI(const char *S) -{ - wchar_t Buf[200]; - if(200==mbstowcs(Buf,S,200)) - return; - printCentered(Buf); -}; -DWORD *GameFlags=(DWORD*)0x5D53A4; -int setGameFlagsL(lua_State *L) -{ - DWORD Old=*GameFlags; - if(lua_type(L,1)==LUA_TNUMBER) - *GameFlags=(DWORD)lua_tointeger(L,1); - lua_pushnumber(L,Old); - return 1; -} -int bitOrL(lua_State *L) -{ - int R; - if(lua_type(L,1)!=LUA_TNUMBER) - return 0; - if(lua_type(L,2)!=LUA_TNUMBER) - return 0; - R=(lua_tointeger(L,1) | lua_tointeger(L,2)) ; - lua_pushinteger(L,R); - return 1; -} -int bitAndL(lua_State *L) -{ - int R; - if(lua_type(L,1)!=LUA_TNUMBER) - return 0; - if(lua_type(L,2)!=LUA_TNUMBER) - return 0; - R=lua_tointeger(L,1) & lua_tointeger(L,2) ; - lua_pushnumber(L,R); - return 1; -} - -int bitXorL(lua_State *L) -{ - int R; - if(lua_type(L,1)!=LUA_TNUMBER) - return 0; - if(lua_type(L,2)!=LUA_TNUMBER) - return 0; - R=lua_tointeger(L,1) ^ lua_tointeger(L,2) ; - lua_pushnumber(L,R); - return 1; -} - - -int printL(lua_State *L) -{ - int n=lua_gettop(L); - int i=0; - TString Rz; - const char *c; -// WCHAR Char; - for(i=1;i<=n;i++) - { - lua_pushvalue(L,i); - c=lua_tostring(L,-1); - lua_pop(L,1); -/* if(c!=NULL) - { - while(*c!=0) - { - mbtowc(&Char,c,1); - Rz+=Char; - c++; - } - }*/ - if(c!=NULL) - Rz.append(c); - - //Rz+=mbstowcs - //Rz - } - lua_Debug ar; - if (0==lua_getstack (L, 1, &ar)) /// , - lua_pushnil(L); - else - lua_getinfo(L, "f", &ar); - if (!lua_isnil(L, -1)) - lua_getfenv(L,-1); - if (lua_type(L,-1)==LUA_TTABLE) - { - lua_getfield(L,-1,"conOutput"); - } - if (lua_type(L,-1)==LUA_TNIL) - { - printI(Rz.c_str()); - } - else if(lua_type(L,-1)==LUA_TFUNCTION) - { - lua_pushlstring(L,Rz.c_str(),Rz.size()); - if (0!=lua_pcall(L,1,0,0)) - { - Rz.assign("Error in print:"); - Rz.append(lua_tostring(L,-1)); - printI(Rz.c_str()); - } - } - else - { - lua_getfield(L,-1,"print"); - lua_pushlstring(L,Rz.c_str(),Rz.size()); - if (0!=lua_pcall(L,1,0,0)) - { - Rz.assign("Error in print:"); - Rz.append(lua_tostring(L,-1)); - printI(Rz.c_str()); - } - } - return 0; -} -void InjectJumpTo(DWORD Addr,void *Fn)// -{ - BYTE *To=(BYTE *)Addr; - DWORD *Dw=(DWORD*)(To+1); - DWORD Delta=(DWORD)Fn; - Delta-=4+(DWORD)Dw; - DWORD OldProtect; - VirtualProtect(To,5,PAGE_EXECUTE_READWRITE,&OldProtect); - *Dw=Delta; - *(To++)=0xE9; - VirtualProtect(To,5,OldProtect,&OldProtect); -}; -void InjectOffs(DWORD Addr,void *Fn)// - c -{ - DWORD *Dw=(DWORD*)(Addr); - DWORD Delta=(DWORD)Fn; - Delta-=4+(DWORD)Dw; - DWORD OldProtect; - VirtualProtect(Dw,4,PAGE_EXECUTE_READWRITE,&OldProtect); - *Dw=Delta; - VirtualProtect(Dw,4,OldProtect,&OldProtect); -} -void InjectAddr(DWORD Addr,void *Fn)// - -{ - DWORD *Dw=(DWORD*)(Addr); - DWORD Delta=(DWORD)Fn; - DWORD OldProtect; - VirtualProtect(Dw,4,PAGE_EXECUTE_READWRITE,&OldProtect); - *Dw=Delta; - VirtualProtect(Dw,4,OldProtect,&OldProtect); -} -void InjectData(DWORD offset, byte* buff, size_t size) -{ - byte *addr = (byte*)(offset); - DWORD OldProtect; - VirtualProtect(addr, size, PAGE_EXECUTE_READWRITE, &OldProtect); - memcpy(addr, buff, size); - VirtualProtect(addr, 4, OldProtect, &OldProtect); -} - -#include -int (__cdecl *noxGetUnitsInRect)(FloatRect *Rect, void (__cdecl *SomeFn)(void *Unit, void *Arg), void *Arg); - -DWORD *frameCounter=(DWORD*)0x0084EA04; -DWORD *idGold=(DWORD*)0x00750714; - -#include -int *scriptStackSize=(int *)0x0075AE40; -std::vector scriptValues; - -int (__cdecl *noxThingTypeByName)(char const *Name); -const char *(__cdecl *noxThingNameByType)(int Type); - -namespace -{ - - void (__cdecl *oldCreateAtPart)(); - void __cdecl noxMyCreateAt(unitBigStructPtr Obj,unitBigStructPtr Parent, float X,float Y) - { - __asm{ - push Y - push X - push Parent - push Obj - push offset l1 - mov eax,0x00750714 - mov eax,[eax] - jmp oldCreateAtPart - l1: - add esp,16 // 4- - } - lua_getglobal(L,"noxOnCreateAt"); - if(lua_type(L,-1)!=LUA_TFUNCTION) - { - lua_pop(L,1); - return ; - } - lua_pushlightuserdata(L,Obj); - lua_pushlightuserdata(L,Parent); - lua_pushnumber(L,X); - lua_pushnumber(L,Y); - if(0!=lua_pcall(L,4,0,0)) - { - lua_pop(L,1); - } - return ; - } -/* - DWORD __cdecl newScriptPushValue(void *Value) - { - int SP=*(scriptStackSize); - if(scriptValues.size()<=SP) - { - scriptValues.resize(SP+1); - } - scriptValues[SP]=Value; - (*scriptStackSize)++; - return SP; - } - void *__cdecl newScriptPopValue() - { - int SP=(*scriptStackSize); - if(SP>0) - { - (*scriptStackSize)--; - SP--; - } - if(scriptValues.size()<=SP) - { - DebugBreak(); - return NULL; - } - - return scriptValues[SP]; - } -*/ - void getUnitsAroundImpl(void *Unit, void *L_) - { - lua_State *LL=(lua_State *)L_; - lua_pushvalue(L,1); - lua_pushlightuserdata(LL,Unit); - if(0!=lua_pcall(LL,1,0,0)) - lua_error_(LL); - } - int getPtrPtrL(lua_State *L) - { - if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA)||(lua_type(L,2)!=LUA_TNUMBER) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - BYTE* P=(BYTE*) lua_touserdata(L,1); - lua_pushnil(L); - if(P==NULL) - return 1; - P=*((BYTE**)(P+lua_tointeger(L,2) )); - if(P==NULL) - return 1; - lua_pushlightuserdata(L, P); - return 1; - } - int getPtrByteL(lua_State *L) - { - if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA)||(lua_type(L,2)!=LUA_TNUMBER) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - BYTE* P=(BYTE*) lua_touserdata(L,1); - if(P==NULL) - return 0; - P+=lua_tointeger(L,2); - lua_pushinteger(L, *((BYTE*)P)); - return 1; - } - int getPtrIntL(lua_State *L) - { - if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA)||(lua_type(L,2)!=LUA_TNUMBER) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - BYTE* P=(BYTE*) lua_touserdata(L,1); - if(P==NULL) - return 0; - P+=lua_tointeger(L,2); - lua_pushinteger(L, *((int*)P)); - return 1; - } - int getPtrShortL(lua_State *L) - { - if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA)||(lua_type(L,2)!=LUA_TNUMBER) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - BYTE* P=(BYTE*) lua_touserdata(L,1); - if(P==NULL) - return 0; - P+=lua_tointeger(L,2); - lua_pushinteger(L, *((USHORT*)P)); - return 1; - } - int getPtrFloatL(lua_State *L) - { - if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA)||(lua_type(L,2)!=LUA_TNUMBER) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - BYTE* P=(BYTE*) lua_touserdata(L,1); - if(P==NULL) - return 0; - P+=lua_tointeger(L,2); - lua_pushnumber(L, *((float*)P)); - return 1; - } - int setPtrFloatL(lua_State *L) - { - if ( ((lua_type(L,1)!=LUA_TLIGHTUSERDATA)&& (lua_type(L,1)!=LUA_TNIL)) - ||(lua_type(L,2)!=LUA_TNUMBER) - ||(lua_type(L,3)!=LUA_TNUMBER)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - BYTE* P=(BYTE*) lua_touserdata(L,1); - if(P==NULL) return 0; - P+=lua_tointeger(L,2); - DWORD Pt=(DWORD)P; - DWORD OldProtect; - if( ((lua_type(L,1)==LUA_TNIL)) &&( (Pt<0x400000) || (Pt>0x600000) ) ) - { - lua_pushstring(L,"wrong offset!"); - lua_error_(L); - } - VirtualProtect(P,4,PAGE_EXECUTE_READWRITE,&OldProtect); - *((float*)P) = lua_tonumber(L,3 ); - VirtualProtect(P,4,OldProtect,&OldProtect); - return 0; - } - int setPtrByteL(lua_State *L) - { - if ( ((lua_type(L,1)!=LUA_TLIGHTUSERDATA)&& (lua_type(L,1)!=LUA_TNIL)) - ||(lua_type(L,2)!=LUA_TNUMBER) - ||(lua_type(L,3)!=LUA_TNUMBER)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - BYTE* P=(BYTE*) lua_touserdata(L,1); - if(P==NULL) return 0; - P+=lua_tointeger(L,2); - DWORD Pt=(DWORD)P; - DWORD OldProtect; - if( ((lua_type(L,1)==LUA_TNIL)) &&( (Pt<0x400000) || (Pt>0x600000) ) ) - { - lua_pushstring(L,"wrong offset!"); - lua_error_(L); - } - VirtualProtect(P,4,PAGE_EXECUTE_READWRITE,&OldProtect); - *((BYTE*)P) = lua_tointeger(L,3 ); - VirtualProtect(P,4,OldProtect,&OldProtect); - return 1; - } - int setPtrIntL(lua_State *L) - { - if ( ((lua_type(L,1)!=LUA_TLIGHTUSERDATA)&& (lua_type(L,1)!=LUA_TNIL)) - ||(lua_type(L,2)!=LUA_TNUMBER) - ||(lua_type(L,3)!=LUA_TNUMBER)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - BYTE* P=(BYTE*) lua_touserdata(L,1); - if (P==NULL) - return 0; - P+=lua_tointeger(L,2); - DWORD Pt=(DWORD)P; - DWORD OldProtect; - if( ((lua_type(L,1)==LUA_TNIL)) &&( (Pt<0x400000) || (Pt>0x600000) ) ) - { - lua_pushstring(L,"wrong offset!"); - lua_error_(L); - } - VirtualProtect(P,4,PAGE_EXECUTE_READWRITE,&OldProtect); - *((int*)P) = lua_tointeger(L,3 ); - VirtualProtect(P,4,OldProtect,&OldProtect); - return 0; - } - int setPtrShortL(lua_State *L) - { - if ( ((lua_type(L,1)!=LUA_TLIGHTUSERDATA)&& (lua_type(L,1)!=LUA_TNIL)) - ||(lua_type(L,2)!=LUA_TNUMBER) - ||(lua_type(L,3)!=LUA_TNUMBER)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - BYTE* P=(BYTE*) lua_touserdata(L,1); - if(P==NULL) return 0; - P+=lua_tointeger(L,2); - DWORD Pt=(DWORD)P; - DWORD OldProtect; - if( ((lua_type(L,1)==LUA_TNIL)) &&( (Pt<0x400000) || (Pt>0x600000) ) ) - { - lua_pushstring(L,"wrong offset!"); - lua_error_(L); - } - VirtualProtect(P,4,PAGE_EXECUTE_READWRITE,&OldProtect); - *((USHORT*)P) = lua_tointeger(L,3 ); - VirtualProtect(P,4,OldProtect,&OldProtect); - return 0; - } - int setPtrPtrL(lua_State *L) - { - if ( ((lua_type(L,1)!=LUA_TLIGHTUSERDATA) && (lua_type(L,1)!=LUA_TNIL)) - ||(lua_type(L,2)!=LUA_TNUMBER) - ||(lua_type(L,3)!=LUA_TLIGHTUSERDATA)) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - BYTE* P=(BYTE*) lua_touserdata(L,1); - if (P==NULL) - return 0; - P+=lua_tointeger(L,2); - DWORD Pt=(DWORD)P; - DWORD OldProtect; - if( ((lua_type(L,1)==LUA_TNIL)) &&( (Pt<0x400000) || (Pt>0x600000) ) ) - { - lua_pushstring(L,"wrong offset!"); - lua_error_(L); - } - VirtualProtect(P,4,PAGE_EXECUTE_READWRITE,&OldProtect); - *((void**)P) = lua_touserdata(L,3 ); - VirtualProtect(P,4,OldProtect,&OldProtect); - return 0; - } - int getUnitClassL(lua_State *L) - { - if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - BYTE* P=(BYTE*) lua_touserdata(L,1); - if(P==NULL) - { - lua_pushnil(L); - return 0; - } - if((lua_gettop(L)>1) && (lua_type(L,2)==LUA_TNUMBER)) - { - lua_pushboolean(L, lua_tointeger(L,2) & (*((int*)(P+0x8))) ); - return 1; - } - lua_pushinteger(L, *((int*)(P+0x8)) ); - return 1; - } - int getUnitFlagsL(lua_State *L) - { - if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - BYTE* P=(BYTE*) lua_touserdata(L,1); - if(P==NULL) - { - lua_pushinteger(L,0); - return 0; - } - if((lua_gettop(L)>1) && (lua_type(L,2)==LUA_TNUMBER)) - { - lua_pushboolean(L, lua_tointeger(L,2) & (*((int*)(P+0x10))) ); - return 1; - } - lua_pushinteger(L, *((int*)(P+0x10)) ); - return 1; - } - int getThingTypeL(lua_State *L) - { - if((lua_type(L,1)==LUA_TSTRING) ) - { - int R=noxThingTypeByName(lua_tostring(L,1)); - if(R>=0) - lua_pushinteger(L,R); - else - lua_pushnil(L); - return 1; - } - else if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - BYTE* P=(BYTE*) lua_touserdata(L,1); - if(P==NULL) - { - lua_pushnil(L); - return 1; - } - lua_pushinteger(L, *((WORD*)(P+4)) ); - return 1; - } - - int setThingTypeL(lua_State *L) - { - int R=0; - if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - if (lua_type(L,2)==LUA_TNUMBER) - { - R=lua_tointeger(L,2); - } - else if(lua_type(L,2)==LUA_TNUMBER) - R=noxThingTypeByName(lua_tostring(L,2)); - if(R<=0) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - - BYTE* P=(BYTE*) lua_touserdata(L,1); - if(P==NULL) - return 0; - *((WORD*)(P+4))=(WORD)R; - return 0; - } - - int getClassNameL(lua_State *L) - { - const char *R; - if (lua_type(L,1)==LUA_TNUMBER) - { - R=noxThingNameByType(lua_tointeger(L,1)); - if(R!=0) - lua_pushstring(L, R); - else - lua_pushnil(L); - return 1; - } - else if( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - BYTE* P=(BYTE*) lua_touserdata(L,1); - if(P==NULL) - return 0; - R=noxThingNameByType(*((WORD*)(P+4))) ; - if(R!=0) - lua_pushstring(L, R); - else - lua_pushnil(L); - return 1; - } - int getUnitsAround(lua_State *L) - { - if ( - (lua_gettop(L)!=5)|| - (lua_type(L,1)!=LUA_TFUNCTION) || - (lua_type(L,2)!=LUA_TNUMBER) || - (lua_type(L,3)!=LUA_TNUMBER) || - (lua_type(L,4)!=LUA_TNUMBER) || - (lua_type(L,5)!=LUA_TNUMBER) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - return 0; - } - noxGetUnitsInRect( - &FloatRect( - lua_tonumber(L,2), - lua_tonumber(L,3), - lua_tonumber(L,4), - lua_tonumber(L,5) ) - ,&getUnitsAroundImpl,L); - return 0; - } -////// - LPTOP_LEVEL_EXCEPTION_FILTER OldFilter=0; - char exAppName[MAX_PATH]=""; - char exCmdLine[MAX_PATH]=""; - char exCurDir[MAX_PATH]=""; - - int ExceptionMode=0; - int setExMode(lua_State *L) - { - lua_settop(L,3); - lua_pushinteger(L,ExceptionMode); - ExceptionMode=lua_tointeger(L,3); - return 1; - } - // 0 - ( ) - // 1 - log - // 2 - log - // - LONG WINAPI ExceptionFilter( - _EXCEPTION_POINTERS *EI - ) - { - static char Buf[1024]; - char *P=Buf; - int L=0; - int Remain=sizeof(Buf)-1; - if (ExceptionMode==0) - { - if (OldFilter!=NULL) - return OldFilter(EI); - } - L=_snprintf(P,Remain,"=========\n== %8d\nE 0x%08x at 0x%08x, Esp: 0x%08x\nStack:\n",_time32(NULL), - EI->ExceptionRecord->ExceptionCode,EI->ExceptionRecord->ExceptionAddress,EI->ContextRecord->Esp); - P+=L;Remain-=L; - DWORD *DW=(DWORD*)EI->ContextRecord->Esp; - for (int i=0;i<32;i++) - { - if (IsBadReadPtr(DW,4)) - break; - if (Remain<4) - break; - L=_snprintf(P,Remain,"0x%08x\n",*(DW++)); - P+=L;Remain-=L; - } - L=_snprintf(P,Remain,"== END ==\n"); - P+=L;Remain-=L; - FILE *F=fopen("UniErrorLog.txt","a+"); - if (F!=NULL) - { - fwrite(Buf,P-Buf,1,F); - fclose(F); - } -// MessageBox(0,Buf,0,0); - if (ExceptionMode==2) - { -// static char Buf[1024]; -// sprintf(Buf,"%s\n%s\n%s",exAppName,exCmdLine,exCurDir); -// MessageBox(0,Buf,0,0); - static STARTUPINFO SI={0}; - static PROCESS_INFORMATION PI={0}; - SI.cb=sizeof(SI); - Sleep(0); - CreateProcess(exAppName,exCmdLine,NULL,NULL,FALSE,0,NULL,exCurDir,&SI,&PI); - CloseHandle(PI.hProcess); - CloseHandle(PI.hThread); - } - ExitProcess(-1); - return 0; - } - void exInit() - { - GetModuleFileName (NULL,exAppName,MAX_PATH); - const char *Cmd=GetCommandLine(); - strncpy(exCmdLine,Cmd,MAX_PATH-1); - GetCurrentDirectory(MAX_PATH,exCurDir); - OldFilter=SetUnhandledExceptionFilter(&ExceptionFilter); - - } - -//// - - int timeoutNextId=1; - struct TimeoutListRec - { - int Id; - DWORD Frame; - bool Persist; - TimeoutListRec(int Id_, DWORD Frame_, bool Persist_) :Id(Id_), Frame(Frame_), Persist(Persist_) - {} - }; - std::list timeoutList; - int setTimeoutL(lua_State *L) /// 3- - 4- - - { - lua_settop(L,4); - if ((lua_type(L,1)!=LUA_TFUNCTION) ||(lua_type(L,2)!=LUA_TNUMBER) - || ((lua_type(L,3)!=LUA_TTABLE) && (lua_type(L,3)!=LUA_TNIL)) - || ((lua_type(L,4)!=LUA_TBOOLEAN) && (lua_type(L,4)!=LUA_TNIL)) - ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - lua_pushlightuserdata(L,setTimeoutL);/// - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushinteger(L,timeoutNextId); - lua_pushvalue(L,1); - lua_settable(L,-3); - lua_pushlightuserdata(L,&timeoutNextId);/// - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushinteger(L,timeoutNextId); - lua_pushvalue(L,3); - lua_settable(L,-3); - - bool ispersistant = lua_toboolean(L, 4); - lua_pushinteger(L,timeoutNextId); - - DWORD Time=*frameCounter +(DWORD)lua_tointeger(L,2); - - std::list::iterator I; - for (I=timeoutList.begin();I!=timeoutList.end();I++) - { - if(I->Frame > Time) - break; - } - timeoutList.insert(I, TimeoutListRec(timeoutNextId++, Time, ispersistant)); - return 1; - } - void (__cdecl *sub51ADF0)();/// - int getFrameCounterL(lua_State *L) - { - lua_pushinteger(L,(int)*frameCounter); - return 1; - } - void __cdecl onEachFrame() - { - replayEachFrame(); - if(specialAuthorisation) - for(int i=0; i<0x20; i++) - { - if(authSendWelcomeMsg[i]==1) - authSendWelcomeMsg[i]=-2; - if(authSendWelcomeMsg[i]>0) - authSendWelcomeMsg[i]--; - if(authSendWelcomeMsg[i]<0) - { - if(authorisedState[i]==4) - netSendChatMessage("You have been authorised! Now you can quit the observer mode and play.", i); - if(authorisedState[i]==2) - netSendChatMessage("Now please enter your password. For best security prefix it with '//auth '.", i); - if(authorisedState[i]==3) - netSendChatMessage("Thank you, we have got your login and password. Please wait a while before we check them...", i); - if(authorisedState[i]==1) - netSendChatMessage("Something weird happened and we couldn't authorise you. Probably you have misspelled your login and password? Please try again. Enter your login. For best security prefix it with '//auth '.", i); - if(authorisedState[i]==0) - { - authorisedState[i]++; - netSendChatMessage("Welcome to our server! Please enter your login in a chat message to proceed. You can't play without having a registered account! For best security prefix it with '//auth '.", i); - } - authSendWelcomeMsg[i]=0; - } - } - serverUpdate(); - DWORD Time = *frameCounter; - int Top = lua_gettop(L); - lua_pushlightuserdata(L, &timeoutNextId);/// - lua_gettable(L, LUA_REGISTRYINDEX); - lua_pushlightuserdata(L, setTimeoutL);/// - lua_gettable(L, LUA_REGISTRYINDEX); - - for (std::list::iterator I = timeoutList.begin(); I != timeoutList.end();) - { - if (Time < I->Frame) - { - I++; - } - else - { - lua_pushinteger(L, I->Id); - lua_gettable(L, -2); - if (lua_type(L, -1) == LUA_TFUNCTION) - { - lua_getfenv(L, -1); - lua_pushvalue(L, -2); - lua_getfield(L, -2, "conOutput");// conOutput - lua_insert(L, -2);// conOutput - lua_pushnil(L); - lua_setfield(L, -4, "conOutput"); - - lua_pushinteger(L, Time); - lua_pushinteger(L, I->Id); - // - lua_gettable(L, -8); // id,Time,Fn, conOutput, env, fn, {Fns},{Args} - if (0 != lua_pcall(L, 2, 0, 0)) - { - const char* errorStr = lua_tostring(L, -1); - char Err[200]; - strcpy(Err, "delayed error: "); - strncat(&Err[strlen(Err)], errorStr, (199 - strlen(Err))); - conPrintI(Err); - lua_pop(L, 1); - } - ///conOutput,env, fn, {Fns},{Args} - lua_getfield(L, -2, "conOutput");// conOutput - if (lua_type(L, -1) == LUA_TNIL) // - , ? - { - lua_pop(L, 1); - lua_setfield(L, -2, "conOutput"); - lua_pop(L, 2); - } - else - lua_pop(L, 3); - - lua_pushinteger(L, I->Id); // - } - else - lua_pop(L, 1); - - lua_pushnil(L); - lua_settable(L, -3); // - lua_pushinteger(L, I->Id); - lua_pushnil(L); - lua_settable(L, -4);// - - I = timeoutList.erase(I); - } - } - lua_settop(L, Top); - sub51ADF0(); - } - - int memFreeL(lua_State *L) - { - if ((lua_type(L,1)!=LUA_TUSERDATA) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - void *P=lua_touserdata(L,1); - if(P!=0) - noxFree(P); - return 0; - } - - int memAllocL(lua_State *L) - { - if ((lua_type(L,1)!=LUA_TNUMBER) ) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - int Size=lua_tonumber(L,1); - if (Size<=0) - { - lua_pushstring(L,"wrong args!"); - lua_error_(L); - } - void *P=noxAlloc(Size); - lua_pushlightuserdata(L,P); - return 1; - } -}; -void mapUnloadUtil() -{ - for (std::list::iterator I = timeoutList.begin(); I != timeoutList.end();) - { - if (I->Persist == false) - { - I=timeoutList.erase(I); - } - else - { - I++; - } - } - DWORD Time = *frameCounter; -} - -void lua_error_(lua_State*L) -{ - int T=lua_gettop(L); - lua_getglobal(L,"debug"); - lua_getfield(L,-1,"traceback"); - if (lua_type(L,-1)==LUA_TFUNCTION) - lua_call(L,0,0); - lua_settop(L,T); - lua_error(L); -} - -extern void initSDL(); -extern void windowsAllInit(); -extern void unitFunctionInit(); -extern void mapInit(); -extern void reactInit(); -extern void spellsInit(); -extern void netInit(); -extern void keysInit(); -extern void consoleInit(); -extern void playerFunctionInint(); -extern void spriteInit(); -extern void spellListInit(); -extern void clientViewInit(); -extern void unitDefsInit(); -extern void tilesInit(); -extern void cliUntilInit(); -extern bool initAuthData(); -extern void polygonInit(); -extern void bugsInit(); -extern void autoServer(); -extern "C" void scoreInit(lua_State *L); -extern "C" void replayInit(lua_State *L); - -extern "C" void initAudServer(lua_State *L); - -extern void guiInit(); -extern void waypointsInit(); -extern char *(__cdecl *mapGetName)(); - -extern DWORD __cdecl onConCmd(wchar_t *A,DWORD B); -extern void initModLib2(); -extern void initFilesystem(); - -extern "C" void adminInit(lua_State *L); -//extern "C" void authInit(lua_State *L); -extern "C" int luaopen_lpeg (lua_State *L); -extern "C" void mapUtilInit(lua_State*L); -extern bool serverUpdate(); - -int initWindowedMode(int param1, int param2, int param3) -{ - DEVMODE devMode; - EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devMode); - if(devMode.dmBitsPerPel>16) - { - devMode.dmBitsPerPel=16; - devMode.dmFields = DM_BITSPERPEL; - } - int result = ChangeDisplaySettings(&devMode, CDS_FULLSCREEN); - return initWindowedModeNox(param1, param2, param3); -} - -void injectCon() -{ - initSDL(); - //MessageBox(0,"!",0,0); - exInit(); - initModLib2(); - luaopen_lpeg (L); - ASSIGN(consolePrint,0x00450B90); - ASSIGN(printCentered,0x00445490); - ASSIGN(sub51ADF0,0x0051ADF0); - ASSIGN(noxGetUnitsInRect,0x00517C10); - ASSIGN(oldCreateAtPart,0x004DAA55);// - ASSIGN(noxAlloc,0x00403560); - ASSIGN(noxCAlloc,0x004041D0); - ASSIGN(noxFree,0x0040425D); - - gameDirectory=(char*)0x005D4B08; - - InjectJumpTo(0x004DAA50,&noxMyCreateAt); - -// InjectJumpTo(0x00507250,&newScriptPopValue); -// InjectJumpTo(0x00507230,&newScriptPushValue); - - ASSIGN(noxThingTypeByName,0x4E3AA0); - ASSIGN(noxThingNameByType,0x4E3A80); - - int Top=lua_gettop(L); - lua_pushcfunction(L,&frameLimiter); - lua_setglobal(L,"frameLimiter"); - lua_pushcfunction(L,&bitOrL); - lua_setglobal(L,"bitOr"); - lua_pushcfunction(L,&bitAndL); - lua_setglobal(L,"bitAnd"); - lua_pushcfunction(L,&bitXorL); - lua_setglobal(L,"bitXor"); - - luaL_dostring(L,"math.randomseed( os.time() )"); - - lua_createtable(L,0,40);/// Client enviroment - lua_newtable(L); - lua_pushvalue(L,LUA_GLOBALSINDEX); - lua_setfield(L,-2,"__index"); - lua_setmetatable(L,-2);/// _G - lua_pushvalue(L,-1); - lua_setfield(L,LUA_REGISTRYINDEX,"client"); - - lua_newtable(L); /// meta2 - lua_pushvalue(L,-2); - lua_setfield(L,-2,"__index"); - // meta2,client - lua_createtable(L,0,40);/// Server enviroment - lua_pushvalue(L,-2); - lua_setmetatable(L,-2);/// - lua_setfield(L,LUA_REGISTRYINDEX,"server"); - - lua_pushcfunction(L,&setTimeoutL); - // , - // - lua_pushvalue(L,-1); - lua_setfield(L,LUA_REGISTRYINDEX,"setTimeout"); - registerServerVar("setTimeout"); - registerserver("setExMode",&setExMode); - registerserver("unitGetAround",&getUnitsAround); - - lua_pushcfunction(L,&printL); - lua_setglobal(L,"print"); - lua_pushcfunction(L,&getFrameCounterL); - lua_setglobal(L,"getFrameCounter"); - lua_pushcfunction(L,&setGameFlagsL); - lua_setglobal(L,"gameFlags"); - lua_getglobal(L,"string"); - lua_getfield(L,-1,"format"); - lua_setglobal(L,"printf"); - lua_pop(L,1); - lua_pushlightuserdata(L,&setTimeoutL); - lua_newtable(L); - lua_settable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,&timeoutNextId); - lua_newtable(L); - lua_settable(L,LUA_REGISTRYINDEX); - - lua_pushcfunction(L,&getThingTypeL); - lua_setglobal(L,"getThingType"); - lua_pushcfunction(L,&setThingTypeL); - lua_setglobal(L,"setThingType"); - - lua_pushcfunction(L,&getClassNameL); - lua_setglobal(L,"getThingName"); - - registerserver("unitClass",&getUnitClassL); - registerserver("unitFlags",&getUnitFlagsL); - - - lua_pushcfunction(L,&getPtrPtrL); - lua_setglobal(L,"getPtrPtr"); - lua_pushcfunction(L,&getPtrIntL); - lua_setglobal(L,"getPtrInt"); - lua_pushcfunction(L,&getPtrFloatL); - lua_setglobal(L,"getPtrFloat"); - lua_pushcfunction(L,&getPtrShortL); - lua_setglobal(L,"getPtrShort"); - lua_pushcfunction(L,&setPtrFloatL); - lua_setglobal(L,"setPtrFloat"); - lua_pushcfunction(L,&setPtrIntL); - lua_setglobal(L,"setPtrInt"); - lua_pushcfunction(L,&setPtrPtrL); - lua_setglobal(L,"setPtrPtr"); - lua_pushcfunction(L,&setPtrShortL); - lua_setglobal(L,"setPtrShort"); - lua_pushcfunction(L,&setPtrByteL); - lua_setglobal(L,"setPtrByte"); - lua_pushcfunction(L,&getPtrByteL); - lua_setglobal(L,"getPtrByte"); - - lua_pushcfunction(L,&memAllocL); - lua_setglobal(L,"memAlloc"); - lua_pushcfunction(L,&memFreeL); - lua_setglobal(L,"memFree"); - - mapUtilInit(L); - initFilesystem(); - consoleInit(); - adminInit(L); - //authInit(L); - initAuthData(); - initAudServer(L); - reactInit(); - - windowsAllInit(); - clientViewInit(); - unitFunctionInit(); - mapInit(); - tilesInit(); - unitDefsInit(); - spellsInit(); - netInit(); - keysInit(); - playerFunctionInint(); - spriteInit(); - spellListInit(); - guiInit(); - scoreInit(L); - replayInit(L); - waypointsInit(); - cliUntilInit(); - polygonInit(); - bugsInit(); - autoServer(); - - InjectJumpTo(0x00443C80,&onConCmd);// - InjectOffs(0x4D2AB5,&onEachFrame); - - InjectOffs(0x00443A81+1, &tokenParseFixup); - InjectOffs(0x00443A71+1, &tokenParseCipherFixup); - - ASSIGN(initWindowedModeNox,0x0048AED0); - - - InjectOffs(0x48A0C2+1,&initWindowedMode); - - ASSIGN(frameLimiterSetting,0x0059449C); - ASSIGN(j_time,0x00416BF0); - ASSIGN(consoleTokenCipher, 0x00443BF0); - -#include "lua/binClient/clientOnJoin.lua.inc" - - lua_getfield(L,LUA_REGISTRYINDEX,"client"); - lua_setfenv(L,-2); - lua_pcall(L,0,0,0); -#include "lua/binServer/chatMode.lua.inc" - lua_getfield(L,LUA_REGISTRYINDEX,"server"); - lua_setfenv(L,-2); - lua_pcall(L,0,0,0); -#include "lua/binGlobal/dofile.lua.inc" - -#include "lua/binGlobal/filesystem.inc.lua.inc" - - lua_settop(L,Top); - - //lua_pushnil(L); - //lua_setglobal(L,"os");/// - - - int topLoad = lua_gettop(L); - - lua_getfield(L, LUA_REGISTRYINDEX, "require.lua"); - if (lua_isfunction(L, -1)) - { - lua_getfield(L, LUA_REGISTRYINDEX, "server"); - lua_setfenv(L, -2); - int err = lua_pcall(L, 0, 0, 0); - if (err != 0) - { - const char* errorMsg = lua_tostring(L, -1); - MessageBoxA(NULL, errorMsg, "LUA load error! The file won't be loaded!", MB_OK); - return; - } - //lua_pushstring(L, "require.lua"); - //lua_pushstring(L, mode); - //lua_settable(L, LUA_REGISTRYINDEX); - } - - lua_settop(L, topLoad); - - if (0==luaL_loadfile(L, "autoexec.lua")) - { - lua_getfield(L,LUA_REGISTRYINDEX,"server"); - lua_setfenv(L,-2); - lua_pcall(L, 0, 0, 0); - } - - - //MessageBox(0,"!",0,0); - - byte OperatorJmps=0xEB; - byte OperatorMovEax1[]={0xB8,0x01,0,0,0}; - byte OperatorNop[]={0x90,0x90}; - byte *bt=(byte*)(0x00553660); - byte *bt2=(byte*)(0x00401E06); - byte *bt3=(byte*)(0x00401114); - byte *bt4=(byte*)(0x0043E82B); - DWORD OldProtect; - VirtualProtect(bt,1,PAGE_EXECUTE_READWRITE,&OldProtect); - memcpy((byte*)bt,&OperatorJmps,1); // - VirtualProtect(bt,1,OldProtect,&OldProtect); - VirtualProtect(bt2,1,PAGE_EXECUTE_READWRITE,&OldProtect); - memcpy((byte*)bt2,&OperatorJmps,1); // 2 - - VirtualProtect(bt2,1,OldProtect,&OldProtect); - VirtualProtect(bt3,5,PAGE_EXECUTE_READWRITE,&OldProtect); - memcpy((byte*)bt3,&OperatorMovEax1,5); // - VirtualProtect(bt3,5,OldProtect,&OldProtect); - VirtualProtect(bt4,2,PAGE_EXECUTE_READWRITE,&OldProtect); - memcpy((byte*)bt4,&OperatorNop,2); // . - VirtualProtect(bt4,2,OldProtect,&OldProtect); - - // ( ?...) -: - InjectAddr(0x444158 + 1, &hostIdx); - - registerclient("getGameDirectory", &getGameDirectoryL); - registerclient("getNormalizedPath", &getNormalizedPathL); - registerclient("getDirectoryListing", &getDirectoryListingL); +#include "stdafx.h" +#include +#include +#include +#include +/* +Исследовать: ++) Появление обелисков +) Респавны юнитов ++.) Свойства стен ++) Баффы оружия/брони (исследовал но не могу применять) + +Eще поправки ++1) Чтобы юнит можно было двигать ++2) Чтбы юнит можно было пнуть в сторону +) определение типа и сабтипа ++3) добавить функцию для карты, ведущую в юнимод +4) чтобы она могла читать/писать переменные по именам ++5) сетевой пакет + +-) сделать в консоли больше место для инфы, а то после скана все и не найдешь, потеряеться +-) сделать так что бы при написании теста в консоли были копипаст хотя бы) ++) что бы по этому тексту можно было пермещаться стрелосками, а то удалялять 300 симболов что бы исправить 1 ошибку не удобно... + +*/ + +#define AddCodeLine(a,b) conPrintI(a) + +typedef unsigned int u_int; +void *(__cdecl *noxCAlloc)(int NumElements,int Size); +void *(__cdecl *noxAlloc)(int Size); +void (__cdecl *noxFree)(void *Ptr); + +int (__cdecl *consolePrint)(int Color, wchar_t *Text); +extern bool serverUpdate(); +extern char authSendWelcomeMsg[0x20]; +extern void netSendChatMessage(char *sendChat, int sendTo, short sendFrom=0, bool fakeSystemMessage=false); +extern byte authorisedState[0x20]; +extern bool specialAuthorisation; //Отключение альтернативной авторизации + +u_int hostIdx = 0x1F; + +extern void replayEachFrame(); + +char* gameDirectory; + +int (__cdecl *initWindowedModeNox)(int param1, int param2, int param3); + +float* frameLimiterSetting; + +int (__cdecl *j_time)(); + +void(__cdecl *consoleTokenCipher)(wchar_t* source, wchar_t* dest); + +using namespace std; + +wchar_t* tokenParseFixup(wchar_t* Dest, wchar_t* Source) +{ + return wcsncpy(Dest, Source, 31); +} + +void tokenParseCipherFixup(wchar_t* Source, wchar_t* Dest) +{ + wchar_t adjustedToken[32]; + adjustedToken[31] = L'\0'; + tokenParseFixup(adjustedToken, Source); + consoleTokenCipher(adjustedToken, Dest); +} + +int frameLimiter(lua_State* L) +{ + byte* bt = (byte*)(0x0043E2F3+1); + byte* bt2 = (byte*)(0x004AB609+1); + if(lua_type(L,1)==LUA_TNUMBER) + { + float limiterFPS = (float)lua_tonumber(L,1); + *frameLimiterSetting = 1000 / limiterFPS; + // Begin of Black Shaman + float* frameLimiterSetting2 = (float*)0x00594498; + *frameLimiterSetting2 = *frameLimiterSetting/1000; + int *frameCounterTest=(int*)0x0062F1D0; + int *frameCounterTest2=(int*)0x0084EA04; + int *frameCounterTest3=(int*)0x0062F1C8; + *frameCounterTest = *frameCounterTest2; + *frameCounterTest3 = j_time(); + + DWORD OldProtect; + VirtualProtect(bt,1,PAGE_EXECUTE_READWRITE,&OldProtect); + *bt=(byte)limiterFPS; + VirtualProtect(bt,1,OldProtect,&OldProtect); + + VirtualProtect(bt2,1,PAGE_EXECUTE_READWRITE,&OldProtect); + *bt2=(byte)limiterFPS; + VirtualProtect(bt2,1,OldProtect,&OldProtect); + + // End of Black Shaman + } + lua_pushnumber(L, *bt); + return 1; +} + +string getGameDirectory() +{ + u_int size = GetFullPathName(gameDirectory, 0, NULL, NULL); + char* buf = new char[size]; + GetFullPathName(gameDirectory, size, buf, NULL); + string result = buf; + return result; +} + +int getGameDirectoryL(lua_State *L) +{ + lua_pushstring(L, getGameDirectory().c_str()); + return 1; +} + +string getNormalizedPath(const char* path) +{ + u_int size = GetFullPathName(path, 0, NULL, NULL); + char* buf = new char[size]; + SetCurrentDirectory(getGameDirectory().c_str()); + GetFullPathName(path, size, buf, NULL); + string result = buf; + delete [] buf; + return result; +} + +int getNormalizedPathL(lua_State *L) +{ + if (lua_type(L,1)==LUA_TSTRING) + { + lua_pushstring(L, getNormalizedPath(lua_tostring(L, 1)).c_str()); + return 1; + } + else + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } +} + +bool isDirectory(string dirName) +{ + DWORD attribs = GetFileAttributes(dirName.c_str()); + if (attribs == INVALID_FILE_ATTRIBUTES) + { + return false; + } + return (attribs & FILE_ATTRIBUTE_DIRECTORY); +} + +map getDirectoryListing(const char* path) +{ + //string directoryPath = getNormalizedPath(path); + string directoryPath = path; + map results; + if(isDirectory(directoryPath)) + { + string directoryPathSearch = directoryPath; + WIN32_FIND_DATA ffd; + HANDLE hFind = INVALID_HANDLE_VALUE; + directoryPathSearch.append("\\*"); + directoryPathSearch=getNormalizedPath(directoryPathSearch.c_str()); + hFind = FindFirstFile(directoryPathSearch.c_str(), &ffd); + do + { + /*string filePath = directoryPath; + filePath.append("\\"); + filePath.append(ffd.cFileName); + bool directory = isDirectory(getNormalizedPath(filePath.c_str()));*/ + results.insert(pair(results.size()+1, ffd)); + } + while(FindNextFile(hFind, &ffd) != 0); + } + return results; +} + +int getDirectoryListingL(lua_State *L) +{ + if (lua_type(L,1)==LUA_TSTRING) + { + string directoryPath = getNormalizedPath(lua_tostring(L, 1)); + map listing = getDirectoryListing(directoryPath.c_str()); + if(listing.size()>0) + { + lua_settop(L,2); + lua_newtable(L); + for (map::const_iterator iter = listing.begin(); iter != listing.end(); ++iter) + { + string filePath = directoryPath; + filePath.append("\\"); + filePath.append(iter->second.cFileName); + bool directory = isDirectory(getNormalizedPath(filePath.c_str())); + LARGE_INTEGER filesize; + filesize.HighPart=iter->second.nFileSizeHigh; + filesize.LowPart=iter->second.nFileSizeLow; + lua_newtable(L); + + lua_pushstring(L,iter->second.cFileName); + lua_setfield(L,-2,"name"); + lua_pushboolean(L,directory); + lua_setfield(L,-2,"directory"); + lua_pushinteger(L,filesize.QuadPart); + lua_setfield(L,-2,"size"); + + lua_pushinteger(L,iter->first); + lua_pushvalue(L,-2); + lua_settable(L,3); + lua_settop(L,3); + } + return 1; + } + else + { + lua_pushstring(L,"not a directory!"); + lua_error_(L); + } + + } + else + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } +} + + +char *copyString(const char *Str) +{ + if (Str==NULL) + return NULL; + char *Ret=(char*)noxAlloc(strlen(Str)+1); + strcpy(Ret,Str); + return Ret; +} +wchar_t *copyStringW(const char *Str) +{ + if (Str==NULL) + return NULL; + wchar_t *Ret=(wchar_t *)noxAlloc(2*(strlen(Str)+1)); + mbstowcs(Ret,Str,strlen(Str)+1); + return Ret; +} +namespace +{ + int lastConColor=2; +} +void conSetNextColor(int C) +{ + lastConColor=C; +} +void conPrintI(const char *S) +{ + wchar_t Buf[200]; + if(200==mbstowcs(Buf,S,200)) + return; + consolePrint(lastConColor,Buf);//3-white + if (lastConColor!=2) + lastConColor=2; +}; +int (__cdecl *printCentered)(wchar_t *Text); +void printI(const char *S) +{ + wchar_t Buf[200]; + if(200==mbstowcs(Buf,S,200)) + return; + printCentered(Buf); +}; +DWORD *GameFlags=(DWORD*)0x5D53A4; +int setGameFlagsL(lua_State *L) +{ + DWORD Old=*GameFlags; + if(lua_type(L,1)==LUA_TNUMBER) + *GameFlags=(DWORD)lua_tointeger(L,1); + lua_pushnumber(L,Old); + return 1; +} +int bitOrL(lua_State *L) +{ + int R; + if(lua_type(L,1)!=LUA_TNUMBER) + return 0; + if(lua_type(L,2)!=LUA_TNUMBER) + return 0; + R=(lua_tointeger(L,1) | lua_tointeger(L,2)) ; + lua_pushinteger(L,R); + return 1; +} +int bitAndL(lua_State *L) +{ + int R; + if(lua_type(L,1)!=LUA_TNUMBER) + return 0; + if(lua_type(L,2)!=LUA_TNUMBER) + return 0; + R=lua_tointeger(L,1) & lua_tointeger(L,2) ; + lua_pushnumber(L,R); + return 1; +} + +int bitXorL(lua_State *L) +{ + int R; + if(lua_type(L,1)!=LUA_TNUMBER) + return 0; + if(lua_type(L,2)!=LUA_TNUMBER) + return 0; + R=lua_tointeger(L,1) ^ lua_tointeger(L,2) ; + lua_pushnumber(L,R); + return 1; +} + + +int printL(lua_State *L) +{ + int n=lua_gettop(L); + int i=0; + TString Rz; + const char *c; +// WCHAR Char; + for(i=1;i<=n;i++) + { + lua_pushvalue(L,i); + c=lua_tostring(L,-1); + lua_pop(L,1); +/* if(c!=NULL) + { + while(*c!=0) + { + mbtowc(&Char,c,1); + Rz+=Char; + c++; + } + }*/ + if(c!=NULL) + Rz.append(c); + + //Rz+=mbstowcs + //Rz + } + lua_Debug ar; + if (0==lua_getstack (L, 1, &ar)) /// Достаем прошлую переменную окружения, чтобы читать данные оттуда + lua_pushnil(L); + else + lua_getinfo(L, "f", &ar); + if (!lua_isnil(L, -1)) + lua_getfenv(L,-1); + if (lua_type(L,-1)==LUA_TTABLE) + { + lua_getfield(L,-1,"conOutput"); + } + if (lua_type(L,-1)==LUA_TNIL) + { + printI(Rz.c_str()); + } + else if(lua_type(L,-1)==LUA_TFUNCTION) + { + lua_pushlstring(L,Rz.c_str(),Rz.size()); + if (0!=lua_pcall(L,1,0,0)) + { + Rz.assign("Error in print:"); + Rz.append(lua_tostring(L,-1)); + printI(Rz.c_str()); + } + } + else + { + lua_getfield(L,-1,"print"); + lua_pushlstring(L,Rz.c_str(),Rz.size()); + if (0!=lua_pcall(L,1,0,0)) + { + Rz.assign("Error in print:"); + Rz.append(lua_tostring(L,-1)); + printI(Rz.c_str()); + } + } + return 0; +} +void InjectJumpTo(DWORD Addr,void *Fn)// Пишем по данному адресу переход на нашу функцию +{ + BYTE *To=(BYTE *)Addr; + DWORD *Dw=(DWORD*)(To+1); + DWORD Delta=(DWORD)Fn; + Delta-=4+(DWORD)Dw; + DWORD OldProtect; + VirtualProtect(To,5,PAGE_EXECUTE_READWRITE,&OldProtect); + *Dw=Delta; + *(To++)=0xE9; + VirtualProtect(To,5,OldProtect,&OldProtect); +}; +void InjectOffs(DWORD Addr,void *Fn)// Пишем по данному адресу - адрес нашей функции c вычислением +{ + DWORD *Dw=(DWORD*)(Addr); + DWORD Delta=(DWORD)Fn; + Delta-=4+(DWORD)Dw; + DWORD OldProtect; + VirtualProtect(Dw,4,PAGE_EXECUTE_READWRITE,&OldProtect); + *Dw=Delta; + VirtualProtect(Dw,4,OldProtect,&OldProtect); +} +void InjectAddr(DWORD Addr,void *Fn)// Пишем по данному адресу - адрес нашей функции +{ + DWORD *Dw=(DWORD*)(Addr); + DWORD Delta=(DWORD)Fn; + DWORD OldProtect; + VirtualProtect(Dw,4,PAGE_EXECUTE_READWRITE,&OldProtect); + *Dw=Delta; + VirtualProtect(Dw,4,OldProtect,&OldProtect); +} +void InjectData(DWORD offset, byte* buff, size_t size) +{ + byte *addr = (byte*)(offset); + DWORD OldProtect; + VirtualProtect(addr, size, PAGE_EXECUTE_READWRITE, &OldProtect); + memcpy(addr, buff, size); + VirtualProtect(addr, 4, OldProtect, &OldProtect); +} + +#include +int (__cdecl *noxGetUnitsInRect)(FloatRect *Rect, void (__cdecl *SomeFn)(void *Unit, void *Arg), void *Arg); + +DWORD *frameCounter=(DWORD*)0x0084EA04; +DWORD *idGold=(DWORD*)0x00750714; + +#include +int *scriptStackSize=(int *)0x0075AE40; +std::vector scriptValues; + +int (__cdecl *noxThingTypeByName)(char const *Name); +const char *(__cdecl *noxThingNameByType)(int Type); + +namespace +{ + + void (__cdecl *oldCreateAtPart)(); + void __cdecl noxMyCreateAt(unitBigStructPtr Obj,unitBigStructPtr Parent, float X,float Y) + { + __asm{ + push Y + push X + push Parent + push Obj + push offset l1 + mov eax,0x00750714 + mov eax,[eax] + jmp oldCreateAtPart + l1: + add esp,16 // 4-е параметра + } + lua_getglobal(L,"noxOnCreateAt"); + if(lua_type(L,-1)!=LUA_TFUNCTION) + { + lua_pop(L,1); + return ; + } + lua_pushlightuserdata(L,Obj); + lua_pushlightuserdata(L,Parent); + lua_pushnumber(L,X); + lua_pushnumber(L,Y); + if(0!=lua_pcall(L,4,0,0)) + { + lua_pop(L,1); + } + return ; + } +/* + DWORD __cdecl newScriptPushValue(void *Value) + { + int SP=*(scriptStackSize); + if(scriptValues.size()<=SP) + { + scriptValues.resize(SP+1); + } + scriptValues[SP]=Value; + (*scriptStackSize)++; + return SP; + } + void *__cdecl newScriptPopValue() + { + int SP=(*scriptStackSize); + if(SP>0) + { + (*scriptStackSize)--; + SP--; + } + if(scriptValues.size()<=SP) + { + DebugBreak(); + return NULL; + } + + return scriptValues[SP]; + } +*/ + void getUnitsAroundImpl(void *Unit, void *L_) + { + lua_State *LL=(lua_State *)L_; + lua_pushvalue(L,1); + lua_pushlightuserdata(LL,Unit); + if(0!=lua_pcall(LL,1,0,0)) + lua_error_(LL); + } + int getPtrPtrL(lua_State *L) + { + if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA)||(lua_type(L,2)!=LUA_TNUMBER) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + BYTE* P=(BYTE*) lua_touserdata(L,1); + lua_pushnil(L); + if(P==NULL) + return 1; + P=*((BYTE**)(P+lua_tointeger(L,2) )); + if(P==NULL) + return 1; + lua_pushlightuserdata(L, P); + return 1; + } + int getPtrByteL(lua_State *L) + { + if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA)||(lua_type(L,2)!=LUA_TNUMBER) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + BYTE* P=(BYTE*) lua_touserdata(L,1); + if(P==NULL) + return 0; + P+=lua_tointeger(L,2); + lua_pushinteger(L, *((BYTE*)P)); + return 1; + } + int getPtrIntL(lua_State *L) + { + if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA)||(lua_type(L,2)!=LUA_TNUMBER) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + BYTE* P=(BYTE*) lua_touserdata(L,1); + if(P==NULL) + return 0; + P+=lua_tointeger(L,2); + lua_pushinteger(L, *((int*)P)); + return 1; + } + int getPtrShortL(lua_State *L) + { + if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA)||(lua_type(L,2)!=LUA_TNUMBER) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + BYTE* P=(BYTE*) lua_touserdata(L,1); + if(P==NULL) + return 0; + P+=lua_tointeger(L,2); + lua_pushinteger(L, *((USHORT*)P)); + return 1; + } + int getPtrFloatL(lua_State *L) + { + if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA)||(lua_type(L,2)!=LUA_TNUMBER) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + BYTE* P=(BYTE*) lua_touserdata(L,1); + if(P==NULL) + return 0; + P+=lua_tointeger(L,2); + lua_pushnumber(L, *((float*)P)); + return 1; + } + int setPtrFloatL(lua_State *L) + { + if ( ((lua_type(L,1)!=LUA_TLIGHTUSERDATA)&& (lua_type(L,1)!=LUA_TNIL)) + ||(lua_type(L,2)!=LUA_TNUMBER) + ||(lua_type(L,3)!=LUA_TNUMBER)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + BYTE* P=(BYTE*) lua_touserdata(L,1); + if(P==NULL) return 0; + P+=lua_tointeger(L,2); + DWORD Pt=(DWORD)P; + DWORD OldProtect; + if( ((lua_type(L,1)==LUA_TNIL)) &&( (Pt<0x400000) || (Pt>0x600000) ) ) + { + lua_pushstring(L,"wrong offset!"); + lua_error_(L); + } + VirtualProtect(P,4,PAGE_EXECUTE_READWRITE,&OldProtect); + *((float*)P) = lua_tonumber(L,3 ); + VirtualProtect(P,4,OldProtect,&OldProtect); + return 0; + } + int setPtrByteL(lua_State *L) + { + if ( ((lua_type(L,1)!=LUA_TLIGHTUSERDATA)&& (lua_type(L,1)!=LUA_TNIL)) + ||(lua_type(L,2)!=LUA_TNUMBER) + ||(lua_type(L,3)!=LUA_TNUMBER)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + BYTE* P=(BYTE*) lua_touserdata(L,1); + if(P==NULL) return 0; + P+=lua_tointeger(L,2); + DWORD Pt=(DWORD)P; + DWORD OldProtect; + if( ((lua_type(L,1)==LUA_TNIL)) &&( (Pt<0x400000) || (Pt>0x600000) ) ) + { + lua_pushstring(L,"wrong offset!"); + lua_error_(L); + } + VirtualProtect(P,4,PAGE_EXECUTE_READWRITE,&OldProtect); + *((BYTE*)P) = lua_tointeger(L,3 ); + VirtualProtect(P,4,OldProtect,&OldProtect); + return 1; + } + int setPtrIntL(lua_State *L) + { + if ( ((lua_type(L,1)!=LUA_TLIGHTUSERDATA)&& (lua_type(L,1)!=LUA_TNIL)) + ||(lua_type(L,2)!=LUA_TNUMBER) + ||(lua_type(L,3)!=LUA_TNUMBER)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + BYTE* P=(BYTE*) lua_touserdata(L,1); + if (P==NULL) + return 0; + P+=lua_tointeger(L,2); + DWORD Pt=(DWORD)P; + DWORD OldProtect; + if( ((lua_type(L,1)==LUA_TNIL)) &&( (Pt<0x400000) || (Pt>0x600000) ) ) + { + lua_pushstring(L,"wrong offset!"); + lua_error_(L); + } + VirtualProtect(P,4,PAGE_EXECUTE_READWRITE,&OldProtect); + *((int*)P) = lua_tointeger(L,3 ); + VirtualProtect(P,4,OldProtect,&OldProtect); + return 0; + } + int setPtrShortL(lua_State *L) + { + if ( ((lua_type(L,1)!=LUA_TLIGHTUSERDATA)&& (lua_type(L,1)!=LUA_TNIL)) + ||(lua_type(L,2)!=LUA_TNUMBER) + ||(lua_type(L,3)!=LUA_TNUMBER)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + BYTE* P=(BYTE*) lua_touserdata(L,1); + if(P==NULL) return 0; + P+=lua_tointeger(L,2); + DWORD Pt=(DWORD)P; + DWORD OldProtect; + if( ((lua_type(L,1)==LUA_TNIL)) &&( (Pt<0x400000) || (Pt>0x600000) ) ) + { + lua_pushstring(L,"wrong offset!"); + lua_error_(L); + } + VirtualProtect(P,4,PAGE_EXECUTE_READWRITE,&OldProtect); + *((USHORT*)P) = lua_tointeger(L,3 ); + VirtualProtect(P,4,OldProtect,&OldProtect); + return 0; + } + int setPtrPtrL(lua_State *L) + { + if ( ((lua_type(L,1)!=LUA_TLIGHTUSERDATA) && (lua_type(L,1)!=LUA_TNIL)) + ||(lua_type(L,2)!=LUA_TNUMBER) + ||(lua_type(L,3)!=LUA_TLIGHTUSERDATA)) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + BYTE* P=(BYTE*) lua_touserdata(L,1); + if (P==NULL) + return 0; + P+=lua_tointeger(L,2); + DWORD Pt=(DWORD)P; + DWORD OldProtect; + if( ((lua_type(L,1)==LUA_TNIL)) &&( (Pt<0x400000) || (Pt>0x600000) ) ) + { + lua_pushstring(L,"wrong offset!"); + lua_error_(L); + } + VirtualProtect(P,4,PAGE_EXECUTE_READWRITE,&OldProtect); + *((void**)P) = lua_touserdata(L,3 ); + VirtualProtect(P,4,OldProtect,&OldProtect); + return 0; + } + int getUnitClassL(lua_State *L) + { + if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + BYTE* P=(BYTE*) lua_touserdata(L,1); + if(P==NULL) + { + lua_pushnil(L); + return 0; + } + if((lua_gettop(L)>1) && (lua_type(L,2)==LUA_TNUMBER)) + { + lua_pushboolean(L, lua_tointeger(L,2) & (*((int*)(P+0x8))) ); + return 1; + } + lua_pushinteger(L, *((int*)(P+0x8)) ); + return 1; + } + int getUnitFlagsL(lua_State *L) + { + if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + BYTE* P=(BYTE*) lua_touserdata(L,1); + if(P==NULL) + { + lua_pushinteger(L,0); + return 0; + } + if((lua_gettop(L)>1) && (lua_type(L,2)==LUA_TNUMBER)) + { + lua_pushboolean(L, lua_tointeger(L,2) & (*((int*)(P+0x10))) ); + return 1; + } + lua_pushinteger(L, *((int*)(P+0x10)) ); + return 1; + } + int getThingTypeL(lua_State *L) + { + if((lua_type(L,1)==LUA_TSTRING) ) + { + int R=noxThingTypeByName(lua_tostring(L,1)); + if(R>=0) + lua_pushinteger(L,R); + else + lua_pushnil(L); + return 1; + } + else if ( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + BYTE* P=(BYTE*) lua_touserdata(L,1); + if(P==NULL) + { + lua_pushnil(L); + return 1; + } + lua_pushinteger(L, *((WORD*)(P+4)) ); + return 1; + } + + int setThingTypeL(lua_State *L) + { + int R=0; + if (lua_type(L,1)!=LUA_TLIGHTUSERDATA) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + if (lua_type(L,2)==LUA_TNUMBER) + { + R=lua_tointeger(L,2); + } + else if(lua_type(L,2)==LUA_TNUMBER) + R=noxThingTypeByName(lua_tostring(L,2)); + if(R<=0) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + + BYTE* P=(BYTE*) lua_touserdata(L,1); + if(P==NULL) + return 0; + *((WORD*)(P+4))=(WORD)R; + return 0; + } + + int getClassNameL(lua_State *L) + { + const char *R; + if (lua_type(L,1)==LUA_TNUMBER) + { + R=noxThingNameByType(lua_tointeger(L,1)); + if(R!=0) + lua_pushstring(L, R); + else + lua_pushnil(L); + return 1; + } + else if( (lua_type(L,1)!=LUA_TLIGHTUSERDATA) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + BYTE* P=(BYTE*) lua_touserdata(L,1); + if(P==NULL) + return 0; + R=noxThingNameByType(*((WORD*)(P+4))) ; + if(R!=0) + lua_pushstring(L, R); + else + lua_pushnil(L); + return 1; + } + int getUnitsAround(lua_State *L) + { + if ( + (lua_gettop(L)!=5)|| + (lua_type(L,1)!=LUA_TFUNCTION) || + (lua_type(L,2)!=LUA_TNUMBER) || + (lua_type(L,3)!=LUA_TNUMBER) || + (lua_type(L,4)!=LUA_TNUMBER) || + (lua_type(L,5)!=LUA_TNUMBER) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + return 0; + } + noxGetUnitsInRect( + &FloatRect( + lua_tonumber(L,2), + lua_tonumber(L,3), + lua_tonumber(L,4), + lua_tonumber(L,5) ) + ,&getUnitsAroundImpl,L); + return 0; + } +////// + LPTOP_LEVEL_EXCEPTION_FILTER OldFilter=0; + char exAppName[MAX_PATH]=""; + char exCmdLine[MAX_PATH]=""; + char exCurDir[MAX_PATH]=""; + + int ExceptionMode=0; + int setExMode(lua_State *L) + { + lua_settop(L,3); + lua_pushinteger(L,ExceptionMode); + ExceptionMode=lua_tointeger(L,3); + return 1; + } + // 0 - ничего не делать(как обычно) + // 1 - записать в log и закрытся + // 2 - записать в log и рестартовать нокс + // + LONG WINAPI ExceptionFilter( + _EXCEPTION_POINTERS *EI + ) + { + static char Buf[1024]; + char *P=Buf; + int L=0; + int Remain=sizeof(Buf)-1; + if (ExceptionMode==0) + { + if (OldFilter!=NULL) + return OldFilter(EI); + } + L=_snprintf(P,Remain,"=========\n== %8d\nE 0x%08x at 0x%08x, Esp: 0x%08x\nStack:\n",_time32(NULL), + EI->ExceptionRecord->ExceptionCode,EI->ExceptionRecord->ExceptionAddress,EI->ContextRecord->Esp); + P+=L;Remain-=L; + DWORD *DW=(DWORD*)EI->ContextRecord->Esp; + for (int i=0;i<32;i++) + { + if (IsBadReadPtr(DW,4)) + break; + if (Remain<4) + break; + L=_snprintf(P,Remain,"0x%08x\n",*(DW++)); + P+=L;Remain-=L; + } + L=_snprintf(P,Remain,"== END ==\n"); + P+=L;Remain-=L; + FILE *F=fopen("UniErrorLog.txt","a+"); + if (F!=NULL) + { + fwrite(Buf,P-Buf,1,F); + fclose(F); + } +// MessageBox(0,Buf,0,0); + if (ExceptionMode==2) + { +// static char Buf[1024]; +// sprintf(Buf,"%s\n%s\n%s",exAppName,exCmdLine,exCurDir); +// MessageBox(0,Buf,0,0); + static STARTUPINFO SI={0}; + static PROCESS_INFORMATION PI={0}; + SI.cb=sizeof(SI); + Sleep(0); + CreateProcess(exAppName,exCmdLine,NULL,NULL,FALSE,0,NULL,exCurDir,&SI,&PI); + CloseHandle(PI.hProcess); + CloseHandle(PI.hThread); + } + ExitProcess(-1); + return 0; + } + void exInit() + { + GetModuleFileName (NULL,exAppName,MAX_PATH); + const char *Cmd=GetCommandLine(); + strncpy(exCmdLine,Cmd,MAX_PATH-1); + GetCurrentDirectory(MAX_PATH,exCurDir); + OldFilter=SetUnhandledExceptionFilter(&ExceptionFilter); + + } + +//// + + int timeoutNextId=1; + struct TimeoutListRec + { + int Id; + DWORD Frame; + bool Persist; + TimeoutListRec(int Id_, DWORD Frame_, bool Persist_) :Id(Id_), Frame(Frame_), Persist(Persist_) + {} + }; + std::list timeoutList; + int setTimeoutL(lua_State *L) /// теперь получает 3-й аргумент - таблицу и 4-ый - следует ли сохранять при смене карты + { + lua_settop(L,4); + if ((lua_type(L,1)!=LUA_TFUNCTION) ||(lua_type(L,2)!=LUA_TNUMBER) + || ((lua_type(L,3)!=LUA_TTABLE) && (lua_type(L,3)!=LUA_TNIL)) + || ((lua_type(L,4)!=LUA_TBOOLEAN) && (lua_type(L,4)!=LUA_TNIL)) + ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + lua_pushlightuserdata(L,setTimeoutL);/// функции + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushinteger(L,timeoutNextId); + lua_pushvalue(L,1); + lua_settable(L,-3); + lua_pushlightuserdata(L,&timeoutNextId);/// сюда положим таблицу + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushinteger(L,timeoutNextId); + lua_pushvalue(L,3); + lua_settable(L,-3); + + bool ispersistant = lua_toboolean(L, 4); + lua_pushinteger(L,timeoutNextId); + + DWORD Time=*frameCounter +(DWORD)lua_tointeger(L,2); + + std::list::iterator I; + for (I=timeoutList.begin();I!=timeoutList.end();I++) + { + if(I->Frame > Time) + break; + } + timeoutList.insert(I, TimeoutListRec(timeoutNextId++, Time, ispersistant)); + return 1; + } + void (__cdecl *sub51ADF0)();/// событие проверки скриптов карты по таймауту + int getFrameCounterL(lua_State *L) + { + lua_pushinteger(L,(int)*frameCounter); + return 1; + } + void __cdecl onEachFrame() + { + replayEachFrame(); + if(specialAuthorisation) + for(int i=0; i<0x20; i++) + { + if(authSendWelcomeMsg[i]==1) + authSendWelcomeMsg[i]=-2; + if(authSendWelcomeMsg[i]>0) + authSendWelcomeMsg[i]--; + if(authSendWelcomeMsg[i]<0) + { + if(authorisedState[i]==4) + netSendChatMessage("You have been authorised! Now you can quit the observer mode and play.", i); + if(authorisedState[i]==2) + netSendChatMessage("Now please enter your password. For best security prefix it with '//auth '.", i); + if(authorisedState[i]==3) + netSendChatMessage("Thank you, we have got your login and password. Please wait a while before we check them...", i); + if(authorisedState[i]==1) + netSendChatMessage("Something weird happened and we couldn't authorise you. Probably you have misspelled your login and password? Please try again. Enter your login. For best security prefix it with '//auth '.", i); + if(authorisedState[i]==0) + { + authorisedState[i]++; + netSendChatMessage("Welcome to our server! Please enter your login in a chat message to proceed. You can't play without having a registered account! For best security prefix it with '//auth '.", i); + } + authSendWelcomeMsg[i]=0; + } + } + serverUpdate(); + DWORD Time = *frameCounter; + int Top = lua_gettop(L); + lua_pushlightuserdata(L, &timeoutNextId);/// таблица аргументов + lua_gettable(L, LUA_REGISTRYINDEX); + lua_pushlightuserdata(L, setTimeoutL);/// таблица функций + lua_gettable(L, LUA_REGISTRYINDEX); + + for (std::list::iterator I = timeoutList.begin(); I != timeoutList.end();) + { + if (Time < I->Frame) + { + I++; + } + else + { + lua_pushinteger(L, I->Id); + lua_gettable(L, -2); + if (lua_type(L, -1) == LUA_TFUNCTION) + { + lua_getfenv(L, -1); + lua_pushvalue(L, -2); + lua_getfield(L, -2, "conOutput");// conOutput функция енв функция + lua_insert(L, -2);// функция conOutput енв функция + lua_pushnil(L); + lua_setfield(L, -4, "conOutput"); + + lua_pushinteger(L, Time); + lua_pushinteger(L, I->Id); + // таблица с аргументом + lua_gettable(L, -8); // id,Time,Fn, conOutput, env, fn, {Fns},{Args} + if (0 != lua_pcall(L, 2, 0, 0)) + { + const char* errorStr = lua_tostring(L, -1); + char Err[200]; + strcpy(Err, "delayed error: "); + strncat(&Err[strlen(Err)], errorStr, (199 - strlen(Err))); + conPrintI(Err); + lua_pop(L, 1); + } + ///conOutput,env, fn, {Fns},{Args} + lua_getfield(L, -2, "conOutput");// conOutput функция енв функция + if (lua_type(L, -1) == LUA_TNIL) // если задали другую функцию - то так и оставим, но как ее обнулить? + { + lua_pop(L, 1); + lua_setfield(L, -2, "conOutput"); + lua_pop(L, 2); + } + else + lua_pop(L, 3); + + lua_pushinteger(L, I->Id); // чтобы было чего удалять + } + else + lua_pop(L, 1); + + lua_pushnil(L); + lua_settable(L, -3); // удаляем функцию + lua_pushinteger(L, I->Id); + lua_pushnil(L); + lua_settable(L, -4);// удаляем аргумент + + I = timeoutList.erase(I); + } + } + lua_settop(L, Top); + sub51ADF0(); + } + + int memFreeL(lua_State *L) + { + if ((lua_type(L,1)!=LUA_TUSERDATA) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + void *P=lua_touserdata(L,1); + if(P!=0) + noxFree(P); + return 0; + } + + int memAllocL(lua_State *L) + { + if ((lua_type(L,1)!=LUA_TNUMBER) ) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + int Size=lua_tonumber(L,1); + if (Size<=0) + { + lua_pushstring(L,"wrong args!"); + lua_error_(L); + } + void *P=noxAlloc(Size); + lua_pushlightuserdata(L,P); + return 1; + } +}; +void mapUnloadUtil() +{ + for (std::list::iterator I = timeoutList.begin(); I != timeoutList.end();) + { + if (I->Persist == false) + { + I=timeoutList.erase(I); + } + else + { + I++; + } + } + DWORD Time = *frameCounter; +} + +void lua_error_(lua_State*L) +{ + int T=lua_gettop(L); + lua_getglobal(L,"debug"); + lua_getfield(L,-1,"traceback"); + if (lua_type(L,-1)==LUA_TFUNCTION) + lua_call(L,0,0); + lua_settop(L,T); + lua_error(L); +} + +extern void initSDL(); +extern void windowsAllInit(); +extern void unitFunctionInit(); +extern void mapInit(); +extern void reactInit(); +extern void spellsInit(); +extern void netInit(); +extern void keysInit(); +extern void consoleInit(); +extern void playerFunctionInint(); +extern void spriteInit(); +extern void spellListInit(); +extern void clientViewInit(); +extern void unitDefsInit(); +extern void tilesInit(); +extern void cliUntilInit(); +extern bool initAuthData(); +extern void polygonInit(); +extern void bugsInit(); +extern void autoServer(); +extern "C" void scoreInit(lua_State *L); +extern "C" void replayInit(lua_State *L); + +extern "C" void initAudServer(lua_State *L); + +extern void guiInit(); +extern void waypointsInit(); +extern char *(__cdecl *mapGetName)(); + +extern DWORD __cdecl onConCmd(wchar_t *A,DWORD B); +extern void initModLib2(); +extern void initFilesystem(); + +extern "C" void adminInit(lua_State *L); +//extern "C" void authInit(lua_State *L); +extern "C" int luaopen_lpeg (lua_State *L); +extern "C" void mapUtilInit(lua_State*L); +extern bool serverUpdate(); + +int initWindowedMode(int param1, int param2, int param3) +{ + DEVMODE devMode; + EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devMode); + if(devMode.dmBitsPerPel>16) + { + devMode.dmBitsPerPel=16; + devMode.dmFields = DM_BITSPERPEL; + } + int result = ChangeDisplaySettings(&devMode, CDS_FULLSCREEN); + return initWindowedModeNox(param1, param2, param3); +} + +void injectCon() +{ + initSDL(); + //MessageBox(0,"!",0,0); + exInit(); + initModLib2(); + luaopen_lpeg (L); + ASSIGN(consolePrint,0x00450B90); + ASSIGN(printCentered,0x00445490); + ASSIGN(sub51ADF0,0x0051ADF0); + ASSIGN(noxGetUnitsInRect,0x00517C10); + ASSIGN(oldCreateAtPart,0x004DAA55);// Возврат + ASSIGN(noxAlloc,0x00403560); + ASSIGN(noxCAlloc,0x004041D0); + ASSIGN(noxFree,0x0040425D); + + gameDirectory=(char*)0x005D4B08; + + InjectJumpTo(0x004DAA50,&noxMyCreateAt); + +// InjectJumpTo(0x00507250,&newScriptPopValue); +// InjectJumpTo(0x00507230,&newScriptPushValue); + + ASSIGN(noxThingTypeByName,0x4E3AA0); + ASSIGN(noxThingNameByType,0x4E3A80); + + int Top=lua_gettop(L); + lua_pushcfunction(L,&frameLimiter); + lua_setglobal(L,"frameLimiter"); + lua_pushcfunction(L,&bitOrL); + lua_setglobal(L,"bitOr"); + lua_pushcfunction(L,&bitAndL); + lua_setglobal(L,"bitAnd"); + lua_pushcfunction(L,&bitXorL); + lua_setglobal(L,"bitXor"); + + luaL_dostring(L,"math.randomseed( os.time() )"); + + lua_createtable(L,0,40);/// Client enviroment + lua_newtable(L); + lua_pushvalue(L,LUA_GLOBALSINDEX); + lua_setfield(L,-2,"__index"); + lua_setmetatable(L,-2);/// теперь клиент пронаследован от _G + lua_pushvalue(L,-1); + lua_setfield(L,LUA_REGISTRYINDEX,"client"); + + lua_newtable(L); /// таблица meta2 + lua_pushvalue(L,-2); + lua_setfield(L,-2,"__index"); + // meta2,client + lua_createtable(L,0,40);/// Server enviroment + lua_pushvalue(L,-2); + lua_setmetatable(L,-2);/// теперь сервер пронаследован от клиента + lua_setfield(L,LUA_REGISTRYINDEX,"server"); + + lua_pushcfunction(L,&setTimeoutL); + // очень важная функция, ее надо в реестр луа класть + // чтобы нельзя было удалить случайно + lua_pushvalue(L,-1); + lua_setfield(L,LUA_REGISTRYINDEX,"setTimeout"); + registerServerVar("setTimeout"); + registerserver("setExMode",&setExMode); + registerserver("unitGetAround",&getUnitsAround); + + lua_pushcfunction(L,&printL); + lua_setglobal(L,"print"); + lua_pushcfunction(L,&getFrameCounterL); + lua_setglobal(L,"getFrameCounter"); + lua_pushcfunction(L,&setGameFlagsL); + lua_setglobal(L,"gameFlags"); + lua_getglobal(L,"string"); + lua_getfield(L,-1,"format"); + lua_setglobal(L,"printf"); + lua_pop(L,1); + lua_pushlightuserdata(L,&setTimeoutL); + lua_newtable(L); + lua_settable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,&timeoutNextId); + lua_newtable(L); + lua_settable(L,LUA_REGISTRYINDEX); + + lua_pushcfunction(L,&getThingTypeL); + lua_setglobal(L,"getThingType"); + lua_pushcfunction(L,&setThingTypeL); + lua_setglobal(L,"setThingType"); + + lua_pushcfunction(L,&getClassNameL); + lua_setglobal(L,"getThingName"); + + registerserver("unitClass",&getUnitClassL); + registerserver("unitFlags",&getUnitFlagsL); + + + lua_pushcfunction(L,&getPtrPtrL); + lua_setglobal(L,"getPtrPtr"); + lua_pushcfunction(L,&getPtrIntL); + lua_setglobal(L,"getPtrInt"); + lua_pushcfunction(L,&getPtrFloatL); + lua_setglobal(L,"getPtrFloat"); + lua_pushcfunction(L,&getPtrShortL); + lua_setglobal(L,"getPtrShort"); + lua_pushcfunction(L,&setPtrFloatL); + lua_setglobal(L,"setPtrFloat"); + lua_pushcfunction(L,&setPtrIntL); + lua_setglobal(L,"setPtrInt"); + lua_pushcfunction(L,&setPtrPtrL); + lua_setglobal(L,"setPtrPtr"); + lua_pushcfunction(L,&setPtrShortL); + lua_setglobal(L,"setPtrShort"); + lua_pushcfunction(L,&setPtrByteL); + lua_setglobal(L,"setPtrByte"); + lua_pushcfunction(L,&getPtrByteL); + lua_setglobal(L,"getPtrByte"); + + lua_pushcfunction(L,&memAllocL); + lua_setglobal(L,"memAlloc"); + lua_pushcfunction(L,&memFreeL); + lua_setglobal(L,"memFree"); + + mapUtilInit(L); + initFilesystem(); + consoleInit(); + adminInit(L); + //authInit(L); + initAuthData(); + initAudServer(L); + reactInit(); + + windowsAllInit(); + clientViewInit(); + unitFunctionInit(); + mapInit(); + tilesInit(); + unitDefsInit(); + spellsInit(); + netInit(); + keysInit(); + playerFunctionInint(); + spriteInit(); + spellListInit(); + guiInit(); + scoreInit(L); + replayInit(L); + waypointsInit(); + cliUntilInit(); + polygonInit(); + bugsInit(); + autoServer(); + + InjectJumpTo(0x00443C80,&onConCmd);// Функция реакции на консольную команду + InjectOffs(0x4D2AB5,&onEachFrame); + + InjectOffs(0x00443A81+1, &tokenParseFixup); + InjectOffs(0x00443A71+1, &tokenParseCipherFixup); + + ASSIGN(initWindowedModeNox,0x0048AED0); + + + InjectOffs(0x48A0C2+1,&initWindowedMode); + + ASSIGN(frameLimiterSetting,0x0059449C); + ASSIGN(j_time,0x00416BF0); + ASSIGN(consoleTokenCipher, 0x00443BF0); + +#include "lua/binClient/clientOnJoin.lua.inc" + + lua_getfield(L,LUA_REGISTRYINDEX,"client"); + lua_setfenv(L,-2); + lua_pcall(L,0,0,0); +#include "lua/binServer/chatMode.lua.inc" + lua_getfield(L,LUA_REGISTRYINDEX,"server"); + lua_setfenv(L,-2); + lua_pcall(L,0,0,0); +#include "lua/binGlobal/dofile.lua.inc" + +#include "lua/binGlobal/filesystem.inc.lua.inc" + + lua_settop(L,Top); + + //lua_pushnil(L); + //lua_setglobal(L,"os");/// выкинуть вон небезопасную таблицу + + + int topLoad = lua_gettop(L); + + lua_getfield(L, LUA_REGISTRYINDEX, "require.lua"); + if (lua_isfunction(L, -1)) + { + lua_getfield(L, LUA_REGISTRYINDEX, "server"); + lua_setfenv(L, -2); + int err = lua_pcall(L, 0, 0, 0); + if (err != 0) + { + const char* errorMsg = lua_tostring(L, -1); + MessageBoxA(NULL, errorMsg, "LUA load error! The file won't be loaded!", MB_OK); + return; + } + //lua_pushstring(L, "require.lua"); + //lua_pushstring(L, mode); + //lua_settable(L, LUA_REGISTRYINDEX); + } + + lua_settop(L, topLoad); + + if (0==luaL_loadfile(L, "autoexec.lua")) + { + lua_getfield(L,LUA_REGISTRYINDEX,"server"); + lua_setfenv(L,-2); + lua_pcall(L, 0, 0, 0); + } + + + //MessageBox(0,"!",0,0); + + byte OperatorJmps=0xEB; + byte OperatorMovEax1[]={0xB8,0x01,0,0,0}; + byte OperatorNop[]={0x90,0x90}; + byte *bt=(byte*)(0x00553660); + byte *bt2=(byte*)(0x00401E06); + byte *bt3=(byte*)(0x00401114); + byte *bt4=(byte*)(0x0043E82B); + DWORD OldProtect; + VirtualProtect(bt,1,PAGE_EXECUTE_READWRITE,&OldProtect); + memcpy((byte*)bt,&OperatorJmps,1); // это убираем серийник + VirtualProtect(bt,1,OldProtect,&OldProtect); + VirtualProtect(bt2,1,PAGE_EXECUTE_READWRITE,&OldProtect); + memcpy((byte*)bt2,&OperatorJmps,1); // это на запуск 2 -ух ноксов + VirtualProtect(bt2,1,OldProtect,&OldProtect); + VirtualProtect(bt3,5,PAGE_EXECUTE_READWRITE,&OldProtect); + memcpy((byte*)bt3,&OperatorMovEax1,5); // убиваем мутекс + VirtualProtect(bt3,5,OldProtect,&OldProtect); + VirtualProtect(bt4,2,PAGE_EXECUTE_READWRITE,&OldProtect); + memcpy((byte*)bt4,&OperatorNop,2); // чиним прожорливость Нокса и архитектурный изъян. + VirtualProtect(bt4,2,OldProtect,&OldProtect); + + // Убиваем (или чиним?...) сисоп-закладку: + InjectAddr(0x444158 + 1, &hostIdx); + + registerclient("getGameDirectory", &getGameDirectoryL); + registerclient("getNormalizedPath", &getNormalizedPathL); + registerclient("getDirectoryListing", &getDirectoryListingL); }; \ No newline at end of file diff --git a/windowMsg.cpp b/windowMsg.cpp index 2d3f56d..2b7dc86 100644 --- a/windowMsg.cpp +++ b/windowMsg.cpp @@ -1,179 +1,179 @@ -#include "stdafx.h" -#include "windowUniMod.h" - -/* -==== -0x400F - clear -0x400D - -=== -0x4016 - - , (ArgA - ) - -==== - -0x4010 - - - -==== -0x401F - Enter -*/ - - -namespace -{ - int editBoxGetText(lua_State *L) - { - wndStruct *H=wndGetHandleByLua(1); - if(H==0 || ((H->drawData.controlType & ctEditBox)==0)) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - wchar_t *R=(wchar_t*) noxCallWndProc(H,0x401D,0,0);/// - if(R==0) - { - lua_pushnil(L); - return 1; - } - int Len=wcslen(R); - char *Buf=new char[Len+1]; - Buf[Len]=0; - wcstombs(Buf,R,Len); - lua_pushstring(L,Buf); - delete Buf; - return 1; - } - int editBoxSetText(lua_State *L) - { - wndStruct *H=wndGetHandleByLua(1); - if(H==0 || lua_type(L,2)!=LUA_TSTRING || ((H->drawData.controlType & ctEditBox)==0)) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - size_t Len; - const char *R; - R=lua_tolstring(L,2,&Len); - if (R==NULL || Len==0) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - wchar_t *Buf=new wchar_t[Len+1]; - mbstowcs(Buf,R,Len); - Buf[Len]=0; - noxCallWndProc(H,0x401E,(int)(Buf),-1);/// - delete Buf; - lua_pushvalue(L,1); - return 1; - } - int buttonSetText(lua_State *L) - { - wndStruct *H=wndGetHandleByLua(1); - if(H==0 || lua_type(L,2)!=LUA_TSTRING || ((H->drawData.controlType & ctPushButton)==0)) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - size_t Len; - const char *R; - R=lua_tolstring(L,2,&Len); - if (R==NULL) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - wchar_t *Buf=new wchar_t[Len+1]; - mbstowcs(Buf,R,Len); - Buf[Len]=0; - noxCallWndProc(H,0x4001,(int)(Buf),-1);/// - delete Buf; - lua_pushvalue(L,1); - return 1; - } - - int ListBoxAddText(lua_State *L) - { - wndStruct *H=wndGetHandleByLua(1); - if(H==0 || lua_type(L,2)!=LUA_TSTRING || ((H->drawData.controlType & ctListBox)==0)) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - size_t Len; - const char *R; - R=lua_tolstring(L,2,&Len); - if (R==NULL) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - wchar_t *Buf=new wchar_t[Len+1]; - mbstowcs(Buf,R,Len); - Buf[Len]=0; - noxCallWndProc(H,0x400D,(int)(Buf),-1);/// - delete Buf; - lua_pushvalue(L,1); - return 1; - } - int ListBoxClear(lua_State *L) - { - wndStruct *H=wndGetHandleByLua(1); - if(H==0 || ((H->drawData.controlType & ctListBox)==0)) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - noxCallWndProc(H,0x400F,0,0);/// - return 0; - } - int ListBoxSetLine(lua_State *L) - { - wndStruct *H=wndGetHandleByLua(1); - if ((H==0) || (lua_type(L,2)!=LUA_TNUMBER) || ((H->drawData.controlType & ctListBox)==0)) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - listBoxDataStruct *listBoxData=(listBoxDataStruct*) H->someData; - int idx=lua_tointeger(L,2); - if (idx>=-1 && idx<=listBoxData->maxLines) - listBoxData->lineSelectIdx=lua_tointeger(L,2); - return 0; - } - - int buttonSwitchOff(lua_State *L) - { - wndStruct *H=wndGetHandleByLua(1); - if(H==0 || ((H->drawData.controlType & ctPushButton)==0)) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - H->flags=(H->flags ^ (H->flags & wfEnabled)); - return 0; - } - - int buttonSwitchOn(lua_State *L) - { - wndStruct *H=wndGetHandleByLua(1); - if(H==0 || ((H->drawData.controlType & ctPushButton)==0)) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - H->flags|=wfEnabled; - return 0; - } - -} -void windowMsgInit(lua_State*L) -{ - registerclient("wndGetText",&editBoxGetText); - registerclient("wndSetText",&editBoxSetText);/// - registerclient("wndLbAddText",&ListBoxAddText);/// - registerclient("wndLbClear",&ListBoxClear); - registerclient("wndLbSelectLine",&ListBoxSetLine); - registerclient("wndButtonSetText",&buttonSetText); - registerclient("wndButtonSwitchOn",&buttonSwitchOn); - registerclient("wndButtonSwitchOff",&buttonSwitchOff); - +#include "stdafx.h" +#include "windowUniMod.h" + +/* +====для листа команды +0x400F - clear +0x400D - добавить строчку +===непроверенно +0x4016 - достать какой-то указатель, мб строчку (ArgA - номер) + +====для листа сообщения - +0x4010 - при выделении строчки + + +====для эдита сообщения +0x401F - при Enter +*/ + + +namespace +{ + int editBoxGetText(lua_State *L) + { + wndStruct *H=wndGetHandleByLua(1); + if(H==0 || ((H->drawData.controlType & ctEditBox)==0)) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + wchar_t *R=(wchar_t*) noxCallWndProc(H,0x401D,0,0);///считать строку + if(R==0) + { + lua_pushnil(L); + return 1; + } + int Len=wcslen(R); + char *Buf=new char[Len+1]; + Buf[Len]=0; + wcstombs(Buf,R,Len); + lua_pushstring(L,Buf); + delete Buf; + return 1; + } + int editBoxSetText(lua_State *L) + { + wndStruct *H=wndGetHandleByLua(1); + if(H==0 || lua_type(L,2)!=LUA_TSTRING || ((H->drawData.controlType & ctEditBox)==0)) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + size_t Len; + const char *R; + R=lua_tolstring(L,2,&Len); + if (R==NULL || Len==0) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + wchar_t *Buf=new wchar_t[Len+1]; + mbstowcs(Buf,R,Len); + Buf[Len]=0; + noxCallWndProc(H,0x401E,(int)(Buf),-1);///записать строку + delete Buf; + lua_pushvalue(L,1); + return 1; + } + int buttonSetText(lua_State *L) + { + wndStruct *H=wndGetHandleByLua(1); + if(H==0 || lua_type(L,2)!=LUA_TSTRING || ((H->drawData.controlType & ctPushButton)==0)) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + size_t Len; + const char *R; + R=lua_tolstring(L,2,&Len); + if (R==NULL) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + wchar_t *Buf=new wchar_t[Len+1]; + mbstowcs(Buf,R,Len); + Buf[Len]=0; + noxCallWndProc(H,0x4001,(int)(Buf),-1);///записать строку + delete Buf; + lua_pushvalue(L,1); + return 1; + } + + int ListBoxAddText(lua_State *L) + { + wndStruct *H=wndGetHandleByLua(1); + if(H==0 || lua_type(L,2)!=LUA_TSTRING || ((H->drawData.controlType & ctListBox)==0)) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + size_t Len; + const char *R; + R=lua_tolstring(L,2,&Len); + if (R==NULL) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + wchar_t *Buf=new wchar_t[Len+1]; + mbstowcs(Buf,R,Len); + Buf[Len]=0; + noxCallWndProc(H,0x400D,(int)(Buf),-1);///записать строку + delete Buf; + lua_pushvalue(L,1); + return 1; + } + int ListBoxClear(lua_State *L) + { + wndStruct *H=wndGetHandleByLua(1); + if(H==0 || ((H->drawData.controlType & ctListBox)==0)) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + noxCallWndProc(H,0x400F,0,0);///Очистить список + return 0; + } + int ListBoxSetLine(lua_State *L) + { + wndStruct *H=wndGetHandleByLua(1); + if ((H==0) || (lua_type(L,2)!=LUA_TNUMBER) || ((H->drawData.controlType & ctListBox)==0)) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + listBoxDataStruct *listBoxData=(listBoxDataStruct*) H->someData; + int idx=lua_tointeger(L,2); + if (idx>=-1 && idx<=listBoxData->maxLines) + listBoxData->lineSelectIdx=lua_tointeger(L,2); + return 0; + } + + int buttonSwitchOff(lua_State *L) + { + wndStruct *H=wndGetHandleByLua(1); + if(H==0 || ((H->drawData.controlType & ctPushButton)==0)) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + H->flags=(H->flags ^ (H->flags & wfEnabled)); + return 0; + } + + int buttonSwitchOn(lua_State *L) + { + wndStruct *H=wndGetHandleByLua(1); + if(H==0 || ((H->drawData.controlType & ctPushButton)==0)) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + H->flags|=wfEnabled; + return 0; + } + +} +void windowMsgInit(lua_State*L) +{ + registerclient("wndGetText",&editBoxGetText); + registerclient("wndSetText",&editBoxSetText);/// для эдитов + registerclient("wndLbAddText",&ListBoxAddText);/// добавляет строчку в листбокс + registerclient("wndLbClear",&ListBoxClear); + registerclient("wndLbSelectLine",&ListBoxSetLine); + registerclient("wndButtonSetText",&buttonSetText); + registerclient("wndButtonSwitchOn",&buttonSwitchOn); + registerclient("wndButtonSwitchOff",&buttonSwitchOff); + } \ No newline at end of file diff --git a/windowUniMod.h b/windowUniMod.h index 6ecdded..06a3945 100644 --- a/windowUniMod.h +++ b/windowUniMod.h @@ -1,144 +1,144 @@ -// , . - -struct wddControl -{ - int flags0; - int group; - int controlType; - int status; - struct wndStruct* wndPtr; - int BgColor; - void* imageH; - int EnabledRectColor; - void* imageEnabledH; - int HiliteColor; - void* imageHiliteH; - int DisabledRectColor; - void* imageDisabledH; - int SelectedColor; - void* imageSelectedH; - int offsetX; - int offsetY; - int TextColor; - wchar_t String[60]; - int field_C0; - int field_C4; - void *FontPtr; - wchar_t tooltipStr[62]; - int field_148; -}; -struct wndStruct -{ - int wndId; - int flags; - int width; - int height; - int screenLeft; - int screenTop; - int screenRight; - int screenBottom; - void *someData; - wddControl drawData; - int wndIdMB; - void *wndProc; - void *wndProcPre; - void *drawFn; - void *onHoverFnMB; - struct wndStruct *nextWnd; - struct wndStruct *nextSibilingMB; - struct wndStruct *parentWindow; - struct wndStruct *firstChild; -}; - - -struct listBoxDataStruct -{ - short maxLines; /// - short LineHeight; // - int Param_3; - int Bool_4;/// 0 - 0x401B ( ) - int Param_5;// bool - - int Param_6;//0x10 - int LineCanUnSelected; - /// ( , ) - void *SomeDataPtr; // +18 - - wndStruct *buttonUp; // - wndStruct *buttonDown; // - wndStruct *slider; // - int unk28; - short freeLinesCount2C; //+2C - short var2E;// / - int lineSelectIdx; - short unk_34; - short unk_36; -}; -struct editBoxDataStruct -{ - // - - wchar_t Buf[0x100]; - wchar_t Buf2[0x100]; - int Password; // ***** - int onlyNumbers; // - int onlyAlphaNum; // - int Param_6; - short maxLen;//0x410 - MaxLenMB - short entryWidth; // ( - ) - int Param_x414; - int Param_x418; - int Param_x41C;//Len - -}; -struct scrollBoxDataStruct -{ - int minValue; - int maxValue; - int stepValue; - int Value; -}; -struct staticTextDataStruct -{ - // - - wchar_t*DataPtr; - int BoolA; - int BoolB; - size_t Size; - wchar_t Buf[]; // - , -}; - -enum wndControlType -{ - ctPushButton=0x1, // 0x100 - ctRadioButton=0x2, // 0x100 - ctCheckBox=0x4, // 0x100 - ctVerticalSlider=0x8, - ctHorizontalSlider=0x10, - ctListBox=0x20, - ctEditBox=0x80, - ctStaticText=0x800, - ctProgressBar=0x1000, - ctUser=0x2000, -}; - -enum wndFlags -{ - wf_1=0x1, - wfSelected=0x2, - wf_4=0x4, - wfEnabled=0x8, - wfHidden=0x10, - wfAbove=0x20, - wfBelow=0x40, - wfImage=0x80, - wf_100=0x100, - wfNoInput=0x200, - wfNoFocus=0x400, - wf_800=0x800, - wfBorder=0x1000, - wf_2000=0x2000, - wfOneLine=0x4000, - -}; - -extern wndStruct *wndGetHandleByLua(int idx); -extern void *(__cdecl *noxCallWndProc)(void* Window,int Msg,int A,int B); -extern void *(__cdecl *noxWndLoad)(char const *WndName,void *WndProc); +// вынесем все в отдельный файл, к чему мучаться. + +struct wddControl +{ + int flags0; + int group; + int controlType; + int status; + struct wndStruct* wndPtr; + int BgColor; + void* imageH; + int EnabledRectColor; + void* imageEnabledH; + int HiliteColor; + void* imageHiliteH; + int DisabledRectColor; + void* imageDisabledH; + int SelectedColor; + void* imageSelectedH; + int offsetX; + int offsetY; + int TextColor; + wchar_t String[60]; + int field_C0; + int field_C4; + void *FontPtr; + wchar_t tooltipStr[62]; + int field_148; +}; +struct wndStruct +{ + int wndId; + int flags; + int width; + int height; + int screenLeft; + int screenTop; + int screenRight; + int screenBottom; + void *someData; + wddControl drawData; + int wndIdMB; + void *wndProc; + void *wndProcPre; + void *drawFn; + void *onHoverFnMB; + struct wndStruct *nextWnd; + struct wndStruct *nextSibilingMB; + struct wndStruct *parentWindow; + struct wndStruct *firstChild; +}; + + +struct listBoxDataStruct +{ + short maxLines; /// похоже количество строчек хотя хз + short LineHeight; //высота одной строчки + int Param_3; + int Bool_4;/// если не 0 - то похоже может увеличиватся в размерах вызывая 0x401B родителя (или себя) + int Param_5;// bool - есть скроллбар + int Param_6;//0x10 + int LineCanUnSelected; + /// это уже после создания ( в структуре не нужно, для справки) + void *SomeDataPtr; // +18 - указатель на буфер с данными + wndStruct *buttonUp; // если есть скроллбар то кнопка вверх + wndStruct *buttonDown; // если есть скроллбар то кнопка вниз + wndStruct *slider; // указатель на сам скроллбар + int unk28; + short freeLinesCount2C; //+2C + short var2E;// может первый/последний свободный в списке + int lineSelectIdx; + short unk_34; + short unk_36; +}; +struct editBoxDataStruct +{ + //сами данные - должны быть первыми и в верном порядке + wchar_t Buf[0x100]; + wchar_t Buf2[0x100]; + int Password; // показывать ***** + int onlyNumbers; // проверять что числа + int onlyAlphaNum; // проверять что буквы + int Param_6; + short maxLen;//0x410 - MaxLenMB + short entryWidth; // ширина бокса для ввода (общая ширина - с подписью) + int Param_x414; + int Param_x418; + int Param_x41C;//Len - задается автоматически +}; +struct scrollBoxDataStruct +{ + int minValue; + int maxValue; + int stepValue; + int Value; +}; +struct staticTextDataStruct +{ + //сами данные - должны быть первыми и в верном порядке + wchar_t*DataPtr; + int BoolA; + int BoolB; + size_t Size; + wchar_t Buf[]; // чисто студийное жульничество - говорим что здесь будет строка, но не говорим размер +}; + +enum wndControlType +{ + ctPushButton=0x1, // странно имеет еще 0x100 + ctRadioButton=0x2, // странно имеет еще 0x100 + ctCheckBox=0x4, // странно имеет еще 0x100 + ctVerticalSlider=0x8, + ctHorizontalSlider=0x10, + ctListBox=0x20, + ctEditBox=0x80, + ctStaticText=0x800, + ctProgressBar=0x1000, + ctUser=0x2000, +}; + +enum wndFlags +{ + wf_1=0x1, + wfSelected=0x2, + wf_4=0x4, + wfEnabled=0x8, + wfHidden=0x10, + wfAbove=0x20, + wfBelow=0x40, + wfImage=0x80, + wf_100=0x100, + wfNoInput=0x200, + wfNoFocus=0x400, + wf_800=0x800, + wfBorder=0x1000, + wf_2000=0x2000, + wfOneLine=0x4000, + +}; + +extern wndStruct *wndGetHandleByLua(int idx); +extern void *(__cdecl *noxCallWndProc)(void* Window,int Msg,int A,int B); +extern void *(__cdecl *noxWndLoad)(char const *WndName,void *WndProc); extern int (__cdecl *noxWndGetPostion) (void* Window,int *xLeft,int *yTop); \ No newline at end of file diff --git a/windows.cpp b/windows.cpp index 1ff4b12..a4df538 100644 --- a/windows.cpp +++ b/windows.cpp @@ -1,1047 +1,1047 @@ -#include "stdafx.h" -#include "windowUniMod.h" -/* -sub_450B70 - ? -*/ - -int (__cdecl *noxWndGetID)(void *Window); -void *(__cdecl *noxWndGetChildByID)(void *Window,int Id); -void (__cdecl *parseWindowStatus)(void *WddPtr,const char *Str); - - -wndStruct* (__cdecl *wndLoadControl) - (const char *ControlName, void *ParentWnd, int wndFlags, - int Left, int Top, int Width, int Height, void *Wdd, void *DataPtr); - -wndStruct* (__cdecl *wndCreate2)(void *parentWnd, int wndFlags, - int screenLeft, int screenTop, int screenWidth, int screenHeight, - void *wndProc); -void (__cdecl *wndShowHide)(void *Wnd,int Hide); -void (__cdecl *wndShowModalMB)(void *Wnd); -void (__cdecl *wndSetFocusMainMB)(void *Wnd); - - -// -void *(__cdecl *wndGetCaptureMain)(); -int (__cdecl *wndSetCaptureMain)(void *Wnd); -void (__cdecl *wndClearCaptureMain)(void *Wnd); - -int (__cdecl *noxWindowDestroy)(void *Window); - -//ASSIGN(,0x); - -extern int (__cdecl *noxSetRectColorMB) (int); -extern int (__cdecl *noxDrawGetStringSize) (int FontPtr, wchar_t *String,int *Width,int,int); -extern void *(__cdecl *guiFontPtrByName)(const char *FontName); -extern DWORD parseColor(const char *Color); -extern void wstringFromLua(lua_State *L,wchar_t *Dst,int MaxLen); -extern void *imageFromLua(lua_State *L); - -extern int (__cdecl uniWindowDrawFn) (void *Window,void *WindowDD); -extern int (__cdecl uniListBoxDrawFn) (wndStruct *Window,void *WindowDD); - - -namespace -{ - int nowCreating=0; - - bool getChildLuaByPtr(void *Ptr) - { - lua_getfield(L,-1,"children"); - if (!lua_istable(L,-1)) - return false; - lua_pushlightuserdata(L,Ptr); - lua_gettable(L,-2); - if (!lua_istable(L,-1)) // - return false; - return true; - - } - int __cdecl parseChildProc(byte* Window,int Msg,int A,int B) - { - int Top=lua_gettop(L); - bool isChild=false; - switch(Msg) - { - case 5: // () - lua_getfield(L,-1,"onLMDown"); - if (!lua_isfunction(L,-1)) - break; - lua_pushvalue(L,-2); /// - lua_pushvalue(L,-5); /// - - if (0!=lua_pcall(L,2,1,0)) - { - const char *S=lua_tostring(L,-2); - break; - } - if (lua_tonumber(L,-1)==1) - return 1; - return 0; - case 6: //LMB up - case 7: - if (wndGetCaptureMain()==Window) - { - wndClearCaptureMain(Window); - lua_getfield(L,-1,"onGrabMouse"); - if (!lua_isfunction(L,-1)) - break; - lua_pushvalue(L,-2); - lua_pushinteger(L,(short)(A&0xFFFF)); - lua_pushinteger(L,(short)(A>>16)); - lua_pcall(L,3,0,0); - return 0; - } - else - { - lua_getfield(L,-1,"onClick"); - if (!lua_isfunction(L,-1)) - break; - lua_pushvalue(L,-2); - lua_pushinteger(L,1); - lua_pushinteger(L,(short)(A&0xFFFF)); - lua_pushinteger(L,(short)(A>>16)); - lua_pcall(L,4,0,0); - return 0; - } - break; - case 9: // ( ) - lua_getfield(L,-1,"onRMDown"); - if (!lua_isfunction(L,-1)) - break; - lua_pushvalue(L,-2); /// - lua_pushvalue(L,-5); /// - - if (0!=lua_pcall(L,2,1,0)) - { - const char *S=lua_tostring(L,-2); - break; - } - if (lua_tonumber(L,-1)==1) - return 1; - return 0; - case 0xC: // ( ) - lua_getfield(L,-1,"onRMDown"); - if (!lua_isfunction(L,-1)) - break; - lua_pushvalue(L,-2); /// - lua_pushvalue(L,-5); /// - - if (0!=lua_pcall(L,2,1,0)) - { - const char *S=lua_tostring(L,-2); - break; - } - if (lua_tonumber(L,-1)==1) - return 1; - return 0; - case 0x11: /// mouse Enter - lua_getfield(L,-1,"onEnter"); - if (!lua_isfunction(L,-1)) - break; - lua_pushvalue(L,-2); /// - lua_pushvalue(L,(short)(A&0xFFFF)); - lua_pushvalue(L,(short)(A>>16)); - if (0!=lua_pcall(L,3,1,0)) - { - const char *S=lua_tostring(L,-1); - break; - } - if (lua_tonumber(L,-1)==1) - return 1; - case 0x12: // on leave - lua_getfield(L,-1,"onLeave"); - if (!lua_isfunction(L,-1)) - break; - lua_pushvalue(L,-2); /// - lua_pushvalue(L,(short)(A&0xFFFF)); - lua_pushvalue(L,(short)(A>>16)); - if (0!=lua_pcall(L,3,1,0)) - { - const char *S=lua_tostring(L,-1); - break; - } - if (lua_tonumber(L,-1)==1) - return 1; - case 0x15: /// A- , B - 1-,2- - /// return 1 , return 0 - return 0; -/* - -A=0 -A=1 -B - ChildId -*/ - case 0x4003: - { - void *P=noxWndGetChildByID(Window,B); - if (P==0 || !getChildLuaByPtr(P)) - return 1; - lua_getfield(L,-1,"onFocus"); - if (!lua_isfunction(L,-1)) - return 1; - lua_pushvalue(L,-2); - lua_pushvalue(L,-5); - lua_pushinteger(L,A); - if (0!=lua_pcall(L,3,1,0)) - { - const char *S=lua_tostring(L,-1); - return 1; - } - return 1;//lua_toboolean(L,-1); - } - } - lua_settop(L,Top); -/* char Buf[40]=""; - sprintf(Buf,"%04x %p %p",Msg,A,B); - conPrintI(Buf);*/ - - if (getChildLuaByPtr((void*)A)) - switch (Msg) - { - case 0x4007: - lua_getfield(L,-1,"onPress"); - if (!lua_isfunction(L,-1)) - break; - lua_pushvalue(L,-2); /// - lua_pushvalue(L,-5); /// - // control click control childrens table - if (0!=lua_pcall(L,2,0,0)) - { - const char *S=lua_tostring(L,-1); - break; - } - return 0; - case 0x4010: /// , - lua_getfield(L,-1,"onSelChange"); - if (!lua_isfunction(L,-1)) - break; - lua_pushvalue(L,-2); /// - lua_pushvalue(L,-5); /// - // control click control childrens table - lua_pushinteger(L,B); /// - if (0!=lua_pcall(L,3,0,0)) - { - const char *S=lua_tostring(L,-1); - break; - } - break; - case 0x401F: // , Enter - lua_getfield(L,-1,"onChange"); - if (!lua_isfunction(L,-1)) - break; - lua_pushvalue(L,-2); /// - lua_pushvalue(L,-5); /// - // control click control childrens table - if (0!=lua_pcall(L,2,0,0)) - { - const char *S=lua_tostring(L,-1); - break; - } - break; - default: - break; - } - - return 0; - } - - int __cdecl newWindowProc(wndStruct* Window,int Msg,int A,int B) - { - int Top=lua_gettop(L); - int Ret=0; - switch(Msg) - { - case 0x02://destroy window - lua_pushlightuserdata(L,&noxWndLoad); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,Window);// - lua_pushnil(L); - lua_settable(L,-3); - break; - case 0x01: - lua_pushlightuserdata(L,&noxWndLoad); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushinteger(L,nowCreating); - lua_gettable(L,-2); - if(lua_type(L,-1) ==LUA_TNIL) - break; - lua_pushlightuserdata(L,Window); - lua_pushvalue(L,-2); - lua_settable(L,-4); - - lua_getfield(L,-1,"wndProc"); - if(lua_type(L,-1)==LUA_TFUNCTION) - { - lua_pushvalue(L,-2);/// - lua_pushinteger(L,Msg); - lua_pushinteger(L,A); - lua_pushinteger(L,B); - lua_pcall(L,4,1,0); - } - if (!lua_isboolean(L,-1) || !lua_toboolean(L,-1)) - { - lua_getfield(L,-2,"oldWndProc"); - if (lua_type(L,-1)==LUA_TLIGHTUSERDATA) - { - int (__cdecl *oldProc)(void* Window,int Msg,int A,int B); - *((void**)&oldProc)=lua_touserdata(L,-1); - if (oldProc) - Ret=oldProc(Window,Msg,A,B); - } - } - break; - case 0x17:/// -/* - lua_pushlightuserdata(L,&noxWndLoad); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,Window);// - lua_pushnil(L); - lua_settable(L,-3);*/ - /// - case 0x16:// + A= ID - - default: - lua_pushlightuserdata(L,&noxWndLoad); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,Window);// - lua_gettable(L,-2); - if(lua_type(L,-1) ==LUA_TNIL) - break; - lua_getfield(L,-1,"wndProc"); - if (lua_isnil(L,-1)) /// - { - lua_pop(L,1); - Ret=parseChildProc((byte*)Window,Msg,A,B); - } - else - { - if(lua_type(L,-1)==LUA_TFUNCTION) - { - lua_pushvalue(L,-2);/// - lua_pushinteger(L,Msg); - lua_pushlightuserdata(L,(void *)A); - lua_pushinteger(L,B); - lua_pcall(L,4,1,0); - } - if (!lua_isboolean(L,-1) || !lua_toboolean(L,-1)) - { - lua_getfield(L,-2,"oldWndProc"); - if (lua_type(L,-1)==LUA_TLIGHTUSERDATA) - { - int (__cdecl *oldProc)(void* Window,int Msg,int A,int B); - *((void**)&oldProc)=lua_touserdata(L,-1); - if (oldProc) - Ret=oldProc(Window,Msg,A,B); - } - } - } - } - lua_settop(L,Top); - return Ret; - } - int __cdecl newWindowControlProc(wndStruct* Window,int Msg,int A,int B) // - { - int Top=lua_gettop(L); - int Ret=0; - - wndStruct *Parent=Window->drawData.wndPtr; // , - lua_pushlightuserdata(L,&noxWndLoad); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,Parent); - lua_gettable(L,-2); - lua_getfield(L,-1,"children"); - - if (Msg==2) - { - lua_pushlightuserdata(L,Window); - lua_pushnil(L); - lua_settable(L,-3); - - } - lua_pushlightuserdata(L,Window); - lua_gettable(L,-2); - if (!lua_type(L,-1)==LUA_TTABLE) - return 0; - int Tops=lua_gettop(L); - parseChildProc((byte*)Window,Msg,A,B); - lua_settop(L,Tops); - lua_getfield(L,-1,"wndControlProc"); - if (lua_type(L,-1)==LUA_TLIGHTUSERDATA) - { - int (__cdecl *wndControlProc)(wndStruct* Window,int Msg,int A,int B); - *((void**)&wndControlProc)=lua_touserdata(L,-1); - if (wndControlProc) - Ret=wndControlProc(Window,Msg,A,B); - } - lua_settop(L,Top); - return Ret; - } - int __cdecl newDrawProc(byte *Window,byte *drawData) - { - int Top=lua_gettop(L); - lua_pushlightuserdata(L,&noxWndLoad); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,Window); - lua_gettable(L,-2); - if (lua_type(L,-1)!=LUA_TTABLE) - { - lua_settop(L,Top); - return 0; - } - lua_getfield(L,-1,"drawFn"); - lua_pushlightuserdata(L,Window); - lua_pcall(L,1,0,0); - - lua_settop(L,Top); - return 0; - } - ParseAttrib attrOffsets[]= - { - {"textColor",0x68,3}, - {0,0,0} - }; - - int wndSetAttr(lua_State *L) - { - lua_settop(L,3); - if (lua_type(L,2)!=LUA_TSTRING) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - wndStruct *H=wndGetHandleByLua(1); - parseAttr(L,2,3,H,attrOffsets); - return 1; - } - int wndDestroyL(lua_State *L) - { - wndStruct *H=wndGetHandleByLua(1); - lua_pushinteger(L,noxWindowDestroy(H)); - return 1; - } - int getChildByIdL(lua_State *L) - { - void *R; - if(lua_type(L,2)!=LUA_TNUMBER) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - wndStruct *H=wndGetHandleByLua(1); - if(H==0) - { - lua_pushnil(L); - return 1; - } - R=noxWndGetChildByID(H,lua_tonumber(L,2)); - if(R==0) - lua_pushnil(L); - else - lua_pushlightuserdata(L,R); - return 1; - } - int wndShow(lua_State *L) - { - lua_settop(L,2); - wndStruct *H=wndGetHandleByLua(1); - wndShowHide(H,lua_toboolean(L,2)?0:1); - return 0; - } - int wndUnGrabMouse(lua_State *L) - { - lua_settop(L,1); - wndStruct *H=wndGetHandleByLua(1); - wndClearCaptureMain(H); - return 0; - } - int wndGrabMouse(lua_State *L) - { - lua_settop(L,2); - wndStruct *H=wndGetHandleByLua(1); - if (0==lua_toboolean(L,2) && ( 0!=wndGetCaptureMain() ))// true - - return 0; - wndSetCaptureMain(H); - return 0; - } - int wndGetIdL(lua_State *L) - { - wndStruct *H=wndGetHandleByLua(1); - if(H==0) - { - lua_pushnil(L); - return 1; - } - lua_pushinteger(L,noxWndGetID(H)); - return 1; - } - int callWndProcL(lua_State *L) - { - void *R; - wndStruct *H=wndGetHandleByLua(1); - lua_settop(L,4); - R=noxCallWndProc(H,lua_tointeger(L,2), - (lua_type(L,3)==LUA_TLIGHTUSERDATA)?(int)lua_touserdata(L,3):lua_tointeger(L,3), - (lua_type(L,4)==LUA_TLIGHTUSERDATA)?(int)lua_touserdata(L,4):lua_tointeger(L,4)); - if(R==0) - lua_pushinteger(L,0); - else if(R==(void *)1) - lua_pushinteger(L,1); - else - { - lua_pushlightuserdata(L,R); - } - return 1; - } - int wndSetProcL(lua_State *L) // wnd+0x178 - - { - wndStruct *Window=wndGetHandleByLua(1); - bool haveTable=false; - if(lua_type(L,1)==LUA_TTABLE) - haveTable=true; - if(lua_type(L,2)!=LUA_TFUNCTION) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - lua_pushlightuserdata(L,&noxWndLoad); - lua_gettable(L,LUA_REGISTRYINDEX); - if (haveTable) - lua_pushvalue(L,1); - { - lua_newtable(L); - lua_pushlightuserdata(L,Window); - lua_setfield(L,-2,"handle"); - lua_pushvalue(L,2); - lua_setfield(L,-2,"wndProc"); - } - lua_pushlightuserdata(L,Window->wndProcPre); - lua_setfield(L,-2,"oldFn");/// - lua_pushlightuserdata(L,Window); - lua_pushvalue(L,-2); - /// : -1=, -2=, , - // , [ ], , - lua_settable(L,-4); - /// 174 - 178 - ? - Window->wndProcPre=&newWindowProc; - - return 1; - } -class staticTextDataClass /// -{ -public: - staticTextDataStruct staticTextData; - - static void *Create(lua_State *L,int Idx)/// , - { - lua_getfield(L,Idx,"text"); - int NeedSize=lua_objlen(L,-1)*2; // - NeedSize=(sizeof(staticTextDataStruct)+NeedSize+0x3F)&(~0x3F);// ( 64) - - staticTextDataStruct *Me=(staticTextDataStruct *)lua_newuserdata(L,NeedSize); // - - Me->BoolA=0;Me->BoolB=0; - Me->Size=NeedSize-sizeof(staticTextDataStruct); - Me->DataPtr=Me->Buf; - mbstowcs(Me->Buf,lua_tostring(L,-2),Me->Size>>1); - lua_remove(L,-2); - return Me; - } -}; -class editboxDataClass -{ -public: - editBoxDataStruct editboxData; - - void *Create(lua_State *L,int Idx)/// - { - int Top=lua_gettop(L); - editBoxDataStruct *Me=&this->editboxData; - lua_getfield(L,Idx,"password"); - Me->Password=lua_toboolean(L,-1); - lua_getfield(L,Idx,"onlyNumbers"); - Me->onlyNumbers=lua_toboolean(L,-1); - lua_getfield(L,Idx,"onlyAlphaNum"); - Me->onlyAlphaNum=lua_toboolean(L,-1); - lua_getfield(L,Idx,"maxLen"); - Me->maxLen=lua_tointeger(L,-1); // MaxLen - if (Me->maxLen<1) - Me->maxLen=255; - - Me->entryWidth=-1;// MB - Me->Param_6=0; - lua_settop(L,Top); - return Me; - } -}; -class ListboxDataClass -{ -public: - listBoxDataStruct listboxData; - - void *Create(lua_State *L,int Idx)/// - { - listBoxDataStruct *Me=&this->listboxData; - memset(this,0,sizeof(listBoxDataStruct)); - int Top=lua_gettop(L); - lua_getfield(L,Idx,"maxLines"); - Me->maxLines=lua_tointeger(L,-1); // MaxLen - if (Me->maxLines<1) - Me->maxLines=100;/// , - Me->LineHeight=18; - lua_getfield(L,Idx,"lineUnSelected"); - if (lua_isboolean(L,-1) || lua_toboolean(L,-1)) - Me->LineCanUnSelected=1; - else - Me->LineCanUnSelected=0; -/* Me->Password=lua_toboolean(L,-1); - lua_getfield(L,Idx,"maxLen"); - - lua_settop(L,Top); - return Me;*/ - return this; - } - - void CreateSlider(lua_State *L,wndStruct *Wnd) - { - int isSlider=false; - lua_getfield(L,1,"slider"); // 2 - getClientVar("wndCreate"); - if (lua_type(L,2)==LUA_TTABLE) - { - for (int i=1;i<=3;i++) - { - lua_pushnumber(L,i); - lua_gettable(L,2); - if (lua_type(L,-1)!=LUA_TTABLE) - break; - lua_getfield(L,-1,"type"); - if (lua_type(L,-1)==LUA_TSTRING) - { - const char *ControlType=lua_tostring(L,-1); - if (0==strcmpi(ControlType,"PUSHBUTTON")) - { - isSlider=false; - }else if (0==strcmpi(ControlType,"VERTSLIDER")) - { - isSlider=true; - } - else - break; // - } - lua_pop(L,1); - lua_pushvalue(L,3); - lua_pushvalue(L,-2); - lua_pushlightuserdata(L,Wnd); - if (0!=lua_pcall(L,2,1,0)) - { - const char *S=lua_tostring(L,-1); - lua_settop(L,1); - return; - } - lua_getfield(L,-1,"handle"); - - wndStruct *createdWnd=(wndStruct*) lua_touserdata(L,-1); - lua_getfield(L,-2,"wndControlProc"); // , - createdWnd->wndProc=lua_touserdata(L,-1); - - listBoxDataStruct *listboxData=(listBoxDataStruct*)Wnd->someData; - if (isSlider) - listboxData->slider=createdWnd; - else if (listboxData->buttonUp==0) - listboxData->buttonUp=createdWnd; - else - listboxData->buttonDown=createdWnd; - Wnd->drawFn=&uniListBoxDrawFn; - lua_settop(L,3); - } - } - lua_settop(L,1); - return; - } - - -}; -class scrollboxDataClass -{ -public: - scrollBoxDataStruct scrollboxData; - - void *Create(lua_State *L,int Idx)/// - { - int Top=lua_gettop(L); - scrollBoxDataStruct *Me=&this->scrollboxData; - memset(this,0,sizeof(scrollBoxDataStruct)); - return Me; - } -}; - - int wndLoad(lua_State *L) - { - void * Window; - if(lua_type(L,1)!=LUA_TSTRING) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - lua_settop(L,2); - if(lua_type(L,2)==LUA_TNIL) - {lua_pop(L,1);lua_newtable(L);}// - - else if(lua_type(L,2)!=LUA_TTABLE) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - lua_pushlightuserdata(L,&noxWndLoad); - lua_gettable(L,LUA_REGISTRYINDEX); - - lua_pushinteger(L,++nowCreating);// - lua_pushvalue(L,2); - lua_settable(L,-3);// , - Window=noxWndLoad(lua_tostring(L,1),&newWindowProc); - lua_pushinteger(L,nowCreating--);// - lua_pushnil(L); - lua_settable(L,-3); - - if(Window==0) - { - lua_pushnil(L); - return 1; - } - lua_pushlightuserdata(L,Window); - lua_pushvalue(L,2); - lua_pushstring(L,"handle"); - lua_pushlightuserdata(L,Window); - lua_settable(L,-3);// - lua_settable(L,-3);// , - lua_settop(L,2);/// - return 1; - } - inline int lua_getint(lua_State*L,const char *Name) - { - lua_getfield(L,1,Name); - return lua_tointeger(L,-1); - } - ListboxDataClass LD; - editboxDataClass ED; - scrollboxDataClass VS; - - int wndCreate(lua_State *L) - { - lua_settop(L,2); - if (lua_type(L,1)!=LUA_TTABLE) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - void *Parent=0; // - if(lua_type(L,2)==LUA_TTABLE) - { - lua_getfield(L,-1,"handle"); - lua_insert(L,2); - lua_settop(L,2); - } - if (lua_type(L,2)==LUA_TLIGHTUSERDATA) - { - Parent=lua_touserdata(L,2); - } -/* - - wndCreate( - { - x=100,y=100,w=200,h=30, - bgcolor='#FF00FF'; - { - type="PUSHBUTTON", - x=10,y=10,w=100,h=20, - id=1000, - status = "IMAGE+NOFOCUS" - wndProc=fn | nil - click=fn, - highlight=fn | "none" | "default"; - font="large"; - bgcolor='#332211'; - color='#112233'; - alpha=false; - hiliteColor='#123233'; - disabledColor='#112233'; - selectedColor='#112233'; - disabledImage="somename"; - selectedImage="somename"; - image="somename" - hiliteImage="somename" - text="Test1"; - tooltip="Test1 tooltip"; - drawFn=function (me) end - } - } - ) -*/ -/* - WINDOW - 10112 201 272 45 15 PUSHBUTTON; - STATUS = ENABLED+IMAGE+NOFOCUS; - STYLE = MOUSETRACK; - SELECTEDIMAGE = UIButtonSmLit; - HILITEIMAGE = UIButtonSmLit; - BACKGROUNDIMAGE = UIButtonSm; - ENABLEDIMAGE = NULL; - DISABLEDIMAGE = UIButtonSmDis; - IMAGEOFFSET = 0 -5; - TEXT = Access.wnd:Add; - TOOLTIP = Access.wnd:AddTT; - END - - -*/ - int x,y,w,h; - DWORD Flags=wfNoFocus+wfEnabled; - - x=lua_getint(L,"x"); - y=lua_getint(L,"y"); - w=lua_getint(L,"w"); - h=lua_getint(L,"h"); - if (w<1) w=10; - if (h<1) h=10; - - wddControl Wdd={0}; - lua_getfield(L,1,"status"); - if (lua_type(L,-1)==LUA_TNUMBER) - Wdd.status=lua_tointeger(L,-1); - else if (lua_type(L,-1)==LUA_TSTRING) - parseWindowStatus(&Wdd,lua_tostring(L,-1)); - - lua_getfield(L,1,"bgcolor"); - if (lua_type(L,-1)==LUA_TSTRING) - Wdd.BgColor=parseColor(lua_tostring(L,-1)); - lua_getfield(L,1,"image"); - Wdd.imageH=imageFromLua(L); - if (Wdd.imageH) - Flags|=0x80; - - lua_getfield(L,1,"enabledColor"); - if (lua_type(L,-1)==LUA_TSTRING) - Wdd.EnabledRectColor=parseColor(lua_tostring(L,-1)); - - lua_getfield(L,1,"disabledColor"); - if (lua_type(L,-1)==LUA_TSTRING) - Wdd.DisabledRectColor=parseColor(lua_tostring(L,-1)); - lua_getfield(L,1,"disabledImage"); - Wdd.imageDisabledH=imageFromLua(L); - lua_getfield(L,1,"hiliteColor"); - if (lua_type(L,-1)==LUA_TSTRING) - Wdd.HiliteColor=parseColor(lua_tostring(L,-1)); - lua_getfield(L,1,"hiliteImage"); - Wdd.imageHiliteH=imageFromLua(L); - lua_getfield(L,1,"selectedColor"); - if (lua_type(L,-1)==LUA_TSTRING) - Wdd.SelectedColor=parseColor(lua_tostring(L,-1)); - lua_getfield(L,1,"selectedImage"); - Wdd.imageSelectedH=imageFromLua(L); - - lua_settop(L,1); - lua_getfield(L,1,"offsetX"); - Wdd.offsetX=lua_tointeger(L,-1); - lua_getfield(L,1,"offsetY"); - Wdd.offsetY=lua_tointeger(L,-1); - - lua_getfield(L,1,"textColor"); - if (lua_type(L,-1)==LUA_TSTRING) - Wdd.TextColor=parseColor(lua_tostring(L,-1)); - lua_getfield(L,1,"text"); - if (lua_type(L,-1)==LUA_TSTRING) - wstringFromLua(L,Wdd.String,60);// 64 - lua_getfield(L,1,"tooltip"); - if (lua_type(L,-1)==LUA_TSTRING) - { - wstringFromLua(L,Wdd.tooltipStr,62);// 64 - } - lua_getfield(L,1,"font"); - if (lua_type(L,-1)==LUA_TSTRING) - { - Wdd.FontPtr=guiFontPtrByName(lua_tostring(L,-1));// 64 - } - lua_settop(L,1); - - static int nextChildId=0x100; - lua_getfield(L,1,"type"); - if (lua_type(L,-1)==LUA_TSTRING) - { - const char *ControlType=lua_tostring(L,-1); - if (0==strcmpi(ControlType,"listbox")) - ControlType="SCROLLLISTBOX"; - void *DataPtr=NULL; - if (0==strcmpi(ControlType,"STATICTEXT")) - { - lua_pushstring(L,"__bindata"); - DataPtr=staticTextDataClass::Create(L,1); - lua_settable(L,1); // - }else if (0==strcmpi(ControlType,"ENTRYFIELD")) - { - ED.Create(L,1); - DataPtr=&ED; - }else if (0==strcmpi(ControlType,"SCROLLLISTBOX")) - { - LD.Create(L,1); - DataPtr=&LD; - }else if (0==strcmpi(ControlType,"VERTSLIDER")) - { - VS.Create(L,1); - DataPtr=&VS; - }else if (0==strcmpi(ControlType,"PUSHBUTTON")) - { - Wdd.controlType=0x100; - } - wndStruct *Wnd=wndLoadControl(ControlType,Parent, Wdd.status,x,y,w,h, &Wdd,DataPtr); - if (Wnd==NULL) - { - lua_pushstring(L,"wrong args - unable to create control"); - lua_error(L); - } - - if ((Wnd->drawData.controlType & ctListBox)!=0) // , - { - lua_settop(L,1); - LD.CreateSlider(L,Wnd); - } - - Wnd->wndId=nextChildId; - lua_pushstring(L,"wndControlProc"); - lua_pushlightuserdata(L,Wnd->wndProc); - lua_settable(L,1); - Wnd->wndProc=&newWindowControlProc; - lua_pushstring(L,"childId"); - lua_pushinteger(L,nextChildId++); - lua_settable(L,1); - lua_pushstring(L,"handle"); - lua_pushlightuserdata(L,Wnd); - lua_settable(L,1); - /*lua_pushlightuserdata(L,&noxWndLoad); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushlightuserdata(L,Wnd); - lua_pushvalue(L,1); - lua_settable(L,-3);*/ - lua_settop(L,1); - return 1; - } - - Wdd.controlType|=ctUser;// - - - lua_pushlightuserdata(L,&noxWndLoad); - lua_gettable(L,LUA_REGISTRYINDEX); - lua_pushinteger(L,++nowCreating); - lua_pushvalue(L,1); - lua_settable(L,-3);/// - - wndStruct *Wnd=wndCreate2(Parent,Wdd.status,x,y,w,h,&newWindowProc); - lua_pushinteger(L,nowCreating--); /// - lua_pushnil(L); - lua_settable(L,-3); - if (Wnd==0) - { - lua_pushstring(L,"wndCreate2 Fail!"); - lua_error(L); - } - Wnd->drawFn=&uniWindowDrawFn; // - Wnd->wndProcPre=&newWindowProc; - - Wnd->wndId=nextChildId; - lua_pushstring(L,"childId"); - lua_pushinteger(L,nextChildId++); - lua_settable(L,1); - - lua_getfield(L,1,"drawFn"); - if (lua_type(L,-1)==LUA_TFUNCTION) - { - Wnd->drawFn=&newDrawProc; - } - lua_settop(L,1); - - lua_pushlightuserdata(L,Wnd); - lua_pushvalue(L,1); - lua_pushstring(L,"handle"); - lua_pushlightuserdata(L,Wnd); - lua_settable(L,-3);// - lua_settable(L,-3); - Wnd->drawData=Wdd; - - - lua_settop(L,1); - lua_getfield(L,1,"children"); - if (!lua_istable(L,-1)) - { - lua_settop(L,1); - lua_newtable(L); - lua_pushvalue(L,-1); - lua_setfield(L,1,"children"); - } - getClientVar("wndCreate"); //wndcreaet, children, table, - for (int i=1;;i++)/// - { - lua_pushvalue(L,-1); - lua_pushinteger(L,i); - lua_gettable(L,1); - if (lua_type(L,-1)!=LUA_TTABLE) - break; - lua_getfield(L,-1,"handle"); - if (lua_type(L,-1)!=LUA_TNIL) - { - // ? ? - lua_pop(L,3); - continue; - } - lua_pop(L,1); - lua_pushvalue(L,1); - if (0!=lua_pcall(L,2,1,0)) - { - const char *S=lua_tostring(L,-1); - break; - } - lua_getfield(L,-1,"handle"); - lua_pushvalue(L,-2); - lua_settable(L,2);/// children - lua_settop(L,3); - } - lua_settop(L,1); - return 1; - } - -}; -extern void InjectAddr(DWORD Addr,void *Fn); -extern void InjectJumpTo(DWORD Addr,void *Fn); - -void windowsInit() -{ - ASSIGN(noxWndGetID,0x46B0A0); - ASSIGN(noxWndGetChildByID,0x46B0C0); - ASSIGN(noxWindowDestroy,0x46C4E0); - ASSIGN(parseWindowStatus,0x004A0A00); - - ASSIGN(wndShowHide,0x0046AC00); - ASSIGN(wndShowModalMB,0x0046A8C0); - ASSIGN(wndSetFocusMainMB,0x0046ADC0); - - ASSIGN(wndLoadControl,0x004A1510); - ASSIGN(wndCreate2,0x0046C3E0); - - ASSIGN(wndGetCaptureMain,0x0046AE00); - ASSIGN(wndSetCaptureMain,0x0046ADC0); - ASSIGN(wndClearCaptureMain,0x0046ADE0); - - - lua_pushlightuserdata(L,&noxWndLoad); - lua_newtable(L); - lua_settable(L,LUA_REGISTRYINDEX); - - - registerclient("wndSetProc",&wndSetProcL); - registerclient("wndCall",&callWndProcL); - registerclient("wndGrabMouse",&wndGrabMouse); - registerclient("wndUnGrabMouse",&wndUnGrabMouse); - - registerclient("wndShow",&wndShow); // / - registerclient("wndClose",&wndDestroyL); - registerclient("wndCreate",&wndCreate,1); - registerclient("wndLoad",&wndLoad); - - registerclient("wndGetId",&wndGetIdL); - registerclient("wndChildById",&getChildByIdL); - registerclient("wndSetAttr",&wndSetAttr); // - -} - - +#include "stdafx.h" +#include "windowUniMod.h" +/* +sub_450B70 - стереть все из консоли? +*/ + +int (__cdecl *noxWndGetID)(void *Window); +void *(__cdecl *noxWndGetChildByID)(void *Window,int Id); +void (__cdecl *parseWindowStatus)(void *WddPtr,const char *Str); + + +wndStruct* (__cdecl *wndLoadControl) + (const char *ControlName, void *ParentWnd, int wndFlags, + int Left, int Top, int Width, int Height, void *Wdd, void *DataPtr); + +wndStruct* (__cdecl *wndCreate2)(void *parentWnd, int wndFlags, + int screenLeft, int screenTop, int screenWidth, int screenHeight, + void *wndProc); +void (__cdecl *wndShowHide)(void *Wnd,int Hide); +void (__cdecl *wndShowModalMB)(void *Wnd); +void (__cdecl *wndSetFocusMainMB)(void *Wnd); + + +// какое окно схарчило мышь +void *(__cdecl *wndGetCaptureMain)(); +int (__cdecl *wndSetCaptureMain)(void *Wnd); +void (__cdecl *wndClearCaptureMain)(void *Wnd); + +int (__cdecl *noxWindowDestroy)(void *Window); + +//ASSIGN(,0x); + +extern int (__cdecl *noxSetRectColorMB) (int); +extern int (__cdecl *noxDrawGetStringSize) (int FontPtr, wchar_t *String,int *Width,int,int); +extern void *(__cdecl *guiFontPtrByName)(const char *FontName); +extern DWORD parseColor(const char *Color); +extern void wstringFromLua(lua_State *L,wchar_t *Dst,int MaxLen); +extern void *imageFromLua(lua_State *L); + +extern int (__cdecl uniWindowDrawFn) (void *Window,void *WindowDD); +extern int (__cdecl uniListBoxDrawFn) (wndStruct *Window,void *WindowDD); + + +namespace +{ + int nowCreating=0; + + bool getChildLuaByPtr(void *Ptr) + { + lua_getfield(L,-1,"children"); + if (!lua_istable(L,-1)) + return false; + lua_pushlightuserdata(L,Ptr); + lua_gettable(L,-2); + if (!lua_istable(L,-1)) // дочернее окно + return false; + return true; + + } + int __cdecl parseChildProc(byte* Window,int Msg,int A,int B) + { + int Top=lua_gettop(L); + bool isChild=false; + switch(Msg) + { + case 5: // тут ловим клик (левый) что бы он дальше не ушел + lua_getfield(L,-1,"onLMDown"); + if (!lua_isfunction(L,-1)) + break; + lua_pushvalue(L,-2); /// таблица окна + lua_pushvalue(L,-5); /// таблица - родитель + if (0!=lua_pcall(L,2,1,0)) + { + const char *S=lua_tostring(L,-2); + break; + } + if (lua_tonumber(L,-1)==1) + return 1; + return 0; + case 6: //LMB up + case 7: + if (wndGetCaptureMain()==Window) + { + wndClearCaptureMain(Window); + lua_getfield(L,-1,"onGrabMouse"); + if (!lua_isfunction(L,-1)) + break; + lua_pushvalue(L,-2); + lua_pushinteger(L,(short)(A&0xFFFF)); + lua_pushinteger(L,(short)(A>>16)); + lua_pcall(L,3,0,0); + return 0; + } + else + { + lua_getfield(L,-1,"onClick"); + if (!lua_isfunction(L,-1)) + break; + lua_pushvalue(L,-2); + lua_pushinteger(L,1); + lua_pushinteger(L,(short)(A&0xFFFF)); + lua_pushinteger(L,(short)(A>>16)); + lua_pcall(L,4,0,0); + return 0; + } + break; + case 9: // Ловим правый клик (тут он долгий) + lua_getfield(L,-1,"onRMDown"); + if (!lua_isfunction(L,-1)) + break; + lua_pushvalue(L,-2); /// таблица окна + lua_pushvalue(L,-5); /// таблица - родитель + if (0!=lua_pcall(L,2,1,0)) + { + const char *S=lua_tostring(L,-2); + break; + } + if (lua_tonumber(L,-1)==1) + return 1; + return 0; + case 0xC: // Ловим правый клик (тут долгий) + lua_getfield(L,-1,"onRMDown"); + if (!lua_isfunction(L,-1)) + break; + lua_pushvalue(L,-2); /// таблица окна + lua_pushvalue(L,-5); /// таблица - родитель + if (0!=lua_pcall(L,2,1,0)) + { + const char *S=lua_tostring(L,-2); + break; + } + if (lua_tonumber(L,-1)==1) + return 1; + return 0; + case 0x11: /// mouse Enter + lua_getfield(L,-1,"onEnter"); + if (!lua_isfunction(L,-1)) + break; + lua_pushvalue(L,-2); /// таблица окна + lua_pushvalue(L,(short)(A&0xFFFF)); + lua_pushvalue(L,(short)(A>>16)); + if (0!=lua_pcall(L,3,1,0)) + { + const char *S=lua_tostring(L,-1); + break; + } + if (lua_tonumber(L,-1)==1) + return 1; + case 0x12: // on leave + lua_getfield(L,-1,"onLeave"); + if (!lua_isfunction(L,-1)) + break; + lua_pushvalue(L,-2); /// таблица окна + lua_pushvalue(L,(short)(A&0xFFFF)); + lua_pushvalue(L,(short)(A>>16)); + if (0!=lua_pcall(L,3,1,0)) + { + const char *S=lua_tostring(L,-1); + break; + } + if (lua_tonumber(L,-1)==1) + return 1; + case 0x15: /// нажатие на кнопку A- код, B - 1-отпускание,2- нажатие + /// похоже return 1 съедает кнопку, return 0 передает дальше + return 0; +/* +сообщение о изменении фокуса +A=0 фокус получен +A=1 фокус потерян +B - ChildId +*/ + case 0x4003: + { + void *P=noxWndGetChildByID(Window,B); + if (P==0 || !getChildLuaByPtr(P)) + return 1; + lua_getfield(L,-1,"onFocus"); + if (!lua_isfunction(L,-1)) + return 1; + lua_pushvalue(L,-2); + lua_pushvalue(L,-5); + lua_pushinteger(L,A); + if (0!=lua_pcall(L,3,1,0)) + { + const char *S=lua_tostring(L,-1); + return 1; + } + return 1;//lua_toboolean(L,-1); + } + } + lua_settop(L,Top); +/* char Buf[40]=""; + sprintf(Buf,"%04x %p %p",Msg,A,B); + conPrintI(Buf);*/ + + if (getChildLuaByPtr((void*)A)) + switch (Msg) + { + case 0x4007: + lua_getfield(L,-1,"onPress"); + if (!lua_isfunction(L,-1)) + break; + lua_pushvalue(L,-2); /// таблица окна + lua_pushvalue(L,-5); /// таблица - родитель // control click control childrens table + if (0!=lua_pcall(L,2,0,0)) + { + const char *S=lua_tostring(L,-1); + break; + } + return 0; + case 0x4010: /// листбокс, смена элемента + lua_getfield(L,-1,"onSelChange"); + if (!lua_isfunction(L,-1)) + break; + lua_pushvalue(L,-2); /// таблица окна + lua_pushvalue(L,-5); /// таблица - родитель // control click control childrens table + lua_pushinteger(L,B); /// Номер в списке + if (0!=lua_pcall(L,3,0,0)) + { + const char *S=lua_tostring(L,-1); + break; + } + break; + case 0x401F: // эдит текст, Enter + lua_getfield(L,-1,"onChange"); + if (!lua_isfunction(L,-1)) + break; + lua_pushvalue(L,-2); /// таблица окна + lua_pushvalue(L,-5); /// таблица - родитель // control click control childrens table + if (0!=lua_pcall(L,2,0,0)) + { + const char *S=lua_tostring(L,-1); + break; + } + break; + default: + break; + } + + return 0; + } + + int __cdecl newWindowProc(wndStruct* Window,int Msg,int A,int B) + { + int Top=lua_gettop(L); + int Ret=0; + switch(Msg) + { + case 0x02://destroy window + lua_pushlightuserdata(L,&noxWndLoad); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,Window);// Удаляем таблицу из реестра + lua_pushnil(L); + lua_settable(L,-3); + break; + case 0x01: + lua_pushlightuserdata(L,&noxWndLoad); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushinteger(L,nowCreating); + lua_gettable(L,-2); + if(lua_type(L,-1) ==LUA_TNIL) + break; + lua_pushlightuserdata(L,Window); + lua_pushvalue(L,-2); + lua_settable(L,-4); + + lua_getfield(L,-1,"wndProc"); + if(lua_type(L,-1)==LUA_TFUNCTION) + { + lua_pushvalue(L,-2);///сама таблица + lua_pushinteger(L,Msg); + lua_pushinteger(L,A); + lua_pushinteger(L,B); + lua_pcall(L,4,1,0); + } + if (!lua_isboolean(L,-1) || !lua_toboolean(L,-1)) + { + lua_getfield(L,-2,"oldWndProc"); + if (lua_type(L,-1)==LUA_TLIGHTUSERDATA) + { + int (__cdecl *oldProc)(void* Window,int Msg,int A,int B); + *((void**)&oldProc)=lua_touserdata(L,-1); + if (oldProc) + Ret=oldProc(Window,Msg,A,B); + } + } + break; + case 0x17:/// уничтожено дочернее окно +/*здесь надо дочернее удалить + lua_pushlightuserdata(L,&noxWndLoad); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,Window);// Удаляем таблицу из реестра + lua_pushnil(L); + lua_settable(L,-3);*/ + /// прочие случаи + case 0x16:// создано дочернее окно + A= ID + + default: + lua_pushlightuserdata(L,&noxWndLoad); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,Window);// Удаляем таблицу из реестра + lua_gettable(L,-2); + if(lua_type(L,-1) ==LUA_TNIL) + break; + lua_getfield(L,-1,"wndProc"); + if (lua_isnil(L,-1)) /// возможно используем реакции на дочерние функции + { + lua_pop(L,1); + Ret=parseChildProc((byte*)Window,Msg,A,B); + } + else + { + if(lua_type(L,-1)==LUA_TFUNCTION) + { + lua_pushvalue(L,-2);///сама таблица + lua_pushinteger(L,Msg); + lua_pushlightuserdata(L,(void *)A); + lua_pushinteger(L,B); + lua_pcall(L,4,1,0); + } + if (!lua_isboolean(L,-1) || !lua_toboolean(L,-1)) + { + lua_getfield(L,-2,"oldWndProc"); + if (lua_type(L,-1)==LUA_TLIGHTUSERDATA) + { + int (__cdecl *oldProc)(void* Window,int Msg,int A,int B); + *((void**)&oldProc)=lua_touserdata(L,-1); + if (oldProc) + Ret=oldProc(Window,Msg,A,B); + } + } + } + } + lua_settop(L,Top); + return Ret; + } + int __cdecl newWindowControlProc(wndStruct* Window,int Msg,int A,int B) // специально для контролов + { + int Top=lua_gettop(L); + int Ret=0; + + wndStruct *Parent=Window->drawData.wndPtr; // не совсем парент, но в это окно по идее идут мсж + lua_pushlightuserdata(L,&noxWndLoad); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,Parent); + lua_gettable(L,-2); + lua_getfield(L,-1,"children"); + + if (Msg==2) + { + lua_pushlightuserdata(L,Window); + lua_pushnil(L); + lua_settable(L,-3); + + } + lua_pushlightuserdata(L,Window); + lua_gettable(L,-2); + if (!lua_type(L,-1)==LUA_TTABLE) + return 0; + int Tops=lua_gettop(L); + parseChildProc((byte*)Window,Msg,A,B); + lua_settop(L,Tops); + lua_getfield(L,-1,"wndControlProc"); + if (lua_type(L,-1)==LUA_TLIGHTUSERDATA) + { + int (__cdecl *wndControlProc)(wndStruct* Window,int Msg,int A,int B); + *((void**)&wndControlProc)=lua_touserdata(L,-1); + if (wndControlProc) + Ret=wndControlProc(Window,Msg,A,B); + } + lua_settop(L,Top); + return Ret; + } + int __cdecl newDrawProc(byte *Window,byte *drawData) + { + int Top=lua_gettop(L); + lua_pushlightuserdata(L,&noxWndLoad); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,Window); + lua_gettable(L,-2); + if (lua_type(L,-1)!=LUA_TTABLE) + { + lua_settop(L,Top); + return 0; + } + lua_getfield(L,-1,"drawFn"); + lua_pushlightuserdata(L,Window); + lua_pcall(L,1,0,0); + + lua_settop(L,Top); + return 0; + } + ParseAttrib attrOffsets[]= + { + {"textColor",0x68,3}, + {0,0,0} + }; + + int wndSetAttr(lua_State *L) + { + lua_settop(L,3); + if (lua_type(L,2)!=LUA_TSTRING) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + wndStruct *H=wndGetHandleByLua(1); + parseAttr(L,2,3,H,attrOffsets); + return 1; + } + int wndDestroyL(lua_State *L) + { + wndStruct *H=wndGetHandleByLua(1); + lua_pushinteger(L,noxWindowDestroy(H)); + return 1; + } + int getChildByIdL(lua_State *L) + { + void *R; + if(lua_type(L,2)!=LUA_TNUMBER) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + wndStruct *H=wndGetHandleByLua(1); + if(H==0) + { + lua_pushnil(L); + return 1; + } + R=noxWndGetChildByID(H,lua_tonumber(L,2)); + if(R==0) + lua_pushnil(L); + else + lua_pushlightuserdata(L,R); + return 1; + } + int wndShow(lua_State *L) + { + lua_settop(L,2); + wndStruct *H=wndGetHandleByLua(1); + wndShowHide(H,lua_toboolean(L,2)?0:1); + return 0; + } + int wndUnGrabMouse(lua_State *L) + { + lua_settop(L,1); + wndStruct *H=wndGetHandleByLua(1); + wndClearCaptureMain(H); + return 0; + } + int wndGrabMouse(lua_State *L) + { + lua_settop(L,2); + wndStruct *H=wndGetHandleByLua(1); + if (0==lua_toboolean(L,2) && ( 0!=wndGetCaptureMain() ))// если второй параметр true - схарчим в любом случае + return 0; + wndSetCaptureMain(H); + return 0; + } + int wndGetIdL(lua_State *L) + { + wndStruct *H=wndGetHandleByLua(1); + if(H==0) + { + lua_pushnil(L); + return 1; + } + lua_pushinteger(L,noxWndGetID(H)); + return 1; + } + int callWndProcL(lua_State *L) + { + void *R; + wndStruct *H=wndGetHandleByLua(1); + lua_settop(L,4); + R=noxCallWndProc(H,lua_tointeger(L,2), + (lua_type(L,3)==LUA_TLIGHTUSERDATA)?(int)lua_touserdata(L,3):lua_tointeger(L,3), + (lua_type(L,4)==LUA_TLIGHTUSERDATA)?(int)lua_touserdata(L,4):lua_tointeger(L,4)); + if(R==0) + lua_pushinteger(L,0); + else if(R==(void *)1) + lua_pushinteger(L,1); + else + { + lua_pushlightuserdata(L,R); + } + return 1; + } + int wndSetProcL(lua_State *L) // wnd+0x178 - прок окна + { + wndStruct *Window=wndGetHandleByLua(1); + bool haveTable=false; + if(lua_type(L,1)==LUA_TTABLE) + haveTable=true; + if(lua_type(L,2)!=LUA_TFUNCTION) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + lua_pushlightuserdata(L,&noxWndLoad); + lua_gettable(L,LUA_REGISTRYINDEX); + if (haveTable) + lua_pushvalue(L,1); + { + lua_newtable(L); + lua_pushlightuserdata(L,Window); + lua_setfield(L,-2,"handle"); + lua_pushvalue(L,2); + lua_setfield(L,-2,"wndProc"); + } + lua_pushlightuserdata(L,Window->wndProcPre); + lua_setfield(L,-2,"oldFn");/// сохраним старую функцию + lua_pushlightuserdata(L,Window); + lua_pushvalue(L,-2); + /// сейчас стэк устроен так: -1=новаятаблица, -2=юзердата, новая таблица, + // табл из реестра, [юзердата из первого], функция, второй аргумент + lua_settable(L,-4); + /// 174 - 178 - какой из проков? + Window->wndProcPre=&newWindowProc; + + return 1; + } +class staticTextDataClass /// данные для статикстекста +{ +public: + staticTextDataStruct staticTextData; + + static void *Create(lua_State *L,int Idx)/// получает таблицу с параметрами окна, и кладет в нее себя + { + lua_getfield(L,Idx,"text"); + int NeedSize=lua_objlen(L,-1)*2; // какой длинны строку нам прислали + NeedSize=(sizeof(staticTextDataStruct)+NeedSize+0x3F)&(~0x3F);//вычисляем сколько нам надо памяти (с шагом в 64байта) + + staticTextDataStruct *Me=(staticTextDataStruct *)lua_newuserdata(L,NeedSize); // пускай луа выделит нам память - она же и будет за ней следить + Me->BoolA=0;Me->BoolB=0; + Me->Size=NeedSize-sizeof(staticTextDataStruct); + Me->DataPtr=Me->Buf; + mbstowcs(Me->Buf,lua_tostring(L,-2),Me->Size>>1); + lua_remove(L,-2); + return Me; + } +}; +class editboxDataClass +{ +public: + editBoxDataStruct editboxData; + + void *Create(lua_State *L,int Idx)/// получает таблицу с параметрами окна + { + int Top=lua_gettop(L); + editBoxDataStruct *Me=&this->editboxData; + lua_getfield(L,Idx,"password"); + Me->Password=lua_toboolean(L,-1); + lua_getfield(L,Idx,"onlyNumbers"); + Me->onlyNumbers=lua_toboolean(L,-1); + lua_getfield(L,Idx,"onlyAlphaNum"); + Me->onlyAlphaNum=lua_toboolean(L,-1); + lua_getfield(L,Idx,"maxLen"); + Me->maxLen=lua_tointeger(L,-1); // возможно MaxLen + if (Me->maxLen<1) + Me->maxLen=255; + + Me->entryWidth=-1;// стартовая ширина MB + Me->Param_6=0; + lua_settop(L,Top); + return Me; + } +}; +class ListboxDataClass +{ +public: + listBoxDataStruct listboxData; + + void *Create(lua_State *L,int Idx)/// получает таблицу с параметрами окна + { + listBoxDataStruct *Me=&this->listboxData; + memset(this,0,sizeof(listBoxDataStruct)); + int Top=lua_gettop(L); + lua_getfield(L,Idx,"maxLines"); + Me->maxLines=lua_tointeger(L,-1); // возможно MaxLen + if (Me->maxLines<1) + Me->maxLines=100;/// не стоит их много делать, память кушает + Me->LineHeight=18; + lua_getfield(L,Idx,"lineUnSelected"); + if (lua_isboolean(L,-1) || lua_toboolean(L,-1)) + Me->LineCanUnSelected=1; + else + Me->LineCanUnSelected=0; +/* Me->Password=lua_toboolean(L,-1); + lua_getfield(L,Idx,"maxLen"); + + lua_settop(L,Top); + return Me;*/ + return this; + } + + void CreateSlider(lua_State *L,wndStruct *Wnd) + { + int isSlider=false; + lua_getfield(L,1,"slider"); // что бы это таблица лежала под индексом 2 + getClientVar("wndCreate"); + if (lua_type(L,2)==LUA_TTABLE) + { + for (int i=1;i<=3;i++) + { + lua_pushnumber(L,i); + lua_gettable(L,2); + if (lua_type(L,-1)!=LUA_TTABLE) + break; + lua_getfield(L,-1,"type"); + if (lua_type(L,-1)==LUA_TSTRING) + { + const char *ControlType=lua_tostring(L,-1); + if (0==strcmpi(ControlType,"PUSHBUTTON")) + { + isSlider=false; + }else if (0==strcmpi(ControlType,"VERTSLIDER")) + { + isSlider=true; + } + else + break; // если ни то и ни другео то нафига мы тут вообще + } + lua_pop(L,1); + lua_pushvalue(L,3); + lua_pushvalue(L,-2); + lua_pushlightuserdata(L,Wnd); + if (0!=lua_pcall(L,2,1,0)) + { + const char *S=lua_tostring(L,-1); + lua_settop(L,1); + return; + } + lua_getfield(L,-1,"handle"); + + wndStruct *createdWnd=(wndStruct*) lua_touserdata(L,-1); + lua_getfield(L,-2,"wndControlProc"); // нужно вернуть дефлотный прок, ибо эти окна не имеют своих таблиц + createdWnd->wndProc=lua_touserdata(L,-1); + + listBoxDataStruct *listboxData=(listBoxDataStruct*)Wnd->someData; + if (isSlider) + listboxData->slider=createdWnd; + else if (listboxData->buttonUp==0) + listboxData->buttonUp=createdWnd; + else + listboxData->buttonDown=createdWnd; + Wnd->drawFn=&uniListBoxDrawFn; + lua_settop(L,3); + } + } + lua_settop(L,1); + return; + } + + +}; +class scrollboxDataClass +{ +public: + scrollBoxDataStruct scrollboxData; + + void *Create(lua_State *L,int Idx)/// получает таблицу с параметрами окна + { + int Top=lua_gettop(L); + scrollBoxDataStruct *Me=&this->scrollboxData; + memset(this,0,sizeof(scrollBoxDataStruct)); + return Me; + } +}; + + int wndLoad(lua_State *L) + { + void * Window; + if(lua_type(L,1)!=LUA_TSTRING) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + lua_settop(L,2); + if(lua_type(L,2)==LUA_TNIL) + {lua_pop(L,1);lua_newtable(L);}// если ничего не дали - то создадим новую + else if(lua_type(L,2)!=LUA_TTABLE) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + lua_pushlightuserdata(L,&noxWndLoad); + lua_gettable(L,LUA_REGISTRYINDEX); + + lua_pushinteger(L,++nowCreating);// записываем элемент + lua_pushvalue(L,2); + lua_settable(L,-3);//записываем в реестр ту таблицу, что нам подсунули + Window=noxWndLoad(lua_tostring(L,1),&newWindowProc); + lua_pushinteger(L,nowCreating--);// удаляем номерной элемент + lua_pushnil(L); + lua_settable(L,-3); + + if(Window==0) + { + lua_pushnil(L); + return 1; + } + lua_pushlightuserdata(L,Window); + lua_pushvalue(L,2); + lua_pushstring(L,"handle"); + lua_pushlightuserdata(L,Window); + lua_settable(L,-3);// Записываем в таблицу хэндл + lua_settable(L,-3);//записываем в реестр ту таблицу, что нам подсунули + lua_settop(L,2);/// и ее же и вернем + return 1; + } + inline int lua_getint(lua_State*L,const char *Name) + { + lua_getfield(L,1,Name); + return lua_tointeger(L,-1); + } + ListboxDataClass LD; + editboxDataClass ED; + scrollboxDataClass VS; + + int wndCreate(lua_State *L) + { + lua_settop(L,2); + if (lua_type(L,1)!=LUA_TTABLE) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + void *Parent=0; // родительское окно + if(lua_type(L,2)==LUA_TTABLE) + { + lua_getfield(L,-1,"handle"); + lua_insert(L,2); + lua_settop(L,2); + } + if (lua_type(L,2)==LUA_TLIGHTUSERDATA) + { + Parent=lua_touserdata(L,2); + } +/* +примерное применение + wndCreate( + { + x=100,y=100,w=200,h=30, + bgcolor='#FF00FF'; + { + type="PUSHBUTTON", + x=10,y=10,w=100,h=20, + id=1000, + status = "IMAGE+NOFOCUS" + wndProc=fn | nil + click=fn, + highlight=fn | "none" | "default"; + font="large"; + bgcolor='#332211'; + color='#112233'; + alpha=false; + hiliteColor='#123233'; + disabledColor='#112233'; + selectedColor='#112233'; + disabledImage="somename"; + selectedImage="somename"; + image="somename" + hiliteImage="somename" + text="Test1"; + tooltip="Test1 tooltip"; + drawFn=function (me) end + } + } + ) +*/ +/* + WINDOW + 10112 201 272 45 15 PUSHBUTTON; + STATUS = ENABLED+IMAGE+NOFOCUS; + STYLE = MOUSETRACK; + SELECTEDIMAGE = UIButtonSmLit; + HILITEIMAGE = UIButtonSmLit; + BACKGROUNDIMAGE = UIButtonSm; + ENABLEDIMAGE = NULL; + DISABLEDIMAGE = UIButtonSmDis; + IMAGEOFFSET = 0 -5; + TEXT = Access.wnd:Add; + TOOLTIP = Access.wnd:AddTT; + END + + +*/ + int x,y,w,h; + DWORD Flags=wfNoFocus+wfEnabled; + + x=lua_getint(L,"x"); + y=lua_getint(L,"y"); + w=lua_getint(L,"w"); + h=lua_getint(L,"h"); + if (w<1) w=10; + if (h<1) h=10; + + wddControl Wdd={0}; + lua_getfield(L,1,"status"); + if (lua_type(L,-1)==LUA_TNUMBER) + Wdd.status=lua_tointeger(L,-1); + else if (lua_type(L,-1)==LUA_TSTRING) + parseWindowStatus(&Wdd,lua_tostring(L,-1)); + + lua_getfield(L,1,"bgcolor"); + if (lua_type(L,-1)==LUA_TSTRING) + Wdd.BgColor=parseColor(lua_tostring(L,-1)); + lua_getfield(L,1,"image"); + Wdd.imageH=imageFromLua(L); + if (Wdd.imageH) + Flags|=0x80; + + lua_getfield(L,1,"enabledColor"); + if (lua_type(L,-1)==LUA_TSTRING) + Wdd.EnabledRectColor=parseColor(lua_tostring(L,-1)); + + lua_getfield(L,1,"disabledColor"); + if (lua_type(L,-1)==LUA_TSTRING) + Wdd.DisabledRectColor=parseColor(lua_tostring(L,-1)); + lua_getfield(L,1,"disabledImage"); + Wdd.imageDisabledH=imageFromLua(L); + lua_getfield(L,1,"hiliteColor"); + if (lua_type(L,-1)==LUA_TSTRING) + Wdd.HiliteColor=parseColor(lua_tostring(L,-1)); + lua_getfield(L,1,"hiliteImage"); + Wdd.imageHiliteH=imageFromLua(L); + lua_getfield(L,1,"selectedColor"); + if (lua_type(L,-1)==LUA_TSTRING) + Wdd.SelectedColor=parseColor(lua_tostring(L,-1)); + lua_getfield(L,1,"selectedImage"); + Wdd.imageSelectedH=imageFromLua(L); + + lua_settop(L,1); + lua_getfield(L,1,"offsetX"); + Wdd.offsetX=lua_tointeger(L,-1); + lua_getfield(L,1,"offsetY"); + Wdd.offsetY=lua_tointeger(L,-1); + + lua_getfield(L,1,"textColor"); + if (lua_type(L,-1)==LUA_TSTRING) + Wdd.TextColor=parseColor(lua_tostring(L,-1)); + lua_getfield(L,1,"text"); + if (lua_type(L,-1)==LUA_TSTRING) + wstringFromLua(L,Wdd.String,60);// возможно 64 + lua_getfield(L,1,"tooltip"); + if (lua_type(L,-1)==LUA_TSTRING) + { + wstringFromLua(L,Wdd.tooltipStr,62);// возможно 64 + } + lua_getfield(L,1,"font"); + if (lua_type(L,-1)==LUA_TSTRING) + { + Wdd.FontPtr=guiFontPtrByName(lua_tostring(L,-1));// возможно 64 + } + lua_settop(L,1); + + static int nextChildId=0x100; + lua_getfield(L,1,"type"); + if (lua_type(L,-1)==LUA_TSTRING) + { + const char *ControlType=lua_tostring(L,-1); + if (0==strcmpi(ControlType,"listbox")) + ControlType="SCROLLLISTBOX"; + void *DataPtr=NULL; + if (0==strcmpi(ControlType,"STATICTEXT")) + { + lua_pushstring(L,"__bindata"); + DataPtr=staticTextDataClass::Create(L,1); + lua_settable(L,1); // положим данные в таблицу окна + }else if (0==strcmpi(ControlType,"ENTRYFIELD")) + { + ED.Create(L,1); + DataPtr=&ED; + }else if (0==strcmpi(ControlType,"SCROLLLISTBOX")) + { + LD.Create(L,1); + DataPtr=&LD; + }else if (0==strcmpi(ControlType,"VERTSLIDER")) + { + VS.Create(L,1); + DataPtr=&VS; + }else if (0==strcmpi(ControlType,"PUSHBUTTON")) + { + Wdd.controlType=0x100; + } + wndStruct *Wnd=wndLoadControl(ControlType,Parent, Wdd.status,x,y,w,h, &Wdd,DataPtr); + if (Wnd==NULL) + { + lua_pushstring(L,"wrong args - unable to create control"); + lua_error(L); + } + + if ((Wnd->drawData.controlType & ctListBox)!=0) // если листбокс, то проверяем на слайдер + { + lua_settop(L,1); + LD.CreateSlider(L,Wnd); + } + + Wnd->wndId=nextChildId; + lua_pushstring(L,"wndControlProc"); + lua_pushlightuserdata(L,Wnd->wndProc); + lua_settable(L,1); + Wnd->wndProc=&newWindowControlProc; + lua_pushstring(L,"childId"); + lua_pushinteger(L,nextChildId++); + lua_settable(L,1); + lua_pushstring(L,"handle"); + lua_pushlightuserdata(L,Wnd); + lua_settable(L,1); + /*lua_pushlightuserdata(L,&noxWndLoad); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushlightuserdata(L,Wnd); + lua_pushvalue(L,1); + lua_settable(L,-3);*/ + lua_settop(L,1); + return 1; + } + + Wdd.controlType|=ctUser;// кастомный контрол + + + lua_pushlightuserdata(L,&noxWndLoad); + lua_gettable(L,LUA_REGISTRYINDEX); + lua_pushinteger(L,++nowCreating); + lua_pushvalue(L,1); + lua_settable(L,-3);/// кладем таблицу для события + + wndStruct *Wnd=wndCreate2(Parent,Wdd.status,x,y,w,h,&newWindowProc); + lua_pushinteger(L,nowCreating--); /// удаляем номерную таблицу + lua_pushnil(L); + lua_settable(L,-3); + if (Wnd==0) + { + lua_pushstring(L,"wndCreate2 Fail!"); + lua_error(L); + } + Wnd->drawFn=&uniWindowDrawFn; // наа рисовалка + Wnd->wndProcPre=&newWindowProc; + + Wnd->wndId=nextChildId; + lua_pushstring(L,"childId"); + lua_pushinteger(L,nextChildId++); + lua_settable(L,1); + + lua_getfield(L,1,"drawFn"); + if (lua_type(L,-1)==LUA_TFUNCTION) + { + Wnd->drawFn=&newDrawProc; + } + lua_settop(L,1); + + lua_pushlightuserdata(L,Wnd); + lua_pushvalue(L,1); + lua_pushstring(L,"handle"); + lua_pushlightuserdata(L,Wnd); + lua_settable(L,-3);// Записываем в таблицу хэндл + lua_settable(L,-3); + Wnd->drawData=Wdd; + + + lua_settop(L,1); + lua_getfield(L,1,"children"); + if (!lua_istable(L,-1)) + { + lua_settop(L,1); + lua_newtable(L); + lua_pushvalue(L,-1); + lua_setfield(L,1,"children"); + } + getClientVar("wndCreate"); //wndcreaet, children, table, + for (int i=1;;i++)/// создаем дочерние окна + { + lua_pushvalue(L,-1); + lua_pushinteger(L,i); + lua_gettable(L,1); + if (lua_type(L,-1)!=LUA_TTABLE) + break; + lua_getfield(L,-1,"handle"); + if (lua_type(L,-1)!=LUA_TNIL) + { + //что еще за хрень? почему дочернее окно уже создано? + lua_pop(L,3); + continue; + } + lua_pop(L,1); + lua_pushvalue(L,1); + if (0!=lua_pcall(L,2,1,0)) + { + const char *S=lua_tostring(L,-1); + break; + } + lua_getfield(L,-1,"handle"); + lua_pushvalue(L,-2); + lua_settable(L,2);/// children + lua_settop(L,3); + } + lua_settop(L,1); + return 1; + } + +}; +extern void InjectAddr(DWORD Addr,void *Fn); +extern void InjectJumpTo(DWORD Addr,void *Fn); + +void windowsInit() +{ + ASSIGN(noxWndGetID,0x46B0A0); + ASSIGN(noxWndGetChildByID,0x46B0C0); + ASSIGN(noxWindowDestroy,0x46C4E0); + ASSIGN(parseWindowStatus,0x004A0A00); + + ASSIGN(wndShowHide,0x0046AC00); + ASSIGN(wndShowModalMB,0x0046A8C0); + ASSIGN(wndSetFocusMainMB,0x0046ADC0); + + ASSIGN(wndLoadControl,0x004A1510); + ASSIGN(wndCreate2,0x0046C3E0); + + ASSIGN(wndGetCaptureMain,0x0046AE00); + ASSIGN(wndSetCaptureMain,0x0046ADC0); + ASSIGN(wndClearCaptureMain,0x0046ADE0); + + + lua_pushlightuserdata(L,&noxWndLoad); + lua_newtable(L); + lua_settable(L,LUA_REGISTRYINDEX); + + + registerclient("wndSetProc",&wndSetProcL); + registerclient("wndCall",&callWndProcL); + registerclient("wndGrabMouse",&wndGrabMouse); + registerclient("wndUnGrabMouse",&wndUnGrabMouse); + + registerclient("wndShow",&wndShow); // показывает/скрывает + registerclient("wndClose",&wndDestroyL); + registerclient("wndCreate",&wndCreate,1); + registerclient("wndLoad",&wndLoad); + + registerclient("wndGetId",&wndGetIdL); + registerclient("wndChildById",&getChildByIdL); + registerclient("wndSetAttr",&wndSetAttr); // для задания разных параметров + +} + + diff --git a/windowsUniModFunction.cpp b/windowsUniModFunction.cpp index 382fa48..bf96dba 100644 --- a/windowsUniModFunction.cpp +++ b/windowsUniModFunction.cpp @@ -1,46 +1,46 @@ -#include "stdafx.h" -#include "windowUniMod.h" - -// - -void *(__cdecl *noxCallWndProc)(void* Window,int Msg,int A,int B); -void *(__cdecl *noxWndLoad)(char const *WndName,void *WndProc); -int (__cdecl *noxWndGetPostion) (void* Window,int *xLeft,int *yTop); - -wndStruct *wndGetHandleByLua(int idx) // -{ - int Top=lua_gettop(L); - wndStruct *H=0; - if(lua_type(L,idx)==LUA_TLIGHTUSERDATA) - H=(wndStruct*) lua_touserdata(L,idx); - else if(lua_type(L,idx)==LUA_TTABLE) - { - lua_getfield(L,idx,"handle"); - if(lua_type(L,-1)!=LUA_TLIGHTUSERDATA) - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - H=(wndStruct*) lua_touserdata(L,-1); - } - else - { - lua_pushstring(L,"wrong args!"); - lua_error(L); - } - lua_settop(L,Top); - return H; -} - -extern void windowsInit(); -extern void windowMsgInit(lua_State*L); - -void windowsAllInit() -{ - windowsInit(); - windowMsgInit(L); - - ASSIGN(noxCallWndProc,0x46B490); - ASSIGN(noxWndLoad,0x4A0AD0); - ASSIGN(noxWndGetPostion,0x46AA60); +#include "stdafx.h" +#include "windowUniMod.h" + +// сюда все функции которые связанны с окнами и юзаются в нескольких файлах + +void *(__cdecl *noxCallWndProc)(void* Window,int Msg,int A,int B); +void *(__cdecl *noxWndLoad)(char const *WndName,void *WndProc); +int (__cdecl *noxWndGetPostion) (void* Window,int *xLeft,int *yTop); + +wndStruct *wndGetHandleByLua(int idx) // достаем хендл окна по идиксу +{ + int Top=lua_gettop(L); + wndStruct *H=0; + if(lua_type(L,idx)==LUA_TLIGHTUSERDATA) + H=(wndStruct*) lua_touserdata(L,idx); + else if(lua_type(L,idx)==LUA_TTABLE) + { + lua_getfield(L,idx,"handle"); + if(lua_type(L,-1)!=LUA_TLIGHTUSERDATA) + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + H=(wndStruct*) lua_touserdata(L,-1); + } + else + { + lua_pushstring(L,"wrong args!"); + lua_error(L); + } + lua_settop(L,Top); + return H; +} + +extern void windowsInit(); +extern void windowMsgInit(lua_State*L); + +void windowsAllInit() +{ + windowsInit(); + windowMsgInit(L); + + ASSIGN(noxCallWndProc,0x46B490); + ASSIGN(noxWndLoad,0x4A0AD0); + ASSIGN(noxWndGetPostion,0x46AA60); } \ No newline at end of file From 4c60332f5973394387d8a303455f36216ec78fd2 Mon Sep 17 00:00:00 2001 From: Darkclainer Date: Mon, 25 May 2020 19:34:44 +0300 Subject: [PATCH 2/3] Fix gui.cpp encoding --- gui.cpp | Bin 21870 -> 10600 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/gui.cpp b/gui.cpp index 2c0b8a3799693c2a5ebc6d0c54742527131ea835..651335ed3c85076379451e9ffc1daeea30373aad 100644 GIT binary patch literal 10600 zcmds7{c_vJ5&xTdijy)!10Yn95-opFP=^#nNi8jNDA|-I)6qZ#B%y%-4gi*9ZO# z|0MYm@tR8>_5<7Y(5dK73W?$gS+IBtt7YL3bzL)z?4aYLYY5Nbh|cg%gS)o-zIbjE z&kj{3mn#H5LUx8h=m+396x1GrR36KSU;*sNj*elLf=X4Iy~o`q;}5mls3^!)+EVlQ zzA?P#Mvw)OL!|AS*1`2PgXq&OQWJ_Fn+Ku3w zBXa$TQ7E7rHMKl0mp32O@9vgsxyaK+WHld2TiwX8ZQa0j-?1TmEua@zqsLEhqi3Pb z1;z+Hg-oy@a1*#vTGRRzJFy9513V}8wsEI?hZT!V>uec!9uQ+hl?+AesH-rESlbP4hKdkDeNNC?AgJFdRnQp3 z-!Y7J6cv{)bPW_0{>WH`7lNq*plSlzyBV~ZfEpRlQsKoC3T-Ie?d=V9YpYUW&zZ8f zy}b?(ciD5Lf#bEcwYBL#rthXdOuwDJn!cTVHT@T>Y{J8v*-P;_`-0BQm&ETmt^?dQ zL7#v-1O{qLFL-hsfgj=QYz6*xduS@|&^$Ye%*bY1TNj5W)0!ba%pRF=uz4y*Pzc%i zEMoAu5H?3a-#|W*?{el!TVJi{MI;3w&;vIoj&JD8D>v^j zv;)hGOfCU8QjUu$eb=KXNP8C(%J1#Tfi3&XYk0(?8NX=S;)T zkc@IZ!6?}`6#hl!G$4hXLSO+A3yJ1@O;mm!Lm4WNWg&uud~p;}mXIamt7;vCB&>B- zw>_wPmbu3ufe7ni5S5n=kOs1sB2YTWqynITvPX_Lv_YUkIC7%?6+=)2j=}k7@YgpX zkE}n03YDvbWH?^nwbh|L0!zS_G87!pR5;k`uIu+Pc1snC>H;ng@t$CH(2mb&3MbQ4 zh3&HvgT?)eP*sfti=yFnC=|{E+x!F{Nu&)FsgH#!&H*1v@(X;V!#r6u&8Yeiif@q@ zkQFHhTa+qjrX_+HN-{QAa$OU8a&-#H)=S7xS6#9NiW-;a3(_W3H)(wrwLW*E3&(b? zxlz{EjvqH4!!sD_1>`!&9uV&FU1jJwypY9nx#fuhC0*N6q1$Y#bQAg8^hdaad@+3k zDffrj*Kjj=HT#Cm{xW^b;A-+__8BDP?=T(1_iuDI`x0{TJ2w4x_7(jH$@&$WzG2fJ z0sU_JPx$}U>`Oqun|(HWIs2L?!N%$FF5F5y%TVyErZO%Osy?!;9SF_9hl>`J-C+7; zAi*`8h(tZdHHIIP_*ol_jiMOT1{0%5GZ2`t7*yIFNK20IDZ&7Qu|AlP`*5=;8ZR>x zz?Q12%8GQLbGy6-&3{0};0r3kW`9M^XD`tA%_Zd(iz;K)nI| zzn^^$B0qz_!nkCBVi@fgp&gyn*d#S@in`DdK&T72C5B~?g^uPz0n2KtHWiwtbiVJn zPGs-vW1VY56##O{N6&F0hgNV&+-PV9V%xYBMbNyY!K@IUs};Pq!ZVh#se5CJnp+m! zgY_UL@=H64{DIP@2^<&y7p<>P$WZnQ#Z;#a96<>#&m{?qCyRtlU@C^gwyM zqtc-#84Ng~g@qYt6Z2|e#l$->F9H&2{Bz%TZPVii9+_Sefo{zoBnMV+usS;IXX$}r zL$H$fbZ{rxPKutKydy5gBJqqo3l0l7YOx!E-Ie%e9cLd=9!W6I+PQLEi`Snnzo$2$ z2#ERM0_UI)3>nJ8yr%MXR<}d{+C~rtIVKAboAX3#OH2UiI+h(k9Zm)Z*Kz@JFvu$@ zvs3fuL$H$fWN~XCLu!vGMXORH=_Fz=XEX&9BC=@E|Mi(pIpKmm5`r^dia1Rh3w{+T>b;V%tg~QZ(JT=rhI5s~i&IHzHZd_~(!@^lNDvol zoCPy*HRrRunk500ab+7W3`JnFH8(8}G8|SWVtyjei||4zc+M(h8nt7(CBS_<-I|^7 zVLW#5PZXMH3^Ll-Na0UPbBRvSGllVL;?l&~L^(;u^ITn+09{HF;uiZe39m72m?Qv_ z@rkx73@Uk=G)N^Ck^~b}+ktl?hyG}Om`h#;=+bkt4w1JX0Z9d!-uA2 zHK6hJiQ<(u_2L1)xHeX|Vf-MnuaydqHEHBNnPfiDRDRlPbF}gxL#}utoNxCmDs-}t zI~-z0wmw~)j5~SK>io`KkVg2yh~Ae5E9pXR9xlQ_Vy9sO0ZNn&cNzu6vA;uai9T?< zDc-WNfjJI7tLp!H=V81im*OfJ@xvqL{x1?Q6)v9SoW%nq8&X+>D7rE{oX~SzD2%J> zZ#OCrvoxZ>lxW0OKp-}3-ZLovj}k;R&*8sLI*{Cwb)3WVxxAehAac_G5P#b4t?q=3 z%a=+HYo0yjglpL@Pq^t+BAqQ~XZT~CaA5Zp&-}!;RCYaq-UFUV@RC9i=gZld8D2xy z!m|cmF1T(gtz$akSwF;ij8|w0m&?`7o%P)^4nYco56E8BdY6BHaNzwBnuT@C3dHXo z@T+Kgwea=eBKR>hgx?$dyW#cV*nb~5zVLezIqreyM9Ggj;Ab=Z8DDWydqsv6>PJTh zdxr`f<*6Th=%oFO8Jfog4R$|$~^{KKjQx1Pbxe@z7t z@v|y8N9J;)qf_06nAQDimQ|{H60mADD;YAx{x1hS*x60l07Q=g)SZn{Ejk3Vf{C_O z(tqOU`bKLfBOCHe_qbvxx3A2Y*KC{uid7-OZncr&Db;rH!yo}`-G$$!r3@&+5=@ye z5HJ+n6t5H!8@u-^^%A`KmiHL4!#DAl(4(^hxINikq^!VaBI1f(v`9e^7tuM`d3h+n z^MM;Enj*a*UVOa)nW{8o_Hp&WHOQ4qx(Nbh=4zO?Ub0D`F|ne{PxLw@t9k;!hJu8r m{z4xAYzJUP&yM7;LyZ^o2rQC(zXghWii<>O@rVRVFa85LulVHv literal 21870 zcmeHPZBtvv72Xf}qR#X`$nK0IuxP->HhzHwfx&JF@fZ^9>0~k(u%i|O1EfGn{zCiP z@{jsFdvtWp-n;io!r0TM84W_ZclYdhf7`wK_20k#>rbH<4#G~@4?l(7uoqh4W;h9_ z_`Dt7hV$^}@FTALG5jIqM!v_WQ;et|br#py4Ts?@e2dk3;cI-}b+ZVcc${MWcK89W zorn$bYK2MMIRq}Nz_Axr@R=i@0oz`9ht*F3uNx-f+<)M14|6B+O-H`Kh-2J;9O)Ro z&IZ9)#&Wbe+2bytc76VYb5Oc(uZO<6ff`mKt~P|4aPMH%6ms8MtkO zGpnHIG;Bm%xz0O$?uCEiYDyXTky6&d>N}Aulw1q2cEFWw!2JQ=Cli<*z!W}DhONjc z%FkbYHuyFU$B6q&;JSnVOTc9xf5%QPvg+s%l`9HUc%ZnShc&GA7Hb*i7hw}?9=R*j zyIqX&^!OYA|kyc;gUI%NMo>PJz#B9IMkha+*t>JAhQ^3p&A5xP_~`V_2zbNQ%QcAYaG&{*Ktq)mCF%qC6Q%+78FEhaca+=e42=&ngeI2JUXd zE@@MOrN_j3l%gj|SMuCD0z}Gf&+)O^Q(X_Qy-!FvEtFZ*Yb6$I_C%fXv}-KV>}13F zgI8fbH1SdknuL6(p^wve-474LVz?Kc;ysFno~=Q@m6#>V&=w0jSF z!yIim^ieQZ+kZ940EWR`9tmrO`?{Y+442oP-vbS1Rg66?Y#3$L;`6)2u33 z)P#Ci9=GeUJ?j5u%%GczFJ!c!bf*#LUiSa5_WyU|f8kOyu^#U^USO12xsL83zhgCE zcjhr}9TmhHUajymUac4zj{*5T^08hrx`Vo96BsRG&ITgqB0fLG=S^In03>2O(Wj>g ze?%%MIYtZG>KxwvtBBVmVBP?f&rlhCRtZVCqjO(`+j!}>w=r^&MwNIE@MdsdVbep% z9Ok*4s~BGnFqajcgeRD*Qm5}x{t?zf#B&;WG9$T#cV6X;&)|(b_Dyh!oVbm9?Ko;8 zOko7)D&9?u*pL3Zm04vGBg?C-jI;{p-UbKMGkQA6oB42Oz=7sK8##)ar@WT`l&@j@ zO95x{obYBV;8BCG0`GnWJX%6MJlaUnvl{P^BfN7j zUT?#X==jI6GW|TvHWnI>8#9e*)TCcE9->N}K@^&4%r&}$D=V>X?Z%o_b>Qa#&a(3T z0Y8ruYf-vLf#7f1)>+>|CCgcXeI3G9*I;SepnzS6ZB(hOdf7=}|6vk$JB1pSSC=Cs ztM|Uf45~=6xu{s5=)N{+y+7Y)Y@UH_a z63Ci!n#Cy`^Hyc6WsS}X;t2H`b4#w$0mPg5b^xyI<24aImFckOx?WX%QEL~R7EpN? zx#R7nZgp1fl9AF+>N=^1)T_Gsd-O|40joOFWfTc7It6@Weo}B6- zOz$T9)@CwLoRw21(irC|ijRYlt+9(4kFeC*#O-#E#Xzrg>hfrM|;_pDUYo zlP`HKns6L0dMH}>=s2zczg6_aHi7j9;vDOgMSNSV!PuZ5LgSc^A0yMJ9nv<98_GGA zw%5Z}pU-)TTBg4UsI()aX(O)VZC<0`SHR=~^z6dE&ECHQR{MjiUebhg3<}tL>foLF zOMbTyJsHf5GS!9)#X=&-twr_@o|WO3Bcs1iMp6l~!*sE(g$dfH|$9 zg>2&y-r3*va+E+00}hWe!oQX}6uy&q?=A zq}z4P&xZetM`1=BT zL<@}vc%N>p0>%R7cL7(ZG{4eC$9NO*oO-ntaih-ZRq9$Rq1tTr40PY4jJ%)4bT zP5SJjx#baMh~$GoRsNsj8mm9qOS;I6n1p{lhhMpccR!ZbFXDASOZ=fwDBX1Sy6O9R z_)iI@QX}k6gyii=qX;Wkt*XVt2;|$b-XqUg18bFUQoaW%JccY=fuAUkR`@zfv5Qa3 zxHsLni%;{2Zz}aA=*1IUdxU#mV(c8G`KYnfm!!`Wo4}cMwMc+5lKz(-m=*V{$fb*# z5w9JWt=ceXZy{msyPSYBq0m>$^xWF#wr(i-N-ZEZmVH0N=Y9M!6JlqSyuN_0nI2dV zKy7wB_<5LVX30*7LRXKFqq_^5EjCDJr`*4>NT1d+tcGF9DX>?mUJgDr`#jSap)zjwHN6x4N8W?X0pbMgK{6SUaOz{|SC--^PjOD`6f@Iq zrBL`{vC}AJUz3%P>_4Y9dYMm$ko6&6l=pV@qgK}$XR7#N``jOsGulm5Zd76OF>z47 zi!V0I>_C%frCyR%UTX9_WevWSu}${PRSP9kIfImTlR8skKQ%4CZ*F%aXAwS{wpT$U zyd_jE^!2;29^Wse_xBh|S6~A;YxPU4ln(0HIlP68Vs0^fK5fQ(2Sy<7<+5f}NZtcT zrXjpfaaFC)Vd0SNmuP8 z{1ISz)(EYs*9-}J6U2NSEeN>^h|xRIcltRx=7ob3u=%k8APNqxIargZEHKjNfH!(#~4i zAz>B$SL~s2$M<{ZtIA!OE#!VJ^q)HY6_{DEKK%~(dW;EAaPT9(FT~j*7Oal9FlNi) zpn5<}l=FE3+qJ&0oLH9bFm?4DXPWJ0I#utrxO>lf-|D`+*OL7KT}|t{iRgRFC(%qo zIWNLBy$=4i{E>Eur1!B2+vO=r>#oQ-J>jJ1g3U9p;=KudiRWwCH_!rxjiILdRa5)7 z`o-*@aZkLX&!5BtN{4YA`&SCoQweOIa5Ep5KM&}!zA6+ui^zDM(w_5ub+oI;{}j}Z z=JiMAC3};4rqFY>o*%}GqnI0P#XN&`FYEgaWD=auNInin>b+ArryAX-*T;kF_31YX z=S(b;kCu_KPT-+-g8FvnG@pI~RJk53Z>{Ji?yxbGGi2jLB zT}cl)ujA6uQQf*6NMg8_r!hFyayf6P94co$)pHe-G;>jZUe>gn2TA#7UO=?Ou+rx$ zQeU1*nX~0gDm#%gsE}o!g`ER_e=^WjuhZW9>AA=@B$CeO_x$|S-x*I*u5jPC>a;LV zqZ2>VSH_R(@jP8jeEfK;zwDFN<7%;{F~(=^09LQ`3YMmp>Urk<0C&x%B9yd>$@u|W zmphCKSv|+-KA;KuWz8y{dXHiLQtiL&FU}J?9%aS_@R!qQUJg|rz@N}a#}u<7Flj7AUr3KUcQ)MQ3 zVw3ZyJ;)@@((|L_WQvbn<~Pb1sD+v)wiA09SEE;;i`?}(Mm9(MsM|){24uu+MNb?5 zuGLk&Hr24_rTw85c;zm#37%hImMCYf`P6k6fAjdujd+B!L42BQ7o#Yl9h@QKdFR_W zkIwEA*YP^jg$G>d&v+gs_8#MT27dS`?$es*%t2ZPtn0DK9P~DxtQdv?X)pTt54CTV z8Kb`UEqOcj7+Pdt1~7bX`Se+y59tYlCS;$JYFgczx5$s?Ga?>$#a1J5j@qJjrC!DI z9bH>Fsd3W03TwtCXum#v`YC)1b%oK8QB!hi`Obb+eSh$ODUPZf%lq)8)9hJg^Km`X z+;7k;&BQZs#>u>WsT`{E09Hm`9#?}>?B~@(;fVyE^4y2t<|!6x#22uK8AO#~_!hgi z`IU;1MWKF7ukw3_;`PWf_|bY#pT-X`Lzx}J7yQ5G9(k)$E2{D(tSM3*xGJ2wszb5( zIJV4Q$cI_7L^8#ayefAQ(!94S!{#}s{UpP#&wQ#o1UzL=XzV5Oqyj%N58<;PdofpU zVTbnud&E3JrB$3f)xru+Izv{U6CR(fc|Yha+CA>k@mwQMsaI1bCrW(faWa6_1cvNy z@;M*wC~_}<7L~;ks$>4zg7&F&??k_Az9;|Xo%hmTu&^i2o`c%IMP8iZxhGaL+~4+l zn|d|FPji_XcSPlD?rWD!=aJpZEmGn-8#+B$J%D;qGhInTv#N2P537qs- z&@^vMc_mn>{VTU@Cs=nIiGBbY-`WzJ}iNX8(Jcqc>v~x{De7y(;6h!5 z^)d`b3OhGq+*OvN)XFQQ+0wXB4KqeB--oH9pg7J}6gkWLXq?OMsLIOqd#<+Xu$9WO zN6xBnm8yHbhdVxe_0ahh^zJxo3_EARm4=NOXFb2uqjn?ISRB&pSB0yQP4a*u^z^Q+ JLGAh_{0EQFnM(iw From d2f90d75c9949af45ffe2128b5da4066f0482c4d Mon Sep 17 00:00:00 2001 From: Darkclainer Date: Mon, 25 May 2020 19:42:04 +0300 Subject: [PATCH 3/3] Treat gui.cpp as a text file --- gui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui.cpp b/gui.cpp index 651335e..ed038f1 100644 --- a/gui.cpp +++ b/gui.cpp @@ -431,4 +431,4 @@ void guiInit() registerclient("stringDraw",stringDrawL); registerclient("stringGetSize",stringGetSizeL); -} \ No newline at end of file +}