Пример #1
0
bool redisUpdateAccountSession(Redis *self, RedisAccountSessionKey *key, AccountSession *accountSession) {

    redisReply *reply = NULL;

    dbg("HMSET accountId%llx"
        " " REDIS_ACCOUNT_SESSION_credits_str " %f"
        " " REDIS_ACCOUNT_SESSION_privilegeLevel_str " %x"
        " " REDIS_ACCOUNT_SESSION_familyName_str " %s"
        " " REDIS_ACCOUNT_SESSION_barrackType_str " %x"
        , key->accountId,
        accountSession->credits,
        accountSession->privilege,
        accountSession->familyName,
        accountSession->barrackType);

    reply = redisCommandDbg(self,
        "HMSET accountId%llx"
        " " REDIS_ACCOUNT_SESSION_credits_str " %f"
        " " REDIS_ACCOUNT_SESSION_privilegeLevel_str " %x"
        " " REDIS_ACCOUNT_SESSION_familyName_str " %s"
        " " REDIS_ACCOUNT_SESSION_barrackType_str " %x"
        , key->accountId,
        accountSession->credits,
        accountSession->privilege,
        CHECK_REDIS_EMPTY_STRING(accountSession->familyName),
        accountSession->barrackType
    );

    if (!reply) {
        error("Redis error encountered : The request is invalid.");
        return false;
    }

    switch (reply->type)
    {
        case REDIS_REPLY_ERROR:
            error("Redis error encountered : %s", reply->str);
            return false;
            break;

        case REDIS_REPLY_STATUS:
            // info("Redis status : %s", reply->str);
            break;

        default :
            error("Unexpected Redis status : %d", reply->type);
            redisReplyDestroy(&reply);
            return false;
            break;
    }

    redisReplyDestroy(&reply);

    return true;
}
Пример #2
0
bool redisGetAccountSession(Redis *self, RedisAccountSessionKey *key, AccountSession *accountSession) {

    bool result = false;
    redisReply *reply = NULL;

    reply = redisCommandDbg(self,
        "HMGET zone%x:map%x:acc%llx"
        " " REDIS_SESSION_account_accountName_str
        " " REDIS_SESSION_account_sessionKey_str
        " " REDIS_SESSION_account_privilege_str
        " " REDIS_SESSION_account_commandersCountMax_str
        , key->routerId, key->mapId, key->accountId
    );

    if (!reply) {
        error("Redis error encountered : The request is invalid.");
        goto cleanup;
    }

    switch (reply->type)
    {
        case REDIS_REPLY_ERROR:
            error("Redis error encountered : %s", reply->str);
            goto cleanup;
            break;

        case REDIS_REPLY_ARRAY: {
            // Check if any element of the reply is NULL
            size_t elementIndex;
            if ((elementIndex = redisAnyElementIsNull (reply->element, reply->elements)) != -1) {
                error("Element <%s> returned by Redis is NULL.", redisAccountSessionsStr[elementIndex]);
                goto cleanup;
            }

            /// Write the reply to the session
            COPY_REDIS_ACCOUNT_STR(accountSession->accountName, accountName);
            COPY_REDIS_ACCOUNT_STR(accountSession->sessionKey, sessionKey);
            accountSession->privilege = GET_REDIS_ACCOUNT_32(privilege);
            accountSession->commandersCountMax = GET_REDIS_ACCOUNT_32(commandersCountMax);
        }
        break;

        default :
            error("Unexpected Redis status (%d).", reply->type);
            goto cleanup;
            break;
    }

    result = true;

cleanup:
    if (reply) {
        redisReplyDestroy(&reply);
    }

    return result;
}
Пример #3
0
bool redisFlushAccountSession(Redis *self, RedisAccountSessionKey *key) {

    redisReply *reply = NULL;

    // Delete the key from the Redis
    reply = redisCommandDbg(self,
        "DEL accountId%llx",
        key->accountId
    );

    if (!reply) {
        error("Redis error encountered : The request is invalid.");
        return false;
    }

    switch (reply->type)
    {
        case REDIS_REPLY_ERROR:
            error("Redis error encountered : %s", reply->str);
            return false;
            break;

        case REDIS_REPLY_INTEGER:
            // Delete OK
            break;

        default :
            error("Unexpected Redis status : %d", reply->type);
            redisReplyDestroy(&reply);
            return false;
            break;
    }

    redisReplyDestroy(&reply);

    return true;
}
Пример #4
0
bool redisMoveGameSession (Redis *self, RedisGameSessionKey *from, RedisGameSessionKey *to) {
    bool result = true;
    redisReply *reply = NULL;

    reply = redisCommandDbg(self,
        "RENAME "
        "zone%x:map%x:acc%llx "
        "zone%x:map%x:acc%llx",
        from->routerId, from->mapId, from->accountId,
          to->routerId,   to->mapId,   to->accountId
    );

    if (!reply) {
        error("Redis error encountered : The request is invalid.");
        result = false;
        goto cleanup;
    }

    switch (reply->type)
    {
        case REDIS_REPLY_ERROR:
            error("Redis error encountered : %s", reply->str);
            result = false;
            goto cleanup;
            break;

        case REDIS_REPLY_STATUS:
            // info("Redis status : %s", reply->str);
            break;

        default :
            error("Unexpected Redis status. (%d)", reply->type);
            result = false;
            goto cleanup;
            break;
    }

cleanup:
    if (reply) {
        redisReplyDestroy(&reply);
    }

    return result;
}
Пример #5
0
// ------ Extern functions implementation -------
bool redisGetAccountSession(Redis *self, RedisAccountSessionKey *key, AccountSession *accountSession) {

	redisReply *reply = NULL;

	reply = redisCommandDbg(self,
        "HMGET accountId%llx "
        REDIS_ACCOUNT_SESSION_credits_str " "
        REDIS_ACCOUNT_SESSION_privilegeLevel_str " "
        REDIS_ACCOUNT_SESSION_familyName_str " "
        REDIS_ACCOUNT_SESSION_barrackType_str " ",
        key->accountId
    );

    if (!reply) {
        error("Redis error encountered : The request is invalid.");
        return false;
    }

    switch (reply->type)
    {
        case REDIS_REPLY_ERROR:
            error("Redis error encountered : %s", reply->str);
            redisReplyDestroy(&reply);
            return false;
            break;

        case REDIS_REPLY_STATUS:
            // info("Redis status : %s", reply->str);
            redisReplyDestroy(&reply);
            return false;
            break;

        case REDIS_REPLY_ARRAY:
            if (reply->elements != REDIS_ACCOUNT_SESSION_COUNT) {
                error("Wrong number of elements received.");
                redisReplyDestroy(&reply);
                return false;
            }

            if (redisAnyElementIsNull (reply->element, reply->elements) != -1) {
                // AccountSession not found
                return false;
            }
            else {
                // Read the socket Session from the Redis server
                accountSession->accountId = key->accountId;
                accountSession->credits = strtof(reply->element[REDIS_ACCOUNT_SESSION_credits]->str, NULL);
                accountSession->privilege = strtoul(reply->element[REDIS_ACCOUNT_SESSION_privilegeLevel]->str, NULL, 16);
                strncpy(accountSession->familyName, reply->element[REDIS_ACCOUNT_SESSION_familyName]->str, sizeof(accountSession->familyName));
                accountSession->barrackType = strtoul(reply->element[REDIS_ACCOUNT_SESSION_barrackType]->str, NULL, 16);

            }
        break;

        default :
            error("Unexpected Redis status : %d", reply->type);
            redisReplyDestroy(&reply);
            return false;
            break;
    }

    redisReplyDestroy(&reply);

    return true;
}
Пример #6
0
bool redisGetGameSession(Redis *self, RedisGameSessionKey *key, GameSession *gameSession) {
    bool result = true;
    redisReply *reply = NULL;

    reply = redisCommandDbg(self,
        "HMGET zone%x:map%x:acc%llx"
        /** Keep these fields in the same order than the RedisGameSessionFields fields one */
        // Account
        " " REDIS_GAME_SESSION_account_login_str
        " " REDIS_GAME_SESSION_account_sessionKey_str
        " " REDIS_GAME_SESSION_account_privilege_str
        // Barrack
        " " REDIS_GAME_SESSION_barrack_charactersCreatedCount_str
        // Commander
        " " REDIS_GAME_SESSION_commander_mapId_str
        " " REDIS_GAME_SESSION_commander_commanderName_str
        " " REDIS_GAME_SESSION_commander_familyName_str
        " " REDIS_GAME_SESSION_commander_accountId_str
        " " REDIS_GAME_SESSION_commander_classId_str
        " " REDIS_GAME_SESSION_commander_unk4_str
        " " REDIS_GAME_SESSION_commander_jobId_str
        " " REDIS_GAME_SESSION_commander_gender_str
        " " REDIS_GAME_SESSION_commander_unk5_str
        " " REDIS_GAME_SESSION_commander_level_str
        " " REDIS_GAME_SESSION_commander_hairId_str
        " " REDIS_GAME_SESSION_commander_pose_str
        // Equipment
        " " REDIS_GAME_SESSION_equipment_head_top_str
        " " REDIS_GAME_SESSION_equipment_head_middle_str
        " " REDIS_GAME_SESSION_equipment_itemUnk1_str
        " " REDIS_GAME_SESSION_equipment_body_armor_str
        " " REDIS_GAME_SESSION_equipment_gloves_str
        " " REDIS_GAME_SESSION_equipment_boots_str
        " " REDIS_GAME_SESSION_equipment_itemUnk2_str
        " " REDIS_GAME_SESSION_equipment_bracelet_str
        " " REDIS_GAME_SESSION_equipment_weapon_str
        " " REDIS_GAME_SESSION_equipment_shield_str
        " " REDIS_GAME_SESSION_equipment_costume_str
        " " REDIS_GAME_SESSION_equipment_itemUnk3_str
        " " REDIS_GAME_SESSION_equipment_itemUnk4_str
        " " REDIS_GAME_SESSION_equipment_itemUnk5_str
        " " REDIS_GAME_SESSION_equipment_leg_armor_str
        " " REDIS_GAME_SESSION_equipment_itemUnk6_str
        " " REDIS_GAME_SESSION_equipment_itemUnk7_str
        " " REDIS_GAME_SESSION_equipment_ring_left_str
        " " REDIS_GAME_SESSION_equipment_ring_right_str
        " " REDIS_GAME_SESSION_equipment_necklace_str
        // CommanderInfo Info
        " " REDIS_GAME_SESSION_info_posX_str
        " " REDIS_GAME_SESSION_info_posY_str
        " " REDIS_GAME_SESSION_info_posZ_str
        " " REDIS_GAME_SESSION_info_currentXP_str
        " " REDIS_GAME_SESSION_info_maxXP_str
        " " REDIS_GAME_SESSION_info_pcId_str
        " " REDIS_GAME_SESSION_info_socialInfoId_str
        " " REDIS_GAME_SESSION_info_commanderId_str
        " " REDIS_GAME_SESSION_info_currentHP_str
        " " REDIS_GAME_SESSION_info_maxHP_str
        " " REDIS_GAME_SESSION_info_currentSP_str
        " " REDIS_GAME_SESSION_info_maxSP_str
        " " REDIS_GAME_SESSION_info_currentStamina_str
        " " REDIS_GAME_SESSION_info_maxStamina_str
        " " REDIS_GAME_SESSION_info_unk6_str
        " " REDIS_GAME_SESSION_info_unk7_str

        , key->routerId, key->mapId, key->accountId
    );

    if (!reply) {
        error("Redis error encountered : The request is invalid.");
        result = false;
        goto cleanup;
    }

    switch (reply->type)
    {
        case REDIS_REPLY_ERROR:
            error("Redis error encountered : %s", reply->str);
            result = false;
            goto cleanup;
            break;

        case REDIS_REPLY_STATUS:
            // info("Redis status : %s", reply->str);
            break;

        case REDIS_REPLY_ARRAY: {
            // Check the number of elements retrieved
            if (reply->elements != REDIS_GAME_SESSION_COUNT) {
                error("Wrong number of elements received.");
                result = false;
                goto cleanup;
            }

            // Check if any element of the reply is NULL
            size_t elementIndex;
            if ((elementIndex = redisAnyElementIsNull (reply->element, reply->elements)) != -1) {
                error("Element <%s> returned by Redis is NULL.", redisGameSessionsStr[elementIndex]);
                result = false;
                goto cleanup;
            }

            /// Write the reply to the session
            CommanderSession *commanderSession = &gameSession->commanderSession;
            CommanderInfo *cInfo = &commanderSession->currentCommander.info;
            CommanderAppearance *appearance = &cInfo->appearance;
            CommanderEquipment *equipment = &appearance->equipment;

            // Account
            COPY_REDIS_STR(gameSession->accountSession.login, account_login);
            COPY_REDIS_STR(gameSession->accountSession.sessionKey, account_sessionKey);
            gameSession->accountSession.privilege = GET_REDIS_32(account_privilege);

            // Barrack
            gameSession->barrackSession.charactersCreatedCount = GET_REDIS_32(barrack_charactersCreatedCount);

            // Commander
            commanderSession->mapId = GET_REDIS_32(commander_mapId);
            COPY_REDIS_STR(appearance->commanderName, commander_commanderName);
            COPY_REDIS_STR(appearance->familyName, commander_familyName);
            appearance->accountId = GET_REDIS_64 (commander_accountId);
            appearance->classId   = GET_REDIS_32(commander_classId);
            appearance->unk4      = GET_REDIS_32(commander_unk4);
            appearance->jobId     = GET_REDIS_32(commander_jobId);
            appearance->gender    = GET_REDIS_32(commander_gender);
            appearance->unk5      = GET_REDIS_32(commander_unk5);
            appearance->level     = GET_REDIS_32(commander_level);
            appearance->hairId    = GET_REDIS_32(commander_hairId);
            appearance->pose      = GET_REDIS_32(commander_pose);

            // Equipment
            equipment->head_top    = GET_REDIS_32(equipment_head_top);
            equipment->head_middle = GET_REDIS_32(equipment_head_middle);
            equipment->itemUnk1    = GET_REDIS_32(equipment_itemUnk1);
            equipment->body_armor  = GET_REDIS_32(equipment_body_armor);
            equipment->gloves      = GET_REDIS_32(equipment_gloves);
            equipment->boots       = GET_REDIS_32(equipment_boots);
            equipment->itemUnk2    = GET_REDIS_32(equipment_itemUnk2);
            equipment->bracelet    = GET_REDIS_32(equipment_bracelet);
            equipment->weapon      = GET_REDIS_32(equipment_weapon);
            equipment->shield      = GET_REDIS_32(equipment_shield);
            equipment->costume     = GET_REDIS_32(equipment_costume);
            equipment->itemUnk3    = GET_REDIS_32(equipment_itemUnk3);
            equipment->itemUnk4    = GET_REDIS_32(equipment_itemUnk4);
            equipment->itemUnk5    = GET_REDIS_32(equipment_itemUnk5);
            equipment->leg_armor   = GET_REDIS_32(equipment_leg_armor);
            equipment->itemUnk6    = GET_REDIS_32(equipment_itemUnk6);
            equipment->itemUnk7    = GET_REDIS_32(equipment_itemUnk7);
            equipment->ring_left   = GET_REDIS_32(equipment_ring_left);
            equipment->ring_right  = GET_REDIS_32(equipment_ring_right);
            equipment->necklace    = GET_REDIS_32(equipment_necklace);

            // CommanderInfo info
            cInfo->pos.x = GET_REDIS_FLOAT (info_posX);
            cInfo->pos.y = GET_REDIS_FLOAT (info_posY);
            cInfo->pos.z = GET_REDIS_FLOAT (info_posZ);
            cInfo->currentXP = GET_REDIS_32(info_currentXP);
            cInfo->maxXP = GET_REDIS_32(info_maxXP);
            cInfo->pcId = GET_REDIS_32(info_pcId);
            cInfo->socialInfoId = GET_REDIS_64 (info_socialInfoId);
            cInfo->commanderId = GET_REDIS_64 (info_commanderId);
            cInfo->currentHP = GET_REDIS_32(info_currentHP);
            cInfo->maxHP = GET_REDIS_32(info_maxHP);
            cInfo->currentSP = GET_REDIS_32(info_currentSP);
            cInfo->maxSP = GET_REDIS_32(info_maxSP);
            cInfo->currentStamina = GET_REDIS_32(info_currentStamina);
            cInfo->maxStamina = GET_REDIS_32(info_maxStamina);
            cInfo->unk6 = GET_REDIS_32(info_unk6);
            cInfo->unk7 = GET_REDIS_32(info_unk7);

            #undef COPY_REDIS_STR
            #undef GET_REDIS_32
            #undef GET_REDIS_64
            #undef GET_REDIS_FLOAT
        }
        break;

        default :
            error("Unexpected Redis status (%d).", reply->type);
            result = false;
            goto cleanup;
            break;
    }

cleanup:
    if (reply) {
        redisReplyDestroy(&reply);
    }

    return result;
}
Пример #7
0
zlist_t *redisGetClientsWithinDistance (
    Redis *self,
    uint16_t routerId, uint16_t mapId,
    PositionXZ *center,
    float range,
    char *ignoredSessionKey
) {
    bool status = true;
    zlist_t *clients = NULL;
    redisReply *reply = NULL;
    redisReply *posReply = NULL;

    // TODO : Could be better. Don't allocate a new zlist everytime we call this function.
    // Who got this list then ? The Worker?
    if (!(clients = zlist_new())) {
        error("Cannot allocate a new zlist.");
        status = false;
        goto cleanup;
    }

    // Iterate through all the clients

    // TODO : Huge optimization to do here !
    // It iterates through all the clients of the zone server in the chosen map
    // It could use a better clustering method, but it should be enough for the moment

    // Start iterating
    int iterator = 0;

    do {
        // Get all the accounts within the same area
        reply = redisCommandDbg(self,
            "SCAN %d MATCH zone%x:map%x:acc*",
            iterator, routerId, mapId
        );

        if (!reply) {
            error("Redis error encountered : The request is invalid.");
            status = false;
            goto cleanup;
        }

        switch (reply->type) {
            case REDIS_REPLY_ERROR:
                error("Redis error encountered : %s", reply->str);
                status = false;
                goto cleanup;
                break;

            case REDIS_REPLY_ARRAY: {
                // [0] = new iterator
                iterator = strtoul(reply->element[0]->str, NULL, 10);
                // [1] = results
                for (int i = 0; i < reply->element[1]->elements; i++) {
                    // Get the position of all accounts in the map
                    posReply = redisCommandDbg(self,
                        "HMGET %s " REDIS_GAME_SESSION_info_posX_str
                                " " REDIS_GAME_SESSION_info_posZ_str // Get position
                                " " REDIS_GAME_SESSION_account_sessionKey_str, // SocketKey
                        reply->element[1]->element[i]->str // account key
                    );

                    if (!posReply) {
                        error("Redis error encountered : The request is invalid.");
                        status = false;
                        goto cleanup;
                    }

                    switch (posReply->type) {

                        case REDIS_REPLY_ERROR:
                            error("Redis error encountered : %s", reply->str);
                            status = false;
                            goto cleanup;
                            break;

                        case REDIS_REPLY_STATUS:
                            // info("Redis status : %s", reply->str);
                            break;

                        case REDIS_REPLY_ARRAY: {
                            if (posReply->elements != 3) {
                                error("Abnormal number of elements (%d, should be 3).", posReply->elements);
                                status = false;
                                goto cleanup;
                            }

                            // [0] = X, [1] = Z, [2] = socketId
                            PositionXZ curPpos = {
                                .x = strtof (posReply->element[0]->str, NULL),
                                .z = strtof (posReply->element[1]->str, NULL)
                            };
                            char *socketId = posReply->element[2]->str;

                            // Check range here
                            if (mathIsWithin2DManhattanDistance (&curPpos, center, range)) {
                                // The current client is within the area, add it to the list
                                // Don't include the ignored socketId
                                if (!(ignoredSessionKey && strcmp (socketId, ignoredSessionKey) == 0)) {
                                    zlist_append(clients, strdup(socketId));
                                }
                            }
                        } break;

                        default :
                            error("Unexpected Redis status. (%d)", reply->type);
                            status = false;
                            goto cleanup;
                            break;
                    }

                    redisReplyDestroy(&posReply);
                }
            } break;

            default :
                error("Unexpected Redis status. (%d)", reply->type);
                status = false;
                goto cleanup;
                break;
        }

        redisReplyDestroy(&reply);

    } while (iterator != 0);

cleanup:
    if (!status) {
        zlist_destroy (&clients);
    }
    redisReplyDestroy(&reply);
    redisReplyDestroy(&posReply);

    return clients;
}

