uox3/source/cSocket.h
Xoduz e38be292e3 0.99.6d
Cleaned up an issue with last commit where wrong npclists were used in some spawn regions
Made a few additional adjustments to the new spawn regions in Lost Lands/New Haven
Included more changes related to poison updates that should've been in previous commit (like the complete UOX.INI support for POISONCORROSIONSYSTEM setting)
Adjusted region setup for New Haven to set the individual "building" regions within as a sub-region of the main town (regions.dfn)
Fixed an issue where the displayed HP of an equipped item would not update correctly
Further updates to convert timers 32-bit to 64-bit. This affects and addresses some potential issues with: Character creation/NPC guild-join timestamps, NPC movement, combat timers, idle timeouts, item decay, spellcasting
Added support for new JS Events that can trigger from global script, and can be used to store persistent custom entries in players' paperdoll profiles:
	onProfileRequest( socket, profileOwnerChar ) - Triggers when client requests data for a paperdoll profile
	onProfileUpdate( socket, updatedText ) - Triggers when client sends updated data from paperdoll profile
Added two new helper functions in code that allows faster (but very slightly less accurate) distance checks between two points: 	GetApproxDist( Point3_st a, Point3_st b )
	GetApproxDist( CBaseObject *a, CBaseObject *b )
Improved pathfinding for NPCs attempting to follow another character, by adopting a system of weighted variables to help the NPC determine when to recalculate the path vs when to stick with the old, combined with faster distance checks via GetApproxDist(). The end result of this is faster, smarter and more responsive NPC followers and NPC opponents in combat. The variables influencing this include: how far the target has moved from last pathfind target location, whether NPC is heading in the overall right direction or not, time since last path calculation and some small randomization to avoid edge case jitters.
Updated default command levels in commands.dfn, code and scripts to support the Seer role and make space for some custom roles. These are the new defaults as listed in commands.dfn, which should not be changed as they are linked to specific enums in code. Do take note that this might invalidate command levels for existing GMs/Seers/Counselors, who might need another round of 'make gm/seer/cns from an admin:
	ADMIN - command level 10
	GM - command level 9
	SEER - command level 7
	CNS - command level 4
	PLAYER - command level 0
Updated how UOX3 makes use of the account-level flags 0x2000 (Seer) and 0x4000 (Counselor). If either of these flags are set on an account, all new characters created on the accounts will automatically receive the relevant command privileges.
Fixed an issue with 'wholist command that prevented admin characters from seeing characters with lower privilege levels in the list (js/commands/wholist.js)
Fixed an issue with hiding/GM hide that prevented admin characters from seeing hidden characters with lower privilege levels in the world
UOX3 now includes the cross-platform, header-only utf8cpp library found at https://github.com/nemtrif/utfcpp and freely available under Boost Software License v1.0. The immediate use-case for this is in code right now is to better handle strings related to custom paperdoll profiles, but will also look to make more heavy use of this in future updates
2025-06-28 22:37:42 +08:00

379 lines
11 KiB
C++

