Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New get_file_write_time opcode #162

Merged
merged 2 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions cleo_plugins/FileSystemOperations/FileSystemOperations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class FileSystemOperations
CLEO_RegisterOpcode(0x2302, opcode_2302); // write_block_to_file
CLEO_RegisterOpcode(0x2303, opcode_2303); // resolve_filepath
CLEO_RegisterOpcode(0x2304, opcode_2304); // get_script_filename
CLEO_RegisterOpcode(0x2305, opcode_2305); // get_file_write_time

// register event callbacks
CLEO_RegisterCallback(eCallbackId::ScriptsFinalize, OnFinalizeScriptObjects);
Expand Down Expand Up @@ -760,6 +761,45 @@ class FileSystemOperations
OPCODE_CONDITION_RESULT(true);
return OR_CONTINUE;
}

//2305=8, get_file_write_time %1s% year %2d% month %3d% day %3d% hour %4d% minute %5d% second %6d% milisecond %7d% // IF and SET
static OpcodeResult __stdcall opcode_2305(CRunningScript* thread)
{
OPCODE_READ_PARAM_FILEPATH(path);

HANDLE file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (file == INVALID_HANDLE_VALUE)
{
OPCODE_SKIP_PARAMS(7);
OPCODE_CONDITION_RESULT(false);
return OR_CONTINUE;
}

FILETIME writeTime;
if (!GetFileTime(file, nullptr, nullptr, &writeTime))
{
CloseHandle(file);
OPCODE_SKIP_PARAMS(7);
OPCODE_CONDITION_RESULT(false);
return OR_CONTINUE;
}
CloseHandle(file);

// convert to local time
SYSTEMTIME timeUTC, timeLocal;
FileTimeToSystemTime(&writeTime, &timeUTC);
SystemTimeToTzSpecificLocalTime(NULL, &timeUTC, &timeLocal);

OPCODE_WRITE_PARAM_INT(timeLocal.wYear);
OPCODE_WRITE_PARAM_INT(timeLocal.wMonth);
OPCODE_WRITE_PARAM_INT(timeLocal.wDay);
OPCODE_WRITE_PARAM_INT(timeLocal.wHour);
OPCODE_WRITE_PARAM_INT(timeLocal.wMinute);
OPCODE_WRITE_PARAM_INT(timeLocal.wSecond);
OPCODE_WRITE_PARAM_INT(timeLocal.wMilliseconds);
OPCODE_CONDITION_RESULT(true);
return OR_CONTINUE;
}
} fileSystemOperations;

std::set<DWORD> FileSystemOperations::m_hFiles;
Expand Down
110 changes: 110 additions & 0 deletions tests/cleo_tests/FilesystemOperations/2305.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
{$CLEO .s}
{$INCLUDE_ONCE ../cleo_tester.inc}

script_name "2305" // get_file_write_time
test("2305 (get_file_write_time)", tests)
terminate_this_custom_script


function tests
const Test_File_Path = ".\test_file.ini"

before_each(@prepare)
after_each(@finalize)

it("should fail", test1)
it("should return valid data", test2)
it("should work with already opened file", test3)
it("should return correct time", test4)
return

:prepare
1@ = 0x11111111
2@ = 0x22222222
3@ = 0x33333333
4@ = 0x44444444
5@ = 0x55555555
6@ = 0x66666666
7@ = 0x77777777
write_int_to_ini_file {value} 1234 {path} Test_File_Path {section} "general" {key} "test"
return

:finalize
delete_file {fileName} Test_File_Path
return

function test1
1@, 2@, 3@, 4@, 5@, 6@, 7@ = get_file_write_time {path} ".\not_existing.ini"
assert_result_false()
assert_eq(1@, 0x11111111)
assert_eq(2@, 0x22222222)
assert_eq(3@, 0x33333333)
assert_eq(4@, 0x44444444)
assert_eq(5@, 0x55555555)
assert_eq(6@, 0x66666666)
assert_eq(7@, 0x77777777)
end

function test2
1@, 2@, 3@, 4@, 5@, 6@, 7@ = get_file_write_time {path} Test_File_Path
assert_result_true()
assert_range(1@, 2000, 2100) // year
assert_range(2@, 1, 12) // month
assert_range(3@, 1, 31) // day
assert_range(4@, 0, 23) // hour
assert_range(5@, 0, 59) // minute
assert_range(6@, 0, 59) // second
assert_range(7@, 0, 999) // milisedond
trace "~g~~h~~h~Read time: %04d-%02d-%02d %02d:%02d:%02d.%03d" 1@ 2@ 3@ 4@ 5@ 6@ 7@
end

function test3
1@, 2@, 3@, 4@, 5@, 6@, 7@ = get_file_write_time {path} "root:\cleo.asi"
assert_result_true()
assert_range(1@, 2000, 2100) // year
assert_range(2@, 1, 12) // month
assert_range(3@, 1, 31) // day
assert_range(4@, 0, 23) // hour
assert_range(5@, 0, 59) // minute
assert_range(6@, 0, 59) // second
assert_range(7@, 0, 999) // milisecond
end

function test4
var 0@ : Integer
var 1@ : Integer
var 2@ : Integer
var 3@ : Integer
var 4@ : Integer
var 5@ : Integer
var 6@ : Integer
var 7@ : Integer
var 8@ : Integer

0@, 0@, 0@, 1@, 2@, 3@, 4@ = get_file_write_time {path} Test_File_Path
assert_result_true()

// calculate small time stamp
2@ *= 60000 // minutes to ms
3@ *= 1000 // seconds to ms
4@ += 2@
4@ += 3@

wait 500
write_int_to_ini_file {value} 1234 {path} Test_File_Path {section} "general" {key} "test4"

0@, 0@, 0@, 5@, 6@, 7@, 8@ = get_file_write_time {path} Test_File_Path
assert_result_true()
assert_eq(5@, 1@) // hour did not changed meanwhile

// calculate small time stamp
6@ *= 60000 // minutes to ms
7@ *= 1000 // seconds to ms
8@ += 6@
8@ += 7@

// timestamps delta
8@ -= 4@
assert_range(8@, 450, 550) // expected 500 plus some margin
end
end
13 changes: 13 additions & 0 deletions tests/cleo_tests/cleo_tester.inc
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,19 @@ function assert_neq(actual: int, expected: int)
end
end

/// checks if int value is within specified range, otherwise stops the test execution
function assert_range(actual: int, expectedMin: int, expectedMax: int)
_cleo_tester_increment_assert()
if
actual < expectedMin
then
_cleo_tester_fail()
trace "%08X to %08X expected~n~%08X occured" expectedMin expectedMax actual
breakpoint
terminate_this_custom_script
end
end

/// checks if two float values are equal, otherwise stops the test execution
function assert_eqf(actual: float, expected: float)
_cleo_tester_increment_assert()
Expand Down