Compare commits

..

18 Commits

Author SHA1 Message Date
b700113b88 changed mind, added helpers to derive pausedTime without a global 2023-08-21 00:40:13 +10:00
dbf8dce580 removed pausedTime global, its better for clients to derive 2023-08-20 21:15:16 +10:00
9c0d4befba added separate reset button in addition to stop 2023-08-20 18:13:53 +10:00
d09b991771 added getter for event types, and fixed a pausedTime bug 2023-08-20 03:54:29 +10:00
057d051a3a add basic setter for meta-data values 2023-08-16 17:02:25 +10:00
073e610966 added requesting event times 2023-07-25 22:07:33 +10:00
47369a86e9 fixed some undo and redo bugs 2023-07-25 21:30:55 +10:00
0812d68dd1 generalised request commands for metadata tags 2023-07-25 20:24:05 +10:00
f1e2c85e3a made the communication between the server and cmdline client more direct 2023-07-25 19:48:27 +10:00
1bb5864a29 swap out single byte socket communication with 256 byte buffer 2023-07-25 02:01:07 +10:00
fd8bbadb1e added convenient combination command functions 2023-07-24 22:41:54 +10:00
b93f2f0aa7 added proper run clearing function 2023-07-24 18:44:01 +10:00
c24f516380 added segments array 2023-07-20 22:25:09 +10:00
1aa1ed514a added run count 2023-07-20 20:38:06 +10:00
c7387f5acb fixed some infinite loop bug 2023-07-20 20:10:23 +10:00
d3f7a25a64 added saving previous run to file on new run start 2023-07-20 01:18:44 +10:00
f5e5c506af fixed a dumb buffer overflow i think 2023-07-19 01:45:26 +10:00
b208382e60 added nix build stuff 2023-07-18 23:53:22 +10:00
9 changed files with 623 additions and 234 deletions

View File

@ -1,5 +1,5 @@
TARGET = quest TARGET = quest
LIBS = -lm -luiohook -lcjson LIBS = -lm -luiohook -lcjson -lxcb -lXinerama -lX11
CC = gcc CC = gcc
CFLAGS = -g -Wall CFLAGS = -g -Wall
INSTALL_PATH = /usr/local INSTALL_PATH = /usr/local

2
default.nix Normal file
View File

@ -0,0 +1,2 @@
{pkgs ? import <nixpkgs> {} }:
pkgs.callPackage ./derivation.nix {}

23
derivation.nix Normal file
View File

@ -0,0 +1,23 @@
{ stdenv }:
stdenv.mkDerivation rec {
name = "quest-${version}";
version = "0.7";
src = ./src2/.;
nativeBuildInputs = [ ];
buildInputs = [ ];
buildPhase = ''
gcc server.c -o quest-daemon
gcc client.c -o quest-log
gcc tui.c -o quest
'';
installPhase = ''
mkdir -p $out/bin
cp quest-daemon $out/bin
cp quest-log $out/bin
cp quest $out/bin
'';
}

View File

@ -102,9 +102,9 @@ Runs by themselves are simply a list of events that occured
to this data, these more complicated directives are used to define segments to this data, these more complicated directives are used to define segments
that are played between splits and routes made up of these segments. that are played between splits and routes made up of these segments.
Define all your possible segments first, followed by all routes. Define all your possible segments first, followed by all routes.
If no segments are defined, a single unnamed segment is assumed. If no segments are defined, a single unnamed segment is to be assumed.
If no routes are defined, a single unnamed route that passes through all If no routes are defined, a single unnamed route that passes through all
segments in the order of their definition is assumed. segments in the order of their definition is to be assumed.
Segment Segment
Shortname Shortname
@ -141,7 +141,7 @@ Run Directives
These directives are much more complicated and are not intended to be written These directives are much more complicated and are not intended to be written
by a human but rather by the timer software, they will make up the majority by a human but rather by the timer software, they will make up the majority
of a file as they are the run history which may be quite long. of a file as they are the run history which may be quite long.
These data passed by these directives exists agnostic of segments, route, games, The data passed by these directives exists agnostic of segments, route, games,
or categories, rather they are either explicitly matched with metadata that is or categories, rather they are either explicitly matched with metadata that is
applicable, or by default is matched with the last set of metadata declared by applicable, or by default is matched with the last set of metadata declared by
the time of the run directive the time of the run directive
@ -163,7 +163,7 @@ Run
3121111 3121111
Pause Pause
421397 421397
Unpause Resume
2016-10-23 11:16:04.175Z 2016-10-23 11:16:04.175Z
Stop (The last event in a run is always a Stop) Stop (The last event in a run is always a Stop)
123111 123111

View File

