summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--inc/args.h22
-rw-r--r--inc/commands.h11
-rw-r--r--src/args.c129
-rw-r--r--src/commands.c45
-rw-r--r--src/main.c158
5 files changed, 363 insertions, 2 deletions
diff --git a/inc/args.h b/inc/args.h
new file mode 100644
index 0000000..6c06fb2
--- /dev/null
+++ b/inc/args.h
@@ -0,0 +1,22 @@
+#ifndef ARGS_H
+#define ARGS_H
+
+#include "../inc/commands.h"
+
+#define MAX_COMMANDS 64
+
+typedef struct
+{
+ char *demopath;
+ char *mappath;
+ char *outpath;
+ char *extractmap;
+ char print;
+
+ int numcmds;
+ cmdinput commands[MAX_COMMANDS];
+} input;
+
+void parseargs(input *in, int argc, char *argv[]);
+
+#endif // ARGS_H
diff --git a/inc/commands.h b/inc/commands.h
index 654d8b7..9761151 100644
--- a/inc/commands.h
+++ b/inc/commands.h
@@ -3,6 +3,15 @@
#include "demo.h"
+typedef struct
+{
+ char cmdtype;
+ char settype;
+ int id;
+ char from[24];
+ char to[24];
+} cmdinput;
+
int setnamebyid(int id, char *newname, demo *demo);
int setnamebyname(char *oldname, char *newname, demo *demo);
@@ -14,4 +23,6 @@ int setskinbyname(char *name, char *skin, demo *demo);
/* Will fail if mapname >= 31, or map is not a teeworlds datafile */
int changemap(FILE *map, char *mapname, demo *demo);
+void runcommand(cmdinput *cmd, demo *demo);
+
#endif // COMMANDS_H
diff --git a/src/args.c b/src/args.c
new file mode 100644
index 0000000..9544e39
--- /dev/null
+++ b/src/args.c
@@ -0,0 +1,129 @@
+#include "../inc/args.h"
+#include "../inc/commands.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void parsecmdstr(cmdinput *cmd, char *cmdstr)
+{
+ switch (cmd->settype)
+ {
+ case 'i':
+ if (sscanf(cmdstr, "%i:%23[^\n]", &cmd->id, cmd->to) != 2)
+ {
+ fprintf(stderr, "ERROR: Failed to parse argument '%s' to type 'ID:RESULT'\n", cmdstr);
+ exit(EXIT_FAILURE);
+ }
+ break;
+ case 'n':
+ if (sscanf(cmdstr, "%23[^:]:%23[^\n]", cmd->from, cmd->to) != 2)
+ {
+ fprintf(stderr, "ERROR: Failed to parse argument '%s' to type 'NAME:RESULT'\n", cmdstr);
+ exit(EXIT_FAILURE);
+ }
+ break;
+ case '\0':
+ fprintf(stderr, "ERROR: Found no flag modifier\n");
+ exit(EXIT_FAILURE);
+ break;
+ default:
+ fprintf(stderr, "ERROR: Failed to parse flag with '%c' modifier\n", cmd->settype);
+ exit(EXIT_FAILURE);
+ break;
+ }
+}
+
+void parseargs(input *in, int argc, char *argv[])
+{
+ in->demopath = NULL;
+ in->mappath = NULL;
+ in->outpath = NULL;
+ in->print = 0;
+ in->extractmap = 0;
+
+ in->numcmds = 0;
+
+ int argi;
+ for (argi = 1; argi < argc; argi++)
+ {
+ if (argv[argi][0] == '-')
+ {
+ cmdinput *cmd = &in->commands[in->numcmds];
+ switch (argv[argi][1])
+ {
+ case 'n':
+ if (argi + 1 >= argc)
+ {
+ fprintf(stderr, "ERROR: Flag 'n' requires additional argument\n");
+ exit(EXIT_FAILURE);
+ }
+ cmd->cmdtype = argv[argi][1];
+ cmd->settype = argv[argi][2];
+ parsecmdstr(cmd, argv[argi + 1]);
+ in->numcmds++;
+ argi++;
+ break;
+ case 's':
+ if (argi + 1 >= argc)
+ {
+ fprintf(stderr, "ERROR: Flag 's' requires additional argument\n");
+ exit(EXIT_FAILURE);
+ }
+ cmd->cmdtype = argv[argi][1];
+ cmd->settype = argv[argi][2];
+ parsecmdstr(cmd, argv[argi + 1]);
+ in->numcmds++;
+ argi++;
+ break;
+ case 'o':
+ if (argi + 1 >= argc)
+ {
+ fprintf(stderr, "ERROR: Flag 'o' requires additional argument\n");
+ exit(EXIT_FAILURE);
+ }
+ in->outpath = argv[argi + 1];
+ argi++;
+ break;
+ case 'p':
+ in->print = 1;
+ break;
+ case 'e':
+ if (argi + 1 >= argc)
+ {
+ fprintf(stderr, "ERROR: Flag 'e' requires additional argument\n");
+ exit(EXIT_FAILURE);
+ }
+ in->extractmap = argv[argi + 1];
+ argi++;
+ break;
+ case 'm':
+ if (argi + 1 >= argc)
+ {
+ fprintf(stderr, "ERROR: Flag 'm' requires additional argument\n");
+ exit(EXIT_FAILURE);
+ }
+ in->mappath = argv[argi + 1];
+ argi++;
+ break;
+ default:
+ fprintf(stderr, "ERROR: Unknown flag '%c'\n", argv[argi][1]);
+ exit(EXIT_FAILURE);
+ break;
+ }
+ }
+ else
+ {
+ if (in->demopath)
+ {
+ fprintf(stderr, "ERROR: Found two non-flag arguments\n");
+ exit(EXIT_FAILURE);
+ }
+ in->demopath = argv[argi];
+ }
+ }
+ if (!in->demopath)
+ {
+ fprintf(stderr, "ERROR: Found no demo input\n");
+ exit(EXIT_FAILURE);
+ }
+}
diff --git a/src/commands.c b/src/commands.c
index 599c6d0..e2353d8 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -1,5 +1,6 @@
#include "../inc/demo.h"
#include "../inc/pack.h"
+#include "../inc/commands.h"
#include <stdio.h>
#include <stdlib.h>
@@ -122,7 +123,6 @@ int setskinbyname(char *name, char *skin, demo *demo)
char iname[16];
intstostr(item->data, 4, iname);
- printf("comparing: %s : %s\n", name, iname);
if (strcmp(name, iname) == 0)
{
memcpy(&item->data[8], intskin, 5 * sizeof(int));
@@ -142,6 +142,9 @@ int changemap(FILE *map, char *mapname, demo *demo)
fseek(map, 0, SEEK_END);
long mapsize = ftell(map);
fseek(map, 0, SEEK_SET);
+
+ if (mapsize < 4)
+ return -1;
char *mapbuff = (char *)malloc(mapsize);
if (mapbuff == NULL)
@@ -167,3 +170,43 @@ int changemap(FILE *map, char *mapname, demo *demo)
return 1;
}
+
+void runcommand(cmdinput *cmd, demo *demo)
+{
+ switch(cmd->cmdtype)
+ {
+ case 'n':
+ switch(cmd->settype)
+ {
+ case 'i':
+ if (setnamebyid(cmd->id, cmd->to, demo) < 0)
+ printf("WARNING: Could not set name '%s' because it exeeds max limit of 15 characters\n", cmd->to);
+ break;
+ case 'n':
+ if (setnamebyname(cmd->from, cmd->to, demo) < 0)
+ printf("WARNING: Could not set name '%s' because it exeeds max limit of 15 characters\n", cmd->to);
+ break;
+ default:
+ printf("WARNING: Unknown modifier for name\n");
+ }
+ break;
+ case 's':
+ switch(cmd->settype)
+ {
+ case 'i':
+ if (setskinbyid(cmd->id, cmd->to, demo) < 0)
+ printf("WARNING: Could not set skin '%s' because it exeeds max limit of 23 characters\n", cmd->to);
+ break;
+ case 'n':
+ if (setskinbyname(cmd->from, cmd->to, demo) < 0)
+ printf("WARNING: Could not set skin '%s' because it exeeds max limit of 23 characters\n", cmd->to);
+ break;
+ default:
+ printf("WARNING: Unknown modifier for skin\n");
+ }
+ break;
+ default:
+ printf("WARNING: Unknown command type\n");
+ break;
+ }
+}
diff --git a/src/main.c b/src/main.c
index 482bc3c..b344f3d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,6 +1,7 @@
#include "../inc/commands.h"
#include "../inc/demo.h"
#include "../inc/huffman.h"
+#include "../inc/args.h"
#include <stdio.h>
#include <stdlib.h>
@@ -110,10 +111,165 @@ int testdecompress(char *line)
return 1;
}
-int main()
+int mapname(char *mappath, char *out)
+{
+ int start = 0;
+ int end;
+ int i = 0;
+ while (1)
+ {
+ if (mappath[i] == '/')
+ start = i + 1;
+ if (mappath[i] == '.' || mappath[i] == '\0')
+ {
+ end = i;
+ break;
+ }
+ i++;
+ }
+
+ if ((end - start) > 31)
+ return 0;
+
+ i = 0;
+ while (start != end)
+ {
+ out[i] = mappath[start];
+ start++;
+ i++;
+ }
+ out[i] = '\0';
+ return 1;
+}
+
+void run(input *in)
+{
+ if (!in->demopath)
+ exit(EXIT_FAILURE);
+
+ FILE *demofile, *outfile, *mapfile, *exmapfile;
+ demofile = NULL;
+ outfile = NULL;
+ mapfile = NULL;
+ exmapfile = NULL;
+
+ demofile = fopen(in->demopath, "r");
+ if (!demofile)
+ {
+ perror("ERROR: Failed to open demo file, reason");
+ exit(EXIT_FAILURE);
+ }
+
+ if (in->outpath)
+ {
+ outfile = fopen(in->outpath, "w");
+ if (!outfile)
+ {
+ perror("ERROR: Failed to open output file, reason");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (in->mappath)
+ {
+ mapfile = fopen(in->mappath, "r");
+ if (!mapfile)
+ {
+ perror("ERROR: Failed to open map file, reason");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (in->extractmap)
+ {
+ exmapfile = fopen(in->extractmap, "r");
+ if (!exmapfile)
+ {
+ perror("ERROR: Failed to open extract map file, reason");
+ exit(EXIT_FAILURE);
+ }
+ // TODO extract map here
+ }
+
+ demo dmo;
+
+ if (readdemo(demofile, &dmo) < 0)
+ {
+ fprintf(stderr, "ERROR: Failed to parse demo\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (in->print)
+ printdemo(&dmo, 0);
+
+ if (mapfile)
+ {
+ char mname[32];
+ if (mapname(in->mappath, mname))
+ {
+ if (changemap(mapfile, mname, &dmo) < 0)
+ {
+ fprintf(stderr, "ERROR: Failed to set map '%s'\n", in->mappath);
+ exit(EXIT_FAILURE);
+ }
+ }
+ else
+ {
+ fprintf(stderr, "ERROR: Given map has too long name (must be < 32)\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ for (int i = 0; i < in->numcmds; i++)
+ {
+ runcommand(&in->commands[i], &dmo);
+ }
+
+ if (outfile)
+ {
+ if (writedemo(outfile, &dmo) < 0)
+ {
+ fprintf(stderr, "ERROR: Failed to write demo to '%s'\n", in->outpath);
+ exit(EXIT_FAILURE);
+ }
+ }
+}
+
+int main(int argc, char *argv[])
{
inithuff(NULL);
+ if (argc == 1)
+ {
+ printf("HELP! This should help you.\n");
+ exit(EXIT_SUCCESS);
+ }
+
+ input in;
+
+ parseargs(&in, argc, argv);
+
+ /*
+ printf("demopath: %s\n", in.demopath);
+ printf("outpath: %s\n", in.outpath);
+ printf("mappath: %s\n", in.mappath);
+ printf("extractpath: %s\n", in.extractmap);
+ printf("print: %d\n", in.print);
+
+ printf("\ncommands:\n");
+ for (int i = 0; i < in.numcmds; i++)
+ {
+ cmdinput *c = &in.commands[i];
+ printf("command: {cmd: %c, type: %c, id: %d, from: %s, to: %s}\n", c->cmdtype, c->settype, c->id, c->from, c->to);
+ }
+
+ printf("\nEXITING SUCCESS\n");
+ */
+
+ run(&in);
+
+ exit(EXIT_SUCCESS);
+
// FILE *fp = fopen("/home/johannes/.local/share/ddnet/demos/auto/pepeg_2024-02-09_20-35-38.demo", "r");
FILE *fp = fopen("data/test.demo", "r");
FILE *op = fopen("data/out.demo", "w");