|
Архив - только для чтения |
Модератор форума: andycrowz |
Форум Корзина форума Корзина Защита от Alt+F4 (Возможно ли?) |
Защита от Alt+F4 |
Добрый день всем
Уже не в первый раз возникает вопрос - возможно ли сделать так чтобы игрок нажавший Alt+F4 ещё какое-то время находился в игре? (тоесть сервер считал что игрок всё ещё в игре, не выкидывал его перса сразу) обыскиваю сейчас WorldSession и CharacterHandler но пока безуспешно
Если помог, ставь плюсик в репу :)
Сообщение # 1 написано 02.10.2012 в 10:15
|
Разве Alt+F4 не закрывает саму игру? соединение прерывается = игрока нет в сети
Каким то образом сделать, чтобы был онлайн статус пользователя, при прекращении соединения... начерта?.. (название темы как бы подразумевает, что alt+f4 - это новый вирус, или опасный читкод, или, там, отака на сервер какаято: собирается толпа детей, например, в Даларане, и все разом жмут alt+f4 ) |
за нахождение перса в игре отвечает СЕРВЕР
Мне нужен не статус а сам персонаж По-моему очевидно для чего это нужно - многих бесит что начинаешь с кем-нибудь драться а он чтобы не дать фраг берёт и дискается так вот чтобы победитель всё-таки получил свой фраг надо чтобы альт+ф4 не давало возможности свалить из игры мгновенно!
Если помог, ставь плюсик в репу :)
Сообщение # 3 написано 02.10.2012 в 11:32
|
Сообщение # 4 написано 02.10.2012 в 11:51
|
Нашёл только изменение времени АФК
в поиске alt+f4 (и аналогичные запросы) задать нельзя - не ищет Добавлено (02.10.2012, 15:27) --------------------------------------------- Подозреваю что тут но как исправить пока не знаю Code // Kick a player out of the World void WorldSession::KickPlayer() { if (m_Socket) m_Socket->CloseSocket(); } Вот ещё возможно: Code // WorldSession destructor WorldSession::~WorldSession() { // unload player if not unloaded if (_player) LogoutPlayer(true); // If have unclosed socket, close it if (m_Socket) { m_Socket->CloseSocket(); m_Socket->RemoveReference(); m_Socket = NULL; } if (m_Warden) delete m_Warden; // empty incoming packet queue WorldPacket* packet; while (_recvQueue.next(packet)) delete packet; LoginDatabase.PExecute("UPDATE account SET active_realm_id = 0 WHERE id = %u;", GetAccountId()); CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE account = %u;", GetAccountId()); }
Если помог, ставь плюсик в репу :)
|
Правильно знаешь но сокет-то закрывает сервер и перса соответственно выкидывает из игры тоже сервер
Сейчас попытался сделать так: Code // unload player if not unloaded if (_player && !_player->isInCombat()) LogoutPlayer(true); Перс остался в игре после ALT+F4 (в бою) но как только я шевельнул вторым персом сервер сразу упал Вобщем править надо именно это место но пока не знаю как Добавлено (02.10.2012, 16:52) Добавлено (02.10.2012, 21:20)
Если помог, ставь плюсик в репу :)
Сообщение # 7 написано 02.10.2012 в 21:20
|
ну по крайней мере 1 уже есть у кого патчик стоит только он жадничает и посылает на Тринити-кор (к слову сказать я прогнал поиском все возможные и невозможные комбинации фраз и так ничего и не нашёл + искал через Гугл и через Яндекс - и снова ничего)
Если помог, ставь плюсик в репу :)
Сообщение # 9 написано 02.10.2012 в 23:30
|
Лично у меня, все нормально на тринити, даже участок кода нашел, который за это отвечает.
Может укажете свое ядро и его ревизию?
Arcanum Core © Dev.
Для запросов на выдачу наград/снятие замечаний есть темы в Работе Портала. Не пишите по этому поводу в личку.
Сообщение # 10 написано 03.10.2012 в 00:16
|
Киньте ка сюда свой метод WorldSession::LogoutPlayer.
Arcanum Core © Dev.
Для запросов на выдачу наград/снятие замечаний есть темы в Работе Портала. Не пишите по этому поводу в личку.
Сообщение # 12 написано 03.10.2012 в 12:14
|
Code // Log the player out void WorldSession::LogoutPlayer(bool Save) { // finish pending transfers before starting the logout while (_player && _player->IsBeingTeleportedFar()) HandleMoveWorldportAckOpcode(); m_playerLogout = true; m_playerSave = Save; if (_player) { if (uint64 lguid = GetPlayer()->GetLootGUID()) DoLootRelease(lguid); // If the player just died before logging out, make him appear as a ghost // FIXME: logout must be delayed in case lost connection with client in time of combat if (_player->GetDeathTimer()) { _player->getHostileRefManager().deleteReferences(); _player->BuildPlayerRepop(); _player->RepopAtGraveyard(); } else if (!_player->getAttackers().empty()) { _player->CombatStop(); _player->getHostileRefManager().setOnlineOfflineState(false); _player->RemoveAllAurasOnDeath(); // build set of player who attack _player or who have pet attacking of _player std::set<Player*> aset; for (Unit::AttackerSet::const_iterator itr = _player->getAttackers().begin(); itr != _player->getAttackers().end(); ++itr) { Unit* owner = (*itr)->GetOwner(); // including player controlled case if (owner) { if (owner->GetTypeId() == TYPEID_PLAYER) aset.insert(owner->ToPlayer()); } else if ((*itr)->GetTypeId() == TYPEID_PLAYER) aset.insert((*itr)->ToPlayer()); } _player->SetPvPDeath(!aset.empty()); _player->KillPlayer(); _player->BuildPlayerRepop(); _player->RepopAtGraveyard(); // give honor to all attackers from set like group case for (std::set<Player*>::const_iterator itr = aset.begin(); itr != aset.end(); ++itr) (*itr)->RewardHonor(_player,aset.size()); // give bg rewards and update counters like kill by first from attackers // this can't be called for all attackers. if (!aset.empty()) if (BattleGround *bg = _player->GetBattleGround()) bg->HandleKillPlayer(_player,*aset.begin()); } else if (_player->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) { // this will kill character by SPELL_AURA_SPIRIT_OF_REDEMPTION _player->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT); //_player->SetDeathPvP(*); set at SPELL_AURA_SPIRIT_OF_REDEMPTION apply time _player->KillPlayer(); _player->BuildPlayerRepop(); _player->RepopAtGraveyard(); } //drop a flag if player is carrying it if (BattleGround *bg = _player->GetBattleGround()) bg->EventPlayerLoggedOut(_player); // Teleport to home if the player is in an invalid instance if (!_player->m_InstanceValid && !_player->isGameMaster()) { _player->TeleportToHomebind(); //this is a bad place to call for far teleport because we need player to be in world for successful logout //maybe we should implement delayed far teleport logout? } // FG: finish pending transfers after starting the logout // this should fix players beeing able to logout and login back with full hp at death position while (_player->IsBeingTeleportedFar()) HandleMoveWorldportAckOpcode(); sOutdoorPvPMgr.HandlePlayerLeaveZone(_player,_player->GetZoneId()); for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) { if (int32 bgTypeId = _player->GetBattleGroundQueueId(i)) { _player->RemoveBattleGroundQueueId(bgTypeId); sBattleGroundMgr.m_BattleGroundQueues[ bgTypeId ].RemovePlayer(_player->GetGUID(), true); } } // If the player is in a guild, update the guild roster and broadcast a logout message to other guild members if (Guild *guild = objmgr.GetGuildById(_player->GetGuildId())) { guild->LoadPlayerStatsByGuid(_player->GetGUID()); guild->UpdateLogoutTime(_player->GetGUID()); guild->BroadcastEvent(GE_SIGNED_OFF, _player->GetGUID(), _player->GetName()); } // Remove pet _player->RemovePet(NULL, PET_SAVE_AS_CURRENT, true); // empty buyback items and save the player in the database // some save parts only correctly work in case player present in map/player_lists (pets, etc) if (Save) { uint32 eslot; for (int j = BUYBACK_SLOT_START; j < BUYBACK_SLOT_END; ++j) { eslot = j - BUYBACK_SLOT_START; _player->SetUInt64Value(PLAYER_FIELD_VENDORBUYBACK_SLOT_1 + (eslot * 2), 0); _player->SetUInt32Value(PLAYER_FIELD_BUYBACK_PRICE_1 + eslot, 0); _player->SetUInt32Value(PLAYER_FIELD_BUYBACK_TIMESTAMP_1 + eslot, 0); } _player->SaveToDB(); } // Leave all channels before player delete... _player->CleanupChannels(); // If the player is in a group (or invited), remove him. If the group if then only 1 person, disband the group. _player->UninviteFromGroup(); // remove player from the group if he is: // a) in group; b) not in raid group; c) logging out normally (not being kicked or disconnected) if (_player->GetGroup() && !_player->GetGroup()->isRaidGroup() && m_Socket) _player->RemoveFromGroup(); // Send update to group if (_player->GetGroup()) _player->GetGroup()->SendUpdate(); // Broadcast a logout message to the player's friends sSocialMgr.SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUIDLow(), true); sSocialMgr.RemovePlayerSocial (_player->GetGUIDLow ()); // Remove the player from the world // the player may not be in the world when logging out // e.g if he got disconnected during a transfer to another map // calls to GetMap in this case may cause crashes _player->CleanupsBeforeDelete(); Map* _map = _player->GetMap(); _map->Remove(_player, true); _player = NULL; // deleted in Remove call // Send the 'logout complete' packet to the client WorldPacket data(SMSG_LOGOUT_COMPLETE, 0); SendPacket(&data); // Since each account can only have one online character at any given time, ensure all characters for active account are marked as offline //No SQL injection as AccountId is uint32 CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE account = '%u'", GetAccountId()); sLog.outDebug("SESSION: Sent SMSG_LOGOUT_COMPLETE Message"); } //Hook for OnLogout Event sScriptMgr.OnLogout(_player); m_playerLogout = false; m_playerSave = false; m_playerRecentlyLogout = true; LogoutRequest(0); }
Если помог, ставь плюсик в репу :)
Сообщение # 13 написано 03.10.2012 в 13:05
|
В вашем коде всем игрокам, которые атаковали игрока, вышедшего из игры начисляется хонор и киллы.
Не пойму, чем вас это не устраивает. Если же надо копать дальше, то копайте в сторону: Quote void WorldSession::LogoutPlayer(bool Save) { // finish pending transfers before starting the logout while (_player && _player->IsBeingTeleportedFar()) HandleMoveWorldportAckOpcode(); m_playerLogout = true; m_playerSave = Save; if (_player) { if (uint64 lguid = GetPlayer()->GetLootGUID()) DoLootRelease(lguid); // If the player just died before logging out, make him appear as a ghost // FIXME: logout must be delayed in case lost connection with client in time of combat if (_player->GetDeathTimer()) { _player->getHostileRefManager().deleteReferences(); _player->BuildPlayerRepop(); _player->RepopAtGraveyard(); } else if (!_player->getAttackers().empty()) { _player->CombatStop(); _player->getHostileRefManager().setOnlineOfflineState(false); _player->RemoveAllAurasOnDeath(); // build set of player who attack _player or who have pet attacking of _player std::set<Player*> aset; for (Unit::AttackerSet::const_iterator itr = _player->getAttackers().begin(); itr != _player->getAttackers().end(); ++itr) { Unit* owner = (*itr)->GetOwner(); // including player controlled case if (owner) { if (owner->GetTypeId() == TYPEID_PLAYER) aset.insert(owner->ToPlayer()); } else if ((*itr)->GetTypeId() == TYPEID_PLAYER) aset.insert((*itr)->ToPlayer()); } _player->SetPvPDeath(!aset.empty()); _player->KillPlayer(); _player->BuildPlayerRepop(); _player->RepopAtGraveyard(); // give honor to all attackers from set like group case for (std::set<Player*>::const_iterator itr = aset.begin(); itr != aset.end(); ++itr) (*itr)->RewardHonor(_player,aset.size()); // give bg rewards and update counters like kill by first from attackers // this can't be called for all attackers. if (!aset.empty()) if (BattleGround *bg = _player->GetBattleGround()) bg->HandleKillPlayer(_player,*aset.begin()); } else if (_player->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) { // this will kill character by SPELL_AURA_SPIRIT_OF_REDEMPTION _player->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT); //_player->SetDeathPvP(*); set at SPELL_AURA_SPIRIT_OF_REDEMPTION apply time _player->KillPlayer(); _player->BuildPlayerRepop(); _player->RepopAtGraveyard(); } //drop a flag if player is carrying it if (BattleGround *bg = _player->GetBattleGround()) bg->EventPlayerLoggedOut(_player); // Teleport to home if the player is in an invalid instance if (!_player->m_InstanceValid && !_player->isGameMaster()) { _player->TeleportToHomebind(); //this is a bad place to call for far teleport because we need player to be in world for successful logout //maybe we should implement delayed far teleport logout? } // FG: finish pending transfers after starting the logout // this should fix players beeing able to logout and login back with full hp at death position while (_player->IsBeingTeleportedFar()) HandleMoveWorldportAckOpcode(); sOutdoorPvPMgr.HandlePlayerLeaveZone(_player,_player->GetZoneId()); for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) { if (int32 bgTypeId = _player->GetBattleGroundQueueId(i)) { _player->RemoveBattleGroundQueueId(bgTypeId); sBattleGroundMgr.m_BattleGroundQueues[ bgTypeId ].RemovePlayer(_player->GetGUID(), true); } } // If the player is in a guild, update the guild roster and broadcast a logout message to other guild members if (Guild *guild = objmgr.GetGuildById(_player->GetGuildId())) { guild->LoadPlayerStatsByGuid(_player->GetGUID()); guild->UpdateLogoutTime(_player->GetGUID()); guild->BroadcastEvent(GE_SIGNED_OFF, _player->GetGUID(), _player->GetName()); } // Remove pet _player->RemovePet(NULL, PET_SAVE_AS_CURRENT, true); // empty buyback items and save the player in the database // some save parts only correctly work in case player present in map/player_lists (pets, etc) if (Save) { uint32 eslot; for (int j = BUYBACK_SLOT_START; j < BUYBACK_SLOT_END; ++j) { eslot = j - BUYBACK_SLOT_START; _player->SetUInt64Value(PLAYER_FIELD_VENDORBUYBACK_SLOT_1 + (eslot * 2), 0); _player->SetUInt32Value(PLAYER_FIELD_BUYBACK_PRICE_1 + eslot, 0); _player->SetUInt32Value(PLAYER_FIELD_BUYBACK_TIMESTAMP_1 + eslot, 0); } _player->SaveToDB(); } // Leave all channels before player delete... _player->CleanupChannels(); // If the player is in a group (or invited), remove him. If the group if then only 1 person, disband the group. _player->UninviteFromGroup(); // remove player from the group if he is: // a) in group; b) not in raid group; c) logging out normally (not being kicked or disconnected) if (_player->GetGroup() && !_player->GetGroup()->isRaidGroup() && m_Socket) _player->RemoveFromGroup(); // Send update to group if (_player->GetGroup()) _player->GetGroup()->SendUpdate(); // Broadcast a logout message to the player's friends sSocialMgr.SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUIDLow(), true); sSocialMgr.RemovePlayerSocial (_player->GetGUIDLow ()); // Remove the player from the world // the player may not be in the world when logging out // e.g if he got disconnected during a transfer to another map // calls to GetMap in this case may cause crashes _player->CleanupsBeforeDelete(); Map* _map = _player->GetMap(); _map->Remove(_player, true); _player = NULL; // deleted in Remove call // Send the 'logout complete' packet to the client WorldPacket data(SMSG_LOGOUT_COMPLETE, 0); SendPacket(&data); // Since each account can only have one online character at any given time, ensure all characters for active account are marked as offline //No SQL injection as AccountId is uint32 CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE account = '%u'", GetAccountId()); sLog.outDebug("SESSION: Sent SMSG_LOGOUT_COMPLETE Message"); } //Hook for OnLogout Event sScriptMgr.OnLogout(_player); m_playerLogout = false; m_playerSave = false; m_playerRecentlyLogout = true; LogoutRequest(0); }
Arcanum Core © Dev.
Для запросов на выдачу наград/снятие замечаний есть темы в Работе Портала. Не пишите по этому поводу в личку. |
хех если бы начислялось я бы не парился
я видел кусок кода который за это должен отвечать но к сожалению он почему-то не работает (только что проверил - зашёл в 2 окна начал драться и одним игроком вышел из игры через Alt+F4 - ничего не начислили) я думал поставить таймер но честно говоря так пока и не разобрался со структурой таймеров это на сколько я понимаю надо создавать VOID типа void Timer(const uint32 diff) а дальше уже задавать условия, но МОЖНО ЛИ такое создавать внутри void WorldSession::LogoutPlayer(bool Save) вот это вопрос вопросов
Если помог, ставь плюсик в репу :)
|
Ха-ха, смешная ситуация, сейчас кину решение.
Arcanum Core © Dev.
Для запросов на выдачу наград/снятие замечаний есть темы в Работе Портала. Не пишите по этому поводу в личку.
Сообщение # 16 написано 03.10.2012 в 13:54
|
Code diff -r af889f221f44 src/server/game/Server/WorldSession.cpp --- a/src/server/game/Server/WorldSession.cpp Sun Sep 23 13:33:58 2012 +0300 +++ b/src/server/game/Server/WorldSession.cpp Wed Oct 03 12:55:49 2012 +0300 @@ -417,10 +417,6 @@ } else if (!_player->getAttackers().empty()) { - _player->CombatStop(); - _player->getHostileRefManager().setOnlineOfflineState(false); - _player->RemoveAllAurasOnDeath(); - // build set of player who attack _player or who have pet attacking of _player std::set<Player*> aset; for (Unit::AttackerSet::const_iterator itr = _player->getAttackers().begin(); itr != _player->getAttackers().end(); ++itr) @@ -432,11 +428,6 @@ aset.insert((Player*)(*itr)); } - _player->SetPvPDeath(!aset.empty()); - _player->KillPlayer(); - _player->BuildPlayerRepop(); - _player->RepopAtGraveyard(); - // give honor to all attackers from set like group case for (std::set<Player*>::const_iterator itr = aset.begin(); itr != aset.end(); ++itr) (*itr)->RewardHonor(_player, aset.size()); @@ -446,6 +437,14 @@ if (!aset.empty()) if (Battleground* bg = _player->GetBattleground()) bg->HandleKillPlayer(_player, *aset.begin()); + + _player->CombatStop(); + _player->getHostileRefManager().setOnlineOfflineState(false); + _player->RemoveAllAurasOnDeath(); + _player->SetPvPDeath(!aset.empty()); + _player->KillPlayer(); + _player->BuildPlayerRepop(); + _player->RepopAtGraveyard(); } else if (_player->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) {
Arcanum Core © Dev.
Для запросов на выдачу наград/снятие замечаний есть темы в Работе Портала. Не пишите по этому поводу в личку.
Сообщение # 17 написано 03.10.2012 в 13:56
|
опаньки....
тоесть вся проблема просто в расположении строк? походу я так мало ещё знаю .............. просто не могу понять логики а ОЧЕНЬ хочется понять Ставлю плюс так как решение работает - но я не понял как получилось
Если помог, ставь плюсик в репу :)
|
Логика в том, что метод CombatStop() удаляет список всех атакующих.
Если поставить его до выдачи наград, то ясное дело, награды никому не выдадутся.
Arcanum Core © Dev.
Для запросов на выдачу наград/снятие замечаний есть темы в Работе Портала. Не пишите по этому поводу в личку.
Сообщение # 19 написано 03.10.2012 в 14:06
|
Данная тема была перемещена из раздела [TrinityCore] Help.
Причина перемещения: Решено, пошел делать пулл реквест в офф. репо. Переместил: Dimitro.
Arcanum Core © Dev.
Для запросов на выдачу наград/снятие замечаний есть темы в Работе Портала. Не пишите по этому поводу в личку.
Сообщение # 21 написано 03.10.2012 в 14:10
|
| |||
| |||