@ -22,6 +22,7 @@ struct pastseg *pastRuns;
int segCount; int segCount;
int currSeg = -1; int currSeg = -1;
char currentTime[10]; char currentTime[10];
int *route;
void sub_timespec(struct timespec t1, struct timespec t2, struct timespec* td) void sub_timespec(struct timespec t1, struct timespec t2, struct timespec* td)
{ {

View File

@ -24,6 +24,7 @@
struct segment struct segment
{ {
int id;
char *name; char *name;
int ms; int ms;
bool isSkipped; bool isSkipped;
@ -49,6 +50,7 @@ extern struct segment *bestsegs;
extern struct segment *wrrun; extern struct segment *wrrun;
extern struct segment *segments; extern struct segment *segments;
extern struct timespec notif; extern struct timespec notif;
extern int *route;
void sub_timespec(struct timespec t1, struct timespec t2, struct timespec* td); void sub_timespec(struct timespec t1, struct timespec t2, struct timespec* td);
void add_timespec(struct timespec t1, struct timespec t2, struct timespec* td); void add_timespec(struct timespec t1, struct timespec t2, struct timespec* td);

View File

@ -13,7 +13,6 @@ int main(int argc, char *argv[]) {
struct hostent *server; struct hostent *server;
char buffer[256]; char buffer[256];
char commandcode;
if (argc < 2) { if (argc < 2) {
fprintf(stderr,"usage %s command\n", argv[0]); fprintf(stderr,"usage %s command\n", argv[0]);
@ -48,71 +47,27 @@ int main(int argc, char *argv[]) {
exit(1); exit(1);
} }
if (!strcmp(argv[1], "time")) { bzero(buffer, 256);
commandcode = 1; for (int i = 1; i < argc; i++) {
} else if (!strcmp(argv[1], "start")) { strcat(buffer, argv[i]);
commandcode = 2; strcat(buffer, " ");
} else if (!strcmp(argv[1], "stop")) {
commandcode = 3;
} else if (!strcmp(argv[1], "kill")) {
commandcode = 4;
} else if (!strcmp(argv[1], "split")) {
commandcode = 5;
} else if (!strcmp(argv[1], "skip")) {
commandcode = 6;
} else if (!strcmp(argv[1], "pause")) {
commandcode = 7;
} else if (!strcmp(argv[1], "resume")) {
commandcode = 8;
} else if (!strcmp(argv[1], "undo")) {
commandcode = 9;
} else if (!strcmp(argv[1], "redo")) {
commandcode = 10;
} else if (!strcmp(argv[1], "foreground")) {
commandcode = 11;
} else if (!strcmp(argv[1], "background")) {
commandcode = 12;
} else {
perror("No valid command given");
exit(1);
} }
/* Send message to the server */ /* Send message to the server */
n = write(sockfd, &commandcode, 1); n = write(sockfd, &buffer, 256);
if (n < 0) { if (n < 0) {
perror("ERROR writing to socket"); perror("ERROR writing to socket");
exit(1); exit(1);
} }
/* Now read server response */ /* Now read server response */
//bzero(buffer,256);
//read an int response
if (commandcode < 11) {
int x = -1;
n = read(sockfd, &x, sizeof(int));
if (n < 0) {
perror("ERROR reading from socket");
exit(1);
}
if (x != -1)
printf("%d\n",x);
}
//read a string response
else {
bzero(buffer,256); bzero(buffer,256);
n = read(sockfd, &buffer, 255); n = read(sockfd, &buffer, 256);
if (n < 0) { if (n < 0) {
perror("ERROR reading from socket"); perror("ERROR reading from socket");
exit(1); exit(1);
} }
if (buffer != NULL) if (buffer != NULL)
printf("%s", buffer); printf("%s\n", buffer);
}
return 0; return 0;
} }

View File

@ -12,10 +12,11 @@
#define NS_PER_S 1000000000 #define NS_PER_S 1000000000
struct timespec finish, delta; struct timespec finish, delta;
int pausedTime = 0;
bool timerActive = false; bool timerActive = false;
bool paused = false; bool paused = false;
bool alive = true; bool alive = true;
bool hasUndoneAtLeastOnce = false;
bool runUnsaved = false;
int timerOffset = 0; int timerOffset = 0;
enum event_type { enum event_type {
START, START,
@ -23,12 +24,23 @@ enum event_type {
SKIP, SKIP,
PAUSE, PAUSE,
RESUME, RESUME,
RESET,
STOP STOP
}; };
struct run_event { struct run_event {
enum event_type type; enum event_type type;
struct timespec time; struct timespec time;
}; };
struct segment {
char *shortname;
char *longname;
char *description;
};
struct route {
char *name;
int segment_count;
struct segment *segments;
};
struct run_event *run; struct run_event *run;
//Enough to hold a sm64 16 star, can realloc later //Enough to hold a sm64 16 star, can realloc later
@ -37,10 +49,58 @@ int runMarker = 0;
int runMarker2 = 0; int runMarker2 = 0;
//save file stuff //save file stuff
char *default_file_name = "untitled.quest";
int run_count = 0;
int files = 0; int files = 0;
char **filePaths = NULL; char **filePaths = NULL;
char **names, **values; char **meta_keys, **meta_values;
int valuecount; int valuecount;
struct segment *segments;
int segment_count = 0;
struct route *routes;
int route_count = 0;
struct route current_route;
//functions
void sub_timespec(struct timespec t1, struct timespec t2, struct timespec* td);
void offset_timespec(int milliseconds, struct timespec* t);
int timespecToMS(struct timespec t);
void extend_run();
void add_event(enum event_type t);
void appendRunToFile();
void timespecToRFC3339(struct timespec t, char buf[]);
void loadFiles();
void add_segment(char *sname, char *lname, char *desc);
void addFile(char *path);
void sendInt(int sock, int value);
void sendValue(int sock, char* name);
void sendString(int sock, char* str);
void process_socket_input(int sock);
void set_metadata(char *key, char *value);
void save_metadata_to_file(char *token, char *token2);
void reset_timer();
int current_ms();
//basic timer commands
void start();
void split();
void stop();
void skip();
void undo();
void redo();
void pause_timer();
void resume();
void reset();
//convenient combination commands
void start_split_stop();
void start_reset();
void start_split();
void split_stop();
void start_stop();
void pause_resume();
void undo_redo();
void sub_timespec(struct timespec t1, struct timespec t2, struct timespec* td) void sub_timespec(struct timespec t1, struct timespec t2, struct timespec* td)
{ {
@ -92,100 +152,149 @@ void add_event(enum event_type t)
offset_timespec(timerOffset, &run[runMarker].time); offset_timespec(timerOffset, &run[runMarker].time);
runMarker++; runMarker++;
runMarker2 = runMarker; runMarker2 = runMarker;
hasUndoneAtLeastOnce = false;
}
void reset_timer()
{
runMarker = 0;
runMarker2 = 0;
} }
void start() void start()
{ {
//TODO: Save the old run to the file before the new one starts, if (timerActive) return;
//Save the old run to the file before the new one starts,
//the reason to do this here is it gives the runner a chance to undo //the reason to do this here is it gives the runner a chance to undo
//if they accidentally hit the stop button //if they accidentally hit the stop button
//TODO: Clear the run data first appendRunToFile();
reset_timer();
timerActive = true; timerActive = true;
add_event(START); add_event(START);
} }
void stop() void stop()
{ {
if (!timerActive) return;
timerActive = false; timerActive = false;
add_event(STOP); add_event(STOP);
//this makes sure the time clients recieve from time //this makes sure the time clients recieve from time
//requests match the time on the stop event //requests match the time on the stop event
finish = run[runMarker - 1].time; finish = run[runMarker - 1].time;
runUnsaved = true;
}
//Identical function to stop() but with a RESET event
void reset()
{
if (!timerActive) return;
timerActive = false;
add_event(RESET);
finish = run[runMarker - 1].time;
runUnsaved = true;
}
void start_split_stop()
{
if (!timerActive) {
start();
} else {
if (runMarker < current_route.segment_count) {
split();
} else {
stop();
}
}
}
void start_split()
{
if (!timerActive) start();
else split();
}
void split_stop()
{
if (runMarker < current_route.segment_count) split();
else stop();
}
void start_stop()
{
if (!timerActive) start();
else stop();
}
void start_reset()
{
if (!timerActive) start();
else reset();
} }
void split() void split()
{ {
if (!timerActive) return;
add_event(SPLIT); add_event(SPLIT);
} }
void skip() void skip()
{ {
if (!timerActive) return;
add_event(SKIP); add_event(SKIP);
} }
void addPauseTime()
{
int pauseEvent = 0;
for (int i = runMarker - 2; i >= 1; i--) {
if (run[i].type == PAUSE) {
pauseEvent = i;
break;
}
}
sub_timespec(run[pauseEvent].time, run[runMarker - 1].time, &delta);
pausedTime += timespecToMS(delta);
}
void subtractPauseTime()
{
int pauseEvent = 0;
for (int i = runMarker - 1; i >= i; i--) {
if (run[i].type == PAUSE) {
pauseEvent = i;
break;
}
}
sub_timespec(run[pauseEvent].time, run[runMarker].time, &delta);
pausedTime -= timespecToMS(delta);
}
void undo() void undo()
{ {
if (runMarker > 0) { if (runMarker > 0) {
runMarker--; runMarker--;
if (run[runMarker].type == STOP) if (run[runMarker].type == STOP) {
timerActive = true; timerActive = true;
runUnsaved = false;
}
if (run[runMarker].type == START) if (run[runMarker].type == START)
timerActive = false; timerActive = false;
if (run[runMarker].type == PAUSE) if (run[runMarker].type == PAUSE)
paused = false; paused = false;
if (run[runMarker].type == RESUME) { if (run[runMarker].type == RESUME) {
paused = true; paused = true;
subtractPauseTime();
} }
hasUndoneAtLeastOnce = true;
} }
} }
void redo() void redo()
{ {
if (!timerActive) return;
if (runMarker < runMarker2) { if (runMarker < runMarker2) {
runMarker++; runMarker++;
if (run[runMarker - 1].type == STOP) if (run[runMarker - 1].type == STOP) {
timerActive = false; timerActive = false;
runUnsaved = true;
finish = run[runMarker - 1].time;
}
if (run[runMarker - 1].type == START) if (run[runMarker - 1].type == START)
timerActive = true; timerActive = true;
if (run[runMarker - 1].type == PAUSE) if (run[runMarker - 1].type == PAUSE)
paused = true; paused = true;
if (run[runMarker - 1].type == RESUME) { if (run[runMarker - 1].type == RESUME) {
paused = false; paused = false;
addPauseTime();
} }
} }
if (runMarker == runMarker2) {
hasUndoneAtLeastOnce = false;
}
}
void undo_redo()
{
if (hasUndoneAtLeastOnce) redo();
else undo();
} }
//this isnt just called pause() because that would overlap with <unistd.h> //this isnt just called pause() because that would overlap with <unistd.h>
void pause_timer() void pause_timer()
{ {
if (!timerActive) return;
if (!paused) { if (!paused) {
add_event(PAUSE); add_event(PAUSE);
paused = true; paused = true;
@ -194,50 +303,162 @@ void pause_timer()
void resume() void resume()
{ {
if (!timerActive) return;
if (paused) { if (paused) {
add_event(RESUME); add_event(RESUME);
paused = false; paused = false;
addPauseTime();
} }
} }
void pause_resume()
{
if (paused) resume();
else pause_timer();
}
void appendRunToFile()
{
if (!runUnsaved)
return;
char* save_path = NULL;
if (files <= 0)
save_path = default_file_name;
else
save_path = filePaths[0];
FILE* fp;
fp = fopen(save_path, "a+");
fprintf(fp, "%s\n", "Run");
if (current_route.name != NULL) {
fprintf(fp, "\t%s\n", "Route");
fprintf(fp, "\t\t%s\n", current_route.name);
}
int i = 0;
bool done = false;
while (!done) {
if (run[i].type == STOP) {
done = true;
}
switch (run[i].type) {
case START:
fprintf(fp, "\t%s\n", "Start");
break;
case SPLIT:
fprintf(fp, "\t%s\n", "Split");
break;
case SKIP:
fprintf(fp, "\t%s\n", "Skip");
break;
case PAUSE:
fprintf(fp, "\t%s\n", "Pause");
break;
case RESUME:
fprintf(fp, "\t%s\n", "Resume");
break;
case RESET:
fprintf(fp, "\t%s\n", "Reset");
break;
case STOP:
fprintf(fp, "\t%s\n", "Stop");
break;
}
if (i == 0) {
char buf[25];
timespecToRFC3339(run[i].time, buf);
fprintf(fp, "\t\t%s\n", buf);
}
else {
sub_timespec(run[i - 1].time, run[i].time, &delta);
fprintf(fp, "\t\t%d\n", timespecToMS(delta));
}
i++;
}
fprintf(fp, "\n");
fclose(fp);
run_count++;
runUnsaved = false;
}
void timespecToRFC3339(struct timespec t, char buf[])
{
const int tmpsize = 21;
struct tm tm;
gmtime_r(&t.tv_sec, &tm);
strftime(buf, tmpsize, "%Y-%m-%d %H:%M:%S.", &tm);
sprintf(buf + tmpsize - 1, "%03luZ", (t.tv_nsec / 1000000));
}
void loadFiles() void loadFiles()
{ {
FILE* fp; FILE* fp;
//TODO: for now we're just looking for the metadata values
char buff[255]; char buff[255];
char buff2[255]; char buff2[255];
for (int i = 0; i < files; i++) { for (int i = 0; i < files; i++) {
fp = fopen(filePaths[i], "r"); fp = fopen(filePaths[i], "r+");
while(1) { while(1) {
char *x = fgets(buff, 255, fp); if (!fgets(buff, 255, fp))
if (buff[0] == '/' && buff[1] == '/' || buff[0] == '\n') break;
continue; if (buff[0] == '/' && buff[1] == '/' || buff[0] == '\n' || buff[0] == '\t')
if (!strcmp(buff, "Segment") || !strcmp(buff, "Route") || x == NULL) continue;
if (!strcmp(buff, "Segment\n")) {
char *s = NULL;
char *l = NULL;
char *d = NULL;
for (int x = 0; x < 3; x++) {
if (!fgets(buff2, 255, fp))
break;
if (!strcmp(buff2, "\tShortname\n")) {
if (!fgets(buff2, 255, fp))
break;
s = malloc(strlen(buff2) - 2);
s = strncpy(s, buff2 + 2, strlen(buff2) - 2);
s[strlen(s) - 1] = '\0';
} else if (!strcmp(buff2, "\tLongname\n")) {
if (!fgets(buff2, 255, fp))
break;
l = malloc(strlen(buff2) - 2);
l = strncpy(l, buff2 + 2, strlen(buff2) - 2);
l[strlen(l) - 1] = '\0';
} else if (!strcmp(buff2, "\tDescription\n")) {
if (!fgets(buff2, 255, fp))
break;
d = malloc(strlen(buff2) - 2);
d = strncpy(d, buff2 + 2, strlen(buff2) - 2);
d[strlen(d) - 1] = '\0';
}
}
add_segment(s, l, d);
continue;
}
if (!strcmp(buff, "Route\n"))
continue;
if (!strcmp(buff, "Run\n")) {
run_count++;
continue;
}
if (!fgets(buff2, 255, fp))
break; break;
fgets(buff2, 255, fp);
if (buff2[0] == '\t') { if (buff2[0] == '\t') {
valuecount++; buff[strlen(buff) - 1] = '\0';
names = realloc(names, sizeof(char*) * valuecount); buff2[strlen(buff2) - 1] = '\0';
names[valuecount - 1] = malloc(strlen(buff) - 1); set_metadata(buff, buff2 + 1);
strncpy(names[valuecount - 1], buff, strlen(buff) - 1);
names[valuecount - 1][strlen(buff)] = '\0';
values = realloc(values, sizeof(char*) * valuecount);
values[valuecount - 1] = malloc(strlen(buff2) - 2);
strncpy(values[valuecount - 1], buff2 + 1, strlen(buff2) - 1);
values[valuecount - 1][strlen(buff2)] = '\0';
} }
} }
fclose(fp); fclose(fp);
} }
//Print metadata arrays
for (int i = 0; i < valuecount; i++) {
printf("%s | %s", names[i], values[i]);
} }
void add_segment(char *sname, char *lname, char *desc)
{
segment_count++;
segments = realloc(segments, sizeof(struct segment) * segment_count);
segments[segment_count - 1].shortname = sname;
segments[segment_count - 1].longname = lname;
segments[segment_count - 1].description = desc;
} }
//TODO: eventually file loading should support loading multiple files //TODO: eventually file loading should support loading multiple files
@ -249,19 +470,23 @@ void addFile(char *path)
loadFiles(); loadFiles();
} }
void sendTime(int sock) int current_ms()
{ {
int n, x;
if (timerActive) if (timerActive)
clock_gettime(CLOCK_REALTIME, &finish); clock_gettime(CLOCK_REALTIME, &finish);
if (paused) { //if (paused) {
sub_timespec(run[0].time, run[runMarker - 1].time, &delta); // sub_timespec(run[0].time, run[runMarker - 1].time, &delta);
} else { //} else {
sub_timespec(run[0].time, finish, &delta); sub_timespec(run[0].time, finish, &delta);
//}
return timespecToMS(delta);
} }
x = timespecToMS(delta) - pausedTime;
n = write(sock, &x, sizeof(int));
void sendInt(int sock, int value)
{
char buffer[256];
sprintf(buffer, "%d", value);
int n = write(sock, &buffer, 256);
if (n < 0) { if (n < 0) {
perror("ERROR writing to socket"); perror("ERROR writing to socket");
exit(1); exit(1);
@ -270,73 +495,276 @@ void sendTime(int sock)
void sendValue(int sock, char* name) void sendValue(int sock, char* name)
{ {
char buffer[256];
int n, x; int n, x;
bool namefound = false; bool namefound = false;
if (name == NULL) {
strcpy(buffer, "DATA NOT PRESENT");
} else {
for(int i = 0; i < valuecount; i++) { for(int i = 0; i < valuecount; i++) {
if (!strcmp(names[i], name)) { if (!strcmp(meta_keys[i], name)) {
x = i; x = i;
namefound = true; namefound = true;
} }
} }
if (namefound) if (namefound)
n = write(sock, values[x], strlen(values[x])); strcpy(buffer, meta_values[x]);
else else
n = write(sock, "DATA NOT PRESENT", 17); strcpy(buffer, "DATA NOT PRESENT");
}
n = write(sock, &buffer, 256);
if (n < 0) { if (n < 0) {
perror("ERROR writing to socket"); perror("ERROR writing to socket");
exit(1); exit(1);
} }
} }
void doprocessing (int sock) void sendString(int sock, char* str)
{
char buffer[256];
strcpy(buffer, str);
int n = write(sock, &buffer, 256);
if (n < 0) {
perror("ERROR writing to socket");
exit(1);
}
}
void set_metadata(char *key, char *value)
{
char key_pos = -1;
for (int i = 0; i < valuecount; i++)
if (!strcmp(meta_keys[i], key))
key_pos = i;
if (key_pos > -1) {
meta_values[key_pos] = realloc(meta_values[key_pos], strlen(value));
strncpy(meta_values[key_pos], value, strlen(value));
meta_values[key_pos][strlen(value)] = '\0';
} else {
valuecount++;
meta_keys = realloc(meta_keys, sizeof(char*) * valuecount);
meta_keys[valuecount - 1] = malloc(strlen(key));
strncpy(meta_keys[valuecount - 1], key, strlen(key));
meta_keys[valuecount - 1][strlen(key)] = '\0';
meta_values = realloc(meta_values, sizeof(char*) * valuecount);
meta_values[valuecount - 1] = malloc(strlen(value));
strncpy(meta_values[valuecount - 1], value, strlen(value));
meta_values[valuecount - 1][strlen(value)] = '\0';
}
}
void save_metadata_to_file(char *token, char *token2)
{
char* save_path = NULL;
if (files <= 0)
save_path = default_file_name;
else
save_path = filePaths[0];
FILE* fp;
fp = fopen(save_path, "r+");
fprintf(fp, "%s\n", token);
fprintf(fp, "\t%s\n\n", token2);
fclose(fp);
}
void process_socket_input(int sock)
{ {
int n; int n;
char commandcode; char buffer[256];
n = read(sock,&commandcode,1); n = read(sock, &buffer, 256);
if (n < 0) { if (n < 0) {
perror("ERROR reading from socket"); perror("ERROR reading from socket");
exit(1); exit(1);
} }
if (commandcode == 1) { char *token = strtok(buffer, " ");
//printf("Recieved time command\n");
sendTime(sock); //Imperative commands
} else if (commandcode == 2) { if (!strcmp(token, "start")) {
printf("Recieved start command\n");
start(); start();
} else if (commandcode == 3) { } else if (!strcmp(token, "stop")) {
printf("Recieved stop command\n");
stop(); stop();
} else if (commandcode == 4) { } else if (!strcmp(token, "reset")) {
printf("Recieved kill command\n"); reset();
} else if (!strcmp(token, "kill")) {
alive = false; alive = false;
} else if (commandcode == 5) { } else if (!strcmp(token, "split")) {
printf("Recieved split command\n");
split(); split();
} else if (commandcode == 6) { } else if (!strcmp(token, "skip")) {
printf("Recieved skip command\n");
skip(); skip();
} else if (commandcode == 7) { } else if (!strcmp(token, "pause")) {
printf("Recieved pause command\n");
pause_timer(); pause_timer();
} else if (commandcode == 8) { } else if (!strcmp(token, "resume")) {
printf("Recieved resume command\n");
resume(); resume();
} else if (commandcode == 9) { } else if (!strcmp(token, "undo")) {
printf("Recieved undo command\n");
undo(); undo();
} else if (commandcode == 10) { } else if (!strcmp(token, "redo")) {
printf("Recieved redo command\n");
redo(); redo();
} else if (commandcode == 11) { } else if (!strcmp(token, "save")) {
printf("Recieved request for foreground color\n"); appendRunToFile();
sendValue(sock, "Foreground-Color"); } else if (!strcmp(token, "start-split-stop")) {
} else if (commandcode == 12) { start_split_stop();
printf("Recieved request for background color\n"); } else if (!strcmp(token, "pause-resume")) {
sendValue(sock, "Background-Color"); pause_resume();
} else { } else if (!strcmp(token, "start-stop")) {
printf("Recieved invalid command code, ignoring...\n"); start_stop();
} else if (!strcmp(token, "start-reset")) {
start_reset();
} else if (!strcmp(token, "start-split")) {
start_split();
} else if (!strcmp(token, "split-stop")) {
split_stop();
} else if (!strcmp(token, "undo-redo")) {
undo_redo();
//Getters
} else if (!strcmp(token, "get")) {
token = strtok(NULL, " ");
if (!strcmp(token, "current_time")) {
sendInt(sock, current_ms());
} else if (!strcmp(token, "current_time_with_pause")) {
int running_pause = 0;
struct timespec p, r;
bool tracking_pause = false;
for (int i = 0; i < runMarker; i++) {
if (run[i].type == PAUSE) {
sub_timespec(run[0].time, run[i].time, &p);
tracking_pause = true;
}
if (run[i].type == RESUME) {
sub_timespec(run[0].time, run[i].time, &r);
running_pause += timespecToMS(r) - timespecToMS(p);
tracking_pause = false;
} else if (i == runMarker - 1 && tracking_pause) {
running_pause += current_ms() - timespecToMS(p);
}
}
sendInt(sock, current_ms() - running_pause);
} else if (!strcmp(token, "run_count")) {
sendInt(sock, run_count);
} else if (!strcmp(token, "segment_count")) {
sendInt(sock, segment_count);
} else if (!strcmp(token, "route_count")) {
sendInt(sock, route_count);
} else if (!strcmp(token, "event_count")) {
sendInt(sock, runMarker);
} else if (!strcmp(token, "segment_shortname")) {
token = strtok(NULL, " ");
int x = atoi(token);
sendString(sock, segments[x].shortname);
} else if (!strcmp(token, "segment_longname")) {
token = strtok(NULL, " ");
int x = atoi(token);
sendString(sock, segments[x].longname);
} else if (!strcmp(token, "segment_description")) {
token = strtok(NULL, " ");
int x = atoi(token);
sendString(sock, segments[x].description);
} else if (!strcmp(token, "route_name")) {
token = strtok(NULL, " ");
int x = atoi(token);
sendString(sock, routes[x].name);
} else if (!strcmp(token, "route_segment_count")) {
token = strtok(NULL, " ");
int x = atoi(token);
sendInt(sock, routes[x].segment_count);
} else if (!strcmp(token, "route_segment_shortname")) {
token = strtok(NULL, " ");
int x = atoi(token);
token = strtok(NULL, " ");
int y = atoi(token);
sendString(sock, routes[x].segments[y].shortname);
} else if (!strcmp(token, "event_time")) {
token = strtok(NULL, " ");
int x;
if (!strcmp(token, "last"))
x = runMarker - 1;
else if (!strcmp(token, "first"))
x = 0;
else
x = atoi(token);
struct timespec t;
sub_timespec(run[0].time, run[x].time, &t);
sendInt(sock, timespecToMS(t));
} else if (!strcmp(token, "event_time_with_pause")) {
token = strtok(NULL, " ");
int x;
if (!strcmp(token, "last"))
x = runMarker - 1;
else if (!strcmp(token, "first"))
x = 0;
else
x = atoi(token);
int running_pause = 0;
struct timespec p, r;
bool tracking_pause = false;
for (int i = 0; i < x; i++) {
if (run[i].type == PAUSE) {
sub_timespec(run[0].time, run[i].time, &p);
tracking_pause = true;
}
if (run[i].type == RESUME) {
sub_timespec(run[0].time, run[i].time, &r);
running_pause += timespecToMS(r) - timespecToMS(p);
tracking_pause = false;
} else if (i == x - 1 && tracking_pause) {
sub_timespec(run[0].time, run[x].time, &r);
running_pause += timespecToMS(r) - timespecToMS(p);
}
}
struct timespec t;
sub_timespec(run[0].time, run[x].time, &t);
sendInt(sock, timespecToMS(t) - running_pause);
} else if (!strcmp(token, "event_type")) {
token = strtok(NULL, " ");
int x;
if (!strcmp(token, "last"))
x = runMarker - 1;
else if (!strcmp(token, "first"))
x = 0;
else
x = atoi(token);
char *reply;
switch (run[x].type) {
case START:
reply = "START";
break;
case SPLIT:
reply = "SPLIT";
break;
case SKIP:
reply = "SKIP";
break;
case PAUSE:
reply = "PAUSE";
break;
case RESUME:
reply = "RESUME";
break;
case RESET:
reply = "RESET";
break;
case STOP:
reply = "STOP";
break;
}
sendString(sock, reply);
} else if (!strcmp(token, "meta")) {
token = strtok(NULL, " ");
sendValue(sock, token);
}
//Setters
} else if (!strcmp(token, "set")) {
token = strtok(NULL, " ");
if (!strcmp(token, "meta")) {
token = strtok(NULL, " ");
char *token2 = strtok(NULL, " ");
set_metadata(token, token2);
save_metadata_to_file(token, token2);
}
} }
} }
@ -373,43 +801,19 @@ int main(int argc, char *argv[])
exit(1); exit(1);
} }
/* Now start listening for the clients, here
* process will go in sleep mode and will wait
* for the incoming connection
*/
listen(sockfd,5); listen(sockfd,5);
clilen = sizeof(cli_addr); clilen = sizeof(cli_addr);
printf("Ready!\n");
while (alive) { while (alive) {
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0) { if (newsockfd < 0) {
perror("ERROR on accept"); perror("ERROR on accept");
exit(1); exit(1);
} }
process_socket_input(newsockfd);
/* Create child process */
//pid = fork();
pid = 1;
if (pid < 0) {
perror("ERROR on fork");
exit(1);
}
if (pid == 0) {
/* This is the child process */
//close(sockfd);
//doprocessing(newsockfd);
//exit(0);
}
else {
doprocessing(newsockfd);
close(newsockfd); close(newsockfd);
} }
} /* end of while */
free(run); free(run);
close(sockfd); close(sockfd);
} }

View File

@ -31,6 +31,17 @@ struct color bl = {224, 34, 34}; //Behind, and losing time segment color
int w, h; int w, h;
//functions
void timestring(char *str, int ms);
void printbig(int x, int y, int ms);
int timestringDigits(int ms);
void resize(int i);
void initScreen();
void resetScreen();
void die(int i);
void processColorString(struct color *c, char* s);
int timestringDigits(int ms) int timestringDigits(int ms)
{ {
int chars = 4; int chars = 4;
@ -53,7 +64,7 @@ int timestringDigits(int ms)
void printbig(int x, int y, int ms) void printbig(int x, int y, int ms)
{ {
char small[13]; char small[13];
timestring(&small, ms); timestring(small, ms);
if (w < strlen(small)) { if (w < strlen(small)) {
printf("2smol\n"); printf("2smol\n");
return; return;
@ -67,32 +78,21 @@ void printbig(int x, int y, int ms)
printf("\033[%d;%dH", y + sy, x); //go to position printf("\033[%d;%dH", y + sy, x); //go to position
for (int cc = 0; cc < 12; cc++) { //then, for every character for (int cc = 0; cc < 12; cc++) { //then, for every character
int c = small[cc]; //check what character we're on int c = small[cc]; //check what character we're on
if (c >= 48 && c <= 57) { //if its a number, print 4 pixels int mapcharacterwidth = (c >= 48 && c <= 57) ? 4 : 2;//if its a number, print 4 pixels, if its punctuation, print 2 pixels
for (int xx = 0; xx < 4; xx++) { int mapoffset;
int xxx = c - 48; if (c >= 48 && c <= 57)
if (numbermap[sy][(xxx * 4) + xx] == 'x') mapoffset = (c - 48) * 4;
else if (c == 46)
mapoffset = 42;
else
mapoffset = 40;
for (int xx = 0; xx < mapcharacterwidth; xx++) {
if (numbermap[sy][mapoffset + xx] == 'x')
printf("\033[48;2;%d;%d;%dm ", f.r, f.g, f.b); printf("\033[48;2;%d;%d;%dm ", f.r, f.g, f.b);
if (numbermap[sy][(xxx * 4) + xx] == '.') if (numbermap[sy][mapoffset + xx] == '.')
printf("\033[48;2;%d;%d;%dm ", b.r, b.g, b.b); printf("\033[48;2;%d;%d;%dm ", b.r, b.g, b.b);
} }
} }
if (c == 46 || c == 58) { //if its punctuation, print 2 pixels
for (int xx = 0; xx < 2; xx++) {
if (c == 46) {
if (numbermap[sy][42 + xx] == 'x')
printf("\033[48;2;%d;%d;%dm ", f.r, f.g, f.b);
if (numbermap[sy][42 + xx] == '.')
printf("\033[48;2;%d;%d;%dm ", b.r, b.g, b.b);
}
if (c == 58) {
if (numbermap[sy][40 + xx] == 'x')
printf("\033[48;2;%d;%d;%dm ", f.r, f.g, f.b);
if (numbermap[sy][40 + xx] == '.')
printf("\033[48;2;%d;%d;%dm ", b.r, b.g, b.b);
}
}
}
}
} }
printf("\n"); printf("\n");
//printf("\033[%d;%dH%s\n", y, x, small + (12 - timestringDigits(time))); //printf("\033[%d;%dH%s\n", y, x, small + (12 - timestringDigits(time)));
@ -123,7 +123,7 @@ void initScreen()
t.c_lflag &= (~ECHO & ~ICANON); t.c_lflag &= (~ECHO & ~ICANON);
tcsetattr(1, TCSANOW, &t); tcsetattr(1, TCSANOW, &t);
//TODO:Figure out why i did this //TODO:Figure out why i did this
dup(0); //dup(0);
fcntl(0, F_SETFL, O_NONBLOCK); fcntl(0, F_SETFL, O_NONBLOCK);
printf("\033[?1049h\n"); //Switch to TUI mode (alternate buffer) printf("\033[?1049h\n"); //Switch to TUI mode (alternate buffer)
printf("\033[?25l\n"); //Hide text cursor printf("\033[?25l\n"); //Hide text cursor
@ -193,19 +193,21 @@ int main (int argc, char *argv[])
char ti[13]; char ti[13];
//Request foreground color from config file //Request foreground color from config file
fp = popen("./result/bin/quest-log foreground", "r"); fp = popen("./result/bin/quest-log Foreground-Color", "r");
fgets(path, sizeof(path), fp); if (fgets(path, sizeof(path), fp)) {
if (strcmp(path, "DATA NOT PRESENT")) if (strcmp(path, "DATA NOT PRESENT"))
processColorString(&f, path); processColorString(&f, path);
printf("\033[38;2;%d;%d;%dm", f.r, f.g, f.b); printf("\033[38;2;%d;%d;%dm", f.r, f.g, f.b);
}
pclose(fp); pclose(fp);
//Request background color from config file //Request background color from config file
fp = popen("./result/bin/quest-log background", "r"); fp = popen("./result/bin/quest-log Background-Color", "r");
fgets(path, sizeof(path), fp); if (fgets(path, sizeof(path), fp)) {
if (strcmp(path, "DATA NOT PRESENT")) if (strcmp(path, "DATA NOT PRESENT"))
processColorString(&b, path); processColorString(&b, path);
printf("\033[48;2;%d;%d;%dm", b.r, b.g, b.b); printf("\033[48;2;%d;%d;%dm", b.r, b.g, b.b);
}
pclose(fp); pclose(fp);
//Set fps from command line argument //Set fps from command line argument
@ -215,7 +217,7 @@ int main (int argc, char *argv[])
} }
while (1) { while (1) {
int time = 0; int time = 0;
fp = popen("./result/bin/quest-log time", "r"); fp = popen("./result/bin/quest-log current_time", "r");
if (fp == NULL) { if (fp == NULL) {
printf("Failed to run command\n"); printf("Failed to run command\n");
exit(1); exit(1);