Subversion Repositories WoWGM

Rev

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

Rev Author Line No. Line
3 tristanc 1
#include "pch.h"
2
#pragma hdrstop
3
 
4
#include "ConsoleClient.h"
5
#include <Os/W32/OsFile.h>
6
 
7
/****************************************************************************
8
*
31 tristanc 9
*   Client memory addresses
3 tristanc 10
*
11
***/
12
 
31 tristanc 13
#define  CONSOLECOMMANDDESTROY  0x007685C0;
3 tristanc 14
 
15
 
31 tristanc 16
/****************************************************************************
17
*
18
*   Client symbol pointers
19
*
20
***/
21
 
22
void (*ConsoleCommandDestroyPtr)() = *(void(*)())CONSOLECOMMANDDESTROY;
23
 
24
 
25
/****************************************************************************
26
*
27
*   Privates
28
*
29
***/
30
 
31
static char s_fileName[260] = {};
32
 
3 tristanc 33
//===========================================================================
31 tristanc 34
void ConsoleCommandDestroy () {
3 tristanc 35
	// Remove the function trampoline
36
	DETOUR_INIT;
37
	DETOUR_DETACH(ConsoleCommandDestroyPtr,ConsoleCommandDestroy);
38
	DETOUR_COMMIT;
39
 
40
	ConsoleCommandUnregister("new");
41
	ConsoleCommandUnregister("run");
42
	ConsoleCommandUnregister("end");
21 tristanc 43
	ConsoleCommandUnregister("ver");
3 tristanc 44
 
45
	// Call the original function
46
	ConsoleCommandDestroyPtr();
47
}
48
 
31 tristanc 49
//===========================================================================
50
BOOL ValidateFileName (const char* fileName) {
51
  if (fileName && *fileName) {
52
    if (strstr(fileName,"..") || strstr(fileName,"\\")) {
53
      ConsoleWrite("File Name cannot contain '\\' or '..'",ERROR_COLOR);
54
      return FALSE;
55
    }
3 tristanc 56
 
31 tristanc 57
    const char* fileExtension = strrchr(fileName,'.');
58
    if (fileExtension&& *fileExtension) {
59
      if (_strcmpi(fileExtension,".wtf")) {
60
        ConsoleWrite("Only '.wtf' extensions are allowed",ERROR_COLOR);
61
        return FALSE;
62
      }
63
    }
64
    return TRUE;
65
  }
3 tristanc 66
 
31 tristanc 67
  return FALSE;
3 tristanc 68
}
69
 
70
//===========================================================================
31 tristanc 71
BOOL CreateWTFFilePath (char* filePath, unsigned int size) {
11 tristanc 72
	char buffer[FILENAME_MAX] = {};
3 tristanc 73
 
74
	if (filePath && *filePath && size != 0) {
11 tristanc 75
		SStrCopy(buffer,"WTF\\",FILENAME_MAX);
76
		strncat_s(buffer,filePath,FILENAME_MAX);
3 tristanc 77
 
78
		char* extension = strrchr(filePath,'.');
79
		if (extension && *extension) {
80
			if (_strcmpi(extension,".wtf")) {
81
				ConsoleWrite("File must have '.wtf' extension",ERROR_COLOR);
82
				return FALSE;
83
			}
84
		}
85
		else {
11 tristanc 86
			strncat_s(buffer,".wtf",FILENAME_MAX);
3 tristanc 87
		}
11 tristanc 88
		SStrCopy(filePath,buffer,FILENAME_MAX);
3 tristanc 89
		return TRUE;
90
	}
31 tristanc 91
 
3 tristanc 92
	return FALSE;
93
}
94
 
95
 
96
/****************************************************************************
97
*
31 tristanc 98
*   Command definitions
3 tristanc 99
*
100
***/
101
 
