More consistency of some sort...
Oh god, what has possessed me to do this?
3 * ===============================================================
4 * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
5 * ===============================================================
7 * This file is not open source and may not be copied without explicit
8 * written permission of AlliedModders LLC. This file may not be redistributed
9 * in whole or significant part.
10 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
16 #include "sm_globals.h"
17 #include "HandleSys.h"
18 #include "LibrarySys.h"
19 #include "sm_stringutil.h"
21 #include "PluginSys.h"
22 #include "sourcemm_api.h"
24 HandleType_t g_FileType;
25 HandleType_t g_DirType;
29 public IHandleTypeDispatch
32 virtual void OnSourceModAllInitialized()
34 g_FileType = g_HandleSys.CreateType("File", this, 0, NULL, NULL, g_pCoreIdent, NULL);
35 g_DirType = g_HandleSys.CreateType("Directory", this, 0, NULL, NULL, g_pCoreIdent, NULL);
37 virtual void OnSourceModShutdown()
39 g_HandleSys.RemoveType(g_DirType, g_pCoreIdent);
40 g_HandleSys.RemoveType(g_FileType, g_pCoreIdent);
44 virtual void OnHandleDestroy(HandleType_t type, void *object)
46 if (type == g_FileType)
48 FILE *fp = (FILE *)object;
50 } else if (type == g_DirType) {
51 IDirectory *pDir = (IDirectory *)object;
52 g_LibSys.CloseDirectory(pDir);
58 static cell_t sm_OpenDirectory(IPluginContext *pContext, const cell_t *params)
62 if ((err=pContext->LocalToString(params[1], &path)) != SP_ERROR_NONE)
64 pContext->ThrowNativeErrorEx(err, NULL);
68 char realpath[PLATFORM_MAX_PATH];
69 g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
71 IDirectory *pDir = g_LibSys.OpenDirectory(realpath);
77 return g_HandleSys.CreateHandle(g_DirType, pDir, pContext->GetIdentity(), g_pCoreIdent, NULL);
80 static cell_t sm_ReadDirEntry(IPluginContext *pContext, const cell_t *params)
82 Handle_t hndl = static_cast<Handle_t>(params[1]);
89 sec.pIdentity = g_pCoreIdent;
91 if ((herr=g_HandleSys.ReadHandle(hndl, g_DirType, &sec, (void **)&pDir))
94 return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
97 if (!pDir->MoreFiles())
103 if ((err=pContext->LocalToPhysAddr(params[4], &filetype)) != SP_ERROR_NONE)
105 pContext->ThrowNativeErrorEx(err, NULL);
109 if (pDir->IsEntryDirectory())
112 } else if (pDir->IsEntryFile()) {
118 const char *path = pDir->GetEntryName();
119 if ((err=pContext->StringToLocalUTF8(params[2], params[3], path, NULL))
122 pContext->ThrowNativeErrorEx(err, NULL);
131 static cell_t sm_OpenFile(IPluginContext *pContext, const cell_t *params)
135 if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
137 pContext->ThrowNativeErrorEx(err, NULL);
140 if ((err=pContext->LocalToString(params[2], &mode)) != SP_ERROR_NONE)
142 pContext->ThrowNativeErrorEx(err, NULL);
146 char realpath[PLATFORM_MAX_PATH];
147 g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
149 FILE *pFile = fopen(realpath, mode);
155 return g_HandleSys.CreateHandle(g_FileType, pFile, pContext->GetIdentity(), g_pCoreIdent, NULL);
158 static cell_t sm_DeleteFile(IPluginContext *pContext, const cell_t *params)
162 if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
164 pContext->ThrowNativeErrorEx(err, NULL);
168 char realpath[PLATFORM_MAX_PATH];
169 g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
171 return (unlink(realpath)) ? 0 : 1;
174 static cell_t sm_ReadFileLine(IPluginContext *pContext, const cell_t *params)
176 Handle_t hndl = static_cast<Handle_t>(params[1]);
183 sec.pIdentity = g_pCoreIdent;
185 if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
188 return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
192 if ((err=pContext->LocalToString(params[2], &buf)) != SP_ERROR_NONE)
194 pContext->ThrowNativeErrorEx(err, NULL);
198 if (fgets(buf, params[3], pFile) == NULL)
206 static cell_t sm_IsEndOfFile(IPluginContext *pContext, const cell_t *params)
208 Handle_t hndl = static_cast<Handle_t>(params[1]);
214 sec.pIdentity = g_pCoreIdent;
216 if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
219 return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
222 return (feof(pFile)) ? 1 : 0;
225 static cell_t sm_FileSeek(IPluginContext *pContext, const cell_t *params)
227 Handle_t hndl = static_cast<Handle_t>(params[1]);
233 sec.pIdentity = g_pCoreIdent;
235 if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
238 return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
241 fseek(pFile, params[2], params[3]);
246 static cell_t sm_FilePosition(IPluginContext *pContext, const cell_t *params)
248 Handle_t hndl = static_cast<Handle_t>(params[1]);
254 sec.pIdentity = g_pCoreIdent;
256 if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
259 return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
265 static cell_t sm_FileExists(IPluginContext *pContext, const cell_t *params)
269 if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
271 pContext->ThrowNativeErrorEx(err, NULL);
275 char realpath[PLATFORM_MAX_PATH];
276 g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
277 #ifdef PLATFORM_WINDOWS
279 if (_stat(realpath, &s) != 0)
283 if (s.st_mode & S_IFREG)
288 #elif defined PLATFORM_POSIX
290 if (stat(realpath, &s) != 0)
294 if (S_ISREG(s.st_mode))
302 static cell_t sm_RenameFile(IPluginContext *pContext, const cell_t *params)
304 char *newpath, *oldpath;
306 if ((err=pContext->LocalToString(params[1], &newpath)) != SP_ERROR_NONE)
308 pContext->ThrowNativeErrorEx(err, NULL);
311 if ((err=pContext->LocalToString(params[2], &oldpath)) != SP_ERROR_NONE)
313 pContext->ThrowNativeErrorEx(err, NULL);
317 char new_realpath[PLATFORM_MAX_PATH];
318 g_SourceMod.BuildPath(Path_Game, new_realpath, sizeof(new_realpath), "%s", newpath);
319 char old_realpath[PLATFORM_MAX_PATH];
320 g_SourceMod.BuildPath(Path_Game, old_realpath, sizeof(old_realpath), "%s", oldpath);
322 #ifdef PLATFORM_WINDOWS
323 return (MoveFileA(old_realpath, new_realpath)) ? 1 : 0;
324 #elif defined PLATFORM_POSIX
325 return (rename(old_realpath, new_realpath)) ? 0 : 1;
329 static cell_t sm_DirExists(IPluginContext *pContext, const cell_t *params)
333 if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
335 pContext->ThrowNativeErrorEx(err, NULL);
339 char realpath[PLATFORM_MAX_PATH];
340 g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
341 #ifdef PLATFORM_WINDOWS
343 if (_stat(realpath, &s) != 0)
347 if (s.st_mode & S_IFDIR)
352 #elif defined PLATFORM_POSIX
354 if (stat(realpath, &s) != 0)
358 if (S_ISDIR(s.st_mode))
366 static cell_t sm_FileSize(IPluginContext *pContext, const cell_t *params)
370 if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
372 pContext->ThrowNativeErrorEx(err, NULL);
376 char realpath[PLATFORM_MAX_PATH];
377 g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
378 #ifdef PLATFORM_WINDOWS
380 if (_stat(realpath, &s) != 0)
384 if (s.st_mode & S_IFREG)
386 return static_cast<cell_t>(s.st_size);
389 #elif defined PLATFORM_POSIX
391 if (stat(realpath, &s) != 0)
395 if (S_ISREG(s.st_mode))
397 return static_cast<cell_t>(s.st_size);
403 static cell_t sm_RemoveDir(IPluginContext *pContext, const cell_t *params)
407 if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
409 pContext->ThrowNativeErrorEx(err, NULL);
413 char realpath[PLATFORM_MAX_PATH];
414 g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
416 return (rmdir(realpath)) ? 0 : 1;
419 static cell_t sm_WriteFileLine(IPluginContext *pContext, const cell_t *params)
421 Handle_t hndl = static_cast<Handle_t>(params[1]);
427 sec.pIdentity = g_pCoreIdent;
429 if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
432 return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
437 if ((err=pContext->LocalToString(params[2], &fmt)) != SP_ERROR_NONE)
439 pContext->ThrowNativeErrorEx(err, NULL);
445 atcprintf(buffer, sizeof(buffer), fmt, pContext, params, &arg);
446 fprintf(pFile, "%s\n", buffer);
451 static cell_t sm_BuildPath(IPluginContext *pContext, const cell_t *params)
453 char path[PLATFORM_MAX_PATH], *fmt, *buffer;
455 pContext->LocalToString(params[2], &buffer);
456 pContext->LocalToString(params[4], &fmt);
458 atcprintf(path, sizeof(path), fmt, pContext, params, &arg);
460 return g_SourceMod.BuildPath(Path_SM_Rel, buffer, params[3], "%s", path);
463 static cell_t sm_LogToGame(IPluginContext *pContext, const cell_t *params)
466 size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
468 if (len >= sizeof(buffer)-2)
473 buffer[len++] = '\n';
477 engine->LogPrint(buffer);
482 static cell_t sm_LogMessage(IPluginContext *pContext, const cell_t *params)
485 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
487 IPlugin *pPlugin = g_PluginSys.FindPluginByContext(pContext->GetContext());
488 g_Logger.LogMessage("[%s] %s", pPlugin->GetFilename(), buffer);
493 static cell_t sm_LogError(IPluginContext *pContext, const cell_t *params)
496 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
498 IPlugin *pPlugin = g_PluginSys.FindPluginByContext(pContext->GetContext());
499 g_Logger.LogError("[%s] %s", pPlugin->GetFilename(), buffer);
504 static FileNatives s_FileNatives;
506 REGISTER_NATIVES(filesystem)
508 {"OpenDirectory", sm_OpenDirectory},
509 {"ReadDirEntry", sm_ReadDirEntry},
510 {"OpenFile", sm_OpenFile},
511 {"DeleteFile", sm_DeleteFile},
512 {"ReadFileLine", sm_ReadFileLine},
513 {"IsEndOfFile", sm_IsEndOfFile},
514 {"FileSeek", sm_FileSeek},
515 {"FilePosition", sm_FilePosition},
516 {"FileExists", sm_FileExists},
517 {"RenameFile", sm_RenameFile},
518 {"DirExists", sm_DirExists},
519 {"FileSize", sm_FileSize},
520 {"RemoveDir", sm_RemoveDir},
521 {"WriteFileLine", sm_WriteFileLine},
522 {"BuildPath", sm_BuildPath},
523 {"LogToGame", sm_LogToGame},
524 {"LogMessage", sm_LogMessage},
525 {"LogError", sm_LogError},