bool redisFlushGameSession (Redis *self, RedisGameSessionKey *key) {

    bool result = true;
    redisReply *reply = NULL;

    // Delete the key from the Redis
    reply = redisCommandDbg(self,
        "DEL zone%x:map%x:acc%llx",
        key->routerId, key->mapId, key->accountId
    );

    if (!reply) {
        error("Redis error encountered : The request is invalid.");
        result = false;
        goto cleanup;
    }

    switch (reply->type)
    {
        case REDIS_REPLY_ERROR:
            error("Redis error encountered : %s", reply->str);
            result = false;
            goto cleanup;
            break;

        case REDIS_REPLY_INTEGER:
            // Delete OK
            break;

        default :
            error("Unexpected Redis status : %d", reply->type);
            result = false;
            goto cleanup;
            break;
    }

cleanup:
    if (reply) {
        redisReplyDestroy(&reply);
    }

    return result;
}
Пример #8
0
bool redisGetGameSessionBySocketId (Redis *self, uint16_t routerId, uint8_t *sessionKey, GameSession *gameSession) {

    SocketSession socketSession;
    RedisSocketSessionKey socketKey = {
        .routerId = routerId,
        .sessionKey = sessionKey
    };
    if (!(redisGetSocketSession(self, &socketKey, &socketSession))) {
        error("Cannot get the socket session of the client.");
        return false;
    }

    RedisGameSessionKey gameKey = {
        .routerId = socketSession.routerId,
        .mapId = socketSession.mapId,
        .accountId = socketSession.accountId
    };

    if (!(redisGetGameSession(self, &gameKey, gameSession))) {
        error("Cannot get the game session of the client.");
        return false;
    }

    return true;
}

