Subversion Repositories WoWGM

Rev

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