#ifndef __CSOCKET_H__
#define __CSOCKET_H__
#include "IP4Address.hpp"
enum ClientTypes
{
CV_DEFAULT = 0,
CV_UNKNOWN,
CV_KRRIOS,
CV_T2A, // From 4.0.0p to 4.0.11c
CV_UO3D, // Third Dawn 3D client
CV_ML, // From 4.0.11f to 5.0.9.1
CV_KR2D, // From 6.0.0.0+ to 6.0.14.1, first packet sent is 0xEF.
CV_KR3D,
CV_SA2D, // From 6.0.14.2 to 7.0.8.2, Stygian Abyss expansion client. First patcket sent is 0xEF, requires 0xB9 size-change from 3 to 5, new 0xF3 packet replacex 0x1A
CV_SA3D,
CV_HS2D, // From 7.0.9.0 to 7.0.45.89, High Seas expansion client
CV_HS3D,
CV_TOL2D, // From 7.0.46.0 to infinity, Time of Legends expansion client (Endless Journey "started" at 7.0.61.0, but it's not an expansion)
CV_TOL3D,
CV_COUNT
};
// Only client-versions with major packet changes included. Clients between two versions "belong" to the nearest previous version
enum ClientVersions
{
CVS_DEFAULT = 0,
CVS_400,
CVS_407a,
CVS_4011c,
CVS_500a, // map0.mul size increased from 6144x4096 to 7168x4096
CVS_502a,
CVS_5082,
CVS_6000, // Felucca/Trammel no longer both use map0.mul, Trammel gets its own: map1.mul
CVS_6017, // Packet updates to support container-grid in KR client, support implemented so it (in theory) will have no effect on lower versions
CVS_6050, // 21 extra bytes of data added prior to initial 0x80 packet, in the form of a new clientversion packet: 0xEF
CVS_25302, // UOKR3D 2.53.0.2
CVS_60142,
CVS_7000, // animation packet 0xE2 replaces 0x6E, packet 0xF3 is sent instead of 0x1A (object information packet)
CVS_7090,
CVS_70130, // Packet 0xA9 updated with extra information and longer City/Building names
CVS_70151,
CVS_70160, // Packet 0xF8 (New Character Creation) replaces 0x00 (Character Creation)
CVS_70240, // Map#.mul files are now wrapped in .uop headers. This means incompability with tools, and updated emulators needed to read map correctly.
CVS_70300,
CVS_70331,
CVS_704565,
CVS_705527, // Max update range increase from 18 to 24
CVS_70610,
CVS_COUNT
};
enum cS_TID
{
// PC Timers
tPC_SKILLDELAY = 0,
tPC_OBJDELAY,
tPC_SPIRITSPEAK,
tPC_TRACKING,
tPC_FISHING,
tPC_MUTETIME,
tPC_TRACKINGDISPLAY,
tPC_TRAFFICWARDEN,
tPC_COUNT
};
class CSocket
{
public:
// Account Related Member(s)
CAccountBlock_st& GetAccount( void );
void SetAccount( CAccountBlock_st& actbBlock );
void InternalReset( void );
Ip4Addr_st ipaddress;
private:
std::vector<UI16> trigWords;
std::vector<UI16>::iterator twIter;
UI16 accountNum;
CChar * currCharObj;
TIMERVAL idleTimeout;
bool wasIdleWarned;
bool objDelayMsgShown;
bool skillDelayMsgShown;
TIMERVAL negotiateTimeout;
bool negotiatedWithAssistant;
UI08 buffer[MAXBUFFER];
UI08 outbuffer[MAXBUFFER];
// These vectors are for dealing with packets that are larger than the buffer size
// While admittedly not thread friendly, the number of times these buffers are used
// should be very small and right now, is an implementation that will increase clieht
// compatability
std::vector<UI08> largeBuffer;
std::vector<UI08> largePackBuffer;
std::string xtext;
std::string xtext2;
SI16 clickx;
SI16 clicky;
SI08 clickz;
UI08 currentSpellType;
SI32 outlength;
SI32 inlength;
bool logging;
UI08 range;
bool cryptclient;
size_t cliSocket; // client
SI16 walkSequence;
size_t postAckCount;
PickupLocations pSpot;
SERIAL pFrom;
GenericList<CItem *> contsOpened;
SI16 pX;
SI16 pY;
SI08 pZ;
UnicodeTypes lang;
ClientTypes cliType;
ClientVersions cliVerShort;
UI32 clientVersion;
UI32 bytesReceived;
UI32 bytesSent;
bool receivedVersion;
// Temporary variables (For targeting commands, etc)
CBaseObject * tmpObj;
CBaseObject * tmpObj2;
SI32 tempint;
SI32 tempint2;
UI08 dyeall;
UI08 addid[4];
bool newClient;
bool firstPacket;
bool forceOffline;
UI08 clientip[4];
bool loginComplete;
CItem * cursorItem; //pointer to item held on mouse cursor
UI16 bytesRecvWarningCount;
UI16 bytesSentWarningCount;
bool targetok;
std::vector<SERIAL> postAcked;
std::vector<SERIAL>::iterator ackIter;
UI32 Pack( void *pvIn, void *pvOut, SI32 len );
// Timer Vals moved here from CChar due to their inherently temporary nature and to reduce wasted memory
TIMERVAL pcTimers[tPC_COUNT];
public:
CSocket( size_t sockNum );
~CSocket();
UI32 ClientVersion( void ) const;
void ClientVersion( UI32 newVer );
void ClientVersion( UI08 major, UI08 minor, UI08 sub, UI08 letter );
void ClientVersionMajor( UI08 value );
void ClientVersionMinor( UI08 value );
void ClientVersionSub( UI08 value );
void ClientVersionLetter( UI08 value );
UI08 ClientVersionMajor( void ) const;
UI08 ClientVersionMinor( void ) const;
UI08 ClientVersionSub( void ) const;
UI08 ClientVersionLetter( void ) const;
ClientVersions ClientVerShort( void ) const;
void ClientVerShort( ClientVersions newVer );
ClientTypes ClientType( void ) const;
void ClientType( ClientTypes newVer );
void ClearPage( void );
void AddTrigWord( UI16 );
// Accessors
bool LoginComplete( void ) const;
CItem * GetCursorItem( void ) const;
void SetCursorItem( CItem *newValue );
SI16 PickupX( void ) const;
SI16 PickupY( void ) const;
SI08 PickupZ( void ) const;
PickupLocations PickupSpot( void ) const;
SERIAL PickupSerial( void ) const;
bool FirstPacket( void ) const;
TIMERVAL IdleTimeout( void ) const;
bool WasIdleWarned( void ) const;
bool ObjDelayMsgShown( void ) const;
bool SkillDelayMsgShown( void ) const;
TIMERVAL NegotiateTimeout( void ) const;
bool NegotiatedWithAssistant( void ) const;
UI08 * Buffer( void );
UI08 * OutBuffer( void );
SI16 WalkSequence( void ) const;
UI16 AcctNo( void ) const;
std::string XText( void );
std::string XText2( void );
bool CryptClient( void ) const;
size_t CliSocket( void ) const;
UI08 CurrentSpellType( void ) const;
SI32 OutLength( void ) const;
SI32 InLength( void ) const;
bool Logging( void ) const;
CChar * CurrcharObj( void ) const;
UI08 ClientIP1( void ) const;
UI08 ClientIP2( void ) const;
UI08 ClientIP3( void ) const;
UI08 ClientIP4( void ) const;
bool NewClient( void ) const;
bool TargetOK( void ) const;
UI16 FirstTrigWord( void );
UI16 NextTrigWord( void );
bool FinishedTrigWords( void );
void ClearTrigWords( void );
bool ForceOffline( void ) const;
// Temporary Variables
CBaseObject * TempObj( void ) const;
CBaseObject * TempObj2( void ) const;
SI32 TempInt( void ) const;
SI32 TempInt2( void ) const;
UI32 AddId( void ) const;
UI08 AddId1( void ) const;
UI08 AddId2( void ) const;
UI08 AddId3( void ) const;
UI08 AddId4( void ) const;
UI08 DyeAll( void ) const;
SI08 ClickZ( void ) const;
SERIAL FirstPostAck( void );
SERIAL NextPostAck( void );
bool FinishedPostAck( void );
SERIAL RemovePostAck( void );
size_t PostCount( void ) const;
size_t PostAckCount( void ) const;
SI16 ClickX( void ) const;
SI16 ClickY( void ) const;
UI08 Range( void ) const;
void CloseSocket( void );
// Mutators
void LoginComplete( bool newVal );
void PickupLocation( SI16 x, SI16 y, SI08 z );
void PickupX( SI16 x );
void PickupY( SI16 y );
void PickupZ( SI08 z );
void PickupSpot( PickupLocations newValue );
void PickupSerial( SERIAL pickupSerial );
void FirstPacket( bool newValue );
void IdleTimeout( TIMERVAL newValue );
void WasIdleWarned( bool value );
void ObjDelayMsgShown( bool value );
void SkillDelayMsgShown( bool value );
void NegotiateTimeout( TIMERVAL newValue );
void NegotiatedWithAssistant( bool value );
void WalkSequence( SI16 newValue );
void AcctNo( UI16 newValue );
void CryptClient( bool newValue );
void CliSocket( size_t newValue );
void CurrentSpellType( UI08 newValue );
void OutLength( SI32 newValue );
void InLength( SI32 newValue );
void Logging( bool newValue );
void CurrcharObj( CChar *newValue );
void ClientIP1( UI08 );
void ClientIP2( UI08 newValue );
void ClientIP3( UI08 newValue );
void ClientIP4( UI08 newValue );
void NewClient( bool newValue );
void Range( UI08 value );
void ForceOffline( bool newValue );
// Temporary Variables
// Under protest I add, NEVER NEVER Do this
cScript *scriptForCallBack;
// Get rid of above as soon as possible, horible.
void TempObj( CBaseObject *newValue );
void TempObj2( CBaseObject *newValue );
void TempInt( SI32 newValue );
void TempInt2( SI32 newValue );
void AddId( UI32 newValue );
void AddId1( UI08 newValue );
void AddId2( UI08 newValue );
void AddId3( UI08 newValue );
void AddId4( UI08 newValue );
void DyeAll( UI08 newValue );
void ClickZ( SI08 newValue );
bool FlushBuffer( bool doLog = true );
bool FlushLargeBuffer( bool doLog = true );
void FlushIncoming( void );
void Send( const void *point, SI32 length );
SI32 Receive( SI32 x, bool doLog = true );
void ReceiveLogging( CPInputBuffer *toLog );
UI32 GetDWord( size_t offset );
UI16 GetWord( size_t offset );
UI08 GetByte( size_t offset );
void SetDWord( size_t offset, UI32 newValue );
void SetWord( size_t offset, UI16 newValue );
void SetByte( size_t offset, UI08 newValue );
void ClientIP( UI32 newValue );
void TargetOK( bool newValue );
void ClickX( SI16 newValue );
void ClickY( SI16 newValue );
void PostAcked( SERIAL newValue );
void PostAckCount( size_t newValue );
void PostClear();
void XText( const std::string &newValue );
void XText2( const std::string &newValue );
void Send( CPUOXBuffer *toSend );
UnicodeTypes Language( void ) const;
void Language( UnicodeTypes newVal );
void SysMessage( const std::string txt, ... );
void SysMessageJS( const std::string& uformat, UI16 txtColor, const std::string& data );
void SysMessage( SI32 dictEntry, ... );
void ObjMessage( const std::string& txt, CBaseObject *getObj, R32 secsFromNow = 0.0f, UI16 Color = 0x03B2 );
void ObjMessage( SI32 dictEntry, CBaseObject *getObj, R32 secsFromNow = 0.0f, UI32 Color = 0x03B2, ... );
void ShowCharName( CChar *i, bool showSer );
void SendTargetCursor( UI08 targType, UI08 targId, const std::string& txt, UI08 cursorType = 0 );
void SendTargetCursor( UI08 targType, UI08 targId, UI08 cursorType, SI32 dictEntry, ... );
void mtarget( UI16 itemId, SI32 dictEntry );
void StatWindow( CBaseObject *i, bool updateParty = true );
void UpdateSkill( UI08 skillnum );
void OpenPack( CItem *i, bool isPlayerVendor = false );
void OpenBank( CChar *i );
void OpenURL( const std::string& txt );
auto GetContsOpenedList() -> GenericList<CItem *> *;
bool ReceivedVersion( void ) const;
void ReceivedVersion( bool value );
UI32 BytesSent( void ) const;
void BytesSent( UI32 newValue );
UI32 BytesReceived( void ) const;
void BytesReceived( UI32 newValue );
UI16 BytesReceivedWarning( void ) const;
void BytesReceivedWarning( UI16 newValue );
UI16 BytesSentWarning( void ) const;
void BytesSentWarning( UI16 newValue );
TIMERVAL GetTimer( cS_TID timerId ) const;
void SetTimer( cS_TID timerId, TIMERVAL value );
void ClearTimers( void );
COLOUR GetFlagColour( CChar *src, CChar *trg );
auto GetHtmlFlagColour( CChar *src, CChar *trg ) -> std::string;
private:
};
#endif