mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-28 15:17:46 +00:00
Persistence for cross-class skills
This commit is contained in:
parent
cf32d4fe4d
commit
f4a3c9493b
9 changed files with 54 additions and 8 deletions
1
sql/migrations/20230309164293_AddBorrowAction.sql
Normal file
1
sql/migrations/20230309164293_AddBorrowAction.sql
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE `characlass` ADD `BorrowAction` binary(40) DEFAULT NULL NULL AFTER `Lvl`;
|
|
@ -256,12 +256,14 @@ void PlayerMinimal::saveAsNew()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CharacterId, ClassIdx, Exp, Lvl
|
// CharacterId, ClassIdx, Exp, Lvl, BorrowAction
|
||||||
auto stmtClass = g_charaDb.getPreparedStatement( Db::ZoneDbStatements::CHARA_CLASS_INS );
|
auto stmtClass = g_charaDb.getPreparedStatement( Db::ZoneDbStatements::CHARA_CLASS_INS );
|
||||||
stmtClass->setUInt64( 1, m_characterId );
|
stmtClass->setUInt64( 1, m_characterId );
|
||||||
stmtClass->setInt( 2, g_exdData.getRow< Excel::ClassJob >( m_class )->data().WorkIndex );
|
stmtClass->setInt( 2, g_exdData.getRow< Excel::ClassJob >( m_class )->data().WorkIndex );
|
||||||
stmtClass->setInt( 3, 0 );
|
stmtClass->setInt( 3, 0 );
|
||||||
stmtClass->setInt( 4, 1 );
|
stmtClass->setInt( 4, 1 );
|
||||||
|
std::vector< uint8_t > borrowActionVec( Common::ARRSIZE_BORROWACTION * 4 );
|
||||||
|
stmtClass->setBinary( 5, borrowActionVec );
|
||||||
g_charaDb.directExecute( stmtClass );
|
g_charaDb.directExecute( stmtClass );
|
||||||
|
|
||||||
auto stmtSearchInfo = g_charaDb.getPreparedStatement( Db::ZoneDbStatements::CHARA_SEARCHINFO_INS );
|
auto stmtSearchInfo = g_charaDb.getPreparedStatement( Db::ZoneDbStatements::CHARA_SEARCHINFO_INS );
|
||||||
|
|
|
@ -37,6 +37,7 @@ namespace Sapphire::Common
|
||||||
const uint16_t ARRSIZE_UNLOCKS = 64u;
|
const uint16_t ARRSIZE_UNLOCKS = 64u;
|
||||||
const uint16_t ARRSIZE_ORCHESTRION = 40u;
|
const uint16_t ARRSIZE_ORCHESTRION = 40u;
|
||||||
const uint16_t ARRSIZE_MONSTERNOTE = 12u;
|
const uint16_t ARRSIZE_MONSTERNOTE = 12u;
|
||||||
|
const uint16_t ARRSIZE_BORROWACTION = 10u;
|
||||||
|
|
||||||
const uint8_t TOWN_COUNT = 6;
|
const uint8_t TOWN_COUNT = 6;
|
||||||
|
|
||||||
|
|
|
@ -161,11 +161,11 @@ void Sapphire::Db::ZoneDbConnection::doPrepareStatements()
|
||||||
prepareStatement( CHARA_SEL_QUEST, "SELECT * FROM charaquest WHERE CharacterId = ?;", CONNECTION_SYNC );
|
prepareStatement( CHARA_SEL_QUEST, "SELECT * FROM charaquest WHERE CharacterId = ?;", CONNECTION_SYNC );
|
||||||
|
|
||||||
/// CLASS INFO
|
/// CLASS INFO
|
||||||
prepareStatement( CHARA_CLASS_SEL, "SELECT ClassIdx, Exp, Lvl FROM characlass WHERE CharacterId = ?;",
|
prepareStatement( CHARA_CLASS_SEL, "SELECT ClassIdx, Exp, Lvl, BorrowAction FROM characlass WHERE CharacterId = ?;",
|
||||||
CONNECTION_SYNC );
|
CONNECTION_SYNC );
|
||||||
prepareStatement( CHARA_CLASS_INS, "INSERT INTO characlass ( CharacterId, ClassIdx, Exp, Lvl ) VALUES( ?,?,?,? );",
|
prepareStatement( CHARA_CLASS_INS, "INSERT INTO characlass ( CharacterId, ClassIdx, Exp, Lvl, BorrowAction ) VALUES( ?,?,?,?,? );",
|
||||||
CONNECTION_BOTH );
|
CONNECTION_BOTH );
|
||||||
prepareStatement( CHARA_CLASS_UP, "UPDATE characlass SET Exp = ?, Lvl = ? WHERE CharacterId = ? AND ClassIdx = ?;",
|
prepareStatement( CHARA_CLASS_UP, "UPDATE characlass SET Exp = ?, Lvl = ?, BorrowAction = ? WHERE CharacterId = ? AND ClassIdx = ?;",
|
||||||
CONNECTION_ASYNC );
|
CONNECTION_ASYNC );
|
||||||
prepareStatement( CHARA_CLASS_DEL, "DELETE FROM characlass WHERE CharacterId = ?;", CONNECTION_ASYNC );
|
prepareStatement( CHARA_CLASS_DEL, "DELETE FROM characlass WHERE CharacterId = ?;", CONNECTION_ASYNC );
|
||||||
|
|
||||||
|
|
|
@ -563,6 +563,22 @@ void Player::setRewardFlag( Common::UnlockEntry unlockId )
|
||||||
Network::Util::Player::sendActorControlSelf( *this, SetRewardFlag, unlock, 1 );
|
Network::Util::Player::sendActorControlSelf( *this, SetRewardFlag, unlock, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::setBorrowAction( uint8_t slot, uint32_t action )
|
||||||
|
{
|
||||||
|
if( slot > Common::ARRSIZE_BORROWACTION )
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto& borrowAction = getBorrowAction();
|
||||||
|
borrowAction[ slot ] = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player::BorrowAction& Player::getBorrowAction()
|
||||||
|
{
|
||||||
|
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||||
|
uint8_t classJobIndex = exdData.getRow< Excel::ClassJob >( static_cast<uint8_t>( getClass() ) )->data().WorkIndex;
|
||||||
|
return m_borrowActions[ classJobIndex ];
|
||||||
|
}
|
||||||
|
|
||||||
void Player::learnSong( uint8_t songId, uint32_t itemId )
|
void Player::learnSong( uint8_t songId, uint32_t itemId )
|
||||||
{
|
{
|
||||||
uint16_t index;
|
uint16_t index;
|
||||||
|
|
|
@ -38,6 +38,7 @@ namespace Sapphire::Entity
|
||||||
|
|
||||||
using ClassList = std::array< uint16_t, Common::ARRSIZE_CLASSJOB >;
|
using ClassList = std::array< uint16_t, Common::ARRSIZE_CLASSJOB >;
|
||||||
using ExpList = std::array< uint32_t, Common::ARRSIZE_CLASSJOB >;
|
using ExpList = std::array< uint32_t, Common::ARRSIZE_CLASSJOB >;
|
||||||
|
using BorrowAction = std::array< uint32_t, Common::ARRSIZE_BORROWACTION >;
|
||||||
|
|
||||||
struct AchievementData {
|
struct AchievementData {
|
||||||
std::array< uint8_t, 2048 / 8 > unlockList;
|
std::array< uint8_t, 2048 / 8 > unlockList;
|
||||||
|
@ -446,6 +447,10 @@ namespace Sapphire::Entity
|
||||||
/*! learn an action / update the unlock bitmask. */
|
/*! learn an action / update the unlock bitmask. */
|
||||||
void setRewardFlag( Common::UnlockEntry unlockId );
|
void setRewardFlag( Common::UnlockEntry unlockId );
|
||||||
|
|
||||||
|
void setBorrowAction( uint8_t slot, uint32_t action );
|
||||||
|
|
||||||
|
BorrowAction& getBorrowAction();
|
||||||
|
|
||||||
/*! learn a song / update the unlock bitmask. */
|
/*! learn a song / update the unlock bitmask. */
|
||||||
void learnSong( uint8_t songId, uint32_t itemId );
|
void learnSong( uint8_t songId, uint32_t itemId );
|
||||||
|
|
||||||
|
@ -966,6 +971,8 @@ namespace Sapphire::Entity
|
||||||
|
|
||||||
std::array< Common::HuntingLogEntry, Common::ARRSIZE_MONSTERNOTE > m_huntingLogEntries{};
|
std::array< Common::HuntingLogEntry, Common::ARRSIZE_MONSTERNOTE > m_huntingLogEntries{};
|
||||||
|
|
||||||
|
std::array< BorrowAction, Common::ARRSIZE_CLASSJOB > m_borrowActions{};
|
||||||
|
|
||||||
FriendListIDVec m_friendList{};
|
FriendListIDVec m_friendList{};
|
||||||
FriendListDataVec m_friendInviteList{};
|
FriendListDataVec m_friendInviteList{};
|
||||||
|
|
||||||
|
|
|
@ -258,7 +258,7 @@ bool Sapphire::Entity::Player::loadAchievements()
|
||||||
bool Sapphire::Entity::Player::loadClassData()
|
bool Sapphire::Entity::Player::loadClassData()
|
||||||
{
|
{
|
||||||
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
||||||
// ClassIdx, Exp, Lvl
|
// ClassIdx, Exp, Lvl, BorrowAction
|
||||||
auto stmt = db.getPreparedStatement( Db::ZoneDbStatements::CHARA_CLASS_SEL );
|
auto stmt = db.getPreparedStatement( Db::ZoneDbStatements::CHARA_CLASS_SEL );
|
||||||
stmt->setUInt64( 1, m_characterId );
|
stmt->setUInt64( 1, m_characterId );
|
||||||
auto res = db.query( stmt );
|
auto res = db.query( stmt );
|
||||||
|
@ -268,9 +268,11 @@ bool Sapphire::Entity::Player::loadClassData()
|
||||||
auto index = res->getUInt16( 1 );
|
auto index = res->getUInt16( 1 );
|
||||||
auto exp = res->getUInt( 2 );
|
auto exp = res->getUInt( 2 );
|
||||||
auto lvl = res->getUInt8( 3 );
|
auto lvl = res->getUInt8( 3 );
|
||||||
|
auto borrowAction = res->getBlobVector( "BorrowAction" );
|
||||||
|
|
||||||
m_classArray[ index ] = lvl;
|
m_classArray[ index ] = lvl;
|
||||||
m_expArray[ index ] = exp;
|
m_expArray[ index ] = exp;
|
||||||
|
memcpy( m_borrowActions[ index ].data(), borrowAction.data(), borrowAction.size() );
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -487,13 +489,19 @@ void Sapphire::Entity::Player::updateDbClass() const
|
||||||
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
||||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||||
uint8_t classJobIndex = exdData.getRow< Excel::ClassJob >( static_cast<uint8_t>( getClass() ) )->data().WorkIndex;
|
uint8_t classJobIndex = exdData.getRow< Excel::ClassJob >( static_cast<uint8_t>( getClass() ) )->data().WorkIndex;
|
||||||
|
auto& borrowAction = m_borrowActions[ classJobIndex ];
|
||||||
|
|
||||||
//Exp = ?, Lvl = ? WHERE CharacterId = ? AND ClassIdx = ?
|
//Exp = ?, Lvl = ?, BorrowAction = ? WHERE CharacterId = ? AND ClassIdx = ?
|
||||||
auto stmtS = db.getPreparedStatement( Db::CHARA_CLASS_UP );
|
auto stmtS = db.getPreparedStatement( Db::CHARA_CLASS_UP );
|
||||||
stmtS->setInt( 1, getExp() );
|
stmtS->setInt( 1, getExp() );
|
||||||
stmtS->setInt( 2, getLevel() );
|
stmtS->setInt( 2, getLevel() );
|
||||||
stmtS->setUInt64( 3, m_characterId );
|
|
||||||
stmtS->setInt( 4, classJobIndex );
|
std::vector< uint8_t > borrowActionVec( borrowAction.size() * 4 );
|
||||||
|
memcpy( borrowActionVec.data(), borrowAction.data(), borrowAction.size() * 4 );
|
||||||
|
stmtS->setBinary( 3, borrowActionVec );
|
||||||
|
|
||||||
|
stmtS->setUInt64( 4, m_characterId );
|
||||||
|
stmtS->setInt( 5, classJobIndex );
|
||||||
db.execute( stmtS );
|
db.execute( stmtS );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,10 +589,14 @@ void Sapphire::Entity::Player::insertDbClass( const uint8_t classJobIndex, uint8
|
||||||
{
|
{
|
||||||
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
||||||
auto stmtClass = db.getPreparedStatement( Db::CHARA_CLASS_INS );
|
auto stmtClass = db.getPreparedStatement( Db::CHARA_CLASS_INS );
|
||||||
|
auto& borrowAction = m_borrowActions[ classJobIndex ];
|
||||||
|
|
||||||
stmtClass->setUInt64( 1, m_characterId );
|
stmtClass->setUInt64( 1, m_characterId );
|
||||||
stmtClass->setInt( 2, classJobIndex );
|
stmtClass->setInt( 2, classJobIndex );
|
||||||
stmtClass->setInt( 3, 0 );
|
stmtClass->setInt( 3, 0 );
|
||||||
stmtClass->setInt( 4, level );
|
stmtClass->setInt( 4, level );
|
||||||
|
std::vector< uint8_t > borrowActionVec( borrowAction.size() );
|
||||||
|
stmtClass->setBinary( 5, borrowActionVec );
|
||||||
db.directExecute( stmtClass );
|
db.directExecute( stmtClass );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -497,6 +497,11 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
|
||||||
Network::Util::Player::sendTitleList( player );
|
Network::Util::Player::sendTitleList( player );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PacketCommand::BORROW_ACTION:
|
||||||
|
{
|
||||||
|
player.setBorrowAction( static_cast< uint8_t >( data.Arg1 ), data.Arg2 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
case PacketCommand::SET_HOWTO: // Update howtos seen
|
case PacketCommand::SET_HOWTO: // Update howtos seen
|
||||||
{
|
{
|
||||||
player.updateHowtosSeen( data.Arg0 );
|
player.updateHowtosSeen( data.Arg0 );
|
||||||
|
|
|
@ -291,10 +291,12 @@ void Util::Player::sendPlayerSetup( Entity::Player& player )
|
||||||
void Util::Player::sendChangeClass( Entity::Player& player )
|
void Util::Player::sendChangeClass( Entity::Player& player )
|
||||||
{
|
{
|
||||||
auto classInfo = makeZonePacket< FFXIVIpcChangeClass >( player.getId() );
|
auto classInfo = makeZonePacket< FFXIVIpcChangeClass >( player.getId() );
|
||||||
|
auto& borrowAction = player.getBorrowAction();
|
||||||
classInfo->data().ClassJob = static_cast< uint8_t >( player.getClass() );
|
classInfo->data().ClassJob = static_cast< uint8_t >( player.getClass() );
|
||||||
classInfo->data().Lv = player.getLevel();
|
classInfo->data().Lv = player.getLevel();
|
||||||
classInfo->data().Lv1 = player.getLevel();
|
classInfo->data().Lv1 = player.getLevel();
|
||||||
classInfo->data().Login = player.isLogin() ? 1 : 0;
|
classInfo->data().Login = player.isLogin() ? 1 : 0;
|
||||||
|
memcpy( &classInfo->data().BorrowAction[ 0 ], borrowAction.data(), borrowAction.size() * 4 );
|
||||||
server().queueForPlayer( player.getCharacterId(), classInfo );
|
server().queueForPlayer( player.getCharacterId(), classInfo );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue