bool mySqlGetCommanders(MySQL *self, char *familyName, Commander **commanders) { MYSQL_ROW row; for (int i = 0; (row = mysql_fetch_row(self->result)); i++) { Commander *curCommander = commanders[i]; commanderInit(curCommander); strncpy(curCommander->familyName, familyName, sizeof(curCommander->familyName)); strncpy(curCommander->commanderName, row[MYSQL_COMMANDER_commander_name], sizeof(curCommander->commanderName)); curCommander->accountId = strtol(row[MYSQL_COMMANDER_account_id], NULL, 10); curCommander->classId = strtol(row[MYSQL_COMMANDER_class_id], NULL, 10); curCommander->jobId = strtol(row[MYSQL_COMMANDER_job_id], NULL, 10); curCommander->gender = strtol(row[MYSQL_COMMANDER_gender], NULL, 10); curCommander->level = strtol(row[MYSQL_COMMANDER_level], NULL, 10); curCommander->hairId = strtol(row[MYSQL_COMMANDER_hair_id], NULL, 10); curCommander->pose = 0; // IDLE curCommander->pos = PositionXYZ_decl( strtof(row[MYSQL_COMMANDER_position_x], NULL), strtof(row[MYSQL_COMMANDER_position_y], NULL), strtof(row[MYSQL_COMMANDER_position_z], NULL) ); curCommander->barrackPos = PositionXYZ_decl( strtof(row[MYSQL_COMMANDER_barrack_position_x], NULL), strtof(row[MYSQL_COMMANDER_barrack_position_y], NULL), strtof(row[MYSQL_COMMANDER_barrack_position_z], NULL) ); /* curCommander->dir = PositionXZ_decl( strtof(row[MYSQL_COMMANDER_direction_x], NULL), strtof(row[MYSQL_COMMANDER_direction_y], NULL), ); */ curCommander->currentXP = strtol(row[MYSQL_COMMANDER_exp], NULL, 10); curCommander->maxXP = 1337; /** TODO : Get max XP from XP tables */ curCommander->pcId = rand(); /** TODO : Get unique PCID */ curCommander->socialInfoId = strtoll(row[MYSQL_COMMANDER_commander_id], NULL, 10); /** TODO : Get socialInfoId from MYSQL */ curCommander->commanderId = strtoll(row[MYSQL_COMMANDER_commander_id], NULL, 10); curCommander->currentHP = strtol(row[MYSQL_COMMANDER_hp], NULL, 10); curCommander->maxHP = curCommander->currentHP; /** TODO : Get maxHP from MYSQL */ curCommander->currentSP = strtol(row[MYSQL_COMMANDER_mp], NULL, 10); curCommander->maxSP = curCommander->currentSP; /** TODO : Get maxHP from MYSQL */ curCommander->currentStamina = 25000; /** TODO : Get currentStamina from MYSQL */ curCommander->maxStamina = curCommander->currentStamina; /** TODO : Get maxStamina from MYSQL */ curCommander->mapId = strtol(row[MYSQL_COMMANDER_map_id], NULL, 10); // load equipped items for (ItemEquipmentSlot_t slot = 0; slot < EQSLOT_COUNT; slot++) { MySqlCommanderEnumField field = MYSQL_COMMANDER_eqslot_head_top + slot; ItemId_t itemId = strtol(row[field], NULL, 10); curCommander->inventory.equippedItems[slot] = itemFactoryCreateEquipable(itemId, 1, slot); } } return true; }
static PacketHandlerState zoneHandlerConnect( Worker *self, Session *session, uint8_t *packet, size_t packetSize, zmsg_t *replyMsg) { #pragma pack(push, 1) struct { uint32_t unk1; uint64_t accountId; uint64_t zoneServerId; uint8_t login[ACCOUNT_SESSION_LOGIN_MAXSIZE]; uint8_t unk4; uint32_t zoneServerIndex; uint16_t unk3; uint8_t channelListId; } *clientPacket = (void *) packet; #pragma pack(pop) // TODO : Reverse CZ_CONNECT correctly // CHECK_CLIENT_PACKET_SIZE(*clientPacket, packetSize, CZ_CONNECT); // Get the Game Session that the Barrack Server moved RedisGameSessionKey gameKey = { .routerId = self->info.routerId, .mapId = -1, .accountId = clientPacket->accountId }; if (!(redisGetGameSession(self->redis, &gameKey, &session->game))) { error("Cannot retrieve the game session."); return PACKET_HANDLER_ERROR; } // Check the client packet here(authentication) if (strncmp(session->game.accountSession.login, clientPacket->login, sizeof(session->game.accountSession.login)) != 0) { error("Wrong account authentication.(clientPacket account = <%s>, Session account = <%s>", clientPacket->login, session->game.accountSession.login); return PACKET_HANDLER_ERROR; } // Authentication OK ! // Update the Socket Session socketSessionInit(&session->socket, clientPacket->accountId, self->info.routerId, session->game.commanderSession.mapId, session->socket.sessionKey, true ); // Move the game Session to the current mapId RedisGameSessionKey fromKey = { .routerId = session->socket.routerId, .mapId = -1, .accountId = session->socket.accountId }; RedisGameSessionKey toKey = { .routerId = session->socket.routerId, .mapId = session->socket.mapId, .accountId = session->socket.accountId }; if (!(redisMoveGameSession(self->redis, &fromKey, &toKey))) { error("Cannot move the game session to the current mapId."); return PACKET_HANDLER_ERROR; } session->game.commanderSession.currentCommander.pos = PositionXYZ_decl(76.0f, 1.0f, 57.0f); zoneBuilderConnectOk( session->game.commanderSession.currentCommander.pcId, 0, // GameMode 0, // accountPrivileges &session->game.commanderSession.currentCommander, // Current commander replyMsg ); return PACKET_HANDLER_UPDATE_SESSION; } static PacketHandlerState zoneHandlerJump( Worker *self, Session *session, uint8_t *packet, size_t packetSize, zmsg_t *replyMsg) { #pragma pack(push, 1) struct { uint8_t unk1; } *clientPacket = (void *) packet; #pragma pack(pop) CHECK_CLIENT_PACKET_SIZE(*clientPacket, packetSize, CZ_JUMP); // Notify the players around GameEventJump event = { .updatePosEvent = { .mapId = session->socket.mapId, .commanderInfo = session->game.commanderSession.currentCommander }, .height = COMMANDER_HEIGHT_JUMP }; workerDispatchEvent(self, session->socket.sessionKey, EVENT_TYPE_JUMP, &event, sizeof(event)); return PACKET_HANDLER_OK; } static PacketHandlerState zoneHandlerOnAir( Worker *self, Session *session, uint8_t *packet, size_t packetSize, zmsg_t *replyMsg) { warning("CZ_ON_AIR not implemented yet."); return PACKET_HANDLER_OK; } static PacketHandlerState zoneHandlerOnGround( Worker *self, Session *session, uint8_t *packet, size_t packetSize, zmsg_t *replyMsg) { warning("CZ_ON_GROUND not implemented yet."); return PACKET_HANDLER_OK; }
static PacketHandlerState zoneHandlerConnect( Worker *self, Session *session, uint8_t *packet, size_t packetSize, zmsg_t *replyMsg) { PacketHandlerState status = PACKET_HANDLER_ERROR; #pragma pack(push, 1) struct { uint32_t unk1; uint64_t accountId; uint64_t zoneServerId; uint8_t accountName[ACCOUNT_SESSION_ACCOUNT_NAME_MAXSIZE]; uint8_t unk4; uint32_t zoneServerIndex; uint16_t unk3; uint8_t channelListId; } *clientPacket = (void *) packet; #pragma pack(pop) dbg("zoneHandlerConnect"); dbg("unk1 %x", clientPacket->unk1); dbg("accountId %d", clientPacket->accountId); dbg("zoneServerId %d", clientPacket->zoneServerId); dbg("zoneServerIndex %d", clientPacket->zoneServerIndex); dbg("unk3 %x", clientPacket->unk3); dbg("unk4 %x", clientPacket->unk4); dbg("channelListId %d", clientPacket->channelListId); dbg("accountName %s", clientPacket->accountName); // TODO : Reverse CZ_CONNECT correctly // CHECK_CLIENT_PACKET_SIZE(*clientPacket, packetSize, CZ_CONNECT); GameSession tmpGameSession; AccountSession *tmpAccountSession = &tmpGameSession.accountSession; CommanderSession *tmpCommanderSession = &tmpGameSession.commanderSession; // TODO : Get the account session from Db. RedisAccountSessionKey accountKey = { .routerId = self->info.routerId, .mapId = SOCKET_SESSION_UNDEFINED_MAP, .accountId = clientPacket->accountId }; if (!(redisGetAccountSession(self->redis, &accountKey, tmpAccountSession))) { error("Cannot retrieve the account session."); goto cleanup; } // Check the client packet here (authentication) // TODO improve it if (strncmp(tmpAccountSession->accountName, clientPacket->accountName, sizeof(tmpAccountSession->accountName)) != 0) { error("Wrong account authentication. (clientPacket account = <%s>, Session account = <%s>", clientPacket->accountName, tmpAccountSession->accountName); goto cleanup; } // === Authentication OK ! === // Get list of Commanders for this AccountId size_t commandersCount; if (!(mySqlLoadAccountCommanders(self->sqlConn, tmpAccountSession, clientPacket->accountId, &commandersCount))) { error("Cannot load commanders."); goto cleanup; } // FIXME : Determine how to get the correct commander in the commander array tmpCommanderSession->currentCommander = commanderDup(tmpAccountSession->commanders[0]); // Get the Game Session that the Barrack Server moved // TODO : Should be replaced by Db RedisGameSessionKey gameKey = accountKey; if (!(redisGetGameSession(self->redis, &gameKey, &tmpGameSession))) { error("Cannot retrieve the game session."); goto cleanup; } // Update the Socket Session socketSessionInit(&session->socket, clientPacket->accountId, self->info.routerId, tmpCommanderSession->currentCommander->mapId, session->socket.sessionKey, true ); // Move the game Session to the current mapId RedisGameSessionKey fromKey = { .routerId = session->socket.routerId, .mapId = -1, .accountId = session->socket.accountId }; RedisGameSessionKey toKey = { .routerId = session->socket.routerId, .mapId = session->socket.mapId, .accountId = session->socket.accountId }; // TODO : Should be replaced by Db if (!(redisMoveGameSession(self->redis, &fromKey, &toKey))) { error("Cannot move the game session to the current mapId."); goto cleanup; } // FIXME // Set a default position tmpCommanderSession->currentCommander->pos = PositionXYZ_decl(76.0f, 1.0f, 57.0f); // Update the session session->game = tmpGameSession; // Build a reply packet zoneBuilderConnectOk( 0, // GameMode 0, // accountPrivileges session->game.commanderSession.currentCommander, replyMsg ); status = PACKET_HANDLER_UPDATE_SESSION; cleanup: return status; } static PacketHandlerState zoneHandlerJump( Worker *self, Session *session, uint8_t *packet, size_t packetSize, zmsg_t *replyMsg) { #pragma pack(push, 1) struct { uint8_t unk1; } *clientPacket = (void *) packet; #pragma pack(pop) CHECK_CLIENT_PACKET_SIZE(*clientPacket, packetSize, CZ_JUMP); // Notify the players around GameEventJump event = { .updatePosEvent = { .mapId = session->socket.mapId, .commander = *session->game.commanderSession.currentCommander }, .height = COMMANDER_HEIGHT_JUMP }; workerDispatchEvent(self, session->socket.sessionKey, EVENT_TYPE_JUMP, &event, sizeof(event)); return PACKET_HANDLER_OK; } static PacketHandlerState zoneHandlerOnAir( Worker *self, Session *session, uint8_t *packet, size_t packetSize, zmsg_t *replyMsg) { warning("CZ_ON_AIR not implemented yet."); return PACKET_HANDLER_OK; } static PacketHandlerState zoneHandlerOnGround( Worker *self, Session *session, uint8_t *packet, size_t packetSize, zmsg_t *replyMsg) { warning("CZ_ON_GROUND not implemented yet."); return PACKET_HANDLER_OK; }