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:
parent
4430d607d6
commit
c8ba412121
6 changed files with 99 additions and 23 deletions
|
@ -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...
|
|
@ -1,8 +1,10 @@
|
|||
typedef enum {
|
||||
LOGIN = 208176873,
|
||||
LOAD = 5626172,
|
||||
CHUNK = 190974201,
|
||||
CREATE = 7083959236,
|
||||
PROTECT = 295480618573,
|
||||
TRANSFER = 11311529048177,
|
||||
ENTER = 195024746,
|
||||
LEAVE = 207662601,
|
||||
LOGOUT = 7702552890,
|
||||
|
|
5
realm.c
5
realm.c
|
@ -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");
|
||||
|
|
3
realm.h
3
realm.h
|
@ -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
2
user.h
|
@ -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
103
xrxs.c
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue