Compare commits
18 Commits
9c7ccfe0b0
...
newformat
Author | SHA1 | Date | |
---|---|---|---|
b700113b88 | |||
dbf8dce580 | |||
9c0d4befba | |||
d09b991771 | |||
057d051a3a | |||
073e610966 | |||
47369a86e9 | |||
0812d68dd1 | |||
f1e2c85e3a | |||
1bb5864a29 | |||
fd8bbadb1e | |||
b93f2f0aa7 | |||
c24f516380 | |||
1aa1ed514a | |||
c7387f5acb | |||
d3f7a25a64 | |||
f5e5c506af | |||
b208382e60 |
2
Makefile
2
Makefile
@ -1,5 +1,5 @@
|
||||
TARGET = quest
|
||||
LIBS = -lm -luiohook -lcjson
|
||||
LIBS = -lm -luiohook -lcjson -lxcb -lXinerama -lX11
|
||||
CC = gcc
|
||||
CFLAGS = -g -Wall
|
||||
INSTALL_PATH = /usr/local
|
||||
|
2
default.nix
Normal file
2
default.nix
Normal file
@ -0,0 +1,2 @@
|
||||
{pkgs ? import <nixpkgs> {} }:
|
||||
pkgs.callPackage ./derivation.nix {}
|
23
derivation.nix
Normal file
23
derivation.nix
Normal 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
|
||||
'';
|
||||
}
|
@ -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
|
||||
that are played between splits and routes made up of these segments.
|
||||
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
|
||||
segments in the order of their definition is assumed.
|
||||
segments in the order of their definition is to be assumed.
|
||||
|
||||
Segment
|
||||
Shortname
|
||||
@ -141,7 +141,7 @@ Run Directives
|
||||
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
|
||||
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
|
||||
applicable, or by default is matched with the last set of metadata declared by
|
||||
the time of the run directive
|
||||
@ -163,7 +163,7 @@ Run
|
||||
3121111
|
||||
Pause
|
||||
421397
|
||||
Unpause
|
||||
Resume
|
||||
2016-10-23 11:16:04.175Z
|
||||
Stop (The last event in a run is always a Stop)
|
||||
123111
|
||||
|
@ -22,6 +22,7 @@ struct pastseg *pastRuns;
|
||||
int segCount;
|
||||
int currSeg = -1;
|
||||
char currentTime[10];
|
||||
int *route;
|
||||
|
||||
void sub_timespec(struct timespec t1, struct timespec t2, struct timespec* td)
|
||||
{
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
struct segment
|
||||
{
|
||||
int id;
|
||||
char *name;
|
||||
int ms;
|
||||
bool isSkipped;
|
||||
@ -49,6 +50,7 @@ extern struct segment *bestsegs;
|
||||
extern struct segment *wrrun;
|
||||
extern struct segment *segments;
|
||||
extern struct timespec notif;
|
||||
extern int *route;
|
||||
|
||||
void sub_timespec(struct timespec t1, struct timespec t2, struct timespec* td);
|
||||
void add_timespec(struct timespec t1, struct timespec t2, struct timespec* td);
|
||||
|
@ -13,7 +13,6 @@ int main(int argc, char *argv[]) {
|
||||
struct hostent *server;
|
||||
|
||||
char buffer[256];
|
||||
char commandcode;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr,"usage %s command\n", argv[0]);
|
||||
@ -48,71 +47,27 @@ int main(int argc, char *argv[]) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "time")) {
|
||||
commandcode = 1;
|
||||
} else if (!strcmp(argv[1], "start")) {
|
||||
commandcode = 2;
|
||||
} 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);
|
||||
bzero(buffer, 256);
|
||||
for (int i = 1; i < argc; i++) {
|
||||
strcat(buffer, argv[i]);
|
||||
strcat(buffer, " ");
|
||||
}
|
||||
|
||||
/* Send message to the server */
|
||||
n = write(sockfd, &commandcode, 1);
|
||||
|
||||
n = write(sockfd, &buffer, 256);
|
||||
if (n < 0) {
|
||||
perror("ERROR writing to socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
n = read(sockfd, &buffer, 255);
|
||||
|
||||
n = read(sockfd, &buffer, 256);
|
||||
if (n < 0) {
|
||||
perror("ERROR reading from socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (buffer != NULL)
|
||||
printf("%s", buffer);
|
||||
}
|
||||
printf("%s\n", buffer);
|
||||
return 0;
|
||||
}
|
||||
|
656
src2/server.c
656
src2/server.c
@ -12,10 +12,11 @@
|
||||
#define NS_PER_S 1000000000
|
||||
|
||||
struct timespec finish, delta;
|
||||
int pausedTime = 0;
|
||||
bool timerActive = false;
|
||||
bool paused = false;
|
||||
bool alive = true;
|
||||
bool hasUndoneAtLeastOnce = false;
|
||||
bool runUnsaved = false;
|
||||
int timerOffset = 0;
|
||||
enum event_type {
|
||||
START,
|
||||
@ -23,12 +24,23 @@ enum event_type {
|
||||
SKIP,
|
||||
PAUSE,
|
||||
RESUME,
|
||||
RESET,
|
||||
STOP
|
||||
};
|
||||
struct run_event {
|
||||
enum event_type type;
|
||||
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;
|
||||
//Enough to hold a sm64 16 star, can realloc later
|
||||
@ -37,10 +49,58 @@ int runMarker = 0;
|
||||
int runMarker2 = 0;
|
||||
|
||||
//save file stuff
|
||||
char *default_file_name = "untitled.quest";
|
||||
int run_count = 0;
|
||||
int files = 0;
|
||||
char **filePaths = NULL;
|
||||
char **names, **values;
|
||||
char **meta_keys, **meta_values;
|
||||
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)
|
||||
{
|
||||
@ -92,100 +152,149 @@ void add_event(enum event_type t)
|
||||
offset_timespec(timerOffset, &run[runMarker].time);
|
||||
runMarker++;
|
||||
runMarker2 = runMarker;
|
||||
hasUndoneAtLeastOnce = false;
|
||||
}
|
||||
|
||||
void reset_timer()
|
||||
{
|
||||
runMarker = 0;
|
||||
runMarker2 = 0;
|
||||
}
|
||||
|
||||
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
|
||||
//if they accidentally hit the stop button
|
||||
//TODO: Clear the run data first
|
||||
appendRunToFile();
|
||||
reset_timer();
|
||||
timerActive = true;
|
||||
add_event(START);
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
if (!timerActive) return;
|
||||
timerActive = false;
|
||||
add_event(STOP);
|
||||
//this makes sure the time clients recieve from time
|
||||
//requests match the time on the stop event
|
||||
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()
|
||||
{
|
||||
if (!timerActive) return;
|
||||
add_event(SPLIT);
|
||||
}
|
||||
|
||||
void skip()
|
||||
{
|
||||
if (!timerActive) return;
|
||||
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()
|
||||
{
|
||||
if (runMarker > 0) {
|
||||
runMarker--;
|
||||
if (run[runMarker].type == STOP)
|
||||
if (run[runMarker].type == STOP) {
|
||||
timerActive = true;
|
||||
runUnsaved = false;
|
||||
}
|
||||
if (run[runMarker].type == START)
|
||||
timerActive = false;
|
||||
if (run[runMarker].type == PAUSE)
|
||||
paused = false;
|
||||
if (run[runMarker].type == RESUME) {
|
||||
paused = true;
|
||||
subtractPauseTime();
|
||||
}
|
||||
hasUndoneAtLeastOnce = true;
|
||||
}
|
||||
}
|
||||
|
||||
void redo()
|
||||
{
|
||||
if (!timerActive) return;
|
||||
if (runMarker < runMarker2) {
|
||||
runMarker++;
|
||||
if (run[runMarker - 1].type == STOP)
|
||||
if (run[runMarker - 1].type == STOP) {
|
||||
timerActive = false;
|
||||
runUnsaved = true;
|
||||
finish = run[runMarker - 1].time;
|
||||
}
|
||||
if (run[runMarker - 1].type == START)
|
||||
timerActive = true;
|
||||
if (run[runMarker - 1].type == PAUSE)
|
||||
paused = true;
|
||||
if (run[runMarker - 1].type == RESUME) {
|
||||
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>
|
||||
void pause_timer()
|
||||
{
|
||||
if (!timerActive) return;
|
||||
if (!paused) {
|
||||
add_event(PAUSE);
|
||||
paused = true;
|
||||
@ -194,50 +303,162 @@ void pause_timer()
|
||||
|
||||
void resume()
|
||||
{
|
||||
if (!timerActive) return;
|
||||
if (paused) {
|
||||
add_event(RESUME);
|
||||
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()
|
||||
{
|
||||
FILE* fp;
|
||||
//TODO: for now we're just looking for the metadata values
|
||||
char buff[255];
|
||||
char buff2[255];
|
||||
|
||||
for (int i = 0; i < files; i++) {
|
||||
fp = fopen(filePaths[i], "r");
|
||||
|
||||
fp = fopen(filePaths[i], "r+");
|
||||
while(1) {
|
||||
char *x = fgets(buff, 255, fp);
|
||||
if (buff[0] == '/' && buff[1] == '/' || buff[0] == '\n')
|
||||
continue;
|
||||
if (!strcmp(buff, "Segment") || !strcmp(buff, "Route") || x == NULL)
|
||||
if (!fgets(buff, 255, fp))
|
||||
break;
|
||||
if (buff[0] == '/' && buff[1] == '/' || buff[0] == '\n' || buff[0] == '\t')
|
||||
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;
|
||||
fgets(buff2, 255, fp);
|
||||
if (buff2[0] == '\t') {
|
||||
valuecount++;
|
||||
names = realloc(names, sizeof(char*) * valuecount);
|
||||
names[valuecount - 1] = malloc(strlen(buff) - 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';
|
||||
buff[strlen(buff) - 1] = '\0';
|
||||
buff2[strlen(buff2) - 1] = '\0';
|
||||
set_metadata(buff, buff2 + 1);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@ -249,19 +470,23 @@ void addFile(char *path)
|
||||
loadFiles();
|
||||
}
|
||||
|
||||
void sendTime(int sock)
|
||||
int current_ms()
|
||||
{
|
||||
int n, x;
|
||||
if (timerActive)
|
||||
clock_gettime(CLOCK_REALTIME, &finish);
|
||||
if (paused) {
|
||||
sub_timespec(run[0].time, run[runMarker - 1].time, &delta);
|
||||
} else {
|
||||
//if (paused) {
|
||||
// sub_timespec(run[0].time, run[runMarker - 1].time, &delta);
|
||||
//} else {
|
||||
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) {
|
||||
perror("ERROR writing to socket");
|
||||
exit(1);
|
||||
@ -270,73 +495,276 @@ void sendTime(int sock)
|
||||
|
||||
void sendValue(int sock, char* name)
|
||||
{
|
||||
char buffer[256];
|
||||
int n, x;
|
||||
bool namefound = false;
|
||||
if (name == NULL) {
|
||||
strcpy(buffer, "DATA NOT PRESENT");
|
||||
} else {
|
||||
for(int i = 0; i < valuecount; i++) {
|
||||
if (!strcmp(names[i], name)) {
|
||||
if (!strcmp(meta_keys[i], name)) {
|
||||
x = i;
|
||||
namefound = true;
|
||||
}
|
||||
}
|
||||
if (namefound)
|
||||
n = write(sock, values[x], strlen(values[x]));
|
||||
strcpy(buffer, meta_values[x]);
|
||||
else
|
||||
n = write(sock, "DATA NOT PRESENT", 17);
|
||||
|
||||
strcpy(buffer, "DATA NOT PRESENT");
|
||||
}
|
||||
n = write(sock, &buffer, 256);
|
||||
if (n < 0) {
|
||||
perror("ERROR writing to socket");
|
||||
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;
|
||||
char commandcode;
|
||||
n = read(sock,&commandcode,1);
|
||||
|
||||
char buffer[256];
|
||||
n = read(sock, &buffer, 256);
|
||||
if (n < 0) {
|
||||
perror("ERROR reading from socket");
|
||||
exit(1);
|
||||
}
|
||||
if (commandcode == 1) {
|
||||
//printf("Recieved time command\n");
|
||||
sendTime(sock);
|
||||
} else if (commandcode == 2) {
|
||||
printf("Recieved start command\n");
|
||||
char *token = strtok(buffer, " ");
|
||||
|
||||
//Imperative commands
|
||||
if (!strcmp(token, "start")) {
|
||||
start();
|
||||
} else if (commandcode == 3) {
|
||||
printf("Recieved stop command\n");
|
||||
} else if (!strcmp(token, "stop")) {
|
||||
stop();
|
||||
} else if (commandcode == 4) {
|
||||
printf("Recieved kill command\n");
|
||||
} else if (!strcmp(token, "reset")) {
|
||||
reset();
|
||||
} else if (!strcmp(token, "kill")) {
|
||||
alive = false;
|
||||
} else if (commandcode == 5) {
|
||||
printf("Recieved split command\n");
|
||||
} else if (!strcmp(token, "split")) {
|
||||
split();
|
||||
} else if (commandcode == 6) {
|
||||
printf("Recieved skip command\n");
|
||||
} else if (!strcmp(token, "skip")) {
|
||||
skip();
|
||||
} else if (commandcode == 7) {
|
||||
printf("Recieved pause command\n");
|
||||
} else if (!strcmp(token, "pause")) {
|
||||
pause_timer();
|
||||
} else if (commandcode == 8) {
|
||||
printf("Recieved resume command\n");
|
||||
} else if (!strcmp(token, "resume")) {
|
||||
resume();
|
||||
} else if (commandcode == 9) {
|
||||
printf("Recieved undo command\n");
|
||||
} else if (!strcmp(token, "undo")) {
|
||||
undo();
|
||||
} else if (commandcode == 10) {
|
||||
printf("Recieved redo command\n");
|
||||
} else if (!strcmp(token, "redo")) {
|
||||
redo();
|
||||
} else if (commandcode == 11) {
|
||||
printf("Recieved request for foreground color\n");
|
||||
sendValue(sock, "Foreground-Color");
|
||||
} else if (commandcode == 12) {
|
||||
printf("Recieved request for background color\n");
|
||||
sendValue(sock, "Background-Color");
|
||||
} else {
|
||||
printf("Recieved invalid command code, ignoring...\n");
|
||||
} else if (!strcmp(token, "save")) {
|
||||
appendRunToFile();
|
||||
} else if (!strcmp(token, "start-split-stop")) {
|
||||
start_split_stop();
|
||||
} else if (!strcmp(token, "pause-resume")) {
|
||||
pause_resume();
|
||||
} else if (!strcmp(token, "start-stop")) {
|
||||
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);
|
||||
}
|
||||
|
||||
/* Now start listening for the clients, here
|
||||
* process will go in sleep mode and will wait
|
||||
* for the incoming connection
|
||||
*/
|
||||
|
||||
listen(sockfd,5);
|
||||
clilen = sizeof(cli_addr);
|
||||
|
||||
printf("Ready!\n");
|
||||
while (alive) {
|
||||
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
|
||||
|
||||
if (newsockfd < 0) {
|
||||
perror("ERROR on accept");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
process_socket_input(newsockfd);
|
||||
close(newsockfd);
|
||||
}
|
||||
|
||||
} /* end of while */
|
||||
free(run);
|
||||
close(sockfd);
|
||||
}
|
||||
|
60
src2/tui.c
60
src2/tui.c
@ -31,6 +31,17 @@ struct color bl = {224, 34, 34}; //Behind, and losing time segment color
|
||||
|
||||
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 chars = 4;
|
||||
@ -53,7 +64,7 @@ int timestringDigits(int ms)
|
||||
void printbig(int x, int y, int ms)
|
||||
{
|
||||
char small[13];
|
||||
timestring(&small, ms);
|
||||
timestring(small, ms);
|
||||
if (w < strlen(small)) {
|
||||
printf("2smol\n");
|
||||
return;
|
||||
@ -67,32 +78,21 @@ void printbig(int x, int y, int ms)
|
||||
printf("\033[%d;%dH", y + sy, x); //go to position
|
||||
for (int cc = 0; cc < 12; cc++) { //then, for every character
|
||||
int c = small[cc]; //check what character we're on
|
||||
if (c >= 48 && c <= 57) { //if its a number, print 4 pixels
|
||||
for (int xx = 0; xx < 4; xx++) {
|
||||
int xxx = c - 48;
|
||||
if (numbermap[sy][(xxx * 4) + xx] == 'x')
|
||||
int mapcharacterwidth = (c >= 48 && c <= 57) ? 4 : 2;//if its a number, print 4 pixels, if its punctuation, print 2 pixels
|
||||
int mapoffset;
|
||||
if (c >= 48 && c <= 57)
|
||||
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);
|
||||
if (numbermap[sy][(xxx * 4) + xx] == '.')
|
||||
if (numbermap[sy][mapoffset + xx] == '.')
|
||||
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("\033[%d;%dH%s\n", y, x, small + (12 - timestringDigits(time)));
|
||||
@ -123,7 +123,7 @@ void initScreen()
|
||||
t.c_lflag &= (~ECHO & ~ICANON);
|
||||
tcsetattr(1, TCSANOW, &t);
|
||||
//TODO:Figure out why i did this
|
||||
dup(0);
|
||||
//dup(0);
|
||||
fcntl(0, F_SETFL, O_NONBLOCK);
|
||||
printf("\033[?1049h\n"); //Switch to TUI mode (alternate buffer)
|
||||
printf("\033[?25l\n"); //Hide text cursor
|
||||
@ -193,19 +193,21 @@ int main (int argc, char *argv[])
|
||||
char ti[13];
|
||||
|
||||
//Request foreground color from config file
|
||||
fp = popen("./result/bin/quest-log foreground", "r");
|
||||
fgets(path, sizeof(path), fp);
|
||||
fp = popen("./result/bin/quest-log Foreground-Color", "r");
|
||||
if (fgets(path, sizeof(path), fp)) {
|
||||
if (strcmp(path, "DATA NOT PRESENT"))
|
||||
processColorString(&f, path);
|
||||
printf("\033[38;2;%d;%d;%dm", f.r, f.g, f.b);
|
||||
}
|
||||
pclose(fp);
|
||||
|
||||
//Request background color from config file
|
||||
fp = popen("./result/bin/quest-log background", "r");
|
||||
fgets(path, sizeof(path), fp);
|
||||
fp = popen("./result/bin/quest-log Background-Color", "r");
|
||||
if (fgets(path, sizeof(path), fp)) {
|
||||
if (strcmp(path, "DATA NOT PRESENT"))
|
||||
processColorString(&b, path);
|
||||
printf("\033[48;2;%d;%d;%dm", b.r, b.g, b.b);
|
||||
}
|
||||
pclose(fp);
|
||||
|
||||
//Set fps from command line argument
|
||||
@ -215,7 +217,7 @@ int main (int argc, char *argv[])
|
||||
}
|
||||
while (1) {
|
||||
int time = 0;
|
||||
fp = popen("./result/bin/quest-log time", "r");
|
||||
fp = popen("./result/bin/quest-log current_time", "r");
|
||||
if (fp == NULL) {
|
||||
printf("Failed to run command\n");
|
||||
exit(1);
|
||||
|
Reference in New Issue
Block a user