bool redisUpdateGameSession(Redis *self, RedisGameSessionKey *key, uint8_t *socketId, GameSession *gameSession) {

    bool result = true;
    redisReply *reply = NULL;

    CommanderInfo *cInfo = &gameSession->commanderSession.currentCommander.info;
    CommanderAppearance *appearance = &cInfo->appearance;
    CommanderEquipment *equipment = &appearance->equipment;

    reply = redisCommandDbg(self,
        "HMSET zone%x:map%x:acc%llx"
        // Account
        " " REDIS_GAME_SESSION_account_sessionKey_str " %s"
        " " REDIS_GAME_SESSION_account_login_str " %s"
        " " REDIS_GAME_SESSION_account_privilege_str " %x"
        // Barrack
        " " REDIS_GAME_SESSION_barrack_charactersCreatedCount_str " %x"
        // Commander
        " " REDIS_GAME_SESSION_commander_mapId_str " %x"
        " " REDIS_GAME_SESSION_commander_commanderName_str " %s"
        " " REDIS_GAME_SESSION_commander_familyName_str " %s"
        " " REDIS_GAME_SESSION_commander_accountId_str " %llx"
        " " REDIS_GAME_SESSION_commander_classId_str " %x"
        " " REDIS_GAME_SESSION_commander_unk4_str " %x"
        " " REDIS_GAME_SESSION_commander_jobId_str " %x"
        " " REDIS_GAME_SESSION_commander_gender_str " %x"
        " " REDIS_GAME_SESSION_commander_unk5_str " %x"
        " " REDIS_GAME_SESSION_commander_level_str " %x"
        " " REDIS_GAME_SESSION_commander_hairId_str " %x"
        " " REDIS_GAME_SESSION_commander_pose_str " %x"
        // Equipment
        " " REDIS_GAME_SESSION_equipment_head_top_str " %x"
        " " REDIS_GAME_SESSION_equipment_head_middle_str " %x"
        " " REDIS_GAME_SESSION_equipment_itemUnk1_str " %x"
        " " REDIS_GAME_SESSION_equipment_body_armor_str " %x"
        " " REDIS_GAME_SESSION_equipment_gloves_str " %x"
        " " REDIS_GAME_SESSION_equipment_boots_str " %x"
        " " REDIS_GAME_SESSION_equipment_itemUnk2_str " %x"
        " " REDIS_GAME_SESSION_equipment_bracelet_str " %x"
        " " REDIS_GAME_SESSION_equipment_weapon_str " %x"
        " " REDIS_GAME_SESSION_equipment_shield_str " %x"
        " " REDIS_GAME_SESSION_equipment_costume_str " %x"
        " " REDIS_GAME_SESSION_equipment_itemUnk3_str " %x"
        " " REDIS_GAME_SESSION_equipment_itemUnk4_str " %x"
        " " REDIS_GAME_SESSION_equipment_itemUnk5_str " %x"
        " " REDIS_GAME_SESSION_equipment_leg_armor_str " %x"
        " " REDIS_GAME_SESSION_equipment_itemUnk6_str " %x"
        " " REDIS_GAME_SESSION_equipment_itemUnk7_str " %x"
        " " REDIS_GAME_SESSION_equipment_ring_left_str " %x"
        " " REDIS_GAME_SESSION_equipment_ring_right_str " %x"
        " " REDIS_GAME_SESSION_equipment_necklace_str " %x"
        // CommanderInfo Info
        " " REDIS_GAME_SESSION_info_posX_str " %f"
        " " REDIS_GAME_SESSION_info_posY_str " %f"
        " " REDIS_GAME_SESSION_info_posZ_str " %f"
        " " REDIS_GAME_SESSION_info_currentXP_str " %x"
        " " REDIS_GAME_SESSION_info_maxXP_str " %x"
        " " REDIS_GAME_SESSION_info_pcId_str " %x"
        " " REDIS_GAME_SESSION_info_socialInfoId_str " %llx"
        " " REDIS_GAME_SESSION_info_commanderId_str " %llx"
        " " REDIS_GAME_SESSION_info_currentHP_str " %x"
        " " REDIS_GAME_SESSION_info_maxHP_str " %x"
        " " REDIS_GAME_SESSION_info_currentSP_str " %x"
        " " REDIS_GAME_SESSION_info_maxSP_str " %x"
        " " REDIS_GAME_SESSION_info_currentStamina_str " %x"
        " " REDIS_GAME_SESSION_info_maxStamina_str " %x"
        " " REDIS_GAME_SESSION_info_unk6_str " %x"
        " " REDIS_GAME_SESSION_info_unk7_str " %x"
        , key->routerId, key->mapId, key->accountId,

        // Account
        socketId,
        gameSession->accountSession.login,
        gameSession->accountSession.privilege,
        // Barrack
        gameSession->barrackSession.charactersCreatedCount,
        // Commander
        gameSession->commanderSession.mapId,
        CHECK_REDIS_EMPTY_STRING(appearance->commanderName),
        CHECK_REDIS_EMPTY_STRING(appearance->familyName),
        key->accountId,
        appearance->classId,
        appearance->unk4,
        appearance->jobId,
        appearance->gender,
        appearance->unk5,
        appearance->level,
        appearance->hairId,
        appearance->pose,

        // Equipment
        equipment->head_top,
        equipment->head_middle,
        equipment->itemUnk1,
        equipment->body_armor,
        equipment->gloves,
        equipment->boots,
        equipment->itemUnk2,
        equipment->bracelet,
        equipment->weapon,
        equipment->shield,
        equipment->costume,
        equipment->itemUnk3,
        equipment->itemUnk4,
        equipment->itemUnk5,
        equipment->leg_armor,
        equipment->itemUnk6,
        equipment->itemUnk7,
        equipment->ring_left,
        equipment->ring_right,
        equipment->necklace,

        // CommanderInfo info
        cInfo->pos.x,
        cInfo->pos.y,
        cInfo->pos.z,
        cInfo->currentXP,
        cInfo->maxXP,
        cInfo->pcId,
        cInfo->socialInfoId,
        cInfo->commanderId,
        cInfo->currentHP,
        cInfo->maxHP,
        cInfo->currentSP,
        cInfo->maxSP,
        cInfo->currentStamina,
        cInfo->maxStamina,
        cInfo->unk6,
        cInfo->unk7
    );

    if (!reply) {
        error("Redis error encountered : The request is invalid.");
        result = false;
        goto cleanup;
    }

    switch (reply->type)
    {
        case REDIS_REPLY_ERROR:
            error("Redis error encountered : %s", reply->str);
            result = false;
            goto cleanup;
            break;

        case REDIS_REPLY_STATUS:
            // info("Redis status : %s", reply->str);
            break;

        default :
            error("Unexpected Redis status. (%d)", reply->type);
            result = false;
            goto cleanup;
            break;
    }

cleanup:
    if (reply) {
        redisReplyDestroy(&reply);
    }

    return result;
}
Пример #9
0
bool redisGetGameSessionBySocketId(Redis *self, RouterId_t routerId, uint8_t *sessionKey, GameSession *gameSession) {

    SocketSession socketSession;
    RedisSocketSessionKey socketKey = {
        .routerId = routerId,
        .sessionKey = sessionKey
    };
    if (!(redisGetSocketSession(self, &socketKey, &socketSession))) {
        error("Cannot get the socket session of the client.");
        return false;
    }

    RedisGameSessionKey gameKey = {
        .routerId = socketSession.routerId,
        .mapId = socketSession.mapId,
        .accountId = socketSession.accountId
    };

    if (!(redisGetGameSession(self, &gameKey, gameSession))) {
        error("Cannot get the game session of the client.");
        return false;
    }

    return true;
}

