mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 18:51:29 +00:00
Added ClientVersion request system to UCS server (needed to fix saylinks)
This commit is contained in:
parent
361937d443
commit
6c2a8edea6
@ -28,7 +28,7 @@
|
|||||||
namespace EQEmu
|
namespace EQEmu
|
||||||
{
|
{
|
||||||
namespace versions {
|
namespace versions {
|
||||||
enum class ClientVersion {
|
enum class ClientVersion : uint32 {
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
Client62, // Build: 'Aug 4 2005 15:40:59'
|
Client62, // Build: 'Aug 4 2005 15:40:59'
|
||||||
Titanium, // Build: 'Oct 31 2005 10:33:37'
|
Titanium, // Build: 'Oct 31 2005 10:33:37'
|
||||||
@ -72,7 +72,7 @@ namespace EQEmu
|
|||||||
uint32 ConvertClientVersionToExpansion(ClientVersion client_version);
|
uint32 ConvertClientVersionToExpansion(ClientVersion client_version);
|
||||||
|
|
||||||
|
|
||||||
enum class MobVersion {
|
enum class MobVersion : uint32 {
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
Client62,
|
Client62,
|
||||||
Titanium,
|
Titanium,
|
||||||
|
|||||||
@ -613,6 +613,8 @@ RULE_INT(Chat, IntervalDurationMS, 60000)
|
|||||||
RULE_INT(Chat, KarmaUpdateIntervalMS, 1200000)
|
RULE_INT(Chat, KarmaUpdateIntervalMS, 1200000)
|
||||||
RULE_INT(Chat, KarmaGlobalChatLimit, 72) //amount of karma you need to be able to talk in ooc/auction/chat below the level limit
|
RULE_INT(Chat, KarmaGlobalChatLimit, 72) //amount of karma you need to be able to talk in ooc/auction/chat below the level limit
|
||||||
RULE_INT(Chat, GlobalChatLevelLimit, 8) //level limit you need to of reached to talk in ooc/auction/chat if your karma is too low.
|
RULE_INT(Chat, GlobalChatLevelLimit, 8) //level limit you need to of reached to talk in ooc/auction/chat if your karma is too low.
|
||||||
|
RULE_INT(Chat, ExpireClientVersionRequests, 3) // time in seconds to keep current cv requests active
|
||||||
|
RULE_INT(Chat, ExpireClientVersionReplies, 30) // time in seconds to keep current cv replies active
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Merchant)
|
RULE_CATEGORY(Merchant)
|
||||||
|
|||||||
@ -190,6 +190,8 @@
|
|||||||
#define ServerOP_ReloadLogs 0x4010
|
#define ServerOP_ReloadLogs 0x4010
|
||||||
#define ServerOP_ReloadPerlExportSettings 0x4011
|
#define ServerOP_ReloadPerlExportSettings 0x4011
|
||||||
#define ServerOP_CZSetEntityVariableByClientName 0x4012
|
#define ServerOP_CZSetEntityVariableByClientName 0x4012
|
||||||
|
#define ServerOP_UCSClientVersionRequest 0x4013
|
||||||
|
#define ServerOP_UCSClientVersionReply 0x4014
|
||||||
/* Query Server OP Codes */
|
/* Query Server OP Codes */
|
||||||
#define ServerOP_QSPlayerLogTrades 0x5010
|
#define ServerOP_QSPlayerLogTrades 0x5010
|
||||||
#define ServerOP_QSPlayerLogHandins 0x5011
|
#define ServerOP_QSPlayerLogHandins 0x5011
|
||||||
@ -1278,6 +1280,15 @@ struct ServerRequestTellQueue_Struct {
|
|||||||
char name[64];
|
char name[64];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct UCSClientVersionRequest_Struct {
|
||||||
|
uint32 character_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UCSClientVersionReply_Struct {
|
||||||
|
uint32 character_id;
|
||||||
|
EQEmu::versions::ClientVersion client_version;
|
||||||
|
};
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -512,7 +512,9 @@ Client::Client(std::shared_ptr<EQStreamInterface> eqs) {
|
|||||||
AccountGrabUpdateTimer = new Timer(60000); //check every minute
|
AccountGrabUpdateTimer = new Timer(60000); //check every minute
|
||||||
GlobalChatLimiterTimer = new Timer(RuleI(Chat, IntervalDurationMS));
|
GlobalChatLimiterTimer = new Timer(RuleI(Chat, IntervalDurationMS));
|
||||||
|
|
||||||
|
RawConnectionType = '\0';
|
||||||
TypeOfConnection = ConnectionTypeUnknown;
|
TypeOfConnection = ConnectionTypeUnknown;
|
||||||
|
ClientVersion_ = EQEmu::versions::ClientVersion::Unknown;
|
||||||
|
|
||||||
UnderfootOrLater = false;
|
UnderfootOrLater = false;
|
||||||
}
|
}
|
||||||
@ -643,6 +645,10 @@ void Clientlist::Process()
|
|||||||
|
|
||||||
database.GetAccountStatus((*it));
|
database.GetAccountStatus((*it));
|
||||||
|
|
||||||
|
// give world packet a chance to arrive and be processed
|
||||||
|
if ((*it)->GetCharID())
|
||||||
|
ClientVersionRequestQueue[(*it)->GetCharID()] = (Timer::GetCurrentTime() + (RuleI(Chat, ExpireClientVersionRequests) * 1000));
|
||||||
|
|
||||||
if ((*it)->GetConnectionType() == ConnectionTypeCombined)
|
if ((*it)->GetConnectionType() == ConnectionTypeCombined)
|
||||||
(*it)->SendFriends();
|
(*it)->SendFriends();
|
||||||
|
|
||||||
@ -681,8 +687,35 @@ void Clientlist::Process()
|
|||||||
it = ClientChatConnections.erase(it);
|
it = ClientChatConnections.erase(it);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initiate request if we don't already have a reply from 'world enter' (ucs crash recovery protocol)
|
||||||
|
if ((*it)->GetClientVersion() == EQEmu::versions::ClientVersion::Unknown) {
|
||||||
|
if (!CheckForClientVersionReply((*it)))
|
||||||
|
RequestClientVersion((*it)->GetCharID());
|
||||||
|
}
|
||||||
|
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// delete expired replies
|
||||||
|
auto repiter = ClientVersionReplyQueue.begin();
|
||||||
|
while (repiter != ClientVersionReplyQueue.end()) {
|
||||||
|
if ((*repiter).second.second <= Timer::GetCurrentTime()) {
|
||||||
|
repiter = ClientVersionReplyQueue.erase(repiter);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
++repiter;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete expired requests
|
||||||
|
auto reqiter = ClientVersionRequestQueue.begin();
|
||||||
|
while (reqiter != ClientVersionRequestQueue.end()) {
|
||||||
|
if ((*reqiter).second <= Timer::GetCurrentTime()) {
|
||||||
|
reqiter = ClientVersionRequestQueue.erase(reqiter);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
++reqiter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clientlist::ProcessOPMailCommand(Client *c, std::string CommandString)
|
void Clientlist::ProcessOPMailCommand(Client *c, std::string CommandString)
|
||||||
@ -840,6 +873,55 @@ void Clientlist::ProcessOPMailCommand(Client *c, std::string CommandString)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Clientlist::RequestClientVersion(uint32 character_id) {
|
||||||
|
if (!character_id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ClientVersionRequestQueue.find(character_id) != ClientVersionRequestQueue.end()) {
|
||||||
|
if (ClientVersionRequestQueue[character_id] > Timer::GetCurrentTime())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LogSys.log_settings[Logs::UCS_Server].is_category_enabled) {
|
||||||
|
Log(Logs::Detail, Logs::UCS_Server, "Requesting ClientVersion reply for character id: %u",
|
||||||
|
character_id);
|
||||||
|
}
|
||||||
|
ClientVersionRequestIDs.push_back(character_id);
|
||||||
|
ClientVersionRequestQueue[character_id] = (Timer::GetCurrentTime() + (RuleI(Chat, ExpireClientVersionRequests) * 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Clientlist::QueueClientVersionReply(uint32 character_id, EQEmu::versions::ClientVersion client_version) {
|
||||||
|
if (!character_id)
|
||||||
|
return true;
|
||||||
|
if (client_version == EQEmu::versions::ClientVersion::Unknown)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (LogSys.log_settings[Logs::UCS_Server].is_category_enabled) {
|
||||||
|
Log(Logs::Detail, Logs::UCS_Server, "Queueing ClientVersion %u reply for character id: %u",
|
||||||
|
static_cast<uint32>(client_version), character_id);
|
||||||
|
}
|
||||||
|
ClientVersionReplyQueue[character_id] = cvt_pair(client_version, (Timer::GetCurrentTime() + (RuleI(Chat, ExpireClientVersionReplies) * 1000)));
|
||||||
|
ClientVersionRequestQueue.erase(character_id);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Clientlist::CheckForClientVersionReply(Client* c) {
|
||||||
|
if (!c)
|
||||||
|
return true;
|
||||||
|
if (ClientVersionReplyQueue.find(c->GetCharID()) == ClientVersionReplyQueue.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (LogSys.log_settings[Logs::UCS_Server].is_category_enabled) {
|
||||||
|
Log(Logs::General, Logs::UCS_Server, "Registering ClientVersion %s for stream %s:%u",
|
||||||
|
EQEmu::versions::ClientVersionName(ClientVersionReplyQueue[c->GetCharID()].first), c->ClientStream->GetRemoteAddr().c_str(), c->ClientStream->GetRemotePort());
|
||||||
|
}
|
||||||
|
c->SetClientVersion(ClientVersionReplyQueue[c->GetCharID()].first);
|
||||||
|
ClientVersionReplyQueue.erase(c->GetCharID());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Clientlist::CloseAllConnections() {
|
void Clientlist::CloseAllConnections() {
|
||||||
|
|
||||||
|
|
||||||
@ -2132,6 +2214,8 @@ void Client::AccountUpdate()
|
|||||||
|
|
||||||
void Client::SetConnectionType(char c) {
|
void Client::SetConnectionType(char c) {
|
||||||
|
|
||||||
|
RawConnectionType = c;
|
||||||
|
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case 'S':
|
case 'S':
|
||||||
@ -2161,6 +2245,7 @@ void Client::SetConnectionType(char c) {
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
RawConnectionType = '\0';
|
||||||
TypeOfConnection = ConnectionTypeUnknown;
|
TypeOfConnection = ConnectionTypeUnknown;
|
||||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is unknown.");
|
Log(Logs::Detail, Logs::UCS_Server, "Connection type is unknown.");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -139,8 +139,13 @@ public:
|
|||||||
std::string MailBoxName();
|
std::string MailBoxName();
|
||||||
int GetMailBoxNumber() { return CurrentMailBox; }
|
int GetMailBoxNumber() { return CurrentMailBox; }
|
||||||
int GetMailBoxNumber(std::string CharacterName);
|
int GetMailBoxNumber(std::string CharacterName);
|
||||||
|
|
||||||
|
char GetRawConnectionType() { return RawConnectionType; }
|
||||||
void SetConnectionType(char c);
|
void SetConnectionType(char c);
|
||||||
ConnectionType GetConnectionType() { return TypeOfConnection; }
|
ConnectionType GetConnectionType() { return TypeOfConnection; }
|
||||||
|
void SetClientVersion(EQEmu::versions::ClientVersion client_version) { ClientVersion_ = client_version; }
|
||||||
|
EQEmu::versions::ClientVersion GetClientVersion() { return ClientVersion_; }
|
||||||
|
|
||||||
inline bool IsMailConnection() { return (TypeOfConnection == ConnectionTypeMail) || (TypeOfConnection == ConnectionTypeCombined); }
|
inline bool IsMailConnection() { return (TypeOfConnection == ConnectionTypeMail) || (TypeOfConnection == ConnectionTypeCombined); }
|
||||||
void SendNotification(int MailBoxNumber, std::string From, std::string Subject, int MessageID);
|
void SendNotification(int MailBoxNumber, std::string From, std::string Subject, int MessageID);
|
||||||
void ChangeMailBox(int NewMailBox);
|
void ChangeMailBox(int NewMailBox);
|
||||||
@ -167,7 +172,10 @@ private:
|
|||||||
Timer *GlobalChatLimiterTimer; //60 seconds
|
Timer *GlobalChatLimiterTimer; //60 seconds
|
||||||
int AttemptedMessages;
|
int AttemptedMessages;
|
||||||
bool ForceDisconnect;
|
bool ForceDisconnect;
|
||||||
|
|
||||||
|
char RawConnectionType;
|
||||||
ConnectionType TypeOfConnection;
|
ConnectionType TypeOfConnection;
|
||||||
|
EQEmu::versions::ClientVersion ClientVersion_;
|
||||||
bool UnderfootOrLater;
|
bool UnderfootOrLater;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -182,12 +190,22 @@ public:
|
|||||||
Client *IsCharacterOnline(std::string CharacterName);
|
Client *IsCharacterOnline(std::string CharacterName);
|
||||||
void ProcessOPMailCommand(Client *c, std::string CommandString);
|
void ProcessOPMailCommand(Client *c, std::string CommandString);
|
||||||
|
|
||||||
|
std::list<uint32> ClientVersionRequestIDs;
|
||||||
|
|
||||||
|
void RequestClientVersion(uint32 character_id);
|
||||||
|
bool QueueClientVersionReply(uint32 character_id, EQEmu::versions::ClientVersion client_version);
|
||||||
|
bool CheckForClientVersionReply(Client* c);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
typedef std::pair<EQEmu::versions::ClientVersion, uint32> cvt_pair;
|
||||||
|
|
||||||
EQ::Net::EQStreamManager *chatsf;
|
EQ::Net::EQStreamManager *chatsf;
|
||||||
|
|
||||||
std::list<Client*> ClientChatConnections;
|
std::list<Client*> ClientChatConnections;
|
||||||
|
|
||||||
|
std::map<uint32, uint32> ClientVersionRequestQueue;
|
||||||
|
std::map<uint32, cvt_pair> ClientVersionReplyQueue;
|
||||||
|
|
||||||
OpcodeManager *ChatOpMgr;
|
OpcodeManager *ChatOpMgr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -140,12 +140,17 @@ int main() {
|
|||||||
|
|
||||||
worldserver = new WorldServer;
|
worldserver = new WorldServer;
|
||||||
|
|
||||||
|
// now that we can send packets to world, see if there's a
|
||||||
|
// broadcast opcode that tells the client to relog into ucs
|
||||||
|
|
||||||
while(RunLoops) {
|
while(RunLoops) {
|
||||||
|
|
||||||
Timer::SetCurrentTime();
|
Timer::SetCurrentTime();
|
||||||
|
|
||||||
g_Clientlist->Process();
|
g_Clientlist->Process();
|
||||||
|
|
||||||
|
worldserver->ProcessClientVersionRequests(g_Clientlist->ClientVersionRequestIDs);
|
||||||
|
|
||||||
if(ChannelListProcessTimer.Check())
|
if(ChannelListProcessTimer.Check())
|
||||||
ChannelList->Process();
|
ChannelList->Process();
|
||||||
|
|
||||||
|
|||||||
@ -114,5 +114,23 @@ void WorldServer::ProcessMessage(uint16 opcode, EQ::Net::Packet &p)
|
|||||||
std::string());
|
std::string());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ServerOP_UCSClientVersionReply:
|
||||||
|
{
|
||||||
|
UCSClientVersionReply_Struct* cvr = (UCSClientVersionReply_Struct*)pack->pBuffer;
|
||||||
|
g_Clientlist->QueueClientVersionReply(cvr->character_id, cvr->client_version);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WorldServer::ProcessClientVersionRequests(std::list<uint32>& id_list) {
|
||||||
|
UCSClientVersionRequest_Struct cvr;
|
||||||
|
EQ::Net::DynamicPacket dp_cvr;
|
||||||
|
for (auto iter : id_list) {
|
||||||
|
cvr.character_id = iter;
|
||||||
|
dp_cvr.PutData(0, &cvr, sizeof(cvr));
|
||||||
|
m_connection->Send(ServerOP_UCSClientVersionRequest, dp_cvr);
|
||||||
|
}
|
||||||
|
id_list.clear();
|
||||||
|
}
|
||||||
|
|||||||
@ -29,6 +29,8 @@ public:
|
|||||||
~WorldServer();
|
~WorldServer();
|
||||||
void ProcessMessage(uint16 opcode, EQ::Net::Packet &);
|
void ProcessMessage(uint16 opcode, EQ::Net::Packet &);
|
||||||
|
|
||||||
|
void ProcessClientVersionRequests(std::list<uint32>& id_list);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::unique_ptr<EQ::Net::ServertalkClient> m_connection;
|
std::unique_ptr<EQ::Net::ServertalkClient> m_connection;
|
||||||
|
|||||||
@ -1215,6 +1215,14 @@ void Client::EnterWorld(bool TryBootup) {
|
|||||||
wtz->response = 0;
|
wtz->response = 0;
|
||||||
zone_server->SendPacket(pack);
|
zone_server->SendPacket(pack);
|
||||||
delete pack;
|
delete pack;
|
||||||
|
|
||||||
|
UCSClientVersionReply_Struct cvr;
|
||||||
|
cvr.character_id = GetCharID();
|
||||||
|
cvr.client_version = GetClientVersion();
|
||||||
|
EQ::Net::DynamicPacket dp_cvr;
|
||||||
|
dp_cvr.PutData(0, &cvr, sizeof(cvr));
|
||||||
|
zone_server->HandleMessage(ServerOP_UCSClientVersionReply, dp_cvr);
|
||||||
|
|
||||||
}
|
}
|
||||||
else { // if they havent seen character select screen, we can assume this is a zone
|
else { // if they havent seen character select screen, we can assume this is a zone
|
||||||
// to zone movement, which should be preauthorized before they leave the previous zone
|
// to zone movement, which should be preauthorized before they leave the previous zone
|
||||||
|
|||||||
@ -68,6 +68,7 @@ public:
|
|||||||
inline const char* GetLSKey() { if (cle) { return cle->GetLSKey(); } return "NOKEY"; }
|
inline const char* GetLSKey() { if (cle) { return cle->GetLSKey(); } return "NOKEY"; }
|
||||||
inline uint32 GetCharID() { return charid; }
|
inline uint32 GetCharID() { return charid; }
|
||||||
inline const char* GetCharName() { return char_name; }
|
inline const char* GetCharName() { return char_name; }
|
||||||
|
inline EQEmu::versions::ClientVersion GetClientVersion() { return m_ClientVersion; }
|
||||||
inline ClientListEntry* GetCLE() { return cle; }
|
inline ClientListEntry* GetCLE() { return cle; }
|
||||||
inline void SetCLE(ClientListEntry* iCLE) { cle = iCLE; }
|
inline void SetCLE(ClientListEntry* iCLE) { cle = iCLE; }
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -2,11 +2,14 @@
|
|||||||
#include "../common/eqemu_logsys.h"
|
#include "../common/eqemu_logsys.h"
|
||||||
#include "ucs.h"
|
#include "ucs.h"
|
||||||
#include "world_config.h"
|
#include "world_config.h"
|
||||||
|
#include "zonelist.h"
|
||||||
|
|
||||||
#include "../common/misc_functions.h"
|
#include "../common/misc_functions.h"
|
||||||
#include "../common/md5.h"
|
#include "../common/md5.h"
|
||||||
#include "../common/packet_dump.h"
|
#include "../common/packet_dump.h"
|
||||||
|
|
||||||
|
extern ZSList zoneserver_list;
|
||||||
|
|
||||||
UCSConnection::UCSConnection()
|
UCSConnection::UCSConnection()
|
||||||
{
|
{
|
||||||
Stream = 0;
|
Stream = 0;
|
||||||
@ -49,6 +52,11 @@ void UCSConnection::ProcessPacket(uint16 opcode, EQ::Net::Packet &p)
|
|||||||
Log(Logs::Detail, Logs::UCS_Server, "Got authentication from UCS when they are already authenticated.");
|
Log(Logs::Detail, Logs::UCS_Server, "Got authentication from UCS when they are already authenticated.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ServerOP_UCSClientVersionRequest:
|
||||||
|
{
|
||||||
|
zoneserver_list.SendPacket(pack);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
Log(Logs::Detail, Logs::UCS_Server, "Unknown ServerOPcode from UCS 0x%04x, size %d", opcode, pack->size);
|
Log(Logs::Detail, Logs::UCS_Server, "Unknown ServerOPcode from UCS 0x%04x, size %d", opcode, pack->size);
|
||||||
|
|||||||
@ -1262,6 +1262,7 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ServerOP_UCSClientVersionReply:
|
||||||
case ServerOP_UCSMailMessage:
|
case ServerOP_UCSMailMessage:
|
||||||
{
|
{
|
||||||
UCSLink.SendPacket(pack);
|
UCSLink.SendPacket(pack);
|
||||||
|
|||||||
@ -1813,6 +1813,20 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ServerOP_UCSClientVersionRequest:
|
||||||
|
{
|
||||||
|
UCSClientVersionRequest_Struct* cvreq = (UCSClientVersionRequest_Struct*)pack->pBuffer;
|
||||||
|
Client* c = entity_list.GetClientByCharID(cvreq->character_id);
|
||||||
|
if (c) {
|
||||||
|
UCSClientVersionReply_Struct cvrep;
|
||||||
|
cvrep.character_id = c->CharacterID();
|
||||||
|
cvrep.client_version = c->ClientVersion();
|
||||||
|
EQ::Net::DynamicPacket dp_cvrep;
|
||||||
|
dp_cvrep.PutData(0, &cvrep, sizeof(cvrep));
|
||||||
|
worldserver.m_connection->Send(ServerOP_UCSClientVersionReply, dp_cvrep);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ServerOP_CZSetEntityVariableByNPCTypeID:
|
case ServerOP_CZSetEntityVariableByNPCTypeID:
|
||||||
{
|
{
|
||||||
CZSetEntVarByNPCTypeID_Struct* CZM = (CZSetEntVarByNPCTypeID_Struct*)pack->pBuffer;
|
CZSetEntVarByNPCTypeID_Struct* CZM = (CZSetEntVarByNPCTypeID_Struct*)pack->pBuffer;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user