Subversion Repositories WoWGM

Rev

Rev 21 | Rev 32 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "pch.h"
#pragma hdrstop

#include "ConsoleClient.h"
#include <Os/W32/OsFile.h>

/****************************************************************************
*
*   Client memory addresses
*
***/

#define  CONSOLECOMMANDDESTROY  0x007685C0;


/****************************************************************************
*
*   Client symbol pointers
*
***/

void (*ConsoleCommandDestroyPtr)() = *(void(*)())CONSOLECOMMANDDESTROY;


/****************************************************************************
*
*   Privates
*
***/

static char s_fileName[260] = {};

//===========================================================================
void ConsoleCommandDestroy () {
        // Remove the function trampoline
        DETOUR_INIT;
        DETOUR_DETACH(ConsoleCommandDestroyPtr,ConsoleCommandDestroy);
        DETOUR_COMMIT;

        ConsoleCommandUnregister("new");
        ConsoleCommandUnregister("run");
        ConsoleCommandUnregister("end");
        ConsoleCommandUnregister("ver");

        // Call the original function
        ConsoleCommandDestroyPtr();
}

//===========================================================================
BOOL ValidateFileName (const char* fileName) {
  if (fileName && *fileName) {
    if (strstr(fileName,"..") || strstr(fileName,"\\")) {
      ConsoleWrite("File Name cannot contain '\\' or '..'",ERROR_COLOR);
      return FALSE;
    }

    const char* fileExtension = strrchr(fileName,'.');
    if (fileExtension&& *fileExtension) {
      if (_strcmpi(fileExtension,".wtf")) {
        ConsoleWrite("Only '.wtf' extensions are allowed",ERROR_COLOR);
        return FALSE;
      }
    }
    return TRUE;
  }

  return FALSE;
}

//===========================================================================
BOOL CreateWTFFilePath (char* filePath, unsigned int size) {
        char buffer[FILENAME_MAX] = {};

        if (filePath && *filePath && size != 0) {
                SStrCopy(buffer,"WTF\\",FILENAME_MAX);
                strncat_s(buffer,filePath,FILENAME_MAX);

                char* extension = strrchr(filePath,'.');
                if (extension && *extension) {
                        if (_strcmpi(extension,".wtf")) {
                                ConsoleWrite("File must have '.wtf' extension",ERROR_COLOR);
                                return FALSE;
                        }
                }
                else {
                        strncat_s(buffer,".wtf",FILENAME_MAX);
                }
                SStrCopy(filePath,buffer,FILENAME_MAX);
                return TRUE;
        }

        return FALSE;
}


/****************************************************************************
*
*   Command definitions
*
***/

//===========================================================================
BOOL  ConsoleCommand_CreateExec (const char* cmd, const char* arguments) {
        if (ValidateFileName(arguments)) {
                char folder[FILENAME_MAX] = {};
                char filePath[FILENAME_MAX] = {};

                SStrCopy(s_fileName,arguments,FILENAME_MAX);
                SStrCopy(filePath,s_fileName,FILENAME_MAX);

                if (CreateWTFFilePath(filePath,FILENAME_MAX)) {
                        if (OsFileExists(filePath)) {
                                ConsoleWrite("File exists are you sure you want to Overwrite Y / N ? ",WARNING_COLOR);
                                g_ExecCreateMode = EM_PROMPTOVERWRITE;
                        }
                        else {
                                SStrCopy(folder,filePath,FILENAME_MAX);

                                char* dirName = strrchr(folder,'\\');
                                if (dirName)
                                        *dirName = 0;

                                if (OsDirectoryExists(folder)) {
                                        g_ExecCreateMode = EM_RECORDING;
                                        ConsoleWrite("Begin Typing the commands",ECHO_COLOR);
                                }
                                else {
                                        ConsoleWrite("Error! WTF folder does not exist.",ERROR_COLOR);
                                        g_ExecCreateMode = EM_NOTACTIVE;
                                }
                        }
                }
        }
        return FALSE;
}

//===========================================================================
BOOL ConsoleCommand_CloseExec (const char *cmd, const char *arguments) {
        BOOL result = FALSE;
        if (g_ExecCreateMode < EM_APPEND || g_ExecCreateMode > EM_WRITEFILE)
        {
                ConsoleWrite("You must type 'new' 'filename' to begin creating an Exec file",WARNING_COLOR);
                result = TRUE;
        }
        else
        {
                char filePath[FILENAME_MAX] = {};
                SStrCopy(filePath, s_fileName, FILENAME_MAX);

                if (CreateWTFFilePath(filePath, FILENAME_MAX))
                {
                        HANDLE hFile = OsCreateFile(filePath,FILE_ALL_ACCESS,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,(HANDLE)0x3F3F3F3F);
                        if (hFile == INVALID_HANDLE_VALUE)
                        {
                                ConsoleWrite("Error trying to create the file.",ERROR_COLOR);
                        }
                        else
                        {
                                if (g_ExecCreateMode == EM_APPEND)
                                        OsSetFilePointer(hFile,CREATE_ALWAYS,0i64);

                                DWORD count = 0;
                                DWORD bufLen = SStrLen(g_ExecBuffer);
                                COLOR_T color;
                                const char *str;
                                OsWriteFile(hFile,g_ExecBuffer,bufLen,&count);
                                if (count)
                                {
                                        color = ECHO_COLOR;
                                        str = "File written successfully";
                                }
                                else
                                {
                                        color = ERROR_COLOR;
                                        str = "Error Writing ExecFile";
                                }
                                ConsoleWrite(str,color);
                                OsCloseFile(hFile);
                        }
                }
                g_ExecCreateMode = EM_NOTACTIVE;
                memset(g_ExecBuffer,'\0',sizeof(g_ExecBuffer));
                result = TRUE;
        }

        return result;
}

