1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-26 06:27:45 +00:00

Merged most recent 4.1 fixes to SQL rewrites, new fields will have to be readded by hand

This commit is contained in:
Mordred Admin 2017-10-11 10:16:25 +02:00
commit 292e1e5d15
28 changed files with 678 additions and 157 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 537 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View file

@ -0,0 +1,38 @@
class CmnDefCutSceneReplayDef
{
def CmnDefCutSceneReplayDef()
{
this.id = 721028;
}
def Scene00000( player )
{
player.eventPlay( this.id, 0, 0x2000/*flags*/, 0/*unk*/, 1/*unk*/,
fun( player, eventId, param1, param2, param3 )
{
if( param2 != 0 )
{
CmnDefCutSceneReplay.Scene00001( player, param2 );
}
});
}
def Scene00001( player, returnScene )
{
player.eventPlay( this.id, 1, 0xFB2EC8F8/*flags*/, 0/*unk*/, 1, returnScene,
fun( player, eventId, param1, param2, param3 )
{
});
}
def onTalk( eventId, player, actorId )
{
this.Scene00000( player );
}
};
GLOBAL CmnDefCutSceneReplay = CmnDefCutSceneReplayDef();

View file

@ -0,0 +1,62 @@
class CmnDefInnBedDef
{
def CmnDefInnBedDef()
{
this.id = 720916;
}
def Scene00000( player ) //Menu
{
player.eventPlay( this.id, 0, 0x2000/*flags*/, 0/*unk*/, 1/*unk*/,
fun( player, eventId, param1, param2, param3 )
{
if( param2 > 1 )
{
CmnDefInnBed.Scene00001( player, param2 );
}
});
}
def Scene00001( player, what ) //Lay down
{
player.eventPlay( this.id, 1, 0xF32E48F8/*flags*/, 0/*unk*/, 1/*unk*/, what,
fun( player, eventId, param1, param2, param3 )
{
CmnDefInnBed.Scene00002( player, param2 );
});
}
def Scene00002( player, what ) //Log out
{
player.eventPlay( this.id, 2, 0xF32E48F8/*flags*/, 0/*unk*/, 1/*unk*/, what,
fun( player, eventId, param1, param2, param3 )
{
});
}
def Scene00100( player ) //Wake up
{
player.eventPlay( this.id, 100, 0xF32E48F8/*flags*/, 0/*unk*/, 0/*unk*/,
fun( player, eventId, param1, param2, param3 )
{
});
}
def onTalk( eventId, player, actorId )
{
this.Scene00000( player );
}
def onEnterTerritory( eventId, player, param1, param2 )
{
this.Scene00100( player );
}
};
GLOBAL CmnDefInnBed = CmnDefInnBedDef();

View file

@ -0,0 +1,26 @@
class HouFurOrchestrionDef
{
def HouFurOrchestrionDef()
{
this.id = 721226;
}
def Scene00000( player )
{
player.eventPlay( this.id, 0, 0x2000/*flags*/, 0/*unk*/, 1/*unk*/,
fun( player, eventId, param1, param2, param3 )
{
});
}
def onTalk( eventId, player, actorId )
{
this.Scene00000( player );
}
};
GLOBAL HouFurOrchestrion = HouFurOrchestrionDef();

90
sql/charadetail.sql Normal file
View file

@ -0,0 +1,90 @@
-- --------------------------------------------------------
-- Host: 127.0.0.1
-- Server version: 10.1.24-MariaDB - mariadb.org binary distribution
-- Server OS: Win32
-- HeidiSQL Version: 9.4.0.5125
-- --------------------------------------------------------
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8 */;
/*!50503 SET NAMES utf8mb4 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
-- Dumping structure for table sapphire.charadetail
CREATE TABLE IF NOT EXISTS `charadetail` (
`GuardianDeity` int(3) DEFAULT NULL,
`BirthDay` int(3) DEFAULT NULL,
`BirthMonth` int(3) NOT NULL,
`Class` int(3) DEFAULT NULL,
`MakeValid` int(3) DEFAULT NULL,
`RetainerId` int(20) DEFAULT NULL,
`RetainerName` varchar(32) DEFAULT NULL,
`CreateUnixTime` int(20) DEFAULT NULL,
`IsActive` int(3) DEFAULT NULL,
`IsRename` int(3) DEFAULT NULL,
`Status` int(3) DEFAULT NULL,
`Platform` varchar(32) DEFAULT NULL,
`TotalPlayTime` int(10) DEFAULT '0',
`TotalPlayTimeSecond` float DEFAULT NULL,
`FirstClass` int(3) DEFAULT NULL,
`HomePoint` int(3) DEFAULT NULL,
`FavoritePoint` binary(3) DEFAULT NULL,
`RestPoint` int(10) DEFAULT NULL,
`RentalTimer` float DEFAULT NULL,
`StartTown` int(3) DEFAULT NULL,
`ActiveTitle` int(5) DEFAULT NULL,
`TitleList` binary(32) DEFAULT NULL,
`Achievement` binary(16) DEFAULT NULL,
`Aetheryte` binary(16) DEFAULT NULL,
`HowTo` binary(33) DEFAULT NULL,
`Minions` binary(33) DEFAULT NULL,
`Mounts` binary(13) DEFAULT NULL,
`EquippedMannequin` int(5) DEFAULT NULL,
`ConfigFlags` smallint(5) NOT NULL DEFAULT '0',
`GatheringHistoryPointId` binary(8) DEFAULT NULL,
`GatheringDivisionOpenFla` binary(40) DEFAULT NULL,
`GatheringItemGetFlags` binary(60) DEFAULT NULL,
`RecipeDivisionOpenFlags` binary(80) DEFAULT NULL,
`RecipeCreateFlags` binary(100) DEFAULT NULL,
`QuestCompleteFlags` binary(200) DEFAULT NULL,
`LeveCompleteFlags` binary(200) DEFAULT NULL,
`OpeningSequence` int(3) DEFAULT '0',
`QuestTracking` binary(10) DEFAULT NULL,
`LeveTicketNum` int(3) DEFAULT NULL,
`LeveTicketLastGetTime` int(10) DEFAULT NULL,
`GuildleveAssignmentSeed` int(5) DEFAULT NULL,
`GuildleveAssignmentCount` int(3) DEFAULT NULL,
`GuildleveFactionCreditBr` int(5) DEFAULT NULL,
`GuildleveFactionCreditAz` int(5) DEFAULT NULL,
`GuildleveFactionCreditHo` int(5) DEFAULT NULL,
`GrandCompany` int(3) DEFAULT NULL,
`GrandCompanyRank` binary(3) DEFAULT NULL,
`Discovery` blob,
`ContentRetryTime` blob,
`ContentJoinTime` int(10) DEFAULT NULL,
`ContentClearFlag` blob,
`CFPenaltyUntil` int(10) unsigned NOT NULL DEFAULT '0',
`TownWarpFstFlags` binary(2) DEFAULT NULL,
`PathId` int(10) DEFAULT NULL,
`StepIndex` int(5) DEFAULT NULL,
`ChocoboTaxiStandFlags` binary(8) DEFAULT NULL,
`GMRank` int(3) DEFAULT '0',
`EquipDisplayFlags` int(3) DEFAULT '0',
`unlocks` binary(64) DEFAULT NULL,
`Orchestrion` binary(38) DEFAULT NULL,
`CharacterId` int(20) NOT NULL DEFAULT '0',
`IS_DELETE` int(3) DEFAULT '0',
`IS_NOT_ACTIVE_FLG` int(3) DEFAULT '0',
`UPDATE_DATE` datetime DEFAULT NULL,
PRIMARY KEY (`CharacterId`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- Dumping data for table sapphire.charadetail: 0 rows
DELETE FROM `charadetail`;
/*!40000 ALTER TABLE `charadetail` DISABLE KEYS */;
/*!40000 ALTER TABLE `charadetail` ENABLE KEYS */;
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

