diff --git a/build/controller.o b/build/controller.o new file mode 100644 index 0000000..3b87275 Binary files /dev/null and b/build/controller.o differ diff --git a/build/gsl_reader.o b/build/gsl_reader.o new file mode 100644 index 0000000..bf080f4 Binary files /dev/null and b/build/gsl_reader.o differ diff --git a/build/main.o b/build/main.o new file mode 100644 index 0000000..d5c0ddd Binary files /dev/null and b/build/main.o differ diff --git a/build/parser.o b/build/parser.o new file mode 100644 index 0000000..dab3eab Binary files /dev/null and b/build/parser.o differ diff --git a/build/scanner.o b/build/scanner.o new file mode 100644 index 0000000..0994e1a Binary files /dev/null and b/build/scanner.o differ diff --git a/build/timer.o b/build/timer.o new file mode 100644 index 0000000..1ae1f3b Binary files /dev/null and b/build/timer.o differ diff --git a/src/controller.c b/src/controller.c new file mode 100644 index 0000000..f9e9f51 --- /dev/null +++ b/src/controller.c @@ -0,0 +1,29 @@ +#include "controller.h" + +int *splits = 0; + +void ctrl_pause(GHTimer *timer) { + if (timer->paused) { + ghtimer_resume(timer); + } else { + ghtimer_pause(timer); + } +} + +void ctrl_start(GHTimer *timer) { + if (timer->running) { + if (splits != NULL) { + //splits_next(); + } else { + ghtimer_stop(timer); //stop or reset, save splits + } + + //pause timer if last split + if (splits == NULL) { + ghtimer_pause(timer); + return; + } + } else { + ghtimer_start(timer); + } +} diff --git a/src/controller.h b/src/controller.h new file mode 100644 index 0000000..4d0fbd5 --- /dev/null +++ b/src/controller.h @@ -0,0 +1,11 @@ +#ifndef CTRL_H +#define CTRL_H + +#include "timer.h" +//controller binds the timer to the splits +//and to the input handler +//and to the autosplitter + +void ctrl_start(GHTimer *timer); +void ctrl_pause(GHTimer *timer); +#endif diff --git a/src/gsl_reader.c b/src/gsl_reader.c new file mode 100644 index 0000000..2c5fd97 --- /dev/null +++ b/src/gsl_reader.c @@ -0,0 +1,11 @@ +//gsl_reader.c +#include "parser.h" + +void init_autosplit(const char *path) { + char *file_buffer = load_file(path); + char *line; + + for (line = get_next_line(file_buffer, 0); line != NULL; line = get_next_line(file_buffer, 0)) { + printf("%s\n", line); + } +} diff --git a/src/gsl_reader.h b/src/gsl_reader.h new file mode 100644 index 0000000..e7fb046 --- /dev/null +++ b/src/gsl_reader.h @@ -0,0 +1 @@ +#ifndef GSL_READER diff --git a/src/main.c b/src/main.c index 071e95f..c0ba708 100644 --- a/src/main.c +++ b/src/main.c @@ -1,23 +1,45 @@ #include #include "timer.h" +#include "controller.h" +#include "scanner.h" +#include + +GHTimer timer = {0}; char timer_string[50]; +int remote_state = 0; + +void control(void) { + static int last_state; + if (last_state != remote_state) + ctrl_pause(&timer); + + //printf("%d, %d\n", last_state, remote_state); + last_state = remote_state; +} + int main(int argc, char *argv[]) { InitWindow(640, 480, "Ghost"); SetTargetFPS(60); - GHTimer timer = {0}; - ghtimer_start(&timer); + set_control_func(control); + set_pid(17329); while (!WindowShouldClose()) { ghtimer_tick(&timer); ghtimer_timestring(&timer, timer_string); + + if (IsKeyPressed(KEY_P)) { + ctrl_pause(&timer); + } + + remote_state = watch_memory((void *)0x7ffc517105f4, 0); BeginDrawing(); ClearBackground(RAYWHITE); - DrawText(timer_string , 0, 0, 20, BLACK); + DrawText(timer_string , 10, 1, 100, BLACK); EndDrawing(); } } diff --git a/src/parser.c b/src/parser.c new file mode 100644 index 0000000..dc52261 --- /dev/null +++ b/src/parser.c @@ -0,0 +1,86 @@ +#include "parser.h" + +/* + I've separated this out into its own file + so it can be used anywhere, and be compiled + with any C standard that supports strtok_r. + +*/ + +size_t get_file_len(FILE *file) { + fseek(file, 0, SEEK_END); + unsigned int len = ftell(file); + fseek(file, 0, SEEK_SET); + return len; +} + +/* + loads a files and mallocates a buffer + and returns a pointer to it. + + remember to free the buffer when you're done. +*/ +char *load_file(const char *path) { + FILE *file = fopen(path, "r"); + if (file == NULL) { + printf("%s\n", "Could not open file."); + return NULL; + } + + size_t len = get_file_len(file); + + char *buffer = malloc(len); + + #pragma GCC diagnostic ignored "-Wunused-result" + fread(buffer, len, 1, file); + fclose(file); + return buffer; +} + +char *get_next_line(char* buffer, bool clear) { + static char* saveptr; + static char *line; + + if (clear) { + saveptr = NULL; + line = NULL; + return NULL; + } + + if (saveptr == NULL) { + line = strtok_r(buffer, "\n", &saveptr); + } else { + if (line == NULL) { + saveptr = NULL; + return NULL; + } + + line = strtok_r(NULL, "\n", &saveptr); + } + + return line; +} + +char *get_next_token(char *buffer, char *delim, bool clear) { + static char *saveptr; + static char *token; + + if (clear) { + saveptr = NULL; + token = NULL; + return NULL; + } + + if (saveptr == NULL) { + token = strtok_r(buffer, delim, &saveptr); + } else { + if (token == NULL) { + saveptr = NULL; + return NULL; + } + + token = strtok_r(NULL, delim, &saveptr); + } + + return token; +} diff --git a/src/parser.h b/src/parser.h new file mode 100644 index 0000000..cb3bd9f --- /dev/null +++ b/src/parser.h @@ -0,0 +1,14 @@ +#ifndef PARSER_H +#define PARSER_H + +#include +#include +#include +#include + +size_t get_file_len(FILE *file); +char *load_file(const char *path); +char *get_next_line(char* buffer, bool clear); +char *get_next_token(char *buffer, char *delim, bool clear); + +#endif diff --git a/src/scanner.c b/src/scanner.c new file mode 100644 index 0000000..b3406ff --- /dev/null +++ b/src/scanner.c @@ -0,0 +1,54 @@ +#define _GNU_SOURCE +/* + the idea of the scanner is that + you give it a memory address to watch + and it reads from the address and if it + matches the desired value, it sends + a message to a controller + + ideally to detect a loading screen + you would want to call the control function + on a state change rather than every time + the value matches +*/ + +//if linux +#include +#include +#include +#include + +//only watch one process at a time +static pid_t pid; + +//control function +static void (*callback)(void); + +int watch_memory(void *addr, int desired) { + int values[1]; + struct iovec local[1]; + struct iovec remote[1]; + + local[0].iov_base = values; + local[0].iov_len = 1 * sizeof(int); + + remote[0].iov_base = (void *) addr; + remote[0].iov_len = 1 * sizeof(int); + + int nread = process_vm_readv(pid, local, 4, remote, 4, 0); + + if (desired == values[0]) { + //printf("%d %d\n", values[0], desired); + callback(); + } + + return values[0]; +} + +void set_control_func(void (*c)(void)) { + callback = c; +} + +void set_pid(pid_t p) { + pid = p; +} diff --git a/src/scanner.h b/src/scanner.h new file mode 100644 index 0000000..d5c8645 --- /dev/null +++ b/src/scanner.h @@ -0,0 +1,11 @@ +#ifndef SCANNER_H +#define SCANNER_H + +#include +#include +#include + +int watch_memory(void *addr, int desired); +void set_control_func(void (*c)(void)); +void set_pid(pid_t p); +#endif diff --git a/src/splits.h b/src/splits.h new file mode 100644 index 0000000..2fd9c6c --- /dev/null +++ b/src/splits.h @@ -0,0 +1,14 @@ +#ifndef SPLITS_H +#define SPLITS_H + +#include + +typedef struct segment segment; +struct segment { + struct timespec realtime; + struct timespec gametime; + struct timespec best; + char *name; +}; + +#endif diff --git a/test/auto.gsl b/test/auto.gsl new file mode 100644 index 0000000..f8cca86 --- /dev/null +++ b/test/auto.gsl @@ -0,0 +1,7 @@ +auto + name: NameOfProcess.exe + addr: 0x1234123412341234 + init: 0 + test: 1 + func: split, pause +end diff --git a/test/test b/test/test new file mode 100755 index 0000000..219c0ca Binary files /dev/null and b/test/test differ diff --git a/test/test.c b/test/test.c new file mode 100644 index 0000000..a412572 --- /dev/null +++ b/test/test.c @@ -0,0 +1,39 @@ +#include +#include +#include + +static pid_t pid; + +int main(void) { + unsigned int read_value = 1; + InitWindow(640, 480, "Test Window"); + SetTargetFPS(60); + char pid_buf[20]; + char adr_buf[20]; + + Color primary = WHITE; + Color secondary = BLACK; + pid = getpid(); + sprintf(pid_buf, "%d", pid); + sprintf(adr_buf, "%p", &read_value); + + while (!WindowShouldClose()) { + if (IsKeyPressed(KEY_SPACE)) { + read_value ^= 1; + } + + BeginDrawing(); + + primary = read_value ? WHITE : BLACK; + secondary = !read_value ? WHITE : BLACK; + ClearBackground(primary); + + DrawText(pid_buf, 0, 0, 50, secondary); + DrawText(adr_buf, 0, 50 + 1, 50, secondary); + + EndDrawing(); + } + + CloseWindow(); + return 0; +}