Subversion Repositories WoWGM

Rev

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