View file

@ -15,4 +15,11 @@
-- ADD `Lv_25` INT(5) NOT NULL DEFAULT '0' AFTER `Exp_24`,
-- ADD `Exp_25` INT(19) NOT NULL DEFAULT '0' AFTER `Lv_25`;
-- -------------------------------------------
-- update.sql Before Merge into Other SQL's 30/08/2017
-- update.sql Before Merge into Other SQL's 30/08/2017
-- -------------------------------------------
-- ALTER TABLE `charadetail` ADD `EquipDisplayFlags` int(3) DEFAULT '0' AFTER `GMRank`;
-- -------------------------------------------
-- update.sql before titles added 09/10/2017
ALTER TABLE `charadetail` CHANGE `TitleList` `Titlelist` BINARY(48) NULL DEFAULT NULL;
ALTER TABLE `charadetail` ADD COLUMN `Orchestrion` BINARY(38) DEFAULT NULL AFTER `unlocks`;

View file

@ -917,9 +917,11 @@ namespace Core {
SetMaxGearSets = 0x230,
ToggleDisplayHeadAndWeapon = 0x260,
SetCharaGearParamUI = 0x260,
GearSetEquipMsg = 0x321
GearSetEquipMsg = 0x321,
ToggleOrchestrionUnlock = 0x396
};
enum struct ChatType : uint32_t
@ -1027,6 +1029,15 @@ namespace Core {
Unused100
};
enum EquipDisplayFlags : uint8_t
{
HideNothing = 0x0,
HideHead = 0x1,
HideWeapon = 0x2,
Visor = 0x40,
};
struct ServerEntry
{
uint32_t serverId;

View file

@ -85,7 +85,7 @@ bool Core::Data::ExdData::loadZoneInfo()
int16_t map_index = getField< int16_t >( mapDataFields, 12 );
bool is_two_bytes = getField< bool >( mapDataFields, 15 );
uint8_t weather_rate = getField< uint8_t >( fields, 10 ) > 75 ? 0 : getField< uint8_t >( fields, 10 );
uint16_t weather_rate = getField< uint16_t >( fields, 10 ) > 75 ? 0 : getField< uint16_t >( fields, 10 );
auto weatherRateFields = weatherRate.get_row( weather_rate );
int32_t aetheryte_index = getField< int32_t >( fields, 20 );
@ -136,6 +136,16 @@ bool Core::Data::ExdData::loadStatusEffectInfo()
StatusEffectInfo info { 0 };
info.id = id;
info.name = getField< std::string >( fields, 0 );
info.lock_movement = getField< bool >( fields, 7 ); // 7
info.lock_actions = getField< bool >( fields, 9 ); // 9
info.lock_control = getField< bool >( fields, 10 ); // 10
info.transfiguration = getField< bool >( fields, 11 ); // 11
info.can_dispel = getField< bool >( fields, 13 ); // 13
info.is_permanent = getField< bool >( fields, 15 ); // 15
info.inflicted_by_actor = getField< bool >( fields, 17 ); // 17
info.is_fc_buff = getField< bool >( fields, 21 ); // 21
info.invisibility = getField< bool >( fields, 22 ); // 22
m_statusEffectInfoMap[id] = info;
}
@ -355,6 +365,9 @@ bool Core::Data::ExdData::loadActionInfo()
uint16_t toggle_status_id = getField< uint16_t >( fields, 42 ); // 42
bool affects_position = getField< bool >( fields, 47 ); // 47
bool no_effect_in_battle = getField< bool >( fields, 60 ); // 60
info->id = id;
info->name = name;
info->category = category;
@ -389,6 +402,8 @@ bool Core::Data::ExdData::loadActionInfo()
info->toggle_status_id = toggle_status_id;
info->affects_position = affects_position;
info->no_effect_in_battle = no_effect_in_battle;
// If action type is SingleTarget with an AoE radius set, or if action type isn't SingleTarget
info->is_aoe = ( info->aoe_type == 1 && info->aoe_width != 0 ) || ( info->aoe_type != 1 );
@ -520,26 +535,26 @@ boost::shared_ptr< Core::Data::QuestInfo >
info->quest_level = getField< uint16_t >( row, 4 );
info->enpc_resident_start = getField< uint32_t >( row, 38 );
info->enpc_resident_end = getField< uint32_t >( row, 40 );
info->enpc_resident_start = getField< uint32_t >( row, 40 );
info->enpc_resident_end = getField< uint32_t >( row, 42 );
info->reward_exp_factor = getField< uint16_t >( row, 1437 );
info->reward_gil = getField< uint32_t >( row, 1438 );
info->reward_gc_seals = getField< uint16_t >( row, 1440 );
info->reward_exp_factor = getField< uint16_t >( row, 1439 );
info->reward_gil = getField< uint32_t >( row, 1440 );
info->reward_gc_seals = getField< uint16_t >( row, 1442 );
info->reward_item_type = getField< uint8_t >( row, 1447 );
info->reward_item_type = getField< uint8_t >( row, 1449 );
for( uint32_t i = 0; i < 6; i++ )
{
uint32_t entry = getField< uint32_t >( row, i + 1448 );
uint32_t entry = getField< uint32_t >( row, i + 1450 );
if( entry > 0 )
info->reward_item.push_back( entry );
uint8_t entry1 = getField< uint8_t >( row, i + 1455 );
uint8_t entry1 = getField< uint8_t >( row, i + 1457 );
if( entry1 > 0 )
info->reward_item_count.push_back( entry1 );
uint8_t entry2 = getField< uint8_t >( row, i + 1462 );
uint8_t entry2 = getField< uint8_t >( row, i + 1464 );
if( entry2 > 0 )
info->reward_item_stain.push_back( entry2 );
@ -547,39 +562,39 @@ boost::shared_ptr< Core::Data::QuestInfo >
for( uint32_t i = 0; i < 5; i++ )
{
uint32_t entry = getField< uint32_t >( row, i + 1469 );
uint32_t entry = getField< uint32_t >( row, i + 1471 );
if( entry > 0 )
info->reward_item_optional.push_back( entry );
uint8_t entry1 = getField< uint8_t >( row, i + 1474 );
uint8_t entry1 = getField< uint8_t >( row, i + 1476 );
if( entry1 > 0 )
info->reward_item_optional_count.push_back( entry1 );
uint8_t entry2 = getField< uint8_t >( row, i + 1484 );
uint8_t entry2 = getField< uint8_t >( row, i + 1486 );
if( entry2 > 0 )
info->reward_item_optional_stain.push_back( entry2 );
}
info->reward_emote = getField< uint8_t >( row, 1489 );
info->reward_action = getField< uint16_t >( row, 1490 );
info->reward_action_general1 = getField< uint8_t >( row, 1491 );
info->reward_action_general2 = getField< uint8_t >( row, 1492 );
info->reward_other = getField< uint8_t >( row, 1494 );
info->reward_emote = getField< uint8_t >( row, 1491 );
info->reward_action = getField< uint16_t >( row, 1492 );
info->reward_action_general1 = getField< uint8_t >( row, 1493 );
info->reward_action_general2 = getField< uint8_t >( row, 1494 );
info->reward_other = getField< uint8_t >( row, 1496 );
info->instanced_content_unlock = getField< uint32_t >( row, 1497 );
info->instanced_content_unlock = getField< uint32_t >( row, 1499 );
info->reward_tome_type = getField< uint8_t >( row, 1499 );
info->reward_tome_count = getField< uint8_t >( row, 1500 );
info->reward_tome_type = getField< uint8_t >( row, 1501 );
info->reward_tome_count = getField< uint8_t >( row, 1502 );
info->reward_reputation = getField< uint8_t >( row, 1501 );
info->reward_reputation = getField< uint8_t >( row, 1503 );
for( uint32_t i = 0; i < 50; i++ )
{
std::string entry = getField< std::string >( row, i + 47 );
std::string entry = getField< std::string >( row, i + 49 );
if( entry.size() > 0 )
{
info->script_entity.push_back( entry );
uint32_t entry1 = getField< uint32_t >( row, i + 97 );
uint32_t entry1 = getField< uint32_t >( row, i + 99 );
info->script_value.push_back( entry1 );
}
}

View file

@ -33,7 +33,7 @@ namespace Core {
uint16_t map_id;
int16_t discovery_index;
bool is_two_byte;
uint8_t weather_rate;
uint16_t weather_rate;
std::map< uint8_t, int32_t> weather_rate_map;
int32_t aetheryte_index;
@ -255,7 +255,11 @@ namespace Core {
bool affects_position; // 47
bool no_effect_in_battle; // 60
bool is_aoe; // Internal only
};
struct EventItemInfo
@ -269,7 +273,16 @@ namespace Core {
struct StatusEffectInfo
{
uint32_t id;
std::string name; //0
std::string name; // 0
bool lock_movement; // 7
bool lock_actions; // 9
bool lock_control; // 10
bool transfiguration; // 11
bool can_dispel; // 13
bool is_permanent; // 15
bool inflicted_by_actor; // 17
bool is_fc_buff; // 21
bool invisibility; // 22
};
class ExdData

View file

@ -19,6 +19,8 @@ struct FFXIVIpcTell : FFXIVIpcBasePacket<Tell>
uint16_t u2a;
uint16_t u2b;
uint8_t preName;
uint8_t u3a;
uint8_t u3b;
char receipientName[32];
char msg[1031];
};

View file

@ -44,88 +44,94 @@ namespace Packets {
*/
enum ServerZoneIpcType : uint16_t
{
Ping = 0x0065, // updated for sb
Init = 0x0066, // updated for sb
Chat = 0x0067, // updated for sb
Ping = 0x0065,
Init = 0x0066,
Chat = 0x0067,
ChatBanned = 0x006B,
Logout = 0x0077, // updated for sb
Logout = 0x0077,
CFNotify = 0x0078,
CFMemberStatus = 0x0079,
CFDutyInfo = 0x007A,
CFPlayerInNeed = 0x007F,
Playtime = 0x00AF, // updated for sb
Playtime = 0x00B7, // updated 4.1
SocialRequestError = 0x00AD,
SocialRequestResponse = 0x11AF,
CFRegistered = 0x00B0,
SocialList = 0x00B4, // updated for sb
UpdateSearchInfo = 0x00B6, // updated for sb
InitSearchInfo = 0x00B7, // updated for sb
ServerNotice = 0x00BC, // updated for sb
SetOnlineStatus = 0x00BD, // updated for sb
BlackList = 0x00CA, // updated for sb
LogMessage = 0x00D0, // updated for sb
LinkshellList = 0x00D1, // updated for sb
StatusEffectList = 0x00F0, // updated for sb
Effect = 0x00F1, // updated for sb
SocialRequestResponse = 0x00BB, // updated 4.1
CFRegistered = 0x00B8, // updated 4.1
SocialList = 0x00BE, // updated 4.1
UpdateSearchInfo = 0x10BB,
InitSearchInfo = 0x00C1, // updated 4.1
ServerNotice = 0x00C6, // updated 4.1
SetOnlineStatus = 0x00C7, // test update
BlackList = 0x00D4, // updated 4.1
LogMessage = 0x00D0,
LinkshellList = 0x00DC, // updated 4.1
StatusEffectList = 0x00FA, // updated 4.1
Effect = 0x00FB, // updated 4.1
GCAffiliation = 0x00FC,
ActorSetPos = 0x0114, // updated for sb
ActorCast = 0x0116, // updated for sb
PlayerSpawn = 0x0110, // updated for sb
NpcSpawn = 0x0111, // updated for sb
ActorMove = 0x0112, // updated for sb
HateList = 0x011A, // updated for sb borked
UpdateClassInfo = 0x011D, // updated for sb
InitUI = 0x011E, // updated for sb
PlayerStats = 0x011F, // updated for sb
ActorOwner = 0x0120, // updated for sb
PlayerStateFlags = 0x0121, // updated for sb
PlayerClassInfo = 0x0123, // updated for sb
ModelEquip = 0x0124, // updated for sb
ItemInfo = 0x0139, // updated for sb
ContainerInfo = 0x013A, // updated for sb
InventoryTransactionFinish = 0x013B, // updated for sb
InventoryTransaction = 0x013C, // updated for sb
CurrencyCrystalInfo = 0x013D,
ActorSetPos = 0x0120, // updated 4.1
ActorCast = 0x0123, // updated 4.1
PlayerSpawn = 0x011C, // updated 4.1
NpcSpawn = 0x011D, // updated 4.1
ActorMove = 0x011E, // updated 4.1
HateList = 0x011A,
UpdateClassInfo = 0x011D,
InitUI = 0x012B, // updated 4.1
ActorOwner = 0x012D, // updated 4.1
PlayerStats = 0x0138, // updated 4.1
PlayerStateFlags = 0x013A, // updated 4.1
PlayerClassInfo = 0x013B, // updated 4.1
ModelEquip = 0x013C, // updated 4.1
ItemInfo = 0x014C, // updated 4.1
ContainerInfo = 0x014D, // updated 4.1
InventoryTransactionFinish = 0x014E, // updated 4.1
InventoryTransaction = 0x014F, // updated 4.1
CurrencyCrystalInfo = 0x0150, // updated 4.1
InventoryActionAck = 0x1139,
UpdateInventorySlot = 0x0140, // updated for sb
UpdateInventorySlot = 0x0153, // updated 4.1
AddStatusEffect = 0x0141,
ActorControl142 = 0x0142, // unchanged for sb
ActorControl143 = 0x0143, // unchanged for sb
ActorControl144 = 0x0144, // unchanged for sb
UpdateHpMpTp = 0x0145, // unchanged for sb
ActorControl142 = 0x0142, // updated 4.1
ActorControl143 = 0x0143, // updated 4.1
ActorControl144 = 0x0144, // updated 4.1
UpdateHpMpTp = 0x0145, // updated 4.1
EventPlay = 0x0154, // updated for sb
EventStart = 0x015D, // updated for sb
EventFinish = 0x015E, // updated for sb
EventPlay = 0x0160, // updated 4.1
EventStart = 0x0169, // updated 4.1
EventFinish = 0x016A, // updated 4.1
EventLinkshell = 0x0169,
EventLinkshell = 0x1169,
QuestActiveList = 0x0171, // updated for sb
QuestUpdate = 0x0172, // updated for sb
QuestCompleteList = 0x0173, // updated for sb
QuestFinish = 0x0174, // updated for sb
QuestActiveList = 0x017D, // updated 4.1
QuestUpdate = 0x017E, // updated 4.1
QuestCompleteList = 0x017F, // updated 4.1
QuestFinish = 0x0180, // updated 4.1
QuestMessage = 0x0179,
QuestTracker = 0x0181, // updated for sb
QuestTracker = 0x018D, // updated 4.1
ActorSpawn = 0x0190, // todo: split into playerspawn/actorspawn and use opcode 0x110/0x111
ActorFreeSpawn = 0x0191, // unchanged for sb
InitZone = 0x019A, // unchanged for sb
WeatherChange = 0x01AF, // updated for sb
Discovery = 0x01B2, // updated for sb
PlayerTitleList = 0x01BD, // updated for 4.1
Discovery = 0x01BE, // updated for 4.1
EorzeaTimeOffset = 0x01B4,
EorzeaTimeOffset = 0x01C0, // updated 4.1
EquipDisplayFlags = 0x01CC, // updated 4.1
CFAvailableContents = 0x01CF,
PrepareZoning = 0x0239, // updated for sb
PrepareZoning = 0x0248, // updated 4.1
// Unknown IPC types that still need to be sent
// TODO: figure all these out properly
IPCTYPE_UNK_320 = 0x1FB,
IPCTYPE_UNK_322 = 0x1FD,
IPCTYPE_UNK_320 = 0x0207, // updated 4.1
IPCTYPE_UNK_322 = 0x0209, // updated 4.1
};
@ -138,53 +144,57 @@ namespace Packets {
{
PingHandler = 0x0065, // updated for sb
InitHandler = 0x0066, // updated for sb
ChatHandler = 0x0067, // updated for sb
InitHandler = 0x0066, // updated 4.1
ChatHandler = 0x00AD, // updated 4.1
FinishLoadingHandler = 0x0069, // updated for sb
FinishLoadingHandler = 0x0069, // updated 4.1
CFCommenceHandler = 0x006F,
CFRegisterDuty = 0x0071,
CFRegisterRoulette = 0x0072,
PlayTimeHandler = 0x0073, // updated for sb
LogoutHandler = 0x0074, // updated for sb
PlayTimeHandler = 0x0073, // updated 4.1
LogoutHandler = 0x0074, // updated 4.1
CFDutyInfoHandler = 0x0078,
CFDutyInfoHandler = 0x0078, // updated 4.1 ??
SocialReqSendHandler = 0x00A5,
SocialListHandler = 0x00AA, // updated for sb
SetSearchInfoHandler = 0x00AC, // updated for sb
SocialReqSendHandler = 0x00AE, // updated 4.1
SocialListHandler = 0x00B3, // updated 4.1
SetSearchInfoHandler = 0x00B5, // updated 4.1
ReqSearchInfoHandler = 0x00AD,
ReqSearchInfoHandler = 0x00B6, // updated 4.1
BlackListHandler = 0x00B7, // updated for sb
BlackListHandler = 0x00C0, // updated 4.1
LinkshellListHandler = 0x00BF, // updated for sb
LinkshellListHandler = 0x00C8, // updated 4.1
FcInfoReqHandler = 0x0100, // updated for sb
FcInfoReqHandler = 0x0109, // updated 4.1
ZoneLineHandler = 0x0107, // updated for sb
ActionHandler = 0x0108, // updated for sb
DiscoveryHandler = 0x0109, // updated for sb
ZoneLineHandler = 0x0110, // updated 4.1
ActionHandler = 0x0111, // updated 4.1
DiscoveryHandler = 0x0112, // updated 4.1
SkillHandler = 0x010B, // updated for sb
GMCommand1 = 0x010C, // updated for sb
GMCommand2 = 0x010D, // updated for sb
UpdatePositionHandler = 0x010F, // updated for sb
SkillHandler = 0x0114, // updated 4.1
GMCommand1 = 0x0115, // updated 4.1 ??
GMCommand2 = 0x0116, // updated 4.1 ??
UpdatePositionHandler = 0x0118, // updated 4.1
InventoryModifyHandler = 0x0116, // updated for sb
InventoryModifyHandler = 0x011F, // updated 4.1
TalkEventHandler = 0x011F, // updated for sb
EmoteEventHandler = 0x0120, // updated for sb
WithinRangeEventHandler = 0x0121, // updated for sb
OutOfRangeEventHandler = 0x0122, // updated for sb
EnterTeriEventHandler = 0x0123, // updated for sb
TalkEventHandler = 0x0128, // updated 4.1
EmoteEventHandler = 0x0129, // updated 4.1
WithinRangeEventHandler = 0x012A, // updated 4.1
OutOfRangeEventHandler = 0x012B, // updated 4.1
EnterTeriEventHandler = 0x012C, // updated 4.1
ReturnEventHandler = 0x0128,
TradeReturnEventHandler = 0x0129,
ReturnEventHandler = 0x0131, // updated 4.1
TradeReturnEventHandler = 0x0132, // updated 4.1
LinkshellEventHandler = 0x0144, // updated 4.1 ??
LinkshellEventHandler1 = 0x0145, // updated 4.1 ??
ReqEquipDisplayFlagsChange = 0x014C, // updated 4.1 ??
LinkshellEventHandler = 0x013B,
LinkshellEventHandler1 = 0x013C,
};
////////////////////////////////////////////////////////////////////////////////

View file

@ -340,15 +340,15 @@ struct FFXIVIpcPlayerSpawn : FFXIVIpcBasePacket<PlayerSpawn>
{
uint16_t title;
uint16_t u1b;
uint8_t gmRank;
uint8_t u2ab;
uint8_t u2b;
uint8_t u2ab;
uint8_t gmRank;
uint8_t onlineStatus;
uint8_t pose;
uint8_t u3a;
uint8_t u3b;
uint8_t u3c;
uint8_t u3d;
uint8_t pose;
uint32_t u4;
@ -368,8 +368,8 @@ struct FFXIVIpcPlayerSpawn : FFXIVIpcBasePacket<PlayerSpawn>
uint32_t u20;
uint32_t ownerId;
uint32_t u22;
uint32_t hPCurr;
uint32_t hPMax;
uint32_t hPCurr;
uint32_t displayFlags;
uint16_t fateID;
uint16_t mPCurr;
@ -639,6 +639,14 @@ struct FFXIVIpcUpdateClassInfo : FFXIVIpcBasePacket<UpdateClassInfo>
uint32_t restedExp;
};
/**
* Structural representation of the packet sent by the server
* to send the titles available to the player
*/
struct FFXIVIpcPlayerTitleList : FFXIVIpcBasePacket<PlayerTitleList>
{
uint8_t titleList[48];
};
/**
* Structural representation of the packet sent by the server
@ -718,7 +726,7 @@ struct FFXIVIpcInitUI : FFXIVIpcBasePacket<InitUI>
uint16_t unknown_005;
uint8_t unknown_114;
uint8_t padding_114;
uint8_t unknown_1141[52];
uint8_t unknown_1141[61];
uint8_t preNamePadding;
char name[32];
uint8_t unknown_54[16];
@ -781,7 +789,7 @@ struct FFXIVIpcInitUI : FFXIVIpcBasePacket<InitUI>
uint8_t unknownRest[32];
uint8_t tripleTriadCards[26];
uint8_t unknownRest1[21];
uint8_t orchestrionMask[19];
uint8_t orchestrionMask[38];
uint8_t hallOfNoviceCompleteMask[3];
uint8_t unknownMask2[11];
uint8_t unknownMask3[16];
@ -1286,6 +1294,14 @@ struct FFXIVIpcEorzeaTimeOffset : FFXIVIpcBasePacket<EorzeaTimeOffset>
uint64_t timestamp;
};
/**
* Structural representation of the packet sent by the server
* to set the gear show/hide status of a character
*/
struct FFXIVIpcEquipDisplayFlags : FFXIVIpcBasePacket<EquipDisplayFlags>
{
uint8_t bitmask;
};
} /* Server */

View file

@ -92,7 +92,11 @@ void Core::Action::ActionCast::onInterrupt()
m_pSource->getAsPlayer()->sendStateFlags();
auto control = ActorControlPacket142( m_pSource->getId(), ActorControlType::CastInterrupt,
0x219, 1, m_id, 1 );
0x219, 1, m_id, 0 );
// Note: When cast interrupt from taking too much damage, set the last value to 1. This enables the cast interrupt effect. Example:
// auto control = ActorControlPacket142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 1, m_id, 0 );
m_pSource->sendToInRangeSet( control, true );
}

View file

@ -696,9 +696,13 @@ void Core::Entity::Actor::handleScriptSkill( uint32_t type, uint32_t actionId, u
if ( isPlayer() && !ActionCollision::isActorApplicable( pTarget.shared_from_this(), TargetFilter::Enemies ) )
break;
pTarget.takeDamage( static_cast< uint32_t >( param1 ) );
pTarget.onActionHostile( shared_from_this() );
sendToInRangeSet( effectPacket, true );
pTarget.takeDamage( static_cast< uint32_t >( param1 ) );
if ( pTarget.isAlive() )
pTarget.onActionHostile( shared_from_this() );
}
else
{
@ -711,8 +715,11 @@ void Core::Entity::Actor::handleScriptSkill( uint32_t type, uint32_t actionId, u
effectPacket.data().effectTarget = pHitActor->getId();
sendToInRangeSet( effectPacket, true ); // todo: send to range of what? ourselves? when mob script hits this is going to be lacking
pHitActor->takeDamage( static_cast< uint32_t >( param1 ) );
pHitActor->onActionHostile( shared_from_this() );
if( pHitActor->isAlive() )
pHitActor->onActionHostile( shared_from_this() );
// Debug
if ( isPlayer() )

View file

@ -43,6 +43,16 @@ public:
Active = 1,
};
enum DisplayFlags : uint16_t
{
ActiveStance = 0x001,
Invisible = 0x020,
HideHead = 0x040,
HideWeapon = 0x080,
Faded = 0x100,
Visor = 0x800,
};
enum struct ActorStatus : uint8_t
{
Idle = 0x01,

View file

@ -385,6 +385,11 @@ void Core::Entity::Player::setZone( uint32_t zoneId )
sendInventory();
if( isLogin() )
{
queuePacket(ActorControlPacket143( getId(), SetCharaGearParamUI, m_equipDisplayFlags, 1 ) );
}
// set flags, will be reset automatically by zoning ( only on client side though )
pPlayer->setStateFlag( PlayerStateFlag::BetweenAreas );
pPlayer->setStateFlag( PlayerStateFlag::BetweenAreas1 );
@ -592,6 +597,17 @@ void Core::Entity::Player::learnAction( uint8_t actionId )
queuePacket( ActorControlPacket143( getId(), ToggleActionUnlock, actionId, 1 ) );
}
void Core::Entity::Player::learnSong( uint8_t songId, uint32_t itemId )
{
uint16_t index;
uint8_t value;
Util::valueToFlagByteIndexValue( songId, value, index );
m_orchestrion[index] |= value;
queuePacket( ActorControlPacket143( getId(), ToggleOrchestrionUnlock, songId, 1, itemId ) );
}
bool Core::Entity::Player::isActionLearned( uint8_t actionId ) const
{
uint16_t index;
@ -1154,6 +1170,11 @@ const uint8_t * Core::Entity::Player::getUnlockBitmask() const
return m_unlocks;
}
const uint8_t * Core::Entity::Player::getOrchestrionBitmask() const
{
return m_orchestrion;
}
uint64_t Core::Entity::Player::getContentId() const
{
return m_contentId;
@ -1370,6 +1391,52 @@ void Core::Entity::Player::setIsLogin( bool bIsLogin )
m_bIsLogin = bIsLogin;
}
uint8_t * Core::Entity::Player::getTitleList()
{
return m_titleList;
}
uint16_t Core::Entity::Player::getTitle() const
{
return m_title;
}
void Core::Entity::Player::addTitle( uint16_t titleId )
{
uint16_t index;
uint8_t value;
Util::valueToFlagByteIndexValue( titleId, value, index );
m_titleList[index] |= value;
}
void Core::Entity::Player::setTitle( uint16_t titleId )
{
uint16_t index;
uint8_t value;
Util::valueToFlagByteIndexValue( titleId, value, index );
if ( ( m_titleList[index] & value ) == 0 ) // Player doesn't have title - bail
return;
m_title = titleId;
sendToInRangeSet( ActorControlPacket142( getId(), SetTitle, titleId ), true );
}
void Core::Entity::Player::setEquipDisplayFlags( uint8_t state )
{
m_equipDisplayFlags = state;
GamePacketNew< FFXIVIpcEquipDisplayFlags, ServerZoneIpcType > paramPacket( getId() );
paramPacket.data().bitmask = m_equipDisplayFlags;
sendToInRangeSet( paramPacket, true );
}
uint8_t Core::Entity::Player::getEquipDisplayFlags() const
{
return m_equipDisplayFlags;
}
void Core::Entity::Player::autoAttack( ActorPtr pTarget )
{

View file

@ -328,6 +328,18 @@ public:
void teleport( uint16_t aetheryteId, uint8_t type = 1 );
/*! prepares zoning / fades out the screen */
void prepareZoning( uint16_t targetZone, bool fadeOut, uint8_t fadoutTime = 0, uint16_t animation = 0 );
/*! get player's title list (available titles) */
uint8_t * getTitleList();
/*! get player's active title */
uint16_t getTitle() const;
/*! add title to player title list */
void addTitle( uint16_t titleId );
/*! change player's active title */
void setTitle( uint16_t titleId );
/*! change gear param state */
void setEquipDisplayFlags( uint8_t state );
/*! get gear param state and send update to inRangeSet */
uint8_t getEquipDisplayFlags() const;
void calculateStats() override;
void sendStats();
@ -361,10 +373,14 @@ public:
void updateHowtosSeen( uint32_t howToId );
/*! learn an action / update the unlock bitmask. */
void learnAction( uint8_t actionId );
/*! learn a song / update the unlock bitmask. */
void learnSong( uint8_t songId, uint32_t itemId );
/*! check if an action is already unlocked in the bitmask. */
bool isActionLearned( uint8_t actionId ) const;
/*! return a const pointer to the unlock bitmask array */
const uint8_t * getUnlockBitmask() const;
/*! return a const pointer to the orchestrion bitmask array */
const uint8_t * getOrchestrionBitmask() const;
// Spawn handling
@ -563,7 +579,8 @@ private:
uint8_t status;
} m_retainerInfo[8];
uint8_t m_titleList[32];
uint16_t m_title;
uint8_t m_titleList[48];
uint8_t m_achievement[16];
uint8_t m_howTo[33];
uint8_t m_minions[33];
@ -581,6 +598,7 @@ private:
uint32_t m_expArray[25];
uint8_t m_aetheryte[16];
uint8_t m_unlocks[64];
uint8_t m_orchestrion[38];
uint8_t m_openingSequence;
@ -599,6 +617,8 @@ private:
uint8_t m_gmRank;
uint16_t zoneId;
uint8_t m_equipDisplayFlags;
bool m_bInCombat;
bool m_bLoadingComplete;
bool m_bAutoattack;

View file

@ -386,7 +386,6 @@ void Core::Entity::Player::updateSql()
stmt->setInt( 43, 0 ); // EquippedMannequin
stmt->setInt( 44, 0 ); // DisplayFlags
std::vector< uint8_t > questCompleteVec( sizeof( m_questCompleteFlags ) );
memcpy( questCompleteVec.data(), m_questCompleteFlags, sizeof( m_questCompleteFlags ) );
stmt->setBinary( 45, questCompleteVec );
@ -417,8 +416,6 @@ void Core::Entity::Player::updateSql()
g_charaDb.execute( stmt );
std::set< std::string > charaBaseSet;
std::set< std::string > charaDetailSet;
std::set< std::string > charaClassSet;
std::set< std::string > charaQuestSet;
std::set< std::string > charaInfoSearchSet;

View file

@ -118,6 +118,7 @@ void Core::DebugCommandHandler::scriptReload( char * data, Core::Entity::PlayerP
boost::shared_ptr<Core::DebugCommand> command )
{
g_scriptMgr.reload();
pPlayer->sendDebug( "Scripts reloaded." );
}
void Core::DebugCommandHandler::set( char * data, Core::Entity::PlayerPtr pPlayer, boost::shared_ptr<Core::DebugCommand> command )
@ -182,13 +183,6 @@ void Core::DebugCommandHandler::set( char * data, Core::Entity::PlayerPtr pPlaye
pPlayer->teleport( aetheryteId );
}
else if( ( subCommand == "unlockaetheryte" ) && ( params != "" ) )
{
for( uint8_t i = 0; i < 255; i++ )
pPlayer->registerAetheryte( i );
}
else if( ( subCommand == "discovery" ) && ( params != "" ) )
{
int32_t map_id;
@ -304,13 +298,21 @@ void Core::DebugCommandHandler::add( char * data, Core::Entity::PlayerPtr pPlaye
int32_t duration;
uint16_t param;
sscanf( params.c_str(), "%d %d %hd", &id, &duration, &param );
sscanf( params.c_str(), "%d %d %hu", &id, &duration, &param );
StatusEffect::StatusEffectPtr effect( new StatusEffect::StatusEffect( id, pPlayer, pPlayer, duration, 3000 ) );
effect->setParam( param );
pPlayer->addStatusEffect( effect );
}
else if ( subCommand == "title" )
{
uint32_t titleId;
sscanf( params.c_str(), "%u", &titleId );
pPlayer->addTitle( titleId );
pPlayer->sendNotice( "Added title (ID: " + std::to_string( titleId ) + ")" );
}
else if( subCommand == "spawn" )
{
int32_t model, name;
@ -333,7 +335,6 @@ void Core::DebugCommandHandler::add( char * data, Core::Entity::PlayerPtr pPlaye
pPlayer->queuePacket( pPe );
}
else if( subCommand == "actrl" )
{
// temporary research packet

View file

@ -93,8 +93,9 @@ Core::Network::GameConnection::GameConnection( Core::Network::HivePtr pHive,
setZoneHandler( ClientZoneIpcType::CFRegisterRoulette, "CFRegisterRoulette", &GameConnection::cfRegisterRoulette );
setZoneHandler( ClientZoneIpcType::CFCommenceHandler, "CFDutyAccepted", &GameConnection::cfDutyAccepted);
setZoneHandler( ClientZoneIpcType::ReqEquipDisplayFlagsChange, "ReqEquipDisplayFlagsChange",&GameConnection::reqEquipDisplayFlagsHandler);
setChatHandler( ClientChatIpcType::TellReq, "TellReq", &GameConnection::tellHandler);
setChatHandler( ClientChatIpcType::TellReq, "TellReq", &GameConnection::tellHandler);
}
@ -116,7 +117,7 @@ void Core::Network::GameConnection::OnAccept( const std::string & host, uint16_t
void Core::Network::GameConnection::OnDisconnect()
{
g_log.debug( "DISCONNECT" );
g_log.debug( "GameConnection DISCONNECT" );
m_pSession = nullptr;
}
@ -167,7 +168,7 @@ void Core::Network::GameConnection::OnRecv( std::vector< uint8_t > & buffer )
void Core::Network::GameConnection::OnError( const boost::system::error_code & error )
{
g_log.debug( "ERROR" );
g_log.debug( "GameConnection ERROR: " + error.message() );
}
void Core::Network::GameConnection::queueInPacket( Core::Network::Packets::GamePacketPtr inPacket )
@ -380,10 +381,21 @@ void Core::Network::GameConnection::handlePackets( const Core::Network::Packets:
{
g_log.info( "[" + std::string( id ) + "] Session not registered, creating" );
// return;
g_serverZone.createSession( playerId );
if( !g_serverZone.createSession( playerId ) )
{
Disconnect();
return;
}
session = g_serverZone.getSession( playerId );
}
if( !session->isValid() ) //TODO: Catch more things in lobby and send real errors
{
g_log.error( "[" + std::string(id) + "] Session INVALID, disconnecting" );
Disconnect();
return;
}
// if not set, set the session for this connection
if( !m_pSession && session )
m_pSession = session;
@ -416,8 +428,6 @@ void Core::Network::GameConnection::handlePackets( const Core::Network::Packets:
sendSinglePacket( &pPe );
}
break;
}

View file

@ -116,10 +116,10 @@ public:
DECLARE_HANDLER( gm1Handler );
DECLARE_HANDLER( gm2Handler );
DECLARE_HANDLER( reqEquipDisplayFlagsHandler );
DECLARE_HANDLER( tellHandler );
};

View file

@ -114,10 +114,23 @@ void Core::Network::GameConnection::actionHandler( const Packets::GamePacket& in
}
case 0x69: // Cancel cast
{
if( pPlayer->checkAction() )
if( pPlayer->getCurrentAction() != nullptr )
pPlayer->getCurrentAction()->setInterrupted();
break;
}
case 0x12E: // Set player title
{
pPlayer->setTitle( param1 );
break;
}
case 0x12F: // Get title list
{
GamePacketNew< FFXIVIpcPlayerTitleList, ServerZoneIpcType > titleListPacket( pPlayer->getId() );
memcpy( titleListPacket.data().titleList, pPlayer->getTitleList(), sizeof( titleListPacket.data().titleList ) );
pPlayer->queuePacket( titleListPacket );
break;
}
case 0x133: // Update howtos seen
{
uint32_t howToId = static_cast< uint32_t >( param1 );
@ -216,6 +229,10 @@ void Core::Network::GameConnection::actionHandler( const Packets::GamePacket& in
}
break;
}
default:
{
g_log.debug( "[" + std::to_string( m_pSession->getId() ) + "] Unhandled action: " +
boost::str( boost::format( "%|04X|" ) % (uint32_t) ( commandId & 0xFFFF ) ) );
}
}
}

View file

@ -72,6 +72,8 @@ enum GmCommand
Exp = 0x0068,
Inv = 0x006A,
Orchestrion = 0x0074,
Item = 0x00C8,
Gil = 0x00C9,
Collect = 0x00CA,
@ -84,6 +86,7 @@ enum GmCommand
QuestInspect = 0x0131,
GC = 0x0154,
GCRank = 0x0155,
Aetheryte = 0x015E,
Teri = 0x0258,
TeriInfo = 0x025D,
Jump = 0x025E,
@ -364,6 +367,52 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
" was switched." );
break;
}
case GmCommand::Aetheryte:
{
if( param1 == 0 )
{
if( param2 == 0 )
{
for( uint8_t i = 0; i < 255; i++ )
targetActor->getAsPlayer()->registerAetheryte( i );
pPlayer->sendNotice( "All Aetherytes for " + targetPlayer->getName() +
" were turned on." );
}
else
{
targetActor->getAsPlayer()->registerAetheryte( param2 );
pPlayer->sendNotice( "Aetheryte " + std::to_string( param2 ) + " for " + targetPlayer->getName() +
" was turned on." );
}
}
break;
}
case GmCommand::Orchestrion:
{
if( param1 == 1 )
{
if( param2 == 0 )
{
for( uint8_t i = 0; i < 255; i++ )
targetActor->getAsPlayer()->learnSong( i, 0 );
pPlayer->sendNotice( "All Songs for " + targetPlayer->getName() +
" were turned on." );
}
else
{
targetActor->getAsPlayer()->learnSong( param2, 0 );
pPlayer->sendNotice( "Song " + std::to_string( param2 ) + " for " + targetPlayer->getName() +
" was turned on." );
}
}
break;
}
default:
pPlayer->sendUrgent( "GM1 Command not implemented: " + std::to_string( commandId ) );

View file

@ -283,7 +283,11 @@ void Core::Network::GameConnection::updatePositionHandler( const Packets::GamePa
}
void Core::Network::GameConnection::reqEquipDisplayFlagsHandler( const Packets::GamePacket& inPacket,
Entity::PlayerPtr pPlayer )
{
pPlayer->setEquipDisplayFlags( inPacket.getValAt< uint8_t >( 0x20 ) );
}
void Core::Network::GameConnection::zoneLineHandler( const Packets::GamePacket& inPacket,
Entity::PlayerPtr pPlayer )

View file

@ -42,7 +42,7 @@ private:
m_data.namedayMonth = player->getBirthMonth();
m_data.namedayDay = player->getBirthDay();
// TODO: Support grand company status.
m_data.grandCompany = static_cast< Common::GrandCompany >( player->getStartTown() );
m_data.grandCompany = static_cast< Common::GrandCompany >( player->getGc() );
//m_data.gcRank = GCRank::None;
// TODO: Support starting city.
@ -62,6 +62,8 @@ private:
m_data.exp[i] = player->getExpArray()[i];
}
memcpy( m_data.orchestrionMask, player->getOrchestrionBitmask(), sizeof( m_data.orchestrionMask ) );
memcpy( m_data.unlockBitmask, player->getUnlockBitmask(), sizeof( m_data.unlockBitmask ) );
memcpy( m_data.discovery, player->getDiscoveryBitmask(), sizeof( m_data.discovery ) );

