mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
Data verification utils, not in use yet. Also added ability for lua packet to bypass the translation layer (dangerous) if a writer so desires (useful for quickly trying packet stuff)
This commit is contained in:
parent
9878459049
commit
0d12715d77
43
common/data_verification.h
Normal file
43
common/data_verification.h
Normal file
@ -0,0 +1,43 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef COMMON_DATA_VERIFICATION_H
|
||||
#define COMMON_DATA_VERIFICATION_H
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
T Clamp(const T& value, const T& lower, const T& upper) {
|
||||
return std::max(lower, std::min(value, upper));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T ClampLower(const T& value, const T& lower) {
|
||||
return std::max(lower, value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T ClampUpper(const T& value, const T& upper) {
|
||||
return std::min(value, upper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -97,16 +97,15 @@ protected:
|
||||
};
|
||||
|
||||
class EQApplicationPacket : public EQPacket {
|
||||
// friend class EQProtocolPacket;
|
||||
friend class EQStream;
|
||||
public:
|
||||
EQApplicationPacket() : EQPacket(OP_Unknown,nullptr,0)
|
||||
EQApplicationPacket() : EQPacket(OP_Unknown, nullptr, 0), opcode_bypass(0)
|
||||
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
|
||||
EQApplicationPacket(const EmuOpcode op) : EQPacket(op,nullptr,0)
|
||||
EQApplicationPacket(const EmuOpcode op) : EQPacket(op, nullptr, 0), opcode_bypass(0)
|
||||
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
|
||||
EQApplicationPacket(const EmuOpcode op, const uint32 len) : EQPacket(op,nullptr,len)
|
||||
EQApplicationPacket(const EmuOpcode op, const uint32 len) : EQPacket(op, nullptr, len), opcode_bypass(0)
|
||||
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
|
||||
EQApplicationPacket(const EmuOpcode op, const unsigned char *buf, const uint32 len) : EQPacket(op,buf,len)
|
||||
EQApplicationPacket(const EmuOpcode op, const unsigned char *buf, const uint32 len) : EQPacket(op, buf, len), opcode_bypass(0)
|
||||
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
|
||||
bool combine(const EQApplicationPacket *rhs);
|
||||
uint32 serialize (uint16 opcode, unsigned char *dest) const;
|
||||
@ -119,12 +118,16 @@ public:
|
||||
virtual void DumpRawHeader(uint16 seq=0xffff, FILE *to = stdout) const;
|
||||
virtual void DumpRawHeaderNoTime(uint16 seq=0xffff, FILE *to = stdout) const;
|
||||
|
||||
uint16 GetOpcodeBypass() { return opcode_bypass; }
|
||||
void SetOpcodeBypass(uint16 v) { opcode_bypass = v; }
|
||||
|
||||
protected:
|
||||
|
||||
uint8 app_opcode_size;
|
||||
uint16 opcode_bypass;
|
||||
private:
|
||||
|
||||
EQApplicationPacket(const EQApplicationPacket &p) : EQPacket(p.emu_opcode, p.pBuffer, p.size) { app_opcode_size = p.app_opcode_size; }
|
||||
EQApplicationPacket(const EQApplicationPacket &p) : EQPacket(p.emu_opcode, p.pBuffer, p.size), opcode_bypass(p.opcode_bypass) { app_opcode_size = p.app_opcode_size; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -532,9 +532,12 @@ void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req)
|
||||
return;
|
||||
}
|
||||
|
||||
uint16 opcode = (*OpMgr)->EmuToEQ(pack->emu_opcode);
|
||||
|
||||
//_log(NET__APP_TRACE, "Queueing %sacked packet with opcode 0x%x (%s) and length %d", ack_req?"":"non-", opcode, OpcodeManager::EmuToName(pack->emu_opcode), pack->size);
|
||||
uint16 opcode = 0;
|
||||
if(pack->GetOpcodeBypass() != 0) {
|
||||
opcode = pack->GetOpcodeBypass();
|
||||
} else {
|
||||
opcode = (*OpMgr)->EmuToEQ(pack->emu_opcode);
|
||||
}
|
||||
|
||||
if (!ack_req) {
|
||||
NonSequencedPush(new EQProtocolPacket(opcode, pack->pBuffer, pack->size));
|
||||
@ -877,43 +880,6 @@ sockaddr_in address;
|
||||
AddBytesSent(length);
|
||||
}
|
||||
|
||||
/*
|
||||
commented out since im not sure theres a lot of merit in it.
|
||||
Really it was bitterness towards allocating a 2k buffer on the stack each call.
|
||||
Im sure the thought was client side, but even then, they will
|
||||
likely need a whole thread to call this method, in which case, they should
|
||||
supply the buffer so we dont re-allocate it each time.
|
||||
EQProtocolPacket *EQStream::Read(int eq_fd, sockaddr_in *from)
|
||||
{
|
||||
int socklen;
|
||||
int length=0;
|
||||
EQProtocolPacket *p=nullptr;
|
||||
char temp[15];
|
||||
|
||||
socklen=sizeof(sockaddr);
|
||||
#ifdef _WINDOWS
|
||||
length=recvfrom(eq_fd, (char *)_tempBuffer, 2048, 0, (struct sockaddr*)from, (int *)&socklen);
|
||||
#else
|
||||
length=recvfrom(eq_fd, _tempBuffer, 2048, 0, (struct sockaddr*)from, (socklen_t *)&socklen);
|
||||
#endif
|
||||
|
||||
if (length>=2) {
|
||||
p=new EQProtocolPacket(_tempBuffer[1],&_tempBuffer[2],length-2);
|
||||
|
||||
uint32 ip=from->sin_addr.s_addr;
|
||||
sprintf(temp,"%d.%d.%d.%d:%d",
|
||||
*(unsigned char *)&ip,
|
||||
*((unsigned char *)&ip+1),
|
||||
*((unsigned char *)&ip+2),
|
||||
*((unsigned char *)&ip+3),
|
||||
ntohs(from->sin_port));
|
||||
//std::cout << timestamp() << "Data from: " << temp << " OpCode 0x" << std::hex << std::setw(2) << std::setfill('0') << (int)p->opcode << std::dec << std::endl;
|
||||
//dump_message(p->pBuffer,p->size,timestamp());
|
||||
|
||||
}
|
||||
return p;
|
||||
}*/
|
||||
|
||||
void EQStream::SendSessionResponse()
|
||||
{
|
||||
EQProtocolPacket *out=new EQProtocolPacket(OP_SessionResponse,nullptr,sizeof(SessionResponse));
|
||||
@ -1101,14 +1067,6 @@ EQProtocolPacket *p=nullptr;
|
||||
SequencedQueue.clear();
|
||||
}
|
||||
MOutboundQueue.unlock();
|
||||
|
||||
/*if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
||||
_log(NET__ERROR, _L "Out-bound Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
}
|
||||
if(NextSequencedSend > SequencedQueue.size()) {
|
||||
_log(NET__ERROR, _L "Out-bound Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size());
|
||||
}*/
|
||||
//NOTE: we prolly want to reset counters if we are stupposed to do anything after this.
|
||||
}
|
||||
|
||||
void EQStream::PacketQueueClear()
|
||||
|
||||
@ -17,6 +17,11 @@ StructStrategy::StructStrategy() {
|
||||
}
|
||||
|
||||
void StructStrategy::Encode(EQApplicationPacket **p, EQStream *dest, bool ack_req) const {
|
||||
if((*p)->GetOpcodeBypass() != 0) {
|
||||
PassEncoder(p, dest, ack_req);
|
||||
return;
|
||||
}
|
||||
|
||||
EmuOpcode op = (*p)->GetOpcode();
|
||||
Encoder proc = encoders[op];
|
||||
proc(p, dest, ack_req);
|
||||
|
||||
@ -8,6 +8,7 @@ SET(tests_sources
|
||||
|
||||
SET(tests_headers
|
||||
atobool_test.h
|
||||
data_verification_test.h
|
||||
fixed_memory_test.h
|
||||
fixed_memory_variable_test.h
|
||||
hextoi_32_64_test.h
|
||||
@ -20,6 +21,8 @@ ADD_EXECUTABLE(tests ${tests_sources} ${tests_headers})
|
||||
|
||||
TARGET_LINK_LIBRARIES(tests common cppunit)
|
||||
|
||||
INSTALL(TARGETS tests RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
|
||||
IF(MSVC)
|
||||
SET_TARGET_PROPERTIES(tests PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
|
||||
TARGET_LINK_LIBRARIES(tests "Ws2_32.lib")
|
||||
|
||||
94
tests/data_verification_test.h
Normal file
94
tests/data_verification_test.h
Normal file
@ -0,0 +1,94 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __EQEMU_TESTS_DATA_VERIFICATION_H
|
||||
#define __EQEMU_TESTS_DATA_VERIFICATION_H
|
||||
|
||||
#include "cppunit/cpptest.h"
|
||||
#include "../common/data_verification.h"
|
||||
|
||||
class DataVerificationTest : public Test::Suite {
|
||||
typedef void(DataVerificationTest::*TestFunction)(void);
|
||||
public:
|
||||
DataVerificationTest() {
|
||||
TEST_ADD(DataVerificationTest::Clamp);
|
||||
TEST_ADD(DataVerificationTest::ClampUpper);
|
||||
TEST_ADD(DataVerificationTest::ClampLower);
|
||||
}
|
||||
|
||||
~DataVerificationTest() {
|
||||
}
|
||||
|
||||
private:
|
||||
void Clamp() {
|
||||
float value_f = 500.0f;
|
||||
int value_i = 500;
|
||||
|
||||
float vf1 = EQEmu::Clamp(value_f, 0.0f, 1000.0f);
|
||||
float vf2 = EQEmu::Clamp(value_f, 0.0f, 250.0f);
|
||||
float vf3 = EQEmu::Clamp(value_f, 750.0f, 1000.0f);
|
||||
|
||||
int vi1 = EQEmu::Clamp(value_i, 0, 1000);
|
||||
int vi2 = EQEmu::Clamp(value_i, 0, 250);
|
||||
int vi3 = EQEmu::Clamp(value_i, 750, 1000);
|
||||
|
||||
TEST_ASSERT_EQUALS(vf1, 500.0f);
|
||||
TEST_ASSERT_EQUALS(vf2, 250.0f);
|
||||
TEST_ASSERT_EQUALS(vf3, 750.0f);
|
||||
|
||||
TEST_ASSERT_EQUALS(vi1, 500);
|
||||
TEST_ASSERT_EQUALS(vi2, 250);
|
||||
TEST_ASSERT_EQUALS(vi3, 750);
|
||||
}
|
||||
|
||||
void ClampUpper() {
|
||||
float value_f = 500.0f;
|
||||
int value_i = 500;
|
||||
|
||||
float vf1 = EQEmu::ClampUpper(value_f, 1000.0f);
|
||||
float vf2 = EQEmu::ClampUpper(value_f, 250.0f);
|
||||
|
||||
int vi1 = EQEmu::ClampUpper(value_i, 1000);
|
||||
int vi2 = EQEmu::ClampUpper(value_i, 250);
|
||||
|
||||
TEST_ASSERT_EQUALS(vf1, 500.0f);
|
||||
TEST_ASSERT_EQUALS(vf2, 250.0f);
|
||||
|
||||
TEST_ASSERT_EQUALS(vi1, 500);
|
||||
TEST_ASSERT_EQUALS(vi2, 250);
|
||||
}
|
||||
|
||||
void ClampLower() {
|
||||
float value_f = 500.0f;
|
||||
int value_i = 500;
|
||||
|
||||
float vf1 = EQEmu::ClampLower(value_f, 0.0f);
|
||||
float vf2 = EQEmu::ClampLower(value_f, 750.0f);
|
||||
|
||||
int vi1 = EQEmu::ClampLower(value_i, 0);
|
||||
int vi2 = EQEmu::ClampLower(value_i, 750);
|
||||
|
||||
TEST_ASSERT_EQUALS(vf1, 500.0f);
|
||||
TEST_ASSERT_EQUALS(vf2, 750.0f);
|
||||
|
||||
TEST_ASSERT_EQUALS(vi1, 500);
|
||||
TEST_ASSERT_EQUALS(vi2, 750);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -27,6 +27,7 @@
|
||||
#include "atobool_test.h"
|
||||
#include "hextoi_32_64_test.h"
|
||||
#include "string_util_test.h"
|
||||
#include "data_verification_test.h"
|
||||
|
||||
int main() {
|
||||
try {
|
||||
@ -40,6 +41,7 @@ int main() {
|
||||
tests.add(new atoboolTest());
|
||||
tests.add(new hextoi_32_64_Test());
|
||||
tests.add(new StringUtilTest());
|
||||
tests.add(new DataVerificationTest());
|
||||
tests.run(*output, true);
|
||||
} catch(...) {
|
||||
return -1;
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
#include "../common/string_util.h"
|
||||
|
||||
class StringUtilTest : public Test::Suite {
|
||||
typedef void(IPCMutexTest::*TestFunction)(void);
|
||||
typedef void(StringUtilTest::*TestFunction)(void);
|
||||
public:
|
||||
StringUtilTest() {
|
||||
TEST_ADD(StringUtilTest::StringFormatTest);
|
||||
@ -35,7 +35,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void StringFormatTest() {
|
||||
void StringFormatTest() {
|
||||
const char* fmt = "Test: %c %d %4.2f";
|
||||
char c = 'a';
|
||||
int i = 2014;
|
||||
|
||||
@ -701,14 +701,10 @@ void Client::QueuePacket(const EQApplicationPacket* app, bool ack_req, CLIENT_CO
|
||||
}
|
||||
|
||||
void Client::FastQueuePacket(EQApplicationPacket** app, bool ack_req, CLIENT_CONN_STATUS required_state) {
|
||||
|
||||
//std::cout << "Sending: 0x" << std::hex << std::setw(4) << std::setfill('0') << (*app)->GetOpcode() << std::dec << ", size=" << (*app)->size << std::endl;
|
||||
|
||||
// if the program doesnt care about the status or if the status isnt what we requested
|
||||
if (required_state != CLIENT_CONNECTINGALL && client_state != required_state) {
|
||||
// todo: save packets for later use
|
||||
AddPacket(app, ack_req);
|
||||
// LogFile->write(EQEMuLog::Normal, "Adding Packet to list (%d) (%d)", (*app)->GetOpcode(), (int)required_state);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
|
||||
@ -14,14 +14,31 @@ Lua_Packet::Lua_Packet(int opcode, int size) {
|
||||
owned_ = true;
|
||||
}
|
||||
|
||||
Lua_Packet::Lua_Packet(int opcode, int size, bool raw) {
|
||||
if(raw) {
|
||||
SetLuaPtrData(new EQApplicationPacket(OP_Unknown, size));
|
||||
owned_ = true;
|
||||
|
||||
EQApplicationPacket *self = reinterpret_cast<EQApplicationPacket*>(d_);
|
||||
self->SetOpcodeBypass(opcode);
|
||||
} else {
|
||||
SetLuaPtrData(new EQApplicationPacket(static_cast<EmuOpcode>(opcode), size));
|
||||
owned_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
Lua_Packet& Lua_Packet::operator=(const Lua_Packet& o) {
|
||||
if(o.owned_) {
|
||||
owned_ = true;
|
||||
EQApplicationPacket *app = reinterpret_cast<EQApplicationPacket*>(o.d_);
|
||||
if(app)
|
||||
if(app) {
|
||||
d_ = new EQApplicationPacket(app->GetOpcode(), app->pBuffer, app->size);
|
||||
else
|
||||
|
||||
EQApplicationPacket *self = reinterpret_cast<EQApplicationPacket*>(d_);
|
||||
self->SetOpcodeBypass(app->GetOpcodeBypass());
|
||||
} else {
|
||||
d_ = nullptr;
|
||||
}
|
||||
} else {
|
||||
owned_ = false;
|
||||
d_ = o.d_;
|
||||
@ -33,10 +50,14 @@ Lua_Packet::Lua_Packet(const Lua_Packet& o) {
|
||||
if(o.owned_) {
|
||||
owned_ = true;
|
||||
EQApplicationPacket *app = reinterpret_cast<EQApplicationPacket*>(o.d_);
|
||||
if(app)
|
||||
if(app) {
|
||||
d_ = new EQApplicationPacket(app->GetOpcode(), app->pBuffer, app->size);
|
||||
else
|
||||
|
||||
EQApplicationPacket *self = reinterpret_cast<EQApplicationPacket*>(d_);
|
||||
self->SetOpcodeBypass(app->GetOpcodeBypass());
|
||||
} else {
|
||||
d_ = nullptr;
|
||||
}
|
||||
} else {
|
||||
owned_ = false;
|
||||
d_ = o.d_;
|
||||
@ -54,6 +75,16 @@ int Lua_Packet::GetOpcode() {
|
||||
}
|
||||
|
||||
void Lua_Packet::SetOpcode(int op) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetOpcodeBypass(static_cast<uint16>(op));
|
||||
}
|
||||
|
||||
int Lua_Packet::GetRawOpcode() {
|
||||
Lua_Safe_Call_Int();
|
||||
return static_cast<int>(self->GetOpcodeBypass());
|
||||
}
|
||||
|
||||
void Lua_Packet::SetRawOpcode(int op) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetOpcode(static_cast<EmuOpcode>(op));
|
||||
}
|
||||
@ -244,11 +275,14 @@ luabind::scope lua_register_packet() {
|
||||
return luabind::class_<Lua_Packet>("Packet")
|
||||
.def(luabind::constructor<>())
|
||||
.def(luabind::constructor<int,int>())
|
||||
.def(luabind::constructor<int,int,bool>())
|
||||
.property("null", &Lua_Packet::Null)
|
||||
.property("valid", &Lua_Packet::Valid)
|
||||
.def("GetSize", &Lua_Packet::GetSize)
|
||||
.def("GetOpcode", &Lua_Packet::GetOpcode)
|
||||
.def("SetOpcode", &Lua_Packet::SetOpcode)
|
||||
.def("GetRawOpcode", &Lua_Packet::GetRawOpcode)
|
||||
.def("SetRawOpcode", &Lua_Packet::SetRawOpcode)
|
||||
.def("WriteInt8", &Lua_Packet::WriteInt8)
|
||||
.def("WriteInt16", &Lua_Packet::WriteInt16)
|
||||
.def("WriteInt32", &Lua_Packet::WriteInt32)
|
||||
@ -809,7 +843,10 @@ luabind::scope lua_register_packet_opcodes() {
|
||||
luabind::value("MercenaryDismiss", static_cast<int>(OP_MercenaryDismiss)),
|
||||
luabind::value("MercenaryTimerRequest", static_cast<int>(OP_MercenaryTimerRequest)),
|
||||
luabind::value("OpenInventory", static_cast<int>(OP_OpenInventory)),
|
||||
luabind::value("OpenContainer", static_cast<int>(OP_OpenContainer))
|
||||
luabind::value("OpenContainer", static_cast<int>(OP_OpenContainer)),
|
||||
luabind::value("Marquee", static_cast<int>(OP_Marquee)),
|
||||
luabind::value("ClientTimeStamp", static_cast<int>(OP_ClientTimeStamp)),
|
||||
luabind::value("GuildPromote", static_cast<int>(OP_GuildPromote))
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@ public:
|
||||
Lua_Packet() : Lua_Ptr(nullptr), owned_(false) { }
|
||||
Lua_Packet(EQApplicationPacket *d) : Lua_Ptr(d), owned_(false) { }
|
||||
Lua_Packet(int opcode, int size);
|
||||
Lua_Packet(int opcode, int size, bool raw);
|
||||
Lua_Packet& operator=(const Lua_Packet& o);
|
||||
Lua_Packet(const Lua_Packet& o);
|
||||
virtual ~Lua_Packet() { if(owned_) { EQApplicationPacket *ptr = GetLuaPtrData(); if(ptr) { delete ptr; } } }
|
||||
@ -28,6 +29,8 @@ public:
|
||||
int GetSize();
|
||||
int GetOpcode();
|
||||
void SetOpcode(int op);
|
||||
int GetRawOpcode();
|
||||
void SetRawOpcode(int op);
|
||||
void WriteInt8(int offset, int value);
|
||||
void WriteInt16(int offset, int value);
|
||||
void WriteInt32(int offset, int value);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user