Example #1
0
DS::String DS::Stream::readSafeString(DS::StringType format)
{
    uint16_t length = read<uint16_t>();
    if (!(length & 0xF000))
        read<uint16_t>();   // Discarded
    length &= 0x0FFF;

    String result;
    if (format == e_StringUTF16) {
        chr16_t* buffer = new chr16_t[length];
        ssize_t bytes = readBytes(buffer, length * sizeof(chr16_t));
        read<chr16_t>(); // redundant L'\0'
        DS_DASSERT(bytes == static_cast<ssize_t>(length * sizeof(chr16_t)));
        if (length && (buffer[0] & 0x8000)) {
            for (uint16_t i=0; i<length; ++i)
                buffer[i] = ~buffer[i];
        }
        result = String::FromUtf16(buffer, length);
        delete[] buffer;
    } else {
        chr8_t* buffer = new chr8_t[length];
        ssize_t bytes = readBytes(buffer, length * sizeof(chr8_t));
        DS_DASSERT(bytes == static_cast<ssize_t>(length * sizeof(chr8_t)));
        if (length && (buffer[0] & 0x80)) {
            for (uint16_t i=0; i<length; ++i)
                buffer[i] = ~buffer[i];
        }
        result = (format == e_StringUTF8) ? String::FromUtf8(buffer, length)
                                          : String::FromRaw(buffer, length);
        delete[] buffer;
    }
    return result;
}
Example #2
0
DS::SocketHandle DS::AcceptSock(const DS::SocketHandle sock)
{
    DS_DASSERT(sock);
    SocketHandle_Private* sockp = reinterpret_cast<SocketHandle_Private*>(sock);

    SocketHandle_Private* client = new SocketHandle_Private();
    client->m_sockfd = accept(sockp->m_sockfd, &client->m_addr, &client->m_addrLen);
    if (client->m_sockfd < 0) {
        delete client;
        if (errno == EINVAL) {
            throw DS::SockHup();
        } else if (errno == ECONNABORTED) {
            return 0;
        } else {
            fprintf(stderr, "Socket closed: %s\n", strerror(errno));
            DS_DASSERT(0);
        }
    }
    timeval tv;
    // Client pings us every 30 seconds. A timeout of 45 gives us some wiggle room
    // so networks can suck without kicking a client off.
    tv.tv_sec = 45;
    tv.tv_usec = 0;
    setsockopt(client->m_sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
    // eap-tastic protocols require Nagle's algo be disabled
    setsockopt(client->m_sockfd, IPPROTO_TCP, TCP_NODELAY, &SOCK_YES, sizeof(SOCK_YES));
    return reinterpret_cast<SocketHandle>(client);
}
Example #3
0
ST::string DS::Stream::readSafeString(DS::StringType format)
{
    uint16_t length = read<uint16_t>();
    if (!(length & 0xF000))
        read<uint16_t>();   // Discarded
    length &= 0x0FFF;

    if (format == e_StringUTF16) {
        ST::utf16_buffer result;
        char16_t* buffer = result.create_writable_buffer(length);
        ssize_t bytes = readBytes(buffer, length * sizeof(char16_t));
        read<char16_t>(); // redundant u'\0'
        DS_DASSERT(bytes == static_cast<ssize_t>(length * sizeof(char16_t)));
        if (length && (buffer[0] & 0x8000)) {
            for (uint16_t i=0; i<length; ++i)
                buffer[i] = ~buffer[i];
        }
        buffer[length] = 0;
        return ST::string::from_utf16(result, ST::substitute_invalid);
    } else {
        ST::char_buffer result;
        char* buffer = result.create_writable_buffer(length);
        ssize_t bytes = readBytes(buffer, length * sizeof(char));
        DS_DASSERT(bytes == static_cast<ssize_t>(length * sizeof(char)));
        if (length && (buffer[0] & 0x80)) {
            for (uint16_t i=0; i<length; ++i)
                buffer[i] = ~buffer[i];
        }
        buffer[length] = 0;
        return (format == e_StringUTF8)
               ? ST::string::from_utf8(result, ST::substitute_invalid)
               : ST::string::from_latin_1(result);
    }
}
Example #4
0
DS::Uuid::Uuid(const char* struuid)
{
    char hexbuf[9];
    DS_DASSERT(strlen(struuid) == 36);
    DS_DASSERT(struuid[8] == '-' && struuid[13] == '-' && struuid[18] == '-'
               && struuid[23] == '-');

    /* First segment */
    memcpy(hexbuf, struuid, 8);
    hexbuf[8] = 0;
    m_data1 = strtoul(hexbuf, 0, 16);

    /* Second segment */
    memcpy(hexbuf, struuid + 9, 4);
    hexbuf[4] = 0;
    m_data2 = strtoul(hexbuf, 0, 16);

    /* Third segment */
    memcpy(hexbuf, struuid + 14, 4);
    hexbuf[4] = 0;
    m_data3 = strtoul(hexbuf, 0, 16);

    /* Fourth segment */
    memcpy(hexbuf, struuid + 19, 2);
    hexbuf[2] = 0;
    m_data4[0] = strtoul(hexbuf, 0, 16);
    memcpy(hexbuf, struuid + 21, 2);
    hexbuf[2] = 0;
    m_data4[1] = strtoul(hexbuf, 0, 16);

    /* Fifth segment */
    memcpy(hexbuf, struuid + 24, 2);
    hexbuf[2] = 0;
    m_data4[2] = strtoul(hexbuf, 0, 16);
    memcpy(hexbuf, struuid + 26, 2);
    hexbuf[2] = 0;
    m_data4[3] = strtoul(hexbuf, 0, 16);
    memcpy(hexbuf, struuid + 28, 2);
    hexbuf[2] = 0;
    m_data4[4] = strtoul(hexbuf, 0, 16);
    memcpy(hexbuf, struuid + 30, 2);
    hexbuf[2] = 0;
    m_data4[5] = strtoul(hexbuf, 0, 16);
    memcpy(hexbuf, struuid + 32, 2);
    hexbuf[2] = 0;
    m_data4[6] = strtoul(hexbuf, 0, 16);
    memcpy(hexbuf, struuid + 34, 2);
    hexbuf[2] = 0;
    m_data4[7] = strtoul(hexbuf, 0, 16);
}
Example #5
0
static uint32_t find_public_age_1(const DS::String& filename)
{
    PGresult* result;
    {
        PostgresStrings<1> parm;
        parm.set(0, filename);
        result = PQexecParams(s_postgres,
                "SELECT \"AgeUuid\" FROM game.\"PublicAges\""
                "    WHERE \"AgeFilename\"=$1 AND \"SeqNumber\"=0",
                1, 0, parm.m_values, 0, 0, 0);
    }
    if (PQresultStatus(result) != PGRES_TUPLES_OK) {
        fprintf(stderr, "%s:%d:\n    Postgres SELECT error: %s\n",
                __FILE__, __LINE__, PQerrorMessage(s_postgres));
        PQclear(result);
        return 0;
    }
    DS_DASSERT(PQntuples(result) == 1);

    DS::Uuid ageId(PQgetvalue(result, 0, 0));
    PQclear(result);

    {
        PostgresStrings<2> parms;
        parms.set(0, DS::Vault::e_NodeAgeInfo);
        parms.set(1, ageId.toString());
        result = PQexecParams(s_postgres,
                "SELECT idx FROM vault.\"Nodes\""
                "    WHERE \"NodeType\"=$1 AND \"Uuid_1\"=$2",
                2, 0, parms.m_values, 0, 0, 0);
    }
    if (PQresultStatus(result) != PGRES_TUPLES_OK) {
        fprintf(stderr, "%s:%d:\n    Postgres SELECT error: %s\n",
                __FILE__, __LINE__, PQerrorMessage(s_postgres));
        PQclear(result);
        return 0;
    }
    if (PQntuples(result) == 0) {
        // Public age not found
        PQclear(result);
        return 0;
    }
    DS_DASSERT(PQntuples(result) == 1);

    uint32_t ageInfoNode = strtoul(PQgetvalue(result, 0, 0), 0, 10);
    PQclear(result);
    return ageInfoNode;
}
Example #6
0
DS::Vault::NodeRef v_send_node(uint32_t nodeId, uint32_t playerId, uint32_t senderId)
{
    DS::Vault::NodeRef ref;
    ref.m_child = ref.m_owner = ref.m_parent = 0;
    PostgresStrings<2> parms;
    parms.set(0, playerId);
    parms.set(1, DS::Vault::e_InboxFolder);
    PGresult* result = PQexecParams(s_postgres,
            "SELECT idx FROM vault.find_folder($1, $2);",
            2, 0, parms.m_values, 0, 0, 0);
    if (PQresultStatus(result) != PGRES_TUPLES_OK) {
        fprintf(stderr, "%s:%d:\n    Postgres SELECT error: %s\n",
                __FILE__, __LINE__, PQerrorMessage(s_postgres));
        PQclear(result);
        return ref;
    }
    DS_DASSERT(PQntuples(result) == 1);
    uint32_t inbox = strtoul(PQgetvalue(result, 0, 0), 0, 10);
    PQclear(result);

    if (v_ref_node(inbox, nodeId, senderId)) {
        ref.m_child = nodeId;
        ref.m_owner = senderId;
        ref.m_parent = inbox;
    }
    return ref;
}
Example #7
0
bool v_has_node(uint32_t parentId, uint32_t childId)
{
    if (parentId == 0)
        return false;
    if (parentId == childId)
        return true;

    PostgresStrings<2> parms;
    parms.set(0, parentId);
    parms.set(1, childId);

    check_postgres();
    PGresult* result = PQexecParams(s_postgres,
                                    "SELECT vault.has_node($1, $2)",
                                    2, 0, parms.m_values, 0, 0, 0);
    if (PQresultStatus(result) != PGRES_TUPLES_OK) {
        fprintf(stderr, "%s:%d:\n    Postgres SELECT error: %s\n",
                __FILE__, __LINE__, PQerrorMessage(s_postgres));
        PQclear(result);
        return false;
    }
    DS_DASSERT(PQntuples(result) == 1);
    bool retval = (*PQgetvalue(result, 0, 0) == 't');
    PQclear(result);
    return retval != 0;
}
Example #8
0
void DS::CryptEstablish(uint8_t* seed, uint8_t* key, const uint8_t* N,
                        const uint8_t* K, uint8_t* Y)
{
    BIGNUM* bn_Y = BN_new();
    BIGNUM* bn_N = BN_new();
    BIGNUM* bn_K = BN_new();
    BIGNUM* bn_seed = BN_new();
    BN_CTX* ctx = BN_CTX_new();

    /* Random 7-byte server seed */
    init_rand();
    RAND_bytes(reinterpret_cast<unsigned char*>(seed), 7);

    /* client = Y ^ K % N */
    BN_bin2bn(reinterpret_cast<const unsigned char*>(Y), 64, bn_Y);
    BN_bin2bn(reinterpret_cast<const unsigned char*>(N), 64, bn_N);
    BN_bin2bn(reinterpret_cast<const unsigned char*>(K), 64, bn_K);
    DS_PASSERT(!BN_is_zero(bn_N));
    BN_mod_exp(bn_seed, bn_Y, bn_K, bn_N, ctx);

    /* Apply server seed for establishing crypt state with client */
    uint8_t keybuf[64];
    DS_DASSERT(BN_num_bytes(bn_seed) <= 64);
    size_t outBytes = BN_bn2bin(bn_seed, reinterpret_cast<unsigned char*>(keybuf));
    BYTE_SWAP_BUFFER(keybuf, outBytes);
    for (size_t i=0; i<7; ++i)
        key[i] = keybuf[i] ^ seed[i];

    BN_free(bn_Y);
    BN_free(bn_N);
    BN_free(bn_K);
    BN_free(bn_seed);
    BN_CTX_free(ctx);
}
Example #9
0
DS::SocketHandle DS::AcceptSock(const DS::SocketHandle sock)
{
    DS_DASSERT(sock);
    SocketHandle_Private* sockp = reinterpret_cast<SocketHandle_Private*>(sock);

    SocketHandle_Private* client = new SocketHandle_Private();
    client->m_sockfd = accept(sockp->m_sockfd, &client->m_addr, &client->m_addrLen);
    if (client->m_sockfd < 0) {
        delete client;
        if (errno != EINVAL) {
            fprintf(stderr, "Socket closed: %s\n", strerror(errno));
            DS_DASSERT(0);
        }
        return 0;
    }
    return reinterpret_cast<SocketHandle>(client);
}
Example #10
0
DS::String DS::Stream::readString(size_t length, DS::StringType format)
{
    String result;
    if (format == e_StringUTF16) {
        chr16_t* buffer = new chr16_t[length];
        ssize_t bytes = readBytes(buffer, length * sizeof(chr16_t));
        DS_DASSERT(bytes == static_cast<ssize_t>(length * sizeof(chr16_t)));
        result = String::FromUtf16(buffer, length);
        delete[] buffer;
    } else {
        chr8_t* buffer = new chr8_t[length];
        ssize_t bytes = readBytes(buffer, length * sizeof(chr8_t));
        DS_DASSERT(bytes == static_cast<ssize_t>(length * sizeof(chr8_t)));
        result = (format == e_StringUTF8) ? String::FromUtf8(buffer, length)
                                          : String::FromRaw(buffer, length);
        delete[] buffer;
    }
    return result;
}
Example #11
0
ST::string DS::Stream::readString(size_t length, DS::StringType format)
{
    if (format == e_StringUTF16) {
        ST::utf16_buffer result;
        char16_t* buffer = result.create_writable_buffer(length);
        ssize_t bytes = readBytes(buffer, length * sizeof(char16_t));
        DS_DASSERT(bytes == static_cast<ssize_t>(length * sizeof(char16_t)));
        buffer[length] = 0;
        return ST::string::from_utf16(result, ST::substitute_invalid);
    } else {
        ST::char_buffer result;
        char* buffer = result.create_writable_buffer(length);
        ssize_t bytes = readBytes(buffer, length * sizeof(char));
        DS_DASSERT(bytes == static_cast<ssize_t>(length * sizeof(char)));
        buffer[length] = 0;
        return (format == e_StringUTF8) ? ST::string::from_utf8(result, ST::substitute_invalid)
                                        : ST::string::from_latin_1(result);
    }
}
Example #12
0
void dm_save_sdl_state(GameHost_Private* host, const DS::String& descriptor,
                       const MOUL::Uoid& object, const SDL::State& state)
{
    check_postgres(host);

    DS::Blob sdlBlob = state.toBlob();
    PostgresStrings<4> parms;
    host->m_buffer.truncate();
    object.write(&host->m_buffer);
    parms.set(0, host->m_serverIdx);
    parms.set(1, descriptor);
    parms.set(2, DS::Base64Encode(host->m_buffer.buffer(), host->m_buffer.size()));
    parms.set(3, DS::Base64Encode(sdlBlob.buffer(), sdlBlob.size()));
    PGresult* result = PQexecParams(host->m_postgres,
                                    "SELECT idx FROM game.\"AgeStates\""
                                    "    WHERE \"ServerIdx\"=$1 AND \"Descriptor\"=$2 AND \"ObjectKey\"=$3",
                                    3, 0, parms.m_values, 0, 0, 0);
    if (PQresultStatus(result) != PGRES_TUPLES_OK) {
        fprintf(stderr, "%s:%d:\n    Postgres SELECT error: %s\n",
                __FILE__, __LINE__, PQerrorMessage(host->m_postgres));
        PQclear(result);
        return;
    }
    if (PQntuples(result) == 0) {
        PQclear(result);
        result = PQexecParams(host->m_postgres,
                              "INSERT INTO game.\"AgeStates\""
                              "    (\"ServerIdx\", \"Descriptor\", \"ObjectKey\", \"SdlBlob\")"
                              "    VALUES ($1, $2, $3, $4)",
                              4, 0, parms.m_values, 0, 0, 0);
        if (PQresultStatus(result) != PGRES_COMMAND_OK) {
            fprintf(stderr, "%s:%d:\n    Postgres INSERT error: %s\n",
                    __FILE__, __LINE__, PQerrorMessage(host->m_postgres));
            PQclear(result);
            return;
        }
        PQclear(result);
    } else {
        DS_DASSERT(PQntuples(result) == 1);
        parms.set(0, DS::String(PQgetvalue(result, 0, 0)));
        parms.set(1, parms.m_strings[3]);   // SDL blob
        PQclear(result);
        result = PQexecParams(host->m_postgres,
                              "UPDATE game.\"AgeStates\""
                              "    SET \"SdlBlob\"=$2 WHERE idx=$1",
                              2, 0, parms.m_values, 0, 0, 0);
        if (PQresultStatus(result) != PGRES_COMMAND_OK) {
            fprintf(stderr, "%s:%d:\n    Postgres UPDATE error: %s\n",
                    __FILE__, __LINE__, PQerrorMessage(host->m_postgres));
            PQclear(result);
            return;
        }
        PQclear(result);
    }
}
Example #13
0
bool dm_vault_init()
{
    PostgresStrings<1> sparm;
    sparm.set(0, DS::Vault::e_NodeSystem);
    PGresult* result = PQexecParams(s_postgres,
            "SELECT \"idx\" FROM vault.\"Nodes\""
            "    WHERE \"NodeType\"=$1",
            1, 0, sparm.m_values, 0, 0, 0);
    if (PQresultStatus(result) != PGRES_TUPLES_OK) {
        fprintf(stderr, "%s:%d:\n    Postgres SELECT error: %s\n",
                __FILE__, __LINE__, PQerrorMessage(s_postgres));
        PQclear(result);
        return false;
    }

    int count = PQntuples(result);
    if (count == 0) {
        PQclear(result);

        fputs("[Vault] Initializing empty DirtSand vault\n", stderr);

        // Create system and global inbox nodes
        DS::Vault::Node node;
        node.set_NodeType(DS::Vault::e_NodeSystem);
        s_systemNode = v_create_node(node);
        if (s_systemNode == 0)
            return false;

        node.set_NodeType(DS::Vault::e_NodeFolder);
        node.set_Int32_1(DS::Vault::e_GlobalInboxFolder);
        uint32_t globalInbox = v_create_node(node);
        if (globalInbox == 0)
            return false;

        if (!v_ref_node(s_systemNode, globalInbox, 0))
            return false;

        std::list<AuthServer_AgeInfo> ages = configure_static_ages();
        for (auto iter = ages.begin(); iter != ages.end(); ++iter) {
            if (std::get<0>(v_create_age(*iter, e_AgePublic)) == 0)
                return false;
        }
    } else {
        DS_DASSERT(count == 1);
        s_systemNode = strtoul(PQgetvalue(result, 0, 0), 0, 10);
        PQclear(result);
    }

    return true;
}
Example #14
0
DS::Uuid gen_uuid()
{
    check_postgres();
    PGresult* result = PQexec(s_postgres, "SELECT uuid_generate_v4()");
    if (PQresultStatus(result) != PGRES_TUPLES_OK) {
        fprintf(stderr, "%s:%d:\n    Postgres SELECT error: %s\n",
                __FILE__, __LINE__, PQerrorMessage(s_postgres));
        PQclear(result);
        return DS::Uuid();
    }
    DS_DASSERT(PQntuples(result) == 1);
    DS::Uuid uuid(PQgetvalue(result, 0, 0));
    PQclear(result);
    return uuid;
}
Example #15
0
static uint32_t find_public_age_1(const DS::String& filename)
{
    PostgresStrings<1> parm;
    parm.set(0, filename);
    PGresult* result = PQexecParams(s_postgres, "SELECT idx FROM vault.\"Nodes\""
                       "    WHERE \"Int32_2\" = 1 AND \"String64_2\"=$1",
                       1, 0, parm.m_values, 0, 0, 0);
    uint32_t ageInfoId = 0;
    if (PQresultStatus(result) == PGRES_TUPLES_OK) {
        DS_DASSERT(PQntuples(result) == 1);
        ageInfoId = strtoul(PQgetvalue(result, 0, 0), 0, 10);
    } else {
        fprintf(stderr, "%s:%d:\n    Postgres SELECT error: %s\n",
                __FILE__, __LINE__, PQerrorMessage(s_postgres));
    }
    PQclear(result);
    return ageInfoId;
}
Example #16
0
void dm_gameHost(GameHost_Private* host)
{
    for ( ;; ) {
        DS::FifoMessage msg = host->m_channel.getMessage();
        try {
            switch (msg.m_messageType) {
            case e_GameShutdown:
                dm_game_shutdown(host);
                return;
            case e_GameDisconnect:
                dm_game_disconnect(host, reinterpret_cast<Game_ClientMessage*>(msg.m_payload));
                break;
            case e_GameJoinAge:
                dm_game_join(host, reinterpret_cast<Game_ClientMessage*>(msg.m_payload));
                break;
            case e_GamePropagate:
                dm_game_message(host, reinterpret_cast<Game_PropagateMessage*>(msg.m_payload));
                break;
            case e_GameLocalSdlUpdate:
                dm_local_sdl_update(host, reinterpret_cast<Game_SdlMessage*>(msg.m_payload));
                break;
            case e_GameGlobalSdlUpdate:
                dm_global_sdl_update(host);
                break;
            default:
                /* Invalid message...  This shouldn't happen */
                DS_DASSERT(0);
                break;
            }
        } catch (DS::AssertException ex) {
            fprintf(stderr, "[Game] Assertion failed at %s:%ld:  %s\n",
                    ex.m_file, ex.m_line, ex.m_cond);
            if (msg.m_payload) {
                // Keep clients from blocking on a reply
                SEND_REPLY(reinterpret_cast<Game_ClientMessage*>(msg.m_payload),
                           DS::e_NetInternalError);
            }
        }
    }

    dm_game_shutdown(host);
}
Example #17
0
void MOUL::NetMsgSharedState::read(DS::Stream* stream)
{
    NetMsgObject::read(stream);

    NetMsgStream msgStream;
    msgStream.read(stream);
    m_compression = msgStream.m_compression;

    // Read the state
    uint16_t nameLen = msgStream.m_stream.read<uint16_t>();
    m_stateName = msgStream.m_stream.readString(nameLen, DS::e_StringUTF8);
    m_vars.resize(msgStream.m_stream.read<uint32_t>());
    m_serverMayDelete = msgStream.m_stream.readBool();

    for (size_t i=0; i<m_vars.size(); ++i)
        m_vars[i].read(&msgStream.m_stream);
    DS_DASSERT(msgStream.m_stream.atEof());

    m_lockRequest = stream->read<uint8_t>();
}
Example #18
0
uint32_t DS::FileManifest::encodeToStream(DS::Stream* stream)
{
    uint32_t start = stream->tell();

    for (auto it = m_files.begin(); it != m_files.end(); ++it) {
        StringBuffer<chr16_t> wstrbuf = (*it)->m_filename.toUtf16();
        stream->writeBytes(wstrbuf.data(), wstrbuf.length() * sizeof(chr16_t));
        stream->write<chr16_t>(0);

        wstrbuf = (*it)->m_downloadName.toUtf16();
        stream->writeBytes(wstrbuf.data(), wstrbuf.length() * sizeof(chr16_t));
        stream->write<chr16_t>(0);

        stream->writeBytes((*it)->m_fileHash, 32 * sizeof(chr16_t));
        stream->write<chr16_t>(0);

        stream->writeBytes((*it)->m_downloadHash, 32 * sizeof(chr16_t));
        stream->write<chr16_t>(0);

        stream->write<uint16_t>((*it)->m_fileSize >> 16);
        stream->write<uint16_t>((*it)->m_fileSize & 0xFFFF);
        stream->write<uint16_t>(0);

        stream->write<uint16_t>((*it)->m_downloadSize >> 16);
        stream->write<uint16_t>((*it)->m_downloadSize & 0xFFFF);
        stream->write<uint16_t>(0);

        stream->write<uint16_t>((*it)->m_flags >> 16);
        stream->write<uint16_t>((*it)->m_flags & 0xFFFF);
        stream->write<uint16_t>(0);
    }
    stream->write<uint16_t>(0);

    DS_DASSERT((stream->tell() - start) % sizeof(chr16_t) == 0);
    return (stream->tell() - start) / sizeof(chr16_t);
}
Example #19
0
void DS::CloseSock(DS::SocketHandle sock)
{
    DS_DASSERT(sock);
    shutdown(reinterpret_cast<SocketHandle_Private*>(sock)->m_sockfd, SHUT_RDWR);
    close(reinterpret_cast<SocketHandle_Private*>(sock)->m_sockfd);
}
Example #20
0
static uint32_t find_a_friendly_neighborhood_for_our_new_visitor(uint32_t playerInfoId)
{
    PGresult* result = PQexec(s_postgres,
            "SELECT \"AgeUuid\" FROM game.\"PublicAges\""
            "    WHERE \"AgeFilename\" = 'Neighborhood'"
            "    AND \"Population\" < 20 AND \"SeqNumber\" <> 0");
    if (PQresultStatus(result) != PGRES_TUPLES_OK) {
        fprintf(stderr, "%s:%d:\n    Postgres SELECT error: %s\n",
                __FILE__, __LINE__, PQerrorMessage(s_postgres));
        PQclear(result);
        return 0;
    }

    std::pair<uint32_t, uint32_t> ageNode;
    DS::Uuid ageId;
    if (PQntuples(result) != 0) {
        ageId = DS::Uuid(PQgetvalue(result, 0, 0));
        PQclear(result);

        PostgresStrings<2> parms;
        parms.set(0, DS::Vault::e_NodeAgeInfo);
        parms.set(1, ageId.toString());
        result = PQexecParams(s_postgres,
                "SELECT idx FROM vault.\"Nodes\""
                "    WHERE \"NodeType\"=$1 AND \"Uuid_1\"=$2",
                2, 0, parms.m_values, 0, 0, 0);
        if (PQresultStatus(result) != PGRES_TUPLES_OK) {
            fprintf(stderr, "%s:%d:\n    Postgres SELECT error: %s\n",
                    __FILE__, __LINE__, PQerrorMessage(s_postgres));
            PQclear(result);
            return 0;
        }
        DS_DASSERT(PQntuples(result) == 1);
        ageNode.second = strtoul(PQgetvalue(result, 0, 0), 0, 10);
        PQclear(result);
    } else {
        PQclear(result);
        AuthServer_AgeInfo age;
        age.m_ageId = gen_uuid();
        age.m_filename = "Neighborhood";
        age.m_instName = "Neighborhood";
        age.m_userName = "******";
        age.m_description = "DS Neighborhood";
        age.m_seqNumber = -1;   // Auto-generate
        ageNode = v_create_age(age, e_AgePublic);
        if (ageNode.second == 0)
            return 0;
    }

    {
        PostgresStrings<2> parms;
        parms.set(0, ageNode.second);
        parms.set(1, DS::Vault::e_AgeOwnersFolder);
        result = PQexecParams(s_postgres,
                "SELECT idx FROM vault.find_folder($1, $2);",
                2, 0, parms.m_values, 0, 0, 0);
    }
    if (PQresultStatus(result) != PGRES_TUPLES_OK) {
        fprintf(stderr, "%s:%d:\n    Postgres SELECT error: %s\n",
                __FILE__, __LINE__, PQerrorMessage(s_postgres));
        PQclear(result);
        return 0;
    }
    DS_DASSERT(PQntuples(result) == 1);
    uint32_t ownerFolder = strtoul(PQgetvalue(result, 0, 0), 0, 10);
    PQclear(result);

    if (!v_ref_node(ownerFolder, playerInfoId, 0))
        return 0;

    {
        PostgresStrings<1> parms;
        parms.set(0, ageId.toString());
        result = PQexecParams(s_postgres,
                "UPDATE game.\"PublicAges\""
                "    SET \"Population\" = \"Population\"+1"
                "    WHERE \"AgeUuid\" = $1",
                1, 0, parms.m_values, 0, 0, 0);
    }
    if (PQresultStatus(result) != PGRES_COMMAND_OK) {
        fprintf(stderr, "%s:%d:\n    Postgres SELECT error: %s\n",
                __FILE__, __LINE__, PQerrorMessage(s_postgres));
        PQclear(result);
        return 0;
    }
    PQclear(result);

    return ageNode.second;
}
Example #21
0
void DS::ListenSock(const DS::SocketHandle sock, int backlog)
{
    DS_DASSERT(sock);
    int result = listen(reinterpret_cast<SocketHandle_Private*>(sock)->m_sockfd, backlog);
    DS_PASSERT(result == 0);
}
Example #22
0
DS::Vault::Node v_fetch_node(uint32_t nodeIdx)
{
    PostgresStrings<1> parm;
    parm.set(0, nodeIdx);
    PGresult* result = PQexecParams(s_postgres,
        "SELECT idx, \"CreateTime\", \"ModifyTime\", \"CreateAgeName\","
        "    \"CreateAgeUuid\", \"CreatorUuid\", \"CreatorIdx\", \"NodeType\","
        "    \"Int32_1\", \"Int32_2\", \"Int32_3\", \"Int32_4\","
        "    \"Uint32_1\", \"Uint32_2\", \"Uint32_3\", \"Uint32_4\","
        "    \"Uuid_1\", \"Uuid_2\", \"Uuid_3\", \"Uuid_4\","
        "    \"String64_1\", \"String64_2\", \"String64_3\", \"String64_4\","
        "    \"String64_5\", \"String64_6\", \"IString64_1\", \"IString64_2\","
        "    \"Text_1\", \"Text_2\", \"Blob_1\", \"Blob_2\""
        "    FROM vault.\"Nodes\" WHERE idx=$1",
        1, 0, parm.m_values, 0, 0, 0);
    if (PQresultStatus(result) != PGRES_TUPLES_OK) {
        fprintf(stderr, "%s:%d:\n    Postgres SELECT error: %s\n",
                __FILE__, __LINE__, PQerrorMessage(s_postgres));
        PQclear(result);
        return DS::Vault::Node();
    }
    if (PQntuples(result) == 0) {
        PQclear(result);
        return DS::Vault::Node();
    }
    DS_DASSERT(PQntuples(result) == 1);

    DS::Vault::Node node;
    node.set_NodeIdx(strtoul(PQgetvalue(result, 0, 0), 0, 10));
    node.set_CreateTime(strtoul(PQgetvalue(result, 0, 1), 0, 10));
    node.set_ModifyTime(strtoul(PQgetvalue(result, 0, 2), 0, 10));
    if (!PQgetisnull(result, 0, 3))
        node.set_CreateAgeName(PQgetvalue(result, 0, 3));
    if (!PQgetisnull(result, 0, 4))
        node.set_CreateAgeUuid(PQgetvalue(result, 0, 4));
    if (!PQgetisnull(result, 0, 5))
        node.set_CreatorUuid(PQgetvalue(result, 0, 5));
    if (!PQgetisnull(result, 0, 6))
        node.set_CreatorIdx(strtoul(PQgetvalue(result, 0, 6), 0, 10));
    node.set_NodeType(strtoul(PQgetvalue(result, 0, 7), 0, 10));
    if (!PQgetisnull(result, 0, 8))
        node.set_Int32_1(strtol(PQgetvalue(result, 0, 8), 0, 10));
    if (!PQgetisnull(result, 0, 9))
        node.set_Int32_2(strtol(PQgetvalue(result, 0, 9), 0, 10));
    if (!PQgetisnull(result, 0, 10))
        node.set_Int32_3(strtol(PQgetvalue(result, 0, 10), 0, 10));
    if (!PQgetisnull(result, 0, 11))
        node.set_Int32_4(strtol(PQgetvalue(result, 0, 11), 0, 10));
    if (!PQgetisnull(result, 0, 12))
        node.set_Uint32_1(strtoul(PQgetvalue(result, 0, 12), 0, 10));
    if (!PQgetisnull(result, 0, 13))
        node.set_Uint32_2(strtoul(PQgetvalue(result, 0, 13), 0, 10));
    if (!PQgetisnull(result, 0, 14))
        node.set_Uint32_3(strtoul(PQgetvalue(result, 0, 14), 0, 10));
    if (!PQgetisnull(result, 0, 15))
        node.set_Uint32_4(strtoul(PQgetvalue(result, 0, 15), 0, 10));
    if (!PQgetisnull(result, 0, 16))
        node.set_Uuid_1(PQgetvalue(result, 0, 16));
    if (!PQgetisnull(result, 0, 17))
        node.set_Uuid_2(PQgetvalue(result, 0, 17));
    if (!PQgetisnull(result, 0, 18))
        node.set_Uuid_3(PQgetvalue(result, 0, 18));
    if (!PQgetisnull(result, 0, 19))
        node.set_Uuid_4(PQgetvalue(result, 0, 19));
    if (!PQgetisnull(result, 0, 20))
        node.set_String64_1(PQgetvalue(result, 0, 20));
    if (!PQgetisnull(result, 0, 21))
        node.set_String64_2(PQgetvalue(result, 0, 21));
    if (!PQgetisnull(result, 0, 22))
        node.set_String64_3(PQgetvalue(result, 0, 22));
    if (!PQgetisnull(result, 0, 23))
        node.set_String64_4(PQgetvalue(result, 0, 23));
    if (!PQgetisnull(result, 0, 24))
        node.set_String64_5(PQgetvalue(result, 0, 24));
    if (!PQgetisnull(result, 0, 25))
        node.set_String64_6(PQgetvalue(result, 0, 25));
    if (!PQgetisnull(result, 0, 26))
        node.set_IString64_1(PQgetvalue(result, 0, 26));
    if (!PQgetisnull(result, 0, 27))
        node.set_IString64_2(PQgetvalue(result, 0, 27));
    if (!PQgetisnull(result, 0, 28))
        node.set_Text_1(PQgetvalue(result, 0, 28));
    if (!PQgetisnull(result, 0, 29))
        node.set_Text_2(PQgetvalue(result, 0, 29));
    if (!PQgetisnull(result, 0, 30))
        node.set_Blob_1(DS::Base64Decode(PQgetvalue(result, 0, 30)));
    if (!PQgetisnull(result, 0, 31))
        node.set_Blob_2(DS::Base64Decode(PQgetvalue(result, 0, 31)));

    PQclear(result);
    return node;
}
Example #23
0
bool v_update_node(const DS::Vault::Node& node)
{
    /* This should be plenty to store everything we need without a bunch
     * of dynamic reallocations
     */
    PostgresStrings<32> parms;
    char fieldbuf[1024];

    size_t parmcount = 1;
    char* fieldp = fieldbuf;

    #define SET_FIELD(name, value) \
        { \
            parms.set(parmcount++, value); \
            fieldp += sprintf(fieldp, "\"" #name "\"=$%Zu,", parmcount); \
        }
    int now = time(0);
    SET_FIELD(ModifyTime, now);
    if (node.has_CreateAgeName())
        SET_FIELD(CreateAgeName, node.m_CreateAgeName);
    if (node.has_CreateAgeUuid())
        SET_FIELD(CreateAgeUuid, node.m_CreateAgeUuid.toString());
    if (node.has_CreatorUuid())
        SET_FIELD(CreatorUuid, node.m_CreatorUuid.toString());
    if (node.has_CreatorIdx())
        SET_FIELD(CreatorIdx, node.m_CreatorIdx);
    if (node.has_NodeType())
        SET_FIELD(NodeType, node.m_NodeType);
    if (node.has_Int32_1())
        SET_FIELD(Int32_1, node.m_Int32_1);
    if (node.has_Int32_2())
        SET_FIELD(Int32_2, node.m_Int32_2);
    if (node.has_Int32_3())
        SET_FIELD(Int32_3, node.m_Int32_3);
    if (node.has_Int32_4())
        SET_FIELD(Int32_4, node.m_Int32_4);
    if (node.has_Uint32_1())
        SET_FIELD(Uint32_1, node.m_Uint32_1);
    if (node.has_Uint32_2())
        SET_FIELD(Uint32_2, node.m_Uint32_2);
    if (node.has_Uint32_3())
        SET_FIELD(Uint32_3, node.m_Uint32_3);
    if (node.has_Uint32_4())
        SET_FIELD(Uint32_4, node.m_Uint32_4);
    if (node.has_Uuid_1())
        SET_FIELD(Uuid_1, node.m_Uuid_1.toString());
    if (node.has_Uuid_2())
        SET_FIELD(Uuid_2, node.m_Uuid_2.toString());
    if (node.has_Uuid_3())
        SET_FIELD(Uuid_3, node.m_Uuid_3.toString());
    if (node.has_Uuid_4())
        SET_FIELD(Uuid_4, node.m_Uuid_4.toString());
    if (node.has_String64_1())
        SET_FIELD(String64_1, node.m_String64_1);
    if (node.has_String64_2())
        SET_FIELD(String64_2, node.m_String64_2);
    if (node.has_String64_3())
        SET_FIELD(String64_3, node.m_String64_3);
    if (node.has_String64_4())
        SET_FIELD(String64_4, node.m_String64_4);
    if (node.has_String64_5())
        SET_FIELD(String64_5, node.m_String64_5);
    if (node.has_String64_6())
        SET_FIELD(String64_6, node.m_String64_6);
    if (node.has_IString64_1())
        SET_FIELD(IString64_1, node.m_IString64_1);
    if (node.has_IString64_2())
        SET_FIELD(IString64_2, node.m_IString64_2);
    if (node.has_Text_1())
        SET_FIELD(Text_1, node.m_Text_1);
    if (node.has_Text_2())
        SET_FIELD(Text_2, node.m_Text_2);
    if (node.has_Blob_1())
        SET_FIELD(Blob_1, DS::Base64Encode(node.m_Blob_1.buffer(), node.m_Blob_1.size()));
    if (node.has_Blob_2())
        SET_FIELD(Blob_2, DS::Base64Encode(node.m_Blob_2.buffer(), node.m_Blob_2.size()));
    #undef SET_FIELD

    DS_DASSERT(fieldp - fieldbuf < 1024);
    *(fieldp - 1) = 0;  // Get rid of the last comma
    DS::String queryStr = "UPDATE vault.\"Nodes\"\n    SET ";
    queryStr += fieldbuf;
    queryStr += "\n    WHERE idx=$1";
    parms.set(0, node.m_NodeIdx);

    check_postgres();
    PGresult* result = PQexecParams(s_postgres, queryStr.c_str(),
                                    parmcount, 0, parms.m_values, 0, 0, 0);
    if (PQresultStatus(result) != PGRES_COMMAND_OK) {
        fprintf(stderr, "%s:%d:\n    Postgres UPDATE error: %s\n",
                __FILE__, __LINE__, PQerrorMessage(s_postgres));
        PQclear(result);
        return false;
    }
    PQclear(result);
    return true;
}
Example #24
0
uint32_t v_create_node(const DS::Vault::Node& node)
{
    /* This should be plenty to store everything we need without a bunch
     * of dynamic reallocations
     */
    PostgresStrings<31> parms;
    char fieldbuf[1024];

    size_t parmcount = 0;
    char* fieldp = fieldbuf;

    #define SET_FIELD(name, value) \
        { \
            parms.set(parmcount++, value); \
            fieldp += sprintf(fieldp, "\"" #name "\","); \
        }
    int now = time(0);
    SET_FIELD(CreateTime, now);
    SET_FIELD(ModifyTime, now);
    if (node.has_CreateAgeName())
        SET_FIELD(CreateAgeName, node.m_CreateAgeName);
    if (node.has_CreateAgeUuid())
        SET_FIELD(CreateAgeUuid, node.m_CreateAgeUuid.toString());
    if (node.has_CreatorUuid())
        SET_FIELD(CreatorUuid, node.m_CreatorUuid.toString());
    if (node.has_CreatorIdx())
        SET_FIELD(CreatorIdx, node.m_CreatorIdx);
    if (node.has_NodeType())
        SET_FIELD(NodeType, node.m_NodeType);
    if (node.has_Int32_1())
        SET_FIELD(Int32_1, node.m_Int32_1);
    if (node.has_Int32_2())
        SET_FIELD(Int32_2, node.m_Int32_2);
    if (node.has_Int32_3())
        SET_FIELD(Int32_3, node.m_Int32_3);
    if (node.has_Int32_4())
        SET_FIELD(Int32_4, node.m_Int32_4);
    if (node.has_Uint32_1())
        SET_FIELD(Uint32_1, node.m_Uint32_1);
    if (node.has_Uint32_2())
        SET_FIELD(Uint32_2, node.m_Uint32_2);
    if (node.has_Uint32_3())
        SET_FIELD(Uint32_3, node.m_Uint32_3);
    if (node.has_Uint32_4())
        SET_FIELD(Uint32_4, node.m_Uint32_4);
    if (node.has_Uuid_1())
        SET_FIELD(Uuid_1, node.m_Uuid_1.toString());
    if (node.has_Uuid_2())
        SET_FIELD(Uuid_2, node.m_Uuid_2.toString());
    if (node.has_Uuid_3())
        SET_FIELD(Uuid_3, node.m_Uuid_3.toString());
    if (node.has_Uuid_4())
        SET_FIELD(Uuid_4, node.m_Uuid_4.toString());
    if (node.has_String64_1())
        SET_FIELD(String64_1, node.m_String64_1);
    if (node.has_String64_2())
        SET_FIELD(String64_2, node.m_String64_2);
    if (node.has_String64_3())
        SET_FIELD(String64_3, node.m_String64_3);
    if (node.has_String64_4())
        SET_FIELD(String64_4, node.m_String64_4);
    if (node.has_String64_5())
        SET_FIELD(String64_5, node.m_String64_5);
    if (node.has_String64_6())
        SET_FIELD(String64_6, node.m_String64_6);
    if (node.has_IString64_1())
        SET_FIELD(IString64_1, node.m_IString64_1);
    if (node.has_IString64_2())
        SET_FIELD(IString64_2, node.m_IString64_2);
    if (node.has_Text_1())
        SET_FIELD(Text_1, node.m_Text_1);
    if (node.has_Text_2())
        SET_FIELD(Text_2, node.m_Text_2);
    if (node.has_Blob_1())
        SET_FIELD(Blob_1, DS::Base64Encode(node.m_Blob_1.buffer(), node.m_Blob_1.size()));
    if (node.has_Blob_2())
        SET_FIELD(Blob_2, DS::Base64Encode(node.m_Blob_2.buffer(), node.m_Blob_2.size()));
    #undef SET_FIELD

    DS_DASSERT(fieldp - fieldbuf < 1024);
    *(fieldp - 1) = ')';    // Get rid of the last comma
    DS::String queryStr = "INSERT INTO vault.\"Nodes\" (";
    queryStr += fieldbuf;

    fieldp = fieldbuf;
    for (size_t i=0; i<parmcount; ++i) {
        sprintf(fieldp, "$%Zu,", i+1);
        fieldp += strlen(fieldp);
    }
    DS_DASSERT(fieldp - fieldbuf < 1024);
    *(fieldp - 1) = ')';    // Get rid of the last comma
    queryStr += "\n    VALUES (";
    queryStr += fieldbuf;
    queryStr += "\n    RETURNING idx";

    check_postgres();
    PGresult* result = PQexecParams(s_postgres, queryStr.c_str(),
                                    parmcount, 0, parms.m_values, 0, 0, 0);
    if (PQresultStatus(result) != PGRES_TUPLES_OK) {
        fprintf(stderr, "%s:%d:\n    Postgres INSERT error: %s\n",
                __FILE__, __LINE__, PQerrorMessage(s_postgres));
        PQclear(result);
        return 0;
    }
    DS_DASSERT(PQntuples(result) == 1);
    uint32_t idx = strtoul(PQgetvalue(result, 0, 0), 0, 10);
    PQclear(result);
    return idx;
}
Example #25
0
bool v_find_nodes(const DS::Vault::Node& nodeTemplate, std::vector<uint32_t>& nodes)
{
    if (nodeTemplate.isNull())
        return false;

    /* This should be plenty to store everything we need without a bunch
     * of dynamic reallocations
     */
    PostgresStrings<31> parms;
    char fieldbuf[1024];

    size_t parmcount = 0;
    char* fieldp = fieldbuf;

    #define SET_FIELD(name, value) \
        { \
            parms.set(parmcount++, value); \
            fieldp += sprintf(fieldp, "\"" #name "\"=$%Zu AND ", parmcount); \
        }
    #define SET_FIELD_I(name, value) \
        { \
            parms.set(parmcount++, value); \
            fieldp += sprintf(fieldp, "LOWER(\"" #name "\")=LOWER($%Zu) AND ", parmcount); \
        }
    if (nodeTemplate.has_CreateTime())
        SET_FIELD(CreateTime, nodeTemplate.m_CreateTime);
    if (nodeTemplate.has_ModifyTime())
        SET_FIELD(ModifyTime, nodeTemplate.m_ModifyTime);
    if (nodeTemplate.has_CreateAgeName())
        SET_FIELD(CreateAgeName, nodeTemplate.m_CreateAgeName);
    if (nodeTemplate.has_CreateAgeUuid())
        SET_FIELD(CreateAgeUuid, nodeTemplate.m_CreateAgeUuid.toString());
    if (nodeTemplate.has_CreatorUuid())
        SET_FIELD(CreatorUuid, nodeTemplate.m_CreatorUuid.toString());
    if (nodeTemplate.has_CreatorIdx())
        SET_FIELD(CreatorIdx, nodeTemplate.m_CreatorIdx);
    if (nodeTemplate.has_NodeType())
        SET_FIELD(NodeType, nodeTemplate.m_NodeType);
    if (nodeTemplate.has_Int32_1())
        SET_FIELD(Int32_1, nodeTemplate.m_Int32_1);
    if (nodeTemplate.has_Int32_2())
        SET_FIELD(Int32_2, nodeTemplate.m_Int32_2);
    if (nodeTemplate.has_Int32_3())
        SET_FIELD(Int32_3, nodeTemplate.m_Int32_3);
    if (nodeTemplate.has_Int32_4())
        SET_FIELD(Int32_4, nodeTemplate.m_Int32_4);
    if (nodeTemplate.has_Uint32_1())
        SET_FIELD(Uint32_1, nodeTemplate.m_Uint32_1);
    if (nodeTemplate.has_Uint32_2())
        SET_FIELD(Uint32_2, nodeTemplate.m_Uint32_2);
    if (nodeTemplate.has_Uint32_3())
        SET_FIELD(Uint32_3, nodeTemplate.m_Uint32_3);
    if (nodeTemplate.has_Uint32_4())
        SET_FIELD(Uint32_4, nodeTemplate.m_Uint32_4);
    if (nodeTemplate.has_Uuid_1())
        SET_FIELD(Uuid_1, nodeTemplate.m_Uuid_1.toString());
    if (nodeTemplate.has_Uuid_2())
        SET_FIELD(Uuid_2, nodeTemplate.m_Uuid_2.toString());
    if (nodeTemplate.has_Uuid_3())
        SET_FIELD(Uuid_3, nodeTemplate.m_Uuid_3.toString());
    if (nodeTemplate.has_Uuid_4())
        SET_FIELD(Uuid_4, nodeTemplate.m_Uuid_4.toString());
    if (nodeTemplate.has_String64_1())
        SET_FIELD(String64_1, nodeTemplate.m_String64_1);
    if (nodeTemplate.has_String64_2())
        SET_FIELD(String64_2, nodeTemplate.m_String64_2);
    if (nodeTemplate.has_String64_3())
        SET_FIELD(String64_3, nodeTemplate.m_String64_3);
    if (nodeTemplate.has_String64_4())
        SET_FIELD(String64_4, nodeTemplate.m_String64_4);
    if (nodeTemplate.has_String64_5())
        SET_FIELD(String64_5, nodeTemplate.m_String64_5);
    if (nodeTemplate.has_String64_6())
        SET_FIELD(String64_6, nodeTemplate.m_String64_6);
    if (nodeTemplate.has_IString64_1())
        SET_FIELD_I(IString64_1, nodeTemplate.m_IString64_1);
    if (nodeTemplate.has_IString64_2())
        SET_FIELD_I(IString64_2, nodeTemplate.m_IString64_2);
    if (nodeTemplate.has_Text_1())
        SET_FIELD(Text_1, nodeTemplate.m_Text_1);
    if (nodeTemplate.has_Text_2())
        SET_FIELD(Text_2, nodeTemplate.m_Text_2);
    if (nodeTemplate.has_Blob_1())
        SET_FIELD(Blob_1, DS::Base64Encode(nodeTemplate.m_Blob_1.buffer(), nodeTemplate.m_Blob_1.size()));
    if (nodeTemplate.has_Blob_2())
        SET_FIELD(Blob_2, DS::Base64Encode(nodeTemplate.m_Blob_2.buffer(), nodeTemplate.m_Blob_2.size()));
    #undef SET_FIELD
    #undef SET_FIELD_I

    DS_DASSERT(parmcount > 0);
    DS_DASSERT(fieldp - fieldbuf < 1024);
    *(fieldp - 5) = 0;  // Get rid of the last ' AND '
    DS::String queryStr = "SELECT idx FROM vault.\"Nodes\"\n    WHERE ";
    queryStr += fieldbuf;

    check_postgres();
    PGresult* result = PQexecParams(s_postgres, queryStr.c_str(),
                                    parmcount, 0, parms.m_values, 0, 0, 0);
    if (PQresultStatus(result) != PGRES_TUPLES_OK) {
        fprintf(stderr, "%s:%d:\n    Postgres SELECT error: %s\n",
                __FILE__, __LINE__, PQerrorMessage(s_postgres));
        PQclear(result);
        return false;
    }

    nodes.resize(PQntuples(result));
    for (size_t i=0; i<nodes.size(); ++i)
        nodes[i] = strtoul(PQgetvalue(result, i, 0), 0, 10);
    PQclear(result);
    return true;
}
Example #26
0
static inline void check_postgres()
{
    if (PQstatus(s_postgres) == CONNECTION_BAD)
        PQreset(s_postgres);
    DS_DASSERT(PQstatus(s_postgres) == CONNECTION_OK);
}
Example #27
0
std::tuple<uint32_t, uint32_t>
v_create_age(AuthServer_AgeInfo age, uint32_t flags)
{
    if (age.m_ageId.isNull())
        age.m_ageId = gen_uuid();
    int seqNumber = age.m_seqNumber;
    if (seqNumber < 0) {
        check_postgres();

        PGresult* result = PQexec(s_postgres, "SELECT nextval('game.\"AgeSeqNumber\"'::regclass)");
        if (PQresultStatus(result) != PGRES_TUPLES_OK) {
            fprintf(stderr, "%s:%d:\n    Postgres SELECT error: %s\n",
                    __FILE__, __LINE__, PQerrorMessage(s_postgres));
            PQclear(result);
            return std::make_pair(0, 0);
        }
        DS_DASSERT(PQntuples(result) == 1);
        seqNumber = strtol(PQgetvalue(result, 0, 0), 0, 10);
        PQclear(result);
    }

    DS::Vault::Node node;
    node.set_NodeType(DS::Vault::e_NodeAge);
    node.set_CreatorUuid(age.m_ageId);
    node.set_Uuid_1(age.m_ageId);
    if (!age.m_parentId.isNull())
        node.set_Uuid_2(age.m_parentId);
    node.set_String64_1(age.m_filename);
    uint32_t ageNode = v_create_node(node);
    if (ageNode == 0)
        return std::make_pair(0, 0);

    // TODO: Global SDL node

    node.clear();
    node.set_NodeType(DS::Vault::e_NodeFolder);
    node.set_CreatorUuid(age.m_ageId);
    node.set_CreatorIdx(ageNode);
    node.set_Int32_1(DS::Vault::e_ChronicleFolder);
    uint32_t chronFolder = v_create_node(node);
    if (chronFolder == 0)
        return std::make_pair(0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodePlayerInfoList);
    node.set_CreatorUuid(age.m_ageId);
    node.set_CreatorIdx(ageNode);
    node.set_Int32_1(DS::Vault::e_PeopleIKnowAboutFolder);
    uint32_t knownFolder = v_create_node(node);
    if (knownFolder == 0)
        return std::make_pair(0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodeAgeInfoList);
    node.set_CreatorUuid(age.m_ageId);
    node.set_CreatorIdx(ageNode);
    node.set_Int32_1(DS::Vault::e_SubAgesFolder);
    uint32_t subAgesFolder = v_create_node(node);
    if (subAgesFolder == 0)
        return std::make_pair(0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodeAgeInfo);
    node.set_CreatorUuid(age.m_ageId);
    node.set_CreatorIdx(ageNode);
    node.set_Int32_1(seqNumber);
    node.set_Int32_2((flags & e_AgePublic) != 0 ? 1 : 0);
    node.set_Int32_3(age.m_language);
    node.set_Uint32_1(ageNode);
    node.set_Uint32_2(0);   // Czar ID
    node.set_Uint32_3(0);   // Flags
    node.set_Uuid_1(age.m_ageId);
    if (!age.m_parentId.isNull())
        node.set_Uuid_2(age.m_parentId);
    node.set_String64_2(age.m_filename);
    if (!age.m_instName.isNull())
        node.set_String64_3(age.m_instName);
    if (!age.m_userName.isEmpty())
        node.set_String64_4(age.m_userName);
    if (!age.m_description.isEmpty())
        node.set_Text_1(age.m_description);
    uint32_t ageInfoNode = v_create_node(node);
    if (ageInfoNode == 0)
        return std::make_pair(0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodeFolder);
    node.set_CreatorUuid(age.m_ageId);
    node.set_CreatorIdx(ageNode);
    node.set_Int32_1(DS::Vault::e_AgeDevicesFolder);
    uint32_t devsFolder = v_create_node(node);
    if (devsFolder == 0)
        return std::make_pair(0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodePlayerInfoList);
    node.set_CreatorUuid(age.m_ageId);
    node.set_CreatorIdx(ageNode);
    node.set_Int32_1(DS::Vault::e_CanVisitFolder);
    uint32_t canVisitList = v_create_node(node);
    if (canVisitList == 0)
        return std::make_pair(0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodeSDL);
    node.set_CreatorUuid(age.m_ageId);
    node.set_CreatorIdx(ageNode);
    node.set_Int32_1(0);
    node.set_String64_1(age.m_filename);
    node.set_Blob_1(gen_default_sdl(age.m_filename));
    uint32_t ageSdlNode = v_create_node(node);
    if (ageSdlNode == 0)
        return std::make_pair(0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodePlayerInfoList);
    node.set_CreatorUuid(age.m_ageId);
    node.set_CreatorIdx(ageNode);
    node.set_Int32_1(DS::Vault::e_AgeOwnersFolder);
    uint32_t ageOwners = v_create_node(node);
    if (ageOwners == 0)
        return std::make_pair(0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodeAgeInfoList);
    node.set_CreatorUuid(age.m_ageId);
    node.set_CreatorIdx(ageNode);
    node.set_Int32_1(DS::Vault::e_ChildAgesFolder);
    uint32_t childAges = v_create_node(node);
    if (childAges == 0)
        return std::make_pair(0, 0);

    if (!v_ref_node(ageNode, s_systemNode, 0))
        return std::make_pair(0, 0);
    if (!v_ref_node(ageNode, chronFolder, 0))
        return std::make_pair(0, 0);
    if (!v_ref_node(ageNode, knownFolder, 0))
        return std::make_pair(0, 0);
    if (!v_ref_node(ageNode, subAgesFolder, 0))
        return std::make_pair(0, 0);
    if (!v_ref_node(ageNode, ageInfoNode, 0))
        return std::make_pair(0, 0);
    if (!v_ref_node(ageNode, devsFolder, 0))
        return std::make_pair(0, 0);
    if (!v_ref_node(ageInfoNode, canVisitList, 0))
        return std::make_pair(0, 0);
    if (!v_ref_node(ageInfoNode, ageSdlNode, 0))
        return std::make_pair(0, 0);
    if (!v_ref_node(ageInfoNode, ageOwners, 0))
        return std::make_pair(0, 0);
    if (!v_ref_node(ageInfoNode, childAges, 0))
        return std::make_pair(0, 0);

    // Register with the server database
    {
        DS::String agedesc = !age.m_description.isEmpty() ? age.m_description
                           : !age.m_instName.isEmpty() ? age.m_instName
                           : age.m_filename;

        PostgresStrings<5> parms;
        parms.set(0, age.m_ageId.toString());
        parms.set(1, age.m_filename);
        parms.set(2, agedesc);
        parms.set(3, ageNode);
        parms.set(4, ageSdlNode);
        PGresult* result = PQexecParams(s_postgres,
                "INSERT INTO game.\"Servers\""
                "    (\"AgeUuid\", \"AgeFilename\", \"DisplayName\", \"AgeIdx\", \"SdlIdx\")"
                "    VALUES ($1, $2, $3, $4, $5)",
                5, 0, parms.m_values, 0, 0, 0);
        if (PQresultStatus(result) != PGRES_COMMAND_OK) {
            fprintf(stderr, "%s:%d:\n    Postgres INSERT error: %s\n",
                    __FILE__, __LINE__, PQerrorMessage(s_postgres));
            PQclear(result);
            return std::make_pair(0, 0);
        }
        PQclear(result);
    }

    return std::make_tuple(ageNode, ageInfoNode);
}
Example #28
0
GameHost_Private* start_game_host(uint32_t ageMcpId)
{
    PGconn* postgres = PQconnectdb(DS::String::Format(
                    "host='%s' port='%s' user='******' password='******' dbname='%s'",
                    DS::Settings::DbHostname(), DS::Settings::DbPort(),
                    DS::Settings::DbUsername(), DS::Settings::DbPassword(),
                    DS::Settings::DbDbaseName()).c_str());
    if (PQstatus(postgres) != CONNECTION_OK) {
        fprintf(stderr, "Error connecting to postgres: %s", PQerrorMessage(postgres));
        PQfinish(postgres);
        return 0;
    }

    PostgresStrings<1> parms;
    parms.set(0, ageMcpId);
    PGresult* result = PQexecParams(postgres,
            "SELECT \"AgeUuid\", \"AgeFilename\", \"AgeIdx\", \"SdlIdx\", \"Temporary\""
            "    FROM game.\"Servers\" WHERE idx=$1",
            1, 0, parms.m_values, 0, 0, 0);
    if (PQresultStatus(result) != PGRES_TUPLES_OK) {
        fprintf(stderr, "%s:%d:\n    Postgres SELECT error: %s\n",
                __FILE__, __LINE__, PQerrorMessage(postgres));
        PQclear(result);
        PQfinish(postgres);
        return 0;
    }
    if (PQntuples(result) == 0) {
        fprintf(stderr, "[Game] Age MCP %u not found\n", ageMcpId);
        PQclear(result);
        PQfinish(postgres);
        return 0;
    } else {
        DS_DASSERT(PQntuples(result) == 1);

        GameHost_Private* host = new GameHost_Private();
        host->m_instanceId = PQgetvalue(result, 0, 0);
        host->m_ageFilename = PQgetvalue(result, 0, 1);
        host->m_ageIdx = strtoul(PQgetvalue(result, 0, 2), 0, 10);
        host->m_gameMaster = 0;
        host->m_serverIdx = ageMcpId;
        host->m_postgres = postgres;
        host->m_temp = strcmp("t", PQgetvalue(result, 0, 4)) == 0;

        // Fetch the age states
        Auth_FetchSDL sdlFetch;
        AuthClient_Private fakeClient;
        sdlFetch.m_client = &fakeClient;
        sdlFetch.m_ageFilename = host->m_ageFilename;
        sdlFetch.m_sdlNodeId = strtoul(PQgetvalue(result, 0, 3), 0, 10);
        PQclear(result);

        s_authChannel.putMessage(e_AuthFetchSDL, reinterpret_cast<void*>(&sdlFetch));
        DS::FifoMessage reply = fakeClient.m_channel.getMessage();
        if (reply.m_messageType != DS::e_NetSuccess) {
            fputs("[Game] Error fetching Age SDL\n", stderr);
            PQfinish(postgres);
            delete host;
            return 0;
        }
        host->m_sdlIdx = sdlFetch.m_sdlNodeId;
        host->m_globalState = sdlFetch.m_globalState;

        // Load the local state and see if it needs to be updated
        try {
            host->m_localState = SDL::State::FromBlob(sdlFetch.m_localState);
        } catch (DS::EofException&) {
            fprintf(stderr, "[SDL] Error parsing Age SDL state for %s\n",
                    host->m_ageFilename.c_str());
            PQfinish(postgres);
            delete host;
            return 0;
        }
        if (host->m_localState.update()) {
            DS::Blob local = host->m_localState.toBlob();
            dm_local_sdl_update(host, local);
            host->m_ageSdlHook = SDL::State::FromBlob(local);
        } else {
            host->m_ageSdlHook = SDL::State::FromBlob(sdlFetch.m_localState);
        }
        host->m_ageSdlHook.merge(host->m_globalState);

        s_gameHostMutex.lock();
        s_gameHosts[ageMcpId] = host;
        s_gameHostMutex.unlock();

        // Fetch initial server state
        PostgresStrings<1> parms;
        parms.set(0, host->m_serverIdx);
        PGresult* result = PQexecParams(host->m_postgres,
                "SELECT \"Descriptor\", \"ObjectKey\", \"SdlBlob\""
                "    FROM game.\"AgeStates\" WHERE \"ServerIdx\"=$1",
                1, 0, parms.m_values, 0, 0, 0);
        if (PQresultStatus(result) != PGRES_TUPLES_OK) {
            fprintf(stderr, "%s:%d:\n    Postgres SELECT error: %s\n",
                    __FILE__, __LINE__, PQerrorMessage(host->m_postgres));
        } else {
            int count = PQntuples(result);

            for (int i=0; i<count; ++i) {
                DS::BlobStream bsObject(DS::Base64Decode(PQgetvalue(result, i, 1)));
                DS::Blob sdlblob = DS::Base64Decode(PQgetvalue(result, i, 2));
                MOUL::Uoid key;
                key.read(&bsObject);
                try {
                    SDL::State state = SDL::State::FromBlob(sdlblob);
                    state.update();

                    GameState gs;
                    gs.m_isAvatar = false;
                    gs.m_persist = true;
                    gs.m_state = state;
                    host->m_states[key][PQgetvalue(result, i, 0)] = gs;
                } catch (DS::EofException) {
                    fprintf(stderr, "[SDL] Error parsing state %s for [%04X]%s\n",
                            PQgetvalue(result, i, 0), key.m_type, key.m_name.c_str());
                }
            }
        }
        PQclear(result);

        std::thread threadh(&dm_gameHost, host);
        threadh.detach();
        return host;
    }
}
Example #29
0
std::tuple<uint32_t, uint32_t, uint32_t>
v_create_player(DS::Uuid acctId, const AuthServer_PlayerInfo& player)
{
    DS::Vault::Node node;
    node.set_NodeType(DS::Vault::e_NodePlayer);
    node.set_CreatorUuid(acctId);
    node.set_Int32_2(player.m_explorer);
    node.set_Uuid_1(acctId);
    node.set_String64_1(player.m_avatarModel);
    node.set_IString64_1(player.m_playerName);
    uint32_t playerIdx = v_create_node(node);
    if (playerIdx == 0)
        return std::make_tuple(0, 0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodePlayerInfo);
    node.set_CreatorUuid(acctId);
    node.set_CreatorIdx(playerIdx);
    node.set_Uint32_1(playerIdx);
    node.set_IString64_1(player.m_playerName);
    uint32_t playerInfoNode = v_create_node(node);
    if (playerInfoNode == 0)
        return std::make_tuple(0, 0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodePlayerInfoList);
    node.set_CreatorUuid(acctId);
    node.set_CreatorIdx(playerIdx);
    node.set_Int32_1(DS::Vault::e_BuddyListFolder);
    uint32_t buddyList = v_create_node(node);
    if (buddyList == 0)
        return std::make_tuple(0, 0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodePlayerInfoList);
    node.set_CreatorUuid(acctId);
    node.set_CreatorIdx(playerIdx);
    node.set_Int32_1(DS::Vault::e_IgnoreListFolder);
    uint32_t ignoreList = v_create_node(node);
    if (ignoreList == 0)
        return std::make_tuple(0, 0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodeFolder);
    node.set_CreatorUuid(acctId);
    node.set_CreatorIdx(playerIdx);
    node.set_Int32_1(DS::Vault::e_PlayerInviteFolder);
    uint32_t invites = v_create_node(node);
    if (invites == 0)
        return std::make_tuple(0, 0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodeAgeInfoList);
    node.set_CreatorUuid(acctId);
    node.set_CreatorIdx(playerIdx);
    node.set_Int32_1(DS::Vault::e_AgesIOwnFolder);
    uint32_t agesNode = v_create_node(node);
    if (agesNode == 0)
        return std::make_tuple(0, 0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodeFolder);
    node.set_CreatorUuid(acctId);
    node.set_CreatorIdx(playerIdx);
    node.set_Int32_1(DS::Vault::e_AgeJournalsFolder);
    uint32_t journals = v_create_node(node);
    if (journals == 0)
        return std::make_tuple(0, 0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodeFolder);
    node.set_CreatorUuid(acctId);
    node.set_CreatorIdx(playerIdx);
    node.set_Int32_1(DS::Vault::e_ChronicleFolder);
    uint32_t chronicles = v_create_node(node);
    if (chronicles == 0)
        return std::make_tuple(0, 0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodeAgeInfoList);
    node.set_CreatorUuid(acctId);
    node.set_CreatorIdx(playerIdx);
    node.set_Int32_1(DS::Vault::e_AgesICanVisitFolder);
    uint32_t visitFolder = v_create_node(node);
    if (visitFolder == 0)
        return std::make_tuple(0, 0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodeFolder);
    node.set_CreatorUuid(acctId);
    node.set_CreatorIdx(playerIdx);
    node.set_Int32_1(DS::Vault::e_AvatarOutfitFolder);
    uint32_t outfit = v_create_node(node);
    if (outfit == 0)
        return std::make_tuple(0, 0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodeFolder);
    node.set_CreatorUuid(acctId);
    node.set_CreatorIdx(playerIdx);
    node.set_Int32_1(DS::Vault::e_AvatarClosetFolder);
    uint32_t closet = v_create_node(node);
    if (closet == 0)
        return std::make_tuple(0, 0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodeFolder);
    node.set_CreatorUuid(acctId);
    node.set_CreatorIdx(playerIdx);
    node.set_Int32_1(DS::Vault::e_InboxFolder);
    uint32_t inbox = v_create_node(node);
    if (inbox == 0)
        return std::make_tuple(0, 0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodePlayerInfoList);
    node.set_CreatorUuid(acctId);
    node.set_CreatorIdx(playerIdx);
    node.set_Int32_1(DS::Vault::e_PeopleIKnowAboutFolder);
    uint32_t peopleNode = v_create_node(node);
    if (peopleNode == 0)
        return std::make_tuple(0, 0, 0);

    DS::Blob link(reinterpret_cast<const uint8_t*>("Default:LinkInPointDefault:;"),
                  strlen("Default:LinkInPointDefault:;"));
    node.clear();
    node.set_NodeType(DS::Vault::e_NodeAgeLink);
    node.set_CreatorUuid(acctId);
    node.set_CreatorIdx(playerIdx);
    node.set_Blob_1(link);
    uint32_t reltoLink = v_create_node(node);
    if (reltoLink == 0)
        return std::make_tuple(0, 0, 0);

    node.clear();
    node.set_NodeType(DS::Vault::e_NodeAgeLink);
    node.set_CreatorUuid(acctId);
    node.set_CreatorIdx(playerIdx);
    node.set_Blob_1(link);
    uint32_t hoodLink = v_create_node(node);
    if (hoodLink == 0)
        return std::make_tuple(0, 0, 0);

    link = DS::Blob(reinterpret_cast<const uint8_t*>("Ferry Terminal:LinkInPointFerry:;"),
                    strlen("Ferry Terminal:LinkInPointFerry:;"));
    node.clear();
    node.set_NodeType(DS::Vault::e_NodeAgeLink);
    node.set_CreatorUuid(acctId);
    node.set_CreatorIdx(playerIdx);
    node.set_Blob_1(link);
    uint32_t cityLink = v_create_node(node);
    if (hoodLink == 0)
        return std::make_tuple(0, 0, 0);

    AuthServer_AgeInfo relto;
    relto.m_ageId = gen_uuid();
    relto.m_filename = "Personal";
    relto.m_instName = "Relto";
    relto.m_userName = player.m_playerName + "'s";
    relto.m_description = relto.m_userName + " " + relto.m_instName;
    std::tuple<uint32_t, uint32_t> reltoAge = v_create_age(relto, 0);
    if (std::get<0>(reltoAge) == 0)
        return std::make_tuple(0, 0, 0);

    {
        PostgresStrings<2> parms;
        parms.set(0, std::get<1>(reltoAge));
        parms.set(1, DS::Vault::e_AgeOwnersFolder);
        PGresult* result = PQexecParams(s_postgres,
                "SELECT idx FROM vault.find_folder($1, $2);",
                2, 0, parms.m_values, 0, 0, 0);
        if (PQresultStatus(result) != PGRES_TUPLES_OK) {
            fprintf(stderr, "%s:%d:\n    Postgres SELECT error: %s\n",
                    __FILE__, __LINE__, PQerrorMessage(s_postgres));
            PQclear(result);
            return std::make_tuple(0, 0, 0);
        }
        DS_DASSERT(PQntuples(result) == 1);
        uint32_t ownerFolder = strtoul(PQgetvalue(result, 0, 0), 0, 10);
        PQclear(result);

        if (!v_ref_node(ownerFolder, playerInfoNode, 0))
            return std::make_tuple(0, 0, 0);
    }

    std::tuple<uint32_t, uint32_t> hoodAge =
        find_a_friendly_neighborhood_for_our_new_visitor();
    if (std::get<0>(hoodAge) == 0)
        return std::make_tuple(0, 0, 0);
    uint32_t cityAge = find_public_age_1("city");
    if (cityAge == 0)
        return std::make_tuple(0, 0, 0);

    if (!v_ref_node(playerIdx, s_systemNode, 0))
        return std::make_tuple(0, 0, 0);
    if (!v_ref_node(playerIdx, playerInfoNode, 0))
        return std::make_tuple(0, 0, 0);
    if (!v_ref_node(playerIdx, buddyList, 0))
        return std::make_tuple(0, 0, 0);
    if (!v_ref_node(playerIdx, ignoreList, 0))
        return std::make_tuple(0, 0, 0);
    if (!v_ref_node(playerIdx, invites, 0))
        return std::make_tuple(0, 0, 0);
    if (!v_ref_node(playerIdx, agesNode, 0))
        return std::make_tuple(0, 0, 0);
    if (!v_ref_node(playerIdx, journals, 0))
        return std::make_tuple(0, 0, 0);
    if (!v_ref_node(playerIdx, chronicles, 0))
        return std::make_tuple(0, 0, 0);
    if (!v_ref_node(playerIdx, visitFolder, 0))
        return std::make_tuple(0, 0, 0);
    if (!v_ref_node(playerIdx, outfit, 0))
        return std::make_tuple(0, 0, 0);
    if (!v_ref_node(playerIdx, closet, 0))
        return std::make_tuple(0, 0, 0);
    if (!v_ref_node(playerIdx, inbox, 0))
        return std::make_tuple(0, 0, 0);
    if (!v_ref_node(playerIdx, peopleNode, 0))
        return std::make_tuple(0, 0, 0);
    if (!v_ref_node(agesNode, reltoLink, 0))
        return std::make_tuple(0, 0, 0);
    if (!v_ref_node(agesNode, hoodLink, 0))
        return std::make_tuple(0, 0, 0);
    if (!v_ref_node(agesNode, cityLink, 0))
        return std::make_tuple(0, 0, 0);
    if (!v_ref_node(reltoLink, std::get<1>(reltoAge), 0))
        return std::make_tuple(0, 0, 0);
    if (!v_ref_node(hoodLink, std::get<0>(hoodAge), 0))
        return std::make_tuple(0, 0, 0);
    if (!v_ref_node(cityLink, cityAge, 0))
        return std::make_tuple(0, 0, 0);
    if (!v_ref_node(std::get<0>(reltoAge), agesNode, 0))
        return std::make_tuple(0, 0, 0);

    return std::make_tuple(playerIdx, playerInfoNode, std::get<1>(hoodAge));
}
Example #30
0
bool dm_vault_init()
{
    PostgresStrings<1> sparm;
    sparm.set(0, DS::Vault::e_NodeSystem);
    PGresult* result = PQexecParams(s_postgres,
            "SELECT \"idx\" FROM vault.\"Nodes\""
            "    WHERE \"NodeType\"=$1",
            1, 0, sparm.m_values, 0, 0, 0);
    if (PQresultStatus(result) != PGRES_TUPLES_OK) {
        fprintf(stderr, "%s:%d:\n    Postgres SELECT error: %s\n",
                __FILE__, __LINE__, PQerrorMessage(s_postgres));
        PQclear(result);
        return false;
    }

    int count = PQntuples(result);
    if (count == 0) {
        PQclear(result);

        fprintf(stderr, "[Vault] Initializing empty DirtSand vault\n");

        // Create system and global inbox nodes
        DS::Vault::Node node;
        node.set_NodeType(DS::Vault::e_NodeSystem);
        s_systemNode = v_create_node(node);
        if (s_systemNode == 0)
            return false;

        node.set_NodeType(DS::Vault::e_NodeFolder);
        node.set_Int32_1(DS::Vault::e_GlobalInboxFolder);
        uint32_t globalInbox = v_create_node(node);
        if (globalInbox == 0)
            return false;

        if (!v_ref_node(s_systemNode, globalInbox, 0))
            return false;

        AuthServer_AgeInfo age;
        age.m_ageId = gen_uuid();
        age.m_filename = "city";
        age.m_instName = "Ae'gura";
        if (v_create_age(age, e_AgePublic).first == 0)
            return false;

        age.m_ageId = gen_uuid();
        age.m_filename = "Neighborhood02";
        age.m_instName = "Kirel";
        if (v_create_age(age, e_AgePublic).first == 0)
            return false;

        age.m_ageId = gen_uuid();
        age.m_filename = "Kveer";
        age.m_instName = "K'veer";
        if (v_create_age(age, e_AgePublic).first == 0)
            return false;

        age.m_ageId = gen_uuid();
        age.m_filename = "GreatTreePub";
        age.m_instName = "The Watcher's Pub";
        if (v_create_age(age, e_AgePublic).first == 0)
            return false;

        age.m_ageId = gen_uuid();
        age.m_filename = "GuildPub-Cartographers";
        age.m_instName = "The Cartographers' Guild Pub";
        if (v_create_age(age, e_AgePublic).first == 0)
            return false;

        age.m_ageId = gen_uuid();
        age.m_filename = "GuildPub-Greeters";
        age.m_instName = "The Greeters' Guild Pub";
        if (v_create_age(age, e_AgePublic).first == 0)
            return false;

        age.m_ageId = gen_uuid();
        age.m_filename = "GuildPub-Maintainers";
        age.m_instName = "The Maintainers' Guild Pub";
        if (v_create_age(age, e_AgePublic).first == 0)
            return false;

        age.m_ageId = gen_uuid();
        age.m_filename = "GuildPub-Messengers";
        age.m_instName = "The Messengers' Guild Pub";
        if (v_create_age(age, e_AgePublic).first == 0)
            return false;

        age.m_ageId = gen_uuid();
        age.m_filename = "GuildPub-Writers";
        age.m_instName = "The Writers' Guild Pub";
        if (v_create_age(age, e_AgePublic).first == 0)
            return false;
    } else {
        DS_DASSERT(count == 1);
        s_systemNode = strtoul(PQgetvalue(result, 0, 0), 0, 10);
        PQclear(result);
    }

    return true;
}