102
//===========================================================================
31 tristanc 103
BOOL  ConsoleCommand_CreateExec (const char* cmd, const char* arguments) {
104
	if (ValidateFileName(arguments)) {
11 tristanc 105
		char folder[FILENAME_MAX] = {};
106
		char filePath[FILENAME_MAX] = {};
3 tristanc 107
 
11 tristanc 108
		SStrCopy(s_fileName,arguments,FILENAME_MAX);
109
		SStrCopy(filePath,s_fileName,FILENAME_MAX);
3 tristanc 110
 
11 tristanc 111
		if (CreateWTFFilePath(filePath,FILENAME_MAX)) {
3 tristanc 112
			if (OsFileExists(filePath)) {
113
				ConsoleWrite("File exists are you sure you want to Overwrite Y / N ? ",WARNING_COLOR);
114
				g_ExecCreateMode = EM_PROMPTOVERWRITE;
115
			}
116
			else {
11 tristanc 117
				SStrCopy(folder,filePath,FILENAME_MAX);
3 tristanc 118
 
119
				char* dirName = strrchr(folder,'\\');
120
				if (dirName)
121
					*dirName = 0;
122
 
123
				if (OsDirectoryExists(folder)) {
124
					g_ExecCreateMode = EM_RECORDING;
125
					ConsoleWrite("Begin Typing the commands",ECHO_COLOR);
126
				}
127
				else {
128
					ConsoleWrite("Error! WTF folder does not exist.",ERROR_COLOR);
129
					g_ExecCreateMode = EM_NOTACTIVE;
130
				}
131
			}
132
		}
133
	}
31 tristanc 134
	return FALSE;
3 tristanc 135
}
136
 
137
//===========================================================================
31 tristanc 138
BOOL ConsoleCommand_CloseExec (const char *cmd, const char *arguments) {
139
	BOOL result = FALSE;
3 tristanc 140
	if (g_ExecCreateMode < EM_APPEND || g_ExecCreateMode > EM_WRITEFILE)
141
	{
142
		ConsoleWrite("You must type 'new' 'filename' to begin creating an Exec file",WARNING_COLOR);
143
		result = TRUE;
144
	}
145
	else
146
	{
11 tristanc 147
		char filePath[FILENAME_MAX] = {};
148
		SStrCopy(filePath, s_fileName, FILENAME_MAX);
3 tristanc 149
 
11 tristanc 150
		if (CreateWTFFilePath(filePath, FILENAME_MAX))
3 tristanc 151
		{
152
			HANDLE hFile = OsCreateFile(filePath,FILE_ALL_ACCESS,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,(HANDLE)0x3F3F3F3F);
153
			if (hFile == INVALID_HANDLE_VALUE)
154
			{
155
				ConsoleWrite("Error trying to create the file.",ERROR_COLOR);
156
			}
157
			else
158
			{
159
				if (g_ExecCreateMode == EM_APPEND)
160
					OsSetFilePointer(hFile,CREATE_ALWAYS,0i64);
161
 
162
				DWORD count = 0;
11 tristanc 163
				DWORD bufLen = SStrLen(g_ExecBuffer);
3 tristanc 164
				COLOR_T color;
165
				const char *str;
166
				OsWriteFile(hFile,g_ExecBuffer,bufLen,&count);
167
				if (count)
168
				{
169
					color = ECHO_COLOR;
170
					str = "File written successfully";
171
				}
172
				else
173
				{
174
					color = ERROR_COLOR;
175
					str = "Error Writing ExecFile";
176
				}
177
				ConsoleWrite(str,color);
178
				OsCloseFile(hFile);
179
			}
180
		}
181
		g_ExecCreateMode = EM_NOTACTIVE;
182
		memset(g_ExecBuffer,'\0',sizeof(g_ExecBuffer));
183
		result = TRUE;
184
	}
31 tristanc 185
 
3 tristanc 186
	return result;
187
}
188
 
