2021-12-05 17:54:36 +00:00
# include "GameMessages.h"
# include "User.h"
# include "Entity.h"
# include "PacketUtils.h"
2023-09-21 01:06:28 +00:00
# include "BitStreamUtils.h"
2021-12-05 17:54:36 +00:00
# include "BitStream.h"
# include "Game.h"
# include "SlashCommandHandler.h"
# include "NiPoint3.h"
# include "NiQuaternion.h"
2023-10-21 23:31:55 +00:00
# include "Logger.h"
2021-12-05 17:54:36 +00:00
# include "GeneralUtils.h"
# include "Character.h"
# include "EntityManager.h"
# include "Database.h"
# include "dServer.h"
# include "../dWorldServer/ObjectIDManager.h"
# include "CppScripts.h"
# include "UserManager.h"
# include "ZoneInstanceManager.h"
# include "WorldPackets.h"
# include "Item.h"
# include "ZCompression.h"
# include "Player.h"
# include "dConfig.h"
# include "TeamManager.h"
# include "ChatPackets.h"
2023-08-18 19:14:40 +00:00
# include "MultiZoneEntranceComponent.h"
2022-09-02 18:49:19 +00:00
# include "eUnequippableActiveType.h"
2023-01-07 05:17:05 +00:00
# include "eMovementPlatformState.h"
# include "LeaderboardManager.h"
2023-05-13 22:22:00 +00:00
# include "Amf3.h"
2023-01-07 05:17:05 +00:00
# include "Loot.h"
2022-12-31 19:44:09 +00:00
# include "eRacingTaskParam.h"
2021-12-05 17:54:36 +00:00
# include "eMissionTaskType.h"
2023-01-07 05:17:05 +00:00
# include "eMissionState.h"
2023-04-25 18:17:40 +00:00
# include "eObjectBits.h"
2023-03-25 10:26:39 +00:00
# include "eTriggerEventType.h"
2023-05-02 22:39:21 +00:00
# include "eMatchUpdate.h"
# include "eCyclingMode.h"
# include "eCinematicEvent.h"
# include "eQuickBuildFailReason.h"
# include "eControlScheme.h"
# include "eStateChangeType.h"
2023-05-03 21:38:32 +00:00
# include "eConnectionType.h"
2021-12-05 17:54:36 +00:00
# include <sstream>
# include <future>
# include <chrono>
# include "RakString.h"
# include "../thirdparty/cpp-httplib/httplib.h" //sorry not sorry.
//CDB includes:
# include "CDClientManager.h"
# include "CDEmoteTable.h"
//Component includes:
# include "ControllablePhysicsComponent.h"
# include "CharacterComponent.h"
# include "MissionOfferComponent.h"
# include "MissionComponent.h"
# include "DestroyableComponent.h"
# include "ScriptComponent.h"
# include "RebuildComponent.h"
# include "VendorComponent.h"
2022-12-18 15:46:04 +00:00
# include "InventoryComponent.h"
2021-12-05 17:54:36 +00:00
# include "RocketLaunchpadControlComponent.h"
# include "PropertyEntranceComponent.h"
# include "MovingPlatformComponent.h"
# include "PetComponent.h"
# include "ModuleAssemblyComponent.h"
# include "VehiclePhysicsComponent.h"
2023-05-13 23:22:13 +00:00
# include "RenderComponent.h"
2021-12-05 17:54:36 +00:00
# include "PossessableComponent.h"
# include "PossessorComponent.h"
# include "RacingControlComponent.h"
# include "RailActivatorComponent.h"
2022-07-24 18:04:02 +00:00
# include "LevelProgressionComponent.h"
2023-08-04 02:44:03 +00:00
# include "DonationVendorComponent.h"
2021-12-05 17:54:36 +00:00
// Message includes:
# include "dZoneManager.h"
# include "PropertyDataMessage.h"
# include "PropertyManagementComponent.h"
# include "PropertyVendorComponent.h"
# include "PropertySelectQueryProperty.h"
# include "TradingManager.h"
2022-10-31 22:32:07 +00:00
# include "ControlBehaviors.h"
# include "AMFDeserialize.h"
2022-11-28 00:48:46 +00:00
# include "eBlueprintSaveResponseType.h"
2023-01-07 05:17:05 +00:00
# include "eAninmationFlags.h"
2023-05-13 22:22:00 +00:00
# include "AmfSerialize.h"
2023-03-04 07:16:37 +00:00
# include "eReplicaComponentType.h"
2023-05-03 21:38:32 +00:00
# include "eClientMessageType.h"
# include "eGameMessageType.h"
2023-05-11 00:26:04 +00:00
# include "ActivityManager.h"
2021-12-05 17:54:36 +00:00
2023-03-17 14:36:21 +00:00
# include "CDComponentsRegistryTable.h"
# include "CDObjectsTable.h"
2021-12-05 17:54:36 +00:00
void GameMessages : : SendFireEventClientSide ( const LWOOBJID & objectID , const SystemAddress & sysAddr , std : : u16string args , const LWOOBJID & object , int64_t param1 , int param2 , const LWOOBJID & sender ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : FIRE_EVENT_CLIENT_SIDE ) ;
2021-12-05 17:54:36 +00:00
//bitStream.Write(args);
uint32_t argSize = args . size ( ) ;
bitStream . Write ( argSize ) ;
for ( uint32_t k = 0 ; k < argSize ; k + + ) {
bitStream . Write ( static_cast < uint16_t > ( args [ k ] ) ) ;
}
bitStream . Write ( object ) ;
bitStream . Write0 ( ) ;
//bitStream.Write(param1);
bitStream . Write0 ( ) ;
//bitStream.Write(param2);
bitStream . Write ( sender ) ;
SEND_PACKET ;
}
2023-06-18 07:00:36 +00:00
void GameMessages : : SendTeleport ( const LWOOBJID & objectID , const NiPoint3 & pos , const NiQuaternion & rot , const SystemAddress & sysAddr , bool bSetRotation ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : TELEPORT ) ;
2021-12-05 17:54:36 +00:00
bool bIgnoreY = ( pos . y = = 0.0f ) ;
bool bUseNavmesh = false ;
bool bSkipAllChecks = false ;
//float w = 1.0f;
//float x = 0.0f;
//float y = 0.0f;
//float z = 0.0f;
bitStream . Write ( bIgnoreY ) ;
bitStream . Write ( bSetRotation ) ;
bitStream . Write ( bSkipAllChecks ) ;
bitStream . Write ( pos . x ) ;
bitStream . Write ( pos . y ) ;
bitStream . Write ( pos . z ) ;
bitStream . Write ( bUseNavmesh ) ;
bitStream . Write ( rot . w ! = 1.0f ) ;
if ( rot . w ! = 1.0f ) bitStream . Write ( rot . w ) ;
bitStream . Write ( rot . x ) ;
bitStream . Write ( rot . y ) ;
bitStream . Write ( rot . z ) ;
SEND_PACKET ;
}
void GameMessages : : SendPlayAnimation ( Entity * entity , const std : : u16string & animationName , float fPriority , float fScale ) {
if ( ! entity ) {
2023-10-21 23:31:55 +00:00
LOG ( " Trying to play animation, but entity var is nullptr! " ) ;
2021-12-05 17:54:36 +00:00
return ;
}
//Stolen from the old DLU codebase as the new one's autogenerated code doesn't work properly for animationIDs longer than 6 characters.
CBITSTREAM ;
CMSGHEADER ;
std : : string sAnimationID = GeneralUtils : : UTF16ToWTF8 ( animationName ) ;
uint32_t animationIDLength = sAnimationID . size ( ) ;
bool bExpectAnimToExist = true ;
bool bPlayImmediate = false ;
bool bTriggerOnCompleteMsg = false ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : PLAY_ANIMATION ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( animationIDLength ) ;
2023-09-21 01:06:28 +00:00
bitStream . Write ( LUWString ( animationName , animationIDLength ) ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bExpectAnimToExist ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
bitStream . Write ( bPlayImmediate ) ;
bitStream . Write ( bTriggerOnCompleteMsg ) ;
bitStream . Write ( fPriority ! = 0.0f ) ;
if ( fPriority ! = 0.0f ) bitStream . Write ( fPriority ) ;
bitStream . Write ( fScale ! = 1.0f ) ;
if ( fScale ! = 1.0f ) bitStream . Write ( fScale ) ;
SEND_PACKET_BROADCAST ;
}
void GameMessages : : SendPlayerReady ( Entity * entity , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : PLAYER_READY ) ;
2021-12-05 17:54:36 +00:00
SEND_PACKET ;
}
void GameMessages : : SendPlayerAllowedRespawn ( LWOOBJID entityID , bool doNotPromptRespawn , const SystemAddress & sysAddr ) {
2022-07-23 02:58:20 +00:00
CBITSTREAM ;
CMSGHEADER ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
bitStream . Write ( entityID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SET_PLAYER_ALLOWED_RESPAWN ) ;
2022-07-23 02:58:20 +00:00
bitStream . Write ( doNotPromptRespawn ) ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
SEND_PACKET ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : SendInvalidZoneTransferList ( Entity * entity , const SystemAddress & sysAddr , const std : : u16string & feedbackURL , const std : : u16string & invalidMapTransferList , bool feedbackOnExit , bool feedbackOnInvalidTransfer ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : INVALID_ZONE_TRANSFER_LIST ) ;
2021-12-05 17:54:36 +00:00
uint32_t CustomerFeedbackURLLength = feedbackURL . size ( ) ;
bitStream . Write ( CustomerFeedbackURLLength ) ;
for ( uint32_t k = 0 ; k < CustomerFeedbackURLLength ; k + + ) {
bitStream . Write ( static_cast < uint16_t > ( feedbackURL [ k ] ) ) ;
}
uint32_t InvalidMapTransferListLength = invalidMapTransferList . size ( ) ;
bitStream . Write ( InvalidMapTransferListLength ) ;
for ( uint32_t k = 0 ; k < InvalidMapTransferListLength ; k + + ) {
bitStream . Write ( static_cast < uint16_t > ( invalidMapTransferList [ k ] ) ) ;
}
bitStream . Write ( feedbackOnExit ) ;
bitStream . Write ( feedbackOnInvalidTransfer ) ;
SEND_PACKET ;
}
void GameMessages : : SendKnockback ( const LWOOBJID & objectID , const LWOOBJID & caster , const LWOOBJID & originator , int knockBackTimeMS , const NiPoint3 & vector ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : KNOCKBACK ) ;
2021-12-05 17:54:36 +00:00
bool casterFlag = caster ! = LWOOBJID_EMPTY ;
bool originatorFlag = originator ! = LWOOBJID_EMPTY ;
bool knockBackTimeMSFlag = knockBackTimeMS ! = 0 ;
bitStream . Write ( casterFlag ) ;
if ( casterFlag ) bitStream . Write ( caster ) ;
bitStream . Write ( originatorFlag ) ;
if ( originatorFlag ) bitStream . Write ( originator ) ;
bitStream . Write ( knockBackTimeMSFlag ) ;
if ( knockBackTimeMSFlag ) bitStream . Write ( knockBackTimeMS ) ;
bitStream . Write ( vector ) ;
SEND_PACKET_BROADCAST ;
}
void GameMessages : : SendStartArrangingWithItem (
Entity * entity ,
const SystemAddress & sysAddr ,
bool bFirstTime ,
const LWOOBJID & buildAreaID ,
NiPoint3 buildStartPOS ,
int sourceBAG ,
const LWOOBJID & sourceID ,
LOT sourceLOT ,
int sourceTYPE ,
const LWOOBJID & targetID ,
LOT targetLOT ,
NiPoint3 targetPOS ,
int targetTYPE
) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : START_ARRANGING_WITH_ITEM ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bFirstTime ) ;
bitStream . Write ( buildAreaID ! = LWOOBJID_EMPTY ) ;
if ( buildAreaID ! = LWOOBJID_EMPTY ) bitStream . Write ( buildAreaID ) ;
bitStream . Write ( buildStartPOS ) ;
bitStream . Write ( sourceBAG ) ;
bitStream . Write ( sourceID ) ;
bitStream . Write ( sourceLOT ) ;
bitStream . Write ( sourceTYPE ) ;
bitStream . Write ( targetID ) ;
bitStream . Write ( targetLOT ) ;
bitStream . Write ( targetPOS ) ;
bitStream . Write ( targetTYPE ) ;
SEND_PACKET ;
}
void GameMessages : : SendPlayerSetCameraCyclingMode ( const LWOOBJID & objectID , const SystemAddress & sysAddr ,
2022-07-23 02:58:20 +00:00
bool bAllowCyclingWhileDeadOnly , eCyclingMode cyclingMode ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : PLAYER_SET_CAMERA_CYCLING_MODE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bAllowCyclingWhileDeadOnly ) ;
2023-05-02 22:39:21 +00:00
bitStream . Write ( cyclingMode ! = eCyclingMode : : ALLOW_CYCLE_TEAMMATES ) ;
if ( cyclingMode ! = eCyclingMode : : ALLOW_CYCLE_TEAMMATES ) {
bitStream . Write ( cyclingMode ) ;
2021-12-05 17:54:36 +00:00
}
SEND_PACKET ;
}
void GameMessages : : SendPlayNDAudioEmitter ( Entity * entity , const SystemAddress & sysAddr , std : : string audioGUID ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : PLAY_ND_AUDIO_EMITTER ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write0 ( ) ;
bitStream . Write0 ( ) ;
uint32_t length = audioGUID . size ( ) ;
bitStream . Write ( length ) ;
for ( uint32_t k = 0 ; k < length ; k + + ) {
bitStream . Write ( static_cast < char > ( audioGUID [ k ] ) ) ;
}
bitStream . Write ( uint32_t ( 0 ) ) ;
bitStream . Write0 ( ) ;
bitStream . Write0 ( ) ;
SEND_PACKET_BROADCAST ;
}
void GameMessages : : SendStartPathing ( Entity * entity ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : START_PATHING ) ;
2021-12-05 17:54:36 +00:00
SEND_PACKET_BROADCAST ;
}
void GameMessages : : SendPlatformResync ( Entity * entity , const SystemAddress & sysAddr , bool bStopAtDesiredWaypoint ,
int iIndex , int iDesiredWaypointIndex , int nextIndex ,
2023-01-07 05:17:05 +00:00
eMovementPlatformState movementState ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
const auto lot = entity - > GetLOT ( ) ;
if ( lot = = 12341 | | lot = = 5027 | | lot = = 5028 | | lot = = 14335 | | lot = = 14447 | | lot = = 14449 ) {
iDesiredWaypointIndex = 0 ;
iIndex = 0 ;
nextIndex = 0 ;
bStopAtDesiredWaypoint = true ;
2023-01-07 05:17:05 +00:00
movementState = eMovementPlatformState : : Stationary ;
2021-12-05 17:54:36 +00:00
}
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : PLATFORM_RESYNC ) ;
2021-12-05 17:54:36 +00:00
bool bReverse = false ;
int eCommand = 0 ;
int eUnexpectedCommand = 0 ;
float fIdleTimeElapsed = 0.0f ;
float fMoveTimeElapsed = 0.0f ;
float fPercentBetweenPoints = 0.0f ;
NiPoint3 ptUnexpectedLocation = NiPoint3 : : ZERO ;
NiQuaternion qUnexpectedRotation = NiQuaternion : : IDENTITY ;
bitStream . Write ( bReverse ) ;
bitStream . Write ( bStopAtDesiredWaypoint ) ;
bitStream . Write ( eCommand ) ;
bitStream . Write < int32_t > ( static_cast < int32_t > ( movementState ) ) ;
bitStream . Write ( eUnexpectedCommand ) ;
bitStream . Write ( fIdleTimeElapsed ) ;
bitStream . Write ( fMoveTimeElapsed ) ;
bitStream . Write ( fPercentBetweenPoints ) ;
bitStream . Write ( iDesiredWaypointIndex ) ;
bitStream . Write ( iIndex ) ;
bitStream . Write ( nextIndex ) ;
bitStream . Write ( ptUnexpectedLocation . x ) ;
bitStream . Write ( ptUnexpectedLocation . y ) ;
bitStream . Write ( ptUnexpectedLocation . z ) ;
bitStream . Write ( qUnexpectedRotation ! = NiQuaternion : : IDENTITY ) ;
if ( qUnexpectedRotation ! = NiQuaternion : : IDENTITY ) {
bitStream . Write ( qUnexpectedRotation . x ) ;
bitStream . Write ( qUnexpectedRotation . y ) ;
bitStream . Write ( qUnexpectedRotation . z ) ;
bitStream . Write ( qUnexpectedRotation . w ) ;
}
SEND_PACKET_BROADCAST ;
}
void GameMessages : : SendRestoreToPostLoadStats ( Entity * entity , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : RESTORE_TO_POST_LOAD_STATS ) ;
2021-12-05 17:54:36 +00:00
SEND_PACKET ;
}
void GameMessages : : SendServerDoneLoadingAllObjects ( Entity * entity , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SERVER_DONE_LOADING_ALL_OBJECTS ) ;
2021-12-05 17:54:36 +00:00
SEND_PACKET ;
}
2023-03-24 23:16:45 +00:00
void GameMessages : : SendChatModeUpdate ( const LWOOBJID & objectID , eGameMasterLevel level ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : UPDATE_CHAT_MODE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( level ) ;
SEND_PACKET_BROADCAST ;
}
2023-03-24 23:16:45 +00:00
void GameMessages : : SendGMLevelBroadcast ( const LWOOBJID & objectID , eGameMasterLevel level ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : SET_GM_LEVEL ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write1 ( ) ;
bitStream . Write ( level ) ;
SEND_PACKET_BROADCAST ;
}
2022-04-23 11:14:55 +00:00
void GameMessages : : SendAddItemToInventoryClientSync ( Entity * entity , const SystemAddress & sysAddr , Item * item , const LWOOBJID & objectID , bool showFlyingLoot , int itemCount , LWOOBJID subKey , eLootSourceType lootSourceType ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : ADD_ITEM_TO_INVENTORY_CLIENT_SYNC ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( item - > GetBound ( ) ) ;
bitStream . Write ( item - > GetInfo ( ) . isBOE ) ;
bitStream . Write ( item - > GetInfo ( ) . isBOP ) ;
2023-05-02 22:39:21 +00:00
bitStream . Write ( lootSourceType ! = eLootSourceType : : NONE ) ; // Loot source
if ( lootSourceType ! = eLootSourceType : : NONE ) bitStream . Write ( lootSourceType ) ;
2021-12-05 17:54:36 +00:00
LWONameValue extraInfo ;
auto config = item - > GetConfig ( ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
for ( auto * data : config ) {
extraInfo . name + = GeneralUtils : : ASCIIToUTF16 ( data - > GetString ( ) ) + u " , " ;
}
if ( extraInfo . name . length ( ) > 0 ) extraInfo . name . pop_back ( ) ; // remove the last comma
2022-07-17 07:35:11 +00:00
bitStream . Write < uint32_t > ( extraInfo . name . size ( ) ) ;
2021-12-05 17:54:36 +00:00
if ( extraInfo . name . size ( ) > 0 ) {
for ( uint32_t i = 0 ; i < extraInfo . name . size ( ) ; + + i ) {
bitStream . Write ( static_cast < uint16_t > ( extraInfo . name [ i ] ) ) ;
}
bitStream . Write ( static_cast < uint16_t > ( 0x00 ) ) ;
}
bitStream . Write ( item - > GetLot ( ) ) ;
bitStream . Write ( subKey ! = LWOOBJID_EMPTY ) ;
if ( subKey ! = LWOOBJID_EMPTY ) bitStream . Write ( subKey ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
auto * inventory = item - > GetInventory ( ) ;
const auto inventoryType = inventory - > GetType ( ) ;
2022-07-17 07:35:11 +00:00
2022-04-23 12:13:06 +00:00
bitStream . Write ( inventoryType ! = eInventoryType : : ITEMS ) ;
if ( inventoryType ! = eInventoryType : : ITEMS ) bitStream . Write ( inventoryType ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( itemCount ! = 1 ) ;
if ( itemCount ! = 1 ) bitStream . Write ( itemCount ) ;
const auto count = item - > GetCount ( ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
bitStream . Write ( count ! = 0 ) ; //items total
if ( count ! = 0 ) bitStream . Write ( count ) ;
bitStream . Write ( objectID ) ;
bitStream . Write ( 0.0f ) ;
bitStream . Write ( 0.0f ) ;
bitStream . Write ( 0.0f ) ;
bitStream . Write ( showFlyingLoot ) ;
bitStream . Write ( item - > GetSlot ( ) ) ;
SEND_PACKET ;
}
2023-05-02 22:39:21 +00:00
void GameMessages : : SendNotifyClientFlagChange ( const LWOOBJID & objectID , uint32_t iFlagID , bool bFlag , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : NOTIFY_CLIENT_FLAG_CHANGE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bFlag ) ;
bitStream . Write ( iFlagID ) ;
SEND_PACKET ;
}
2023-05-02 22:39:21 +00:00
void GameMessages : : SendChangeObjectWorldState ( const LWOOBJID & objectID , eObjectWorldState state , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : CHANGE_OBJECT_WORLD_STATE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( state ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST
SEND_PACKET ;
}
void GameMessages : : SendOfferMission ( const LWOOBJID & entity , const SystemAddress & sysAddr , int32_t missionID , const LWOOBJID & offererID ) {
//You might be wondering.
//"Why are we sending it twice, once to a non-player object?
//Well, the first one (sent to the offerer) makes the client zoom into the object.
//The second, actually makes the UI pop up so you can be offered the mission.
//Why is it like this? Because LU isn't just a clown, it's the entire circus.
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( offererID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : OFFER_MISSION ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( missionID ) ;
bitStream . Write ( offererID ) ;
SEND_PACKET ;
{
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : OFFER_MISSION ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( missionID ) ;
bitStream . Write ( offererID ) ;
SEND_PACKET ;
}
}
void GameMessages : : SendNotifyMission ( Entity * entity , const SystemAddress & sysAddr , int missionID , int missionState , bool sendingRewards ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : NOTIFY_MISSION ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( missionID ) ;
bitStream . Write ( missionState ) ;
bitStream . Write ( sendingRewards ) ;
SEND_PACKET ;
}
void GameMessages : : SendNotifyMissionTask ( Entity * entity , const SystemAddress & sysAddr , int missionID , int taskMask , std : : vector < float > updates ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : NOTIFY_MISSION_TASK ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( missionID ) ;
bitStream . Write ( taskMask ) ;
bitStream . Write ( ( unsigned char ) updates . size ( ) ) ;
for ( uint32_t i = 0 ; i < updates . size ( ) ; + + i ) {
bitStream . Write ( updates [ i ] ) ;
}
SEND_PACKET ;
}
2022-02-03 06:50:02 +00:00
void GameMessages : : SendModifyLEGOScore ( Entity * entity , const SystemAddress & sysAddr , int64_t score , eLootSourceType sourceType ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : MODIFY_LEGO_SCORE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( score ) ;
2023-05-02 22:39:21 +00:00
bitStream . Write ( sourceType ! = eLootSourceType : : NONE ) ;
if ( sourceType ! = eLootSourceType : : NONE ) bitStream . Write ( sourceType ) ;
2021-12-05 17:54:36 +00:00
SEND_PACKET ;
}
2023-05-13 22:22:00 +00:00
void GameMessages : : SendUIMessageServerToSingleClient ( Entity * entity , const SystemAddress & sysAddr , const std : : string & message , AMFBaseValue & args ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : UI_MESSAGE_SERVER_TO_SINGLE_CLIENT ) ;
2021-12-05 17:54:36 +00:00
2023-05-13 22:22:00 +00:00
bitStream . Write < AMFBaseValue & > ( args ) ;
2021-12-05 17:54:36 +00:00
uint32_t strMessageNameLength = message . size ( ) ;
bitStream . Write ( strMessageNameLength ) ;
for ( uint32_t k = 0 ; k < strMessageNameLength ; k + + ) {
bitStream . Write ( static_cast < char > ( message [ k ] ) ) ;
}
SEND_PACKET ;
}
2023-05-13 22:22:00 +00:00
void GameMessages : : SendUIMessageServerToAllClients ( const std : : string & message , AMFBaseValue & args ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
LWOOBJID empty = 0 ;
bitStream . Write ( empty ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : UI_MESSAGE_SERVER_TO_ALL_CLIENTS ) ;
2021-12-05 17:54:36 +00:00
2023-05-13 22:22:00 +00:00
bitStream . Write < AMFBaseValue & > ( args ) ;
2021-12-05 17:54:36 +00:00
uint32_t strMessageNameLength = message . size ( ) ;
bitStream . Write ( strMessageNameLength ) ;
for ( uint32_t k = 0 ; k < strMessageNameLength ; k + + ) {
bitStream . Write ( static_cast < char > ( message [ k ] ) ) ;
}
SEND_PACKET_BROADCAST ;
}
void GameMessages : : SendPlayEmbeddedEffectOnAllClientsNearObject ( Entity * entity , std : : u16string effectName , const LWOOBJID & fromObjectID , float radius ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : PLAY_EMBEDDED_EFFECT_ON_ALL_CLIENTS_NEAR_OBJECT ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( static_cast < uint32_t > ( effectName . length ( ) ) ) ;
for ( uint32_t k = 0 ; k < effectName . length ( ) ; k + + ) {
bitStream . Write ( static_cast < uint16_t > ( effectName [ k ] ) ) ;
}
bitStream . Write ( fromObjectID ) ;
bitStream . Write ( radius ) ;
SEND_PACKET_BROADCAST ;
}
void GameMessages : : SendPlayFXEffect ( Entity * entity , int32_t effectID , const std : : u16string & effectType , const std : : string & name , LWOOBJID secondary , float priority , float scale , bool serialize ) {
SendPlayFXEffect ( entity - > GetObjectID ( ) , effectID , effectType , name , secondary , priority , scale , serialize ) ;
}
void GameMessages : : SendPlayFXEffect ( const LWOOBJID & entity , int32_t effectID , const std : : u16string & effectType , const std : : string & name , LWOOBJID secondary , float priority , float scale , bool serialize ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : PLAY_FX_EFFECT ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( effectID ! = - 1 ) ;
if ( effectID ! = - 1 ) bitStream . Write ( effectID ) ;
bitStream . Write < uint32_t > ( effectType . size ( ) ) ;
for ( const auto & k : effectType ) {
bitStream . Write < uint16_t > ( k ) ;
}
bitStream . Write ( scale ! = 1.0f ) ;
if ( scale ! = 1.0f ) bitStream . Write ( scale ) ;
bitStream . Write < uint32_t > ( name . size ( ) ) ;
for ( const auto & k : name ) {
bitStream . Write ( k ) ;
}
bitStream . Write ( priority ! = 1.0 ) ;
if ( priority ! = 1.0 ) bitStream . Write ( priority ) ;
bitStream . Write ( secondary ! = LWOOBJID_EMPTY ) ;
if ( secondary ! = LWOOBJID_EMPTY ) bitStream . Write ( secondary ) ;
bitStream . Write ( serialize ) ;
SEND_PACKET_BROADCAST ;
}
void GameMessages : : SendStopFXEffect ( Entity * entity , bool killImmediate , std : : string name ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : STOP_FX_EFFECT ) ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
bitStream . Write ( killImmediate ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write < uint32_t > ( name . size ( ) ) ;
bitStream . Write ( name . c_str ( ) , name . size ( ) ) ;
SEND_PACKET_BROADCAST ;
}
void GameMessages : : SendBroadcastTextToChatbox ( Entity * entity , const SystemAddress & sysAddr , const std : : u16string & attrs , const std : : u16string & wsText ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : BROADCAST_TEXT_TO_CHATBOX ) ;
2021-12-05 17:54:36 +00:00
LWONameValue attribs ;
attribs . name = attrs ;
attribs . length = attrs . size ( ) ;
bitStream . Write ( static_cast < uint32_t > ( attribs . length ) ) ;
for ( uint32_t i = 0 ; i < attribs . length ; + + i ) {
bitStream . Write ( static_cast < uint16_t > ( attribs . name [ i ] ) ) ;
}
bitStream . Write ( static_cast < uint16_t > ( 0x00 ) ) ; // Null Terminator
uint32_t wsTextLength = wsText . size ( ) ;
bitStream . Write ( wsTextLength ) ;
for ( uint32_t k = 0 ; k < wsTextLength ; k + + ) {
bitStream . Write ( static_cast < uint16_t > ( wsText [ k ] ) ) ;
}
SEND_PACKET_BROADCAST ;
}
2022-01-04 06:37:40 +00:00
void GameMessages : : SendSetCurrency ( Entity * entity , int64_t currency , int lootType , const LWOOBJID & sourceID , const LOT & sourceLOT , int sourceTradeID , bool overrideCurrent , eLootSourceType sourceType ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SET_CURRENCY ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( currency ) ;
bitStream . Write ( lootType ! = LOOTTYPE_NONE ) ;
if ( lootType ! = LOOTTYPE_NONE ) bitStream . Write ( lootType ) ;
bitStream . Write ( NiPoint3 : : ZERO ) ;
bitStream . Write ( sourceLOT ! = LOT_NULL ) ;
if ( sourceLOT ! = LOT_NULL ) bitStream . Write ( sourceLOT ) ;
bitStream . Write ( sourceID ! = LWOOBJID_EMPTY ) ;
if ( sourceID ! = LWOOBJID_EMPTY ) bitStream . Write ( sourceID ) ;
bitStream . Write ( sourceTradeID ! = LWOOBJID_EMPTY ) ;
if ( sourceTradeID ! = LWOOBJID_EMPTY ) bitStream . Write ( sourceTradeID ) ;
2023-05-02 22:39:21 +00:00
bitStream . Write ( sourceType ! = eLootSourceType : : NONE ) ;
if ( sourceType ! = eLootSourceType : : NONE ) bitStream . Write ( sourceType ) ;
2021-12-05 17:54:36 +00:00
SystemAddress sysAddr = entity - > GetSystemAddress ( ) ;
SEND_PACKET ;
}
2023-05-02 22:39:21 +00:00
void GameMessages : : SendRebuildNotifyState ( Entity * entity , eRebuildState prevState , eRebuildState state , const LWOOBJID & playerID ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : REBUILD_NOTIFY_STATE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( prevState ) ;
bitStream . Write ( state ) ;
bitStream . Write ( playerID ) ;
SEND_PACKET_BROADCAST ;
}
2023-05-02 22:39:21 +00:00
void GameMessages : : SendEnableRebuild ( Entity * entity , bool enable , bool fail , bool success , eQuickBuildFailReason failReason , float duration , const LWOOBJID & playerID ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : ENABLE_REBUILD ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( enable ) ;
bitStream . Write ( fail ) ;
bitStream . Write ( success ) ;
2023-05-02 22:39:21 +00:00
bitStream . Write ( failReason ! = eQuickBuildFailReason : : NOT_GIVEN ) ;
if ( failReason ! = eQuickBuildFailReason : : NOT_GIVEN ) bitStream . Write ( failReason ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( duration ) ;
bitStream . Write ( playerID ) ;
SEND_PACKET_BROADCAST ;
}
void GameMessages : : SendTerminateInteraction ( const LWOOBJID & objectID , eTerminateType type , const LWOOBJID & terminator ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : TERMINATE_INTERACTION ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( terminator ) ;
bitStream . Write ( type ) ;
SEND_PACKET_BROADCAST ;
}
void GameMessages : : SendDieNoImplCode ( Entity * entity , const LWOOBJID & killerID , const LWOOBJID & lootOwnerID , eKillType killType , std : : u16string deathType , float directionRelative_AngleY , float directionRelative_AngleXZ , float directionRelative_Force , bool bClientDeath , bool bSpawnLoot ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : DIE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bClientDeath ) ;
bitStream . Write ( bSpawnLoot ) ;
bitStream . Write ( deathType ) ;
bitStream . Write ( directionRelative_AngleXZ ) ;
bitStream . Write ( directionRelative_AngleY ) ;
bitStream . Write ( directionRelative_Force ) ;
bitStream . Write ( killType ! = eKillType : : VIOLENT ) ;
if ( killType ! = eKillType : : VIOLENT ) bitStream . Write ( killType ) ;
bitStream . Write ( killerID ) ;
bitStream . Write ( lootOwnerID ) ;
SEND_PACKET_BROADCAST ;
}
void GameMessages : : SendDie ( Entity * entity , const LWOOBJID & killerID , const LWOOBJID & lootOwnerID , bool bDieAccepted , eKillType killType , std : : u16string deathType , float directionRelative_AngleY , float directionRelative_AngleXZ , float directionRelative_Force , bool bClientDeath , bool bSpawnLoot , float coinSpawnTime ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : DIE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bClientDeath ) ;
bitStream . Write ( bSpawnLoot ) ;
//bitStream.Write(coinSpawnTime != -1.0f);
//if (coinSpawnTime != -1.0f) bitStream.Write(coinSpawnTime);
uint32_t deathTypeLength = deathType . size ( ) ;
bitStream . Write ( deathTypeLength ) ;
for ( uint32_t k = 0 ; k < deathTypeLength ; k + + ) {
bitStream . Write ( static_cast < uint16_t > ( deathType [ k ] ) ) ;
}
bitStream . Write ( directionRelative_AngleXZ ) ;
bitStream . Write ( directionRelative_AngleY ) ;
bitStream . Write ( directionRelative_Force ) ;
2023-05-02 22:39:21 +00:00
bitStream . Write ( killType ! = eKillType : : VIOLENT ) ;
if ( killType ! = eKillType : : VIOLENT ) bitStream . Write ( killType ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( killerID ) ;
bitStream . Write ( lootOwnerID ! = LWOOBJID_EMPTY ) ;
if ( lootOwnerID ! = LWOOBJID_EMPTY ) {
bitStream . Write ( lootOwnerID ) ;
}
SEND_PACKET_BROADCAST ;
}
void GameMessages : : SendSetInventorySize ( Entity * entity , int invType , int size ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SET_INVENTORY_SIZE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( invType ) ;
bitStream . Write ( size ) ;
SystemAddress sysAddr = entity - > GetSystemAddress ( ) ;
SEND_PACKET ;
}
void GameMessages : : SendSetEmoteLockState ( Entity * entity , bool bLock , int emoteID ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SET_EMOTE_LOCK_STATE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bLock ) ;
bitStream . Write ( emoteID ) ;
SystemAddress sysAddr = entity - > GetSystemAddress ( ) ;
SEND_PACKET ;
}
2022-01-24 22:02:56 +00:00
void GameMessages : : SendSetJetPackMode ( Entity * entity , bool use , bool bypassChecks , bool doHover , int effectID , float airspeed , float maxAirspeed , float verticalVelocity , int warningEffectID ) {
/* historical jamesster jetpack values
2021-12-05 17:54:36 +00:00
if ( bIsJamessterPhysics ) {
fAirspeed = 75 ;
fMaxAirspeed = 75 ;
fVertVel = 15 ;
}
2022-01-24 22:02:56 +00:00
*/
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SET_JET_PACK_MODE ) ;
2021-12-05 17:54:36 +00:00
2022-01-24 22:02:56 +00:00
bitStream . Write ( bypassChecks ) ;
bitStream . Write ( doHover ) ;
bitStream . Write ( use ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( effectID ! = - 1 ) ;
if ( effectID ! = - 1 ) bitStream . Write ( effectID ) ;
2022-01-24 22:02:56 +00:00
bitStream . Write ( airspeed ! = 10 ) ;
if ( airspeed ! = 10 ) bitStream . Write ( airspeed ) ;
2021-12-05 17:54:36 +00:00
2022-01-24 22:02:56 +00:00
bitStream . Write ( maxAirspeed ! = 15 ) ;
if ( maxAirspeed ! = 15 ) bitStream . Write ( maxAirspeed ) ;
2021-12-05 17:54:36 +00:00
2022-01-24 22:02:56 +00:00
bitStream . Write ( verticalVelocity ! = 1 ) ;
if ( verticalVelocity ! = 1 ) bitStream . Write ( verticalVelocity ) ;
2021-12-05 17:54:36 +00:00
2022-01-24 22:02:56 +00:00
bitStream . Write ( warningEffectID ! = - 1 ) ;
if ( warningEffectID ! = - 1 ) bitStream . Write ( warningEffectID ) ;
2021-12-05 17:54:36 +00:00
SEND_PACKET_BROADCAST ;
}
void GameMessages : : SendResurrect ( Entity * entity ) {
2023-03-08 13:32:03 +00:00
// Restore the players health after the animation for respawning has finished.
// This is when the health appered back in live, not immediately upon requesting respawn
// Add a half second in case someone decides to cheat and move during the death animation
// and just make sure the client has time to be ready.
constexpr float respawnTime = 3.66700005531311f + 0.5f ;
entity - > AddCallbackTimer ( respawnTime , [ = ] ( ) {
auto * destroyableComponent = entity - > GetComponent < DestroyableComponent > ( ) ;
if ( destroyableComponent ! = nullptr & & entity - > GetLOT ( ) = = 1 ) {
auto * levelComponent = entity - > GetComponent < LevelProgressionComponent > ( ) ;
if ( levelComponent ) {
2023-05-03 06:31:50 +00:00
int32_t healthToRestore = levelComponent - > GetLevel ( ) > = 45 ? 8 : 4 ;
if ( healthToRestore > destroyableComponent - > GetMaxHealth ( ) ) healthToRestore = destroyableComponent - > GetMaxHealth ( ) ;
destroyableComponent - > SetHealth ( healthToRestore ) ;
int32_t imaginationToRestore = levelComponent - > GetLevel ( ) > = 45 ? 20 : 6 ;
if ( imaginationToRestore > destroyableComponent - > GetMaxImagination ( ) ) imaginationToRestore = destroyableComponent - > GetMaxImagination ( ) ;
destroyableComponent - > SetImagination ( imaginationToRestore ) ;
2023-03-08 13:32:03 +00:00
}
2021-12-05 17:54:36 +00:00
}
2023-10-16 12:55:57 +00:00
} ) ;
2023-03-08 13:32:03 +00:00
2021-12-05 17:54:36 +00:00
2023-03-04 07:16:37 +00:00
auto cont = static_cast < ControllablePhysicsComponent * > ( entity - > GetComponent ( eReplicaComponentType : : CONTROLLABLE_PHYSICS ) ) ;
2021-12-05 17:54:36 +00:00
if ( cont & & entity - > GetLOT ( ) = = 1 ) {
cont - > SetPosition ( entity - > GetRespawnPosition ( ) ) ;
cont - > SetRotation ( entity - > GetRespawnRotation ( ) ) ;
}
CBITSTREAM ;
CMSGHEADER ;
bool bRezImmediately = false ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : RESURRECT ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bRezImmediately ) ;
SEND_PACKET_BROADCAST ;
}
void GameMessages : : SendStop2DAmbientSound ( Entity * entity , bool force , std : : string audioGUID , bool result ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-08-04 02:27:40 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : STOP2_D_AMBIENT_SOUND ) ;
2021-12-05 17:54:36 +00:00
uint32_t audioGUIDSize = audioGUID . size ( ) ;
bitStream . Write ( force ) ;
bitStream . Write ( audioGUIDSize ) ;
for ( uint32_t k = 0 ; k < audioGUIDSize ; k + + ) {
bitStream . Write ( static_cast < char > ( audioGUID [ k ] ) ) ;
}
bitStream . Write ( result ) ;
SystemAddress sysAddr = entity - > GetSystemAddress ( ) ;
SEND_PACKET ;
}
void GameMessages : : SendPlay2DAmbientSound ( Entity * entity , std : : string audioGUID , bool result ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-08-04 02:27:40 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : PLAY2_D_AMBIENT_SOUND ) ;
2021-12-05 17:54:36 +00:00
uint32_t audioGUIDSize = audioGUID . size ( ) ;
bitStream . Write ( audioGUIDSize ) ;
for ( uint32_t k = 0 ; k < audioGUIDSize ; k + + ) {
bitStream . Write ( static_cast < char > ( audioGUID [ k ] ) ) ;
}
bitStream . Write ( result ) ;
SystemAddress sysAddr = entity - > GetSystemAddress ( ) ;
SEND_PACKET ;
}
void GameMessages : : SendSetNetworkScriptVar ( Entity * entity , const SystemAddress & sysAddr , std : : string data ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-08-04 02:27:40 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : SCRIPT_NETWORK_VAR_UPDATE ) ;
2021-12-05 17:54:36 +00:00
2022-08-02 13:56:20 +00:00
// FIXME: this is a bad place to need to do a conversion because we have no clue whether data is utf8 or plain ascii
// an this has performance implications
2021-12-05 17:54:36 +00:00
const auto u16Data = GeneralUtils : : ASCIIToUTF16 ( data ) ;
uint32_t dataSize = static_cast < uint32_t > ( u16Data . size ( ) ) ;
bitStream . Write ( dataSize ) ;
for ( auto value : u16Data ) {
bitStream . Write ( uint16_t ( value ) ) ;
}
if ( dataSize > 0 ) bitStream . Write ( uint16_t ( 0 ) ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendDropClientLoot ( Entity * entity , const LWOOBJID & sourceID , LOT item , int currency , NiPoint3 spawnPos , int count ) {
2023-10-28 10:32:19 +00:00
if ( Game : : config - > GetValue ( " disable_drops " ) = = " 1 " | | ! entity ) {
2021-12-05 17:54:36 +00:00
return ;
}
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
bool bUsePosition = false ;
NiPoint3 finalPosition ;
LWOOBJID lootID = LWOOBJID_EMPTY ;
LWOOBJID owner = entity - > GetObjectID ( ) ;
if ( item ! = LOT_NULL & & item ! = 0 ) {
lootID = ObjectIDManager : : Instance ( ) - > GenerateObjectID ( ) ;
Loot : : Info info ;
info . id = lootID ;
info . count = count ;
info . lot = item ;
entity - > AddLootItem ( info ) ;
}
2021-12-11 13:21:00 +00:00
if ( item = = LOT_NULL & & currency ! = 0 ) {
2021-12-11 13:57:15 +00:00
entity - > RegisterCoinDrop ( currency ) ;
2021-12-11 13:21:00 +00:00
}
2021-12-05 17:54:36 +00:00
if ( spawnPos ! = NiPoint3 : : ZERO ) {
bUsePosition = true ;
//Calculate where the loot will go:
uint16_t degree = GeneralUtils : : GenerateRandomNumber < uint16_t > ( 0 , 360 ) ;
double rad = degree * 3.14 / 180 ;
double sin_v = sin ( rad ) * 4.2 ;
double cos_v = cos ( rad ) * 4.2 ;
finalPosition = NiPoint3 ( static_cast < float > ( spawnPos . GetX ( ) + sin_v ) , spawnPos . GetY ( ) , static_cast < float > ( spawnPos . GetZ ( ) + cos_v ) ) ;
}
//Write data to packet & send:
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : DROP_CLIENT_LOOT ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bUsePosition ) ;
bitStream . Write ( finalPosition ! = NiPoint3 : : ZERO ) ;
if ( finalPosition ! = NiPoint3 : : ZERO ) bitStream . Write ( finalPosition ) ;
bitStream . Write ( currency ) ;
bitStream . Write ( item ) ;
bitStream . Write ( lootID ) ;
bitStream . Write ( owner ) ;
bitStream . Write ( sourceID ) ;
bitStream . Write ( spawnPos ! = NiPoint3 : : ZERO ) ;
if ( spawnPos ! = NiPoint3 : : ZERO ) bitStream . Write ( spawnPos ) ;
auto * team = TeamManager : : Instance ( ) - > GetTeam ( owner ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
// Currency and powerups should not sync
if ( team ! = nullptr & & currency = = 0 ) {
2023-03-17 14:36:21 +00:00
CDObjectsTable * objectsTable = CDClientManager : : Instance ( ) . GetTable < CDObjectsTable > ( ) ;
2021-12-05 17:54:36 +00:00
const CDObjects & object = objectsTable - > GetByID ( item ) ;
if ( object . type ! = " Powerup " ) {
for ( const auto memberId : team - > members ) {
2023-07-15 20:56:33 +00:00
auto * member = Game : : entityManager - > GetEntity ( memberId ) ;
2021-12-05 17:54:36 +00:00
if ( member = = nullptr ) continue ;
SystemAddress sysAddr = member - > GetSystemAddress ( ) ;
SEND_PACKET ;
}
return ;
}
}
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
SystemAddress sysAddr = entity - > GetSystemAddress ( ) ;
SEND_PACKET ;
}
2023-05-02 22:39:21 +00:00
void GameMessages : : SendSetPlayerControlScheme ( Entity * entity , eControlScheme controlScheme ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bool bDelayCamSwitchIfInCinematic = true ;
bool bSwitchCam = true ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SET_PLAYER_CONTROL_SCHEME ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bDelayCamSwitchIfInCinematic ) ;
bitStream . Write ( bSwitchCam ) ;
2023-05-02 22:39:21 +00:00
bitStream . Write ( controlScheme ! = eControlScheme : : SCHEME_A ) ;
if ( controlScheme ! = eControlScheme : : SCHEME_A ) bitStream . Write ( controlScheme ) ;
2021-12-05 17:54:36 +00:00
SystemAddress sysAddr = entity - > GetSystemAddress ( ) ;
SEND_PACKET ;
}
void GameMessages : : SendPlayerReachedRespawnCheckpoint ( Entity * entity , const NiPoint3 & position , const NiQuaternion & rotation ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : PLAYER_REACHED_RESPAWN_CHECKPOINT ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( position . x ) ;
bitStream . Write ( position . y ) ;
bitStream . Write ( position . z ) ;
2023-03-04 07:16:37 +00:00
auto con = static_cast < ControllablePhysicsComponent * > ( entity - > GetComponent ( eReplicaComponentType : : CONTROLLABLE_PHYSICS ) ) ;
2021-12-05 17:54:36 +00:00
if ( con ) {
auto rot = con - > GetRotation ( ) ;
bitStream . Write ( rot . x ) ;
bitStream . Write ( rot . y ) ;
bitStream . Write ( rot . z ) ;
bitStream . Write ( rot . w ) ;
}
//bitStream.Write(position);
//bitStream.Write(rotation);
SystemAddress sysAddr = entity - > GetSystemAddress ( ) ;
SEND_PACKET ;
}
2023-10-09 20:18:51 +00:00
void GameMessages : : SendAddSkill ( Entity * entity , TSkillID skillID , BehaviorSlot slotID ) {
2021-12-05 17:54:36 +00:00
int AICombatWeight = 0 ;
bool bFromSkillSet = false ;
int castType = 0 ;
float fTimeSecs = - 1.0f ;
int iTimesCanCast = - 1 ;
bool temporary = true ;
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : ADD_SKILL ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( AICombatWeight ! = 0 ) ;
if ( AICombatWeight ! = 0 ) bitStream . Write ( AICombatWeight ) ;
bitStream . Write ( bFromSkillSet ) ;
bitStream . Write ( castType ! = 0 ) ;
if ( castType ! = 0 ) bitStream . Write ( castType ) ;
bitStream . Write ( fTimeSecs ! = - 1.0f ) ;
if ( fTimeSecs ! = - 1.0f ) bitStream . Write ( fTimeSecs ) ;
bitStream . Write ( iTimesCanCast ! = - 1 ) ;
if ( iTimesCanCast ! = - 1 ) bitStream . Write ( iTimesCanCast ) ;
bitStream . Write ( skillID ) ;
2023-10-09 20:18:51 +00:00
bitStream . Write ( slotID ! = BehaviorSlot : : Invalid ) ;
if ( slotID ! = BehaviorSlot : : Invalid ) bitStream . Write ( slotID ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( temporary ) ;
SystemAddress sysAddr = entity - > GetSystemAddress ( ) ;
SEND_PACKET ;
}
void GameMessages : : SendRemoveSkill ( Entity * entity , TSkillID skillID ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : REMOVE_SKILL ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( false ) ;
bitStream . Write ( skillID ) ;
SystemAddress sysAddr = entity - > GetSystemAddress ( ) ;
SEND_PACKET ;
}
void GameMessages : : SendFinishArrangingWithItem ( Entity * entity , const LWOOBJID & buildArea ) {
CBITSTREAM ;
CMSGHEADER ;
bool bFirstTime = true ;
const LWOOBJID & buildAreaID = buildArea ;
int newSourceBAG = 0 ;
const LWOOBJID & newSourceID = LWOOBJID_EMPTY ;
LOT newSourceLOT = LOT_NULL ;
int newSourceTYPE = 0 ;
const LWOOBJID & newTargetID = LWOOBJID_EMPTY ;
LOT newTargetLOT = LOT_NULL ;
int newTargetTYPE = 0 ;
NiPoint3 newTargetPOS = NiPoint3 ( ) ;
int oldItemBAG = 0 ;
const LWOOBJID & oldItemID = LWOOBJID_EMPTY ;
LOT oldItemLOT = LOT_NULL ;
int oldItemTYPE = 0 ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : FINISH_ARRANGING_WITH_ITEM ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( buildAreaID ! = LWOOBJID_EMPTY ) ;
if ( buildAreaID ! = LWOOBJID_EMPTY ) bitStream . Write ( buildAreaID ) ;
bitStream . Write ( newSourceBAG ) ;
bitStream . Write ( newSourceID ) ;
bitStream . Write ( newSourceLOT ) ;
bitStream . Write ( newSourceTYPE ) ;
bitStream . Write ( newTargetID ) ;
bitStream . Write ( newTargetLOT ) ;
bitStream . Write ( newTargetTYPE ) ;
bitStream . Write ( newTargetPOS ) ;
bitStream . Write ( oldItemBAG ) ;
bitStream . Write ( oldItemID ) ;
bitStream . Write ( oldItemLOT ) ;
bitStream . Write ( oldItemTYPE ) ;
SystemAddress sysAddr = entity - > GetSystemAddress ( ) ;
SEND_PACKET ;
}
void GameMessages : : SendModularBuildEnd ( Entity * entity ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : MODULAR_BUILD_END ) ;
2021-12-05 17:54:36 +00:00
SystemAddress sysAddr = entity - > GetSystemAddress ( ) ;
SEND_PACKET ;
}
void GameMessages : : SendVendorOpenWindow ( Entity * entity , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : VENDOR_OPEN_WINDOW ) ;
2021-12-05 17:54:36 +00:00
SEND_PACKET ;
}
2022-04-26 10:41:16 +00:00
void GameMessages : : SendVendorStatusUpdate ( Entity * entity , const SystemAddress & sysAddr , bool bUpdateOnly ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
2023-03-04 07:16:37 +00:00
VendorComponent * vendor = static_cast < VendorComponent * > ( entity - > GetComponent ( eReplicaComponentType : : VENDOR ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! vendor ) return ;
2023-08-03 10:51:52 +00:00
auto vendorItems = vendor - > GetInventory ( ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : VENDOR_STATUS_UPDATE ) ;
2021-12-05 17:54:36 +00:00
2022-07-17 07:35:11 +00:00
bitStream . Write ( bUpdateOnly ) ;
2023-08-03 10:51:52 +00:00
bitStream . Write < uint32_t > ( vendorItems . size ( ) ) ;
2021-12-05 17:54:36 +00:00
2023-08-04 02:44:03 +00:00
2023-08-03 10:51:52 +00:00
for ( const auto & item : vendorItems ) {
bitStream . Write ( item . lot ) ;
bitStream . Write ( item . sortPriority ) ;
2021-12-05 17:54:36 +00:00
}
2023-08-03 10:51:52 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : SendVendorTransactionResult ( Entity * entity , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
int iResult = 0x02 ; // success, seems to be the only relevant one
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : VENDOR_TRANSACTION_RESULT ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( iResult ) ;
SEND_PACKET ;
}
void GameMessages : : SendRemoveItemFromInventory ( Entity * entity , const SystemAddress & sysAddr , LWOOBJID objectID , LOT templateID , int inventoryType , uint32_t stackCount , uint32_t stackRemaining ) {
CBITSTREAM ;
CMSGHEADER ;
// this is used for a lot more than just inventory trashing (trades, vendors, etc.) but for now since it's just used for that, that's all im going to implement
bool bConfirmed = true ;
bool bDeleteItem = true ;
bool bOutSuccess = false ;
int eInvType = inventoryType ;
int eLootTypeSource = LOOTTYPE_NONE ;
bool forceDeletion = true ;
LWOOBJID iLootTypeSource = LWOOBJID_EMPTY ;
LWOOBJID iObjID = objectID ;
LOT iObjTemplate = templateID ;
LWOOBJID iRequestingObjID = LWOOBJID_EMPTY ;
uint32_t iStackCount = stackCount ;
uint32_t iStackRemaining = stackRemaining ;
LWOOBJID iSubkey = LWOOBJID_EMPTY ;
LWOOBJID iTradeID = LWOOBJID_EMPTY ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : REMOVE_ITEM_FROM_INVENTORY ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bConfirmed ) ;
bitStream . Write ( bDeleteItem ) ;
bitStream . Write ( bOutSuccess ) ;
bitStream . Write1 ( ) ;
bitStream . Write ( eInvType ) ;
bitStream . Write1 ( ) ;
bitStream . Write ( eLootTypeSource ) ;
bitStream . Write ( static_cast < uint32_t > ( 0 ) ) ; //extra info
//bitStream.Write(static_cast<uint16_t>(0)); //extra info
bitStream . Write ( forceDeletion ) ;
bitStream . Write0 ( ) ;
bitStream . Write1 ( ) ;
bitStream . Write ( iObjID ) ;
bitStream . Write1 ( ) ;
bitStream . Write ( iObjTemplate ) ;
bitStream . Write0 ( ) ;
bitStream . Write1 ( ) ;
bitStream . Write ( iStackCount ) ;
bitStream . Write1 ( ) ;
bitStream . Write ( iStackRemaining ) ;
bitStream . Write0 ( ) ;
bitStream . Write0 ( ) ;
SEND_PACKET ;
}
void GameMessages : : SendConsumeClientItem ( Entity * entity , bool bSuccess , LWOOBJID item ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : CONSUME_CLIENT_ITEM ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bSuccess ) ;
bitStream . Write ( item ) ;
SystemAddress sysAddr = entity - > GetSystemAddress ( ) ;
SEND_PACKET ;
}
void GameMessages : : SendUseItemResult ( Entity * entity , LOT templateID , bool useItemResult ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : USE_ITEM_RESULT ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( templateID ) ;
bitStream . Write ( useItemResult ) ;
SystemAddress sysAddr = entity - > GetSystemAddress ( ) ;
SEND_PACKET ;
}
2023-05-02 22:39:21 +00:00
void GameMessages : : SendUseItemRequirementsResponse ( LWOOBJID objectID , const SystemAddress & sysAddr , eUseItemResponse itemResponse ) {
2022-06-18 05:19:28 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : USE_ITEM_REQUIREMENTS_RESPONSE ) ;
2022-06-18 05:19:28 +00:00
bitStream . Write ( itemResponse ) ;
SEND_PACKET ;
}
2021-12-05 17:54:36 +00:00
void GameMessages : : SendMoveInventoryBatch ( Entity * entity , uint32_t stackCount , int srcInv , int dstInv , const LWOOBJID & iObjID ) {
CBITSTREAM ;
CMSGHEADER ;
2023-03-04 07:16:37 +00:00
InventoryComponent * inv = static_cast < InventoryComponent * > ( entity - > GetComponent ( eReplicaComponentType : : INVENTORY ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! inv ) return ;
Item * itemStack = inv - > FindItemById ( iObjID ) ;
if ( ! itemStack ) return ;
bool bAllowPartial = false ;
bool bOutSuccess = false ;
uint32_t count = stackCount ;
int dstBag = dstInv ;
LOT moveLOT = itemStack - > GetLot ( ) ;
//LWOOBJID moveSubkey = LWOOBJID_EMPTY;
bool showFlyingLoot = false ;
int srcBag = srcInv ;
LWOOBJID startObjectID = iObjID ;
bitStream . Write ( bAllowPartial ) ;
bitStream . Write ( bOutSuccess ) ;
if ( count = = 1 ) {
bitStream . Write0 ( ) ;
} else {
bitStream . Write1 ( ) ;
bitStream . Write ( count ) ;
}
if ( dstBag = = 0 ) {
bitStream . Write0 ( ) ;
} else {
bitStream . Write1 ( ) ;
bitStream . Write ( dstBag ) ;
}
bitStream . Write0 ( ) ;
bitStream . Write ( showFlyingLoot ) ;
if ( srcBag = = 0 ) {
bitStream . Write0 ( ) ;
} else {
bitStream . Write1 ( ) ;
bitStream . Write ( srcBag ) ;
}
bitStream . Write1 ( ) ;
bitStream . Write ( startObjectID ) ;
auto sysAddr = entity - > GetSystemAddress ( ) ;
SEND_PACKET ;
}
void GameMessages : : SendMatchResponse ( Entity * entity , const SystemAddress & sysAddr , int response ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : MATCH_RESPONSE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( response ) ;
SEND_PACKET ;
}
2023-05-02 22:39:21 +00:00
void GameMessages : : SendMatchUpdate ( Entity * entity , const SystemAddress & sysAddr , std : : string data , eMatchUpdate type ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : MATCH_UPDATE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( uint32_t ( data . size ( ) ) ) ;
for ( char character : data ) {
bitStream . Write ( uint16_t ( character ) ) ;
}
if ( data . size ( ) > 0 ) bitStream . Write ( uint16_t ( 0 ) ) ;
bitStream . Write ( type ) ;
SEND_PACKET ;
}
void GameMessages : : SendRequestActivitySummaryLeaderboardData ( const LWOOBJID & objectID , const LWOOBJID & targetID ,
2022-07-23 02:58:20 +00:00
const SystemAddress & sysAddr , const int32_t & gameID ,
const int32_t & queryType , const int32_t & resultsEnd ,
const int32_t & resultsStart , bool weekly ) {
CBITSTREAM ;
CMSGHEADER ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
bitStream . Write ( objectID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : REQUEST_ACTIVITY_SUMMARY_LEADERBOARD_DATA ) ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
bitStream . Write ( gameID ! = 0 ) ;
if ( gameID ! = 0 ) {
bitStream . Write < int32_t > ( gameID ) ;
}
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
bitStream . Write ( queryType ! = 1 ) ;
if ( queryType ! = 1 ) {
bitStream . Write < int32_t > ( queryType ) ;
}
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
bitStream . Write ( resultsEnd ! = 10 ) ;
if ( resultsEnd ! = 10 ) {
bitStream . Write < int32_t > ( resultsEnd ) ;
}
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
bitStream . Write ( resultsStart ! = 0 ) ;
if ( resultsStart ! = 0 ) {
bitStream . Write < int32_t > ( resultsStart ) ;
}
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
bitStream . Write < LWOOBJID > ( targetID ) ;
bitStream . Write ( weekly ) ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
SEND_PACKET ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : SendActivityPause ( LWOOBJID objectId , bool pause , const SystemAddress & sysAddr ) {
2022-07-23 02:58:20 +00:00
CBITSTREAM ;
CMSGHEADER ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : ACTIVITY_PAUSE ) ;
2022-07-23 02:58:20 +00:00
bitStream . Write ( pause ) ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : SendStartActivityTime ( LWOOBJID objectId , float_t startTime , const SystemAddress & sysAddr ) {
2022-07-23 02:58:20 +00:00
CBITSTREAM ;
CMSGHEADER ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : START_ACTIVITY_TIME ) ;
2022-07-23 02:58:20 +00:00
bitStream . Write < float_t > ( startTime ) ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : SendRequestActivityEnter ( LWOOBJID objectId , const SystemAddress & sysAddr , bool bStart , LWOOBJID userID ) {
2022-07-23 02:58:20 +00:00
CBITSTREAM ;
CMSGHEADER ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : REQUEST_ACTIVITY_ENTER ) ;
2022-07-23 02:58:20 +00:00
bitStream . Write < bool > ( bStart ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write < LWOOBJID > ( userID ) ;
2022-07-23 02:58:20 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
2021-12-05 17:54:36 +00:00
}
2022-02-21 03:23:03 +00:00
void GameMessages : : NotifyLevelRewards ( LWOOBJID objectID , const SystemAddress & sysAddr , int level , bool sending_rewards ) {
2022-02-13 05:02:52 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( ( uint16_t ) eGameMessageType : : NOTIFY_LEVEL_REWARDS ) ;
2022-02-13 05:02:52 +00:00
bitStream . Write ( level ) ;
bitStream . Write ( sending_rewards ) ;
2022-07-17 07:35:11 +00:00
2022-02-13 05:02:52 +00:00
SEND_PACKET ;
}
2021-12-05 17:54:36 +00:00
void GameMessages : : SendSetShootingGalleryParams ( LWOOBJID objectId , const SystemAddress & sysAddr ,
float cameraFOV ,
float cooldown ,
float minDistance ,
NiPoint3 muzzlePosOffset ,
NiPoint3 playerPosOffset ,
float projectileVelocity ,
float timeLimit ,
2022-07-17 07:35:11 +00:00
bool bUseLeaderboards ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SET_SHOOTING_GALLERY_PARAMS ) ;
2021-12-05 17:54:36 +00:00
/*
bitStream . Write < float > ( cameraFOV ) ;
bitStream . Write < float > ( cooldown ) ;
bitStream . Write < float > ( minDistance ) ;
bitStream . Write < NiPoint3 > ( muzzlePosOffset ) ;
bitStream . Write < NiPoint3 > ( playerPosOffset ) ;
bitStream . Write < float > ( projectileVelocity ) ;
bitStream . Write < float > ( timeLimit ) ;
bitStream . Write < bool > ( bUseLeaderboards ) ;
*/
// No clue about the order here
bitStream . Write < NiPoint3 > ( playerPosOffset ) ;
bitStream . Write < float > ( projectileVelocity ) ;
bitStream . Write < float > ( cooldown ) ;
bitStream . Write < NiPoint3 > ( muzzlePosOffset ) ;
bitStream . Write < float > ( minDistance ) ;
bitStream . Write < float > ( cameraFOV ) ;
bitStream . Write < bool > ( bUseLeaderboards ) ;
bitStream . Write < float > ( timeLimit ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendNotifyClientShootingGalleryScore ( LWOOBJID objectId , const SystemAddress & sysAddr ,
float addTime ,
int32_t score ,
LWOOBJID target ,
2022-07-17 07:35:11 +00:00
NiPoint3 targetPos ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : NOTIFY_CLIENT_SHOOTING_GALLERY_SCORE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write < float > ( addTime ) ;
bitStream . Write < int32_t > ( score ) ;
bitStream . Write < LWOOBJID > ( target ) ;
bitStream . Write < NiPoint3 > ( targetPos ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : HandleUpdateShootingGalleryRotation ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
float angle = 0.0f ;
NiPoint3 facing = NiPoint3 : : ZERO ;
NiPoint3 muzzlePos = NiPoint3 : : ZERO ;
inStream - > Read ( angle ) ;
inStream - > Read ( facing ) ;
inStream - > Read ( muzzlePos ) ;
}
void GameMessages : : HandleActivitySummaryLeaderboardData ( RakNet : : BitStream * instream , Entity * entity ,
2022-07-23 02:58:20 +00:00
const SystemAddress & sysAddr ) {
2023-10-21 23:31:55 +00:00
LOG ( " We got mail! " ) ;
2021-12-05 17:54:36 +00:00
}
2023-05-30 11:23:48 +00:00
void GameMessages : : SendActivitySummaryLeaderboardData ( const LWOOBJID & objectID , const Leaderboard * leaderboard , const SystemAddress & sysAddr ) {
2022-07-23 02:58:20 +00:00
CBITSTREAM ;
CMSGHEADER ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
bitStream . Write ( objectID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SEND_ACTIVITY_SUMMARY_LEADERBOARD_DATA ) ;
2021-12-05 17:54:36 +00:00
2023-05-09 02:35:19 +00:00
leaderboard - > Serialize ( & bitStream ) ;
2022-07-23 02:58:20 +00:00
SEND_PACKET ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandleRequestActivitySummaryLeaderboardData ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2022-07-23 02:58:20 +00:00
int32_t gameID = 0 ;
if ( inStream - > ReadBit ( ) ) inStream - > Read ( gameID ) ;
2021-12-05 17:54:36 +00:00
2023-05-09 02:59:10 +00:00
Leaderboard : : InfoType queryType = Leaderboard : : InfoType : : MyStanding ;
if ( inStream - > ReadBit ( ) ) inStream - > Read < Leaderboard : : InfoType > ( queryType ) ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
int32_t resultsEnd = 10 ;
if ( inStream - > ReadBit ( ) ) inStream - > Read ( resultsEnd ) ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
int32_t resultsStart = 0 ;
if ( inStream - > ReadBit ( ) ) inStream - > Read ( resultsStart ) ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
LWOOBJID target { } ;
inStream - > Read ( target ) ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
bool weekly = inStream - > ReadBit ( ) ;
2021-12-05 17:54:36 +00:00
2023-06-05 11:10:59 +00:00
LeaderboardManager : : SendLeaderboard ( gameID , queryType , weekly , entity - > GetObjectID ( ) , entity - > GetObjectID ( ) , resultsStart , resultsEnd ) ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandleActivityStateChangeRequest ( RakNet : : BitStream * inStream , Entity * entity ) {
2022-07-23 02:58:20 +00:00
LWOOBJID objectID ;
inStream - > Read < LWOOBJID > ( objectID ) ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
int32_t value1 ;
inStream - > Read < int32_t > ( value1 ) ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
int32_t value2 ;
inStream - > Read < int32_t > ( value2 ) ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
uint32_t stringValueLength ;
inStream - > Read < uint32_t > ( stringValueLength ) ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
std : : u16string stringValue ;
for ( uint32_t i = 0 ; i < stringValueLength ; + + i ) {
uint16_t character ;
inStream - > Read ( character ) ;
stringValue . push_back ( character ) ;
}
2021-12-05 17:54:36 +00:00
2023-07-15 20:56:33 +00:00
auto * assosiate = Game : : entityManager - > GetEntity ( objectID ) ;
2021-12-05 17:54:36 +00:00
2023-10-21 23:31:55 +00:00
LOG ( " %s [%i, %i] from %i to %i " , GeneralUtils : : UTF16ToWTF8 ( stringValue ) . c_str ( ) , value1 , value2 , entity - > GetLOT ( ) , assosiate ! = nullptr ? assosiate - > GetLOT ( ) : 0 ) ;
2021-12-05 17:54:36 +00:00
2023-07-15 20:56:33 +00:00
std : : vector < Entity * > scriptedActs = Game : : entityManager - > GetEntitiesByComponent ( eReplicaComponentType : : SHOOTING_GALLERY ) ;
2021-12-05 17:54:36 +00:00
for ( Entity * scriptEntity : scriptedActs ) {
scriptEntity - > OnActivityStateChangeRequest ( objectID , value1 , value2 , stringValue ) ;
}
2022-07-23 02:58:20 +00:00
entity - > OnActivityStateChangeRequest ( objectID , value1 , value2 , stringValue ) ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : SendStartCelebrationEffect ( Entity * entity , const SystemAddress & sysAddr , int celebrationID ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : START_CELEBRATION_EFFECT ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write < uint32_t > ( 0 ) ; //animation
bitStream . Write0 ( ) ; //No custom bg obj
bitStream . Write0 ( ) ; //custom path
bitStream . Write0 ( ) ; //leadin
bitStream . Write0 ( ) ; //leadout
bitStream . Write1 ( ) ;
bitStream . Write ( celebrationID ) ;
bitStream . Write < float > ( 0.0f ) ; //duration
bitStream . Write < uint32_t > ( 0 ) ; //icon
bitStream . Write < uint32_t > ( 0 ) ; //text
bitStream . Write < uint32_t > ( 0 ) ; //mixer
bitStream . Write < uint32_t > ( 0 ) ; //cue
bitStream . Write < uint32_t > ( 0 ) ; //pathnodename
bitStream . Write < uint32_t > ( 0 ) ; //soundguid
bitStream . Write < uint32_t > ( 0 ) ; //subtext
SEND_PACKET ;
//PacketUtils::SavePacket("StartCelebrationEffect.bin", (char*)bitStream.GetData(), bitStream.GetNumberOfBytesUsed());
}
void GameMessages : : SendSetRailMovement ( const LWOOBJID & objectID , bool pathGoForward , std : : u16string pathName ,
2022-07-23 02:58:20 +00:00
uint32_t pathStart , const SystemAddress & sysAddr , int32_t railActivatorComponentID ,
LWOOBJID railActivatorObjectID ) {
CBITSTREAM ;
CMSGHEADER ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
bitStream . Write ( objectID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SET_RAIL_MOVEMENT ) ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
bitStream . Write ( pathGoForward ) ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
bitStream . Write ( uint32_t ( pathName . size ( ) ) ) ;
for ( auto character : pathName ) {
bitStream . Write < uint16_t > ( character ) ;
}
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
bitStream . Write < uint32_t > ( pathStart ) ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
const auto componentIDIsDefault = railActivatorComponentID = = - 1 ;
bitStream . Write ( ! componentIDIsDefault ) ;
if ( ! componentIDIsDefault )
bitStream . Write < int32_t > ( railActivatorComponentID ) ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
const auto activatorObjectIDIsDefault = railActivatorObjectID = = LWOOBJID_EMPTY ;
bitStream . Write ( ! activatorObjectIDIsDefault ) ;
if ( ! activatorObjectIDIsDefault )
bitStream . Write < LWOOBJID > ( railActivatorObjectID ) ;
2021-12-05 17:54:36 +00:00
2022-07-23 02:58:20 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : SendStartRailMovement ( const LWOOBJID & objectID , std : : u16string pathName , std : : u16string startSound ,
2022-07-23 02:58:20 +00:00
std : : u16string loopSound , std : : u16string stopSound , const SystemAddress & sysAddr ,
uint32_t pathStart , bool goForward , bool damageImmune , bool noAggro , bool notifyActor ,
bool showNameBillboard , bool cameraLocked , bool collisionEnabled , bool useDB ,
int32_t railComponentID , LWOOBJID railActivatorObjectID ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : START_RAIL_MOVEMENT ) ;
2022-07-23 02:58:20 +00:00
bitStream . Write ( damageImmune ) ;
bitStream . Write ( noAggro ) ;
bitStream . Write ( notifyActor ) ;
bitStream . Write ( showNameBillboard ) ;
bitStream . Write ( cameraLocked ) ;
bitStream . Write ( collisionEnabled ) ;
bitStream . Write ( uint32_t ( loopSound . size ( ) ) ) ;
for ( auto character : loopSound ) {
bitStream . Write < uint16_t > ( character ) ;
}
bitStream . Write ( goForward ) ;
bitStream . Write ( uint32_t ( pathName . size ( ) ) ) ;
for ( auto character : pathName ) {
bitStream . Write < uint16_t > ( character ) ;
}
const auto pathStartIsDefault = pathStart = = 0 ;
bitStream . Write ( ! pathStartIsDefault ) ;
if ( ! pathStartIsDefault ) {
bitStream . Write < uint32_t > ( pathStart ) ;
}
const auto railComponentIDIsDefault = railComponentID = = - 1 ;
bitStream . Write ( ! railComponentIDIsDefault ) ;
if ( ! railComponentIDIsDefault ) {
bitStream . Write < int32_t > ( railComponentID ) ;
}
const auto railObjectIDIsDefault = railActivatorObjectID = = LWOOBJID_EMPTY ;
bitStream . Write ( ! railObjectIDIsDefault ) ;
if ( ! railObjectIDIsDefault ) {
bitStream . Write < LWOOBJID > ( railActivatorObjectID ) ;
}
bitStream . Write ( uint32_t ( startSound . size ( ) ) ) ;
for ( auto character : startSound ) {
bitStream . Write < uint16_t > ( character ) ;
}
bitStream . Write ( uint32_t ( stopSound . size ( ) ) ) ;
for ( auto character : stopSound ) {
bitStream . Write < uint16_t > ( character ) ;
}
bitStream . Write ( useDB ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : SendNotifyClientObject ( const LWOOBJID & objectID , std : : u16string name , int param1 , int param2 , const LWOOBJID & paramObj , std : : string paramStr , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : NOTIFY_CLIENT_OBJECT ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( uint32_t ( name . size ( ) ) ) ;
for ( auto character : name ) {
bitStream . Write < uint16_t > ( character ) ;
}
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
bitStream . Write ( param1 ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
bitStream . Write ( param2 ) ;
bitStream . Write ( paramObj ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
bitStream . Write ( uint32_t ( paramStr . size ( ) ) ) ;
for ( auto character : paramStr ) {
bitStream . Write ( character ) ;
}
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendNotifyClientZoneObject ( const LWOOBJID & objectID , const std : : u16string & name , int param1 ,
int param2 , const LWOOBJID & paramObj , const std : : string & paramStr ,
const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : NOTIFY_CLIENT_ZONE_OBJECT ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( uint32_t ( name . size ( ) ) ) ;
for ( const auto & character : name ) {
bitStream . Write < uint16_t > ( character ) ;
}
bitStream . Write ( param1 ) ;
bitStream . Write ( param2 ) ;
bitStream . Write ( paramObj ) ;
bitStream . Write ( uint32_t ( paramStr . size ( ) ) ) ;
for ( const auto & character : paramStr ) {
bitStream . Write ( character ) ;
}
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendNotifyClientFailedPrecondition ( LWOOBJID objectId , const SystemAddress & sysAddr ,
const std : : u16string & failedReason , int preconditionID ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : NOTIFY_CLIENT_FAILED_PRECONDITION ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( uint32_t ( failedReason . size ( ) ) ) ;
for ( uint16_t character : failedReason ) {
bitStream . Write ( uint16_t ( character ) ) ;
}
bitStream . Write ( preconditionID ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendToggleGMInvis ( LWOOBJID objectId , bool enabled , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : TOGGLE_GM_INVIS ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( enabled ) ; // does not matter?
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendSetName ( LWOOBJID objectID , std : : u16string name , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SET_NAME ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write < uint32_t > ( name . size ( ) ) ;
for ( size_t i = 0 ; i < name . size ( ) ; + + i )
bitStream . Write ( name [ i ] ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendBBBSaveResponse ( const LWOOBJID & objectId , const LWOOBJID & localID , unsigned char * buffer , uint32_t bufferSize , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : BBB_SAVE_RESPONSE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( localID ) ;
//Write a fake sd0 header:
bitStream . Write < unsigned char > ( 0x73 ) ; //s
bitStream . Write < unsigned char > ( 0x64 ) ; //d
bitStream . Write < unsigned char > ( 0x30 ) ; //0
bitStream . Write < unsigned char > ( 0x01 ) ; //1
bitStream . Write < unsigned char > ( 0xFF ) ; //end magic
bitStream . Write ( bufferSize ) ;
for ( size_t i = 0 ; i < bufferSize ; + + i )
bitStream . Write ( buffer [ i ] ) ;
SEND_PACKET ;
2023-05-03 21:38:32 +00:00
PacketUtils : : SavePacket ( " eGameMessageType::BBB_SAVE_RESPONSE.bin " , ( char * ) bitStream . GetData ( ) , bitStream . GetNumberOfBytesUsed ( ) ) ;
2021-12-05 17:54:36 +00:00
}
// Property
void GameMessages : : SendOpenPropertyVendor ( const LWOOBJID objectId , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : OPEN_PROPERTY_VENDOR ) ;
2021-12-05 17:54:36 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendOpenPropertyManagment ( const LWOOBJID objectId , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( PropertyManagementComponent : : Instance ( ) - > GetParent ( ) - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : OPEN_PROPERTY_MANAGEMENT ) ;
2021-12-05 17:54:36 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendDownloadPropertyData ( const LWOOBJID objectId , const PropertyDataMessage & data , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : DOWNLOAD_PROPERTY_DATA ) ;
2021-12-05 17:54:36 +00:00
data . Serialize ( bitStream ) ;
2023-10-21 23:31:55 +00:00
LOG ( " (%llu) sending property data (%d) " , objectId , sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendPropertyRentalResponse ( const LWOOBJID objectId , const LWOCLONEID cloneId , const uint32_t code , const LWOOBJID propertyId , const int64_t rentDue , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : PROPERTY_RENTAL_RESPONSE ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
bitStream . Write ( cloneId ) ;
bitStream . Write ( code ) ;
bitStream . Write ( propertyId ) ;
bitStream . Write ( rentDue ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendLockNodeRotation ( Entity * entity , std : : string nodeName ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : LOCK_NODE_ROTATION ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( uint32_t ( nodeName . size ( ) ) ) ;
for ( char character : nodeName ) {
bitStream . Write ( character ) ;
}
SEND_PACKET_BROADCAST ;
}
void GameMessages : : SendSetBuildModeConfirmed ( LWOOBJID objectId , const SystemAddress & sysAddr , bool start , bool warnVisitors , bool modePaused , int32_t modeValue , LWOOBJID playerId , NiPoint3 startPos ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SET_BUILD_MODE_CONFIRMED ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( start ) ;
bitStream . Write ( warnVisitors ) ;
bitStream . Write ( modePaused ) ;
bitStream . Write1 ( ) ;
bitStream . Write ( modeValue ) ;
bitStream . Write ( playerId ) ;
bitStream . Write1 ( ) ;
bitStream . Write ( startPos ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendGetModelsOnProperty ( LWOOBJID objectId , std : : map < LWOOBJID , LWOOBJID > models , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : GET_MODELS_ON_PROPERTY ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( static_cast < uint32_t > ( models . size ( ) ) ) ;
for ( const auto & pair : models ) {
bitStream . Write ( pair . first ) ;
bitStream . Write ( pair . second ) ;
}
2023-10-21 23:31:55 +00:00
LOG ( " Sending property models to (%llu) (%d) " , objectId , sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) ;
2021-12-05 17:54:36 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendZonePropertyModelEquipped ( LWOOBJID objectId , LWOOBJID playerId , LWOOBJID propertyId , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : ZONE_PROPERTY_MODEL_EQUIPPED ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( playerId ) ;
bitStream . Write ( propertyId ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendPlaceModelResponse ( LWOOBJID objectId , const SystemAddress & sysAddr , NiPoint3 position ,
LWOOBJID plaque , int32_t response , NiQuaternion rotation ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : PLACE_MODEL_RESPONSE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( position ! = NiPoint3 : : ZERO ) ;
if ( position ! = NiPoint3 : : ZERO ) {
bitStream . Write ( position ) ;
}
bitStream . Write ( plaque ! = LWOOBJID_EMPTY ) ;
if ( plaque ! = LWOOBJID_EMPTY ) {
bitStream . Write ( plaque ) ;
}
bitStream . Write ( response ! = 0 ) ;
if ( response ! = 0 ) {
bitStream . Write ( response ) ;
}
bitStream . Write ( rotation ! = NiQuaternion : : IDENTITY ) ;
if ( rotation ! = NiQuaternion : : IDENTITY ) {
bitStream . Write ( response ) ;
}
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendUGCEquipPreCreateBasedOnEditMode ( LWOOBJID objectId , const SystemAddress & sysAddr , int modelCount , LWOOBJID model ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-08-04 02:27:40 +00:00
bitStream . Write ( eGameMessageType : : HANDLE_UGC_POST_CREATE_BASED_ON_EDIT_MODE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( modelCount ) ;
bitStream . Write ( model ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendUGCEquipPostDeleteBasedOnEditMode ( LWOOBJID objectId , const SystemAddress & sysAddr , LWOOBJID inventoryItem , int itemTotal ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-08-04 02:27:40 +00:00
bitStream . Write ( eGameMessageType : : HANDLE_UGC_POST_DELETE_BASED_ON_EDIT_MODE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( inventoryItem ) ;
bitStream . Write ( itemTotal ! = 0 ) ;
if ( itemTotal ! = 0 ) {
bitStream . Write ( itemTotal ) ;
}
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : HandleSetPropertyAccess ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
uint8_t accessType { } ;
int32_t renew { } ;
bool accessTypeIsDefault { } ;
inStream - > Read ( accessTypeIsDefault ) ;
if ( accessTypeIsDefault ! = 0 ) inStream - > Read ( accessType ) ;
bool renewIsDefault { } ;
inStream - > Read ( renewIsDefault ) ;
if ( renewIsDefault ! = 0 ) inStream - > Read ( renew ) ;
2023-10-21 23:31:55 +00:00
LOG ( " Set privacy option to: %i " , accessType ) ;
2021-12-05 17:54:36 +00:00
if ( PropertyManagementComponent : : Instance ( ) = = nullptr ) return ;
PropertyManagementComponent : : Instance ( ) - > SetPrivacyOption ( static_cast < PropertyPrivacyOption > ( accessType ) ) ;
}
2022-11-28 00:48:46 +00:00
void GameMessages : : HandleUnUseModel ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
bool unknown { } ;
LWOOBJID objIdToAddToInventory { } ;
inStream - > Read ( unknown ) ;
inStream - > Read ( objIdToAddToInventory ) ;
auto * inventoryComponent = entity - > GetComponent < InventoryComponent > ( ) ;
if ( inventoryComponent ) {
auto * inventory = inventoryComponent - > GetInventory ( eInventoryType : : MODELS_IN_BBB ) ;
auto * item = inventory - > FindItemById ( objIdToAddToInventory ) ;
if ( item ) {
inventoryComponent - > MoveItemToInventory ( item , eInventoryType : : MODELS , 1 ) ;
} else {
2023-10-21 23:31:55 +00:00
LOG ( " item id %llu not found in MODELS_IN_BBB inventory, likely because it does not exist " , objIdToAddToInventory ) ;
2022-11-28 00:48:46 +00:00
}
}
if ( unknown ) {
CBITSTREAM ;
2023-09-21 01:06:28 +00:00
BitStreamUtils : : WriteHeader ( bitStream , eConnectionType : : CLIENT , eClientMessageType : : BLUEPRINT_SAVE_RESPONSE ) ;
2022-11-28 00:48:46 +00:00
bitStream . Write < LWOOBJID > ( LWOOBJID_EMPTY ) ; //always zero so that a check on the client passes
bitStream . Write ( eBlueprintSaveResponseType : : PlacementFailed ) ; // Sending a non-zero error code here prevents the client from deleting its in progress build for some reason?
bitStream . Write < uint32_t > ( 0 ) ;
SEND_PACKET ;
}
}
2021-12-05 17:54:36 +00:00
void GameMessages : : HandleUpdatePropertyOrModelForFilterCheck ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
bool isProperty { } ;
LWOOBJID objectId { } ;
LWOOBJID playerId { } ;
LWOOBJID worldId { } ;
uint32_t nameLength { } ;
std : : u16string name { } ;
uint32_t descriptionLength { } ;
std : : u16string description { } ;
inStream - > Read ( isProperty ) ;
inStream - > Read ( objectId ) ;
inStream - > Read ( playerId ) ;
inStream - > Read ( worldId ) ;
inStream - > Read ( descriptionLength ) ;
for ( uint32_t i = 0 ; i < descriptionLength ; + + i ) {
uint16_t character ;
inStream - > Read ( character ) ;
description . push_back ( character ) ;
}
inStream - > Read ( nameLength ) ;
for ( uint32_t i = 0 ; i < nameLength ; + + i ) {
uint16_t character ;
inStream - > Read ( character ) ;
name . push_back ( character ) ;
}
PropertyManagementComponent : : Instance ( ) - > UpdatePropertyDetails ( GeneralUtils : : UTF16ToWTF8 ( name ) , GeneralUtils : : UTF16ToWTF8 ( description ) ) ;
}
void GameMessages : : HandleQueryPropertyData ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2023-10-21 23:31:55 +00:00
LOG ( " Entity (%i) requesting data " , entity - > GetLOT ( ) ) ;
2021-12-05 17:54:36 +00:00
/*
2023-07-15 20:56:33 +00:00
auto entites = Game : : entityManager - > GetEntitiesByComponent ( eReplicaComponentType : : PROPERTY_VENDOR ) ;
2021-12-05 17:54:36 +00:00
entity = entites [ 0 ] ;
*/
2023-03-04 07:16:37 +00:00
auto * propertyVendorComponent = static_cast < PropertyVendorComponent * > ( entity - > GetComponent ( eReplicaComponentType : : PROPERTY_VENDOR ) ) ;
2021-12-05 17:54:36 +00:00
if ( propertyVendorComponent ! = nullptr ) {
propertyVendorComponent - > OnQueryPropertyData ( entity , sysAddr ) ;
}
/*
2023-07-15 20:56:33 +00:00
entites = Game : : entityManager - > GetEntitiesByComponent ( eReplicaComponentType : : PROPERTY_MANAGEMENT ) ;
2021-12-05 17:54:36 +00:00
entity = entites [ 0 ] ;
*/
2023-03-04 07:16:37 +00:00
auto * propertyManagerComponent = static_cast < PropertyManagementComponent * > ( entity - > GetComponent ( eReplicaComponentType : : PROPERTY_MANAGEMENT ) ) ;
2021-12-05 17:54:36 +00:00
if ( propertyManagerComponent ! = nullptr ) {
propertyManagerComponent - > OnQueryPropertyData ( entity , sysAddr ) ;
}
}
void GameMessages : : HandleSetBuildMode ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
bool start { } ;
int32_t distanceType = - 1 ;
bool modePaused { } ;
int modeValue = 1 ;
LWOOBJID playerId { } ;
NiPoint3 startPosition = NiPoint3 : : ZERO ;
inStream - > Read ( start ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( inStream - > ReadBit ( ) )
inStream - > Read ( distanceType ) ;
inStream - > Read ( modePaused ) ;
if ( inStream - > ReadBit ( ) )
inStream - > Read ( modeValue ) ;
inStream - > Read ( playerId ) ;
if ( inStream - > ReadBit ( ) )
inStream - > Read ( startPosition ) ;
2023-07-15 20:56:33 +00:00
auto * player = Game : : entityManager - > GetEntity ( playerId ) ;
2021-12-05 17:54:36 +00:00
if ( startPosition = = NiPoint3 : : ZERO ) {
startPosition = player - > GetPosition ( ) ;
}
player - > GetCharacter ( ) - > SetBuildMode ( start ) ;
2023-10-21 23:31:55 +00:00
LOG ( " Sending build mode confirm (%i): (%d) (%i) (%d) (%i) (%llu) " , entity - > GetLOT ( ) , start , distanceType , modePaused , modeValue , playerId ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
SendSetBuildModeConfirmed ( entity - > GetObjectID ( ) , UNASSIGNED_SYSTEM_ADDRESS , start , false , modePaused , modeValue , playerId , startPosition ) ;
}
void GameMessages : : HandleStartBuildingWithItem ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2023-03-04 07:16:37 +00:00
if ( ! entity - > HasComponent ( eReplicaComponentType : : PROPERTY_MANAGEMENT ) ) {
2021-12-05 17:54:36 +00:00
return ;
}
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
bool firstTime { } ;
bool success { } ;
int32_t sourceBag { } ;
LWOOBJID sourceId { } ;
LOT sourceLot { } ;
int32_t sourceType { } ;
LWOOBJID targetId { } ;
LOT targetLot { } ;
NiPoint3 targetPosition { } ;
int32_t targetType { } ;
inStream - > Read ( firstTime ) ;
inStream - > Read ( success ) ;
inStream - > Read ( sourceBag ) ;
inStream - > Read ( sourceId ) ;
inStream - > Read ( sourceLot ) ;
inStream - > Read ( sourceType ) ;
inStream - > Read ( targetId ) ;
inStream - > Read ( targetLot ) ;
inStream - > Read ( targetPosition ) ;
inStream - > Read ( targetType ) ;
if ( sourceType = = 1 ) {
sourceType = 4 ;
}
2023-10-21 23:31:55 +00:00
LOG ( " Handling start building with item (%i): (%d) (%d) (%i) (%llu) (%i) (%i) (%llu) (%i) (%i) " , entity - > GetLOT ( ) , firstTime , success , sourceBag , sourceId , sourceLot , sourceType , targetId , targetLot , targetType ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
auto * user = UserManager : : Instance ( ) - > GetUser ( sysAddr ) ;
2023-07-15 20:56:33 +00:00
auto * player = Game : : entityManager - > GetEntity ( user - > GetLoggedInChar ( ) ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
SendStartArrangingWithItem (
player ,
sysAddr ,
firstTime ,
entity - > GetObjectID ( ) ,
player - > GetPosition ( ) ,
sourceBag ,
sourceId ,
sourceLot ,
sourceType ,
targetId ,
targetLot ,
targetPosition ,
targetType
) ;
}
void GameMessages : : HandlePropertyEditorBegin ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
PropertyManagementComponent : : Instance ( ) - > OnStartBuilding ( ) ;
2022-07-17 07:35:11 +00:00
2023-07-17 22:55:33 +00:00
Game : : zoneManager - > GetZoneControlObject ( ) - > OnZonePropertyEditBegin ( ) ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandlePropertyEditorEnd ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
PropertyManagementComponent : : Instance ( ) - > OnFinishBuilding ( ) ;
2023-07-17 22:55:33 +00:00
Game : : zoneManager - > GetZoneControlObject ( ) - > OnZonePropertyEditEnd ( ) ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandlePropertyContentsFromClient ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
User * user = UserManager : : Instance ( ) - > GetUser ( sysAddr ) ;
2023-07-15 20:56:33 +00:00
Entity * player = Game : : entityManager - > GetEntity ( user - > GetLoggedInChar ( ) ) ;
2021-12-05 17:54:36 +00:00
SendGetModelsOnProperty ( player - > GetObjectID ( ) , PropertyManagementComponent : : Instance ( ) - > GetModels ( ) , UNASSIGNED_SYSTEM_ADDRESS ) ;
}
void GameMessages : : HandlePropertyModelEquipped ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2023-07-17 22:55:33 +00:00
Game : : zoneManager - > GetZoneControlObject ( ) - > OnZonePropertyModelEquipped ( ) ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandlePlacePropertyModel ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
LWOOBJID model ;
inStream - > Read ( model ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
PropertyManagementComponent : : Instance ( ) - > UpdateModelPosition ( model , NiPoint3 : : ZERO , NiQuaternion : : IDENTITY ) ;
}
void GameMessages : : HandleUpdatePropertyModel ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
LWOOBJID model ;
NiPoint3 position ;
NiQuaternion rotation = NiQuaternion : : IDENTITY ;
inStream - > Read ( model ) ;
inStream - > Read ( position ) ;
if ( inStream - > ReadBit ( ) ) {
inStream - > Read ( rotation ) ;
}
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
PropertyManagementComponent : : Instance ( ) - > UpdateModelPosition ( model , position , rotation ) ;
}
void GameMessages : : HandleDeletePropertyModel ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
LWOOBJID model = LWOOBJID_EMPTY ;
int deleteReason = 0 ;
if ( inStream - > ReadBit ( ) ) {
inStream - > Read ( model ) ;
}
if ( inStream - > ReadBit ( ) ) {
inStream - > Read ( deleteReason ) ;
}
PropertyManagementComponent : : Instance ( ) - > DeleteModel ( model , deleteReason ) ;
}
void GameMessages : : HandleBBBLoadItemRequest ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2022-11-28 00:48:46 +00:00
LWOOBJID previousItemID = LWOOBJID_EMPTY ;
inStream - > Read ( previousItemID ) ;
2023-10-21 23:31:55 +00:00
LOG ( " Load item request for: %lld " , previousItemID ) ;
2022-11-28 00:48:46 +00:00
LWOOBJID newId = previousItemID ;
auto * inventoryComponent = entity - > GetComponent < InventoryComponent > ( ) ;
if ( inventoryComponent ) {
auto * inventory = inventoryComponent - > GetInventory ( eInventoryType : : MODELS ) ;
auto * itemToMove = inventory - > FindItemById ( previousItemID ) ;
if ( itemToMove ) {
LOT previousLot = itemToMove - > GetLot ( ) ;
inventoryComponent - > MoveItemToInventory ( itemToMove , eInventoryType : : MODELS_IN_BBB , 1 , false ) ;
auto * destinationInventory = inventoryComponent - > GetInventory ( eInventoryType : : MODELS_IN_BBB ) ;
if ( destinationInventory ) {
auto * movedItem = destinationInventory - > FindItemByLot ( previousLot ) ;
if ( movedItem ) newId = movedItem - > GetId ( ) ;
}
} else {
2023-10-21 23:31:55 +00:00
LOG ( " item id %llu not found in MODELS inventory, likely because it does not exist " , previousItemID ) ;
2022-11-28 00:48:46 +00:00
}
}
2021-12-05 17:54:36 +00:00
2022-11-28 00:48:46 +00:00
// Second argument always true (successful) for now
SendBlueprintLoadItemResponse ( sysAddr , true , previousItemID , newId ) ;
}
2021-12-05 17:54:36 +00:00
2022-11-28 00:48:46 +00:00
void GameMessages : : SendBlueprintLoadItemResponse ( const SystemAddress & sysAddr , bool success , LWOOBJID oldItemId , LWOOBJID newItemId ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
2023-09-21 01:06:28 +00:00
BitStreamUtils : : WriteHeader ( bitStream , eConnectionType : : CLIENT , eClientMessageType : : BLUEPRINT_LOAD_RESPONSE_ITEMID ) ;
2022-11-28 00:48:46 +00:00
bitStream . Write ( static_cast < uint8_t > ( success ) ) ;
bitStream . Write < LWOOBJID > ( oldItemId ) ;
bitStream . Write < LWOOBJID > ( newItemId ) ;
2021-12-05 17:54:36 +00:00
SEND_PACKET ;
}
2022-07-20 08:28:57 +00:00
void GameMessages : : SendSmash ( Entity * entity , float force , float ghostOpacity , LWOOBJID killerID , bool ignoreObjectVisibility ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SMASH ) ;
2022-07-20 08:28:57 +00:00
bitStream . Write ( ignoreObjectVisibility ) ;
bitStream . Write ( force ) ;
bitStream . Write ( ghostOpacity ) ;
bitStream . Write ( killerID ) ;
SEND_PACKET_BROADCAST ;
}
void GameMessages : : SendUnSmash ( Entity * entity , LWOOBJID builderID , float duration ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-08-04 02:27:40 +00:00
bitStream . Write ( eGameMessageType : : UN_SMASH ) ;
2022-07-20 08:28:57 +00:00
bitStream . Write ( builderID ! = LWOOBJID_EMPTY ) ;
if ( builderID ! = LWOOBJID_EMPTY ) bitStream . Write ( builderID ) ;
bitStream . Write ( duration ! = 3.0f ) ;
if ( duration ! = 3.0f ) bitStream . Write ( duration ) ;
SEND_PACKET_BROADCAST ;
}
void GameMessages : : HandleControlBehaviors ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2022-10-31 22:32:07 +00:00
AMFDeserialize reader ;
2023-05-13 22:22:00 +00:00
std : : unique_ptr < AMFBaseValue > amfArguments ( reader . Read ( inStream ) ) ;
if ( amfArguments - > GetValueType ( ) ! = eAmf : : Array ) return ;
2022-10-31 22:32:07 +00:00
uint32_t commandLength { } ;
inStream - > Read ( commandLength ) ;
std : : string command ;
for ( uint32_t i = 0 ; i < commandLength ; i + + ) {
unsigned char character ;
inStream - > Read ( character ) ;
command . push_back ( character ) ;
}
auto owner = PropertyManagementComponent : : Instance ( ) - > GetOwner ( ) ;
2022-11-28 00:48:46 +00:00
if ( ! owner ) return ;
2022-10-31 22:32:07 +00:00
2023-02-14 02:55:44 +00:00
ControlBehaviors : : Instance ( ) . ProcessCommand ( entity , sysAddr , static_cast < AMFArrayValue * > ( amfArguments . get ( ) ) , command , owner ) ;
2022-07-20 08:28:57 +00:00
}
2021-12-05 17:54:36 +00:00
void GameMessages : : HandleBBBSaveRequest ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2022-10-29 08:12:29 +00:00
/*
___ ___
/ \ / \ ___ _ __ ___ / __ \ ___ / \ _ __ __ _ __ _ ___ _ __ ___
/ / _ / / _ \ ' __ / _ \ / __ \ /// _ \ / /\ / '__/ _` |/ _` |/ _ \| '_ \/ __|
/ __ / __ / | | __ / / \ / \ __ / / / _ / / | | | ( _ | | ( _ | | ( _ ) | | | \ __ \
\ / / _ / \ ___ | _ | \ ___ | \ _____ / \ ___ | / ___ , ' | _ | \ __ , _ | \ __ , | \ ___ / | _ | | _ | ___ /
| ___ /
___ _
/ __ \ _____ ____ _ _ __ ___ / \
/ __ \ /// _ \ \ /\ / / _` | '__/ _ \/ /
/ \ / \ __ / \ V V / ( _ | | | | __ / \ _ /
\ _____ / \ ___ | \ _ / \ _ / \ __ , _ | _ | \ ___ \ /
< > = = = = = = = ( )
( / \ ___ / | \ \ ( ) = = = = = = = = = = < > _
\ _ / | \ \ //|\ ______/ \)
\ _ | \ \ // | \_/
\ | \ / | \ _ // /\/
( oo ) \ \ _ // /
//_/\_\/ / |
@ @ / | = \ \ |
\ _ = \ _ \ |
\ = = \ \ | \ _ snd
__ ( \ = = = \ ( ) \
( ( ( ~ ) __ ( _ / |
( ( ( ~ ) \ /
______ / /
' - - - - - - '
*/
2021-12-05 17:54:36 +00:00
LWOOBJID localId ;
inStream - > Read ( localId ) ;
2022-10-24 22:20:36 +00:00
uint32_t sd0Size ;
inStream - > Read ( sd0Size ) ;
std : : shared_ptr < char [ ] > sd0Data ( new char [ sd0Size ] ) ;
2022-07-17 07:35:11 +00:00
2023-11-06 09:41:28 +00:00
if ( sd0Data = = nullptr ) return ;
2022-07-17 07:35:11 +00:00
2023-11-06 09:41:28 +00:00
inStream - > ReadAlignedBytes ( reinterpret_cast < unsigned char * > ( sd0Data . get ( ) ) , sd0Size ) ;
2022-07-17 07:35:11 +00:00
2022-10-24 22:20:36 +00:00
uint32_t timeTaken ;
2021-12-05 17:54:36 +00:00
inStream - > Read ( timeTaken ) ;
/*
Disabled this , as it ' s kinda silly to do this roundabout way of storing plaintext lxfml , then recompressing
it to send it back to the client .
On DLU we had agreed that bricks wouldn ' t be taken anyway , but if your server decides otherwise , feel free to
comment this back out and add the needed code to get the bricks used from lxfml and take them from the inventory .
Note , in the live client it ' ll still display the bricks going out as they ' re being used , but on relog / world change ,
they reappear as we didn ' t take them .
2022-10-24 22:20:36 +00:00
TODO Apparently the bricks are supposed to be taken via MoveInventoryBatch ?
2021-12-05 17:54:36 +00:00
*/
////Decompress the SD0 from the client so we can process the lxfml properly
//uint8_t* outData = new uint8_t[327680];
//int32_t error;
//int32_t size = ZCompression::Decompress(inData, lxfmlSize, outData, 327680, error);
//if (size == -1) {
2023-10-21 23:31:55 +00:00
// LOG("Failed to decompress LXFML: (%i)", error);
2021-12-05 17:54:36 +00:00
// return;
//}
//
//std::string lxfml(reinterpret_cast<char*>(outData), size); //std::string version of the decompressed data!
//Now, the cave of dragons:
2022-07-17 07:35:11 +00:00
//We runs this in async because the http library here is blocking, meaning it'll halt the thread.
2021-12-05 17:54:36 +00:00
//But we don't want the server to go unresponsive, because then the client would disconnect.
2023-11-06 09:41:28 +00:00
//We need to get a new ID for our model first:
ObjectIDManager : : Instance ( ) - > RequestPersistentID ( [ = ] ( uint32_t newID ) {
LWOOBJID newIDL = newID ;
GeneralUtils : : SetBit ( newIDL , eObjectBits : : CHARACTER ) ;
GeneralUtils : : SetBit ( newIDL , eObjectBits : : PERSISTENT ) ;
2021-12-05 17:54:36 +00:00
2023-11-06 09:41:28 +00:00
uint32_t blueprintIDSmall = ObjectIDManager : : Instance ( ) - > GenerateRandomObjectID ( ) ;
LWOOBJID blueprintID = blueprintIDSmall ;
GeneralUtils : : SetBit ( blueprintID , eObjectBits : : CHARACTER ) ;
GeneralUtils : : SetBit ( blueprintID , eObjectBits : : PERSISTENT ) ;
//We need to get the propertyID: (stolen from Wincent's propertyManagementComp)
const auto & worldId = Game : : zoneManager - > GetZone ( ) - > GetZoneID ( ) ;
const auto zoneId = worldId . GetMapID ( ) ;
const auto cloneId = worldId . GetCloneID ( ) ;
auto query = CDClientDatabase : : CreatePreppedStmt (
" SELECT id FROM PropertyTemplate WHERE mapID = ?; " ) ;
query . bind ( 1 , ( int ) zoneId ) ;
auto result = query . execQuery ( ) ;
if ( result . eof ( ) | | result . fieldIsNull ( 0 ) ) return ;
int templateId = result . getIntField ( 0 ) ;
auto * propertyLookup = Database : : CreatePreppedStmt ( " SELECT * FROM properties WHERE template_id = ? AND clone_id = ?; " ) ;
propertyLookup - > setInt ( 1 , templateId ) ;
propertyLookup - > setInt64 ( 2 , cloneId ) ;
auto * propertyEntry = propertyLookup - > executeQuery ( ) ;
uint64_t propertyId = 0 ;
if ( propertyEntry - > next ( ) ) {
propertyId = propertyEntry - > getUInt64 ( 1 ) ;
}
delete propertyEntry ;
delete propertyLookup ;
//Insert into ugc:
auto ugcs = Database : : CreatePreppedStmt ( " INSERT INTO `ugc`(`id`, `account_id`, `character_id`, `is_optimized`, `lxfml`, `bake_ao`, `filename`) VALUES (?,?,?,?,?,?,?) " ) ;
ugcs - > setUInt ( 1 , blueprintIDSmall ) ;
ugcs - > setInt ( 2 , entity - > GetParentUser ( ) - > GetAccountID ( ) ) ;
ugcs - > setInt ( 3 , entity - > GetCharacter ( ) - > GetID ( ) ) ;
ugcs - > setInt ( 4 , 0 ) ;
//whacky stream biz
std : : string s ( sd0Data . get ( ) , sd0Size ) ;
std : : istringstream iss ( s ) ;
ugcs - > setBlob ( 5 , & iss ) ;
ugcs - > setBoolean ( 6 , false ) ;
ugcs - > setString ( 7 , " weedeater.lxfml " ) ;
ugcs - > execute ( ) ;
delete ugcs ;
//Insert into the db as a BBB model:
auto * stmt = Database : : CreatePreppedStmt ( " INSERT INTO `properties_contents` VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) " ) ;
stmt - > setUInt64 ( 1 , newIDL ) ;
stmt - > setUInt64 ( 2 , propertyId ) ;
stmt - > setUInt ( 3 , blueprintIDSmall ) ;
stmt - > setUInt ( 4 , 14 ) ; // 14 is the lot the BBB models use
stmt - > setDouble ( 5 , 0.0f ) ; // x
stmt - > setDouble ( 6 , 0.0f ) ; // y
stmt - > setDouble ( 7 , 0.0f ) ; // z
stmt - > setDouble ( 8 , 0.0f ) ; // rx
stmt - > setDouble ( 9 , 0.0f ) ; // ry
stmt - > setDouble ( 10 , 0.0f ) ; // rz
stmt - > setDouble ( 11 , 0.0f ) ; // rw
stmt - > setString ( 12 , " Objects_14_name " ) ; // Model name. TODO make this customizable
stmt - > setString ( 13 , " " ) ; // Model description. TODO implement this.
stmt - > setDouble ( 14 , 0 ) ; // behavior 1. TODO implement this.
stmt - > setDouble ( 15 , 0 ) ; // behavior 2. TODO implement this.
stmt - > setDouble ( 16 , 0 ) ; // behavior 3. TODO implement this.
stmt - > setDouble ( 17 , 0 ) ; // behavior 4. TODO implement this.
stmt - > setDouble ( 18 , 0 ) ; // behavior 5. TODO implement this.
stmt - > execute ( ) ;
delete stmt ;
/*
Commented out until UGC server would be updated to use a sd0 file instead of lxfml stream .
( or you uncomment the lxfml decomp stuff above )
*/
////Send off to UGC for processing, if enabled:
//if (Game::config->GetValue("ugc_remote") == "1") {
// std::string ugcIP = Game::config->GetValue("ugc_ip");
// int ugcPort = std::stoi(Game::config->GetValue("ugc_port"));
// httplib::Client cli(ugcIP, ugcPort); //connect to UGC HTTP server using our config above ^
// //Send out a request:
// std::string request = "/3dservices/UGCC150/150" + std::to_string(blueprintID) + ".lxfml";
// cli.Put(request.c_str(), lxfml.c_str(), "text/lxfml");
// //When the "put" above returns, it means that the UGC HTTP server is done processing our model &
// //the nif, hkx and checksum files are ready to be downloaded from cache.
//}
//Tell the client their model is saved: (this causes us to actually pop out of our current state):
CBITSTREAM ;
BitStreamUtils : : WriteHeader ( bitStream , eConnectionType : : CLIENT , eClientMessageType : : BLUEPRINT_SAVE_RESPONSE ) ;
bitStream . Write ( localId ) ;
bitStream . Write ( eBlueprintSaveResponseType : : EverythingWorked ) ;
bitStream . Write < uint32_t > ( 1 ) ;
bitStream . Write ( blueprintID ) ;
bitStream . Write < uint32_t > ( sd0Size ) ;
bitStream . WriteAlignedBytes ( reinterpret_cast < unsigned char * > ( sd0Data . get ( ) ) , sd0Size ) ;
SEND_PACKET ;
//Now we have to construct this object:
EntityInfo info ;
info . lot = 14 ;
info . pos = { } ;
info . rot = { } ;
info . spawner = nullptr ;
info . spawnerID = entity - > GetObjectID ( ) ;
info . spawnerNodeID = 0 ;
LDFBaseData * ldfBlueprintID = new LDFData < LWOOBJID > ( u " blueprintid " , blueprintID ) ;
LDFBaseData * componentWhitelist = new LDFData < int > ( u " componentWhitelist " , 1 ) ;
LDFBaseData * modelType = new LDFData < int > ( u " modelType " , 2 ) ;
LDFBaseData * propertyObjectID = new LDFData < bool > ( u " propertyObjectID " , true ) ;
LDFBaseData * userModelID = new LDFData < LWOOBJID > ( u " userModelID " , newIDL ) ;
info . settings . push_back ( ldfBlueprintID ) ;
info . settings . push_back ( componentWhitelist ) ;
info . settings . push_back ( modelType ) ;
info . settings . push_back ( propertyObjectID ) ;
info . settings . push_back ( userModelID ) ;
Entity * newEntity = Game : : entityManager - > CreateEntity ( info , nullptr ) ;
if ( newEntity ) {
Game : : entityManager - > ConstructEntity ( newEntity ) ;
//Make sure the propMgmt doesn't delete our model after the server dies
//Trying to do this after the entity is constructed. Shouldn't really change anything but
//there was an issue with builds not appearing since it was placed above ConstructEntity.
PropertyManagementComponent : : Instance ( ) - > AddModel ( newEntity - > GetObjectID ( ) , newIDL ) ;
}
2023-11-16 01:29:53 +00:00
} ) ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandlePropertyEntranceSync ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
bool includeNullAddress { } ;
bool includeNullDescription { } ;
bool playerOwn { } ;
bool updateUi { } ;
int32_t numResults { } ;
int32_t reputation { } ;
int32_t sortMethod { } ;
int32_t startIndex { } ;
uint32_t filterTextLength { } ;
std : : string filterText { } ;
inStream - > Read ( includeNullAddress ) ;
inStream - > Read ( includeNullDescription ) ;
inStream - > Read ( playerOwn ) ;
inStream - > Read ( updateUi ) ;
inStream - > Read ( numResults ) ;
inStream - > Read ( reputation ) ;
inStream - > Read ( sortMethod ) ;
inStream - > Read ( startIndex ) ;
inStream - > Read ( filterTextLength ) ;
for ( auto i = 0u ; i < filterTextLength ; i + + ) {
char c ;
inStream - > Read ( c ) ;
filterText . push_back ( c ) ;
}
auto * player = Player : : GetPlayer ( sysAddr ) ;
auto * entranceComponent = entity - > GetComponent < PropertyEntranceComponent > ( ) ;
if ( entranceComponent = = nullptr ) return ;
entranceComponent - > OnPropertyEntranceSync ( player ,
includeNullAddress ,
includeNullDescription ,
playerOwn ,
updateUi ,
numResults ,
reputation ,
sortMethod ,
startIndex ,
filterText ,
sysAddr
) ;
}
void GameMessages : : HandleEnterProperty ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
uint32_t index { } ;
bool returnToZone { } ;
inStream - > Read ( index ) ;
inStream - > Read ( returnToZone ) ;
auto * player = Player : : GetPlayer ( sysAddr ) ;
auto * entranceComponent = entity - > GetComponent < PropertyEntranceComponent > ( ) ;
2022-05-03 20:05:29 +00:00
if ( entranceComponent ! = nullptr ) {
entranceComponent - > OnEnterProperty ( player , index , returnToZone , sysAddr ) ;
return ;
}
2021-12-05 17:54:36 +00:00
2023-08-18 19:14:40 +00:00
auto multiZoneEntranceComponent = entity - > GetComponent < MultiZoneEntranceComponent > ( ) ;
if ( multiZoneEntranceComponent ! = nullptr ) {
multiZoneEntranceComponent - > OnSelectWorld ( player , index ) ;
2022-05-03 20:05:29 +00:00
}
2021-12-05 17:54:36 +00:00
}
2022-07-17 07:35:11 +00:00
void GameMessages : : HandleSetConsumableItem ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
LOT lot ;
inStream - > Read ( lot ) ;
auto * inventory = entity - > GetComponent < InventoryComponent > ( ) ;
if ( inventory = = nullptr ) return ;
inventory - > SetConsumable ( lot ) ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendPlayCinematic ( LWOOBJID objectId , std : : u16string pathName , const SystemAddress & sysAddr ,
2021-12-05 17:54:36 +00:00
bool allowGhostUpdates , bool bCloseMultiInteract , bool bSendServerNotify , bool bUseControlledObjectForAudioListener ,
2023-03-25 10:26:39 +00:00
eEndBehavior endBehavior , bool hidePlayerDuringCine , float leadIn , bool leavePlayerLockedWhenFinished ,
2022-07-17 07:35:11 +00:00
bool lockPlayer , bool result , bool skipIfSamePath , float startTimeAdvance ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : PLAY_CINEMATIC ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( allowGhostUpdates ) ;
bitStream . Write ( bCloseMultiInteract ) ;
bitStream . Write ( bSendServerNotify ) ;
bitStream . Write ( bUseControlledObjectForAudioListener ) ;
2023-03-25 10:26:39 +00:00
bitStream . Write ( endBehavior ! = eEndBehavior : : RETURN ) ;
if ( endBehavior ! = eEndBehavior : : RETURN ) bitStream . Write ( endBehavior ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( hidePlayerDuringCine ) ;
bitStream . Write ( leadIn ! = - 1 ) ;
if ( leadIn ! = - 1 ) bitStream . Write ( leadIn ) ;
bitStream . Write ( leavePlayerLockedWhenFinished ) ;
bitStream . Write ( lockPlayer ) ;
bitStream . Write < uint32_t > ( pathName . size ( ) ) ;
for ( char16_t c : pathName ) {
bitStream . Write ( c ) ;
}
bitStream . Write ( result ) ;
bitStream . Write ( skipIfSamePath ) ;
bitStream . Write ( startTimeAdvance ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendEndCinematic ( LWOOBJID objectId , std : : u16string pathName , const SystemAddress & sysAddr ,
2022-07-17 07:35:11 +00:00
float leadOut , bool leavePlayerLocked ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : END_CINEMATIC ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( leadOut ! = - 1 ) ;
if ( leadOut ! = - 1 ) bitStream . Write ( leadOut ) ;
bitStream . Write ( leavePlayerLocked ) ;
bitStream . Write < uint32_t > ( pathName . size ( ) ) ;
for ( uint32_t i = 0 ; i < pathName . size ( ) ; i + + ) {
bitStream . Write ( pathName [ i ] ) ;
}
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : HandleCinematicUpdate ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2022-07-23 02:58:20 +00:00
eCinematicEvent event ;
if ( ! inStream - > ReadBit ( ) ) {
2023-05-02 22:39:21 +00:00
event = eCinematicEvent : : STARTED ;
2022-07-23 02:58:20 +00:00
} else {
inStream - > Read < eCinematicEvent > ( event ) ;
}
float_t overallTime ;
if ( ! inStream - > ReadBit ( ) ) {
overallTime = - 1.0f ;
} else {
inStream - > Read < float_t > ( overallTime ) ;
}
uint32_t pathNameLength ;
inStream - > Read ( pathNameLength ) ;
std : : u16string pathName ;
for ( size_t i = 0 ; i < pathNameLength ; i + + ) {
char16_t character ;
inStream - > Read ( character ) ;
pathName . push_back ( character ) ;
}
float_t pathTime ;
if ( ! inStream - > ReadBit ( ) ) {
pathTime = - 1.0f ;
} else {
inStream - > Read < float_t > ( pathTime ) ;
}
int32_t waypoint ;
if ( ! inStream - > ReadBit ( ) ) {
waypoint = - 1 ;
} else {
inStream - > Read < int32_t > ( waypoint ) ;
}
2023-07-15 20:56:33 +00:00
std : : vector < Entity * > scriptedActs = Game : : entityManager - > GetEntitiesByComponent ( eReplicaComponentType : : SCRIPT ) ;
2022-07-23 02:58:20 +00:00
for ( Entity * scriptEntity : scriptedActs ) {
scriptEntity - > OnCinematicUpdate ( scriptEntity , entity , event , pathName , pathTime , overallTime , waypoint ) ;
}
2021-12-05 17:54:36 +00:00
}
2023-01-07 05:59:19 +00:00
void GameMessages : : SendSetStunned ( LWOOBJID objectId , eStateChangeType stateChangeType , const SystemAddress & sysAddr ,
2021-12-05 17:54:36 +00:00
LWOOBJID originator , bool bCantAttack , bool bCantEquip ,
bool bCantInteract , bool bCantJump , bool bCantMove , bool bCantTurn ,
bool bCantUseItem , bool bDontTerminateInteract , bool bIgnoreImmunity ,
bool bCantAttackOutChangeWasApplied , bool bCantEquipOutChangeWasApplied ,
bool bCantInteractOutChangeWasApplied , bool bCantJumpOutChangeWasApplied ,
bool bCantMoveOutChangeWasApplied , bool bCantTurnOutChangeWasApplied ,
2022-07-17 07:35:11 +00:00
bool bCantUseItemOutChangeWasApplied ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SET_STUNNED ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( originator ! = LWOOBJID_EMPTY ) ;
if ( originator ! = LWOOBJID_EMPTY ) bitStream . Write ( originator ) ;
bitStream . Write ( stateChangeType ) ;
bitStream . Write ( bCantAttack ) ;
bitStream . Write ( bCantAttackOutChangeWasApplied ) ;
bitStream . Write ( bCantEquip ) ;
bitStream . Write ( bCantEquipOutChangeWasApplied ) ;
bitStream . Write ( bCantInteract ) ;
bitStream . Write ( bCantInteractOutChangeWasApplied ) ;
bitStream . Write ( bCantJump ) ;
bitStream . Write ( bCantJumpOutChangeWasApplied ) ;
bitStream . Write ( bCantMove ) ;
bitStream . Write ( bCantMoveOutChangeWasApplied ) ;
bitStream . Write ( bCantTurn ) ;
bitStream . Write ( bCantTurnOutChangeWasApplied ) ;
bitStream . Write ( bCantUseItem ) ;
bitStream . Write ( bCantUseItemOutChangeWasApplied ) ;
bitStream . Write ( bDontTerminateInteract ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
bitStream . Write ( bIgnoreImmunity ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2023-01-07 05:59:19 +00:00
void GameMessages : : SendSetStunImmunity ( LWOOBJID target , eStateChangeType state , const SystemAddress & sysAddr ,
2023-10-16 12:55:57 +00:00
LWOOBJID originator ,
bool bImmuneToStunAttack ,
bool bImmuneToStunEquip ,
bool bImmuneToStunInteract ,
bool bImmuneToStunJump ,
bool bImmuneToStunMove ,
bool bImmuneToStunTurn ,
bool bImmuneToStunUseItem ) {
2023-01-07 05:59:19 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( target ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SET_STUN_IMMUNITY ) ;
2023-01-07 05:59:19 +00:00
bitStream . Write ( originator ! = LWOOBJID_EMPTY ) ;
if ( originator ! = LWOOBJID_EMPTY ) bitStream . Write ( originator ) ;
bitStream . Write ( state ) ;
bitStream . Write ( bImmuneToStunAttack ) ;
bitStream . Write ( bImmuneToStunEquip ) ;
bitStream . Write ( bImmuneToStunInteract ) ;
bitStream . Write ( bImmuneToStunJump ) ;
bitStream . Write ( bImmuneToStunMove ) ;
bitStream . Write ( bImmuneToStunTurn ) ;
bitStream . Write ( bImmuneToStunUseItem ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendSetStatusImmunity ( LWOOBJID objectId , eStateChangeType state , const SystemAddress & sysAddr ,
2023-10-16 12:55:57 +00:00
bool bImmuneToBasicAttack ,
bool bImmuneToDamageOverTime ,
bool bImmuneToKnockback ,
bool bImmuneToInterrupt ,
bool bImmuneToSpeed ,
bool bImmuneToImaginationGain ,
bool bImmuneToImaginationLoss ,
bool bImmuneToQuickbuildInterrupt ,
bool bImmuneToPullToPoint ) {
2023-01-07 05:59:19 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SET_STATUS_IMMUNITY ) ;
2023-01-07 05:59:19 +00:00
bitStream . Write ( state ) ;
bitStream . Write ( bImmuneToBasicAttack ) ;
bitStream . Write ( bImmuneToDamageOverTime ) ;
bitStream . Write ( bImmuneToKnockback ) ;
bitStream . Write ( bImmuneToInterrupt ) ;
bitStream . Write ( bImmuneToSpeed ) ;
bitStream . Write ( bImmuneToImaginationGain ) ;
bitStream . Write ( bImmuneToImaginationLoss ) ;
bitStream . Write ( bImmuneToQuickbuildInterrupt ) ;
bitStream . Write ( bImmuneToPullToPoint ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2021-12-05 17:54:36 +00:00
2022-07-17 07:35:11 +00:00
void GameMessages : : SendOrientToAngle ( LWOOBJID objectId , bool bRelativeToCurrent , float fAngle , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : ORIENT_TO_ANGLE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bRelativeToCurrent ) ;
bitStream . Write ( fAngle ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendAddRunSpeedModifier ( LWOOBJID objectId , LWOOBJID caster , uint32_t modifier , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : ADD_RUN_SPEED_MODIFIER ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( caster ! = LWOOBJID_EMPTY ) ;
if ( caster ! = LWOOBJID_EMPTY ) bitStream . Write ( caster ) ;
bitStream . Write ( modifier ! = 500 ) ;
if ( modifier ! = 500 ) bitStream . Write ( modifier ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendRemoveRunSpeedModifier ( LWOOBJID objectId , uint32_t modifier , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : REMOVE_RUN_SPEED_MODIFIER ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( modifier ! = 500 ) ;
if ( modifier ! = 500 ) bitStream . Write ( modifier ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendPropertyEntranceBegin ( LWOOBJID objectId , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : PROPERTY_ENTRANCE_BEGIN ) ;
2021-12-05 17:54:36 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendPropertySelectQuery ( LWOOBJID objectId , int32_t navOffset , bool thereAreMore , int32_t cloneId , bool hasFeaturedProperty , bool wasFriends , const std : : vector < PropertySelectQueryProperty > & entries , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : PROPERTY_SELECT_QUERY ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( navOffset ) ;
bitStream . Write ( thereAreMore ) ;
bitStream . Write ( cloneId ) ;
bitStream . Write ( hasFeaturedProperty ) ;
bitStream . Write ( wasFriends ) ;
bitStream . Write < uint32_t > ( entries . size ( ) ) ;
for ( auto & entry : entries ) {
entry . Serialize ( bitStream ) ;
}
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendNotifyObject ( LWOOBJID objectId , LWOOBJID objIDSender , std : : u16string name , const SystemAddress & sysAddr , int param1 , int param2 ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : NOTIFY_OBJECT ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( objIDSender ) ;
bitStream . Write ( static_cast < uint32_t > ( name . size ( ) ) ) ;
for ( const auto character : name ) {
bitStream . Write ( character ) ;
}
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
bitStream . Write ( param1 ) ;
bitStream . Write ( param2 ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : HandleVerifyAck ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
bool bDifferent ;
std : : string sBitStream ;
uint32_t uiHandle = 0 ;
bDifferent = inStream - > ReadBit ( ) ;
uint32_t sBitStreamLength = 0 ;
inStream - > Read ( sBitStreamLength ) ;
for ( uint64_t k = 0 ; k < sBitStreamLength ; k + + ) {
uint8_t character ;
inStream - > Read ( character ) ;
sBitStream . push_back ( character ) ;
}
if ( inStream - > ReadBit ( ) ) {
inStream - > Read ( uiHandle ) ;
}
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendTeamPickupItem ( LWOOBJID objectId , LWOOBJID lootID , LWOOBJID lootOwnerID , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : TEAM_PICKUP_ITEM ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( lootID ) ;
bitStream . Write ( lootOwnerID ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
//Trading:
void GameMessages : : SendServerTradeInvite ( LWOOBJID objectId , bool bNeedInvitePopUp , LWOOBJID i64Requestor , std : : u16string wsName , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SERVER_TRADE_INVITE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bNeedInvitePopUp ) ;
bitStream . Write ( i64Requestor ) ;
bitStream . Write ( static_cast < uint32_t > ( wsName . size ( ) ) ) ;
for ( const auto character : wsName ) {
bitStream . Write ( character ) ;
}
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendServerTradeInitialReply ( LWOOBJID objectId , LWOOBJID i64Invitee , int32_t resultType , std : : u16string wsName , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SERVER_TRADE_INITIAL_REPLY ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( i64Invitee ) ;
bitStream . Write ( resultType ) ;
bitStream . Write ( static_cast < uint32_t > ( wsName . size ( ) ) ) ;
for ( const auto character : wsName ) {
bitStream . Write ( character ) ;
}
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendServerTradeFinalReply ( LWOOBJID objectId , bool bResult , LWOOBJID i64Invitee , std : : u16string wsName , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SERVER_TRADE_FINAL_REPLY ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bResult ) ;
bitStream . Write ( i64Invitee ) ;
bitStream . Write ( static_cast < uint32_t > ( wsName . size ( ) ) ) ;
for ( const auto character : wsName ) {
bitStream . Write ( character ) ;
}
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendServerTradeAccept ( LWOOBJID objectId , bool bFirst , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SERVER_TRADE_ACCEPT ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bFirst ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendServerTradeCancel ( LWOOBJID objectId , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SERVER_TRADE_CANCEL ) ;
2021-12-05 17:54:36 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendServerTradeUpdate ( LWOOBJID objectId , uint64_t coins , const std : : vector < TradeItem > & items , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SERVER_TRADE_UPDATE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( false ) ;
bitStream . Write ( coins ) ;
bitStream . Write ( static_cast < uint32_t > ( items . size ( ) ) ) ;
for ( const auto & item : items ) {
bitStream . Write ( item . itemId ) ;
bitStream . Write ( item . itemId ) ;
bitStream . Write ( item . itemLot ) ;
bitStream . Write0 ( ) ;
bitStream . Write1 ( ) ;
bitStream . Write ( item . itemCount ) ;
bitStream . Write0 ( ) ;
bitStream . Write0 ( ) ;
bitStream . Write0 ( ) ;
bitStream . Write0 ( ) ;
}
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : HandleClientTradeRequest ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
// Check if the player has restricted trade access
auto * character = entity - > GetCharacter ( ) ;
if ( character - > HasPermission ( ePermissionMap : : RestrictedTradeAccess ) ) {
// Send a message to the player
ChatPackets : : SendSystemMessage (
sysAddr ,
u " This character has restricted trade access. "
) ;
return ;
}
bool bNeedInvitePopUp = inStream - > ReadBit ( ) ;
LWOOBJID i64Invitee ;
inStream - > Read ( i64Invitee ) ;
2023-07-15 20:56:33 +00:00
auto * invitee = Game : : entityManager - > GetEntity ( i64Invitee ) ;
2021-12-05 17:54:36 +00:00
if ( invitee ! = nullptr & & invitee - > IsPlayer ( ) ) {
character = invitee - > GetCharacter ( ) ;
if ( character - > HasPermission ( ePermissionMap : : RestrictedTradeAccess ) ) {
// Send a message to the player
ChatPackets : : SendSystemMessage (
sysAddr ,
u " The character you are trying to trade with has restricted trade access. "
) ;
return ;
}
2023-10-21 23:31:55 +00:00
LOG ( " Trade request to (%llu) " , i64Invitee ) ;
2021-12-05 17:54:36 +00:00
auto * trade = TradingManager : : Instance ( ) - > GetPlayerTrade ( entity - > GetObjectID ( ) ) ;
if ( trade ! = nullptr ) {
if ( ! trade - > IsParticipant ( i64Invitee ) ) {
TradingManager : : Instance ( ) - > CancelTrade ( trade - > GetTradeId ( ) ) ;
TradingManager : : Instance ( ) - > NewTrade ( entity - > GetObjectID ( ) , i64Invitee ) ;
}
} else {
TradingManager : : Instance ( ) - > NewTrade ( entity - > GetObjectID ( ) , i64Invitee ) ;
}
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
SendServerTradeInvite (
i64Invitee ,
bNeedInvitePopUp ,
entity - > GetObjectID ( ) ,
2022-08-02 13:56:20 +00:00
GeneralUtils : : UTF8ToUTF16 ( entity - > GetCharacter ( ) - > GetName ( ) ) ,
2021-12-05 17:54:36 +00:00
invitee - > GetSystemAddress ( )
) ;
}
}
void GameMessages : : HandleClientTradeCancel ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
auto * trade = TradingManager : : Instance ( ) - > GetPlayerTrade ( entity - > GetObjectID ( ) ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( trade = = nullptr ) return ;
2023-10-21 23:31:55 +00:00
LOG ( " Trade canceled from (%llu) " , entity - > GetObjectID ( ) ) ;
2022-04-09 02:36:43 +00:00
2021-12-05 17:54:36 +00:00
TradingManager : : Instance ( ) - > CancelTrade ( trade - > GetTradeId ( ) ) ;
}
void GameMessages : : HandleClientTradeAccept ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
bool bFirst = inStream - > ReadBit ( ) ;
2023-10-21 23:31:55 +00:00
LOG ( " Trade accepted from (%llu) -> (%d) " , entity - > GetObjectID ( ) , bFirst ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
auto * trade = TradingManager : : Instance ( ) - > GetPlayerTrade ( entity - > GetObjectID ( ) ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( trade = = nullptr ) return ;
trade - > SetAccepted ( entity - > GetObjectID ( ) , bFirst ) ;
}
void GameMessages : : HandleClientTradeUpdate ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
uint64_t currency ;
uint32_t itemCount ;
inStream - > Read ( currency ) ;
inStream - > Read ( itemCount ) ;
2023-10-21 23:31:55 +00:00
LOG ( " Trade update from (%llu) -> (%llu), (%i) " , entity - > GetObjectID ( ) , currency , itemCount ) ;
2021-12-05 17:54:36 +00:00
std : : vector < TradeItem > items { } ;
for ( size_t i = 0 ; i < itemCount ; i + + ) {
LWOOBJID itemId ;
LWOOBJID itemId2 ;
inStream - > Read ( itemId ) ;
inStream - > Read ( itemId2 ) ;
LOT lot = 0 ;
LWOOBJID unknown1 = 0 ;
uint32_t unknown2 = 0 ;
uint16_t slot = 0 ;
uint32_t unknown3 = 0 ;
uint32_t ldfSize = 0 ;
bool unknown4 ;
inStream - > Read ( lot ) ;
if ( inStream - > ReadBit ( ) ) {
inStream - > Read ( unknown1 ) ;
}
if ( inStream - > ReadBit ( ) ) {
inStream - > Read ( unknown2 ) ;
}
if ( inStream - > ReadBit ( ) ) {
inStream - > Read ( slot ) ;
}
if ( inStream - > ReadBit ( ) ) {
inStream - > Read ( unknown3 ) ;
}
if ( inStream - > ReadBit ( ) ) // No
{
inStream - > Read ( ldfSize ) ;
bool compressed = inStream - > ReadBit ( ) ;
if ( compressed ) {
uint32_t ldfCompressedSize = 0 ;
inStream - > Read ( ldfCompressedSize ) ;
inStream - > IgnoreBytes ( ldfCompressedSize ) ;
} else {
inStream - > IgnoreBytes ( ldfSize ) ;
}
}
unknown4 = inStream - > ReadBit ( ) ;
items . push_back ( { itemId , lot , unknown2 } ) ;
2023-10-21 23:31:55 +00:00
LOG ( " Trade item from (%llu) -> (%llu)/(%llu), (%i), (%llu), (%i), (%i) " , entity - > GetObjectID ( ) , itemId , itemId2 , lot , unknown1 , unknown2 , unknown3 ) ;
2021-12-05 17:54:36 +00:00
}
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
auto * trade = TradingManager : : Instance ( ) - > GetPlayerTrade ( entity - > GetObjectID ( ) ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( trade = = nullptr ) return ;
trade - > SetCoins ( entity - > GetObjectID ( ) , currency ) ;
trade - > SetItems ( entity - > GetObjectID ( ) , items ) ;
trade - > SendUpdateToOther ( entity - > GetObjectID ( ) ) ;
}
//Pets:
2023-05-02 22:39:21 +00:00
void GameMessages : : SendNotifyPetTamingMinigame ( LWOOBJID objectId , LWOOBJID petId , LWOOBJID playerTamingId , bool bForceTeleport , ePetTamingNotifyType notifyType , NiPoint3 petsDestPos , NiPoint3 telePos , NiQuaternion teleRot , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : NOTIFY_PET_TAMING_MINIGAME ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( petId ) ;
bitStream . Write ( playerTamingId ) ;
bitStream . Write ( bForceTeleport ) ;
bitStream . Write ( notifyType ) ;
bitStream . Write ( petsDestPos ) ;
bitStream . Write ( telePos ) ;
const bool hasDefault = teleRot ! = NiQuaternion : : IDENTITY ;
bitStream . Write ( hasDefault ) ;
if ( hasDefault ) bitStream . Write ( teleRot ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendNotifyTamingModelLoadedOnServer ( LWOOBJID objectId , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : NOTIFY_TAMING_MODEL_LOADED_ON_SERVER ) ;
2021-12-05 17:54:36 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2023-07-17 22:55:25 +00:00
void GameMessages : : SendNotifyPetTamingPuzzleSelected ( LWOOBJID objectId , const std : : vector < Brick > & bricks , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-08-04 02:27:40 +00:00
bitStream . Write ( eGameMessageType : : NOTIFY_TAMING_PUZZLE_SELECTED ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( static_cast < uint32_t > ( bricks . size ( ) ) ) ;
for ( const auto & brick : bricks ) {
bitStream . Write ( brick . designerID ) ;
bitStream . Write ( brick . materialID ) ;
}
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendPetTamingTryBuildResult ( LWOOBJID objectId , bool bSuccess , int32_t iNumCorrect , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : PET_TAMING_TRY_BUILD_RESULT ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bSuccess ) ;
bitStream . Write ( iNumCorrect ! = 0 ) ;
if ( iNumCorrect ! = 0 ) bitStream . Write ( iNumCorrect ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendPetResponse ( LWOOBJID objectId , LWOOBJID objIDPet , int32_t iPetCommandType , int32_t iResponse , int32_t iTypeID , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : PET_RESPONSE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( objIDPet ) ;
bitStream . Write ( iPetCommandType ) ;
bitStream . Write ( iResponse ) ;
bitStream . Write ( iTypeID ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendAddPetToPlayer ( LWOOBJID objectId , int32_t iElementalType , std : : u16string name , LWOOBJID petDBID , LOT petLOT , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : ADD_PET_TO_PLAYER ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( iElementalType ) ;
bitStream . Write ( static_cast < uint32_t > ( name . size ( ) ) ) ;
for ( const auto character : name ) {
bitStream . Write ( character ) ;
}
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
bitStream . Write ( petDBID ) ;
bitStream . Write ( petLOT ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendRegisterPetID ( LWOOBJID objectId , LWOOBJID objID , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : REGISTER_PET_ID ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( objID ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendRegisterPetDBID ( LWOOBJID objectId , LWOOBJID petDBID , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : REGISTER_PET_DBID ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( petDBID ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-09-02 18:49:19 +00:00
void GameMessages : : SendMarkInventoryItemAsActive ( LWOOBJID objectId , bool bActive , eUnequippableActiveType iType , LWOOBJID itemID , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : MARK_INVENTORY_ITEM_AS_ACTIVE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bActive ) ;
2022-07-17 07:35:11 +00:00
2022-09-02 18:49:19 +00:00
bitStream . Write ( iType ! = eUnequippableActiveType : : INVALID ) ;
if ( iType ! = eUnequippableActiveType : : INVALID ) bitStream . Write ( iType ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( itemID ! = LWOOBJID_EMPTY ) ;
if ( itemID ! = LWOOBJID_EMPTY ) bitStream . Write ( itemID ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendClientExitTamingMinigame ( LWOOBJID objectId , bool bVoluntaryExit , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : CLIENT_EXIT_TAMING_MINIGAME ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bVoluntaryExit ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendShowPetActionButton ( LWOOBJID objectId , int32_t buttonLabel , bool bShow , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SHOW_PET_ACTION_BUTTON ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( buttonLabel ) ;
bitStream . Write ( bShow ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendPlayEmote ( LWOOBJID objectId , int32_t emoteID , LWOOBJID target , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : PLAY_EMOTE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( emoteID ) ;
bitStream . Write ( target ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-11-28 00:40:14 +00:00
void GameMessages : : SendRemoveBuff ( Entity * entity , bool fromUnEquip , bool removeImmunity , uint32_t buffId ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : REMOVE_BUFF ) ;
2022-11-28 00:40:14 +00:00
bitStream . Write ( false ) ; // bFromRemoveBehavior but setting this to true makes the GM not do anything on the client?
bitStream . Write ( fromUnEquip ) ;
bitStream . Write ( removeImmunity ) ;
bitStream . Write ( buffId ) ;
SEND_PACKET_BROADCAST ;
}
2021-12-05 17:54:36 +00:00
2022-07-17 07:35:11 +00:00
void GameMessages : : SendBouncerActiveStatus ( LWOOBJID objectId , bool bActive , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : BOUNCER_ACTIVE_STATUS ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bActive ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendSetPetName ( LWOOBJID objectId , std : : u16string name , LWOOBJID petDBID , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SET_PET_NAME ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( static_cast < uint32_t > ( name . size ( ) ) ) ;
for ( const auto character : name ) {
bitStream . Write ( character ) ;
}
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
bitStream . Write ( petDBID ! = LWOOBJID_EMPTY ) ;
if ( petDBID ! = LWOOBJID_EMPTY ) bitStream . Write ( petDBID ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendSetPetNameModerated ( LWOOBJID objectId , LWOOBJID petDBID , int32_t nModerationStatus , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SET_PET_NAME_MODERATED ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
bitStream . Write ( petDBID ! = LWOOBJID_EMPTY ) ;
if ( petDBID ! = LWOOBJID_EMPTY ) bitStream . Write ( petDBID ) ;
bitStream . Write ( nModerationStatus ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendPetNameChanged ( LWOOBJID objectId , int32_t moderationStatus , std : : u16string name , std : : u16string ownerName , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : PET_NAME_CHANGED ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( moderationStatus ) ;
bitStream . Write ( static_cast < uint32_t > ( name . size ( ) ) ) ;
for ( const auto character : name ) {
bitStream . Write ( character ) ;
}
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
bitStream . Write ( static_cast < uint32_t > ( ownerName . size ( ) ) ) ;
for ( const auto character : ownerName ) {
bitStream . Write ( character ) ;
}
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : HandleClientExitTamingMinigame ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
bool bVoluntaryExit = inStream - > ReadBit ( ) ;
auto * petComponent = PetComponent : : GetTamingPet ( entity - > GetObjectID ( ) ) ;
if ( petComponent = = nullptr ) {
return ;
}
petComponent - > ClientExitTamingMinigame ( bVoluntaryExit ) ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : HandleStartServerPetMinigameTimer ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
auto * petComponent = PetComponent : : GetTamingPet ( entity - > GetObjectID ( ) ) ;
if ( petComponent = = nullptr ) {
return ;
}
petComponent - > StartTimer ( ) ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : HandlePetTamingTryBuild ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
uint32_t brickCount ;
std : : vector < Brick > bricks ;
bool clientFailed ;
inStream - > Read ( brickCount ) ;
bricks . reserve ( brickCount ) ;
for ( uint32_t i = 0 ; i < brickCount ; i + + ) {
Brick brick ;
inStream - > Read ( brick ) ;
bricks . push_back ( brick ) ;
}
clientFailed = inStream - > ReadBit ( ) ;
auto * petComponent = PetComponent : : GetTamingPet ( entity - > GetObjectID ( ) ) ;
if ( petComponent = = nullptr ) {
return ;
}
2022-04-07 05:21:17 +00:00
petComponent - > TryBuild ( bricks . size ( ) , clientFailed ) ;
2021-12-05 17:54:36 +00:00
}
2022-07-17 07:35:11 +00:00
void GameMessages : : HandleNotifyTamingBuildSuccess ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
NiPoint3 position ;
inStream - > Read ( position ) ;
auto * petComponent = PetComponent : : GetTamingPet ( entity - > GetObjectID ( ) ) ;
if ( petComponent = = nullptr ) {
return ;
}
petComponent - > NotifyTamingBuildSuccess ( position ) ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : HandleRequestSetPetName ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
uint32_t nameLength ;
std : : u16string name ;
inStream - > Read ( nameLength ) ;
for ( size_t i = 0 ; i < nameLength ; i + + ) {
char16_t character ;
inStream - > Read ( character ) ;
name . push_back ( character ) ;
}
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
auto * petComponent = PetComponent : : GetTamingPet ( entity - > GetObjectID ( ) ) ;
if ( petComponent = = nullptr ) {
petComponent = PetComponent : : GetActivePet ( entity - > GetObjectID ( ) ) ;
if ( petComponent = = nullptr ) {
return ;
}
}
petComponent - > RequestSetPetName ( name ) ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : HandleCommandPet ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
NiPoint3 genericPosInfo ;
LWOOBJID objIdSource ;
int32_t iPetCommandType ;
int32_t iTypeID ;
bool overrideObey ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
inStream - > Read ( genericPosInfo ) ;
inStream - > Read ( objIdSource ) ;
inStream - > Read ( iPetCommandType ) ;
inStream - > Read ( iTypeID ) ;
overrideObey = inStream - > ReadBit ( ) ;
auto * petComponent = entity - > GetComponent < PetComponent > ( ) ;
if ( petComponent = = nullptr ) {
return ;
}
petComponent - > Command ( genericPosInfo , objIdSource , iPetCommandType , iTypeID , overrideObey ) ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : HandleDespawnPet ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
bool bDeletePet ;
bDeletePet = inStream - > ReadBit ( ) ;
auto * petComponent = PetComponent : : GetActivePet ( entity - > GetObjectID ( ) ) ;
if ( petComponent = = nullptr ) {
return ;
}
if ( bDeletePet ) {
petComponent - > Release ( ) ;
} else {
petComponent - > Deactivate ( ) ;
}
}
2022-07-17 07:35:11 +00:00
void GameMessages : : HandleMessageBoxResponse ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
int32_t iButton ;
uint32_t identifierLength ;
std : : u16string identifier ;
uint32_t userDataLength ;
std : : u16string userData ;
inStream - > Read ( iButton ) ;
inStream - > Read ( identifierLength ) ;
for ( size_t i = 0 ; i < identifierLength ; i + + ) {
char16_t character ;
inStream - > Read ( character ) ;
identifier . push_back ( character ) ;
}
inStream - > Read ( userDataLength ) ;
for ( size_t i = 0 ; i < userDataLength ; i + + ) {
char16_t character ;
inStream - > Read ( character ) ;
userData . push_back ( character ) ;
}
2022-07-17 07:35:11 +00:00
2023-10-21 23:31:55 +00:00
LOG ( " Button: %d; LOT: %u identifier: %s; userData: %s " , iButton , entity - > GetLOT ( ) , GeneralUtils : : UTF16ToWTF8 ( identifier ) . c_str ( ) , GeneralUtils : : UTF16ToWTF8 ( userData ) . c_str ( ) ) ;
2021-12-05 17:54:36 +00:00
auto * user = UserManager : : Instance ( ) - > GetUser ( sysAddr ) ;
if ( user = = nullptr ) {
return ;
}
auto * userEntity = user - > GetLastUsedChar ( ) - > GetEntity ( ) ;
if ( userEntity = = nullptr ) {
return ;
}
entity - > OnMessageBoxResponse ( userEntity , iButton , identifier , userData ) ;
auto * scriptedActivityComponent = entity - > GetComponent < ScriptedActivityComponent > ( ) ;
if ( scriptedActivityComponent ! = nullptr ) {
scriptedActivityComponent - > HandleMessageBoxResponse ( userEntity , GeneralUtils : : UTF16ToWTF8 ( identifier ) ) ;
}
auto * racingControlComponent = entity - > GetComponent < RacingControlComponent > ( ) ;
if ( racingControlComponent ! = nullptr ) {
2023-05-09 05:40:00 +00:00
racingControlComponent - > HandleMessageBoxResponse ( userEntity , iButton , GeneralUtils : : UTF16ToWTF8 ( identifier ) ) ;
2021-12-05 17:54:36 +00:00
}
2023-07-15 20:56:33 +00:00
for ( auto * shootingGallery : Game : : entityManager - > GetEntitiesByComponent ( eReplicaComponentType : : SHOOTING_GALLERY ) ) {
2021-12-05 17:54:36 +00:00
shootingGallery - > OnMessageBoxResponse ( userEntity , iButton , identifier , userData ) ;
}
}
2022-07-17 07:35:11 +00:00
void GameMessages : : HandleChoiceBoxRespond ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
int32_t iButton ;
uint32_t buttonIdentifierLength ;
std : : u16string buttonIdentifier ;
uint32_t identifierLength ;
std : : u16string identifier ;
inStream - > Read ( buttonIdentifierLength ) ;
for ( size_t i = 0 ; i < buttonIdentifierLength ; i + + ) {
char16_t character ;
inStream - > Read ( character ) ;
buttonIdentifier . push_back ( character ) ;
}
inStream - > Read ( iButton ) ;
inStream - > Read ( identifierLength ) ;
for ( size_t i = 0 ; i < identifierLength ; i + + ) {
char16_t character ;
inStream - > Read ( character ) ;
identifier . push_back ( character ) ;
}
2022-07-17 07:35:11 +00:00
2023-10-21 23:31:55 +00:00
LOG ( " Button: %d; LOT: %u buttonIdentifier: %s; userData: %s " , iButton , entity - > GetLOT ( ) , GeneralUtils : : UTF16ToWTF8 ( buttonIdentifier ) . c_str ( ) , GeneralUtils : : UTF16ToWTF8 ( identifier ) . c_str ( ) ) ;
2021-12-05 17:54:36 +00:00
auto * user = UserManager : : Instance ( ) - > GetUser ( sysAddr ) ;
if ( user = = nullptr ) {
return ;
}
auto * userEntity = user - > GetLastUsedChar ( ) - > GetEntity ( ) ;
if ( userEntity = = nullptr ) {
return ;
}
entity - > OnChoiceBoxResponse ( userEntity , iButton , buttonIdentifier , identifier ) ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendDisplayZoneSummary ( LWOOBJID objectId , const SystemAddress & sysAddr , bool isPropertyMap , bool isZoneStart , LWOOBJID sender ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : DISPLAY_ZONE_SUMMARY ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( isPropertyMap ) ;
bitStream . Write ( isZoneStart ) ;
bitStream . Write ( sender ! = LWOOBJID_EMPTY ) ;
if ( sender ! = LWOOBJID_EMPTY ) bitStream . Write ( sender ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
//UI
2022-07-17 07:35:11 +00:00
void GameMessages : : SendNotifyNotEnoughInvSpace ( LWOOBJID objectId , uint32_t freeSlotsNeeded , eInventoryType inventoryType , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : VEHICLE_NOTIFY_FINISHED_RACE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( freeSlotsNeeded ) ;
bitStream . Write ( inventoryType ! = 0 ) ;
if ( inventoryType ! = 0 ) bitStream . Write ( inventoryType ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendDisplayMessageBox ( LWOOBJID objectId , bool bShow , LWOOBJID callbackClient , const std : : u16string & identifier , int32_t imageID , const std : : u16string & text , const std : : u16string & userData , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : DISPLAY_MESSAGE_BOX ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bShow ) ;
bitStream . Write ( callbackClient ) ;
bitStream . Write ( static_cast < uint32_t > ( identifier . size ( ) ) ) ;
for ( const auto character : identifier ) {
bitStream . Write ( character ) ;
}
bitStream . Write ( imageID ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
bitStream . Write ( static_cast < uint32_t > ( text . size ( ) ) ) ;
for ( const auto character : text ) {
bitStream . Write ( character ) ;
}
bitStream . Write ( static_cast < uint32_t > ( userData . size ( ) ) ) ;
for ( const auto character : userData ) {
bitStream . Write ( character ) ;
}
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendDisplayChatBubble ( LWOOBJID objectId , const std : : u16string & text , const SystemAddress & sysAddr ) {
2023-05-03 21:38:32 +00:00
// eGameMessageType::DISPLAY_CHAT_BUBBLE
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : DISPLAY_CHAT_BUBBLE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( static_cast < uint32_t > ( text . size ( ) ) ) ;
for ( const auto character : text ) {
bitStream . Write ( character ) ;
}
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-12-16 21:24:13 +00:00
2022-12-23 06:14:51 +00:00
void GameMessages : : SendChangeIdleFlags ( LWOOBJID objectId , eAnimationFlags flagsOn , eAnimationFlags flagsOff , const SystemAddress & sysAddr ) {
2022-12-16 21:24:13 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : CHANGE_IDLE_FLAGS ) ;
2022-12-23 06:14:51 +00:00
bitStream . Write < bool > ( flagsOff ! = eAnimationFlags : : IDLE_NONE ) ;
if ( flagsOff ! = eAnimationFlags : : IDLE_NONE ) bitStream . Write ( flagsOff ) ;
bitStream . Write < bool > ( flagsOn ! = eAnimationFlags : : IDLE_NONE ) ;
if ( flagsOn ! = eAnimationFlags : : IDLE_NONE ) bitStream . Write ( flagsOn ) ;
2022-12-16 21:24:13 +00:00
SEND_PACKET_BROADCAST ;
}
2022-07-17 07:35:11 +00:00
// Mounts
void GameMessages : : SendSetMountInventoryID ( Entity * entity , const LWOOBJID & objectID , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SET_MOUNT_INVENTORY_ID ) ;
2022-07-17 07:35:11 +00:00
bitStream . Write ( objectID ) ;
SEND_PACKET_BROADCAST ;
}
void GameMessages : : HandleDismountComplete ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2022-09-02 18:49:19 +00:00
// Get the objectID from the bitstream
2022-07-17 07:35:11 +00:00
LWOOBJID objectId { } ;
inStream - > Read ( objectId ) ;
2022-09-02 18:49:19 +00:00
// If we aren't possessing somethings, the don't do anything
2022-07-17 07:35:11 +00:00
if ( objectId ! = LWOOBJID_EMPTY ) {
2022-09-02 18:49:19 +00:00
auto * possessorComponent = entity - > GetComponent < PossessorComponent > ( ) ;
2023-07-15 20:56:33 +00:00
auto * mount = Game : : entityManager - > GetEntity ( objectId ) ;
2022-09-02 18:49:19 +00:00
// make sure we have the things we need and they aren't null
if ( possessorComponent & & mount ) {
if ( ! possessorComponent - > GetIsDismounting ( ) ) return ;
possessorComponent - > SetIsDismounting ( false ) ;
possessorComponent - > SetPossessable ( LWOOBJID_EMPTY ) ;
possessorComponent - > SetPossessableType ( ePossessionType : : NO_POSSESSION ) ;
// character related things
auto * character = entity - > GetComponent < CharacterComponent > ( ) ;
if ( character ) {
// If we had an active item turn it off
if ( possessorComponent - > GetMountItemID ( ) ! = LWOOBJID_EMPTY ) GameMessages : : SendMarkInventoryItemAsActive ( entity - > GetObjectID ( ) , false , eUnequippableActiveType : : MOUNT , possessorComponent - > GetMountItemID ( ) , entity - > GetSystemAddress ( ) ) ;
possessorComponent - > SetMountItemID ( LWOOBJID_EMPTY ) ;
}
2022-07-17 07:35:11 +00:00
2022-09-02 18:49:19 +00:00
// Set that the controllabel phsyics comp is teleporting
auto * controllablePhysicsComponent = entity - > GetComponent < ControllablePhysicsComponent > ( ) ;
if ( controllablePhysicsComponent ) controllablePhysicsComponent - > SetIsTeleporting ( true ) ;
2022-07-17 07:35:11 +00:00
2022-09-02 18:49:19 +00:00
// Call dismoint on the possessable comp to let it handle killing the possessable
auto * possessableComponent = mount - > GetComponent < PossessableComponent > ( ) ;
if ( possessableComponent ) possessableComponent - > Dismount ( ) ;
// Update the entity that was possessing
2023-07-15 20:56:33 +00:00
Game : : entityManager - > SerializeEntity ( entity ) ;
2022-09-02 18:49:19 +00:00
// We aren't mounted so remove the stun
2023-01-07 05:59:19 +00:00
GameMessages : : SendSetStunned ( entity - > GetObjectID ( ) , eStateChangeType : : POP , UNASSIGNED_SYSTEM_ADDRESS , LWOOBJID_EMPTY , true , false , true , false , false , false , false , true , true , true , true , true , true , true , true , true ) ;
2022-07-17 07:35:11 +00:00
}
}
}
void GameMessages : : HandleAcknowledgePossession ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2023-07-15 20:56:33 +00:00
Game : : entityManager - > SerializeEntity ( entity ) ;
2022-09-02 18:49:19 +00:00
LWOOBJID objectId { } ;
inStream - > Read ( objectId ) ;
2023-07-15 20:56:33 +00:00
auto * mount = Game : : entityManager - > GetEntity ( objectId ) ;
if ( mount ) Game : : entityManager - > SerializeEntity ( mount ) ;
2022-07-17 07:35:11 +00:00
}
2021-12-05 17:54:36 +00:00
//Racing
void GameMessages : : HandleModuleAssemblyQueryData ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
auto * moduleAssemblyComponent = entity - > GetComponent < ModuleAssemblyComponent > ( ) ;
2023-10-21 23:31:55 +00:00
LOG ( " Got Query from %i " , entity - > GetLOT ( ) ) ;
2021-12-05 17:54:36 +00:00
if ( moduleAssemblyComponent ! = nullptr ) {
2023-10-21 23:31:55 +00:00
LOG ( " Returning assembly %s " , GeneralUtils : : UTF16ToWTF8 ( moduleAssemblyComponent - > GetAssemblyPartsLOTs ( ) ) . c_str ( ) ) ;
2021-12-05 17:54:36 +00:00
2022-07-17 07:35:11 +00:00
SendModuleAssemblyDBDataForClient ( entity - > GetObjectID ( ) , moduleAssemblyComponent - > GetSubKey ( ) , moduleAssemblyComponent - > GetAssemblyPartsLOTs ( ) , UNASSIGNED_SYSTEM_ADDRESS ) ;
2021-12-05 17:54:36 +00:00
}
}
2022-07-17 07:35:11 +00:00
void GameMessages : : HandleModularAssemblyNIFCompleted ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
LWOOBJID objectID ;
inStream - > Read ( objectID ) ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : HandleVehicleSetWheelLockState ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
bool bExtraFriction = inStream - > ReadBit ( ) ;
bool bLocked = inStream - > ReadBit ( ) ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : HandleRacingClientReady ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
LWOOBJID playerID ;
inStream - > Read ( playerID ) ;
2023-07-15 20:56:33 +00:00
auto * player = Game : : entityManager - > GetEntity ( playerID ) ;
2021-12-05 17:54:36 +00:00
if ( player = = nullptr ) {
return ;
}
2023-07-17 22:55:33 +00:00
auto * racingControlComponent = Game : : zoneManager - > GetZoneControlObject ( ) - > GetComponent < RacingControlComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( racingControlComponent = = nullptr ) {
return ;
}
racingControlComponent - > OnRacingClientReady ( player ) ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : HandleRequestDie ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
bool bClientDeath ;
bool bSpawnLoot ;
std : : u16string deathType ;
float directionRelativeAngleXZ ;
float directionRelativeAngleY ;
float directionRelativeForce ;
2023-05-02 22:39:21 +00:00
eKillType killType = eKillType : : VIOLENT ;
2021-12-05 17:54:36 +00:00
LWOOBJID killerID ;
LWOOBJID lootOwnerID = LWOOBJID_EMPTY ;
bClientDeath = inStream - > ReadBit ( ) ;
bSpawnLoot = inStream - > ReadBit ( ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
uint32_t deathTypeLength = 0 ;
inStream - > Read ( deathTypeLength ) ;
for ( size_t i = 0 ; i < deathTypeLength ; i + + ) {
char16_t character ;
inStream - > Read ( character ) ;
deathType . push_back ( character ) ;
}
inStream - > Read ( directionRelativeAngleXZ ) ;
inStream - > Read ( directionRelativeAngleY ) ;
inStream - > Read ( directionRelativeForce ) ;
if ( inStream - > ReadBit ( ) ) {
inStream - > Read ( killType ) ;
}
inStream - > Read ( killerID ) ;
if ( inStream - > ReadBit ( ) ) {
inStream - > Read ( lootOwnerID ) ;
}
2023-07-17 22:55:33 +00:00
auto * zoneController = Game : : zoneManager - > GetZoneControlObject ( ) ;
2021-12-05 17:54:36 +00:00
auto * racingControlComponent = zoneController - > GetComponent < RacingControlComponent > ( ) ;
2023-10-21 23:31:55 +00:00
LOG ( " Got die request: %i " , entity - > GetLOT ( ) ) ;
2021-12-05 17:54:36 +00:00
if ( racingControlComponent ! = nullptr ) {
auto * possessableComponent = entity - > GetComponent < PossessableComponent > ( ) ;
if ( possessableComponent ! = nullptr ) {
2023-07-15 20:56:33 +00:00
entity = Game : : entityManager - > GetEntity ( possessableComponent - > GetPossessor ( ) ) ;
2021-12-05 17:54:36 +00:00
if ( entity = = nullptr ) {
return ;
}
}
racingControlComponent - > OnRequestDie ( entity ) ;
}
2023-11-18 00:43:01 +00:00
else {
auto * destroyableComponent = entity - > GetComponent < DestroyableComponent > ( ) ;
if ( ! destroyableComponent ) return ;
destroyableComponent - > Smash ( killerID , killType , deathType ) ;
}
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandleVehicleNotifyServerAddPassiveBoostAction ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
//SendVehicleAddPassiveBoostAction(entity->GetObjectID(), sysAddr);
}
2022-07-17 07:35:11 +00:00
void GameMessages : : HandleVehicleNotifyServerRemovePassiveBoostAction ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
//SendVehicleRemovePassiveBoostAction(entity->GetObjectID(), sysAddr);
}
2022-07-17 07:35:11 +00:00
void GameMessages : : HandleRacingPlayerInfoResetFinished ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
LWOOBJID playerID ;
inStream - > Read ( playerID ) ;
2023-07-15 20:56:33 +00:00
auto * player = Game : : entityManager - > GetEntity ( playerID ) ;
2021-12-05 17:54:36 +00:00
if ( player = = nullptr ) {
return ;
}
2023-07-17 22:55:33 +00:00
auto * zoneController = Game : : zoneManager - > GetZoneControlObject ( ) ;
2021-12-05 17:54:36 +00:00
auto * racingControlComponent = zoneController - > GetComponent < RacingControlComponent > ( ) ;
2023-10-21 23:31:55 +00:00
LOG ( " Got finished: %i " , entity - > GetLOT ( ) ) ;
2021-12-05 17:54:36 +00:00
if ( racingControlComponent ! = nullptr ) {
racingControlComponent - > OnRacingPlayerInfoResetFinished ( player ) ;
}
}
2022-03-30 06:46:23 +00:00
void GameMessages : : SendUpdateReputation ( const LWOOBJID objectId , const int64_t reputation , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : UPDATE_REPUTATION ) ;
2022-03-30 06:46:23 +00:00
bitStream . Write ( reputation ) ;
SEND_PACKET ;
}
2022-03-30 02:52:07 +00:00
void GameMessages : : HandleUpdatePropertyPerformanceCost ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
float performanceCost = 0.0f ;
if ( inStream - > ReadBit ( ) ) inStream - > Read ( performanceCost ) ;
if ( performanceCost = = 0.0f ) return ;
2023-07-17 22:55:33 +00:00
auto zone = Game : : zoneManager - > GetZone ( ) ;
2022-03-30 02:52:07 +00:00
const auto & worldId = zone - > GetZoneID ( ) ;
const auto cloneId = worldId . GetCloneID ( ) ;
const auto zoneId = worldId . GetMapID ( ) ;
auto updatePerformanceCostQuery = Database : : CreatePreppedStmt ( " UPDATE properties SET performance_cost = ? WHERE clone_id = ? AND zone_id = ? " ) ;
updatePerformanceCostQuery - > setDouble ( 1 , performanceCost ) ;
updatePerformanceCostQuery - > setInt ( 2 , cloneId ) ;
updatePerformanceCostQuery - > setInt ( 3 , zoneId ) ;
2022-03-31 05:14:51 +00:00
updatePerformanceCostQuery - > executeUpdate ( ) ;
2022-03-30 02:52:07 +00:00
delete updatePerformanceCostQuery ;
updatePerformanceCostQuery = nullptr ;
}
2021-12-05 17:54:36 +00:00
2022-07-17 07:35:11 +00:00
void GameMessages : : HandleVehicleNotifyHitImaginationServer ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
LWOOBJID pickupObjID = LWOOBJID_EMPTY ;
LWOOBJID pickupSpawnerID = LWOOBJID_EMPTY ;
int32_t pickupSpawnerIndex = - 1 ;
NiPoint3 vehiclePosition = NiPoint3 : : ZERO ;
if ( inStream - > ReadBit ( ) ) inStream - > Read ( pickupObjID ) ;
if ( inStream - > ReadBit ( ) ) inStream - > Read ( pickupSpawnerID ) ;
if ( inStream - > ReadBit ( ) ) inStream - > Read ( pickupSpawnerIndex ) ;
if ( inStream - > ReadBit ( ) ) inStream - > Read ( vehiclePosition ) ;
2023-07-15 20:56:33 +00:00
auto * pickup = Game : : entityManager - > GetEntity ( pickupObjID ) ;
2021-12-05 17:54:36 +00:00
if ( pickup = = nullptr ) {
return ;
}
auto * possessableComponent = entity - > GetComponent < PossessableComponent > ( ) ;
if ( possessableComponent ! = nullptr ) {
2023-07-15 20:56:33 +00:00
entity = Game : : entityManager - > GetEntity ( possessableComponent - > GetPossessor ( ) ) ;
2021-12-05 17:54:36 +00:00
if ( entity = = nullptr ) {
return ;
}
}
2022-07-23 02:58:20 +00:00
auto * characterComponent = entity - > GetComponent < CharacterComponent > ( ) ;
if ( characterComponent ! = nullptr ) {
characterComponent - > UpdatePlayerStatistic ( RacingImaginationPowerUpsCollected ) ;
}
2021-12-05 17:54:36 +00:00
pickup - > OnFireEventServerSide ( entity , " powerup " ) ;
pickup - > Kill ( entity ) ;
}
void GameMessages : : SendModuleAssemblyDBDataForClient ( LWOOBJID objectId , LWOOBJID assemblyID , const std : : u16string & data , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : MODULE_ASSEMBLY_DB_DATA_FOR_CLIENT ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( assemblyID ) ;
bitStream . Write ( static_cast < uint32_t > ( data . size ( ) ) ) ;
for ( auto character : data ) {
bitStream . Write ( character ) ;
}
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendNotifyVehicleOfRacingObject ( LWOOBJID objectId , LWOOBJID racingObjectID , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : NOTIFY_VEHICLE_OF_RACING_OBJECT ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( racingObjectID ! = LWOOBJID_EMPTY ) ;
if ( racingObjectID ! = LWOOBJID_EMPTY ) bitStream . Write ( racingObjectID ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendRacingPlayerLoaded ( LWOOBJID objectId , LWOOBJID playerID , LWOOBJID vehicleID , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : RACING_PLAYER_LOADED ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( playerID ) ;
bitStream . Write ( vehicleID ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendVehicleUnlockInput ( LWOOBJID objectId , bool bLockWheels , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : VEHICLE_UNLOCK_INPUT ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bLockWheels ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendVehicleSetWheelLockState ( LWOOBJID objectId , bool bExtraFriction , bool bLocked , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : VEHICLE_SET_WHEEL_LOCK_STATE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bExtraFriction ) ;
bitStream . Write ( bLocked ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendRacingSetPlayerResetInfo ( LWOOBJID objectId , int32_t currentLap , uint32_t furthestResetPlane , LWOOBJID playerID , NiPoint3 respawnPos , uint32_t upcomingPlane , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : RACING_SET_PLAYER_RESET_INFO ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( currentLap ) ;
bitStream . Write ( furthestResetPlane ) ;
bitStream . Write ( playerID ) ;
bitStream . Write ( respawnPos ) ;
bitStream . Write ( upcomingPlane ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendRacingResetPlayerToLastReset ( LWOOBJID objectId , LWOOBJID playerID , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : RACING_RESET_PLAYER_TO_LAST_RESET ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( playerID ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2023-03-05 20:34:59 +00:00
void GameMessages : : SendVehicleStopBoost ( Entity * targetEntity , const SystemAddress & playerSysAddr , bool affectPassive ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( targetEntity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : VEHICLE_STOP_BOOST ) ;
2023-05-02 22:39:21 +00:00
2023-03-05 20:34:59 +00:00
bitStream . Write ( affectPassive ) ;
SEND_PACKET_BROADCAST ;
}
void GameMessages : : SendSetResurrectRestoreValues ( Entity * targetEntity , int32_t armorRestore , int32_t healthRestore , int32_t imaginationRestore ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( targetEntity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SET_RESURRECT_RESTORE_VALUES ) ;
2023-05-02 22:39:21 +00:00
2023-03-05 20:34:59 +00:00
bitStream . Write ( armorRestore ! = - 1 ) ;
if ( armorRestore ! = - 1 ) bitStream . Write ( armorRestore ) ;
bitStream . Write ( healthRestore ! = - 1 ) ;
if ( healthRestore ! = - 1 ) bitStream . Write ( healthRestore ) ;
bitStream . Write ( imaginationRestore ! = - 1 ) ;
if ( imaginationRestore ! = - 1 ) bitStream . Write ( imaginationRestore ) ;
SEND_PACKET_BROADCAST ;
}
2021-12-05 17:54:36 +00:00
2022-07-17 07:35:11 +00:00
void GameMessages : : SendNotifyRacingClient ( LWOOBJID objectId , int32_t eventType , int32_t param1 , LWOOBJID paramObj , std : : u16string paramStr , LWOOBJID singleClient , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : NOTIFY_RACING_CLIENT ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( eventType ! = 0 ) ;
if ( eventType ! = 0 ) bitStream . Write ( eventType ) ;
bitStream . Write ( param1 ) ;
bitStream . Write ( paramObj ) ;
bitStream . Write ( static_cast < uint32_t > ( paramStr . size ( ) ) ) ;
for ( auto character : paramStr ) {
bitStream . Write ( character ) ;
}
bitStream . Write ( singleClient ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendActivityEnter ( LWOOBJID objectId , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : ACTIVITY_ENTER ) ;
2021-12-05 17:54:36 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendActivityStart ( LWOOBJID objectId , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : ACTIVITY_START ) ;
2021-12-05 17:54:36 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendActivityExit ( LWOOBJID objectId , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : ACTIVITY_EXIT ) ;
2021-12-05 17:54:36 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendActivityStop ( LWOOBJID objectId , bool bExit , bool bUserCancel , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : ACTIVITY_STOP ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bExit ) ;
bitStream . Write ( bUserCancel ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendVehicleAddPassiveBoostAction ( LWOOBJID objectId , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : VEHICLE_ADD_PASSIVE_BOOST_ACTION ) ;
2021-12-05 17:54:36 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendVehicleRemovePassiveBoostAction ( LWOOBJID objectId , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : VEHICLE_REMOVE_PASSIVE_BOOST_ACTION ) ;
2021-12-05 17:54:36 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendVehicleNotifyFinishedRace ( LWOOBJID objectId , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : VEHICLE_NOTIFY_FINISHED_RACE ) ;
2021-12-05 17:54:36 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendAddBuff ( LWOOBJID & objectID , const LWOOBJID & casterID , uint32_t buffID , uint32_t msDuration ,
2022-07-23 02:58:20 +00:00
bool addImmunity , bool cancelOnDamaged , bool cancelOnDeath , bool cancelOnLogout ,
bool cancelOnRemoveBuff , bool cancelOnUi , bool cancelOnUnequip , bool cancelOnZone ,
const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectID ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : ADD_BUFF ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( false ) ; // Added by teammate
bitStream . Write ( false ) ; // Apply on teammates
bitStream . Write ( false ) ; // Cancel on damage absorb ran out
bitStream . Write ( cancelOnDamaged ) ;
bitStream . Write ( cancelOnDeath ) ;
bitStream . Write ( cancelOnLogout ) ;
bitStream . Write ( false ) ; // Cancel on move
bitStream . Write ( cancelOnRemoveBuff ) ;
bitStream . Write ( cancelOnUi ) ;
bitStream . Write ( cancelOnUnequip ) ;
bitStream . Write ( cancelOnZone ) ;
bitStream . Write ( false ) ; // Ignore immunities
bitStream . Write ( addImmunity ) ;
bitStream . Write ( false ) ; // Use ref count
bitStream . Write ( buffID ) ;
bitStream . Write ( msDuration ) ;
bitStream . Write ( casterID ) ;
bitStream . Write ( casterID ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
// NT
void GameMessages : : HandleRequestMoveItemBetweenInventoryTypes ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2022-12-04 22:25:25 +00:00
bool bAllowPartial { } ;
2021-12-05 17:54:36 +00:00
int32_t destSlot = - 1 ;
int32_t iStackCount = 1 ;
eInventoryType invTypeDst = ITEMS ;
eInventoryType invTypeSrc = ITEMS ;
LWOOBJID itemID = LWOOBJID_EMPTY ;
2022-12-04 22:25:25 +00:00
bool showFlyingLoot { } ;
2021-12-05 17:54:36 +00:00
LWOOBJID subkey = LWOOBJID_EMPTY ;
LOT itemLOT = 0 ;
bAllowPartial = inStream - > ReadBit ( ) ;
if ( inStream - > ReadBit ( ) ) inStream - > Read ( destSlot ) ;
if ( inStream - > ReadBit ( ) ) inStream - > Read ( iStackCount ) ;
if ( inStream - > ReadBit ( ) ) inStream - > Read ( invTypeDst ) ;
if ( inStream - > ReadBit ( ) ) inStream - > Read ( invTypeSrc ) ;
if ( inStream - > ReadBit ( ) ) inStream - > Read ( itemID ) ;
showFlyingLoot = inStream - > ReadBit ( ) ;
if ( inStream - > ReadBit ( ) ) inStream - > Read ( subkey ) ;
if ( inStream - > ReadBit ( ) ) inStream - > Read ( itemLOT ) ;
if ( invTypeDst = = invTypeSrc ) {
return ;
}
auto * inventoryComponent = entity - > GetComponent < InventoryComponent > ( ) ;
if ( inventoryComponent ! = nullptr ) {
if ( itemID ! = LWOOBJID_EMPTY ) {
auto * item = inventoryComponent - > FindItemById ( itemID ) ;
2022-12-04 22:25:25 +00:00
if ( ! item ) return ;
2021-12-05 17:54:36 +00:00
2022-12-04 22:25:25 +00:00
// Despawn the pet if we are moving that pet to the vault.
auto * petComponent = PetComponent : : GetActivePet ( entity - > GetObjectID ( ) ) ;
if ( petComponent & & petComponent - > GetDatabaseId ( ) = = item - > GetSubKey ( ) ) {
inventoryComponent - > DespawnPet ( ) ;
2021-12-05 17:54:36 +00:00
}
inventoryComponent - > MoveItemToInventory ( item , invTypeDst , iStackCount , showFlyingLoot , false , false , destSlot ) ;
}
}
}
2022-07-17 07:35:11 +00:00
void GameMessages : : SendShowActivityCountdown ( LWOOBJID objectId , bool bPlayAdditionalSound , bool bPlayCountdownSound , std : : u16string sndName , int32_t stateToPlaySoundOn , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SHOW_ACTIVITY_COUNTDOWN ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( bPlayAdditionalSound ) ;
bitStream . Write ( bPlayCountdownSound ) ;
bitStream . Write ( static_cast < uint32_t > ( sndName . size ( ) ) ) ;
for ( auto character : sndName ) {
bitStream . Write ( character ) ;
}
bitStream . Write ( stateToPlaySoundOn ) ;
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
//-----------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------- Handlers ------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------------
2022-07-17 07:35:11 +00:00
void GameMessages : : HandleToggleGhostReferenceOverride ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
bool bOverride = false ;
inStream - > Read ( bOverride ) ;
auto * player = Player : : GetPlayer ( sysAddr ) ;
if ( player ! = nullptr ) {
player - > SetGhostOverride ( bOverride ) ;
2022-07-17 07:35:11 +00:00
2023-07-15 20:56:33 +00:00
Game : : entityManager - > UpdateGhosting ( player ) ;
2021-12-05 17:54:36 +00:00
}
}
2022-07-17 07:35:11 +00:00
void GameMessages : : HandleSetGhostReferencePosition ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2021-12-05 17:54:36 +00:00
NiPoint3 position ;
inStream - > Read ( position ) ;
auto * player = Player : : GetPlayer ( sysAddr ) ;
if ( player ! = nullptr ) {
player - > SetGhostOverridePoint ( position ) ;
2023-07-15 20:56:33 +00:00
Game : : entityManager - > UpdateGhosting ( player ) ;
2021-12-05 17:54:36 +00:00
}
}
void GameMessages : : HandleBuyFromVendor ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
bool bConfirmed { } ; // this doesnt even do anything, thanks ND!
bool countIsDefault { } ;
int count = 1 ;
LOT item ;
inStream - > Read ( bConfirmed ) ;
inStream - > Read ( countIsDefault ) ;
if ( countIsDefault ) inStream - > Read ( count ) ;
inStream - > Read ( item ) ;
User * user = UserManager : : Instance ( ) - > GetUser ( sysAddr ) ;
if ( ! user ) return ;
2023-07-15 20:56:33 +00:00
Entity * player = Game : : entityManager - > GetEntity ( user - > GetLoggedInChar ( ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! player ) return ;
2023-03-04 07:16:37 +00:00
auto * propertyVendorComponent = static_cast < PropertyVendorComponent * > ( entity - > GetComponent ( eReplicaComponentType : : PROPERTY_VENDOR ) ) ;
2021-12-05 17:54:36 +00:00
if ( propertyVendorComponent ! = nullptr ) {
propertyVendorComponent - > OnBuyFromVendor ( player , bConfirmed , item , count ) ;
return ;
}
const auto isCommendationVendor = entity - > GetLOT ( ) = = 13806 ;
2022-07-17 07:35:11 +00:00
2023-06-03 07:40:46 +00:00
auto * vend = entity - > GetComponent < VendorComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( ! vend & & ! isCommendationVendor ) return ;
2023-06-03 07:40:46 +00:00
auto * inv = player - > GetComponent < InventoryComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( ! inv ) return ;
2023-06-03 07:40:46 +00:00
if ( ! isCommendationVendor & & ! vend - > SellsItem ( item ) ) {
2023-10-21 23:31:55 +00:00
LOG ( " User %llu %s tried to buy an item %i from a vendor when they do not sell said item " , player - > GetObjectID ( ) , user - > GetUsername ( ) . c_str ( ) , item ) ;
2023-06-03 07:40:46 +00:00
return ;
}
2023-03-17 14:36:21 +00:00
CDComponentsRegistryTable * compRegistryTable = CDClientManager : : Instance ( ) . GetTable < CDComponentsRegistryTable > ( ) ;
CDItemComponentTable * itemComponentTable = CDClientManager : : Instance ( ) . GetTable < CDItemComponentTable > ( ) ;
2021-12-05 17:54:36 +00:00
2023-03-04 07:16:37 +00:00
int itemCompID = compRegistryTable - > GetByIDAndType ( item , eReplicaComponentType : : ITEM ) ;
2021-12-05 17:54:36 +00:00
CDItemComponent itemComp = itemComponentTable - > GetItemComponentByID ( itemCompID ) ;
Character * character = player - > GetCharacter ( ) ;
if ( ! character ) return ;
2022-07-23 02:58:20 +00:00
// Extra currency that needs to be deducted in case of crafting
auto craftingCurrencies = CDItemComponentTable : : ParseCraftingCurrencies ( itemComp ) ;
for ( const auto & craftingCurrency : craftingCurrencies ) {
inv - > RemoveItem ( craftingCurrency . first , craftingCurrency . second * count ) ;
}
2021-12-05 17:54:36 +00:00
if ( isCommendationVendor ) {
if ( itemComp . commendationLOT ! = 13763 ) {
return ;
}
auto * missionComponent = player - > GetComponent < MissionComponent > ( ) ;
if ( missionComponent = = nullptr ) {
return ;
}
LOT tokenId = - 1 ;
if ( missionComponent - > GetMissionState ( 545 ) = = eMissionState : : COMPLETE ) tokenId = 8318 ; // "Assembly Token"
if ( missionComponent - > GetMissionState ( 556 ) = = eMissionState : : COMPLETE ) tokenId = 8321 ; // "Venture League Token"
if ( missionComponent - > GetMissionState ( 567 ) = = eMissionState : : COMPLETE ) tokenId = 8319 ; // "Sentinels Token"
if ( missionComponent - > GetMissionState ( 578 ) = = eMissionState : : COMPLETE ) tokenId = 8320 ; // "Paradox Token"
const uint32_t altCurrencyCost = itemComp . commendationCost * count ;
if ( inv - > GetLotCount ( tokenId ) < altCurrencyCost ) {
return ;
}
inv - > RemoveItem ( tokenId , altCurrencyCost ) ;
2023-05-02 22:39:21 +00:00
inv - > AddItem ( item , count , eLootSourceType : : VENDOR ) ;
2021-12-05 17:54:36 +00:00
} else {
float buyScalar = vend - > GetBuyScalar ( ) ;
const auto coinCost = static_cast < uint32_t > ( std : : floor ( ( itemComp . baseValue * buyScalar ) * count ) ) ;
if ( character - > GetCoins ( ) < coinCost ) {
return ;
}
if ( Inventory : : IsValidItem ( itemComp . currencyLOT ) ) {
const uint32_t altCurrencyCost = std : : floor ( itemComp . altCurrencyCost * buyScalar ) * count ;
if ( inv - > GetLotCount ( itemComp . currencyLOT ) < altCurrencyCost ) {
return ;
}
inv - > RemoveItem ( itemComp . currencyLOT , altCurrencyCost ) ;
}
2023-05-02 22:39:21 +00:00
character - > SetCoins ( character - > GetCoins ( ) - ( coinCost ) , eLootSourceType : : VENDOR ) ;
inv - > AddItem ( item , count , eLootSourceType : : VENDOR ) ;
2021-12-05 17:54:36 +00:00
}
GameMessages : : SendVendorTransactionResult ( entity , sysAddr ) ;
}
void GameMessages : : HandleSellToVendor ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
bool countIsDefault { } ;
int count = 1 ;
LWOOBJID iObjID ;
inStream - > Read ( countIsDefault ) ;
if ( countIsDefault ) inStream - > Read ( count ) ;
inStream - > Read ( iObjID ) ;
User * user = UserManager : : Instance ( ) - > GetUser ( sysAddr ) ;
if ( ! user ) return ;
2023-07-15 20:56:33 +00:00
Entity * player = Game : : entityManager - > GetEntity ( user - > GetLoggedInChar ( ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! player ) return ;
Character * character = player - > GetCharacter ( ) ;
if ( ! character ) return ;
2023-03-04 07:16:37 +00:00
InventoryComponent * inv = static_cast < InventoryComponent * > ( player - > GetComponent ( eReplicaComponentType : : INVENTORY ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! inv ) return ;
2023-03-04 07:16:37 +00:00
VendorComponent * vend = static_cast < VendorComponent * > ( entity - > GetComponent ( eReplicaComponentType : : VENDOR ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! vend ) return ;
Item * item = inv - > FindItemById ( iObjID ) ;
if ( ! item ) return ;
2023-03-17 14:36:21 +00:00
CDComponentsRegistryTable * compRegistryTable = CDClientManager : : Instance ( ) . GetTable < CDComponentsRegistryTable > ( ) ;
CDItemComponentTable * itemComponentTable = CDClientManager : : Instance ( ) . GetTable < CDItemComponentTable > ( ) ;
2021-12-05 17:54:36 +00:00
2023-03-04 07:16:37 +00:00
int itemCompID = compRegistryTable - > GetByIDAndType ( item - > GetLot ( ) , eReplicaComponentType : : ITEM ) ;
2021-12-05 17:54:36 +00:00
CDItemComponent itemComp = itemComponentTable - > GetItemComponentByID ( itemCompID ) ;
// Items with a base value of 0 or max int are special items that should not be sold if they're not sub items
if ( itemComp . baseValue = = 0 | | itemComp . baseValue = = UINT_MAX ) return ;
float sellScalar = vend - > GetSellScalar ( ) ;
if ( Inventory : : IsValidItem ( itemComp . currencyLOT ) ) {
2022-12-24 08:51:59 +00:00
const auto altCurrency = static_cast < uint32_t > ( itemComp . altCurrencyCost * sellScalar ) * count ;
2023-05-02 22:39:21 +00:00
inv - > AddItem ( itemComp . currencyLOT , std : : floor ( altCurrency ) , eLootSourceType : : VENDOR ) ; // Return alt currencies like faction tokens.
2021-12-05 17:54:36 +00:00
}
//inv->RemoveItem(count, -1, iObjID);
2022-04-24 03:32:31 +00:00
inv - > MoveItemToInventory ( item , eInventoryType : : VENDOR_BUYBACK , count , true , false , true ) ;
2023-05-02 22:39:21 +00:00
character - > SetCoins ( std : : floor ( character - > GetCoins ( ) + ( static_cast < uint32_t > ( itemComp . baseValue * sellScalar ) * count ) ) , eLootSourceType : : VENDOR ) ;
2023-07-15 20:56:33 +00:00
//Game::entityManager->SerializeEntity(player); // so inventory updates
2021-12-05 17:54:36 +00:00
GameMessages : : SendVendorTransactionResult ( entity , sysAddr ) ;
}
void GameMessages : : HandleBuybackFromVendor ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
bool confirmed = false ;
bool countIsDefault { } ;
int count = 1 ;
LWOOBJID iObjID ;
inStream - > Read ( confirmed ) ;
inStream - > Read ( countIsDefault ) ;
if ( countIsDefault ) inStream - > Read ( count ) ;
inStream - > Read ( iObjID ) ;
//if (!confirmed) return; they always built in this confirmed garbage... but never used it?
User * user = UserManager : : Instance ( ) - > GetUser ( sysAddr ) ;
if ( ! user ) return ;
2023-07-15 20:56:33 +00:00
Entity * player = Game : : entityManager - > GetEntity ( user - > GetLoggedInChar ( ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! player ) return ;
Character * character = player - > GetCharacter ( ) ;
if ( ! character ) return ;
2023-03-04 07:16:37 +00:00
InventoryComponent * inv = static_cast < InventoryComponent * > ( player - > GetComponent ( eReplicaComponentType : : INVENTORY ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! inv ) return ;
2023-03-04 07:16:37 +00:00
VendorComponent * vend = static_cast < VendorComponent * > ( entity - > GetComponent ( eReplicaComponentType : : VENDOR ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! vend ) return ;
Item * item = inv - > FindItemById ( iObjID ) ;
if ( ! item ) return ;
2023-03-17 14:36:21 +00:00
CDComponentsRegistryTable * compRegistryTable = CDClientManager : : Instance ( ) . GetTable < CDComponentsRegistryTable > ( ) ;
CDItemComponentTable * itemComponentTable = CDClientManager : : Instance ( ) . GetTable < CDItemComponentTable > ( ) ;
2021-12-05 17:54:36 +00:00
2023-03-04 07:16:37 +00:00
int itemCompID = compRegistryTable - > GetByIDAndType ( item - > GetLot ( ) , eReplicaComponentType : : ITEM ) ;
2021-12-05 17:54:36 +00:00
CDItemComponent itemComp = itemComponentTable - > GetItemComponentByID ( itemCompID ) ;
float sellScalar = vend - > GetSellScalar ( ) ;
const auto cost = static_cast < uint32_t > ( std : : floor ( ( ( itemComp . baseValue * sellScalar ) * count ) ) ) ;
if ( character - > GetCoins ( ) < cost ) {
return ;
}
if ( Inventory : : IsValidItem ( itemComp . currencyLOT ) ) {
const uint32_t altCurrencyCost = std : : floor ( itemComp . altCurrencyCost * sellScalar ) * count ;
if ( inv - > GetLotCount ( itemComp . currencyLOT ) < altCurrencyCost ) {
return ;
}
inv - > RemoveItem ( itemComp . currencyLOT , altCurrencyCost ) ;
}
//inv->RemoveItem(count, -1, iObjID);
inv - > MoveItemToInventory ( item , Inventory : : FindInventoryTypeForLot ( item - > GetLot ( ) ) , count , true , false ) ;
2023-05-02 22:39:21 +00:00
character - > SetCoins ( character - > GetCoins ( ) - cost , eLootSourceType : : VENDOR ) ;
2023-07-15 20:56:33 +00:00
//Game::entityManager->SerializeEntity(player); // so inventory updates
2021-12-05 17:54:36 +00:00
GameMessages : : SendVendorTransactionResult ( entity , sysAddr ) ;
}
void GameMessages : : HandleParseChatMessage ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
std : : u16string wsString ;
int iClientState ;
inStream - > Read ( iClientState ) ;
uint32_t wsStringLength ;
inStream - > Read ( wsStringLength ) ;
for ( uint32_t i = 0 ; i < wsStringLength ; + + i ) {
uint16_t character ;
inStream - > Read ( character ) ;
wsString . push_back ( character ) ;
}
if ( wsString [ 0 ] = = L ' / ' ) {
SlashCommandHandler : : HandleChatCommand ( wsString , entity , sysAddr ) ;
}
}
void GameMessages : : HandleFireEventServerSide ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
uint32_t argsLength { } ;
std : : u16string args { } ;
bool param1IsDefault { } ;
int param1 = - 1 ;
bool param2IsDefault { } ;
int param2 = - 1 ;
bool param3IsDefault { } ;
int param3 = - 1 ;
LWOOBJID senderID { } ;
inStream - > Read ( argsLength ) ;
for ( uint32_t i = 0 ; i < argsLength ; + + i ) {
uint16_t character ;
inStream - > Read ( character ) ;
args . push_back ( character ) ;
}
inStream - > Read ( param1IsDefault ) ;
if ( param1IsDefault ) inStream - > Read ( param1 ) ;
inStream - > Read ( param2IsDefault ) ;
if ( param2IsDefault ) inStream - > Read ( param2 ) ;
inStream - > Read ( param3IsDefault ) ;
if ( param3IsDefault ) inStream - > Read ( param3 ) ;
inStream - > Read ( senderID ) ;
2023-07-15 20:56:33 +00:00
auto * sender = Game : : entityManager - > GetEntity ( senderID ) ;
2021-12-05 17:54:36 +00:00
auto * player = Player : : GetPlayer ( sysAddr ) ;
if ( ! player ) {
return ;
}
// This should probably get it's own "ServerEvents" system or something at some point
if ( args = = u " ZonePlayer " ) {
// Should probably check to make sure they're using a launcher at some point before someone makes a hack that lets you testmap
LWOCLONEID cloneId = 0 ;
LWOMAPID mapId = 0 ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
auto * rocketPad = entity - > GetComponent < RocketLaunchpadControlComponent > ( ) ;
if ( rocketPad = = nullptr ) return ;
cloneId = rocketPad - > GetSelectedCloneId ( player - > GetObjectID ( ) ) ;
if ( param2 ) {
mapId = rocketPad - > GetDefaultZone ( ) ;
} else {
mapId = param3 ;
}
if ( mapId = = 0 ) {
mapId = rocketPad - > GetSelectedMapId ( player - > GetObjectID ( ) ) ;
}
if ( mapId = = 0 ) {
2023-07-17 22:55:33 +00:00
mapId = Game : : zoneManager - > GetZoneID ( ) . GetMapID ( ) ; // Fallback to sending the player back to the same zone.
2021-12-05 17:54:36 +00:00
}
2023-10-21 23:31:55 +00:00
LOG ( " Player %llu has requested zone transfer to (%i, %i). " , sender - > GetObjectID ( ) , ( int ) mapId , ( int ) cloneId ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
auto * character = player - > GetCharacter ( ) ;
if ( mapId < = 0 ) {
return ;
}
ZoneInstanceManager : : Instance ( ) - > RequestZoneTransfer ( Game : : server , mapId , cloneId , false , [ = ] ( bool mythranShift , uint32_t zoneID , uint32_t zoneInstance , uint32_t zoneClone , std : : string serverIP , uint16_t serverPort ) {
2023-10-21 23:31:55 +00:00
LOG ( " Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i " , character - > GetName ( ) . c_str ( ) , zoneID , zoneInstance , zoneClone , mythranShift = = true ? " true " : " false " , serverIP . c_str ( ) , serverPort ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( character ) {
character - > SetZoneID ( zoneID ) ;
character - > SetZoneInstance ( zoneInstance ) ;
character - > SetZoneClone ( zoneClone ) ;
}
WorldPackets : : SendTransferToWorld ( sysAddr , serverIP , serverPort , mythranShift ) ;
return ;
} ) ;
}
2022-07-23 02:58:20 +00:00
entity - > OnFireEventServerSide ( sender , GeneralUtils : : UTF16ToWTF8 ( args ) , param1 , param2 , param3 ) ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandleRequestPlatformResync ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
if ( entity - > GetLOT ( ) = = 6267 | | entity - > GetLOT ( ) = = 16141 ) return ;
GameMessages : : SendPlatformResync ( entity , sysAddr ) ;
}
void GameMessages : : HandleRebuildCancel ( RakNet : : BitStream * inStream , Entity * entity ) {
bool bEarlyRelease ;
LWOOBJID userID ;
inStream - > Read ( bEarlyRelease ) ;
inStream - > Read ( userID ) ;
2023-03-04 07:16:37 +00:00
RebuildComponent * rebComp = static_cast < RebuildComponent * > ( entity - > GetComponent ( eReplicaComponentType : : QUICK_BUILD ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! rebComp ) return ;
2023-07-15 20:56:33 +00:00
rebComp - > CancelRebuild ( Game : : entityManager - > GetEntity ( userID ) , eQuickBuildFailReason : : CANCELED_EARLY ) ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandleRequestUse ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
bool bIsMultiInteractUse = false ;
unsigned int multiInteractID ;
int multiInteractType ;
bool secondary ;
LWOOBJID objectID ;
inStream - > Read ( bIsMultiInteractUse ) ;
inStream - > Read ( multiInteractID ) ;
inStream - > Read ( multiInteractType ) ;
inStream - > Read ( objectID ) ;
inStream - > Read ( secondary ) ;
2023-07-15 20:56:33 +00:00
Entity * interactedObject = Game : : entityManager - > GetEntity ( objectID ) ;
2021-12-05 17:54:36 +00:00
if ( interactedObject = = nullptr ) {
2023-10-21 23:31:55 +00:00
LOG ( " Object %llu tried to interact, but doesn't exist! " , objectID ) ;
2021-12-05 17:54:36 +00:00
return ;
}
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( interactedObject - > GetLOT ( ) = = 9524 ) {
entity - > GetCharacter ( ) - > SetBuildMode ( true ) ;
}
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( bIsMultiInteractUse ) {
if ( multiInteractType = = 0 ) {
2023-03-04 07:16:37 +00:00
auto * missionOfferComponent = static_cast < MissionOfferComponent * > ( interactedObject - > GetComponent ( eReplicaComponentType : : MISSION_OFFER ) ) ;
2021-12-05 17:54:36 +00:00
if ( missionOfferComponent ! = nullptr ) {
missionOfferComponent - > OfferMissions ( entity , multiInteractID ) ;
}
} else {
interactedObject - > OnUse ( entity ) ;
}
} else {
interactedObject - > OnUse ( entity ) ;
}
//Perform use task if possible:
2023-03-04 07:16:37 +00:00
auto missionComponent = static_cast < MissionComponent * > ( entity - > GetComponent ( eReplicaComponentType : : MISSION ) ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( missionComponent = = nullptr ) return ;
missionComponent - > Progress ( eMissionTaskType : : TALK_TO_NPC , interactedObject - > GetLOT ( ) , interactedObject - > GetObjectID ( ) ) ;
missionComponent - > Progress ( eMissionTaskType : : INTERACT , interactedObject - > GetLOT ( ) , interactedObject - > GetObjectID ( ) ) ;
}
void GameMessages : : HandlePlayEmote ( RakNet : : BitStream * inStream , Entity * entity ) {
int emoteID ;
LWOOBJID targetID ;
inStream - > Read ( emoteID ) ;
inStream - > Read ( targetID ) ;
2023-10-21 23:31:55 +00:00
LOG_DEBUG ( " Emote (%i) (%llu) " , emoteID , targetID ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
//TODO: If targetID != 0, and we have one of the "perform emote" missions, complete them.
if ( emoteID = = 0 ) return ;
std : : string sAnimationName = " deaded " ; //Default name in case we fail to get the emote
2022-11-27 12:03:30 +00:00
MissionComponent * missionComponent = entity - > GetComponent < MissionComponent > ( ) ;
if ( ! missionComponent ) return ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( targetID ! = LWOOBJID_EMPTY ) {
2023-07-15 20:56:33 +00:00
auto * targetEntity = Game : : entityManager - > GetEntity ( targetID ) ;
2021-12-05 17:54:36 +00:00
2023-10-21 23:31:55 +00:00
LOG_DEBUG ( " Emote target found (%d) " , targetEntity ! = nullptr ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( targetEntity ! = nullptr ) {
targetEntity - > OnEmoteReceived ( emoteID , entity ) ;
2022-11-27 12:03:30 +00:00
missionComponent - > Progress ( eMissionTaskType : : EMOTE , emoteID , targetID ) ;
2021-12-05 17:54:36 +00:00
}
} else {
2023-10-21 23:31:55 +00:00
LOG_DEBUG ( " Target ID is empty, using backup " ) ;
2023-07-15 20:56:33 +00:00
const auto scriptedEntities = Game : : entityManager - > GetEntitiesByComponent ( eReplicaComponentType : : SCRIPT ) ;
2021-12-05 17:54:36 +00:00
const auto & referencePoint = entity - > GetPosition ( ) ;
for ( auto * scripted : scriptedEntities ) {
if ( Vector3 : : DistanceSquared ( scripted - > GetPosition ( ) , referencePoint ) > 5.0f * 5.0f ) continue ;
scripted - > OnEmoteReceived ( emoteID , entity ) ;
2022-11-27 12:03:30 +00:00
missionComponent - > Progress ( eMissionTaskType : : EMOTE , emoteID , scripted - > GetObjectID ( ) ) ;
2021-12-05 17:54:36 +00:00
}
}
2023-03-17 14:36:21 +00:00
CDEmoteTableTable * emotes = CDClientManager : : Instance ( ) . GetTable < CDEmoteTableTable > ( ) ;
2021-12-05 17:54:36 +00:00
if ( emotes ) {
CDEmoteTable * emote = emotes - > GetEmote ( emoteID ) ;
if ( emote ) sAnimationName = emote - > animationName ;
}
2023-03-20 13:10:52 +00:00
RenderComponent : : PlayAnimation ( entity , sAnimationName ) ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandleModularBuildConvertModel ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
LWOOBJID modelID ;
inStream - > Read ( modelID ) ;
User * user = UserManager : : Instance ( ) - > GetUser ( sysAddr ) ;
if ( ! user ) return ;
2023-07-15 20:56:33 +00:00
Entity * character = Game : : entityManager - > GetEntity ( user - > GetLoggedInChar ( ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! character ) return ;
2023-03-04 07:16:37 +00:00
InventoryComponent * inv = static_cast < InventoryComponent * > ( character - > GetComponent ( eReplicaComponentType : : INVENTORY ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! inv ) return ;
auto * item = inv - > FindItemById ( modelID ) ;
if ( item = = nullptr ) {
return ;
}
item - > Disassemble ( TEMP_MODELS ) ;
2023-11-16 01:32:30 +00:00
std : : unique_ptr < sql : : PreparedStatement > stmt ( Database : : CreatePreppedStmt ( " DELETE FROM ugc_modular_build where ugc_id = ? " ) ) ;
stmt - > setUInt64 ( 1 , item - > GetSubKey ( ) ) ;
stmt - > execute ( ) ;
2023-05-02 22:39:21 +00:00
item - > SetCount ( item - > GetCount ( ) - 1 , false , false , true , eLootSourceType : : QUICKBUILD ) ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandleSetFlag ( RakNet : : BitStream * inStream , Entity * entity ) {
bool bFlag { } ;
2023-05-02 22:39:21 +00:00
int32_t iFlagID { } ;
2021-12-05 17:54:36 +00:00
inStream - > Read ( bFlag ) ;
inStream - > Read ( iFlagID ) ;
auto user = entity - > GetParentUser ( ) ;
if ( user ) {
auto character = user - > GetLastUsedChar ( ) ;
if ( ! character ) return ;
character - > SetPlayerFlag ( iFlagID , bFlag ) ;
}
}
void GameMessages : : HandleRespondToMission ( RakNet : : BitStream * inStream , Entity * entity ) {
int missionID { } ;
LWOOBJID playerID { } ;
LWOOBJID receiverID { } ;
bool isDefaultReward { } ;
LOT reward = LOT_NULL ;
inStream - > Read ( missionID ) ;
inStream - > Read ( playerID ) ;
inStream - > Read ( receiverID ) ;
inStream - > Read ( isDefaultReward ) ;
if ( isDefaultReward ) inStream - > Read ( reward ) ;
2023-03-04 07:16:37 +00:00
MissionComponent * missionComponent = static_cast < MissionComponent * > ( entity - > GetComponent ( eReplicaComponentType : : MISSION ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! missionComponent ) {
2023-10-21 23:31:55 +00:00
LOG ( " Unable to get mission component for entity %llu to handle RespondToMission " , playerID ) ;
2021-12-05 17:54:36 +00:00
return ;
}
Mission * mission = missionComponent - > GetMission ( missionID ) ;
if ( mission ) {
mission - > SetReward ( reward ) ;
} else {
2023-10-21 23:31:55 +00:00
LOG ( " Unable to get mission %i for entity %llu to update reward in RespondToMission " , missionID , playerID ) ;
2021-12-05 17:54:36 +00:00
}
2023-07-15 20:56:33 +00:00
Entity * offerer = Game : : entityManager - > GetEntity ( receiverID ) ;
2021-12-05 17:54:36 +00:00
if ( offerer = = nullptr ) {
2023-10-21 23:31:55 +00:00
LOG ( " Unable to get receiver entity %llu for RespondToMission " , receiverID ) ;
2021-12-05 17:54:36 +00:00
return ;
}
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( offerer ) ) {
2023-07-15 20:56:33 +00:00
script - > OnRespondToMission ( offerer , missionID , Game : : entityManager - > GetEntity ( playerID ) , reward ) ;
2021-12-05 17:54:36 +00:00
}
}
void GameMessages : : HandleMissionDialogOK ( RakNet : : BitStream * inStream , Entity * entity ) {
bool bIsComplete { } ;
eMissionState iMissionState { } ;
int missionID { } ;
LWOOBJID responder { } ;
Entity * player = nullptr ;
inStream - > Read ( bIsComplete ) ;
inStream - > Read ( iMissionState ) ;
inStream - > Read ( missionID ) ;
inStream - > Read ( responder ) ;
2023-07-15 20:56:33 +00:00
player = Game : : entityManager - > GetEntity ( responder ) ;
2021-12-05 17:54:36 +00:00
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( entity ) ) {
script - > OnMissionDialogueOK ( entity , player , missionID , iMissionState ) ;
}
// Get the player's mission component
2023-03-04 07:16:37 +00:00
MissionComponent * missionComponent = static_cast < MissionComponent * > ( player - > GetComponent ( eReplicaComponentType : : MISSION ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! missionComponent ) {
2023-10-21 23:31:55 +00:00
LOG ( " Unable to get mission component for entity %llu to handle MissionDialogueOK " , player - > GetObjectID ( ) ) ;
2021-12-05 17:54:36 +00:00
return ;
}
if ( iMissionState = = eMissionState : : AVAILABLE | | iMissionState = = eMissionState : : COMPLETE_AVAILABLE ) {
missionComponent - > AcceptMission ( missionID ) ;
} else if ( iMissionState = = eMissionState : : READY_TO_COMPLETE | | iMissionState = = eMissionState : : COMPLETE_READY_TO_COMPLETE ) {
missionComponent - > CompleteMission ( missionID ) ;
}
}
void GameMessages : : HandleRequestLinkedMission ( RakNet : : BitStream * inStream , Entity * entity ) {
LWOOBJID playerId { } ;
int missionId { } ;
bool bMissionOffered { } ;
inStream - > Read ( playerId ) ;
inStream - > Read ( missionId ) ;
inStream - > Read ( bMissionOffered ) ;
2023-07-15 20:56:33 +00:00
auto * player = Game : : entityManager - > GetEntity ( playerId ) ;
2021-12-05 17:54:36 +00:00
2023-03-04 07:16:37 +00:00
auto * missionOfferComponent = static_cast < MissionOfferComponent * > ( entity - > GetComponent ( eReplicaComponentType : : MISSION_OFFER ) ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( missionOfferComponent ! = nullptr ) {
missionOfferComponent - > OfferMissions ( player , 0 ) ;
}
}
void GameMessages : : HandleHasBeenCollected ( RakNet : : BitStream * inStream , Entity * entity ) {
LWOOBJID playerID ;
inStream - > Read ( playerID ) ;
2023-07-15 20:56:33 +00:00
Entity * player = Game : : entityManager - > GetEntity ( playerID ) ;
2021-12-05 17:54:36 +00:00
if ( ! player | | ! entity | | entity - > GetCollectibleID ( ) = = 0 ) return ;
2023-03-04 07:16:37 +00:00
MissionComponent * missionComponent = static_cast < MissionComponent * > ( player - > GetComponent ( eReplicaComponentType : : MISSION ) ) ;
2021-12-05 17:54:36 +00:00
if ( missionComponent ) {
missionComponent - > Progress ( eMissionTaskType : : COLLECTION , entity - > GetLOT ( ) , entity - > GetObjectID ( ) ) ;
}
}
void GameMessages : : HandleNotifyServerLevelProcessingComplete ( RakNet : : BitStream * inStream , Entity * entity ) {
2022-07-24 18:04:02 +00:00
auto * levelComp = entity - > GetComponent < LevelProgressionComponent > ( ) ;
if ( ! levelComp ) return ;
auto * character = entity - > GetComponent < CharacterComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( ! character ) return ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
//Update our character's level in memory:
2022-07-24 18:04:02 +00:00
levelComp - > SetLevel ( levelComp - > GetLevel ( ) + 1 ) ;
2021-12-05 17:54:36 +00:00
2022-07-24 18:04:02 +00:00
levelComp - > HandleLevelUp ( ) ;
2021-12-05 17:54:36 +00:00
auto * inventoryComponent = entity - > GetComponent < InventoryComponent > ( ) ;
if ( inventoryComponent ! = nullptr ) {
auto * inventory = inventoryComponent - > GetInventory ( ITEMS ) ;
if ( inventory ! = nullptr & & Game : : config - > GetValue ( " disable_extra_backpack " ) ! = " 1 " ) {
inventory - > SetSize ( inventory - > GetSize ( ) + 2 ) ;
}
}
//Play the level up effect:
GameMessages : : SendPlayFXEffect ( entity , 7074 , u " create " , " 7074 " , LWOOBJID_EMPTY , 1.0f , 1.0f , true ) ;
//Send a notification in chat:
std : : stringstream wss ;
wss < < " level=1: " ;
2022-07-24 18:04:02 +00:00
wss < < levelComp - > GetLevel ( ) ;
2021-12-05 17:54:36 +00:00
wss < < " \n " ;
wss < < " name=0: " ;
wss < < character - > GetName ( ) ;
2022-08-02 13:56:20 +00:00
// FIXME: only really need utf8 conversion for the name, so move that up?
std : : u16string attrs = GeneralUtils : : UTF8ToUTF16 ( wss . str ( ) ) ;
2021-12-05 17:54:36 +00:00
std : : u16string wsText = u " UI_LEVEL_PROGRESSION_LEVELUP_MESSAGE " ;
GameMessages : : SendBroadcastTextToChatbox ( entity , UNASSIGNED_SYSTEM_ADDRESS , attrs , wsText ) ;
}
void GameMessages : : HandlePickupCurrency ( RakNet : : BitStream * inStream , Entity * entity ) {
unsigned int currency ;
inStream - > Read ( currency ) ;
2022-07-17 07:35:11 +00:00
2021-12-11 13:21:00 +00:00
if ( currency = = 0 ) return ;
2021-12-05 17:54:36 +00:00
auto * ch = entity - > GetCharacter ( ) ;
2021-12-11 13:57:15 +00:00
if ( entity - > CanPickupCoins ( currency ) ) {
2023-05-02 22:39:21 +00:00
ch - > SetCoins ( ch - > GetCoins ( ) + currency , eLootSourceType : : PICKUP ) ;
2021-12-11 13:21:00 +00:00
}
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandleRequestDie ( RakNet : : BitStream * inStream , Entity * entity ) {
LWOOBJID killerID ;
LWOOBJID lootOwnerID ;
bool bDieAccepted = false ;
eKillType killType ;
std : : u16string deathType ;
float directionRelative_AngleY ;
float directionRelative_AngleXZ ;
float directionRelative_Force ;
bool bClientDeath = false ;
bool bSpawnLoot = true ;
float coinSpawnTime = - 1.0f ;
inStream - > Read ( bClientDeath ) ;
inStream - > Read ( bDieAccepted ) ;
inStream - > Read ( bSpawnLoot ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
bool coinSpawnTimeIsDefault { } ;
inStream - > Read ( coinSpawnTimeIsDefault ) ;
if ( coinSpawnTimeIsDefault ! = 0 ) inStream - > Read ( coinSpawnTime ) ;
/*uint32_t deathTypeLength = deathType.size();
inStream - > Read ( deathTypeLength ) ;
for ( uint32_t k = 0 ; k < deathTypeLength ; k + + ) {
inStream - > Read ( static_cast < uint16_t > ( deathType [ k ] ) ) ;
} */
inStream - > Read ( directionRelative_AngleXZ ) ;
inStream - > Read ( directionRelative_AngleY ) ;
inStream - > Read ( directionRelative_Force ) ;
bool killTypeIsDefault { } ;
inStream - > Read ( killTypeIsDefault ) ;
if ( killTypeIsDefault ! = 0 ) inStream - > Read ( killType ) ;
inStream - > Read ( lootOwnerID ) ;
inStream - > Read ( killerID ) ;
}
void GameMessages : : HandleEquipItem ( RakNet : : BitStream * inStream , Entity * entity ) {
bool immediate ;
LWOOBJID objectID ;
inStream - > Read ( immediate ) ;
inStream - > Read ( immediate ) ; //twice?
inStream - > Read ( objectID ) ;
2023-03-04 07:16:37 +00:00
InventoryComponent * inv = static_cast < InventoryComponent * > ( entity - > GetComponent ( eReplicaComponentType : : INVENTORY ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! inv ) return ;
Item * item = inv - > FindItemById ( objectID ) ;
if ( ! item ) return ;
2022-05-09 00:57:36 +00:00
2021-12-05 17:54:36 +00:00
item - > Equip ( ) ;
2022-07-17 07:35:11 +00:00
2023-07-15 20:56:33 +00:00
Game : : entityManager - > SerializeEntity ( entity ) ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandleUnequipItem ( RakNet : : BitStream * inStream , Entity * entity ) {
bool immediate ;
LWOOBJID objectID ;
inStream - > Read ( immediate ) ;
inStream - > Read ( immediate ) ;
inStream - > Read ( immediate ) ;
inStream - > Read ( objectID ) ;
2023-03-04 07:16:37 +00:00
InventoryComponent * inv = static_cast < InventoryComponent * > ( entity - > GetComponent ( eReplicaComponentType : : INVENTORY ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! inv ) return ;
auto * item = inv - > FindItemById ( objectID ) ;
if ( ! item ) return ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
item - > UnEquip ( ) ;
2022-07-17 07:35:11 +00:00
2023-07-15 20:56:33 +00:00
Game : : entityManager - > SerializeEntity ( entity ) ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandleRemoveItemFromInventory ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
// this is used for a lot more than just inventory trashing (trades, vendors, etc.) but for now since it's just used for that, that's all im going to implement
bool bConfirmed = false ;
bool bDeleteItem = true ;
bool bOutSuccess = false ;
bool eInvTypeIsDefault = false ;
int eInvType = INVENTORY_MAX ;
bool eLootTypeSourceIsDefault = false ;
int eLootTypeSource = LOOTTYPE_NONE ;
LWONameValue extraInfo ;
bool forceDeletion = true ;
bool iLootTypeSourceIsDefault = false ;
LWOOBJID iLootTypeSource = LWOOBJID_EMPTY ;
bool iObjIDIsDefault = false ;
LWOOBJID iObjID ;
bool iObjTemplateIsDefault = false ;
LOT iObjTemplate = LOT_NULL ;
bool iRequestingObjIDIsDefault = false ;
LWOOBJID iRequestingObjID = LWOOBJID_EMPTY ;
bool iStackCountIsDefault = false ;
uint32_t iStackCount = 1 ;
bool iStackRemainingIsDefault = false ;
uint32_t iStackRemaining = 0 ;
bool iSubkeyIsDefault = false ;
LWOOBJID iSubkey = LWOOBJID_EMPTY ;
bool iTradeIDIsDefault = false ;
LWOOBJID iTradeID = LWOOBJID_EMPTY ;
inStream - > Read ( bConfirmed ) ;
inStream - > Read ( bDeleteItem ) ;
inStream - > Read ( bOutSuccess ) ;
inStream - > Read ( eInvTypeIsDefault ) ;
if ( eInvTypeIsDefault ) inStream - > Read ( eInvType ) ;
inStream - > Read ( eLootTypeSourceIsDefault ) ;
if ( eLootTypeSourceIsDefault ) inStream - > Read ( eLootTypeSource ) ;
inStream - > Read ( extraInfo . length ) ;
if ( extraInfo . length > 0 ) {
for ( uint32_t i = 0 ; i < extraInfo . length ; + + i ) {
uint16_t character ;
inStream - > Read ( character ) ;
extraInfo . name . push_back ( character ) ;
}
uint16_t nullTerm ;
inStream - > Read ( nullTerm ) ;
}
inStream - > Read ( forceDeletion ) ;
inStream - > Read ( iLootTypeSourceIsDefault ) ;
if ( iLootTypeSourceIsDefault ) inStream - > Read ( iLootTypeSource ) ;
inStream - > Read ( iObjIDIsDefault ) ;
if ( iObjIDIsDefault ) inStream - > Read ( iObjID ) ;
inStream - > Read ( iObjTemplateIsDefault ) ;
if ( iObjTemplateIsDefault ) inStream - > Read ( iObjTemplate ) ;
inStream - > Read ( iRequestingObjIDIsDefault ) ;
if ( iRequestingObjIDIsDefault ) inStream - > Read ( iRequestingObjID ) ;
inStream - > Read ( iStackCountIsDefault ) ;
if ( iStackCountIsDefault ) inStream - > Read ( iStackCount ) ;
inStream - > Read ( iStackRemainingIsDefault ) ;
if ( iStackRemainingIsDefault ) inStream - > Read ( iStackRemaining ) ;
inStream - > Read ( iSubkeyIsDefault ) ;
if ( iSubkeyIsDefault ) inStream - > Read ( iSubkey ) ;
inStream - > Read ( iTradeIDIsDefault ) ;
if ( iTradeIDIsDefault ) inStream - > Read ( iTradeID ) ;
2023-03-04 07:16:37 +00:00
InventoryComponent * inv = static_cast < InventoryComponent * > ( entity - > GetComponent ( eReplicaComponentType : : INVENTORY ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! inv ) return ;
auto * item = inv - > FindItemById ( iObjID ) ;
if ( item = = nullptr ) {
return ;
}
2022-07-17 07:35:11 +00:00
2022-04-14 09:09:40 +00:00
iStackCount = std : : min < uint32_t > ( item - > GetCount ( ) , iStackCount ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( bConfirmed ) {
2023-11-16 01:29:53 +00:00
if ( eInvType = = eInventoryType : : MODELS ) {
item - > DisassembleModel ( iStackCount ) ;
2021-12-05 17:54:36 +00:00
}
item - > SetCount ( item - > GetCount ( ) - iStackCount , true ) ;
2023-07-15 20:56:33 +00:00
Game : : entityManager - > SerializeEntity ( entity ) ;
2021-12-05 17:54:36 +00:00
auto * missionComponent = entity - > GetComponent < MissionComponent > ( ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( missionComponent ! = nullptr ) {
missionComponent - > Progress ( eMissionTaskType : : GATHER , item - > GetLot ( ) , LWOOBJID_EMPTY , " " , - iStackCount ) ;
}
}
}
2023-10-16 12:55:57 +00:00
void GameMessages : : SendSetGravityScale ( const LWOOBJID & target , const float effectScale , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( target ) ;
bitStream . Write ( eGameMessageType : : SET_GRAVITY_SCALE ) ;
bitStream . Write ( effectScale ) ;
SEND_PACKET ;
}
2021-12-05 17:54:36 +00:00
void GameMessages : : HandleMoveItemInInventory ( RakNet : : BitStream * inStream , Entity * entity ) {
bool destInvTypeIsDefault = false ;
int32_t destInvType = eInventoryType : : INVALID ;
LWOOBJID iObjID ;
int inventoryType ;
int responseCode ;
int slot ;
inStream - > Read ( destInvTypeIsDefault ) ;
if ( destInvTypeIsDefault ) { inStream - > Read ( destInvType ) ; }
inStream - > Read ( iObjID ) ;
inStream - > Read ( inventoryType ) ;
inStream - > Read ( responseCode ) ;
inStream - > Read ( slot ) ;
2023-03-04 07:16:37 +00:00
InventoryComponent * inv = static_cast < InventoryComponent * > ( entity - > GetComponent ( eReplicaComponentType : : INVENTORY ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! inv ) return ;
auto * item = inv - > FindItemById ( iObjID ) ;
if ( ! item ) {
return ;
}
inv - > MoveStack ( item , static_cast < eInventoryType > ( destInvType ) , slot ) ;
2023-07-15 20:56:33 +00:00
Game : : entityManager - > SerializeEntity ( entity ) ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandleMoveItemBetweenInventoryTypes ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2022-04-24 03:32:31 +00:00
eInventoryType inventoryTypeA ;
eInventoryType inventoryTypeB ;
2021-12-05 17:54:36 +00:00
LWOOBJID objectID ;
bool showFlyingLoot = true ;
bool stackCountIsDefault = false ;
uint32_t stackCount = 1 ;
bool templateIDIsDefault = false ;
LOT templateID = LOT_NULL ;
inStream - > Read ( inventoryTypeA ) ;
inStream - > Read ( inventoryTypeB ) ;
inStream - > Read ( objectID ) ;
inStream - > Read ( showFlyingLoot ) ;
inStream - > Read ( stackCountIsDefault ) ;
if ( stackCountIsDefault ) inStream - > Read ( stackCount ) ;
inStream - > Read ( templateIDIsDefault ) ;
if ( templateIDIsDefault ) inStream - > Read ( templateID ) ;
2022-04-24 03:32:31 +00:00
auto inv = entity - > GetComponent < InventoryComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( ! inv ) return ;
auto * item = inv - > FindItemById ( objectID ) ;
2022-07-06 06:18:04 +00:00
if ( ! item ) {
// Attempt to find the item by lot in inventory A since A is the source inventory.
item = inv - > FindItemByLot ( templateID , static_cast < eInventoryType > ( inventoryTypeA ) ) ;
if ( ! item ) {
// As a final resort, try to find the item in its default inventory based on type.
item = inv - > FindItemByLot ( templateID ) ;
if ( ! item ) {
return ;
}
2021-12-05 17:54:36 +00:00
}
}
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( entity - > GetCharacter ( ) ) {
if ( entity - > GetCharacter ( ) - > GetBuildMode ( ) ) {
showFlyingLoot = false ;
}
}
2022-04-24 03:32:31 +00:00
inv - > MoveItemToInventory ( item , inventoryTypeB , stackCount , showFlyingLoot ) ;
2023-07-15 20:56:33 +00:00
Game : : entityManager - > SerializeEntity ( entity ) ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandleBuildModeSet ( RakNet : : BitStream * inStream , Entity * entity ) {
bool bStart = false ;
inStream - > Read ( bStart ) ;
// there's more here but we don't need it (for now?)
2023-10-21 23:31:55 +00:00
LOG ( " Set build mode to (%d) for (%llu) " , bStart , entity - > GetObjectID ( ) ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( entity - > GetCharacter ( ) ) {
entity - > GetCharacter ( ) - > SetBuildMode ( bStart ) ;
}
}
void GameMessages : : HandleModularBuildFinish ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
User * user = UserManager : : Instance ( ) - > GetUser ( sysAddr ) ;
if ( ! user ) return ;
2023-07-15 20:56:33 +00:00
Entity * character = Game : : entityManager - > GetEntity ( user - > GetLoggedInChar ( ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! character ) return ;
2023-03-04 07:16:37 +00:00
InventoryComponent * inv = static_cast < InventoryComponent * > ( character - > GetComponent ( eReplicaComponentType : : INVENTORY ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! inv ) return ;
uint8_t count ; // 3 for rockets, 7 for cars
inStream - > Read ( count ) ;
auto * temp = inv - > GetInventory ( TEMP_MODELS ) ;
std : : vector < LOT > modList ;
2022-12-31 19:44:09 +00:00
auto & oldPartList = character - > GetVar < std : : string > ( u " currentModifiedBuild " ) ;
bool everyPieceSwapped = ! oldPartList . empty ( ) ; // If the player didn't put a build in initially, then they should not get this achievement.
2021-12-05 17:54:36 +00:00
if ( count > = 3 ) {
std : : u16string modules ;
for ( uint32_t k = 0 ; k < count ; k + + ) {
uint32_t mod ;
inStream - > Read ( mod ) ;
modList . push_back ( mod ) ;
2022-12-31 19:44:09 +00:00
auto modToStr = GeneralUtils : : to_u16string ( mod ) ;
modules + = u " 1: " + ( modToStr ) ;
2021-12-05 17:54:36 +00:00
if ( k + 1 ! = count ) modules + = u " + " ;
if ( temp - > GetLotCount ( mod ) > 0 ) {
inv - > RemoveItem ( mod , 1 , TEMP_MODELS ) ;
} else {
inv - > RemoveItem ( mod , 1 ) ;
}
2022-12-31 19:44:09 +00:00
// Doing this check for 1 singular mission that needs to know when you've swapped every part out during a car modular build.
// since all 8129's are the same, skip checking that
if ( mod ! = 8129 ) {
if ( oldPartList . find ( GeneralUtils : : UTF16ToWTF8 ( modToStr ) ) ! = std : : string : : npos ) everyPieceSwapped = false ;
}
2021-12-05 17:54:36 +00:00
}
2023-11-16 01:32:30 +00:00
ObjectIDManager : : Instance ( ) - > RequestPersistentID ( [ = ] ( uint32_t newId ) {
LOG ( " Build finished " ) ;
GameMessages : : SendFinishArrangingWithItem ( character , entity - > GetObjectID ( ) ) ; // kick them from modular build
GameMessages : : SendModularBuildEnd ( character ) ; // i dont know if this does anything but DLUv2 did it
//inv->UnequipItem(inv->GetItemStackByLOT(6086, eInventoryType::ITEMS)); // take off the thinking cap
//Game::entityManager->SerializeEntity(entity);
const auto moduleAssembly = new LDFData < std : : u16string > ( u " assemblyPartLOTs " , modules ) ;
2021-12-05 17:54:36 +00:00
2023-11-16 01:32:30 +00:00
std : : vector < LDFBaseData * > config ;
config . push_back ( moduleAssembly ) ;
2021-12-05 17:54:36 +00:00
2023-11-16 01:32:30 +00:00
LWOOBJID newIdBig = newId ;
2023-11-08 18:18:02 +00:00
GeneralUtils : : SetBit ( newIdBig , eObjectBits : : CHARACTER ) ;
2023-11-16 01:32:30 +00:00
if ( count = = 3 ) {
inv - > AddItem ( 6416 , 1 , eLootSourceType : : QUICKBUILD , eInventoryType : : MODELS , config , LWOOBJID_EMPTY , true , false , newIdBig ) ;
} else if ( count = = 7 ) {
inv - > AddItem ( 8092 , 1 , eLootSourceType : : QUICKBUILD , eInventoryType : : MODELS , config , LWOOBJID_EMPTY , true , false , newIdBig ) ;
}
2021-12-05 17:54:36 +00:00
2023-11-16 01:32:30 +00:00
std : : unique_ptr < sql : : PreparedStatement > stmt ( Database : : CreatePreppedStmt ( " INSERT INTO ugc_modular_build (ugc_id, ldf_config, character_id) VALUES (?,?,?) " ) ) ;
stmt - > setUInt64 ( 1 , newIdBig ) ;
stmt - > setString ( 2 , GeneralUtils : : UTF16ToWTF8 ( modules ) ) ;
auto * pCharacter = character - > GetCharacter ( ) ;
pCharacter ? stmt - > setUInt ( 3 , pCharacter - > GetID ( ) ) : stmt - > setNull ( 3 , sql : : DataType : : BIGINT ) ;
stmt - > execute ( ) ;
2022-07-17 07:35:11 +00:00
2023-11-16 01:32:30 +00:00
auto * missionComponent = character - > GetComponent < MissionComponent > ( ) ;
if ( entity - > GetLOT ( ) ! = 9980 | | Game : : server - > GetZoneID ( ) ! = 1200 ) {
if ( missionComponent ! = nullptr ) {
missionComponent - > Progress ( eMissionTaskType : : SCRIPT , entity - > GetLOT ( ) , entity - > GetObjectID ( ) ) ;
if ( count > = 7 & & everyPieceSwapped ) missionComponent - > Progress ( eMissionTaskType : : RACING , LWOOBJID_EMPTY , ( LWOOBJID ) eRacingTaskParam : : MODULAR_BUILDING ) ;
}
2021-12-05 17:54:36 +00:00
}
2023-11-16 01:32:30 +00:00
ScriptComponent * script = static_cast < ScriptComponent * > ( entity - > GetComponent ( eReplicaComponentType : : SCRIPT ) ) ;
2021-12-05 17:54:36 +00:00
2023-11-16 01:32:30 +00:00
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( entity ) ) {
script - > OnModularBuildExit ( entity , character , count > = 3 , modList ) ;
}
2021-12-05 17:54:36 +00:00
2023-11-16 01:32:30 +00:00
// Move remaining temp models back to models
std : : vector < Item * > items ;
2021-12-05 17:54:36 +00:00
2023-11-16 01:32:30 +00:00
for ( const auto & pair : temp - > GetItems ( ) ) {
items . push_back ( pair . second ) ;
}
2021-12-05 17:54:36 +00:00
2023-11-16 01:32:30 +00:00
for ( auto * item : items ) {
inv - > MoveItemToInventory ( item , eInventoryType : : MODELS , item - > GetCount ( ) , false ) ;
}
} ) ;
2021-12-05 17:54:36 +00:00
}
}
void GameMessages : : HandleDoneArrangingWithItem ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
User * user = UserManager : : Instance ( ) - > GetUser ( sysAddr ) ;
if ( ! user ) return ;
2023-07-15 20:56:33 +00:00
Entity * character = Game : : entityManager - > GetEntity ( user - > GetLoggedInChar ( ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! character ) return ;
2023-03-04 07:16:37 +00:00
InventoryComponent * inv = static_cast < InventoryComponent * > ( character - > GetComponent ( eReplicaComponentType : : INVENTORY ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! inv ) return ;
/**
[ int ] - newSourceBAG
[ LWOOBJID ] - newSourceID
[ LOT ] - newSourceLOT
[ int ] - newSourceTYPE
[ LWOOBJID ] - newTargetID
[ LOT ] - newTargetLOT
[ int ] - newTargetTYPE
[ NiPoint3 ] - newTtargetPOS
[ int ] - oldItemBAG
[ LWOOBJID ] - oldItemID
[ LOT ] - oldItemLOT
[ int ] - oldItemTYPE
*/
int newSourceBAG = 0 ;
LWOOBJID newSourceID = 0 ;
LOT newSourceLOT = 0 ;
int newSourceTYPE = 0 ;
LWOOBJID newTargetID = 0 ;
LOT newTargetLOT = 0 ;
int newTargetTYPE = 0 ;
NiPoint3 newTargetPOS ;
int oldItemBAG = 0 ;
LWOOBJID oldItemID = 0 ;
LOT oldItemLOT = 0 ;
int oldItemTYPE = 0 ;
inStream - > Read ( newSourceBAG ) ;
inStream - > Read ( newSourceID ) ;
inStream - > Read ( newSourceLOT ) ;
inStream - > Read ( newSourceTYPE ) ;
inStream - > Read ( newTargetID ) ;
inStream - > Read ( newTargetLOT ) ;
inStream - > Read ( newTargetTYPE ) ;
inStream - > Read ( newTargetPOS ) ;
inStream - > Read ( oldItemBAG ) ;
inStream - > Read ( oldItemID ) ;
inStream - > Read ( oldItemLOT ) ;
inStream - > Read ( oldItemTYPE ) ;
/*
2023-10-21 23:31:55 +00:00
LOG ( " GameMessages " ,
2022-07-25 02:26:51 +00:00
" \n newSourceBAG: %d \n newSourceID: %llu \n newSourceLOT: %d \n newSourceTYPE: %d \n newTargetID: %llu \n newTargetLOT: %d \n newTargetTYPE: %d \n newTargetPOS: %f, %f, %f \n oldItemBAG: %d \n oldItemID: %llu \n oldItemLOT: %d \n oldItemTYPE: %d " ,
2021-12-05 17:54:36 +00:00
newSourceBAG , newSourceID , newSourceLOT , newSourceTYPE , newTargetID , newTargetLOT , newTargetTYPE , newTargetPOS . x , newTargetPOS . y , newTargetPOS . z , oldItemBAG , oldItemID , oldItemLOT , oldItemTYPE
) ;
*/
if ( PropertyManagementComponent : : Instance ( ) ! = nullptr ) {
2023-07-15 20:56:33 +00:00
const auto & buildAreas = Game : : entityManager - > GetEntitiesByComponent ( eReplicaComponentType : : BUILD_BORDER ) ;
2022-07-17 07:35:11 +00:00
2023-07-15 20:56:33 +00:00
const auto & entities = Game : : entityManager - > GetEntitiesInGroup ( " PropertyPlaque " ) ;
2021-12-05 17:54:36 +00:00
Entity * buildArea ;
if ( ! buildAreas . empty ( ) ) {
buildArea = buildAreas [ 0 ] ;
} else if ( ! entities . empty ( ) ) {
buildArea = entities [ 0 ] ;
2022-07-17 07:35:11 +00:00
2023-10-21 23:31:55 +00:00
LOG ( " Using PropertyPlaque " ) ;
2021-12-05 17:54:36 +00:00
} else {
2023-10-21 23:31:55 +00:00
LOG ( " No build area found " ) ;
2021-12-05 17:54:36 +00:00
return ;
}
2023-10-21 23:31:55 +00:00
LOG ( " Build area found: %llu " , buildArea - > GetObjectID ( ) ) ;
2021-12-05 17:54:36 +00:00
GameMessages : : SendStartArrangingWithItem (
character ,
character - > GetSystemAddress ( ) ,
false ,
buildArea - > GetObjectID ( ) ,
character - > GetPosition ( ) ,
newSourceBAG ,
newSourceID ,
newSourceLOT ,
newSourceTYPE ,
newTargetID ,
newTargetLOT ,
newTargetPOS ,
newTargetTYPE
) ;
}
2023-10-21 23:31:55 +00:00
LOG ( " Done Arranging " ) ;
2021-12-05 17:54:36 +00:00
//GenericInventory* models = inv->GetGenericInventory(MODELS);
//GenericInventory* tempModels = inv->GetGenericInventory(TEMP_MODELS);
auto * inventory = inv - > GetInventory ( TEMP_MODELS ) ;
std : : vector < Item * > items ;
for ( const auto & pair : inventory - > GetItems ( ) ) {
items . push_back ( pair . second ) ;
}
for ( auto * item : items ) {
2022-04-24 03:32:31 +00:00
inv - > MoveItemToInventory ( item , eInventoryType : : MODELS , item - > GetCount ( ) , false , false ) ;
2021-12-05 17:54:36 +00:00
}
}
void GameMessages : : HandleModularBuildMoveAndEquip ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
User * user = UserManager : : Instance ( ) - > GetUser ( sysAddr ) ;
if ( ! user ) return ;
2023-07-15 20:56:33 +00:00
Entity * character = Game : : entityManager - > GetEntity ( user - > GetLoggedInChar ( ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! character ) return ;
2023-10-21 23:31:55 +00:00
LOG ( " Build and move " ) ;
2021-12-05 17:54:36 +00:00
LOT templateID ;
inStream - > Read ( templateID ) ;
2023-03-04 07:16:37 +00:00
InventoryComponent * inv = static_cast < InventoryComponent * > ( character - > GetComponent ( eReplicaComponentType : : INVENTORY ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! inv ) return ;
auto * item = inv - > FindItemByLot ( templateID , TEMP_MODELS ) ;
if ( item = = nullptr ) {
return ;
}
2022-04-24 03:32:31 +00:00
inv - > MoveItemToInventory ( item , eInventoryType : : MODELS , 1 , false , true ) ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandlePickupItem ( RakNet : : BitStream * inStream , Entity * entity ) {
LWOOBJID lootObjectID ;
LWOOBJID playerID ;
inStream - > Read ( lootObjectID ) ;
inStream - > Read ( playerID ) ;
entity - > PickupItem ( lootObjectID ) ;
auto * team = TeamManager : : Instance ( ) - > GetTeam ( entity - > GetObjectID ( ) ) ;
if ( team ! = nullptr ) {
for ( const auto memberId : team - > members ) {
2023-07-15 20:56:33 +00:00
auto * member = Game : : entityManager - > GetEntity ( memberId ) ;
2021-12-05 17:54:36 +00:00
if ( member = = nullptr | | memberId = = playerID ) continue ;
SendTeamPickupItem ( lootObjectID , lootObjectID , playerID , member - > GetSystemAddress ( ) ) ;
}
}
}
void GameMessages : : HandleResurrect ( RakNet : : BitStream * inStream , Entity * entity ) {
2022-07-23 02:58:20 +00:00
bool immediate = inStream - > ReadBit ( ) ;
2021-12-05 17:54:36 +00:00
2023-07-15 20:56:33 +00:00
Entity * zoneControl = Game : : entityManager - > GetZoneControlEntity ( ) ;
2022-07-23 02:58:20 +00:00
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( zoneControl ) ) {
script - > OnPlayerResurrected ( zoneControl , entity ) ;
}
2021-12-05 17:54:36 +00:00
2023-07-15 20:56:33 +00:00
std : : vector < Entity * > scriptedActs = Game : : entityManager - > GetEntitiesByComponent ( eReplicaComponentType : : SCRIPTED_ACTIVITY ) ;
2022-07-23 02:58:20 +00:00
for ( Entity * scriptEntity : scriptedActs ) {
if ( scriptEntity - > GetObjectID ( ) ! = zoneControl - > GetObjectID ( ) ) { // Don't want to trigger twice on instance worlds
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( scriptEntity ) ) {
script - > OnPlayerResurrected ( scriptEntity , entity ) ;
}
}
}
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandlePushEquippedItemsState ( RakNet : : BitStream * inStream , Entity * entity ) {
2023-03-04 07:16:37 +00:00
InventoryComponent * inv = static_cast < InventoryComponent * > ( entity - > GetComponent ( eReplicaComponentType : : INVENTORY ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! inv ) return ;
inv - > PushEquippedItems ( ) ;
}
void GameMessages : : HandlePopEquippedItemsState ( RakNet : : BitStream * inStream , Entity * entity ) {
2023-03-04 07:16:37 +00:00
InventoryComponent * inv = static_cast < InventoryComponent * > ( entity - > GetComponent ( eReplicaComponentType : : INVENTORY ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! inv ) return ;
inv - > PopEquippedItems ( ) ;
2023-07-15 20:56:33 +00:00
Game : : entityManager - > SerializeEntity ( entity ) ; // so it updates on client side
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandleClientItemConsumed ( RakNet : : BitStream * inStream , Entity * entity ) {
LWOOBJID itemConsumed ;
inStream - > Read ( itemConsumed ) ;
2023-03-04 07:16:37 +00:00
auto * inventory = static_cast < InventoryComponent * > ( entity - > GetComponent ( eReplicaComponentType : : INVENTORY ) ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( inventory = = nullptr ) {
return ;
}
auto * item = inventory - > FindItemById ( itemConsumed ) ;
if ( item = = nullptr ) {
return ;
}
2022-12-19 08:07:43 +00:00
LOT itemLot = item - > GetLot ( ) ;
2021-12-05 17:54:36 +00:00
item - > Consume ( ) ;
2023-03-04 07:16:37 +00:00
auto * missions = static_cast < MissionComponent * > ( entity - > GetComponent ( eReplicaComponentType : : MISSION ) ) ;
2021-12-05 17:54:36 +00:00
if ( missions ! = nullptr ) {
2022-12-19 08:07:43 +00:00
missions - > Progress ( eMissionTaskType : : USE_ITEM , itemLot ) ;
2021-12-05 17:54:36 +00:00
}
}
void GameMessages : : HandleUseNonEquipmentItem ( RakNet : : BitStream * inStream , Entity * entity ) {
LWOOBJID itemConsumed ;
inStream - > Read ( itemConsumed ) ;
2022-07-17 07:35:11 +00:00
2023-03-04 07:16:37 +00:00
auto * inv = static_cast < InventoryComponent * > ( entity - > GetComponent ( eReplicaComponentType : : INVENTORY ) ) ;
2022-07-17 07:35:11 +00:00
2021-12-05 17:54:36 +00:00
if ( ! inv ) return ;
auto * item = inv - > FindItemById ( itemConsumed ) ;
2022-07-17 07:35:11 +00:00
2022-12-24 22:41:13 +00:00
if ( item ) item - > UseNonEquip ( item ) ;
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandleMatchRequest ( RakNet : : BitStream * inStream , Entity * entity ) {
LWOOBJID activator ;
//std::map<LWOOBJID, LWONameValue> additionalPlayers;
uint32_t playerChoicesLen ;
std : : string playerChoices ;
int type ;
int value ;
inStream - > Read ( activator ) ;
inStream - > Read ( playerChoicesLen ) ;
for ( uint32_t i = 0 ; i < playerChoicesLen ; + + i ) {
uint16_t character ;
inStream - > Read ( character ) ;
playerChoices . push_back ( character ) ;
}
if ( playerChoicesLen > 0 ) {
uint16_t nullTerm ;
inStream - > Read ( nullTerm ) ;
}
inStream - > Read ( type ) ;
inStream - > Read ( value ) ;
2023-07-15 20:56:33 +00:00
std : : vector < Entity * > scriptedActs = Game : : entityManager - > GetEntitiesByComponent ( eReplicaComponentType : : SCRIPTED_ACTIVITY ) ;
2021-12-05 17:54:36 +00:00
if ( type = = 0 ) { // join
if ( value ! = 0 ) {
for ( Entity * scriptedAct : scriptedActs ) {
2023-03-04 07:16:37 +00:00
ScriptedActivityComponent * comp = static_cast < ScriptedActivityComponent * > ( scriptedAct - > GetComponent ( eReplicaComponentType : : SCRIPTED_ACTIVITY ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! comp ) continue ;
if ( comp - > GetActivityID ( ) = = value ) {
comp - > PlayerJoin ( entity ) ;
}
}
} else {
}
} else if ( type = = 1 ) { // ready/unready
for ( Entity * scriptedAct : scriptedActs ) {
2023-03-04 07:16:37 +00:00
ScriptedActivityComponent * comp = static_cast < ScriptedActivityComponent * > ( scriptedAct - > GetComponent ( eReplicaComponentType : : SCRIPTED_ACTIVITY ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! comp ) continue ;
if ( comp - > PlayerIsInQueue ( entity ) ) {
comp - > PlayerReady ( entity , value ) ;
}
}
}
}
2022-07-23 02:58:20 +00:00
void GameMessages : : HandleGetHotPropertyData ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
SendGetHotPropertyData ( inStream , entity , sysAddr ) ;
}
void GameMessages : : SendGetHotPropertyData ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
/**
* [ u32 ] - Number of properties
* [ objid ] - property id
* [ objid ] - property owner id
* [ wstring ] - property owner name
* [ u64 ] - total reputation
* [ i32 ] - property template id
* [ wstring ] - property name
* [ wstring ] - property description
* [ float ] - performance cost
* [ timestamp ] - time last published
* [ cloneid ] - clone id
2022-07-25 02:26:51 +00:00
*
2022-07-23 02:58:20 +00:00
*/
// TODO This needs to be implemented when reputation is implemented for getting hot properties.
/**
bitStream . Write ( entity - > GetObjectID ( ) ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SEND_HOT_PROPERTY_DATA ) ;
2022-07-23 02:58:20 +00:00
std : : vector < int32_t > t = { 25166 , 25188 , 25191 , 25194 } ;
bitStream . Write < uint32_t > ( 4 ) ;
for ( uint8_t i = 0 ; i < 4 ; i + + ) {
bitStream . Write < LWOOBJID > ( entity - > GetObjectID ( ) ) ;
bitStream . Write < LWOOBJID > ( entity - > GetObjectID ( ) ) ;
bitStream . Write < uint32_t > ( 1 ) ;
bitStream . Write < uint16_t > ( ' c ' ) ;
bitStream . Write < uint64_t > ( 42069 ) ;
bitStream . Write < int32_t > ( t [ i ] ) ;
bitStream . Write < uint32_t > ( 1 ) ;
bitStream . Write < uint16_t > ( ' c ' ) ;
bitStream . Write < uint32_t > ( 1 ) ;
bitStream . Write < uint16_t > ( ' c ' ) ;
bitStream . Write < float > ( 420.69f ) ;
bitStream . Write < uint64_t > ( 1658376385 ) ;
bitStream . Write < int32_t > ( 25166 ) ;
}
SEND_PACKET */
}
2021-12-05 17:54:36 +00:00
void GameMessages : : HandleReportBug ( RakNet : : BitStream * inStream , Entity * entity ) {
//Definitely not stolen from autogenerated code, no sir:
std : : u16string body ;
std : : string clientVersion ;
std : : string nOtherPlayerID ;
std : : string selection ;
uint32_t messageLength ;
2022-03-31 10:20:13 +00:00
int32_t reporterID = 0 ;
2021-12-05 17:54:36 +00:00
//Reading:
inStream - > Read ( messageLength ) ;
for ( uint32_t i = 0 ; i < ( messageLength ) ; + + i ) {
uint16_t character ;
inStream - > Read ( character ) ;
body . push_back ( character ) ;
}
2022-03-21 03:28:26 +00:00
auto character = entity - > GetCharacter ( ) ;
2022-03-21 03:46:34 +00:00
if ( character ) reporterID = character - > GetID ( ) ;
2022-03-21 03:28:26 +00:00
2021-12-05 17:54:36 +00:00
uint32_t clientVersionLength ;
inStream - > Read ( clientVersionLength ) ;
for ( unsigned int k = 0 ; k < clientVersionLength ; k + + ) {
unsigned char character ;
inStream - > Read ( character ) ;
clientVersion . push_back ( character ) ;
}
uint32_t nOtherPlayerIDLength ;
inStream - > Read ( nOtherPlayerIDLength ) ;
for ( unsigned int k = 0 ; k < nOtherPlayerIDLength ; k + + ) {
unsigned char character ;
inStream - > Read ( character ) ;
nOtherPlayerID . push_back ( character ) ;
}
2022-03-21 03:28:26 +00:00
// Convert other player id from LWOOBJID to the database id.
2022-03-31 10:20:13 +00:00
uint32_t otherPlayer = LWOOBJID_EMPTY ;
if ( nOtherPlayerID ! = " " ) otherPlayer = std : : atoi ( nOtherPlayerID . c_str ( ) ) ;
2021-12-05 17:54:36 +00:00
uint32_t selectionLength ;
inStream - > Read ( selectionLength ) ;
for ( unsigned int k = 0 ; k < selectionLength ; k + + ) {
unsigned char character ;
inStream - > Read ( character ) ;
selection . push_back ( character ) ;
}
try {
2022-03-21 03:46:34 +00:00
sql : : PreparedStatement * insertBug = Database : : CreatePreppedStmt ( " INSERT INTO `bug_reports`(body, client_version, other_player_id, selection, reporter_id) VALUES (?, ?, ?, ?, ?) " ) ;
2021-12-05 17:54:36 +00:00
insertBug - > setString ( 1 , GeneralUtils : : UTF16ToWTF8 ( body ) ) ;
insertBug - > setString ( 2 , clientVersion ) ;
2022-03-31 10:20:13 +00:00
insertBug - > setString ( 3 , std : : to_string ( otherPlayer ) ) ;
2021-12-05 17:54:36 +00:00
insertBug - > setString ( 4 , selection ) ;
2022-03-21 03:46:34 +00:00
insertBug - > setInt ( 5 , reporterID ) ;
2021-12-05 17:54:36 +00:00
insertBug - > execute ( ) ;
delete insertBug ;
} catch ( sql : : SQLException & e ) {
2023-10-21 23:31:55 +00:00
LOG ( " Couldn't save bug report! (%s) " , e . what ( ) ) ;
2021-12-05 17:54:36 +00:00
}
}
void
GameMessages : : HandleClientRailMovementReady ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2023-07-15 20:56:33 +00:00
const auto possibleRails = Game : : entityManager - > GetEntitiesByComponent ( eReplicaComponentType : : RAIL_ACTIVATOR ) ;
2022-07-23 02:58:20 +00:00
for ( const auto * possibleRail : possibleRails ) {
const auto * rail = possibleRail - > GetComponent < RailActivatorComponent > ( ) ;
if ( rail ! = nullptr ) {
rail - > OnRailMovementReady ( entity ) ;
}
}
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandleCancelRailMovement ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
2022-07-23 02:58:20 +00:00
const auto immediate = inStream - > ReadBit ( ) ;
2021-12-05 17:54:36 +00:00
2023-07-15 20:56:33 +00:00
const auto possibleRails = Game : : entityManager - > GetEntitiesByComponent ( eReplicaComponentType : : RAIL_ACTIVATOR ) ;
2022-07-23 02:58:20 +00:00
for ( const auto * possibleRail : possibleRails ) {
auto * rail = possibleRail - > GetComponent < RailActivatorComponent > ( ) ;
if ( rail ! = nullptr ) {
rail - > OnCancelRailMovement ( entity ) ;
}
}
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandlePlayerRailArrivedNotification ( RakNet : : BitStream * inStream , Entity * entity ,
const SystemAddress & sysAddr ) {
uint32_t pathNameLength ;
inStream - > Read ( pathNameLength ) ;
std : : u16string pathName ;
for ( auto k = 0 ; k < pathNameLength ; k + + ) {
uint16_t c ;
inStream - > Read ( c ) ;
pathName . push_back ( c ) ;
}
int32_t waypointNumber ;
inStream - > Read ( waypointNumber ) ;
2023-07-15 20:56:33 +00:00
const auto possibleRails = Game : : entityManager - > GetEntitiesByComponent ( eReplicaComponentType : : RAIL_ACTIVATOR ) ;
2021-12-05 17:54:36 +00:00
for ( auto * possibleRail : possibleRails ) {
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( possibleRail ) ) {
script - > OnPlayerRailArrived ( possibleRail , entity , pathName , waypointNumber ) ;
}
}
}
void GameMessages : : HandleModifyPlayerZoneStatistic ( RakNet : : BitStream * inStream , Entity * entity ) {
2022-07-23 02:58:20 +00:00
const auto set = inStream - > ReadBit ( ) ;
const auto statisticsName = GeneralUtils : : ReadWString ( inStream ) ;
int32_t value ;
if ( inStream - > ReadBit ( ) ) {
inStream - > Read < int32_t > ( value ) ;
} else {
value = 0 ;
}
LWOMAPID zone ;
if ( inStream - > ReadBit ( ) ) {
inStream - > Read < LWOMAPID > ( zone ) ;
} else {
zone = LWOMAPID_INVALID ;
}
// Notify the character component that something's changed
auto * characterComponent = entity - > GetComponent < CharacterComponent > ( ) ;
if ( characterComponent ! = nullptr ) {
characterComponent - > HandleZoneStatisticsUpdate ( zone , statisticsName , value ) ;
}
2021-12-05 17:54:36 +00:00
}
void GameMessages : : HandleUpdatePlayerStatistic ( RakNet : : BitStream * inStream , Entity * entity ) {
2022-07-23 02:58:20 +00:00
int32_t updateID ;
inStream - > Read < int32_t > ( updateID ) ;
int64_t updateValue ;
if ( inStream - > ReadBit ( ) ) {
inStream - > Read < int64_t > ( updateValue ) ;
} else {
updateValue = 1 ;
}
auto * characterComponent = entity - > GetComponent < CharacterComponent > ( ) ;
if ( characterComponent ! = nullptr ) {
characterComponent - > UpdatePlayerStatistic ( ( StatisticID ) updateID , ( uint64_t ) std : : max ( updateValue , int64_t ( 0 ) ) ) ;
}
2021-12-05 17:54:36 +00:00
}
2023-01-07 06:14:51 +00:00
void GameMessages : : HandleDeactivateBubbleBuff ( RakNet : : BitStream * inStream , Entity * entity ) {
auto controllablePhysicsComponent = entity - > GetComponent < ControllablePhysicsComponent > ( ) ;
if ( controllablePhysicsComponent ) controllablePhysicsComponent - > DeactivateBubbleBuff ( ) ;
}
void GameMessages : : HandleActivateBubbleBuff ( RakNet : : BitStream * inStream , Entity * entity ) {
bool specialAnimations ;
if ( ! inStream - > Read ( specialAnimations ) ) return ;
std : : u16string type = GeneralUtils : : ReadWString ( inStream ) ;
auto bubbleType = eBubbleType : : DEFAULT ;
if ( type = = u " skunk " ) bubbleType = eBubbleType : : SKUNK ;
else if ( type = = u " energy " ) bubbleType = eBubbleType : : ENERGY ;
auto controllablePhysicsComponent = entity - > GetComponent < ControllablePhysicsComponent > ( ) ;
if ( controllablePhysicsComponent ) controllablePhysicsComponent - > ActivateBubbleBuff ( bubbleType , specialAnimations ) ;
}
void GameMessages : : SendActivateBubbleBuffFromServer ( LWOOBJID objectId , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : ACTIVATE_BUBBLE_BUFF_FROM_SERVER ) ;
2023-01-07 06:14:51 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
void GameMessages : : SendDeactivateBubbleBuffFromServer ( LWOOBJID objectId , const SystemAddress & sysAddr ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : DEACTIVATE_BUBBLE_BUFF_FROM_SERVER ) ;
2023-01-07 06:14:51 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST ;
SEND_PACKET ;
}
2023-03-23 14:49:31 +00:00
2023-03-25 10:26:39 +00:00
void GameMessages : : HandleZoneSummaryDismissed ( RakNet : : BitStream * inStream , Entity * entity ) {
LWOOBJID player_id ;
inStream - > Read < LWOOBJID > ( player_id ) ;
2023-07-15 20:56:33 +00:00
auto target = Game : : entityManager - > GetEntity ( player_id ) ;
2023-03-25 10:26:39 +00:00
entity - > TriggerEvent ( eTriggerEventType : : ZONE_SUMMARY_DISMISSED , target ) ;
} ;
2023-03-23 14:49:31 +00:00
void GameMessages : : SendSetNamebillboardState ( const SystemAddress & sysAddr , LWOOBJID objectId ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SET_NAME_BILLBOARD_STATE ) ;
2023-03-23 14:49:31 +00:00
// Technically these bits would be written, however the client does not
// contain a deserialize method to actually deserialize, so we are leaving it out.
// As such this GM only turns the billboard off.
// bitStream.Write(overrideDefault);
// bitStream.Write(state);
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST
else SEND_PACKET
}
void GameMessages : : SendShowBillboardInteractIcon ( const SystemAddress & sysAddr , LWOOBJID objectId ) {
CBITSTREAM ;
CMSGHEADER ;
bitStream . Write ( objectId ) ;
2023-05-03 21:38:32 +00:00
bitStream . Write ( eGameMessageType : : SHOW_BILLBOARD_INTERACT_ICON ) ;
2023-03-23 14:49:31 +00:00
if ( sysAddr = = UNASSIGNED_SYSTEM_ADDRESS ) SEND_PACKET_BROADCAST
else SEND_PACKET
}
2023-05-11 00:26:04 +00:00
void GameMessages : : HandleRequestActivityExit ( RakNet : : BitStream * inStream , Entity * entity ) {
bool canceled = false ;
inStream - > Read ( canceled ) ;
if ( ! canceled ) return ;
LWOOBJID player_id = LWOOBJID_EMPTY ;
inStream - > Read ( player_id ) ;
2023-07-15 20:56:33 +00:00
auto player = Game : : entityManager - > GetEntity ( player_id ) ;
2023-05-11 00:26:04 +00:00
if ( ! entity | | ! player ) return ;
2023-05-11 14:23:48 +00:00
entity - > RequestActivityExit ( entity , player_id , canceled ) ;
2023-05-11 00:26:04 +00:00
}
2023-08-04 02:44:03 +00:00
void GameMessages : : HandleAddDonationItem ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
uint32_t count = 1 ;
bool hasCount = false ;
inStream - > Read ( hasCount ) ;
if ( hasCount ) inStream - > Read ( count ) ;
LWOOBJID itemId = LWOOBJID_EMPTY ;
inStream - > Read ( itemId ) ;
if ( ! itemId ) return ;
auto * donationVendorComponent = entity - > GetComponent < DonationVendorComponent > ( ) ;
if ( ! donationVendorComponent ) return ;
if ( donationVendorComponent - > GetActivityID ( ) = = 0 ) {
2023-10-21 23:31:55 +00:00
LOG ( " WARNING: Trying to dontate to a vendor with no activity " ) ;
2023-08-04 02:44:03 +00:00
return ;
}
User * user = UserManager : : Instance ( ) - > GetUser ( sysAddr ) ;
if ( ! user ) return ;
Entity * player = Game : : entityManager - > GetEntity ( user - > GetLoggedInChar ( ) ) ;
if ( ! player ) return ;
auto * characterComponent = player - > GetComponent < CharacterComponent > ( ) ;
if ( ! characterComponent ) return ;
auto * inventoryComponent = player - > GetComponent < InventoryComponent > ( ) ;
if ( ! inventoryComponent ) return ;
Item * item = inventoryComponent - > FindItemById ( itemId ) ;
if ( ! item ) return ;
if ( item - > GetCount ( ) < count ) return ;
characterComponent - > SetCurrentInteracting ( entity - > GetObjectID ( ) ) ;
inventoryComponent - > MoveItemToInventory ( item , eInventoryType : : DONATION , count , true , false , true ) ;
}
void GameMessages : : HandleRemoveDonationItem ( RakNet : : BitStream * inStream , Entity * entity , const SystemAddress & sysAddr ) {
bool confirmed = false ;
inStream - > Read ( confirmed ) ;
uint32_t count = 1 ;
bool hasCount = false ;
inStream - > Read ( hasCount ) ;
if ( hasCount ) inStream - > Read ( count ) ;
LWOOBJID itemId = LWOOBJID_EMPTY ;
inStream - > Read ( itemId ) ;
if ( ! itemId ) return ;
User * user = UserManager : : Instance ( ) - > GetUser ( sysAddr ) ;
if ( ! user ) return ;
Entity * player = Game : : entityManager - > GetEntity ( user - > GetLoggedInChar ( ) ) ;
if ( ! player ) return ;
auto * inventoryComponent = player - > GetComponent < InventoryComponent > ( ) ;
if ( ! inventoryComponent ) return ;
Item * item = inventoryComponent - > FindItemById ( itemId ) ;
if ( ! item ) return ;
if ( item - > GetCount ( ) < count ) return ;
inventoryComponent - > MoveItemToInventory ( item , eInventoryType : : BRICKS , count , true , false , true ) ;
}
void GameMessages : : HandleConfirmDonationOnPlayer ( RakNet : : BitStream * inStream , Entity * entity ) {
auto * inventoryComponent = entity - > GetComponent < InventoryComponent > ( ) ;
if ( ! inventoryComponent ) return ;
auto * missionComponent = entity - > GetComponent < MissionComponent > ( ) ;
if ( ! missionComponent ) return ;
auto * characterComponent = entity - > GetComponent < CharacterComponent > ( ) ;
if ( ! characterComponent | | ! characterComponent - > GetCurrentInteracting ( ) ) return ;
auto * donationEntity = Game : : entityManager - > GetEntity ( characterComponent - > GetCurrentInteracting ( ) ) ;
if ( ! donationEntity ) return ;
auto * donationVendorComponent = donationEntity - > GetComponent < DonationVendorComponent > ( ) ;
2023-10-16 12:55:57 +00:00
if ( ! donationVendorComponent ) return ;
2023-08-04 02:44:03 +00:00
if ( donationVendorComponent - > GetActivityID ( ) = = 0 ) {
2023-10-21 23:31:55 +00:00
LOG ( " WARNING: Trying to dontate to a vendor with no activity " ) ;
2023-08-04 02:44:03 +00:00
return ;
}
auto * inventory = inventoryComponent - > GetInventory ( eInventoryType : : DONATION ) ;
if ( ! inventory ) return ;
auto items = inventory - > GetItems ( ) ;
if ( ! items . empty ( ) ) {
uint32_t count = 0 ;
2023-10-16 12:55:57 +00:00
for ( auto & [ itemID , item ] : items ) {
2023-08-04 02:44:03 +00:00
count + = item - > GetCount ( ) ;
item - > RemoveFromInventory ( ) ;
}
missionComponent - > Progress ( eMissionTaskType : : DONATION , 0 , LWOOBJID_EMPTY , " " , count ) ;
LeaderboardManager : : SaveScore ( entity - > GetObjectID ( ) , donationVendorComponent - > GetActivityID ( ) , count ) ;
donationVendorComponent - > SubmitDonation ( count ) ;
Game : : entityManager - > SerializeEntity ( donationEntity ) ;
}
characterComponent - > SetCurrentInteracting ( LWOOBJID_EMPTY ) ;
}
void GameMessages : : HandleCancelDonationOnPlayer ( RakNet : : BitStream * inStream , Entity * entity ) {
auto * inventoryComponent = entity - > GetComponent < InventoryComponent > ( ) ;
if ( ! inventoryComponent ) return ;
auto * inventory = inventoryComponent - > GetInventory ( eInventoryType : : DONATION ) ;
if ( ! inventory ) return ;
auto items = inventory - > GetItems ( ) ;
2023-10-16 12:55:57 +00:00
for ( auto & [ itemID , item ] : items ) {
2023-08-04 02:44:03 +00:00
inventoryComponent - > MoveItemToInventory ( item , eInventoryType : : BRICKS , item - > GetCount ( ) , false , false , true ) ;
}
auto * characterComponent = entity - > GetComponent < CharacterComponent > ( ) ;
if ( ! characterComponent ) return ;
characterComponent - > SetCurrentInteracting ( LWOOBJID_EMPTY ) ;
}