void Game::join(Server & s, Peer & peer) { Sv response = Sv::Yes; for (auto & p : mPlayers) if (p.first->getName() == peer.getName()) { std::cout << peer.getName() << " rejected due to name clash" << std::endl; response = Sv::No; break; } sf::Packet * packet2 = new sf::Packet;//for the peer who joined. join success *packet2 << Sv::ReplyJoin << response; pushPacket(&peer, packet2); if (response == Sv::Yes) { std::cout << peer.getName() << " joined the room\n"; sf::Packet * packet4 = new sf::Packet;//for all the others *packet4 << Sv::PlayerJoined << sf::Int32(1) << peer.getName(); pushPacket(&peer, packet4, true); sf::Packet * packet3 = new sf::Packet; //for the peer who joined. *packet3 << Sv::PlayerJoined << sf::Int32(mPlayers.size()); for (auto & player : mPlayers) *packet3 << player.first->getName(); pushPacket(&peer, packet3); mPlayers.insert({ &peer, false }); } }
bool CAbilityState::CanUseAbility() { if (m_PEntity->objtype == TYPE_MOB || m_PEntity->objtype == TYPE_PET) return true; if (m_PEntity->objtype == TYPE_PC) { auto PAbility = GetAbility(); auto PChar = static_cast<CCharEntity*>(m_PEntity); if (PChar->PRecastContainer->HasRecast(RECAST_ABILITY, PAbility->getRecastId(), PAbility->getRecastTime())) { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 0, MSGBASIC_WAIT_LONGER)); return false; } if (PChar->StatusEffectContainer->HasStatusEffect({EFFECT_AMNESIA, EFFECT_IMPAIRMENT})) { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 0, MSGBASIC_UNABLE_TO_USE_JA2)); return false; } std::unique_ptr<CMessageBasicPacket> errMsg; auto PTarget = GetTarget(); if (PChar->IsValidTarget(PTarget->targid, PAbility->getValidTarget(), errMsg)) { if (PChar != PTarget && distance(PChar->loc.p, PTarget->loc.p) > PAbility->getRange()) { PChar->pushPacket(new CMessageBasicPacket(PChar, PTarget, 0, 0, MSGBASIC_TOO_FAR_AWAY)); return false; } if (!m_PEntity->PAI->TargetFind->canSee(&PTarget->loc.p)) { m_errorMsg = std::make_unique<CMessageBasicPacket>(m_PEntity, PTarget, PAbility->getID(), 0, MSGBASIC_CANNOT_PERFORM_ACTION); return false; } if (PAbility->getID() >= ABILITY_HEALING_RUBY) { // Blood pact MP costs are stored under animation ID if (PChar->health.mp < PAbility->getAnimationID()) { PChar->pushPacket(new CMessageBasicPacket(PChar, PTarget, 0, 0, MSGBASIC_UNABLE_TO_USE_JA)); return false; } } CBaseEntity* PMsgTarget = PChar; int32 errNo = luautils::OnAbilityCheck(PChar, PTarget, PAbility, &PMsgTarget); if (errNo != 0) { PChar->pushPacket(new CMessageBasicPacket(PChar, PMsgTarget, PAbility->getID() + 16, PAbility->getID(), errNo)); return false; } return true; } return false; } return true; }
void CStatusEffectContainer::UpdateStatusIcons() { if (m_POwner->objtype != TYPE_PC) return; auto PChar = static_cast<CCharEntity*>(m_POwner); m_Flags = 0; memset(m_StatusIcons, EFFECT_NONE, sizeof(m_StatusIcons)); uint8 count = 0; for (uint16 i = 0; i < m_StatusEffectList.size(); ++i) { uint16 icon = m_StatusEffectList.at(i)->GetIcon(); if (icon != 0) { if (icon >= 256 && icon < 512) { m_Flags |= 1LL << (count * 2); } if (icon >= 512) { m_Flags |= 1LL << (count * 2 + 1); } //Note: it may be possible that having both bits set is for effects over 768, but there aren't // that many effects as of this writing m_StatusIcons[count] = icon; if (++count == 32) break; } } PChar->pushPacket(new CCharUpdatePacket(PChar)); PChar->pushPacket(new CCharJobExtraPacket(PChar, true)); PChar->pushPacket(new CCharJobExtraPacket(PChar, false)); PChar->pushPacket(new CStatusEffectPacket(PChar)); if (PChar->PParty) { PChar->PParty->PushEffectsPacket(PChar); } }
void Game::leave(Server & s, Peer & p) { if (mPlayers.count(&p) == 1) { mPlayers.erase(&p); sf::Packet * packet = new sf::Packet; *packet << Sv::PlayerDisconnected << p.getName() << "\n"; pushPacket(nullptr, packet, true); mGameWorld.leave(&p, *this); } }
void CPlayerController::RangedAttack(uint16 targid) { auto PChar = static_cast<CCharEntity*>(POwner); if (PChar->PAI->CanChangeState() && server_clock::now() > m_NextRangedTime) { PChar->PAI->Internal_RangedAttack(targid); } else { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 0, MSGBASIC_WAIT_LONGER)); } }
void CPlayerController::Cast(uint16 targid, uint16 spellid) { auto PChar = static_cast<CCharEntity*>(POwner); if (!PChar->PRecastContainer->HasRecast(RECAST_MAGIC, spellid, 0)) { CController::Cast(targid, spellid); } else { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 0, MSGBASIC_UNABLE_TO_CAST)); } }
void CPlayerController::Ability(uint16 targid, uint16 abilityid) { auto PChar = static_cast<CCharEntity*>(POwner); if (PChar->PAI->CanChangeState()) { PChar->PAI->Internal_Ability(targid, abilityid); } else { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 0, MSGBASIC_UNABLE_TO_USE_JA)); } }
bool CreateGameHandler::handle(CMSGCreateGame *p) { auto client = std::dynamic_pointer_cast<Client > (p->source()); if (!client) { WARN("NO SOURCE TO CREATE GAME"); return true; } auto response = std::make_shared<SMSGCreateGame > (p->source()); if (!client->authenticated()) { response->data_.set_success(false); response->data_.set_errormsg("You are not authenticated so you cannot create a new game."); client->pushPacket(response); return true; } if (p->data_.gamename() == "") { response->data_.set_success(false); response->data_.set_errormsg("Name cannot be empty;"); } for (auto game : Server::instance().games()) { if (game->name() == p->data_.gamename()) { WARN("Game with is name already exists, not creating"); response->data_.set_success(false); response->data_.set_errormsg("Name already taken."); p->source()->pushPacket(response); return true; } } std::string sceneName; if (p->data_.has_scenename()) sceneName = p->data_.scenename(); else sceneName = "Test Level"; std::shared_ptr<Game> g(new Game(sceneName)); g->name(p->data_.gamename()); response->data_.set_success(true); response->data_.set_gameuuid(g->uuid()); p->source()->pushPacket(response); Server::instance().addGame(g); return true; }
bool CDeathState::Update(time_point tick) { if (IsCompleted() || m_PEntity->animation != ANIMATION_DEATH) { return true; } else if (tick > GetEntryTime() + m_deathTime && !IsCompleted()) { Complete(); m_PEntity->OnDeathTimer(); } else if (m_PEntity->objtype == TYPE_PC && tick > GetEntryTime() + 8s && !IsCompleted() && !m_raiseSent && m_PEntity->isDead()) { auto PChar = static_cast<CCharEntity*>(m_PEntity); if (PChar->m_hasRaise) { PChar->pushPacket(new CRaiseTractorMenuPacket(PChar, TYPE_RAISE)); m_raiseSent = true; } } return false; }
void Game::step(Server & s) { switch (mState) { case Game::State::Waiting:// players clicked "ready" from lobby if (playersAreReady()) { sf::Packet * packet = new sf::Packet; *packet << Sv::LoadGame; pushPacket(nullptr, packet, true); unreadyPlayers(); //unready them so they can be ready to receive map data std::cout << "Game is starting!" << std::endl; mState = Game::State::Loading; } break; case Game::State::Loading: if (playersAreReady()) { std::string mapName = getRandomMap(); mGameWorld.loadMap(mapName); initializePlayers(); mState = Game::State::Playing; } break; case Game::State::Playing: mGameWorld.step(*this, s.TimeStep.asSeconds()); break; case Game::State::Ended: break; default: break; } }
void Game::handlePacket(Peer & peer, Cl type, sf::Packet & packet) { switch (type) { case Cl::Ready: std::cout << peer.getName() << " readied\n"; mPlayers.at(&peer) = true; break; case Cl::Chat: { std::string msg; packet >> msg; sf::Packet * packet2 = new sf::Packet; *packet2<<Sv::Chat << peer.getName() << msg; pushPacket(nullptr, packet2, true); } break; case Cl::GameEvent: mGameWorld.handlePacket(*this, packet); break; default: break; } }
bool CPlayerController::Engage(uint16 targid) { //#TODO: pet engage/disengage std::unique_ptr<CMessageBasicPacket> errMsg; auto PChar = static_cast<CCharEntity*>(POwner); auto PTarget = PChar->IsValidTarget(targid, TARGET_ENEMY, errMsg); if (PTarget) { if (distance(PChar->loc.p, PTarget->loc.p) < 30) { if (m_LastAttackTime + std::chrono::milliseconds(PChar->GetWeaponDelay(false)) < server_clock::now()) { if (CController::Engage(targid)) { PChar->PLatentEffectContainer->CheckLatentsWeaponDraw(true); PChar->pushPacket(new CLockOnPacket(PChar, PTarget)); return true; } } else { errMsg = std::make_unique<CMessageBasicPacket>(PChar, PTarget, 0, 0, MSGBASIC_WAIT_LONGER); } } else { errMsg = std::make_unique<CMessageBasicPacket>(PChar, PTarget, 0, 0, MSGBASIC_TOO_FAR_AWAY); } } if (errMsg) { PChar->HandleErrorMessage(errMsg); } return false; }
void Game::initializePlayers() { //send game map data //send players data sf::Packet * packet = new sf::Packet; *packet << Sv::GameMapData << mGameWorld.mGameMap.getName(); const std::vector<Entity *> & walls = mGameWorld.getEntitiesOfType(Entity::Type::Wall); *packet << sf::Int32(walls.size()); for (Entity * e : walls) { *packet << e->getID(); *packet << e->getPosition().x << e->getPosition().y << e->getSize().x << e->getSize().y; } pushPacket(nullptr, packet, true); //========================================// std::vector<Peer *> players; for (auto & player : mPlayers) players.push_back(player.first); //choose a zombie Zombie * z = mGameWorld.createEntity<Zombie>(Entity::Type::Zombie); Peer * zombiePlayer = players[thor::random(0u, players.size() - 1)]; mGameWorld.addEntity(z->getID()); mGameWorld.mEntitiesByPeer[zombiePlayer] = z->getID(); //remove the zombie player from players vector players.erase(std::remove(players.begin(), players.end(), zombiePlayer), players.end()); //rest are human for (Peer * human : players) { Human * h = mGameWorld.createEntity<Human>(Entity::Type::Human); mGameWorld.mEntitiesByPeer[human] = h->getID(); mGameWorld.addEntity(h->getID()); } //@zombie sf::Packet * packet2 = new sf::Packet; //zombie id, other human player size *packet2 << Sv::PlayersData << Entity::Type::Zombie << z->getID() << sf::Int32(players.size()); for (Peer * human : players) { //id, *packet2 << mGameWorld.mEntitiesByPeer[human]; } pushPacket(zombiePlayer, packet2); std::cout << "Zombie ID: " << z->getID() << "Human count: " << players.size() << std::endl; //@human for (Peer * human : players) { sf::Packet * packet3 = new sf::Packet; // zombie id player id other human player size *packet3 << Sv::PlayersData << Entity::Type::Human << z->getID() << mGameWorld.mEntitiesByPeer[human] << sf::Int32(players.size() - 1); //insert other's players info for (Peer * human2 : players) { //other player's id if (human2 != human) *packet3 << mGameWorld.mEntitiesByPeer[human2]; } pushPacket(human, packet3); } sf::Packet * packet4 = new sf::Packet; *packet4 << Sv::StartGame; pushPacket(nullptr, packet4, true); }
void CPlayerController::WeaponSkill(uint16 targid, uint16 wsid) { auto PChar = static_cast<CCharEntity*>(POwner); if (PChar->PAI->CanChangeState()) { //#TODO: put all this in weaponskill_state CWeaponSkill* PWeaponSkill = battleutils::GetWeaponSkill(wsid); if (PWeaponSkill && !charutils::hasWeaponSkill(PChar, PWeaponSkill->getID())) { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 0, MSGBASIC_CANNOT_USE_WS)); return; } if (PChar->StatusEffectContainer->HasStatusEffect(EFFECT_AMNESIA)) { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 0, MSGBASIC_CANNOT_USE_ANY_WS)); return; } if (PChar->health.tp < 1000) { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 0, MSGBASIC_NOT_ENOUGH_TP)); return; } if (PWeaponSkill->getType() == SKILL_ARC || PWeaponSkill->getType() == SKILL_MRK) { CItemWeapon* PItem = (CItemWeapon*)PChar->getEquip(SLOT_AMMO); // before allowing ranged weapon skill... if (PItem == nullptr || !(PItem->isType(ITEM_WEAPON)) || !PChar->m_Weapons[SLOT_AMMO]->isRanged() || !PChar->m_Weapons[SLOT_RANGED]->isRanged() || PChar->equip[SLOT_AMMO] == 0) { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 0, MSGBASIC_NO_RANGED_WEAPON)); return; } } std::unique_ptr<CMessageBasicPacket> errMsg; auto PTarget = PChar->IsValidTarget(targid, battleutils::isValidSelfTargetWeaponskill(wsid) ? TARGET_SELF : TARGET_ENEMY, errMsg); if (PTarget) { if (!isFaceing(PChar->loc.p, PTarget->loc.p, 40)) { PChar->pushPacket(new CMessageBasicPacket(PChar, PTarget, 0, 0, MSGBASIC_CANNOT_SEE)); return; } CController::WeaponSkill(targid, wsid); } else if (errMsg) { PChar->pushPacket(std::move(errMsg)); } } else { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 0, MSGBASIC_UNABLE_TO_USE_WS)); } }
int MpDecodeBuffer::getSamples(MpAudioSample *samplesBuffer, int requiredSamples, // required number of samples, for flowgraph sample rate MpSpeechType& speechType) { speechType = MP_SPEECH_UNKNOWN; if (m_pDejitter) { // first do actions that need to be done regardless of whether we have enough // samples m_pDejitter->frameIncrement(); JitterBufferResult jbResult = MP_JITTER_BUFFER_ERROR; // now get more samples if we don't have enough of them if (m_decodeBufferCount < requiredSamples) { // we don't have enough samples. pull some from jitter buffer for (int i = 0; m_pDecoderList[i]; i++) { // loop through all decoders and pull frames for them int payloadType = m_pDecoderList[i]->getPayloadType(); MpRtpBufPtr rtp = m_pDejitter->pullPacket(payloadType, jbResult); while (rtp.isValid()) { // if buffer is valid, then there is undecoded data, we decode it // until we have enough samples here or jitter buffer has no more data // also pass jbResult, since codec may have PLC. In that case we will use codec PLC pushPacket(rtp, jbResult); if (m_decodeBufferCount < requiredSamples) { // still don't have enough, pull more data rtp = m_pDejitter->pullPacket(payloadType, jbResult); } else { break; // we cant break out of for loop, as we need to process rfc2833 too } } } } } int suppliedSamples = 0; // Check we have some available decoded data if (m_decodeBufferCount != 0) { // We could not return more then we have suppliedSamples = min(requiredSamples, m_decodeBufferCount); int count1 = min(suppliedSamples, g_decodeBufferSize - m_decodeBufferOut); // samples to copy before wrap around occurs int count2 = suppliedSamples - count1; // number of samples to copy after wrap around memcpy(samplesBuffer, m_decodeBuffer + m_decodeBufferOut, count1 * sizeof(MpAudioSample)); if (count2 > 0) { // handle wrap around, and copy the rest from the beginning of decode buffer memcpy(samplesBuffer + count1, m_decodeBuffer, count2 * sizeof(MpAudioSample)); } m_decodeBufferCount -= suppliedSamples; m_decodeBufferOut += suppliedSamples; if (m_decodeBufferOut >= g_decodeBufferSize) m_decodeBufferOut -= g_decodeBufferSize; } if (suppliedSamples == 0) { // we will have to generate full noise frame speechType = MP_SPEECH_COMFORT_NOISE; } if (suppliedSamples < requiredSamples) { int noiseFramesNeeded = requiredSamples - suppliedSamples; m_pNoiseGenerator->generateComfortNoise(samplesBuffer + suppliedSamples, noiseFramesNeeded); } return requiredSamples; }
/** \fn nextPacket \brief Read ASF packet & segments Flags are bitwise OR of: 0x40 Explicit packet size specified word16 0X60 Means word32 0x20 Explicit packet size specified byte 0x10 16-bit padding size specified 0x18 means word32 0x08 8-bit padding size specified 0x04 sequence coded in word16 0x02 sequence coded in byte 0x01 More than one segment Docs from http://avifile.sourceforge.net/asf-1.0.htm completed by mplayer code */ uint8_t asfPacket::nextPacket(uint8_t streamWanted) { uint64_t dts; uint32_t aduration,nbSeg,payloadLengthType=0x80; uint32_t sequenceLen,len,streamId; int32_t packetLen=0; uint32_t paddingLen; int lengthTypeFlags,propertyFlags,multiplePayloadPresent; int sequenceType,sequence,offsetLenType,replicaLenType,streamNumberLenType,mediaObjectNumberLenType; packetStart=ftello(_fd); _offset=0; int r82=read8(); if(r82!=0x82) { printf("[ASF PACKET]At pos 0x%" PRIx64" \n",(uint64_t)ftello(_fd)); printf("[ASF PACKET]not a 82 packet but 0x%x\n",r82); return 0; } aprintf("============== New packet ===============\n"); read16(); // Always 0 ???? // / end of error correction // Payload parsing information packetLen=0; paddingLen=0; sequenceType=0; sequenceLen=0; sequence=0; offsetLenType=0; replicaLenType=0; streamNumberLenType=0; mediaObjectNumberLenType=0; lengthTypeFlags=read8(); propertyFlags=read8(); multiplePayloadPresent=lengthTypeFlags&1; // Read packetLen packetLen=readVCL(lengthTypeFlags>>5,pakSize); // Sequence len sequenceLen=readVCL(lengthTypeFlags>>1,0); // Read padding size (padding): paddingLen=readVCL(lengthTypeFlags>>3,0); // replicaLenType=(propertyFlags>>0)&3; offsetLenType=(propertyFlags>>2)&3; mediaObjectNumberLenType=(propertyFlags>>4)&3; streamNumberLenType=(propertyFlags>>6)&3; // Send time dts=1000*read32(); // Send time (ms) aduration=read16(); // Duration (ms) aprintf(":: Time 1 %s\n",ADM_us2plain(dts)); if(!packetLen) { // Padding (relative) size packetLen=pakSize-_offset; packetLen=packetLen-paddingLen; } int mediaObjectNumber, offset,replica,r; int32_t remaining; uint32_t payloadLen; uint32_t keyframe; // Multi payload if(multiplePayloadPresent) { uint8_t r=read8(); nbSeg=r&0x3f; payloadLengthType=r>>6; aprintf("Multiple Payload :%d\n",(int)nbSeg); // Now read Segments.... // for(int seg=0;seg<nbSeg;seg++) { r=read8(); // Read stream Id uint64_t pts=ADM_NO_PTS; if(r&0x80) { keyframe=AVI_KEY_FRAME; aprintf(">>>KeyFrame\n"); } else keyframe=0; streamId=r&0x7f; //printf(">>>>>Stream Id : %x, duration %d ms, send time:%d ms <<<<<\n",streamId,aduration,dts); mediaObjectNumber=readVCL(mediaObjectNumberLenType,0); // Media object number offset=readVCL(offsetLenType,0); replica=readVCL(replicaLenType,0); pts=readPtsFromReplica(replica); payloadLen=readVCL(payloadLengthType,0); remaining=pakSize-_offset; remaining=remaining-paddingLen; if(remaining<=0) { ADM_warning("** Err: No data left (%d)\n",remaining); } if(!payloadLen) { payloadLen=remaining; } if(remaining<payloadLen) { ADM_warning("** WARNING too big %d %d\n", remaining,packetLen); payloadLen=remaining; } // else we read "payloadLen" bytes and put them at offset "offset" if(streamId==streamWanted|| streamWanted==0xff) { pushPacket(keyframe,currentPacket,offset,mediaObjectNumber,payloadLen,streamId,dts,pts); dts=ADM_NO_PTS; }else skip(payloadLen); } } else { // single payload