189
//===========================================================================
31 tristanc 190
BOOL ConsoleCommand_RunExec (const char *command, const char *arguments) {
191
	BOOL result = FALSE;
11 tristanc 192
	char filename[FILENAME_MAX] = { '\0' };
193
	char tmp[FILENAME_MAX] = { '\0' };
3 tristanc 194
	char lineBuffer[128] = { '\0' };
195
	char param1[32] = { '\0' };
196
	DWORD bytes;
197
 
198
	int verbose = 0;
199
	if (sscanf_s(arguments, "%260s %32s", filename, sizeof(filename), param1, sizeof(param1)) != 0)
200
	{
201
		if (!_strcmpi(param1, "verbose"))
202
			verbose = 1;
203
		result = CreateWTFFilePath(filename, 260u);
204
		if (result)
205
		{
206
			HANDLE hFile = OsCreateFile(filename, GENERIC_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
207
			DWORD fileSize = GetFileSize(hFile, NULL);
208
			char *readData = (char *)calloc(1, fileSize +1);
209
			if (!readData)
210
			{
211
				ConsoleWriteA("ConsoleCommand_RunExec, Line %d: call to calloc() failed", ERROR_COLOR, __LINE__);
212
				return 0;
213
			}
214
			if (OsReadFile(hFile, readData, fileSize, &bytes))
215
			{
216
				char *bufferPtr = (char *)calloc(1, bytes + 1);
217
				if (!bufferPtr)
218
				{
219
					ConsoleWriteA("ConsoleCommand_RunExec, Line %d: call to calloc() failed", ERROR_COLOR, __LINE__);
220
					return 0;
221
				}
222
				memcpy((void*)bufferPtr, readData, bytes);
223
				if (bufferPtr)
224
				{
225
					char *token = 0;
226
					char *nextToken = 0;
227
					token = strtok_s(bufferPtr, "\r\n", &nextToken);
228
					if (token)
229
					{
230
						do
231
						{
11 tristanc 232
							SStrCopy(lineBuffer, token, 128u);
3 tristanc 233
							if (lineBuffer[0])
234
							{
235
								if (verbose)
236
								{
11 tristanc 237
									_snprintf(tmp, FILENAME_MAX, "Executing ->%s", lineBuffer);
3 tristanc 238
									ConsoleWrite(tmp, ECHO_COLOR);
239
								}
240
								ConsoleCommandExecute(lineBuffer, 0);
241
							}
242
							token = strtok_s(NULL, "\r\n", &nextToken);
243
						} while (token && *token);
244
					}
245
					else
246
					{
247
						result = 0;
248
					}
249
					free((void*)bufferPtr);
250
				}
251
				else
252
				{
253
					result = 0;
254
				}
255
			}
256
			else
257
			{
258
				if (*command)
11 tristanc 259
					_snprintf(tmp, FILENAME_MAX, "Unable to load file %s", filename);
3 tristanc 260
				else
11 tristanc 261
					_snprintf(tmp, FILENAME_MAX, "Unknown command: %s", arguments);
3 tristanc 262
				ConsoleWrite(tmp, ERROR_COLOR);
263
				result = 0;
264
			}
265
			OsCloseFile(hFile);
266
			free(readData);
267
		}
268
	}
269
	else
270
	{
271
		ConsoleWrite("Invalid number of parameters", ERROR_COLOR);
272
		ConsoleCommandWriteHelp(command);
273
	}
31 tristanc 274
 
3 tristanc 275
	return result;
276
}
277
 
21 tristanc 278
//===========================================================================
279
BOOL ConsoleCommand_Ver (LPCSTR command, LPCSTR args) {
280
#ifdef NDEBUG
281
	ConsoleWriteA("WoW [Release] Build 12340 (%s)", DEFAULT_COLOR, __DATE__);
282
#else
283
	ConsoleWriteA("WoW [Debug] Build 12340 (%s)", DEFAULT_COLOR, __DATE__);
284
#endif
285
	return TRUE;
286
}
3 tristanc 287
 
21 tristanc 288
 
3 tristanc 289
/****************************************************************************
290
*
31 tristanc 291
*   External functions
3 tristanc 292
*
293
***/
294
 
295
//===========================================================================
31 tristanc 296
void ConsoleCommandInitialize () {
297
	// This function is called internally,
3 tristanc 298
	// so only setup a trampoline for ConsoleCommandDestroy()
299
	DETOUR_INIT;
300
	DETOUR_ATTACH(ConsoleCommandDestroyPtr,ConsoleCommandDestroy);
301
	DETOUR_COMMIT;
302
 
31 tristanc 303
	// Replace the client's "ver" command with our own
21 tristanc 304
	ConsoleCommandUnregister("ver");
305
	ConsoleCommandRegister("ver",ConsoleCommand_Ver,DEFAULT,NOHELP); 
306
 
3 tristanc 307
	ConsoleCommandRegister("new",ConsoleCommand_CreateExec,CONSOLE,"[File Name] starts recording a new script");
308
	ConsoleCommandRegister("run",ConsoleCommand_RunExec,CONSOLE,"[File Name] Runs a wtf file from the WTF folder");
309
	ConsoleCommandRegister("end",ConsoleCommand_CloseExec,CONSOLE,"Stops recording script");
310
}