From 346ae7a0f8f3a33f159b17e6dea02f7521ddaaf2 Mon Sep 17 00:00:00 2001 From: onefang Date: Sat, 25 Apr 2020 05:17:12 +1000 Subject: Create in world accounts! --- src/sledjchisl/sledjchisl.c | 307 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 286 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/sledjchisl/sledjchisl.c b/src/sledjchisl/sledjchisl.c index 35f6202..1883ff3 100644 --- a/src/sledjchisl/sledjchisl.c +++ b/src/sledjchisl/sledjchisl.c @@ -393,6 +393,7 @@ struct _reqData qgrow_t *reply; // pageBuildFunction func; struct timespec then; + boolean fromDb; // boolean chillOut, vegOut; }; @@ -3555,6 +3556,41 @@ char *getLevel(short level) return ret; } +typedef struct _systemFolders systemFolders; +struct _systemFolders +{ + char *name; + short type; +}; + +systemFolders sysFolders[] = +{ + {"My Inventory", 8}, + {"Animations", 20}, + {"Body Parts", 13}, + {"Calling Cards", 2}, +// {"Friends", 2}, +// {"All", 2}, + {"Clothing", 5}, + {"Current Outfit", 46}, + {"Favorites", 23}, + {"Gestures", 21}, + {"Landmarks", 3}, + {"Lost And Found", 16}, + {"Mesh", 49}, + {"My Outfits", 48}, + {"My Suitcase", 100}, // All the others are replicated inside. + {"Notecards", 7}, + {"Objects", 6}, + {"Outfit", 47}, + {"Photo Album", 15}, + {"Scripts", 10}, + {"Sounds", 1}, + {"Textures", 0}, + {"Trash", 14}, + {NULL, -1} +}; + static void accountWrite(reqData *Rd) { char *uuid = getStrH(Rd->database, "UserAccounts.PrincipalID"); @@ -3590,8 +3626,8 @@ static void accountWrite(reqData *Rd) getStrH(Rd->stuff, "email"), getLevel(atoi(level)), level, - 64, 0, + 1, getStrH(Rd->stuff, "passwordHash"), getStrH(Rd->stuff, "passwordSalt"), uuid, @@ -3610,25 +3646,253 @@ static void accountWrite(reqData *Rd) int fd = notstdio(xcreate_stdio(file, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, S_IRUSR | S_IWUSR)); size_t l = strlen(tnm); - if (s) - I("Creating user %s.", file); - else - C("Updating user %s.", file); - if (l != writeall(fd, tnm, l)) - perror_msg("Writing %s", file); - else + uuid_t binuuid; + + uuid_clear(binuuid); + if ((NULL != uuid) && ('\0' != uuid[0])) + uuid_parse(uuid, binuuid); + if ((NULL != uuid) && ('\0' != uuid[0]) && (!uuid_is_null(binuuid))) { - char *name = Rd->stuff->getstr(Rd->stuff, "name", true); - char *nm = xmprintf("%s/users/%s.lua", scData, qstrreplace("tr", name, " ", "_")); + if (s) + I("Creating user %s.", file); + else + I("Updating user %s.", file); + if (l != writeall(fd, tnm, l)) + perror_msg("Writing %s", file); + else + { + char *name = Rd->stuff->getstr(Rd->stuff, "name", true); + char *nm = xmprintf("%s/users/%s.lua", scData, qstrreplace("tr", name, " ", "_")); + + free(file); + file = xmprintf("%s.lua", Rd->shs.UUID); + I("Symlinking %s to %s", file, nm); + if (0 != symlink(file, nm)) + perror_msg("Symlinking %s to %s", file, nm); + free(nm); free(name); + } + xclose(fd); + + short lvl = atoi(level); + + if (0 <= lvl) // Note that http://opensimulator.org/wiki/Userlevel claims that 1 and above are "GOD_LIKE". + { + if (Rd->fromDb) + { + I("Updating database user %s.", getStrH(Rd->stuff, "name")); + } + else + { + // Setup the database stuff. + static dbRequest *acntsI = NULL; + if (NULL == acntsI) + { + static char *szi[] = + { + "FirstName", + "LastName", + "Email", + "Created", + "PrincipalID", + "ScopeID", + "UserLevel", + "UserFlags", + "UserTitle", +// "ServiceURLs", // No worky "text", filled with crap. + "active", + NULL + }; + static char *szo[] = {NULL}; + acntsI = xzalloc(sizeof(dbRequest)); + acntsI->db = Rd->db; + acntsI->table = "UserAccounts"; + acntsI->inParams = szi; + acntsI->outParams = szo; + acntsI->where = ""; + acntsI->type = CT_CREATE; + dbRequests->addfirst(dbRequests, acntsI, sizeof(*acntsI)); + } + static dbRequest *authI = NULL; + if (NULL == authI) + { + static char *szi[] = {"UUID", "passwordSalt", "passwordHash", "accountType", "webLoginKey", NULL}; + static char *szo[] = {NULL}; + authI = xzalloc(sizeof(dbRequest)); + authI->db = Rd->db; + authI->table = "auth"; + authI->inParams = szi; + authI->outParams = szo; + authI->where = ""; + authI->type = CT_CREATE; + dbRequests->addfirst(dbRequests, authI, sizeof(*authI)); + } + static dbRequest *invFolderI = NULL; + if (NULL == invFolderI) + { + static char *szi[] = + { + "agentID", + "folderName", + "type", // smallint(6) + "version", // int(11) + "folderID", + "parentFolderID", + NULL + }; + static char *szo[] = {NULL}; + invFolderI = xzalloc(sizeof(dbRequest)); + invFolderI->db = Rd->db; + invFolderI->table = "inventoryfolders"; + invFolderI->inParams = szi; + invFolderI->outParams = szo; + invFolderI->where = ""; + invFolderI->type = CT_CREATE; + dbRequests->addfirst(dbRequests, invFolderI, sizeof(*invFolderI)); + } + static dbRequest *gUserI = NULL; + if (NULL == gUserI) + { +// static char *szi[] = {"UserID", "HomeRegionID", "HomePosition", "HomeLookAt", "LastRegionID", "LastPosition", "LastLookAt", "Online", "Login", "Logout", NULL}; + static char *szi[] = {"UserID", NULL}; // All the defaults are what we would set anyway. + static char *szo[] = {NULL}; + gUserI = xzalloc(sizeof(dbRequest)); + gUserI->db = Rd->db; + gUserI->table = "GridUser"; + gUserI->inParams = szi; + gUserI->outParams = szo; + gUserI->where = ""; + gUserI->type = CT_CREATE; + dbRequests->addfirst(dbRequests, gUserI, sizeof(*gUserI)); + } + + I("Creating database user %s %s.", uuid, getStrH(Rd->stuff, "name")); + char *first = Rd->stuff->getstr(Rd->stuff, "name", true), *last = strchr(first, ' '); + + // create user record. + *last++ = '\0'; + if (0 != dbDoSomething(acntsI, FALSE, + first, + last, + getStrH(Rd->stuff, "email"), + (strcmp("", getStrH(Rd->stuff, "created")) != 0) ? atoi(getStrH(Rd->stuff, "created")) : (int) Rd->shs.timeStamp[1].tv_sec, + uuid, + "00000000-0000-0000-0000-000000000000", + atoi(level), + 0, + getLevel(atoi(level)), +// "", // Defaults to NULL, empty string seems OK to. Then gets filled in later. + 1 + )) + bitch(Rd, "Internal error.", "Failed to create UserAccounts record."); + else + { + char uuidI[37], uuidR[37], uuidC[37], uuidS[37]; + uuid_t binuuidI; + int r = 0, i; + + // Create inventory records. + strcpy(uuidR, "00000000-0000-0000-0000-000000000000"); + for (i = 0; (NULL != sysFolders[i].name) && (0 == r); i++) + { + uuid_generate_random(binuuidI); + uuid_unparse_lower(binuuidI, uuidI); +// TODO - should check there isn't a folder with this UUID already. + D("Creating %s inventory folder for user %s.", sysFolders[i].name, getStrH(Rd->stuff, "name")); + r += dbDoSomething(invFolderI, FALSE, uuid, sysFolders[i].name, sysFolders[i].type, 1, uuidI, uuidR); + if (0 != r) + bitch(Rd, "Internal error.", "Failed to create invenoryFolder record."); + if (strcmp("My Inventory", sysFolders[i].name) == 0) + strcpy(uuidR, uuidI); + if (strcmp("Calling Cards", sysFolders[i].name) == 0) + strcpy(uuidC, uuidI); + if (strcmp("My Suitcase", sysFolders[i].name) == 0) + strcpy(uuidS, uuidI); + } + + uuid_generate_random(binuuidI); + uuid_unparse_lower(binuuidI, uuidI); +// TODO - should check there isn't a folder with this UUID already. + D("Creating %s inventory folder for user %s.", "Friends", getStrH(Rd->stuff, "name")); + r += dbDoSomething(invFolderI, FALSE, uuid, "Friends", 2, 1, uuidI, uuidC); + if (0 != r) + bitch(Rd, "Internal error.", "Failed to create invenoryFolder record."); + strcpy(uuidC, uuidI); + + uuid_generate_random(binuuidI); + uuid_unparse_lower(binuuidI, uuidI); +// TODO - should check there isn't a folder with this UUID already. + D("Creating %s inventory folder for user %s.", "All", getStrH(Rd->stuff, "name")); + r += dbDoSomething(invFolderI, FALSE, uuid, "All", 2, 1, uuidI, uuidC); + if (0 != r) + bitch(Rd, "Internal error.", "Failed to create invenoryFolder record."); + + for (i = 1; (NULL != sysFolders[i].name) && (0 == r); i++) + { + uuid_generate_random(binuuidI); + uuid_unparse_lower(binuuidI, uuidI); +// TODO - should check there isn't a folder with this UUID already. + D("Creating %s inventory folder for user %s.", sysFolders[i].name, getStrH(Rd->stuff, "name")); + r += dbDoSomething(invFolderI, FALSE, uuid, sysFolders[i].name, sysFolders[i].type, 1, uuidI, uuidS); + if (0 != r) + bitch(Rd, "Internal error.", "Failed to create invenoryFolder record."); + } + + if (0 == r) + { + // Create location record. + D("Creating home and last positions for user %s.", getStrH(Rd->stuff, "name")); + if (0 != dbDoSomething(gUserI, FALSE, uuid)) + bitch(Rd, "Internal error.", "Failed to create GridUser record."); + else + { + // Finally create auth record, so they can log in. + D("Creating auth record for user %s %s.", uuid, getStrH(Rd->stuff, "name")); + if (0 != dbDoSomething(authI, FALSE, uuid, getStrH(Rd->stuff, "passwordSalt"), getStrH(Rd->stuff, "passwordHash"), "UserAccount", "00000000-0000-0000-0000-000000000000")) + bitch(Rd, "Internal error.", "Failed to create auth record."); + } + } + + // load iar -m first last / password /opt/opensim_SC/backups/DefaultMember.IAR + simList *sims = getSims(); + struct sysinfo info; + float la; - free(file); - file = xmprintf("%s.lua", Rd->shs.UUID); - I("Symlinking %s to %s", file, nm); - if (0 != symlink(file, nm)) - perror_msg("Symlinking %s to %s", file, nm); - free(nm); free(name); + sysinfo(&info); + la = info.loads[0]/65536.0; + + for (i = 0; i < sims->num; i++) + { + char *sim = sims->sims[i], *name = getSimName(sims->sims[i]); + + if (checkSimIsRunning(sim)) + { + I("Loading default member IAR for %s %s in sim %s, this might take a couple of minutes.", first, last, name); + char *c = xmprintf("%s %s/%s send-keys -t '%s:%d' 'load iar -m %s %s / password /opt/opensim_SC/backups/DefaultMember.IAR' Enter", + Tcmd, scRun, Tsocket, Tconsole, i + 1, first, last); +T(c); + int r = system(c); + if (!WIFEXITED(r)) + E("tmux load iar command failed!"); + else + { +// memset(toybuf, 0, sizeof(toybuf)); +// snprintf(toybuf, sizeof(toybuf), "INITIALIZATION COMPLETE FOR %s", name); +// waitTmuxText(name, toybuf); +// I("%s is done starting up.", name); +// la = waitLoadAverage(la, loadAverageInc, simTimeOut); + } + free(c); + break; + } + } + + } + free(first); + } + } } - xclose(fd); + else + W("Not writing NULL UUID user!"); free(tnm); free(voucher); free(about); @@ -4694,6 +4958,8 @@ static int accountRead(reqData *Rd, char *uuid, char *firstName, char *lastName) dbRequests->addfirst(dbRequests, auth, sizeof(*auth)); } + Rd->fromDb = FALSE; + // uuid = Rd->shs.UUID; first = getStrH(Rd->stuff, "firstName"); last = getStrH(Rd->stuff, "lastName"); // Special for showing another users details. @@ -4783,7 +5049,6 @@ d("accountRead() UUID %s, name %s %s", uuid, first, last); } else if (rows) { - ret += rows->rows->size(rows->rows); if (1 == ret) { @@ -4791,6 +5056,7 @@ d("accountRead() UUID %s, name %s %s", uuid, first, last); char *name = xmprintf("%s %s", getStrH(Rd->database, "UserAccounts.FirstName"), getStrH(Rd->database, "UserAccounts.LastName")); + Rd->fromDb = TRUE; Rd->database->putstr(Rd->database, "Lua.name", name); free(name); dbDoSomething(auth, FALSE, getStrH(Rd->database, "UserAccounts.PrincipalID")); @@ -5154,7 +5420,7 @@ static int accountFilterValidated(struct dirtree *node) struct stat st; struct timespec now; RdAndListTbl *rdl = (RdAndListTbl *) node->parent->extra; - qhashtbl_t *tnm = qhashtbl(0, 0); + qhashtbl_t *tnm = qhashtbl(0, 0); // LEAKY! char *name = node->name; char *where = xmprintf("%s/users/%s", scData, node->name); int rt = LuaToHash(rdl->Rd, where, "user", tnm, 0, &st, &now, "user"); @@ -5488,7 +5754,7 @@ void account_html(char *file, reqData *Rd, HTMLfile *thisFile) accountLevels->putstr(accountLevels, "-200", "newbie"); accountLevels->putstr(accountLevels, "-100", "validated"); accountLevels->putstr(accountLevels, "-50", "vouched for"); - accountLevels->putstr(accountLevels, "1", "approved"); + accountLevels->putstr(accountLevels, "0", "approved"); // Note that http://opensimulator.org/wiki/Userlevel claims that 1 and above are "GOD_LIKE". accountLevels->putstr(accountLevels, "200", "god"); } @@ -6613,7 +6879,6 @@ fcgiDone: } - simList *sims = getSims(); if (1) { -- cgit v1.1