46 Commits

Author SHA1 Message Date
0cd113b33f New install 2024-07-31 22:53:48 -06:00
4c77045add Add pluto sdk 2024-07-31 22:49:19 -06:00
b0ccd678d3 fmt 2024-07-31 22:11:27 -06:00
f4ac726a1e Add use_global for fs_remove and opening for writing 2024-07-31 22:07:00 -06:00
3a4595a641 add pluto sdk 2024-07-31 21:38:17 -06:00
a3a7b8847c note 2024-05-12 11:43:16 -06:00
7fccea636f update to io 2024-05-12 11:41:57 -06:00
38a860e4ce Merge branch 'main' of https://github.com/JezuzLizard/T4SP-Server-Plugin 2023-12-15 15:05:41 -06:00
3995bed200 update 2023-12-15 15:05:36 -06:00
3502a70933 Update README.md 2023-12-15 15:03:41 -06:00
1a33de617d Copy fix from cod2rev 2023-12-15 12:40:46 -06:00
59e57d05f7 Merge pull request #115 from JezuzLizard/dependabot/submodules/deps/json-a259ecc
Bump deps/json from `3780b41` to `a259ecc`
2023-12-15 11:46:28 -06:00
23f5c28c29 Merge pull request #116 from JezuzLizard/dependabot/submodules/deps/curl-78a1814
Bump deps/curl from `1e4cd51` to `78a1814`
2023-12-15 11:46:21 -06:00
0e29d35407 Bump deps/curl from 1e4cd51 to 78a1814
Bumps [deps/curl](https://github.com/curl/curl) from `1e4cd51` to `78a1814`.
- [Release notes](https://github.com/curl/curl/releases)
- [Commits](1e4cd51935...78a1814b33)

---
updated-dependencies:
- dependency-name: deps/curl
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-15 08:06:17 +00:00
a756ab6cc0 Bump deps/json from 3780b41 to a259ecc
Bumps [deps/json](https://github.com/nlohmann/json) from `3780b41` to `a259ecc`.
- [Release notes](https://github.com/nlohmann/json/releases)
- [Commits](3780b41dd0...a259ecc51e)

---
updated-dependencies:
- dependency-name: deps/json
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-15 08:06:09 +00:00
c15f3c21d5 Merge pull request #113 from JezuzLizard/dependabot/submodules/deps/asmjit-416f735
Bump deps/asmjit from `1a81158` to `416f735`
2023-12-14 23:14:50 -06:00
5a944f8711 Merge pull request #114 from JezuzLizard/dependabot/submodules/deps/curl-1e4cd51
Bump deps/curl from `02d81c5` to `1e4cd51`
2023-12-14 23:14:42 -06:00
e0728eb375 Bump deps/curl from 02d81c5 to 1e4cd51
Bumps [deps/curl](https://github.com/curl/curl) from `02d81c5` to `1e4cd51`.
- [Release notes](https://github.com/curl/curl/releases)
- [Commits](02d81c5a68...1e4cd51935)

---
updated-dependencies:
- dependency-name: deps/curl
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 07:43:39 +00:00
bafc637be8 Bump deps/asmjit from 1a81158 to 416f735
Bumps [deps/asmjit](https://github.com/asmjit/asmjit) from `1a81158` to `416f735`.
- [Commits](1a81158e8b...416f735696)

---
updated-dependencies:
- dependency-name: deps/asmjit
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-13 07:16:58 +00:00
7da012fdf3 Merge pull request #111 from JezuzLizard/dependabot/submodules/deps/curl-02d81c5
Bump deps/curl from `f899e91` to `02d81c5`
2023-12-12 16:19:21 -06:00
d9c3b7cab5 Merge pull request #108 from JezuzLizard/dependabot/submodules/deps/asmjit-1a81158
Bump deps/asmjit from `6a13a93` to `1a81158`
2023-12-12 16:19:08 -06:00
8a36e02fdd Bump deps/curl from f899e91 to 02d81c5
Bumps [deps/curl](https://github.com/curl/curl) from `f899e91` to `02d81c5`.
- [Release notes](https://github.com/curl/curl/releases)
- [Commits](f899e91431...02d81c5a68)

---
updated-dependencies:
- dependency-name: deps/curl
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-12 07:41:05 +00:00
944bab5e5c Bump deps/asmjit from 6a13a93 to 1a81158
Bumps [deps/asmjit](https://github.com/asmjit/asmjit) from `6a13a93` to `1a81158`.
- [Commits](6a13a935d1...1a81158e8b)

---
updated-dependencies:
- dependency-name: deps/asmjit
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-08 07:14:33 +00:00
8ca8002067 Merge pull request #107 from JezuzLizard/dependabot/submodules/deps/curl-f899e91
Bump deps/curl from `4528690` to `f899e91`
2023-12-07 10:59:19 -06:00
afc01a05e3 Merge pull request #106 from JezuzLizard/dependabot/submodules/deps/json-3780b41
Bump deps/json from `546370c` to `3780b41`
2023-12-07 10:59:10 -06:00
8cb282da97 Merge pull request #102 from JezuzLizard/dependabot/submodules/deps/asmjit-6a13a93
Bump deps/asmjit from `f1ea8a4` to `6a13a93`
2023-12-07 10:59:01 -06:00
0327434187 Merge pull request #95 from JezuzLizard/dependabot/submodules/deps/minhook-f5485b8
Bump deps/minhook from `49d03ad` to `f5485b8`
2023-12-07 10:58:53 -06:00
b3b693a56e Merge pull request #85 from JezuzLizard/dependabot/submodules/deps/zlib-643e17b
Bump deps/zlib from `04f42ce` to `643e17b`
2023-12-07 10:58:43 -06:00
347033f424 Merge pull request #59 from JezuzLizard/dependabot/submodules/deps/GSL-e64c97f
Bump deps/GSL from `43d60c5` to `e64c97f`
2023-12-07 10:58:34 -06:00
4c78d6fe41 Merge pull request #51 from JezuzLizard/dependabot/submodules/deps/libtomcrypt-7e863d2
Bump deps/libtomcrypt from `b96e96c` to `7e863d2`
2023-12-07 10:58:25 -06:00
33b6006a34 Merge pull request #14 from JezuzLizard/dependabot/submodules/deps/libtommath-8314bde
Bump deps/libtommath from `7f96509` to `8314bde`
2023-12-07 10:58:15 -06:00
98b2c3f4d6 Bump deps/curl from 4528690 to f899e91
Bumps [deps/curl](https://github.com/curl/curl) from `4528690` to `f899e91`.
- [Release notes](https://github.com/curl/curl/releases)
- [Commits](4528690cd5...f899e91431)

---
updated-dependencies:
- dependency-name: deps/curl
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-07 07:28:09 +00:00
beb90edc3d Bump deps/json from 546370c to 3780b41
Bumps [deps/json](https://github.com/nlohmann/json) from `546370c` to `3780b41`.
- [Release notes](https://github.com/nlohmann/json/releases)
- [Commits](546370c9e7...3780b41dd0)

---
updated-dependencies:
- dependency-name: deps/json
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-07 07:28:01 +00:00
df9ef00a64 Bump deps/asmjit from f1ea8a4 to 6a13a93
Bumps [deps/asmjit](https://github.com/asmjit/asmjit) from `f1ea8a4` to `6a13a93`.
- [Commits](f1ea8a46c3...6a13a935d1)

---
updated-dependencies:
- dependency-name: deps/asmjit
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-04 07:22:46 +00:00
1f0717edef fix double slashes 2023-12-03 18:13:22 -06:00
7a82be782d update count 2023-12-03 17:53:21 -06:00
f0c95340bf Fixed up the builtin 2023-12-03 17:43:40 -06:00
4843c61e2e Merge branch 'main' of https://github.com/JezuzLizard/T4SP-Server-Plugin 2023-12-03 17:19:00 -06:00
b79b776f63 add fs_listfiles 2023-12-03 17:18:54 -06:00
d1a0277861 Update README.md 2023-12-03 15:35:03 -06:00
4963a9180a largest gsc string is 65535, but u cant concat gsc strings > 8191 chars, ull get an error 2023-12-02 15:58:56 -06:00
3bff917ce3 Bump deps/minhook from 49d03ad to f5485b8
Bumps [deps/minhook](https://github.com/TsudaKageyu/minhook) from `49d03ad` to `f5485b8`.
- [Release notes](https://github.com/TsudaKageyu/minhook/releases)
- [Commits](49d03ad118...f5485b8454)

---
updated-dependencies:
- dependency-name: deps/minhook
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-27 07:17:52 +00:00
d6a6a096fd Bump deps/zlib from 04f42ce to 643e17b
Bumps [deps/zlib](https://github.com/madler/zlib) from `04f42ce` to `643e17b`.
- [Release notes](https://github.com/madler/zlib/releases)
- [Commits](04f42ceca4...643e17b749)

---
updated-dependencies:
- dependency-name: deps/zlib
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-15 07:48:12 +00:00
c147f3fbe2 Bump deps/GSL from 43d60c5 to e64c97f
Bumps [deps/GSL](https://github.com/microsoft/GSL) from `43d60c5` to `e64c97f`.
- [Release notes](https://github.com/microsoft/GSL/releases)
- [Commits](43d60c5e38...e64c97fc2c)

---
updated-dependencies:
- dependency-name: deps/GSL
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-19 08:00:25 +00:00
7da463ccd3 Bump deps/libtomcrypt from b96e96c to 7e863d2
Bumps [deps/libtomcrypt](https://github.com/libtom/libtomcrypt) from `b96e96c` to `7e863d2`.
- [Release notes](https://github.com/libtom/libtomcrypt/releases)
- [Commits](b96e96cf8b...7e863d2142)

---
updated-dependencies:
- dependency-name: deps/libtomcrypt
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-10 07:23:32 +00:00
7503e8988b Bump deps/libtommath from 7f96509 to 8314bde
Bumps [deps/libtommath](https://github.com/libtom/libtommath) from `7f96509` to `8314bde`.
- [Release notes](https://github.com/libtom/libtommath/releases)
- [Commits](7f96509df1...8314bde5e5)

---
updated-dependencies:
- dependency-name: deps/libtommath
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 01:08:59 +00:00
20 changed files with 290 additions and 96 deletions

3
.gitmodules vendored
View File

@ -29,3 +29,6 @@
[submodule "deps/SQLiteCpp"] [submodule "deps/SQLiteCpp"]
path = deps/SQLiteCpp path = deps/SQLiteCpp
url = https://github.com/SRombauts/SQLiteCpp url = https://github.com/SRombauts/SQLiteCpp
[submodule "deps/plutonium-sdk"]
path = deps/plutonium-sdk
url = https://github.com/plutoniummod/plutonium-sdk.git

View File

@ -9,6 +9,9 @@ Detours and reimplements the entire GSC VM + compiler.
Adds custom GSC functions. Adds custom GSC functions.
# Installation
Move the `t4sp-server-plugin.dll` to `%LOCALAPPDATA%\Plutonium\plugins\`, the plugin will be loaded when you start up a dedicated server for Plutonium T4SP.
## FileIO ## FileIO
This plugin provides FileIO interface to GSC for reading and writing files, this is exact to [CoD4x's](https://github.com/callofduty4x/CoD4x_Server/blob/master/scriptdocumentation/script_functions_reference.md#file-operations) interface. This plugin provides FileIO interface to GSC for reading and writing files, this is exact to [CoD4x's](https://github.com/callofduty4x/CoD4x_Server/blob/master/scriptdocumentation/script_functions_reference.md#file-operations) interface.
@ -17,7 +20,7 @@ However, all reads and writes will take place strictly and only in the `scriptda
All files will be closed upon GSC restart (map_restart or fast_restart or missionfailed, etc), only a maximum of 10 files may be opened at once. All files will be closed upon GSC restart (map_restart or fast_restart or missionfailed, etc), only a maximum of 10 files may be opened at once.
* `<bool> FS_TestFile(<filename string>)` Returns `true` if the file exists, `false` otherwise. * `<bool> FS_TestFile(<filename string>)` Returns `true` if the file exists, `false` otherwise.
* `<bool> FS_Remove(<filename string>)` Deletes the file, return `true` if successful, `false` otherwise. * `<bool> FS_Remove(<filename string>, <(optional) use_global bool>)` Deletes the file, return `true` if successful, `false` otherwise. `use_global` will use non mod specific folder.
```gsc ```gsc
// test to see if "scriptdata/test.txt" file exists // test to see if "scriptdata/test.txt" file exists
if (FS_TestFile("test.txt")) // not a typo, all file io will take place inside the "scriptdata" folder if (FS_TestFile("test.txt")) // not a typo, all file io will take place inside the "scriptdata" folder
@ -39,7 +42,7 @@ All files will be closed upon GSC restart (map_restart or fast_restart or missio
FS_FCloseAll(); // close them all FS_FCloseAll(); // close them all
``` ```
* `<int> FS_FOpen(<filename string>, <mode string>)` Tries to open the file, mode must be one of `read`, `write` (clears the file), `append` (appends to the file), returns the filehandle. Will return `0` if failed to open. * `<int> FS_FOpen(<filename string>, <mode string>, <(optional) use_global bool>)` Tries to open the file, mode must be one of `read`, `write` (clears the file), `append` (appends to the file), returns the filehandle. Will return `0` if failed to open. `use_global` will use non mod specific folder (only applies to `write` mode).
* `FS_FClose(<filehandle int>)` Closes the file pointed by the filehandle given, which was returned from `FS_FOpen`. * `FS_FClose(<filehandle int>)` Closes the file pointed by the filehandle given, which was returned from `FS_FOpen`.
```gsc ```gsc
// opens "scriptdata/test.txt", all io will take place inside the "scriptdata" folder // opens "scriptdata/test.txt", all io will take place inside the "scriptdata" folder
@ -58,8 +61,8 @@ All files will be closed upon GSC restart (map_restart or fast_restart or missio
``` ```
* `<string> FS_ReadLine(<filehandle int>)` Reads a line from the file pointed by the filehandle, removes the newline char. Returns `undefined` when nothing is left to read. Will not read more than 8192 characters at once. Filehandle must be opened for reading. * `<string> FS_ReadLine(<filehandle int>)` Reads a line from the file pointed by the filehandle, removes the newline char. Returns `undefined` when nothing is left to read. Will not read more than 65536 characters at once. Filehandle must be opened for reading.
* `<string> FS_Read(<filehandle int>, <bytes int>(optional))` Reads number of bytes from the file. If bytes is `undefined`, reads the entire file. No more than 8192 characters will be read at once. Returns `undefined` if there are nothing left to read. * `<string> FS_Read(<filehandle int>, <bytes int>(optional))` Reads number of bytes from the file. If bytes is `undefined`, reads the entire file. No more than 65536 characters will be read at once. Returns `undefined` if there are nothing left to read.
```gsc ```gsc
// open the file for reading // open the file for reading
@ -89,8 +92,23 @@ All files will be closed upon GSC restart (map_restart or fast_restart or missio
// close the file // close the file
``` ```
# Installation * `<array of strings> FS_ListFiles(<folder string>)` Returns a list of files inside of the folder given.
Move the `t4sp-server-plugin.dll` to `%LOCALAPPDATA%\Plutonium\storage\t4\plugins\`, the plugin will be loaded when you start up a dedicated server for Plutonium T4SP. ```gsc
folder = "testfolder/";
files = FS_ListFiles(folder);
for (i = 0; i < files.size; i++)
{
filename = files[i];
// do something with the filename
filepath = folder + filename;
}
```
* `<int> FS_Length(<filehandle int>)` Returns the length in bytes of the open'd file.
* `<int> FS_GetSeek(<filehandle int>)` Returns the seek of the open'd file (only for reading).
* `<int> FS_Seek(<filehandle int>, <seek int>)` Sets the seek of the open'd file (only for reading).
# Credits # Credits
- momo5502 (https://github.com/momo5502) - momo5502 (https://github.com/momo5502)

2
deps/GSL vendored

Submodule deps/GSL updated: 43d60c5e38...e64c97fc2c

2
deps/asmjit vendored

2
deps/curl vendored

Submodule deps/curl updated: 4528690cd5...78a1814b33

2
deps/json vendored

Submodule deps/json updated: 546370c9e7...a259ecc51e

2
deps/minhook vendored

1
deps/plutonium-sdk vendored Submodule

Submodule deps/plutonium-sdk added at 17e9a0a4d5

18
deps/premake/plutonium-sdk.lua vendored Normal file
View File

@ -0,0 +1,18 @@
plutonium_sdk = {
source = path.join(dependencies.basePath, "plutonium-sdk"),
}
function plutonium_sdk.import()
plutonium_sdk.includes()
end
function plutonium_sdk.includes()
includedirs {
plutonium_sdk.source,
}
end
function plutonium_sdk.project()
end
table.insert(dependencies, plutonium_sdk)

2
deps/zlib vendored

Submodule deps/zlib updated: 04f42ceca4...643e17b749

View File

@ -67,11 +67,18 @@ namespace codsrc
{ {
int len; int len;
for ( len = refString->u.s.byteLen - 1; if (!refString->u.s.byteLen)
refString->str[len];
len += 256 )
{ {
; len = 256 - 1; //Bugfix for 256 % 256 = 0 or 512 % 256 = 0 or... Just promote it to 256
}
else
{
len = refString->u.s.byteLen - 1;
}
while (refString->str[len])
{
len += 256;
} }
return len; return len;

View File

@ -10,6 +10,7 @@ namespace fileio
namespace namespace
{ {
static constexpr size_t max_fhs = 10; static constexpr size_t max_fhs = 10;
static constexpr size_t max_gsc_string = 0x10000 - 1;
enum class scr_fh_type_e enum class scr_fh_type_e
{ {
@ -33,15 +34,16 @@ namespace fileio
bool validate_scr_path(const std::string& fpath) bool validate_scr_path(const std::string& fpath)
{ {
if (fpath.empty()) auto toks = utils::string::split(fpath, '/');
{
return false;
}
constexpr static std::array bad_strings { R"(..)", R"(../)", R"(..\)" }; for (const auto& tok : toks)
for (auto i = 0u; i < bad_strings.size(); i++)
{ {
if (fpath.find(bad_strings[i]) != std::string::npos) if (tok == "." || tok == "..")
{
return false;
}
if (tok.find(":") != std::string::npos)
{ {
return false; return false;
} }
@ -50,17 +52,21 @@ namespace fileio
return true; return true;
} }
std::string build_base_path(const std::string& path) std::string build_base_path(const std::string& path_)
{ {
auto path = path_;
std::replace(path.begin(), path.end(), '\\', '/');
if (!validate_scr_path(path)) if (!validate_scr_path(path))
{ {
game::Scr_Error(utils::string::va("Invalid path: %s", path.c_str()), game::SCRIPTINSTANCE_SERVER, false); game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, utils::string::va("Invalid path: %s", path_.c_str()));
} }
// its sandboxed, but what about symlinks?
return path.starts_with("scriptdata/") ? path : "scriptdata/" + path; return path.starts_with("scriptdata/") ? path : "scriptdata/" + path;
} }
std::filesystem::path build_full_path(const std::string& path) std::filesystem::path build_full_path(const std::string& path, bool use_global)
{ {
static game::dvar_s* fs_localAppData = nullptr; static game::dvar_s* fs_localAppData = nullptr;
static game::dvar_s* fs_gamedir = nullptr; static game::dvar_s* fs_gamedir = nullptr;
@ -75,7 +81,7 @@ namespace fileio
fs_gamedir = game::Dvar_FindVar("fs_game"); fs_gamedir = game::Dvar_FindVar("fs_game");
} }
return std::filesystem::path(fs_localAppData->current.string) / (*fs_gamedir->current.string ? fs_gamedir->current.string : "raw") / path; return std::filesystem::path(fs_localAppData->current.string) / (!use_global && *fs_gamedir->current.string ? fs_gamedir->current.string : "raw") / path;
} }
void free_scr_fh(scr_fh_t& scr_fh) void free_scr_fh(scr_fh_t& scr_fh)
@ -101,18 +107,25 @@ namespace fileio
} }
} }
void fwrite_to_file(bool append_newline) int scr_get_fh()
{ {
auto fh = game::Scr_GetInt(game::SCRIPTINSTANCE_SERVER, 0) - 1; auto fh = game::Scr_GetInt(game::SCRIPTINSTANCE_SERVER, 0) - 1;
if (fh < 0 || fh >= max_fhs) if (fh < 0 || fh >= max_fhs)
{ {
game::Scr_Error("fs_fwrite: invalid filehandle", game::SCRIPTINSTANCE_SERVER, false); game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, "fs_fwrite: invalid filehandle");
} }
return fh;
}
void fwrite_to_file(bool append_newline)
{
auto fh = scr_get_fh();
if (scr_fhs[fh].type != scr_fh_type_e::WRITE && scr_fhs[fh].type != scr_fh_type_e::APPEND) if (scr_fhs[fh].type != scr_fh_type_e::WRITE && scr_fhs[fh].type != scr_fh_type_e::APPEND)
{ {
game::Scr_Error("File not opened for writing", game::SCRIPTINSTANCE_SERVER, false); game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, "File not opened for writing");
} }
std::string to_write = game::Scr_GetString(1, game::SCRIPTINSTANCE_SERVER); std::string to_write = game::Scr_GetString(1, game::SCRIPTINSTANCE_SERVER);
@ -169,7 +182,7 @@ namespace fileio
{ {
if (scr_fd.type != scr_fh_type_e::UNUSED && scr_fd.base_path == fpath) if (scr_fd.type != scr_fh_type_e::UNUSED && scr_fd.base_path == fpath)
{ {
game::Scr_Error("File already opened", game::SCRIPTINSTANCE_SERVER, false); game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, "File already opened");
} }
} }
@ -185,7 +198,7 @@ namespace fileio
if (i >= max_fhs) if (i >= max_fhs)
{ {
game::Scr_Error("Too many files opened", game::SCRIPTINSTANCE_SERVER, false); game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, "Too many files opened");
} }
// check mode // check mode
@ -224,7 +237,7 @@ namespace fileio
} }
else if (mode == "write"s || mode == "append"s) else if (mode == "write"s || mode == "append"s)
{ {
auto full_path = build_full_path(fpath); auto full_path = build_full_path(fpath, game::Scr_GetNumParam(game::SCRIPTINSTANCE_SERVER) >= 3 && game::Scr_GetType(game::SCRIPTINSTANCE_SERVER, 2) == game::VAR_INTEGER && game::Scr_GetInt(game::SCRIPTINSTANCE_SERVER, 2));
if (!utils::io::write_file(full_path.string(), "", (mode == "append"s))) if (!utils::io::write_file(full_path.string(), "", (mode == "append"s)))
{ {
@ -239,7 +252,7 @@ namespace fileio
} }
else else
{ {
game::Scr_Error(utils::string::va("Invalid mode: %s", mode), game::SCRIPTINSTANCE_SERVER, false); game::Scr_ParamError(1, game::SCRIPTINSTANCE_SERVER, utils::string::va("Invalid mode: %s", mode));
} }
#ifdef DEBUG #ifdef DEBUG
@ -260,16 +273,11 @@ namespace fileio
gsc::function::add("fs_readline", []() gsc::function::add("fs_readline", []()
{ {
auto fh = game::Scr_GetInt(game::SCRIPTINSTANCE_SERVER, 0) - 1; auto fh = scr_get_fh();
if (fh < 0 || fh >= max_fhs)
{
game::Scr_Error("Invalid filehandle", game::SCRIPTINSTANCE_SERVER, false);
}
if (scr_fhs[fh].type != scr_fh_type_e::READ) if (scr_fhs[fh].type != scr_fh_type_e::READ)
{ {
game::Scr_Error("File not opened for reading", game::SCRIPTINSTANCE_SERVER, false); game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, "File not opened for reading");
} }
// file is completed being read // file is completed being read
@ -293,10 +301,10 @@ namespace fileio
} }
} }
if (bytes_to_read > 8191) if (bytes_to_read > max_gsc_string)
{ {
found_nl = false; found_nl = false;
bytes_to_read = 8191; bytes_to_read = max_gsc_string;
game::Com_PrintWarning(game::CON_CHANNEL_SCRIPT, "Line was too long in file %s, truncating\n", scr_fhs[fh].base_path.c_str()); game::Com_PrintWarning(game::CON_CHANNEL_SCRIPT, "Line was too long in file %s, truncating\n", scr_fhs[fh].base_path.c_str());
} }
@ -318,16 +326,11 @@ namespace fileio
gsc::function::add("fs_read", []() gsc::function::add("fs_read", []()
{ {
auto fh = game::Scr_GetInt(game::SCRIPTINSTANCE_SERVER, 0) - 1; auto fh = scr_get_fh();
if (fh < 0 || fh >= max_fhs)
{
game::Scr_Error("Invalid filehandle", game::SCRIPTINSTANCE_SERVER, false);
}
if (scr_fhs[fh].type != scr_fh_type_e::READ) if (scr_fhs[fh].type != scr_fh_type_e::READ)
{ {
game::Scr_Error("File not opened for reading", game::SCRIPTINSTANCE_SERVER, false); game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, "File not opened for reading");
} }
// file is completed being read // file is completed being read
@ -344,13 +347,13 @@ namespace fileio
if (bytes_to_read <= 0) if (bytes_to_read <= 0)
{ {
game::Scr_Error("Trying to read <1 bytes", game::SCRIPTINSTANCE_SERVER, false); game::Scr_ParamError(1, game::SCRIPTINSTANCE_SERVER, "Trying to read <1 bytes");
} }
} }
if (bytes_to_read > 8191) if (bytes_to_read > max_gsc_string)
{ {
bytes_to_read = 8191; bytes_to_read = max_gsc_string;
game::Com_PrintWarning(game::CON_CHANNEL_SCRIPT, "Line was too long in file %s, truncating\n", scr_fhs[fh].base_path.c_str()); game::Com_PrintWarning(game::CON_CHANNEL_SCRIPT, "Line was too long in file %s, truncating\n", scr_fhs[fh].base_path.c_str());
} }
@ -369,16 +372,11 @@ namespace fileio
gsc::function::add("fs_fclose", []() gsc::function::add("fs_fclose", []()
{ {
auto fh = game::Scr_GetInt(game::SCRIPTINSTANCE_SERVER, 0) - 1; auto fh = scr_get_fh();
if (fh < 0 || fh >= max_fhs)
{
game::Scr_Error("Invalid filehandle", game::SCRIPTINSTANCE_SERVER, false);
}
if (scr_fhs[fh].type == scr_fh_type_e::UNUSED) if (scr_fhs[fh].type == scr_fh_type_e::UNUSED)
{ {
game::Scr_Error("File not opened", game::SCRIPTINSTANCE_SERVER, false); game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, "File not opened");
} }
free_scr_fh(scr_fhs[fh]); free_scr_fh(scr_fhs[fh]);
@ -386,10 +384,48 @@ namespace fileio
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 1); game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 1);
}); });
gsc::function::add("fs_length", []()
{
auto fh = scr_get_fh();
if (scr_fhs[fh].type == scr_fh_type_e::UNUSED)
{
game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, "File not opened");
}
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, scr_fhs[fh].file_length);
});
gsc::function::add("fs_getseek", []()
{
auto fh = scr_get_fh();
// write seek would require completely redoing how we write files...
if (scr_fhs[fh].type != scr_fh_type_e::READ)
{
game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, "File not opened for reading");
}
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, scr_fhs[fh].seek);
});
gsc::function::add("fs_seek", []()
{
auto fh = scr_get_fh();
if (scr_fhs[fh].type != scr_fh_type_e::READ)
{
game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, "File not opened for reading");
}
scr_fhs[fh].seek = std::clamp(game::Scr_GetInt(game::SCRIPTINSTANCE_SERVER, 1), 0, scr_fhs[fh].file_length);
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 1);
});
gsc::function::add("fs_remove", []() gsc::function::add("fs_remove", []()
{ {
auto fpath = build_base_path(game::Scr_GetString(0, game::SCRIPTINSTANCE_SERVER)); auto fpath = build_base_path(game::Scr_GetString(0, game::SCRIPTINSTANCE_SERVER));
auto full_path = build_full_path(fpath); auto full_path = build_full_path(fpath, game::Scr_GetNumParam(game::SCRIPTINSTANCE_SERVER) >= 2 && game::Scr_GetType(game::SCRIPTINSTANCE_SERVER, 1) == game::VAR_INTEGER && game::Scr_GetInt(game::SCRIPTINSTANCE_SERVER, 1));
if (!utils::io::remove_file(full_path.string())) if (!utils::io::remove_file(full_path.string()))
{ {
@ -400,6 +436,23 @@ namespace fileio
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 1); game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 1);
}); });
gsc::function::add("fs_listfiles", []()
{
auto fpath = build_base_path(game::Scr_GetString(0, game::SCRIPTINSTANCE_SERVER));
int numfiles;
auto* files = game::FS_ListFiles(fpath.c_str(), "", game::FS_LIST_ALL, &numfiles);
game::Scr_MakeArray(game::SCRIPTINSTANCE_SERVER);
for (int i = 0; i < numfiles; i++)
{
game::Scr_AddString(game::SCRIPTINSTANCE_SERVER, files[i]);
game::Scr_AddArray(game::SCRIPTINSTANCE_SERVER);
}
game::FS_FreeFileList(files);
});
} }
} }

View File

@ -1,40 +1,11 @@
#include <stdinc.hpp> #include <stdinc.hpp>
#include "loader/component_loader.hpp"
#include "component/signatures.hpp"
#include <utils/hook.hpp> PLUTONIUM_API plutonium::sdk::plugin* PLUTONIUM_CALLBACK on_initialize()
{
return plugin::get();
}
BOOL APIENTRY DllMain(HMODULE /*module_*/, DWORD ul_reason_for_call, LPVOID /*reserved_*/) BOOL APIENTRY DllMain(HMODULE /*module_*/, DWORD ul_reason_for_call, LPVOID /*reserved_*/)
{ {
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
{
if (game::environment::t4sp())
{
if (!signatures::process())
{
MessageBoxA(NULL,
std::format("This version of t4sp-server-plugin is outdated.\n" \
"Download the latest dll from here: https://github.com/JezuzLizard/T4SP-Server-Plugin/releases\n" \
"'{}' failed", signatures::get_err_reason()).c_str(),
"ERROR", MB_ICONERROR);
return FALSE;
}
if (game::plutonium::printf.get() != nullptr)
{
utils::hook::jump(reinterpret_cast<uintptr_t>(&printf), game::plutonium::printf);
}
component_loader::post_unpack();
}
else
{
MessageBoxA(nullptr, "Unsupported game executable. (t4sp is only supported)", "ERROR, BRO!", 0);
return FALSE;
}
}
return TRUE; return TRUE;
} }

View File

@ -231,6 +231,21 @@ namespace game
*cmd_functions = newCmd; *cmd_functions = newCmd;
} }
// restored
const char** FS_ListFiles(const char* path, const char* extension, FsListBehavior_e behavior, int* numfiles)
{
return FS_ListFilteredFiles(*fs_searchpaths, path, extension, nullptr, behavior, numfiles);
}
// restored
void FS_FreeFileList(const char** list)
{
if ( list )
{
Hunk_UserDestroy((HunkUser*)*(list - 1));
}
}
// restored // restored
void Sys_EnterCriticalSection(CriticalSection critSect) void Sys_EnterCriticalSection(CriticalSection critSect)
{ {

View File

@ -78,6 +78,9 @@ namespace game
void Sys_EnterCriticalSection(CriticalSection critSect); void Sys_EnterCriticalSection(CriticalSection critSect);
void Sys_LeaveCriticalSection(CriticalSection critSect); void Sys_LeaveCriticalSection(CriticalSection critSect);
const char** FS_ListFiles(const char* path, const char* extension, FsListBehavior_e behavior, int* numfiles);
void FS_FreeFileList(const char** list);
// Variables // Variables
WEAK symbol<CRITICAL_SECTION> s_criticalSection{ 0x0, 0x2298D08 }; WEAK symbol<CRITICAL_SECTION> s_criticalSection{ 0x0, 0x2298D08 };
WEAK symbol<HunkUser*> g_DebugHunkUser{ 0x0, 0x212B2EC }; WEAK symbol<HunkUser*> g_DebugHunkUser{ 0x0, 0x212B2EC };

73
src/plugin.cpp Normal file
View File

@ -0,0 +1,73 @@
#include <stdinc.hpp>
#include "component/signatures.hpp"
#include <utils/hook.hpp>
#include "loader/component_loader.hpp"
namespace plugin
{
std::uint32_t plugin::plugin_version()
{
return 1;
}
const char* plugin::plugin_name()
{
return "t4sp-server-plugin";
}
bool plugin::is_game_supported(plutonium::sdk::game game)
{
return game == plutonium::sdk::game::t4;
}
void plugin::on_startup(plutonium::sdk::iinterface* interface_ptr, plutonium::sdk::game game)
{
this->interface_ = interface_ptr;
this->game_ = game;
if (!game::environment::t4sp())
{
MessageBoxA(nullptr, "Unsupported game executable. (t4sp is only supported)", "ERROR, BRO!", 0);
return;
}
if (!signatures::process())
{
MessageBoxA(NULL,
std::format("This version of t4sp-server-plugin is outdated.\n" \
"Download the latest dll from here: https://github.com/JezuzLizard/T4SP-Server-Plugin/releases\n" \
"'{}' failed", signatures::get_err_reason()).c_str(),
"ERROR", MB_ICONERROR);
return;
}
if (game::plutonium::printf.get() != nullptr)
{
utils::hook::jump(reinterpret_cast<uintptr_t>(&printf), game::plutonium::printf);
}
component_loader::post_unpack();
}
void plugin::on_shutdown()
{
}
plutonium::sdk::iinterface* plugin::get_interface()
{
return this->interface_;
}
plutonium::sdk::game plugin::get_game()
{
return this->game_;
}
plugin* get()
{
static plugin instance;
return &instance;
}
}

30
src/plugin.hpp Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#include <plutonium_sdk.hpp>
namespace plugin
{
class plugin : public plutonium::sdk::plugin
{
public:
~plugin() = default;
std::uint32_t plugin_version() override;
const char* plugin_name() override;
bool is_game_supported(plutonium::sdk::game game) override;
void on_startup(plutonium::sdk::iinterface* interface_ptr, plutonium::sdk::game game) override;
void on_shutdown() override;
plutonium::sdk::iinterface* get_interface();
plutonium::sdk::game get_game();
private:
plutonium::sdk::iinterface* interface_{};
plutonium::sdk::game game_{};
};
plugin* get();
}

View File

@ -71,6 +71,8 @@
#include "game/structs.hpp" #include "game/structs.hpp"
#include "game/symbols.hpp" #include "game/symbols.hpp"
#include "plugin.hpp"
std::string build_gsc_dump(game::scriptInstance_t inst); std::string build_gsc_dump(game::scriptInstance_t inst);
void push_opcode_history(game::scriptInstance_t inst, game::OpcodeVM op); void push_opcode_history(game::scriptInstance_t inst, game::OpcodeVM op);
void push_builtin_history(game::scriptInstance_t inst, int idx); void push_builtin_history(game::scriptInstance_t inst, int idx);