main
sandyx 1 year ago
parent 5c0f3b9891
commit 83a92f8675

@ -1,6 +1,5 @@
SHELL=/bin/sh SHELL=/bin/sh
CC=gcc CC=gcc
AR=
APP_NAME=ghost APP_NAME=ghost
@ -10,7 +9,7 @@ BUILD=build
C_FILES := $(shell find $(SRC) -name '*.c') C_FILES := $(shell find $(SRC) -name '*.c')
O_FILES += $(patsubst $(SRC)/%.c, $(BUILD)/%.o, $(C_FILES)) O_FILES += $(patsubst $(SRC)/%.c, $(BUILD)/%.o, $(C_FILES))
CFLAGS := -O2 -march=native CFLAGS := -O0 -march=native
INCLUDE := INCLUDE :=
LIB := -lraylib LIB := -lraylib

@ -0,0 +1,49 @@
//this file to be compiled as a shared object
#define _GNU_SOURCE
//linux
#include <stdlib.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/uio.h>
static void *addr;
static pid_t pid;
static long long value;
struct iovec local[1];
struct iovec remote[1];
void set_pid(pid_t p) {
pid = p;
}
//value to compare against
void set_value(long long val) {
value = val;
}
bool scan(void *addr, size_t type) {
long long values[1];
local[0].iov_base = values;
local[0].iov_len = sizeof(long long); //may or may not get extra values
remote[0].iov_base = addr;
remote[0].iov_len = local[0].iov_len;
process_vm_readv(pid, local, 1, remote, 1, 0);
//write your comparison function here
//switch on type to trim possible garbage data
switch(type) {
case sizeof(char):
if ((char)value == (char)values[0]) {return true;} break;
if ((short)value == (short)values[0]) {return true;} break;
if ((int)value == (int)values[0]) {return true;} break;
if ((long)value == (long)values[0]) {return true;} break;
}
return false;
}

@ -0,0 +1,5 @@
#include <dlfcn.h>
void load_module(const char *path) {
}

@ -1,7 +1,8 @@
#include <raylib.h> #include <raylib.h>
#include "timer.h" #include "timer.h"
#include "controller.h" #include "controller.h"
#include "scanner.h" //#include "scanner.h"
#include "splits.h"
#include <stdio.h> #include <stdio.h>
GHTimer timer = {0}; GHTimer timer = {0};
@ -10,6 +11,7 @@ char timer_string[50];
int remote_state = 0; int remote_state = 0;
//testing control function
void control(void) { void control(void) {
static int last_state; static int last_state;
if (last_state != remote_state) if (last_state != remote_state)
@ -19,13 +21,18 @@ void control(void) {
last_state = remote_state; last_state = remote_state;
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
InitWindow(640, 480, "Ghost"); InitWindow(420, 640, "Ghost");
SetTargetFPS(60); SetTargetFPS(60);
segment_list segments = open_splits_file("test/splits.ghs");
printf("%d\n" , segments.cnt);
ghtimer_start(&timer); ghtimer_start(&timer);
set_control_func(control); //set_control_func(control);
set_pid(17329); //set_pid(17329);
while (!WindowShouldClose()) { while (!WindowShouldClose()) {
ghtimer_tick(&timer); ghtimer_tick(&timer);
@ -35,11 +42,16 @@ int main(int argc, char *argv[]) {
ctrl_pause(&timer); ctrl_pause(&timer);
} }
remote_state = watch_memory((void *)0x7ffc517105f4, 0); //remote_state = watch_memory((void *)0x7ffc517105f4, 0);
BeginDrawing(); BeginDrawing();
ClearBackground(RAYWHITE); ClearBackground(RAYWHITE);
DrawText(timer_string , 10, 1, 100, BLACK); DrawText(timer_string , 200, 550, 100, BLACK);
for (int i = 0; i < segments.cnt; i++) {
DrawText(segments.list[i]->name, 10, 30 * i, 30, BLACK);
//DrawText(segments.list[i]->realtime, 50, 30 * i, 30, BLACK);
}
EndDrawing(); EndDrawing();
} }
} }