//===========================================================================
BOOL ConsoleCommand_RunExec (const char *command, const char *arguments) {
        BOOL result = FALSE;
        char filename[FILENAME_MAX] = { '\0' };
        char tmp[FILENAME_MAX] = { '\0' };
        char lineBuffer[128] = { '\0' };
        char param1[32] = { '\0' };
        DWORD bytes;

        int verbose = 0;
        if (sscanf_s(arguments, "%260s %32s", filename, sizeof(filename), param1, sizeof(param1)) != 0)
        {
                if (!_strcmpi(param1, "verbose"))
                        verbose = 1;
                result = CreateWTFFilePath(filename, 260u);
                if (result)
                {
                        HANDLE hFile = OsCreateFile(filename, GENERIC_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
                        DWORD fileSize = GetFileSize(hFile, NULL);
                        char *readData = (char *)calloc(1, fileSize +1);
                        if (!readData)
                        {
                                ConsoleWriteA("ConsoleCommand_RunExec, Line %d: call to calloc() failed", ERROR_COLOR, __LINE__);
                                return 0;
                        }
                        if (OsReadFile(hFile, readData, fileSize, &bytes))
                        {
                                char *bufferPtr = (char *)calloc(1, bytes + 1);
                                if (!bufferPtr)
                                {
                                        ConsoleWriteA("ConsoleCommand_RunExec, Line %d: call to calloc() failed", ERROR_COLOR, __LINE__);
                                        return 0;
                                }
                                memcpy((void*)bufferPtr, readData, bytes);
                                if (bufferPtr)
                                {
                                        char *token = 0;
                                        char *nextToken = 0;
                                        token = strtok_s(bufferPtr, "\r\n", &nextToken);
                                        if (token)
                                        {
                                                do
                                                {
                                                        SStrCopy(lineBuffer, token, 128u);
                                                        if (lineBuffer[0])
                                                        {
                                                                if (verbose)
                                                                {
                                                                        _snprintf(tmp, FILENAME_MAX, "Executing ->%s", lineBuffer);
                                                                        ConsoleWrite(tmp, ECHO_COLOR);
                                                                }
                                                                ConsoleCommandExecute(lineBuffer, 0);
                                                        }
                                                        token = strtok_s(NULL, "\r\n", &nextToken);
                                                } while (token && *token);
                                        }
                                        else
                                        {
                                                result = 0;
                                        }
                                        free((void*)bufferPtr);
                                }
                                else
                                {
                                        result = 0;
                                }
                        }
                        else
                        {
                                if (*command)
                                        _snprintf(tmp, FILENAME_MAX, "Unable to load file %s", filename);
                                else
                                        _snprintf(tmp, FILENAME_MAX, "Unknown command: %s", arguments);
                                ConsoleWrite(tmp, ERROR_COLOR);
                                result = 0;
                        }
                        OsCloseFile(hFile);
                        free(readData);
                }
        }
        else
        {
                ConsoleWrite("Invalid number of parameters", ERROR_COLOR);
                ConsoleCommandWriteHelp(command);
        }

        return result;
}

//===========================================================================
BOOL ConsoleCommand_Ver (LPCSTR command, LPCSTR args) {
#ifdef NDEBUG
        ConsoleWriteA("WoW [Release] Build 12340 (%s)", DEFAULT_COLOR, __DATE__);
#else

        ConsoleWriteA("WoW [Debug] Build 12340 (%s)", DEFAULT_COLOR, __DATE__);
#endif

        return TRUE;
}


/****************************************************************************
*
*   External functions
*
***/

//===========================================================================
void ConsoleCommandInitialize () {
        // This function is called internally,
        // so only setup a trampoline for ConsoleCommandDestroy()
        DETOUR_INIT;
        DETOUR_ATTACH(ConsoleCommandDestroyPtr,ConsoleCommandDestroy);
        DETOUR_COMMIT;

        // Replace the client's "ver" command with our own
        ConsoleCommandUnregister("ver");
        ConsoleCommandRegister("ver",ConsoleCommand_Ver,DEFAULT,NOHELP); 

        ConsoleCommandRegister("new",ConsoleCommand_CreateExec,CONSOLE,"[File Name] starts recording a new script");
        ConsoleCommandRegister("run",ConsoleCommand_RunExec,CONSOLE,"[File Name] Runs a wtf file from the WTF folder");
        ConsoleCommandRegister("end",ConsoleCommand_CloseExec,CONSOLE,"Stops recording script");
}