bool redisUpdateGameSession(Redis *self, RedisGameSessionKey *key, uint8_t *socketId, GameSession *gameSession) {

    bool result = true;
    size_t repliesCount = 3;
    redisReply *replies[repliesCount];

    Commander *commander = NULL;

    // Initialize replies
    void *noReply = (void *) -1;
    for (int i = 0; i < repliesCount; i++) {
        replies[i] = noReply;
    }

    commander = gameSession->commanderSession.currentCommander;

    // Account
    replies[0] = redisCommandDbg(self,
        "HMSET zone%x:map%x:acc%llx"
        " " REDIS_SESSION_account_sessionKey_str " %s"
        " " REDIS_SESSION_account_accountName_str " %s"
        " " REDIS_SESSION_account_privilege_str " %x"
        " " REDIS_SESSION_account_commandersCountMax_str " %x",
        key->routerId, key->mapId, key->accountId,

        socketId,
        gameSession->accountSession.accountName,
        gameSession->accountSession.privilege,
        gameSession->accountSession.commandersCountMax
    );

    // Commander
    if (commander) {
        replies[1] = redisCommandDbg(self,
            "HMSET zone%x:map%x:acc%llx"
            " " REDIS_SESSION_commander_mapId_str " %x"
            " " REDIS_SESSION_commander_commanderName_str " %s"
            " " REDIS_SESSION_commander_familyName_str " %s"
            " " REDIS_SESSION_commander_accountId_str " %llx"
            " " REDIS_SESSION_commander_classId_str " %x"
            " " REDIS_SESSION_commander_jobId_str " %x"
            " " REDIS_SESSION_commander_gender_str " %x"
            " " REDIS_SESSION_commander_level_str " %x"
            " " REDIS_SESSION_commander_hairId_str " %x"
            " " REDIS_SESSION_commander_pose_str " %x"
            " " REDIS_SESSION_commander_posX_str " %f"
            " " REDIS_SESSION_commander_posY_str " %f"
            " " REDIS_SESSION_commander_posZ_str " %f"
            " " REDIS_SESSION_commander_currentXP_str " %x"
            " " REDIS_SESSION_commander_maxXP_str " %x"
            " " REDIS_SESSION_commander_pcId_str " %x"
            " " REDIS_SESSION_commander_socialInfoId_str " %llx"
            " " REDIS_SESSION_commander_commanderId_str " %llx"
            " " REDIS_SESSION_commander_currentHP_str " %x"
            " " REDIS_SESSION_commander_maxHP_str " %x"
            " " REDIS_SESSION_commander_currentSP_str " %x"
            " " REDIS_SESSION_commander_maxSP_str " %x"
            " " REDIS_SESSION_commander_currentStamina_str " %x"
            " " REDIS_SESSION_commander_maxStamina_str " %x",
            key->routerId, key->mapId, key->accountId,

            commander->mapId,
            CHECK_REDIS_EMPTY_STRING(commander->commanderName),
            CHECK_REDIS_EMPTY_STRING(commander->familyName),
            key->accountId,
            commander->classId,
            commander->jobId,
            commander->gender,
            commander->level,
            commander->hairId,
            commander->pose,
            commander->pos.x,
            commander->pos.y,
            commander->pos.z,
            commander->currentXP,
            commander->maxXP,
            commander->pcId,
            commander->socialInfoId,
            commander->commanderId,
            commander->currentHP,
            commander->maxHP,
            commander->currentSP,
            commander->maxSP,
            commander->currentStamina,
            commander->maxStamina
        );

        replies[2] = redisCommandDbg(self,
            "HMSET zone%x:map%x:acc%llx"
            " " REDIS_SESSION_EQSLOT_HAT_str " %x"
            " " REDIS_SESSION_EQSLOT_HAT_L_str " %x"
            " " REDIS_SESSION_EQSLOT_UNKOWN1_str " %x"
            " " REDIS_SESSION_EQSLOT_BODY_ARMOR_str " %x"
            " " REDIS_SESSION_EQSLOT_GLOVES_str " %x"
            " " REDIS_SESSION_EQSLOT_BOOTS_str " %x"
            " " REDIS_SESSION_EQSLOT_HELMET_str " %x"
            " " REDIS_SESSION_EQSLOT_BRACELET_str " %x"
            " " REDIS_SESSION_EQSLOT_WEAPON_str " %x"
            " " REDIS_SESSION_EQSLOT_SHIELD_str " %x"
            " " REDIS_SESSION_EQSLOT_COSTUME_str " %x"
            " " REDIS_SESSION_EQSLOT_UNKOWN3_str " %x"
            " " REDIS_SESSION_EQSLOT_UNKOWN4_str " %x"
            " " REDIS_SESSION_EQSLOT_UNKOWN5_str " %x"
            " " REDIS_SESSION_EQSLOT_LEG_ARMOR_str " %x"
            " " REDIS_SESSION_EQSLOT_UNKOWN6_str " %x"
            " " REDIS_SESSION_EQSLOT_UNKOWN7_str " %x"
            " " REDIS_SESSION_EQSLOT_RING_LEFT_str " %x"
            " " REDIS_SESSION_EQSLOT_RING_RIGHT_str " %x"
            " " REDIS_SESSION_EQSLOT_NECKLACE_str " %x"
            , key->routerId, key->mapId, key->accountId,

            // Equipment
            itemGetId((Item *) commander->inventory.equippedItems[EQSLOT_HAT]),
            itemGetId((Item *) commander->inventory.equippedItems[EQSLOT_HAT_L]),
            itemGetId((Item *) commander->inventory.equippedItems[EQSLOT_UNKOWN1]),
            itemGetId((Item *) commander->inventory.equippedItems[EQSLOT_BODY_ARMOR]),
            itemGetId((Item *) commander->inventory.equippedItems[EQSLOT_GLOVES]),
            itemGetId((Item *) commander->inventory.equippedItems[EQSLOT_BOOTS]),
            itemGetId((Item *) commander->inventory.equippedItems[EQSLOT_HELMET]),
            itemGetId((Item *) commander->inventory.equippedItems[EQSLOT_BRACELET]),
            itemGetId((Item *) commander->inventory.equippedItems[EQSLOT_WEAPON]),
            itemGetId((Item *) commander->inventory.equippedItems[EQSLOT_SHIELD]),
            itemGetId((Item *) commander->inventory.equippedItems[EQSLOT_COSTUME]),
            itemGetId((Item *) commander->inventory.equippedItems[EQSLOT_UNKOWN3]),
            itemGetId((Item *) commander->inventory.equippedItems[EQSLOT_UNKOWN4]),
            itemGetId((Item *) commander->inventory.equippedItems[EQSLOT_UNKOWN5]),
            itemGetId((Item *) commander->inventory.equippedItems[EQSLOT_LEG_ARMOR]),
            itemGetId((Item *) commander->inventory.equippedItems[EQSLOT_UNKOWN6]),
            itemGetId((Item *) commander->inventory.equippedItems[EQSLOT_UNKOWN7]),
            itemGetId((Item *) commander->inventory.equippedItems[EQSLOT_RING_LEFT]),
            itemGetId((Item *) commander->inventory.equippedItems[EQSLOT_RING_RIGHT]),
            itemGetId((Item *) commander->inventory.equippedItems[EQSLOT_NECKLACE])
        );
    }

    for (int i = 0; i < repliesCount; i++) {
        redisReply *reply = replies[i];

        if (reply != noReply) {
            if (!reply) {
                error("Redis error encountered : The request is invalid.");
                result = false;
                goto cleanup;
            }
            switch (reply->type)
            {
                case REDIS_REPLY_ERROR:
                    error("Redis error encountered : %s", reply->str);
                    result = false;
                    goto cleanup;
                    break;

                case REDIS_REPLY_STATUS:
                    // Ok
                    break;

                default :
                    error("Unexpected Redis status. (%d)", reply->type);
                    result = false;
                    goto cleanup;
                    break;
            }
        }
    }

cleanup:
    for (int i = 0; i < repliesCount; i++) {
        redisReply *reply = replies[i];

        if (reply && reply != noReply) {
            redisReplyDestroy(&reply);
        }
    }
    return result;
}
Пример #10
0
bool redisGetGameSession(Redis *self, RedisGameSessionKey *key, GameSession *gameSession) {

    memset(gameSession, 0, sizeof(*gameSession));

    bool result = false;
    redisReply *reply = NULL;

    reply = redisCommandDbg(self,
        "HMGET zone%x:map%x:acc%llx"
        /** Keep these fields in the same order than the RedisGameSessionFields fields one */
        // Account
        " " REDIS_SESSION_account_accountName_str
        " " REDIS_SESSION_account_sessionKey_str
        " " REDIS_SESSION_account_privilege_str
        " " REDIS_SESSION_account_commandersCountMax_str
        // Commander
        " " REDIS_SESSION_commander_mapId_str
        " " REDIS_SESSION_commander_commanderName_str
        " " REDIS_SESSION_commander_familyName_str
        " " REDIS_SESSION_commander_accountId_str
        " " REDIS_SESSION_commander_classId_str
        " " REDIS_SESSION_commander_jobId_str
        " " REDIS_SESSION_commander_gender_str
        " " REDIS_SESSION_commander_level_str
        " " REDIS_SESSION_commander_hairId_str
        " " REDIS_SESSION_commander_pose_str
        " " REDIS_SESSION_commander_posX_str
        " " REDIS_SESSION_commander_posY_str
        " " REDIS_SESSION_commander_posZ_str
        " " REDIS_SESSION_commander_currentXP_str
        " " REDIS_SESSION_commander_maxXP_str
        " " REDIS_SESSION_commander_pcId_str
        " " REDIS_SESSION_commander_socialInfoId_str
        " " REDIS_SESSION_commander_commanderId_str
        " " REDIS_SESSION_commander_currentHP_str
        " " REDIS_SESSION_commander_maxHP_str
        " " REDIS_SESSION_commander_currentSP_str
        " " REDIS_SESSION_commander_maxSP_str
        " " REDIS_SESSION_commander_currentStamina_str
        " " REDIS_SESSION_commander_maxStamina_str
        // Equipment
        " " REDIS_SESSION_EQSLOT_HAT_str
        " " REDIS_SESSION_EQSLOT_HAT_L_str
        " " REDIS_SESSION_EQSLOT_UNKOWN1_str
        " " REDIS_SESSION_EQSLOT_BODY_ARMOR_str
        " " REDIS_SESSION_EQSLOT_GLOVES_str
        " " REDIS_SESSION_EQSLOT_BOOTS_str
        " " REDIS_SESSION_EQSLOT_HELMET_str
        " " REDIS_SESSION_EQSLOT_BRACELET_str
        " " REDIS_SESSION_EQSLOT_WEAPON_str
        " " REDIS_SESSION_EQSLOT_SHIELD_str
        " " REDIS_SESSION_EQSLOT_COSTUME_str
        " " REDIS_SESSION_EQSLOT_UNKOWN3_str
        " " REDIS_SESSION_EQSLOT_UNKOWN4_str
        " " REDIS_SESSION_EQSLOT_UNKOWN5_str
        " " REDIS_SESSION_EQSLOT_LEG_ARMOR_str
        " " REDIS_SESSION_EQSLOT_UNKOWN6_str
        " " REDIS_SESSION_EQSLOT_UNKOWN7_str
        " " REDIS_SESSION_EQSLOT_RING_LEFT_str
        " " REDIS_SESSION_EQSLOT_RING_RIGHT_str
        " " REDIS_SESSION_EQSLOT_NECKLACE_str

        , key->routerId, key->mapId, key->accountId
    );

    if (!reply) {
        error("Redis error encountered : The request is invalid.");
        goto cleanup;
    }

    switch (reply->type)
    {
        case REDIS_REPLY_ERROR:
            error("Redis error encountered : %s", reply->str);
            goto cleanup;
            break;

        case REDIS_REPLY_STATUS:
            // info("Redis status : %s", reply->str);
            break;

        case REDIS_REPLY_ARRAY: {
            // Check the number of elements retrieved
            if (reply->elements != REDIS_SESSION_COUNT) {
                error("Wrong number of elements received.");
                goto cleanup;
            }

            // Check if any element of the reply is NULL
            size_t elementIndex;
            if ((elementIndex = redisAnyElementIsNull (reply->element, reply->elements)) != -1) {
                error("Element <%s> returned by Redis is NULL.", redisGameSessionsStr[elementIndex]);
                goto cleanup;
            }

            /// Write the reply to the session
            // Account
            COPY_REDIS_GAME_STR(gameSession->accountSession.accountName, account_accountName);
            COPY_REDIS_GAME_STR(gameSession->accountSession.sessionKey, account_sessionKey);
            gameSession->accountSession.privilege = GET_REDIS_GAME_32(account_privilege);
            gameSession->accountSession.commandersCountMax = GET_REDIS_GAME_32(account_commandersCountMax);

            CommanderSession *commanderSession = &gameSession->commanderSession;
            Commander *commander = commanderSession->currentCommander = commanderNew();

            // Commander
            COPY_REDIS_GAME_STR(commander->commanderName, commander_commanderName);
            COPY_REDIS_GAME_STR(commander->familyName, commander_familyName);
            commander->accountId = GET_REDIS_GAME_64(commander_accountId);
            commander->classId   = GET_REDIS_GAME_32(commander_classId);
            commander->jobId     = GET_REDIS_GAME_32(commander_jobId);
            commander->gender    = GET_REDIS_GAME_32(commander_gender);
            commander->level     = GET_REDIS_GAME_32(commander_level);
            commander->hairId    = GET_REDIS_GAME_32(commander_hairId);
            commander->pose      = GET_REDIS_GAME_32(commander_pose);
            commander->mapId = GET_REDIS_GAME_32(commander_mapId);
            commander->pos.x = GET_REDIS_GAME_FLOAT(commander_posX);
            commander->pos.y = GET_REDIS_GAME_FLOAT(commander_posY);
            commander->pos.z = GET_REDIS_GAME_FLOAT(commander_posZ);
            commander->currentXP = GET_REDIS_GAME_32(commander_currentXP);
            commander->maxXP = GET_REDIS_GAME_32(commander_maxXP);
            commander->pcId = GET_REDIS_GAME_32(commander_pcId);
            commander->socialInfoId = GET_REDIS_GAME_64(commander_socialInfoId);
            commander->commanderId = GET_REDIS_GAME_64(commander_commanderId);
            commander->currentHP = GET_REDIS_GAME_32(commander_currentHP);
            commander->maxHP = GET_REDIS_GAME_32(commander_maxHP);
            commander->currentSP = GET_REDIS_GAME_32(commander_currentSP);
            commander->maxSP = GET_REDIS_GAME_32(commander_maxSP);
            commander->currentStamina = GET_REDIS_GAME_32(commander_currentStamina);
            commander->maxStamina = GET_REDIS_GAME_32(commander_maxStamina);

            // Equipment
            #define GET_REDIS_EQUIPMENT(x)                                                                     \
              if (!(commander->inventory.equippedItems[x] = (ItemEquipable *) itemFactoryCreate(               \
                     GET_REDIS_GAME_32(x), 1)))                                                                \
              {                                                                                                \
                    error("Cannot get item '%s'", STRINGIFY(x));                                               \
                    goto cleanup;                                                                              \
              }                                                                                                \

            GET_REDIS_EQUIPMENT(EQSLOT_HAT);
            GET_REDIS_EQUIPMENT(EQSLOT_HAT_L);
            GET_REDIS_EQUIPMENT(EQSLOT_UNKOWN1);
            GET_REDIS_EQUIPMENT(EQSLOT_BODY_ARMOR);
            GET_REDIS_EQUIPMENT(EQSLOT_GLOVES);
            GET_REDIS_EQUIPMENT(EQSLOT_BOOTS);
            GET_REDIS_EQUIPMENT(EQSLOT_HELMET);
            GET_REDIS_EQUIPMENT(EQSLOT_BRACELET);
            GET_REDIS_EQUIPMENT(EQSLOT_WEAPON);
            GET_REDIS_EQUIPMENT(EQSLOT_SHIELD);
            GET_REDIS_EQUIPMENT(EQSLOT_COSTUME);
            GET_REDIS_EQUIPMENT(EQSLOT_UNKOWN3);
            GET_REDIS_EQUIPMENT(EQSLOT_UNKOWN4);
            GET_REDIS_EQUIPMENT(EQSLOT_UNKOWN5);
            GET_REDIS_EQUIPMENT(EQSLOT_LEG_ARMOR);
            GET_REDIS_EQUIPMENT(EQSLOT_UNKOWN6);
            GET_REDIS_EQUIPMENT(EQSLOT_UNKOWN7);
            GET_REDIS_EQUIPMENT(EQSLOT_RING_LEFT);
            GET_REDIS_EQUIPMENT(EQSLOT_RING_RIGHT);
            GET_REDIS_EQUIPMENT(EQSLOT_NECKLACE);
        }
        break;

        default :
            error("Unexpected Redis status (%d).", reply->type);
            goto cleanup;
            break;
    }

    result = true;

cleanup:
    if (reply) {
        redisReplyDestroy(&reply);
    }

    return result;
}