@ -38,7 +38,7 @@ char *load_file(const char *path) {
} }
char *get_next_line(char* buffer, bool clear) { char *get_next_line(char* buffer, bool clear) {
static char* saveptr; static char *saveptr;
static char *line; static char *line;
if (clear) { if (clear) {
@ -84,3 +84,72 @@ char *get_next_token(char *buffer, char *delim, bool clear) {
return token; return token;
} }
//find first non space char;
//copy that index to beginning of string
//replace last space with null
char *strip(char *str, char c) {
char *idx;
int len = strlen(str);
//find index of first non space char
for (int i = 0; i < len; i++) {
if (str[i] != c) {
idx = &str[i];
break;
}
}
//voodoo math
memcpy(str, idx, len+1 - (idx - str));
return str;
}
//cut off the front
char *cut_front(char *str, char c) {
char *idx;
int len = strlen(str);
//find index of first matching char
for (int i = 0; i < len; i++) {
if (str[i] == c) {
idx = &str[i];
break;
}
}
return idx + 1;
}
//cut off the back
char *cut_back(char *str, char c) {
char *idx;
char *cpy = strdup(str);
int len = strlen(str);
//find index of first matching char
for (int i = 0; i < len; i++) {
if (cpy[i] == c) {
cpy[i] = 0;
break;
}
}
return cpy;
}
//strip a string in place
char *strip_all(char *str) {
char *write = str;
char *read = str;
do {
if (*read != ' ') {
*write++ = *read;
}
} while (*read++ && *read != ' ');
return str;
}

@ -10,5 +10,9 @@ size_t get_file_len(FILE *file);
char *load_file(const char *path); char *load_file(const char *path);
char *get_next_line(char* buffer, bool clear); char *get_next_line(char* buffer, bool clear);
char *get_next_token(char *buffer, char *delim, bool clear); char *get_next_token(char *buffer, char *delim, bool clear);
char *strip_all(char *str);
char *strip(char *str, char c);
char *cut_front(char *str, char c);
char *cut_back(char *str, char c);
#endif #endif

@ -0,0 +1,111 @@
#include "splits.h"
#include "parser.h"
#include "timer.h"
void print_segment(segment *seg) {
printf("%s\n", seg->name);
//printf("%ld.%ld\n", seg->realtime.tv_sec, seg->realtime.tv_nsec);
}
struct timespec parse_time(char *str) {
struct timespec time;
time_t hour_t;
time_t min_t;
time_t sec_t;
time_t nsec_t;
sscanf(str, "%ld:%ld:%ld.%ld", &hour_t, &min_t, &sec_t, &nsec_t);
time.tv_sec = (hour_t * 3600) + (min_t * 60) + (sec_t);
time.tv_nsec = nsec_t * 1e+7f;
//printf("%lf\n", timespec_to_double(time));
//180.500_000_000
return time;
}
segment *read_segment(char *file, char *line) {
segment *seg = calloc(1, sizeof(segment));
while (strcmp(line, "end")) {
char *key = strip(cut_back(line, ':'), ' ');
char *value = cut_front(strip(line, ' '), ' ');
if (!strcmp(key, "name")) {
seg->name = strdup(value);
}
if (!strcmp(key, "gametime")) {
seg->gametime = parse_time(value);
}
if (!strcmp(key, "realtime")) {
seg->realtime = parse_time(value);
}
if (!strcmp(key, "best")) {
seg->best = parse_time(value);
}
free(key);
line = get_next_line(file, 0);
}
return seg;
}
segment_list open_splits_file(const char *path) {
char *file = load_file(path);
int idx = 0;
int cnt = 0;
segment_list segments = {0};
char *line = get_next_line(file, 0);
//enumerate segments
while (line != NULL) {
if (!strcmp(line, "segment")) {
segments.cnt++;
}
line = get_next_line(file, 0);
}
//reset strtok_r and create fresh file since it modified it
get_next_line(NULL, 1);
free(file); file = load_file(path);
//make an extra one so the last segment->next == NULL;
segments.list = calloc(cnt + 1, sizeof(segment *));
line = get_next_line(file, 0);
//create segments
while (line != NULL) {
if (!strcmp(line, "segment")) {
segments.list[idx] = read_segment(file, line);
idx++;
}
line = get_next_line(file, 0);
}
for (int i = 0; i < cnt; i++) {
segments.list[i]->next = segments.list[i+1];
}
//check
/*for (int i = 0; i < idx; i++) {
printf("%p\n", segments[i]);
}*/
//no leaky
free(file);
return segments;
}
//probably need a thing to free all the segments

@ -3,12 +3,22 @@
#include <time.h> #include <time.h>
static char *game_name;
typedef struct segment segment; typedef struct segment segment;
struct segment { struct segment {
struct timespec realtime; struct timespec realtime;
struct timespec gametime; struct timespec gametime;
struct timespec best; struct timespec best;
char *name; char *name;
segment *next;
}; };
typedef struct segment_list {
segment **list;
int cnt;
} segment_list;
segment_list open_splits_file(const char *path);
#endif #endif

@ -0,0 +1,22 @@
game: The Game
segment
name: Segment 1
gametime: 00:01:00.50
realtime: 00:02:00.00
best: 00:01:00.00
end
segment
name: Segment 2
gametime: 00:02:00.57
realtime: 00:04:00.00
best: 00:01:00.00
end
segment
name: Segment 3
gametime: 00:03:00.50
realtime: 00:06:00.00
best: 00:01:00.00
end

Binary file not shown.
Loading…
Cancel
Save