Skip to content

Commit

Permalink
New get_file_write_time opcode (#162)
Browse files Browse the repository at this point in the history
New opcode get_file_write_time
  • Loading branch information
MiranDMC authored Jun 24, 2024
1 parent 5c5d2a4 commit f4ee380
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 0 deletions.
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

0 comments on commit f4ee380

Please sign in to comment.