More work to actually make this usable

This commit is contained in:
KimLS
2015-06-26 01:01:37 -07:00
parent 923252dbcc
commit a6675a483d
28 changed files with 372 additions and 120 deletions
+2
View File
@@ -29,6 +29,7 @@ SET(common_sources
extprofile.cpp
faction.cpp
file_verify.cpp
file_verify_manager.cpp
guild_base.cpp
guilds.cpp
ipc_mutex.cpp
@@ -132,6 +133,7 @@ SET(common_headers
faction.h
features.h
file_verify.h
file_verify_manager.h
fixed_memory_hash_set.h
fixed_memory_variable_hash_set.h
global_define.h
+2
View File
@@ -55,6 +55,8 @@ enum class ClientVersion
MobMerc,
MobBot,
MobPet,
MaxClientVersions
};
#define CLIENT_VERSION_COUNT 12
+23 -58
View File
@@ -1,9 +1,11 @@
#include "global_define.h"
#include "types.h"
#include "clientversions.h"
#include "file_verify.h"
#include "crc32.h"
#include <stdio.h>
#pragma pack(1)
struct VerifyFileStruct
{
uint32 crc;
@@ -11,21 +13,33 @@ struct VerifyFileStruct
uint32 offset[256];
uint32 data[256];
};
#pragma pack()
EQEmu::FileVerify::FileVerify() {
buffer = nullptr;
size = 0;
}
EQEmu::FileVerify::~FileVerify() {
safe_delete_array(buffer);
}
bool EQEmu::FileVerify::Load(const char *file_name) {
safe_delete_array(buffer);
size = 0;
EQEmu::FileVerify::FileVerify(const char *file_name) {
FILE *f = fopen(file_name, "rb");
if(!f) {
buffer = nullptr;
size = 0;
return;
return false;
}
fseek(f, 0U, SEEK_END);
size = ftell(f);
rewind(f);
char *buffer = new char[size];
buffer = new char[size];
auto result = fread(buffer, 1, size, f);
fclose(f);
@@ -33,13 +47,11 @@ EQEmu::FileVerify::FileVerify(const char *file_name) {
safe_delete_array(buffer);
size = 0;
}
return true;
}
EQEmu::FileVerify::~FileVerify() {
safe_delete_array(buffer);
}
bool EQEmu::FileVerify::Verify(const char *data, uint32 size) {
bool EQEmu::FileVerify::Verify(const char *data, uint32 size, ClientVersion version) {
if(!buffer) {
return true;
}
@@ -49,11 +61,11 @@ bool EQEmu::FileVerify::Verify(const char *data, uint32 size) {
}
VerifyFileStruct *vs = (VerifyFileStruct*)data;
if(size != vs->file_size) {
if(this->size != vs->file_size) {
return false;
}
uint32 crc = CRC32::GenerateNoFlip((uchar*)buffer, size);
uint32 crc = CRC32::GenerateNoFlip((uchar*)buffer, this->size);
if(vs->crc != crc) {
return false;
}
@@ -61,7 +73,7 @@ bool EQEmu::FileVerify::Verify(const char *data, uint32 size) {
for(int i = 0; i < 256; ++i) {
uint32 offset = vs->offset[i] * 4;
if((offset - 4) > size) {
if((offset - 4) > this->size) {
return false;
}
@@ -74,50 +86,3 @@ bool EQEmu::FileVerify::Verify(const char *data, uint32 size) {
return true;
}
//bool VerifyFile(const EQApplicationPacket *app, const char* filename) {
// FILE *f = fopen(filename, "rb");
// if(!f) {
// return false;
// }
//
// VerifyFileStruct *vs = (VerifyFileStruct*)app->pBuffer;
//
// fseek(f, 0U, SEEK_END);
// auto size = ftell(f);
// rewind(f);
//
// if(size != vs->file_size || size < 1024) {
// fclose(f);
// return false;
// }
//
// char *buffer = new char[size];
// std::unique_ptr<char> data(buffer);
// auto result = fread(buffer, 1, size, f);
// fclose(f);
//
// if(result != size) {
// return false;
// }
//
// uint32 crc = CRC32::GenerateNoFlip((uchar*)buffer, size);
//
// Log.Out(Logs::General, Logs::Status, "CRC %u vs %u", crc, vs->crc);
//
// for(int i = 0; i < 256; ++i) {
// uint32 offset = vs->check[i] * 4;
//
// Log.Out(Logs::General, Logs::Status, "Data: %c%c%c%c vs %c%c%c%c", vs->data[i * 4], vs->data[i * 4 + 1], vs->data[i * 4 + 2], vs->data[i * 4 + 3],
// buffer[offset], buffer[offset + 1], buffer[offset + 2], buffer[offset + 3]);
//
// if(buffer[offset] != vs->data[i * 4] ||
// buffer[offset + 1] != vs->data[i * 4 + 1] ||
// buffer[offset + 2] != vs->data[i * 4 + 2] ||
// buffer[offset + 3] != vs->data[i * 4 + 3])
// {
// return false;
// }
// }
//
// return true;
//}
+3 -2
View File
@@ -6,10 +6,11 @@ namespace EQEmu
class FileVerify
{
public:
FileVerify(const char *file_name);
FileVerify();
~FileVerify();
bool Verify(const char *data, uint32 size);
bool Load(const char *file_name);
bool Verify(const char *data, uint32 size, ClientVersion version);
private:
char *buffer;
+87
View File
@@ -0,0 +1,87 @@
#include "global_define.h"
#include "types.h"
#include "clientversions.h"
#include "eq_packet.h"
#include "file_verify_manager.h"
#include "string_util.h"
#include <memory>
struct EQEmu::FileVerifyManager::impl {
std::unique_ptr<FileVerify> spell_data;
std::unique_ptr<FileVerify> skill_data;
std::unique_ptr<FileVerify> base_data;
std::unique_ptr<FileVerify> eqgames[(int)ClientVersion::MaxClientVersions];
};
EQEmu::FileVerifyManager::FileVerifyManager() {
impl_ = new impl;
impl_->spell_data.reset(new FileVerify());
impl_->spell_data->Load("verify/spells_us.txt");
impl_->skill_data.reset(new FileVerify());
impl_->skill_data->Load("verify/SkillCaps.txt");
impl_->base_data.reset(new FileVerify());
impl_->base_data->Load("verify/BaseData.txt");
for(int i = 0; i < (int)ClientVersion::MaxClientVersions; ++i) {
impl_->eqgames[i].reset(nullptr);
}
}
EQEmu::FileVerifyManager::~FileVerifyManager() {
delete impl_;
}
bool EQEmu::FileVerifyManager::VerifySpellFile(const EQApplicationPacket *app, ClientVersion version) {
if(!impl_->spell_data) {
impl_->spell_data.reset(new FileVerify());
if(!impl_->spell_data->Load("verify/spells_us.txt")) {
return true;
}
}
return impl_->spell_data->Verify((char*)app->pBuffer, app->size, version);
}
bool EQEmu::FileVerifyManager::VerifySkillFile(const EQApplicationPacket *app, ClientVersion version) {
if(!impl_->skill_data) {
impl_->skill_data.reset(new FileVerify());
if(!impl_->skill_data->Load("verify/SkillCaps.txt")) {
return true;
}
}
return impl_->skill_data->Verify((char*)app->pBuffer, app->size, version);
}
bool EQEmu::FileVerifyManager::VerifyBaseDataFile(const EQApplicationPacket *app, ClientVersion version) {
if(!impl_->base_data) {
impl_->base_data.reset(new FileVerify());
if(!impl_->base_data->Load("verify/BaseData.txt")) {
return true;
}
}
return impl_->base_data->Verify((char*)app->pBuffer, app->size, version);
}
bool EQEmu::FileVerifyManager::VerifyEQGame(const EQApplicationPacket *app, ClientVersion version) {
int v = (int)version;
if(v >= (int)ClientVersion::MaxClientVersions) {
return true;
}
if(!impl_->eqgames[v]) {
impl_->eqgames[v].reset(new FileVerify());
if(!impl_->eqgames[v]->Load(StringFormat("verify/%s/eqgame.exe", ClientVersionName(version)).c_str())) {
return true;
}
}
return impl_->eqgames[v]->Verify((char*)app->pBuffer, app->size, version);
}
+33
View File
@@ -0,0 +1,33 @@
#ifndef EQEMU_COMMON_FILE_VERIFY_MANAGER_H
#define EQEMU_COMMON_FILE_VERIFY_MANAGER_H
#include "file_verify.h"
namespace EQEmu
{
class FileVerifyManager
{
public:
~FileVerifyManager();
static FileVerifyManager& Get()
{
static FileVerifyManager instance;
return instance;
}
bool VerifySpellFile(const EQApplicationPacket *app, ClientVersion version);
bool VerifySkillFile(const EQApplicationPacket *app, ClientVersion version);
bool VerifyBaseDataFile(const EQApplicationPacket *app, ClientVersion version);
bool VerifyEQGame(const EQApplicationPacket *app, ClientVersion version);
private:
FileVerifyManager();
FileVerifyManager(FileVerifyManager const&);
void operator=(FileVerifyManager const&);
struct impl;
impl *impl_;
};
}
#endif
+1
View File
@@ -188,6 +188,7 @@ RULE_BOOL (World, IsGMPetitionWindowEnabled, false)
RULE_INT (World, FVNoDropFlag, 0) // Sets the Firiona Vie settings on the client. If set to 2, the flag will be set for GMs only, allowing trading of no-drop items.
RULE_BOOL (World, IPLimitDisconnectAll, false)
RULE_INT (World, TellQueueSize, 20)
RULE_BOOL (World, AllowActionWithBadFiles, true) // if false then the client will be prevented from moving past world if their client files don't match the server's
RULE_CATEGORY_END()
RULE_CATEGORY(Zone)
+18
View File
@@ -153,6 +153,8 @@
#define ServerOP_GetWorldTime 0x200C
#define ServerOP_SyncWorldTime 0x200E
#define ServerOP_ClientFileStatus 0x2020
#define ServerOP_LSZoneInfo 0x3001
#define ServerOP_LSZoneStart 0x3002
#define ServerOP_LSZoneBoot 0x3003
@@ -1263,6 +1265,22 @@ struct ServerRequestTellQueue_Struct {
char name[64];
};
struct ServerRequestClientFileStatus
{
int zone_id;
int instance_id;
char name[64];
};
struct ServerResponseClientFileStatus
{
char name[64];
bool spells;
bool skills;
bool base_data;
bool eqgame;
};
#pragma pack()
#endif