View file

@ -36,41 +36,49 @@ namespace Server {
// TODO: temporary gm rank
//m_data.gmRank = 0xff;
m_data.currentMount = 0;
m_data.classJob = pPlayer->getClass();
//m_data.status = static_cast< uint8_t >( pPlayer->getStatus() );
m_data.hPCurr = pPlayer->getHp();
m_data.mPCurr = pPlayer->getMp();
m_data.tPCurr = pPlayer->getTp();
m_data.hPMax = pPlayer->getMaxHp();
m_data.mPMax = pPlayer->getMaxMp();
m_data.gmRank = pPlayer->getGmRank();
//m_data.tPMax = 3000;
m_data.level = pPlayer->getLevel();
m_data.gmRank = pPlayer->getGmRank();
m_data.pose = 0;
memcpy( m_data.look, pPlayer->getLookArray(), 26 );
auto item = pPlayer->getInventory()->getItemAt( Inventory::GearSet0, Inventory::EquipSlot::MainHand );
if( item )
m_data.mainWeaponModel = item->getModelId1();
m_data.secWeaponModel = pPlayer->getModelSubWeapon();
m_data.models[0] = pPlayer->getModelForSlot( Inventory::EquipSlot::Head );
m_data.models[1] = pPlayer->getModelForSlot( Inventory::EquipSlot::Body );
m_data.models[2] = pPlayer->getModelForSlot( Inventory::EquipSlot::Hands );
m_data.models[3] = pPlayer->getModelForSlot( Inventory::EquipSlot::Legs );
m_data.models[4] = pPlayer->getModelForSlot( Inventory::EquipSlot::Feet );
strcpy( m_data.name, pPlayer->getName().c_str() );
m_data.pos.x = pPlayer->getPos().x;
m_data.pos.y = pPlayer->getPos().y;
m_data.pos.z = pPlayer->getPos().z;
m_data.voice = pPlayer->getVoiceId();
m_data.rotation = Math::Util::floatToUInt16Rot( pPlayer->getRotation() );
m_data.title = pPlayer->getTitle();
m_data.voice = pPlayer->getVoiceId();
m_data.currentMount = 0;
m_data.onlineStatus = static_cast< uint8_t >( pPlayer->getOnlineStatus() );
//m_data.u23 = 0x04;
//m_data.u24 = 256;
m_data.state = 1;
m_data.state = static_cast< uint8_t >( pPlayer->getStatus() );
m_data.type = 1;
if( pTarget == pPlayer )
{
@ -85,7 +93,22 @@ namespace Server {
if( pPlayer->getZoningType() != Common::ZoneingType::None )
{
m_data.displayFlags |= 0x20;
m_data.displayFlags |= Entity::Actor::DisplayFlags::Invisible;
}
if( pPlayer->getEquipDisplayFlags() & Core::Common::EquipDisplayFlags::HideHead )
{
m_data.displayFlags |= Entity::Actor::DisplayFlags::HideHead;
}
if( pPlayer->getEquipDisplayFlags() & Core::Common::EquipDisplayFlags::HideWeapon )
{
m_data.displayFlags |= Entity::Actor::DisplayFlags::HideWeapon;
}
if( pPlayer->getEquipDisplayFlags() & Core::Common::EquipDisplayFlags::Visor )
{
m_data.displayFlags |= Entity::Actor::DisplayFlags::Visor;
}
m_data.targetId = pPlayer->getTargetId();

View file

@ -11,6 +11,7 @@ Core::Session::Session( uint32_t sessionId )
: m_sessionId( sessionId )
, m_lastDataTime( static_cast< uint32_t >( Util::getTimeSeconds() ) )
, m_lastSqlTime( static_cast< uint32_t >( Util::getTimeSeconds() ) )
, m_isValid( false )
{
// boost::posix_time::ptime now = boost::date_time::not_a_date_time;
@ -50,7 +51,15 @@ bool Core::Session::loadPlayer()
m_pPlayer = Entity::PlayerPtr( new Entity::Player() );
return m_pPlayer->load(m_sessionId, shared_from_this() );
if( !m_pPlayer->load( m_sessionId, shared_from_this() ) )
{
m_isValid = false;
return false;
}
m_isValid = true;
return true;
}
@ -59,6 +68,9 @@ void Core::Session::close()
if( m_pZoneConnection )
m_pZoneConnection->Disconnect();
if( m_pChatConnection )
m_pChatConnection->Disconnect();
// remove the session from the player
if( m_pPlayer )
// reset the zone, so the zone handler knows to remove the actor
@ -80,6 +92,11 @@ uint32_t Core::Session::getLastSqlTime() const
return m_lastSqlTime;
}
bool Core::Session::isValid() const
{
return m_isValid;
}
void Core::Session::updateLastDataTime()
{
m_lastDataTime = static_cast< uint32_t >( Util::getTimeSeconds() );

View file

@ -37,6 +37,8 @@ namespace Core {
void update();
bool isValid() const;
Entity::PlayerPtr getPlayer() const;
private:
@ -47,6 +49,7 @@ namespace Core {
uint32_t m_lastDataTime;
uint32_t m_lastSqlTime;
bool m_isValid;
Network::GameConnectionPtr m_pZoneConnection;
Network::GameConnectionPtr m_pChatConnection;