use libString insead of static character arrays where useful, added some data structure stuff for realm master, random, and scope

This commit is contained in:
Iris Lightshard 2021-07-20 15:59:33 -06:00
parent 4430d607d6
commit c8ba412121
Signed by: Iris Lightshard
GPG key ID: 3B7FBC22144E6398
6 changed files with 99 additions and 23 deletions

View file

@ -13,7 +13,8 @@ This is the working structure of the 9p filesystem:
* `load CART`: Load a cartridge
* `chunk TYPE N`: Load data of type TYPE and chunk number N
* `create REALM`: Create a new realm (start a new game) -- must have a cartridge loaded
* `protect REALM PW`: Protect the realm with a password if not already.
* `protect PW`: Protect the curent realm with a password if you are the master.
* `transfer USER`: Transfer ownership of the realm to another user.
* `enter REALM`: Join an existing realm
* `leave`: Leave the current realm
* `unload`: Unload the cartridge
@ -40,7 +41,7 @@ This is the working structure of the 9p filesystem:
Each realm directory on the server should have the following files:
* `realm`: Basic data for the realm, file should contain only the maximum number of members, and the password hash, if any, separated by a space
* `universe`: The actual game state in for the realm, key value pairs, one per line, as `KEY = VALUE`; limit 15 characters for keys, 63 for values.
* `realm`: Basic data for the realm, file should contain only the maximum number of members, the master's name, and the password hash, if any (otherwise 0), separated by spaces.
* `universe`: The actual game state for the realm as key value pairs, one per line, like `KEY = VALUE`; limit 15 characters for keys, 63 for values.
The realm should be synchronized to disc when realm membership, limit, or password change. Fenagling some periodic autosave should be possible...

View file

@ -1,8 +1,10 @@
typedef enum {
LOGIN = 208176873,
LOAD = 5626172,
CHUNK = 190974201,
CREATE = 7083959236,
PROTECT = 295480618573,
TRANSFER = 11311529048177,
ENTER = 195024746,
LEAVE = 207662601,
LOGOUT = 7702552890,

View file

@ -45,6 +45,7 @@ Realm* create_realm(UserInfo* table, char* uname, char* name) {
self->max = max;
self->password = 0;
self->universe = create_universe();
scpy(uname, self->master, 32);
save_realm(cart, self);
fprintf(stderr, "created realm '%s'\n", name);
return self;
@ -68,7 +69,7 @@ Realm* parse_realm(char* cart, char* name) {
if (f != nil) {
if (fgets(buf, 256, f)) {
self = malloc(sizeof(Realm));
sscanf(buf, "%hu %llu", &(self->max), &(self->password));
sscanf(buf, "%hu %32s %llu", &(self->max), self->master, &(self->password));
fclose(f);
} else {
return nil;
@ -108,7 +109,7 @@ void save_realm(char* cart, Realm* self) {
scat(file, "/realm");
f = fopen(file, "w");
if (f != nil) {
fprintf(f, "%hu %llu", self->max, self->password);
fprintf(f, "%hu %s, %llu", self->max, self->master, self->password);
fclose(f);
save_universe(cart, self->universe, self->name);
fprintf(stderr, "saved realm data");

View file

@ -3,12 +3,13 @@ typedef struct UserInfo UserInfo;
typedef struct Realm {
char name[32];
char master[32];
ushort max;
uvlong password;
Universe* universe;
} Realm;
Realm* create_realm(UserInfo* table, char* cart, char* name);
Realm* create_realm(UserInfo* table, char* uname, char* name);
Realm* parse_realm(char* cart, char* name);
Realm* find_realm(UserInfo* table, char* name);
void save_realm(char* cart, Realm* self);

2
user.h
View file

@ -5,6 +5,8 @@ typedef struct UserInfo {
uvlong password;
Cart* cart;
Realm* realm;
char* scope;
int random;
} UserInfo;
UserInfo* find_user(UserInfo* table, char* uname);

103
xrxs.c
View file

@ -77,6 +77,11 @@ int logout(char* uname) {
if (scmp(uname, u->name)) {
*(u->name) = 0;
u->password = 0;
if (u->scope != nil) {
free(u->scope);
u->scope = nil;
}
u->random = 0;
if (u->realm != nil)
leave_realm(users_table, uname);
if (u->cart != nil)
@ -91,7 +96,7 @@ int logout(char* uname) {
void protect(char* uname, char* password) {
UserInfo* u = find_user(users_table, uname);
if (u != nil && u->realm != nil) {
if (u != nil && u->realm != nil && scmp(uname, u->realm->master)) {
u->realm->password = hash(password, 0);
}
}
@ -117,12 +122,17 @@ void write_ctl(Req* r) {
case LOAD:
load_cart(users_table, r->fid->uid, c);
break;
case CHUNK:
// get_chunk(users_table, r->fid->uid, c);
break;
case CREATE:
create_realm(users_table, r->fid->uid, c);
break;
case PROTECT:
protect(r->fid->uid, c);
break;
case TRANSFER:
// transfer(r->fid->uid, c);
case ENTER:
enter_realm(users_table, r->fid->uid, c);
break;
@ -222,13 +232,18 @@ void read_users(Req* r) {
}
String** list_dir(char* path) {
String** self = malloc(128 * sizeof(String*));
int size = 128;
String** self = malloc(size * sizeof(String*));
DIR* dir;
struct dirent* ent;
int i = 0;
char* c;
if ((dir = opendir(path)) != NULL) {
while ((ent = readdir(dir)) != NULL) {
if (i = size) {
size *= 2;
self = reallloc(self, size * sizeof(String*));
}
c = ent->d_name;
if (scmp(c, ".") || scmp(c, "..")) {
continue;
@ -246,17 +261,38 @@ String** list_dir(char* path) {
return self;
}
void s_freemany(String** ss) {
int i;
String** s = ss;
for (i = 0; i < 128; i++) {
if (*s != nil) {
s_free(*s);
}
}
free(ss);
}
String* s_putmanyc(String* s, char* c) {
String* tmp = s_copy(c);
s_append(s, tmp);
s_free(tmp);
return s;
}
void read_carts(Req* r) {
String** carts = list_dir(CARTSPATH);
String** c = carts;
char data[4096] = {0};
string* data = s_new();
while (*c != nil) {
scat(data, (*c)->base);
ccat(data, '\n');
s_append(data, *c);
s_putc(data, '\n');
c++;
}
readstr(r, data);
s_terminate(data);
readstr(r, data->base);
respond(r, nil);
s_free(data);
s_freemany(carts);
}
void read_slot(Req* r) {
@ -299,7 +335,7 @@ void read_realms(Req* r) {
String** realms;
String** rr;
Realm* realm;
char data[4096] = {0};
String* data = s_new();
int i, u, m, p;
char ubuf[8] = {0};
char mbuf[8] = {0};
@ -316,8 +352,8 @@ void read_realms(Req* r) {
rr = realms;
while (*rr != nil) {
scat(data, (*rr)->base);
ccat(data, ' ');
s_append(data, *rr);
s_putc(data, ' ');
realm = parse_realm(user->cart->name, (*rr)->base);
m = realm->max;
@ -330,18 +366,51 @@ void read_realms(Req* r) {
u++;
}
itoa(u, ubuf, 10);
scat(data, ubuf);
ccat(data, ' ');
s_putmanyc(data, ubuf);
s_putc(data, ' ');
itoa(m, mbuf, 10);
scat(data, mbuf);
ccat(data, ' ');
s_putmanyc(data, mbuf);
s_putc(data, ' ');
itoa(p, pbuf, 10);
scat(data, pbuf);
ccat(data, '\n');
s_putmanyc(data, pbuf);
s_putc(data, '\n');
rr++;
}
readstr(r, data);
s_terminate(data);
readstr(r, data->base);
respond(r, nil);
s_free(data);
s_freemany(realms);
}
void read_universe(Req* r) {
char* uname = r->fid->uid;
UserInfo* u = find_user(users_table, uname);
String* data = s_new();
Universe* universe;
Atom* a;
int i;
if (u == nil || u->realm == nil) {
respond(r, nil);
return;
}
universe = u->realm->universe;
for (i = 0; i < 256; i++) {
a = universe[i];
while (a != nil) {
s_putmanyc(data, a->name);
s_putmanyc(data, " = ");
s_putmanyc(data, a->value);
s_putc(data, '\n');
a = a->next;
}
}
s_terminate(data);
readstr(r, data->base);
respond(r, nil);
s_free(data);
}
void xrxs_read(Req* r) {
@ -365,7 +434,7 @@ void xrxs_read(Req* r) {
read_realms(r);
break;
case UNIVERSE:
// read_universe(r);
read_universe(r);
break;
case SCOPE:
// read_scope(r);