mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-26 06:27:45 +00:00
Merge remote-tracking branch 'upstream/master' into tcp-handling
This commit is contained in:
commit
b5ec4e93a3
20 changed files with 737 additions and 560 deletions
|
@ -1,61 +0,0 @@
|
||||||
// This is an automatically generated chai script template
|
|
||||||
// Content needs to be added by hand to make it function
|
|
||||||
// In order for this script to be loaded, change its extension to .chai
|
|
||||||
|
|
||||||
|
|
||||||
// Quest Script: SubFst004_00027
|
|
||||||
// Quest Name: Preserving the Past
|
|
||||||
// Quest ID: 65563
|
|
||||||
// Start NPC: 1000194
|
|
||||||
// End NPC: 1000789
|
|
||||||
|
|
||||||
class CmnDefCutSceneReplayDef
|
|
||||||
{
|
|
||||||
// Basic quest information
|
|
||||||
var quest_name
|
|
||||||
var quest_id
|
|
||||||
|
|
||||||
// These are the quest vars / flags used in this quest
|
|
||||||
// GetQuestUI8AL
|
|
||||||
// GetQuestUI8BH
|
|
||||||
|
|
||||||
// Available Scenes in this quest, not necessarly all are used
|
|
||||||
attr onScene00000;
|
|
||||||
|
|
||||||
// Quest rewards
|
|
||||||
var RewardExpFactor;
|
|
||||||
var RewardItem;
|
|
||||||
var RewardItemCount;
|
|
||||||
|
|
||||||
// Entities found in the script data of the quest
|
|
||||||
// some of these may be useful
|
|
||||||
var ACTOR0;
|
|
||||||
var ACTOR1;
|
|
||||||
var ACTOR2;
|
|
||||||
var ITEM0;
|
|
||||||
|
|
||||||
def CmnDefCutSceneReplayDef()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
def Scene00000( player, eventId, flags, unk, unk1 )
|
|
||||||
{
|
|
||||||
player.eventPlay(eventId, 0, 0x2000, unk, 1,
|
|
||||||
fun( player, eventId, subEvent, param1, param2, param3 )
|
|
||||||
{
|
|
||||||
player.eventFinish(eventId, 1);
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
def CmnDefCutSceneReplay_START(player, actorId, eventId)
|
|
||||||
{
|
|
||||||
var quest = CmnDefCutSceneReplay();
|
|
||||||
var actor = mapActor( actorId );
|
|
||||||
|
|
||||||
player.eventStart( actorId, eventId, 1, 0, 0 );
|
|
||||||
CmnDefCutSceneReplay.Scene00000( player, eventId, 0, 0, 0 );
|
|
||||||
}
|
|
|
@ -5,8 +5,8 @@
|
||||||
#define _CORE_NETWORK_PACKETS_COMMON_H
|
#define _CORE_NETWORK_PACKETS_COMMON_H
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "PacketDef/Ipcs.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -14,343 +14,160 @@ namespace Core {
|
||||||
namespace Network {
|
namespace Network {
|
||||||
namespace Packets {
|
namespace Packets {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Anticipated usage:
|
||||||
|
* ==================
|
||||||
|
* Set up a stream buffer to collect the bytes to be transmitted as a packet.
|
||||||
|
* Now, you can do the following (given you have the structs filled out already).
|
||||||
|
*
|
||||||
|
* FFXIVARR_PACKET_HEADER pkt_hdr = { . . . };
|
||||||
|
* FFXIVARR_PACKET_SEGMENT_HEADER pkt_seg_hdr[n] = { . . . };
|
||||||
|
*
|
||||||
|
* std::stringstream buf;
|
||||||
|
* buf << pkt_hdr;
|
||||||
|
* for (int i = 0; i < n; i++)
|
||||||
|
* {
|
||||||
|
* buf << pkt_seg_hdr[i];
|
||||||
|
* buf << {pkt_seg_data[i]};
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* The reverse can be done parsing a packet. Remember to validate the packet
|
||||||
|
* type before parsing the headers.
|
||||||
|
*
|
||||||
|
* Compression and Encryption:
|
||||||
|
* ===========================
|
||||||
|
* By using std::iostream's, you can support stream filters. Simply create a
|
||||||
|
* stream that performs the compression or encryption, and use that stream to
|
||||||
|
* read and write.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Structure representing the common header for all FFXIVARR packets.
|
||||||
|
*
|
||||||
|
* 0 4 8 12 14 16
|
||||||
|
* +-------------------------------+---------------+-------+-------+
|
||||||
|
* | timestamp | size | cType | count |
|
||||||
|
* +---+---+-------+---------------+---------------+-------+-------+
|
||||||
|
* | ? |CMP| ? | ? |
|
||||||
|
* +---+---+-------+---------------+
|
||||||
|
* (followed by /count/ FFXIVARR_PACKET_SEGMENTs)
|
||||||
|
*/
|
||||||
|
struct FFXIVARR_PACKET_HEADER
|
||||||
|
{
|
||||||
|
|
||||||
|
uint64_t unknown_0;
|
||||||
|
uint64_t unknown_8;
|
||||||
/**
|
/**
|
||||||
* Anticipated usage:
|
* Represents the number of milliseconds since epoch that the packet was
|
||||||
* ==================
|
* sent.
|
||||||
* Set up a stream buffer to collect the bytes to be transmitted as a packet.
|
|
||||||
* Now, you can do the following (given you have the structs filled out already).
|
|
||||||
*
|
|
||||||
* FFXIVARR_PACKET_HEADER pkt_hdr = { . . . };
|
|
||||||
* FFXIVARR_PACKET_SEGMENT_HEADER pkt_seg_hdr[n] = { . . . };
|
|
||||||
*
|
|
||||||
* std::stringstream buf;
|
|
||||||
* buf << pkt_hdr;
|
|
||||||
* for (int i = 0; i < n; i++)
|
|
||||||
* {
|
|
||||||
* buf << pkt_seg_hdr[i];
|
|
||||||
* buf << {pkt_seg_data[i]};
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* The reverse can be done parsing a packet. Remember to validate the packet
|
|
||||||
* type before parsing the headers.
|
|
||||||
*
|
|
||||||
* Compression and Encryption:
|
|
||||||
* ===========================
|
|
||||||
* By using std::iostream's, you can support stream filters. Simply create a
|
|
||||||
* stream that performs the compression or encryption, and use that stream to
|
|
||||||
* read and write.
|
|
||||||
*/
|
*/
|
||||||
|
uint64_t timestamp;
|
||||||
|
/** The size of the packet header and its payload */
|
||||||
|
uint32_t size;
|
||||||
|
/** The type of this connection - 1 zone, 2 chat*/
|
||||||
|
uint16_t connectionType;
|
||||||
|
/** The number of packet segments that follow. */
|
||||||
|
uint16_t count;
|
||||||
|
uint8_t unknown_20;
|
||||||
|
/** Indicates if the data segments of this packet are compressed. */
|
||||||
|
uint8_t isCompressed;
|
||||||
|
uint32_t unknown_24;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
inline ostream& operator<<(ostream& os, const FFXIVARR_PACKET_HEADER& hdr)
|
||||||
* Structure representing the common header for all FFXIVARR packets.
|
{
|
||||||
*
|
return os.write(reinterpret_cast<const char*>(&hdr), sizeof hdr);
|
||||||
* 0 4 8 12 14 16
|
}
|
||||||
* +-------------------------------+---------------+-------+-------+
|
|
||||||
* | timestamp | size | cType | count |
|
|
||||||
* +---+---+-------+---------------+---------------+-------+-------+
|
|
||||||
* | ? |CMP| ? | ? |
|
|
||||||
* +---+---+-------+---------------+
|
|
||||||
* (followed by /count/ FFXIVARR_PACKET_SEGMENTs)
|
|
||||||
*/
|
|
||||||
struct FFXIVARR_PACKET_HEADER
|
|
||||||
{
|
|
||||||
|
|
||||||
uint64_t unknown_0;
|
inline istream& operator>>(istream& is, FFXIVARR_PACKET_HEADER& hdr)
|
||||||
uint64_t unknown_8;
|
{
|
||||||
/**
|
return is.read(reinterpret_cast<char*>(&hdr), sizeof hdr);
|
||||||
* Represents the number of milliseconds since epoch that the packet was
|
}
|
||||||
* sent.
|
|
||||||
*/
|
|
||||||
uint64_t timestamp;
|
|
||||||
/** The size of the packet header and its payload */
|
|
||||||
uint32_t size;
|
|
||||||
/** The type of this connection - 1 zone, 2 chat*/
|
|
||||||
uint16_t connectionType;
|
|
||||||
/** The number of packet segments that follow. */
|
|
||||||
uint16_t count;
|
|
||||||
uint8_t unknown_20;
|
|
||||||
/** Indicates if the data segments of this packet are compressed. */
|
|
||||||
uint8_t isCompressed;
|
|
||||||
uint32_t unknown_24;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline ostream& operator<<(ostream& os, const FFXIVARR_PACKET_HEADER& hdr)
|
/**
|
||||||
{
|
* Structure representing the header portion of a packet segment.
|
||||||
return os.write(reinterpret_cast<const char*>(&hdr), sizeof hdr);
|
*
|
||||||
}
|
* NOTE: If the main packet header indicated the packet is compressed, this
|
||||||
|
* header will be compressed as well! The header will NOT ever be encrypted.
|
||||||
|
*
|
||||||
|
* 0 4 8 12 16
|
||||||
|
* +---------------+---------------+---------------+-------+-------+
|
||||||
|
* | size | source_actor | target_actor | type | ? |
|
||||||
|
* +---------------+---------------+---------------+-------+-------+
|
||||||
|
* | |
|
||||||
|
* : type-specific data of length, size, follows :
|
||||||
|
* | (NOTE: Some segments MAY be encrypted) |
|
||||||
|
* +---------------------------------------------------------------+
|
||||||
|
*/
|
||||||
|
struct FFXIVARR_PACKET_SEGMENT_HEADER
|
||||||
|
{
|
||||||
|
/** The size of the segment header and its data. */
|
||||||
|
uint32_t size;
|
||||||
|
/** The session ID this segment describes. */
|
||||||
|
uint32_t source_actor;
|
||||||
|
/** The session ID this packet is being delivered to. */
|
||||||
|
uint32_t target_actor;
|
||||||
|
/** The segment type. (1, 2, 3, 7, 8, 9, 10) */
|
||||||
|
uint16_t type;
|
||||||
|
uint16_t _reserved_E;
|
||||||
|
};
|
||||||
|
|
||||||
inline istream& operator>>(istream& is, FFXIVARR_PACKET_HEADER& hdr)
|
inline ostream& operator<<(ostream& os, const FFXIVARR_PACKET_SEGMENT_HEADER& hdr)
|
||||||
{
|
{
|
||||||
return is.read(reinterpret_cast<char*>(&hdr), sizeof hdr);
|
return os.write(reinterpret_cast<const char*>(&hdr), sizeof hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
inline istream& operator>>(istream& is, FFXIVARR_PACKET_SEGMENT_HEADER& hdr)
|
||||||
* Structure representing the header portion of a packet segment.
|
{
|
||||||
*
|
return is.read(reinterpret_cast<char*>(&hdr), sizeof hdr);
|
||||||
* NOTE: If the main packet header indicated the packet is compressed, this
|
}
|
||||||
* header will be compressed as well! The header will NOT ever be encrypted.
|
|
||||||
*
|
|
||||||
* 0 4 8 12 16
|
|
||||||
* +---------------+---------------+---------------+-------+-------+
|
|
||||||
* | size | source_actor | target_actor | type | ? |
|
|
||||||
* +---------------+---------------+---------------+-------+-------+
|
|
||||||
* | |
|
|
||||||
* : type-specific data of length, size, follows :
|
|
||||||
* | (NOTE: Some segments MAY be encrypted) |
|
|
||||||
* +---------------------------------------------------------------+
|
|
||||||
*/
|
|
||||||
struct FFXIVARR_PACKET_SEGMENT_HEADER
|
|
||||||
{
|
|
||||||
/** The size of the segment header and its data. */
|
|
||||||
uint32_t size;
|
|
||||||
/** The session ID this segment describes. */
|
|
||||||
uint32_t source_actor;
|
|
||||||
/** The session ID this packet is being delivered to. */
|
|
||||||
uint32_t target_actor;
|
|
||||||
/** The segment type. (1, 2, 3, 7, 8, 9, 10) */
|
|
||||||
uint16_t type;
|
|
||||||
uint16_t _reserved_E;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline ostream& operator<<(ostream& os, const FFXIVARR_PACKET_SEGMENT_HEADER& hdr)
|
// TODO: Include structures for the individual packet segment types
|
||||||
{
|
|
||||||
return os.write(reinterpret_cast<const char*>(&hdr), sizeof hdr);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline istream& operator>>(istream& is, FFXIVARR_PACKET_SEGMENT_HEADER& hdr)
|
template <int T> struct FFXIVIpcBasePacket
|
||||||
{
|
{
|
||||||
return is.read(reinterpret_cast<char*>(&hdr), sizeof hdr);
|
/** Creates a constant representing the IPC type */
|
||||||
}
|
enum { _ServerIpcType = T };
|
||||||
|
};
|
||||||
|
|
||||||
// TODO: Include structures for the individual packet segment types
|
struct FFXIVARR_PACKET_RAW
|
||||||
|
{
|
||||||
|
FFXIVARR_PACKET_SEGMENT_HEADER segHdr;
|
||||||
|
std::vector<uint8_t> data;
|
||||||
|
};
|
||||||
|
|
||||||
template <int T> struct FFXIVIpcBasePacket
|
/**
|
||||||
{
|
* Structural representation of the common header for IPC packet segments.
|
||||||
/** Creates a constant representing the IPC type */
|
* NOTE: This is packet segment type 3.
|
||||||
enum { _ServerIpcType = T };
|
*
|
||||||
};
|
* 0 4 6 8 12 16
|
||||||
|
* +-------+-------+------+----------+---------------+---------------+
|
||||||
|
* | 14 00 | type | ?? | serverId | timestamp | ??? |
|
||||||
|
* +-------+-------+------+----------+---------------+---------------+
|
||||||
|
* | |
|
||||||
|
* : data :
|
||||||
|
* | |
|
||||||
|
* +-----------------------------------------------------------------+
|
||||||
|
*/
|
||||||
|
struct FFXIVARR_IPC_HEADER
|
||||||
|
{
|
||||||
|
uint16_t reserved;
|
||||||
|
uint16_t type;
|
||||||
|
uint16_t unknown_2;
|
||||||
|
uint16_t serverId;
|
||||||
|
uint32_t timestamp;
|
||||||
|
uint32_t unknown_C;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
inline ostream& operator<<(ostream& os, const FFXIVARR_IPC_HEADER& hdr)
|
||||||
* Server IPC Lobby Type Codes.
|
{
|
||||||
*/
|
return os.write(reinterpret_cast<const char*>(&hdr), sizeof hdr);
|
||||||
enum ServerLobbyIpcType : uint16_t
|
}
|
||||||
{
|
|
||||||
LobbyError = 0x0002,
|
|
||||||
LobbyServiceAccountList = 0x000C,
|
|
||||||
LobbyCharList = 0x000D,
|
|
||||||
LobbyCharCreate = 0x000E,
|
|
||||||
LobbyEnterWorld = 0x000F,
|
|
||||||
LobbyServerList = 0x0015,
|
|
||||||
LobbyRetainerList = 0x0017,
|
|
||||||
|
|
||||||
};
|
inline istream& operator>>(istream& is, FFXIVARR_IPC_HEADER& hdr)
|
||||||
|
{
|
||||||
/**
|
return is.read(reinterpret_cast<char*>(&hdr), sizeof hdr);
|
||||||
* Client IPC Lobby Type Codes.
|
}
|
||||||
*/
|
|
||||||
enum ClientLobbyIpcType : uint16_t
|
|
||||||
{
|
|
||||||
ReqCharList = 0x0003,
|
|
||||||
ReqEnterWorld = 0x0004,
|
|
||||||
ReqServiceAccountList = 0x0005,
|
|
||||||
|
|
||||||
ReqCharDelete = 0x000A,
|
|
||||||
ReqCharCreate = 0x000B,
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Server IPC Zone Type Codes.
|
|
||||||
*/
|
|
||||||
enum ServerZoneIpcType : uint16_t
|
|
||||||
{
|
|
||||||
Ping = 0x0065, // updated for sb
|
|
||||||
Init = 0x0066, // updated for sb
|
|
||||||
Chat = 0x0067, // updated for sb
|
|
||||||
Logout = 0x0077, // updated for sb
|
|
||||||
Playtime = 0x00AF, // updated for sb
|
|
||||||
SocialRequestError = 0x00AD,
|
|
||||||
SocialRequestResponse = 0x11AF,
|
|
||||||
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
|
|
||||||
LinkshellList = 0x00D1, // updated for sb
|
|
||||||
StatusEffectList = 0x00F0, // updated for sb
|
|
||||||
Effect = 0x00F1, // updated for sb
|
|
||||||
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,
|
|
||||||
InventoryTransaction = 0x012A,
|
|
||||||
CurrencyCrystalInfo = 0x013D,
|
|
||||||
InventoryActionAck = 0x0139,
|
|
||||||
UpdateInventorySlot = 0x0140, // updated for sb
|
|
||||||
AddStatusEffect = 0x0141,
|
|
||||||
ActorControl142 = 0x0142, // unchanged for sb
|
|
||||||
ActorControl143 = 0x0143, // unchanged for sb
|
|
||||||
ActorControl144 = 0x0144, // unchanged for sb
|
|
||||||
UpdateHpMpTp = 0x0145, // unchanged for sb
|
|
||||||
|
|
||||||
CFNotify = 0x0078,
|
|
||||||
CFMemberStatus = 0x0079,
|
|
||||||
CFDutyInfo = 0x007A,
|
|
||||||
CFPlayerInNeed = 0x007F,
|
|
||||||
CFRegistered = 0x00B0,
|
|
||||||
CFAvailableContents = 0x01CF,
|
|
||||||
|
|
||||||
EventPlay = 0x0154, // updated for sb
|
|
||||||
EventStart = 0x015D, // updated for sb
|
|
||||||
EventFinish = 0x015E, // updated for sb
|
|
||||||
QuestActiveList = 0x0171, // updated for sb
|
|
||||||
QuestUpdate = 0x0172, // updated for sb
|
|
||||||
QuestCompleteList = 0x0173, // updated for sb
|
|
||||||
QuestFinish = 0x0174, // updated for sb
|
|
||||||
QuestMessage = 0x0179,
|
|
||||||
QuestTracker = 0x0181, // updated for sb
|
|
||||||
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
|
|
||||||
|
|
||||||
PrepareZoning = 0x0239, // updated for sb
|
|
||||||
|
|
||||||
// Unknown IPC types that still need to be sent
|
|
||||||
// TODO: figure all these out properly
|
|
||||||
IPCTYPE_UNK_320 = 0x1FB,
|
|
||||||
IPCTYPE_UNK_322 = 0x1FD,
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: Include structures for the individual packet segment types
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Client IPC Zone Type Codes.
|
|
||||||
*/
|
|
||||||
enum ClientZoneIpcType : uint16_t
|
|
||||||
{
|
|
||||||
|
|
||||||
TellChatHandler = 0x0064,// updated for sb
|
|
||||||
|
|
||||||
PingHandler = 0x0065,// updated for sb
|
|
||||||
InitHandler = 0x0066,// updated for sb
|
|
||||||
ChatHandler = 0x0067,// updated for sb
|
|
||||||
|
|
||||||
FinishLoadingHandler = 0x0069,// updated for sb
|
|
||||||
|
|
||||||
CFCommenceHandler = 0x006F,
|
|
||||||
CFRegisterDuty = 0x0071,
|
|
||||||
CFRegisterRoulette = 0x0072,
|
|
||||||
|
|
||||||
PlayTimeHandler = 0x0073,// updated for sb
|
|
||||||
LogoutHandler = 0x0074,// updated for sb
|
|
||||||
|
|
||||||
CFDutyInfoHandler = 0x0078,
|
|
||||||
|
|
||||||
SocialReqSendHandler = 0x00A5,
|
|
||||||
SocialListHandler = 0x00AA,// updated for sb
|
|
||||||
SetSearchInfoHandler = 0x00AC,// updated for sb
|
|
||||||
|
|
||||||
ReqSearchInfoHandler = 0x00AD,
|
|
||||||
|
|
||||||
BlackListHandler = 0x00B7,// updated for sb
|
|
||||||
|
|
||||||
LinkshellListHandler = 0x00BF,// updated for sb
|
|
||||||
|
|
||||||
FcInfoReqHandler = 0x0100,// updated for sb
|
|
||||||
|
|
||||||
ZoneLineHandler = 0x0107, // updated for sb
|
|
||||||
ActionHandler = 0x0108,// updated for sb
|
|
||||||
|
|
||||||
DiscoveryHandler = 0x0109,// updated for sb
|
|
||||||
|
|
||||||
SkillHandler = 0x010B, // updated for sb
|
|
||||||
GMCommand1 = 0x010C,// updated for sb
|
|
||||||
GMCommand2 = 0x010D,// updated for sb
|
|
||||||
UpdatePositionHandler = 0x010F, // updated for sb
|
|
||||||
|
|
||||||
InventoryModifyHandler = 0x0116, // updated for sb
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
ReturnEventHandler = 0x0128,
|
|
||||||
TradeReturnEventHandler = 0x0129,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Server IPC Chat Type Codes.
|
|
||||||
*/
|
|
||||||
enum ServerChatIpcType : uint16_t
|
|
||||||
{
|
|
||||||
Tell = 0x0064, // updated for sb
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Client IPC Chat Type Codes.
|
|
||||||
*/
|
|
||||||
enum ClientChatIpcType : uint16_t
|
|
||||||
{
|
|
||||||
TellReq = 0x0064,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FFXIVARR_PACKET_RAW
|
|
||||||
{
|
|
||||||
FFXIVARR_PACKET_SEGMENT_HEADER segHdr;
|
|
||||||
std::vector<uint8_t> data;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Structural representation of the common header for IPC packet segments.
|
|
||||||
* NOTE: This is packet segment type 3.
|
|
||||||
*
|
|
||||||
* 0 4 6 8 12 16
|
|
||||||
* +-------+-------+------+----------+---------------+---------------+
|
|
||||||
* | 14 00 | type | ?? | serverId | timestamp | ??? |
|
|
||||||
* +-------+-------+------+----------+---------------+---------------+
|
|
||||||
* | |
|
|
||||||
* : data :
|
|
||||||
* | |
|
|
||||||
* +-----------------------------------------------------------------+
|
|
||||||
*/
|
|
||||||
struct FFXIVARR_IPC_HEADER
|
|
||||||
{
|
|
||||||
uint16_t reserved;
|
|
||||||
uint16_t type;
|
|
||||||
uint16_t unknown_2;
|
|
||||||
uint16_t serverId;
|
|
||||||
uint32_t timestamp;
|
|
||||||
uint32_t unknown_C;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline ostream& operator<<(ostream& os, const FFXIVARR_IPC_HEADER& hdr)
|
|
||||||
{
|
|
||||||
return os.write(reinterpret_cast<const char*>(&hdr), sizeof hdr);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline istream& operator>>(istream& is, FFXIVARR_IPC_HEADER& hdr)
|
|
||||||
{
|
|
||||||
return is.read(reinterpret_cast<char*>(&hdr), sizeof hdr);
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* Packets */
|
} /* Packets */
|
||||||
} /* Network */
|
} /* Network */
|
||||||
|
|
|
@ -46,10 +46,11 @@ Core::Network::Packets::GamePacket::GamePacket( char * pData, uint16_t size, boo
|
||||||
if( bWriteStamp && size > 0x18 )
|
if( bWriteStamp && size > 0x18 )
|
||||||
{
|
{
|
||||||
m_timeStamp = static_cast< uint32_t >( time( nullptr ) );
|
m_timeStamp = static_cast< uint32_t >( time( nullptr ) );
|
||||||
|
*reinterpret_cast< uint16_t* >( &m_dataBuf[0] + 0x10 ) = 0x14;
|
||||||
*reinterpret_cast< uint32_t* >( &m_dataBuf[0] + 0x18 ) = m_timeStamp;
|
*reinterpret_cast< uint32_t* >( &m_dataBuf[0] + 0x18 ) = m_timeStamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_segHdr._reserved_E = 0;
|
//m_segHdr._reserved_E = 0;
|
||||||
m_segHdr.size = *reinterpret_cast< uint32_t* >( &m_dataBuf[0] );
|
m_segHdr.size = *reinterpret_cast< uint32_t* >( &m_dataBuf[0] );
|
||||||
m_segHdr.type = *reinterpret_cast< uint16_t* >( &m_dataBuf[0] + 0x0C );
|
m_segHdr.type = *reinterpret_cast< uint16_t* >( &m_dataBuf[0] + 0x0C );
|
||||||
m_subType = *reinterpret_cast< uint16_t* >( &m_dataBuf[0] + 0x12 );
|
m_subType = *reinterpret_cast< uint16_t* >( &m_dataBuf[0] + 0x12 );
|
||||||
|
|
|
@ -35,6 +35,8 @@ void Core::Network::Packets::PacketContainer::fillSendBuffer( std::vector< uint8
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
auto ms = duration_cast< milliseconds >( system_clock::now().time_since_epoch() );
|
auto ms = duration_cast< milliseconds >( system_clock::now().time_since_epoch() );
|
||||||
uint64_t tick = ms.count();
|
uint64_t tick = ms.count();
|
||||||
|
m_ipcHdr.unknown_0 = 0xE2465DFF41a05252;
|
||||||
|
m_ipcHdr.unknown_8 = 0x75C4997B4D642A7F;
|
||||||
m_ipcHdr.timestamp = tick;
|
m_ipcHdr.timestamp = tick;
|
||||||
m_ipcHdr.unknown_20 = 1;
|
m_ipcHdr.unknown_20 = 1;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
#ifndef _CORE_NETWORK_PACKETS_CHAT_SERVER_IPC_H
|
||||||
|
#define _CORE_NETWORK_PACKETS_CHAT_SERVER_IPC_H
|
||||||
|
|
||||||
|
#include "src/servers/Server_Common/Common.h"
|
||||||
|
#include "src/servers/Server_Common/Network/CommonNetwork.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
namespace Network {
|
||||||
|
namespace Packets {
|
||||||
|
namespace Server {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Structural representation of the packet sent by the server as response
|
||||||
|
* to a tell request
|
||||||
|
*/
|
||||||
|
struct FFXIVIpcTell : FFXIVIpcBasePacket<Tell>
|
||||||
|
{
|
||||||
|
uint32_t u1;
|
||||||
|
uint16_t u2a;
|
||||||
|
uint16_t u2b;
|
||||||
|
uint8_t preName;
|
||||||
|
char receipientName[32];
|
||||||
|
char msg[1031];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Structural representation of the packet sent by the server as response
|
||||||
|
* to a failed tell because of unavailable target player
|
||||||
|
*/
|
||||||
|
struct FFXIVIpcTellErrNotFound : FFXIVIpcBasePacket<TellErrNotFound>
|
||||||
|
{
|
||||||
|
char receipientName[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* Server */
|
||||||
|
} /* Packets */
|
||||||
|
} /* Network */
|
||||||
|
} /* Core */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*_CORE_NETWORK_PACKETS_CHAT_SERVER_IPC_H*/
|
203
src/servers/Server_Common/Network/PacketDef/Ipcs.h
Normal file
203
src/servers/Server_Common/Network/PacketDef/Ipcs.h
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
#ifndef _CORE_NETWORK_PACKETS_IPCS_H
|
||||||
|
#define _CORE_NETWORK_PACKETS_IPCS_H
|
||||||
|
|
||||||
|
#include<stdint.h>
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
namespace Network {
|
||||||
|
namespace Packets {
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Lobby Connection IPC Codes
|
||||||
|
/**
|
||||||
|
* Server IPC Lobby Type Codes.
|
||||||
|
*/
|
||||||
|
enum ServerLobbyIpcType : uint16_t
|
||||||
|
{
|
||||||
|
LobbyError = 0x0002,
|
||||||
|
LobbyServiceAccountList = 0x000C,
|
||||||
|
LobbyCharList = 0x000D,
|
||||||
|
LobbyCharCreate = 0x000E,
|
||||||
|
LobbyEnterWorld = 0x000F,
|
||||||
|
LobbyServerList = 0x0015,
|
||||||
|
LobbyRetainerList = 0x0017,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client IPC Lobby Type Codes.
|
||||||
|
*/
|
||||||
|
enum ClientLobbyIpcType : uint16_t
|
||||||
|
{
|
||||||
|
ReqCharList = 0x0003,
|
||||||
|
ReqEnterWorld = 0x0004,
|
||||||
|
ReqServiceAccountList = 0x0005,
|
||||||
|
|
||||||
|
ReqCharDelete = 0x000A,
|
||||||
|
ReqCharCreate = 0x000B,
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Zone Connection IPC Codes
|
||||||
|
/**
|
||||||
|
* Server IPC Zone Type Codes.
|
||||||
|
*/
|
||||||
|
enum ServerZoneIpcType : uint16_t
|
||||||
|
{
|
||||||
|
Ping = 0x0065, // updated for sb
|
||||||
|
Init = 0x0066, // updated for sb
|
||||||
|
Chat = 0x0067, // updated for sb
|
||||||
|
Logout = 0x0077, // updated for sb
|
||||||
|
Playtime = 0x00AF, // updated for sb
|
||||||
|
SocialRequestError = 0x00AD,
|
||||||
|
SocialRequestResponse = 0x11AF,
|
||||||
|
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
|
||||||
|
LinkshellList = 0x00D1, // updated for sb
|
||||||
|
StatusEffectList = 0x00F0, // updated for sb
|
||||||
|
Effect = 0x00F1, // updated for sb
|
||||||
|
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,
|
||||||
|
InventoryTransaction = 0x012A,
|
||||||
|
CurrencyCrystalInfo = 0x013D,
|
||||||
|
InventoryActionAck = 0x0139,
|
||||||
|
UpdateInventorySlot = 0x0140, // updated for sb
|
||||||
|
AddStatusEffect = 0x0141,
|
||||||
|
ActorControl142 = 0x0142, // unchanged for sb
|
||||||
|
ActorControl143 = 0x0143, // unchanged for sb
|
||||||
|
ActorControl144 = 0x0144, // unchanged for sb
|
||||||
|
UpdateHpMpTp = 0x0145, // unchanged for sb
|
||||||
|
|
||||||
|
CFNotify = 0x0078,
|
||||||
|
CFMemberStatus = 0x0079,
|
||||||
|
CFDutyInfo = 0x007A,
|
||||||
|
CFPlayerInNeed = 0x007F,
|
||||||
|
CFRegistered = 0x00B0,
|
||||||
|
CFAvailableContents = 0x01CF,
|
||||||
|
|
||||||
|
EventPlay = 0x0154, // updated for sb
|
||||||
|
EventStart = 0x015D, // updated for sb
|
||||||
|
EventFinish = 0x015E, // updated for sb
|
||||||
|
QuestActiveList = 0x0171, // updated for sb
|
||||||
|
QuestUpdate = 0x0172, // updated for sb
|
||||||
|
QuestCompleteList = 0x0173, // updated for sb
|
||||||
|
QuestFinish = 0x0174, // updated for sb
|
||||||
|
QuestMessage = 0x0179,
|
||||||
|
QuestTracker = 0x0181, // updated for sb
|
||||||
|
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
|
||||||
|
|
||||||
|
PrepareZoning = 0x0239, // updated for sb
|
||||||
|
|
||||||
|
// Unknown IPC types that still need to be sent
|
||||||
|
// TODO: figure all these out properly
|
||||||
|
IPCTYPE_UNK_320 = 0x1FB,
|
||||||
|
IPCTYPE_UNK_322 = 0x1FD,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: Include structures for the individual packet segment types
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client IPC Zone Type Codes.
|
||||||
|
*/
|
||||||
|
enum ClientZoneIpcType : uint16_t
|
||||||
|
{
|
||||||
|
|
||||||
|
PingHandler = 0x0065, // updated for sb
|
||||||
|
InitHandler = 0x0066, // updated for sb
|
||||||
|
ChatHandler = 0x0067, // updated for sb
|
||||||
|
|
||||||
|
FinishLoadingHandler = 0x0069, // updated for sb
|
||||||
|
|
||||||
|
CFCommenceHandler = 0x006F,
|
||||||
|
CFRegisterDuty = 0x0071,
|
||||||
|
CFRegisterRoulette = 0x0072,
|
||||||
|
PlayTimeHandler = 0x0073, // updated for sb
|
||||||
|
LogoutHandler = 0x0074, // updated for sb
|
||||||
|
|
||||||
|
CFDutyInfoHandler = 0x0078,
|
||||||
|
|
||||||
|
SocialReqSendHandler = 0x00A5,
|
||||||
|
SocialListHandler = 0x00AA, // updated for sb
|
||||||
|
SetSearchInfoHandler = 0x00AC, // updated for sb
|
||||||
|
|
||||||
|
ReqSearchInfoHandler = 0x00AD,
|
||||||
|
|
||||||
|
BlackListHandler = 0x00B7, // updated for sb
|
||||||
|
|
||||||
|
LinkshellListHandler = 0x00BF, // updated for sb
|
||||||
|
|
||||||
|
FcInfoReqHandler = 0x0100, // updated for sb
|
||||||
|
|
||||||
|
ZoneLineHandler = 0x0107, // updated for sb
|
||||||
|
ActionHandler = 0x0108, // updated for sb
|
||||||
|
DiscoveryHandler = 0x0109, // updated for sb
|
||||||
|
|
||||||
|
SkillHandler = 0x010B, // updated for sb
|
||||||
|
GMCommand1 = 0x010C, // updated for sb
|
||||||
|
GMCommand2 = 0x010D, // updated for sb
|
||||||
|
UpdatePositionHandler = 0x010F, // updated for sb
|
||||||
|
|
||||||
|
InventoryModifyHandler = 0x0116, // updated for sb
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
ReturnEventHandler = 0x0128,
|
||||||
|
TradeReturnEventHandler = 0x0129,
|
||||||
|
|
||||||
|
LinkshellEventHandler = 0x013C,
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Chat Connection IPC Codes
|
||||||
|
/**
|
||||||
|
* Server IPC Chat Type Codes.
|
||||||
|
*/
|
||||||
|
enum ServerChatIpcType : uint16_t
|
||||||
|
{
|
||||||
|
Tell = 0x0064, // updated for sb
|
||||||
|
TellErrNotFound = 0x0066,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client IPC Chat Type Codes.
|
||||||
|
*/
|
||||||
|
enum ClientChatIpcType : uint16_t
|
||||||
|
{
|
||||||
|
TellReq = 0x0064,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} /* Packets */
|
||||||
|
} /* Network */
|
||||||
|
} /* Core */
|
||||||
|
|
||||||
|
#endif /*_CORE_NETWORK_PACKETS_IPCS_H*/
|
|
@ -9,132 +9,132 @@ namespace Network {
|
||||||
namespace Packets {
|
namespace Packets {
|
||||||
namespace Server {
|
namespace Server {
|
||||||
|
|
||||||
struct FFXIVIpcRetainerList : FFXIVIpcBasePacket<LobbyRetainerList>
|
struct FFXIVIpcRetainerList : FFXIVIpcBasePacket<LobbyRetainerList>
|
||||||
{
|
{
|
||||||
uint8_t padding[0x210];
|
uint8_t padding[0x210];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
struct FFXIVIpcServiceIdInfo : FFXIVIpcBasePacket<LobbyServiceAccountList>
|
struct FFXIVIpcServiceIdInfo : FFXIVIpcBasePacket<LobbyServiceAccountList>
|
||||||
|
{
|
||||||
|
uint64_t seq;
|
||||||
|
uint8_t padding;
|
||||||
|
uint8_t numServiceAccounts;
|
||||||
|
uint8_t u1;
|
||||||
|
uint8_t u2;
|
||||||
|
uint32_t padding1;
|
||||||
|
|
||||||
|
struct
|
||||||
{
|
{
|
||||||
uint64_t seq;
|
uint32_t id;
|
||||||
uint8_t padding;
|
uint32_t unknown;
|
||||||
uint8_t numServiceAccounts;
|
uint32_t index;
|
||||||
uint8_t u1;
|
char name[0x44];
|
||||||
uint8_t u2;
|
} serviceAccount[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct FFXIVIpcServerList : FFXIVIpcBasePacket<LobbyServerList>
|
||||||
|
{
|
||||||
|
uint64_t seq;
|
||||||
|
uint16_t final;
|
||||||
|
uint16_t offset;
|
||||||
|
uint32_t numServers;
|
||||||
|
uint32_t padding;
|
||||||
|
uint32_t padding1;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint16_t id;
|
||||||
|
uint16_t index;
|
||||||
|
uint32_t flags; // 0x02 = World not accepting new characters
|
||||||
uint32_t padding1;
|
uint32_t padding1;
|
||||||
|
uint32_t icon; // 2 = bonus XP star
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint32_t id;
|
|
||||||
uint32_t unknown;
|
|
||||||
uint32_t index;
|
|
||||||
char name[0x44];
|
|
||||||
} serviceAccount[8];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct FFXIVIpcServerList : FFXIVIpcBasePacket<LobbyServerList>
|
|
||||||
{
|
|
||||||
uint64_t seq;
|
|
||||||
uint16_t final;
|
|
||||||
uint16_t offset;
|
|
||||||
uint32_t numServers;
|
|
||||||
uint32_t padding;
|
|
||||||
uint32_t padding1;
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint16_t id;
|
|
||||||
uint16_t index;
|
|
||||||
uint32_t flags; // 0x02 = World not accepting new characters
|
|
||||||
uint32_t padding1;
|
|
||||||
uint32_t icon; // 2 = bonus XP star
|
|
||||||
uint32_t padding2;
|
|
||||||
char name[0x40];
|
|
||||||
} server[6];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FFXIVIpcCharList : FFXIVIpcBasePacket<LobbyCharList>
|
|
||||||
{
|
|
||||||
uint64_t seq;
|
|
||||||
uint8_t counter; // current packet count * 4, count * 4 +1 on last packet.
|
|
||||||
uint8_t numInPacket; // always 2??
|
|
||||||
uint16_t padding;
|
|
||||||
uint8_t unknown1;
|
|
||||||
uint8_t unknown2;
|
|
||||||
uint8_t unknown3;
|
|
||||||
uint8_t unknown4; // 0x80 in case of last packet
|
|
||||||
uint32_t unknown5[7];
|
|
||||||
uint8_t unknown6; // 0x80 in case of last packet
|
|
||||||
uint8_t veteranRank;
|
|
||||||
uint8_t unknown7;
|
|
||||||
uint8_t padding1;
|
|
||||||
uint32_t daysSubscribed;
|
|
||||||
uint32_t remainingDays;
|
|
||||||
uint32_t daysToNextRank;
|
|
||||||
uint16_t maxCharOnWorld;
|
|
||||||
uint16_t unknown8;
|
|
||||||
uint32_t entitledExpansion;
|
|
||||||
uint32_t padding2;
|
uint32_t padding2;
|
||||||
|
char name[0x40];
|
||||||
|
} server[6];
|
||||||
|
};
|
||||||
|
|
||||||
struct CharaDetails
|
struct FFXIVIpcCharList : FFXIVIpcBasePacket<LobbyCharList>
|
||||||
{
|
{
|
||||||
uint32_t uniqueId;
|
uint64_t seq;
|
||||||
uint32_t padding;
|
uint8_t counter; // current packet count * 4, count * 4 +1 on last packet.
|
||||||
uint64_t contentId;
|
uint8_t numInPacket; // always 2??
|
||||||
uint32_t index;
|
uint16_t padding;
|
||||||
uint32_t padding2;
|
uint8_t unknown1;
|
||||||
uint16_t serverId;
|
uint8_t unknown2;
|
||||||
char nameChara[32];
|
uint8_t unknown3;
|
||||||
char nameServer[32];
|
uint8_t unknown4; // 0x80 in case of last packet
|
||||||
char charDetailJson[1030];
|
uint32_t unknown5[7];
|
||||||
} charaDetails[2];
|
uint8_t unknown6; // 0x80 in case of last packet
|
||||||
|
uint8_t veteranRank;
|
||||||
|
uint8_t unknown7;
|
||||||
|
uint8_t padding1;
|
||||||
|
uint32_t daysSubscribed;
|
||||||
|
uint32_t remainingDays;
|
||||||
|
uint32_t daysToNextRank;
|
||||||
|
uint16_t maxCharOnWorld;
|
||||||
|
uint16_t unknown8;
|
||||||
|
uint32_t entitledExpansion;
|
||||||
|
uint32_t padding2;
|
||||||
|
|
||||||
};
|
struct CharaDetails
|
||||||
|
|
||||||
struct FFXIVIpcEnterWorld : FFXIVIpcBasePacket<LobbyEnterWorld>
|
|
||||||
{
|
{
|
||||||
uint64_t seq;
|
uint32_t uniqueId;
|
||||||
uint32_t charId;
|
|
||||||
uint32_t padding;
|
uint32_t padding;
|
||||||
uint64_t contentId;
|
uint64_t contentId;
|
||||||
|
uint32_t index;
|
||||||
uint32_t padding2;
|
uint32_t padding2;
|
||||||
char sid[66];
|
uint16_t serverId;
|
||||||
uint16_t port;
|
char nameChara[32];
|
||||||
char host[48];
|
char nameServer[32];
|
||||||
uint64_t padding3;
|
char charDetailJson[1030];
|
||||||
uint64_t padding4;
|
} charaDetails[2];
|
||||||
};
|
|
||||||
|
|
||||||
struct FFXIVIpcCharCreate : FFXIVIpcBasePacket<LobbyCharCreate>
|
};
|
||||||
{
|
|
||||||
uint64_t seq;
|
|
||||||
uint8_t unknown;
|
|
||||||
uint8_t unknown_2;
|
|
||||||
uint8_t type;
|
|
||||||
uint8_t padding;
|
|
||||||
uint32_t unknown_3;
|
|
||||||
uint32_t unknown_4;
|
|
||||||
uint32_t unknown_5;
|
|
||||||
uint64_t content_id;
|
|
||||||
uint16_t unknown_7;
|
|
||||||
uint16_t unknown_8;
|
|
||||||
uint32_t unknown_9;
|
|
||||||
uint16_t unknown_10;
|
|
||||||
char name[32];
|
|
||||||
char world[32];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FFXIVIpcLobbyError : FFXIVIpcBasePacket<LobbyError>
|
struct FFXIVIpcEnterWorld : FFXIVIpcBasePacket<LobbyEnterWorld>
|
||||||
{
|
{
|
||||||
uint64_t seq;
|
uint64_t seq;
|
||||||
uint32_t error_id;
|
uint32_t charId;
|
||||||
uint32_t param;
|
uint32_t padding;
|
||||||
uint16_t message_id;
|
uint64_t contentId;
|
||||||
char message[516];
|
uint32_t padding2;
|
||||||
};
|
char sid[66];
|
||||||
|
uint16_t port;
|
||||||
|
char host[48];
|
||||||
|
uint64_t padding3;
|
||||||
|
uint64_t padding4;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FFXIVIpcCharCreate : FFXIVIpcBasePacket<LobbyCharCreate>
|
||||||
|
{
|
||||||
|
uint64_t seq;
|
||||||
|
uint8_t unknown;
|
||||||
|
uint8_t unknown_2;
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t padding;
|
||||||
|
uint32_t unknown_3;
|
||||||
|
uint32_t unknown_4;
|
||||||
|
uint32_t unknown_5;
|
||||||
|
uint64_t content_id;
|
||||||
|
uint16_t unknown_7;
|
||||||
|
uint16_t unknown_8;
|
||||||
|
uint32_t unknown_9;
|
||||||
|
uint16_t unknown_10;
|
||||||
|
char name[32];
|
||||||
|
char world[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FFXIVIpcLobbyError : FFXIVIpcBasePacket<LobbyError>
|
||||||
|
{
|
||||||
|
uint64_t seq;
|
||||||
|
uint32_t error_id;
|
||||||
|
uint32_t param;
|
||||||
|
uint16_t message_id;
|
||||||
|
char message[516];
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ public:
|
||||||
|
|
||||||
void handleGamePacket( Packets::FFXIVARR_PACKET_RAW &pPacket );
|
void handleGamePacket( Packets::FFXIVARR_PACKET_RAW &pPacket );
|
||||||
|
|
||||||
void handleGamePacket( Packets::GamePacketPtr pPacket );
|
void handlePacket( Packets::GamePacketPtr pPacket );
|
||||||
|
|
||||||
void sendPackets( Packets::PacketContainer * pPacket );
|
void sendPackets( Packets::PacketContainer * pPacket );
|
||||||
|
|
||||||
|
|
|
@ -247,7 +247,7 @@ namespace Core {
|
||||||
" UPDATE_DATE ) "
|
" UPDATE_DATE ) "
|
||||||
" VALUES (100, 100, " + std::to_string( m_iD ) + ", " + std::to_string( m_contentId ) + ", " +
|
" VALUES (100, 100, " + std::to_string( m_iD ) + ", " + std::to_string( m_contentId ) + ", " +
|
||||||
" UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)customize, size ) ) + "'), " +
|
" UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)customize, size ) ) + "'), " +
|
||||||
"'" + std::string( m_name ) + "', " + std::to_string( m_voice ) + ", 1, 1, " +
|
"'" + g_database.escapeString( std::string( m_name ) ) + "', " + std::to_string( m_voice ) + ", 1, 1, " +
|
||||||
std::to_string( startZone ) + ", " + std::to_string( x ) + ", " +
|
std::to_string( startZone ) + ", " + std::to_string( x ) + ", " +
|
||||||
std::to_string( y ) + ", " + std::to_string( z ) + ", " + std::to_string( o ) + ", " +
|
std::to_string( y ) + ", " + std::to_string( z ) + ", " + std::to_string( o ) + ", " +
|
||||||
std::to_string( m_accountId ) + ", UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)equipModel, 40 ) ) + "'), 1, NOW());" );
|
std::to_string( m_accountId ) + ", UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)equipModel, 40 ) ) + "'), 1, NOW());" );
|
||||||
|
|
|
@ -235,7 +235,7 @@ std::vector<Core::PlayerMinimal> Core::Network::SapphireAPI::getCharList( uint32
|
||||||
|
|
||||||
bool Core::Network::SapphireAPI::checkNameTaken( std::string name )
|
bool Core::Network::SapphireAPI::checkNameTaken( std::string name )
|
||||||
{
|
{
|
||||||
std::string query = "SELECT * FROM charabase WHERE Name = '" + name + "';";
|
std::string query = "SELECT * FROM charabase WHERE Name = '" + g_database.escapeString( name ) + "';";
|
||||||
|
|
||||||
auto pQR = g_database.query( query );
|
auto pQR = g_database.query( query );
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ extern Core::Data::ExdData g_exdData;
|
||||||
TODO:
|
TODO:
|
||||||
|
|
||||||
Base HP val modifier. I can only find values for levels 50~70.
|
Base HP val modifier. I can only find values for levels 50~70.
|
||||||
Attack power (and healing power). Need more researchg on this.
|
Attack power (and healing power). Needs more research on this.
|
||||||
Damage outgoing calculations. This includes auto-attacks, etc.
|
Damage outgoing calculations. This includes auto-attacks, etc.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -34,9 +34,9 @@ uint32_t CalcBattle::calculateBaseStat( PlayerPtr pPlayer )
|
||||||
uint8_t level = pPlayer->getLevel();
|
uint8_t level = pPlayer->getLevel();
|
||||||
|
|
||||||
if (level < 51)
|
if (level < 51)
|
||||||
base = static_cast<uint32_t>( 0.053f * ( level * level ) + (1.022f * level) - 0.907f + 20 );
|
base = 0.053f * ( level * level ) + ( 1.022f * level ) - 0.907f + 20;
|
||||||
else
|
else
|
||||||
base = static_cast<uint32_t>( 1.627f * level + 120.773f );
|
base = 1.627f * level + 120.773f;
|
||||||
|
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
@ -46,26 +46,35 @@ uint32_t CalcBattle::calculateBaseStat( PlayerPtr pPlayer )
|
||||||
|
|
||||||
uint32_t CalcBattle::calculateMaxHp( PlayerPtr pPlayer )
|
uint32_t CalcBattle::calculateMaxHp( PlayerPtr pPlayer )
|
||||||
{
|
{
|
||||||
// TODO: Replace ApproxBaseHP with something that can get us a BaseHP reliably.
|
// TODO: Replace ApproxBaseHP with something that can get us an accurate BaseHP.
|
||||||
// Is there any way to pull BaseHP without having to manually use a pet for every level, and using the values from a table?
|
// Is there any way to pull BaseHP without having to manually use a pet for every level, and using the values from a table?
|
||||||
|
// More info here: https://docs.google.com/spreadsheets/d/1de06KGT0cNRUvyiXNmjNgcNvzBCCQku7jte5QxEQRbs/edit?usp=sharing
|
||||||
|
|
||||||
auto classInfoIt = g_exdData.m_classJobInfoMap.find( pPlayer->getClass() );
|
auto classInfoIt = g_exdData.m_classJobInfoMap.find( pPlayer->getClass() );
|
||||||
auto paramGrowthInfoIt = g_exdData.m_paramGrowthInfoMap.find( pPlayer->getLevel() );
|
auto paramGrowthInfoIt = g_exdData.m_paramGrowthInfoMap.find( pPlayer->getLevel() );
|
||||||
|
|
||||||
|
if ( classInfoIt == g_exdData.m_classJobInfoMap.end() ||
|
||||||
|
paramGrowthInfoIt == g_exdData.m_paramGrowthInfoMap.end() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
uint8_t level = pPlayer->getLevel();
|
||||||
|
|
||||||
float baseStat = calculateBaseStat( pPlayer );
|
float baseStat = calculateBaseStat( pPlayer );
|
||||||
uint16_t vit = pPlayer->getStats().vit;
|
uint16_t vitStat = pPlayer->getStats().vit;
|
||||||
uint16_t hp_mod = paramGrowthInfoIt->second.hp_mod;
|
uint16_t hpMod = paramGrowthInfoIt->second.hp_mod;
|
||||||
uint16_t jobModHp = classInfoIt->second.mod_hp;
|
uint16_t jobModHp = classInfoIt->second.mod_hp;
|
||||||
uint16_t approxBaseHp = 0; // Read above
|
float approxBaseHp = 0.0f; // Read above
|
||||||
|
|
||||||
// These values are not precise.
|
// These values are not precise.
|
||||||
if ( pPlayer->getLevel() > 50 )
|
|
||||||
approxBaseHp = 0.1452f * paramGrowthInfoIt->second.mp_const + 1356.6f;
|
if ( level >= 60 )
|
||||||
|
approxBaseHp = 2600 + ( level - 60 ) * 100;
|
||||||
|
else if ( level >= 50 )
|
||||||
|
approxBaseHp = 1700 + ( ( level - 50 ) * ( 1700 * 1.04325f ) );
|
||||||
else
|
else
|
||||||
approxBaseHp = paramGrowthInfoIt->second.mp_const * 0.525f;
|
approxBaseHp = paramGrowthInfoIt->second.mp_const * 0.7596f;
|
||||||
|
|
||||||
uint16_t result = floor( jobModHp * ( approxBaseHp / 100.0f ) ) + floor( hp_mod / 100.0f * ( vit - baseStat ) );
|
|
||||||
|
|
||||||
|
uint16_t result = floor( jobModHp * ( approxBaseHp / 100.0f ) ) + floor( hpMod / 100.0f * ( vitStat - baseStat ) );
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -78,13 +87,17 @@ uint32_t CalcBattle::calculateMaxMp( PlayerPtr pPlayer )
|
||||||
auto classInfoIt = g_exdData.m_classJobInfoMap.find( pPlayer->getClass() );
|
auto classInfoIt = g_exdData.m_classJobInfoMap.find( pPlayer->getClass() );
|
||||||
auto paramGrowthInfoIt = g_exdData.m_paramGrowthInfoMap.find( pPlayer->getLevel() );
|
auto paramGrowthInfoIt = g_exdData.m_paramGrowthInfoMap.find( pPlayer->getLevel() );
|
||||||
|
|
||||||
|
if ( classInfoIt == g_exdData.m_classJobInfoMap.end() ||
|
||||||
|
paramGrowthInfoIt == g_exdData.m_paramGrowthInfoMap.end() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
float baseStat = calculateBaseStat( pPlayer );
|
float baseStat = calculateBaseStat( pPlayer );
|
||||||
uint16_t piety = pPlayer->getStats().pie;
|
uint16_t piety = pPlayer->getStats().pie;
|
||||||
uint16_t piety_scalar = paramGrowthInfoIt->second.mp_mod;
|
uint16_t pietyScalar = paramGrowthInfoIt->second.mp_mod;
|
||||||
uint16_t jobModMp = classInfoIt->second.mod_mpcpgp;
|
uint16_t jobModMp = classInfoIt->second.mod_mpcpgp;
|
||||||
uint16_t baseMp = paramGrowthInfoIt->second.mp_const;
|
uint16_t baseMp = paramGrowthInfoIt->second.mp_const;
|
||||||
|
|
||||||
uint16_t result = floor( floor( piety - baseStat ) * ( piety_scalar / 100 ) + baseMp ) * jobModMp / 100;
|
uint16_t result = floor( floor( piety - baseStat ) * ( pietyScalar / 100 ) + baseMp ) * jobModMp / 100;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -99,7 +112,6 @@ uint32_t CalcBattle::calculateHealValue( PlayerPtr pPlayer, uint32_t potency )
|
||||||
paramGrowthInfoIt == g_exdData.m_paramGrowthInfoMap.end())
|
paramGrowthInfoIt == g_exdData.m_paramGrowthInfoMap.end())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
auto jobModVal = classInfoIt->second;
|
auto jobModVal = classInfoIt->second;
|
||||||
|
|
||||||
// consider 3% variation
|
// consider 3% variation
|
||||||
|
|
|
@ -413,7 +413,8 @@ void Core::Entity::Player::setZone( uint32_t zoneId )
|
||||||
GamePacketNew< FFXIVIpcInitZone, ServerZoneIpcType > initZonePacket( getId() );
|
GamePacketNew< FFXIVIpcInitZone, ServerZoneIpcType > initZonePacket( getId() );
|
||||||
initZonePacket.data().zoneId = getCurrentZone()->getLayoutId();
|
initZonePacket.data().zoneId = getCurrentZone()->getLayoutId();
|
||||||
initZonePacket.data().weatherId = static_cast< uint8_t >( getCurrentZone()->getCurrentWeather() );
|
initZonePacket.data().weatherId = static_cast< uint8_t >( getCurrentZone()->getCurrentWeather() );
|
||||||
initZonePacket.data().bitmask = 0x2A;
|
initZonePacket.data().bitmask = 0x1;
|
||||||
|
initZonePacket.data().unknown5 = 0x2A;
|
||||||
initZonePacket.data().pos.x = getPos().x;
|
initZonePacket.data().pos.x = getPos().x;
|
||||||
initZonePacket.data().pos.y = getPos().y;
|
initZonePacket.data().pos.y = getPos().y;
|
||||||
initZonePacket.data().pos.z = getPos().z;
|
initZonePacket.data().pos.z = getPos().z;
|
||||||
|
@ -1255,6 +1256,19 @@ void Core::Entity::Player::queuePacket( Core::Network::Packets::GamePacketPtr pP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Core::Entity::Player::queueChatPacket( Core::Network::Packets::GamePacketPtr pPacket )
|
||||||
|
{
|
||||||
|
auto pSession = g_serverZone.getSession( m_id );
|
||||||
|
|
||||||
|
if( pSession )
|
||||||
|
{
|
||||||
|
auto pChatCon = pSession->getChatConnection();
|
||||||
|
|
||||||
|
if( pChatCon )
|
||||||
|
pChatCon->queueOutPacket( pPacket );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Core::Entity::Player::isLoadingComplete() const
|
bool Core::Entity::Player::isLoadingComplete() const
|
||||||
{
|
{
|
||||||
return m_bLoadingComplete;
|
return m_bLoadingComplete;
|
||||||
|
|
|
@ -433,6 +433,8 @@ public:
|
||||||
void sendQuestMessage( uint32_t questId, int8_t msgId, uint8_t type, uint32_t var1, uint32_t var2 );
|
void sendQuestMessage( uint32_t questId, int8_t msgId, uint8_t type, uint32_t var1, uint32_t var2 );
|
||||||
/*! queue a packet for the player */
|
/*! queue a packet for the player */
|
||||||
void queuePacket( Network::Packets::GamePacketPtr pPacket );
|
void queuePacket( Network::Packets::GamePacketPtr pPacket );
|
||||||
|
/*! queue a char connection packet for the player */
|
||||||
|
void queueChatPacket( Network::Packets::GamePacketPtr pPacket );
|
||||||
/*! returns true if loading is complete ( 0x69 has been received ) */
|
/*! returns true if loading is complete ( 0x69 has been received ) */
|
||||||
bool isLoadingComplete() const;
|
bool isLoadingComplete() const;
|
||||||
/*! set the loading complete bool */
|
/*! set the loading complete bool */
|
||||||
|
|
|
@ -46,6 +46,7 @@ Core::DebugCommandHandler::DebugCommandHandler()
|
||||||
registerCommand( "add", &DebugCommandHandler::add, "Loads and injects a premade Packet.", Common::UserLevel::all );
|
registerCommand( "add", &DebugCommandHandler::add, "Loads and injects a premade Packet.", Common::UserLevel::all );
|
||||||
//registerCommand( "debug", &DebugCommandHandler::debug, "Loads and injects a premade Packet.", Common::UserLevel::all );
|
//registerCommand( "debug", &DebugCommandHandler::debug, "Loads and injects a premade Packet.", Common::UserLevel::all );
|
||||||
registerCommand( "inject", &DebugCommandHandler::injectPacket, "Loads and injects a premade Packet.", Common::UserLevel::all );
|
registerCommand( "inject", &DebugCommandHandler::injectPacket, "Loads and injects a premade Packet.", Common::UserLevel::all );
|
||||||
|
registerCommand( "injectc", &DebugCommandHandler::injectChatPacket, "Loads and injects a premade Packet.", Common::UserLevel::all );
|
||||||
registerCommand( "script_reload", &DebugCommandHandler::scriptReload, "Loads and injects a premade Packet.", Common::UserLevel::all );
|
registerCommand( "script_reload", &DebugCommandHandler::scriptReload, "Loads and injects a premade Packet.", Common::UserLevel::all );
|
||||||
registerCommand( "nudge", &DebugCommandHandler::nudge, "Nudges you forward/up/down", Common::UserLevel::all );
|
registerCommand( "nudge", &DebugCommandHandler::nudge, "Nudges you forward/up/down", Common::UserLevel::all );
|
||||||
|
|
||||||
|
@ -473,6 +474,13 @@ void Core::DebugCommandHandler::injectPacket( char * data, Core::Entity::PlayerP
|
||||||
pSession->getZoneConnection()->injectPacket( data + 7, pPlayer );
|
pSession->getZoneConnection()->injectPacket( data + 7, pPlayer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Core::DebugCommandHandler::injectChatPacket( char * data, Core::Entity::PlayerPtr pPlayer, boost::shared_ptr< Core::DebugCommand > command )
|
||||||
|
{
|
||||||
|
auto pSession = g_serverZone.getSession( pPlayer->getId() );
|
||||||
|
if( pSession )
|
||||||
|
pSession->getChatConnection()->injectPacket( data + 8, pPlayer );
|
||||||
|
}
|
||||||
|
|
||||||
void Core::DebugCommandHandler::nudge( char * data, Entity::PlayerPtr pPlayer, boost::shared_ptr<DebugCommand> command )
|
void Core::DebugCommandHandler::nudge( char * data, Entity::PlayerPtr pPlayer, boost::shared_ptr<DebugCommand> command )
|
||||||
{
|
{
|
||||||
std::string subCommand;
|
std::string subCommand;
|
||||||
|
|
|
@ -35,6 +35,7 @@ public:
|
||||||
void scriptReload( char * data, Entity::PlayerPtr pPlayer, boost::shared_ptr<DebugCommand> command );
|
void scriptReload( char * data, Entity::PlayerPtr pPlayer, boost::shared_ptr<DebugCommand> command );
|
||||||
|
|
||||||
void injectPacket( char * data, Entity::PlayerPtr pPlayer, boost::shared_ptr<DebugCommand> command );
|
void injectPacket( char * data, Entity::PlayerPtr pPlayer, boost::shared_ptr<DebugCommand> command );
|
||||||
|
void injectChatPacket( char * data, Entity::PlayerPtr pPlayer, boost::shared_ptr<DebugCommand> command );
|
||||||
void nudge( char* data, Entity::PlayerPtr pPlayer, boost::shared_ptr<DebugCommand> command );
|
void nudge( char* data, Entity::PlayerPtr pPlayer, boost::shared_ptr<DebugCommand> command );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,7 +34,13 @@ Core::Network::GameConnection::GameConnection( Core::Network::HivePtr pHive,
|
||||||
auto setZoneHandler = [=]( uint16_t opcode, std::string handlerName, GameConnection::Handler pHandler )
|
auto setZoneHandler = [=]( uint16_t opcode, std::string handlerName, GameConnection::Handler pHandler )
|
||||||
{
|
{
|
||||||
m_zoneHandlerMap[opcode] = pHandler;
|
m_zoneHandlerMap[opcode] = pHandler;
|
||||||
m_packetHandlerStrMap[opcode] = handlerName;
|
m_zoneHandlerStrMap[opcode] = handlerName;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto setChatHandler = [=]( uint16_t opcode, std::string handlerName, GameConnection::Handler pHandler )
|
||||||
|
{
|
||||||
|
m_chatHandlerMap[opcode] = pHandler;
|
||||||
|
m_chatHandlerStrMap[opcode] = handlerName;
|
||||||
};
|
};
|
||||||
|
|
||||||
setZoneHandler( ClientZoneIpcType::PingHandler, "PingHandler", &GameConnection::pingHandler );
|
setZoneHandler( ClientZoneIpcType::PingHandler, "PingHandler", &GameConnection::pingHandler );
|
||||||
|
@ -79,11 +85,16 @@ Core::Network::GameConnection::GameConnection( Core::Network::HivePtr pHive,
|
||||||
setZoneHandler( ClientZoneIpcType::ReturnEventHandler, "EventHandlerReturn", &GameConnection::eventHandler );
|
setZoneHandler( ClientZoneIpcType::ReturnEventHandler, "EventHandlerReturn", &GameConnection::eventHandler );
|
||||||
setZoneHandler( ClientZoneIpcType::TradeReturnEventHandler, "EventHandlerReturn", &GameConnection::eventHandler );
|
setZoneHandler( ClientZoneIpcType::TradeReturnEventHandler, "EventHandlerReturn", &GameConnection::eventHandler );
|
||||||
|
|
||||||
|
setZoneHandler( ClientZoneIpcType::LinkshellEventHandler, "LinkshellEventHandler", &GameConnection::eventHandler );
|
||||||
|
|
||||||
setZoneHandler( ClientZoneIpcType::CFDutyInfoHandler, "CFDutyInfoRequest", &GameConnection::cfDutyInfoRequest );
|
setZoneHandler( ClientZoneIpcType::CFDutyInfoHandler, "CFDutyInfoRequest", &GameConnection::cfDutyInfoRequest );
|
||||||
setZoneHandler( ClientZoneIpcType::CFRegisterDuty, "CFRegisterDuty", &GameConnection::cfRegisterDuty );
|
setZoneHandler( ClientZoneIpcType::CFRegisterDuty, "CFRegisterDuty", &GameConnection::cfRegisterDuty );
|
||||||
setZoneHandler( ClientZoneIpcType::CFRegisterRoulette, "CFRegisterRoulette", &GameConnection::cfRegisterRoulette );
|
setZoneHandler( ClientZoneIpcType::CFRegisterRoulette, "CFRegisterRoulette", &GameConnection::cfRegisterRoulette );
|
||||||
setZoneHandler( ClientZoneIpcType::CFCommenceHandler, "CFDutyAccepted", &GameConnection::cfDutyAccepted);
|
setZoneHandler( ClientZoneIpcType::CFCommenceHandler, "CFDutyAccepted", &GameConnection::cfDutyAccepted);
|
||||||
|
|
||||||
|
|
||||||
|
setChatHandler( ClientChatIpcType::TellReq, "TellReq", &GameConnection::tellHandler);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::Network::GameConnection::~GameConnection()
|
Core::Network::GameConnection::~GameConnection()
|
||||||
|
@ -168,40 +179,78 @@ void Core::Network::GameConnection::queueOutPacket( Core::Network::Packets::Game
|
||||||
m_outQueue.push( outPacket );
|
m_outQueue.push( outPacket );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::Network::GameConnection::handleGamePacket( Core::Network::Packets::GamePacketPtr pPacket )
|
void Core::Network::GameConnection::handleZonePacket( const Packets::GamePacket& pPacket )
|
||||||
|
{
|
||||||
|
auto it = m_zoneHandlerMap.find( pPacket.getSubType() );
|
||||||
|
|
||||||
|
std::string sessionStr = "[" + std::to_string( m_pSession->getId() ) + "]";
|
||||||
|
|
||||||
|
if( it != m_zoneHandlerMap.end() )
|
||||||
|
{
|
||||||
|
auto itStr = m_zoneHandlerStrMap.find( pPacket.getSubType() );
|
||||||
|
std::string name = itStr != m_zoneHandlerStrMap.end() ? itStr->second : "unknown";
|
||||||
|
// dont display packet notification if it is a ping or pos update, don't want the spam
|
||||||
|
if( pPacket.getSubType() != PingHandler &&
|
||||||
|
pPacket.getSubType() != UpdatePositionHandler )
|
||||||
|
|
||||||
|
g_log.debug( sessionStr + " Handling Zone IPC : " + name + "( " +
|
||||||
|
boost::str( boost::format( "%|04X|" ) %
|
||||||
|
static_cast< uint32_t >( pPacket.getSubType() & 0xFFFF ) ) + " )" );
|
||||||
|
|
||||||
|
( this->*( it->second ) )( pPacket, m_pSession->getPlayer() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_log.debug( sessionStr + " Undefined Zone IPC : Unknown ( " +
|
||||||
|
boost::str( boost::format( "%|04X|" ) %
|
||||||
|
static_cast< uint32_t >( pPacket.getSubType() & 0xFFFF ) ) + " )" );
|
||||||
|
g_log.debug( pPacket.toString() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Core::Network::GameConnection::handleChatPacket( const Packets::GamePacket& pPacket )
|
||||||
|
{
|
||||||
|
auto it = m_chatHandlerMap.find( pPacket.getSubType() );
|
||||||
|
|
||||||
|
std::string sessionStr = "[" + std::to_string( m_pSession->getId() ) + "]";
|
||||||
|
|
||||||
|
if( it != m_chatHandlerMap.end() )
|
||||||
|
{
|
||||||
|
auto itStr = m_chatHandlerStrMap.find( pPacket.getSubType() );
|
||||||
|
std::string name = itStr != m_chatHandlerStrMap.end() ? itStr->second : "unknown";
|
||||||
|
// dont display packet notification if it is a ping or pos update, don't want the spam
|
||||||
|
|
||||||
|
g_log.debug( sessionStr + " Handling Chat IPC : " + name + "( " +
|
||||||
|
boost::str( boost::format( "%|04X|" ) %
|
||||||
|
static_cast< uint32_t >( pPacket.getSubType() & 0xFFFF ) ) + " )" );
|
||||||
|
|
||||||
|
( this->*( it->second ) )( pPacket, m_pSession->getPlayer() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_log.debug( sessionStr + " Undefined Chat IPC : Unknown ( " +
|
||||||
|
boost::str( boost::format( "%|04X|" ) %
|
||||||
|
static_cast< uint32_t >( pPacket.getSubType() & 0xFFFF ) ) + " )" );
|
||||||
|
g_log.debug( pPacket.toString() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::Network::GameConnection::handlePacket( Core::Network::Packets::GamePacketPtr pPacket )
|
||||||
{
|
{
|
||||||
if( !m_pSession )
|
if( !m_pSession )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*if( m_conType == Network::ConnectionType::Zone )
|
switch( m_conType )
|
||||||
{
|
{
|
||||||
g_log.debug( "Zone Packet" );
|
case Network::ConnectionType::Zone:
|
||||||
|
handleZonePacket( *pPacket );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Network::ConnectionType::Chat:
|
||||||
|
handleChatPacket( *pPacket );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if( m_conType == Network::ConnectionType::Chat )
|
|
||||||
{
|
|
||||||
g_log.debug( "Chat Packet" );
|
|
||||||
}*/
|
|
||||||
|
|
||||||
auto it = m_zoneHandlerMap.find( pPacket->getSubType() );
|
|
||||||
|
|
||||||
if( it != m_zoneHandlerMap.end() )
|
|
||||||
{
|
|
||||||
auto name = m_packetHandlerStrMap[pPacket->getSubType()];
|
|
||||||
// dont display packet notification if it is a ping or pos update, don't want the spam
|
|
||||||
if( pPacket->getSubType() != ClientZoneIpcType::PingHandler &&
|
|
||||||
pPacket->getSubType() != ClientZoneIpcType::UpdatePositionHandler )
|
|
||||||
g_log.debug( "[" + std::to_string( m_pSession->getId() ) + "] Handling packet : " + name + "( " +
|
|
||||||
boost::str( boost::format( "%|04X|" ) % static_cast< uint32_t >( pPacket->getSubType() & 0xFFFF ) ) + " )" );
|
|
||||||
|
|
||||||
( this->*( it->second ) )( *pPacket, m_pSession->getPlayer() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_log.debug( "[" + std::to_string( m_pSession->getId() ) + "] Undefined packet : Unknown ( " +
|
|
||||||
boost::str( boost::format( "%|04X|" ) % static_cast< uint32_t >( pPacket->getSubType() & 0xFFFF ) ) + " )" );
|
|
||||||
g_log.debug( pPacket->toString() );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +268,7 @@ void Core::Network::GameConnection::processInQueue()
|
||||||
// handle the incoming game packets
|
// handle the incoming game packets
|
||||||
while( auto pPacket = m_inQueue.pop() )
|
while( auto pPacket = m_inQueue.pop() )
|
||||||
{
|
{
|
||||||
handleGamePacket( pPacket );
|
handlePacket(pPacket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,27 +387,37 @@ void Core::Network::GameConnection::handlePackets( const Core::Network::Packets:
|
||||||
if( !m_pSession && session )
|
if( !m_pSession && session )
|
||||||
m_pSession = session;
|
m_pSession = session;
|
||||||
|
|
||||||
|
GamePacket pPe( 0x00, 0x18, 0, 0, 0x07 );
|
||||||
|
//pPe.setValAt< uint32_t >( 0x10, 0xE0000005 );
|
||||||
|
pPe.setValAt< uint32_t >( 0x10, 0xE0037603 );
|
||||||
|
pPe.setValAt< uint32_t >( 0x14, static_cast< uint32_t >( time( nullptr ) ) );
|
||||||
|
sendSinglePacket( &pPe );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// main connection, assinging it to the session
|
// main connection, assinging it to the session
|
||||||
if( ipcHeader.connectionType == ConnectionType::Zone )
|
if( ipcHeader.connectionType == ConnectionType::Zone )
|
||||||
{
|
{
|
||||||
|
pPe = GamePacket( 0x00, 0x38, 0, 0, 0x02 );
|
||||||
|
pPe.setValAt< uint32_t >( 0x10, playerId );
|
||||||
|
sendSinglePacket( &pPe );
|
||||||
g_log.info( "[" + std::string( id ) + "] Setting session for zone connection" );
|
g_log.info( "[" + std::string( id ) + "] Setting session for zone connection" );
|
||||||
session->setZoneConnection( pCon );
|
session->setZoneConnection( pCon );
|
||||||
}
|
}
|
||||||
// chat connection, assinging it to the session
|
// chat connection, assinging it to the session
|
||||||
else if( ipcHeader.connectionType == ConnectionType::Chat )
|
else if( ipcHeader.connectionType == ConnectionType::Chat )
|
||||||
{
|
{
|
||||||
|
pPe = GamePacket( 0x00, 0x38, 0, 0, 0x02 );
|
||||||
|
pPe.setValAt< uint32_t >( 0x10, playerId );
|
||||||
|
sendSinglePacket( &pPe );
|
||||||
|
|
||||||
g_log.info( "[" + std::string( id ) + "] Setting session for chat connection" );
|
g_log.info( "[" + std::string( id ) + "] Setting session for chat connection" );
|
||||||
session->setChatConnection( pCon );
|
session->setChatConnection( pCon );
|
||||||
|
pPe = GamePacket( 0x02, 0x28, playerId, playerId, 0x03 );
|
||||||
|
sendSinglePacket( &pPe );
|
||||||
}
|
}
|
||||||
|
|
||||||
GamePacket pPe( 0x00, 0x18, 0, 0, 0x07 );
|
|
||||||
pPe.setValAt< uint32_t >( 0x10, 0xE0000005 );
|
|
||||||
pPe.setValAt< uint32_t >( 0x14, static_cast< uint32_t >( time( nullptr ) ) );
|
|
||||||
sendSinglePacket( &pPe );
|
|
||||||
|
|
||||||
pPe = GamePacket( 0x00, 0x38, 0, 0, 0x02 );
|
|
||||||
pPe.setValAt< uint32_t >( 0x10, playerId );
|
|
||||||
sendSinglePacket( &pPe );
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,13 @@ private:
|
||||||
|
|
||||||
AcceptorPtr m_pAcceptor;
|
AcceptorPtr m_pAcceptor;
|
||||||
|
|
||||||
// handler for game packets (main type 0x03)
|
// handler for game packets (main type 0x03, connection type 1)
|
||||||
HandlerMap m_zoneHandlerMap;
|
HandlerMap m_zoneHandlerMap;
|
||||||
HandlerStrMap m_packetHandlerStrMap;
|
HandlerStrMap m_zoneHandlerStrMap;
|
||||||
|
|
||||||
|
// handler for game packets (main type 0x03, connection type 2)
|
||||||
|
HandlerMap m_chatHandlerMap;
|
||||||
|
HandlerStrMap m_chatHandlerStrMap;
|
||||||
|
|
||||||
SessionPtr m_pSession;
|
SessionPtr m_pSession;
|
||||||
|
|
||||||
|
@ -70,7 +74,11 @@ public:
|
||||||
void processInQueue();
|
void processInQueue();
|
||||||
void processOutQueue();
|
void processOutQueue();
|
||||||
|
|
||||||
void handleGamePacket( Packets::GamePacketPtr pPacket );
|
void handlePacket( Packets::GamePacketPtr pPacket );
|
||||||
|
|
||||||
|
void handleZonePacket( const Packets::GamePacket& pPacket );
|
||||||
|
|
||||||
|
void handleChatPacket( const Packets::GamePacket& pPacket );
|
||||||
|
|
||||||
void sendPackets( Packets::PacketContainer * pPacket );
|
void sendPackets( Packets::PacketContainer * pPacket );
|
||||||
|
|
||||||
|
@ -108,6 +116,8 @@ public:
|
||||||
DECLARE_HANDLER( gm1Handler );
|
DECLARE_HANDLER( gm1Handler );
|
||||||
DECLARE_HANDLER( gm2Handler );
|
DECLARE_HANDLER( gm2Handler );
|
||||||
|
|
||||||
|
DECLARE_HANDLER( tellHandler );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -108,7 +108,8 @@ void Core::Network::GameConnection::actionHandler( const Packets::GamePacket& in
|
||||||
}
|
}
|
||||||
case 0x69: // Cancel cast
|
case 0x69: // Cancel cast
|
||||||
{
|
{
|
||||||
pPlayer->getCurrentAction()->setInterrupted();
|
if( pPlayer->checkAction() )
|
||||||
|
pPlayer->getCurrentAction()->setInterrupted();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x133: // Update howtos seen
|
case 0x133: // Update howtos seen
|
||||||
|
|
|
@ -129,6 +129,16 @@ void Core::Network::GameConnection::eventHandler( const Packets::GamePacket& inP
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ClientZoneIpcType::LinkshellEventHandler:
|
||||||
|
{
|
||||||
|
uint32_t eventId = inPacket.getValAt< uint32_t >( 0x20 );
|
||||||
|
uint16_t subEvent = inPacket.getValAt< uint16_t >( 0x24 );
|
||||||
|
std::string lsName = inPacket.getStringAt( 0x27 );
|
||||||
|
|
||||||
|
abortEventFunc( pPlayer, 0, eventId );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <src/servers/Server_Common/Logging/Logger.h>
|
#include <src/servers/Server_Common/Logging/Logger.h>
|
||||||
#include <src/servers/Server_Common/Exd/ExdData.h>
|
#include <src/servers/Server_Common/Exd/ExdData.h>
|
||||||
#include <src/servers/Server_Common/Network/PacketContainer.h>
|
#include <src/servers/Server_Common/Network/PacketContainer.h>
|
||||||
|
#include <src/servers/Server_Common/Network/PacketDef/Chat/ServerChatDef.h>
|
||||||
|
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
|
|
||||||
|
@ -542,3 +543,58 @@ void Core::Network::GameConnection::logoutHandler( const Packets::GamePacket& in
|
||||||
logoutPacket.data().flags2 = 0x2000;
|
logoutPacket.data().flags2 = 0x2000;
|
||||||
queueOutPacket( logoutPacket );
|
queueOutPacket( logoutPacket );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Core::Network::GameConnection::tellHandler( const Packets::GamePacket& inPacket,
|
||||||
|
Entity::PlayerPtr pPlayer )
|
||||||
|
{
|
||||||
|
std::string targetPcName = inPacket.getStringAt( 0x21 );
|
||||||
|
std::string msg = inPacket.getStringAt( 0x41 );
|
||||||
|
|
||||||
|
auto pSession = g_serverZone.getSession( targetPcName );
|
||||||
|
|
||||||
|
if( !pSession )
|
||||||
|
{
|
||||||
|
GamePacketNew< FFXIVIpcTellErrNotFound, ServerChatIpcType > tellErrPacket( pPlayer->getId() );
|
||||||
|
strcpy( tellErrPacket.data().receipientName, targetPcName.c_str() );
|
||||||
|
sendSinglePacket( tellErrPacket );
|
||||||
|
|
||||||
|
g_log.debug( "TargetPc not found" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pTargetPlayer = pSession->getPlayer();
|
||||||
|
|
||||||
|
if( pTargetPlayer->hasStateFlag( PlayerStateFlag::BetweenAreas ) ||
|
||||||
|
pTargetPlayer->hasStateFlag( PlayerStateFlag::BetweenAreas1 ) )
|
||||||
|
{
|
||||||
|
// send error for player between areas
|
||||||
|
// TODO: implement me
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pTargetPlayer->hasStateFlag( PlayerStateFlag::BoundByDuty ) ||
|
||||||
|
pTargetPlayer->hasStateFlag( PlayerStateFlag::BoundByDuty1 ) )
|
||||||
|
{
|
||||||
|
// send error for player bound by duty
|
||||||
|
// TODO: implement me
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pTargetPlayer->getOnlineStatus() == OnlineStatus::Busy )
|
||||||
|
{
|
||||||
|
// send error for player being busy
|
||||||
|
// TODO: implement me ( i've seen this done with packet type 67 i think )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GamePacketNew< FFXIVIpcTell, ServerChatIpcType > tellPacket( pPlayer->getId() );
|
||||||
|
strcpy( tellPacket.data().msg, msg.c_str() );
|
||||||
|
strcpy( tellPacket.data().receipientName, pPlayer->getName().c_str() );
|
||||||
|
// TODO: do these have a meaning?
|
||||||
|
//tellPacket.data().u1 = 0x92CD7337;
|
||||||
|
//tellPacket.data().u2a = 0x2E;
|
||||||
|
//tellPacket.data().u2b = 0x40;
|
||||||
|
pTargetPlayer->queueChatPacket( tellPacket );
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue