Editing Mod protocol
From EMule Wiki
Warning: The database has been locked for maintenance, so you will not be able to save your edits right now. You may wish to cut-n-paste the text into a text file and save it for later.
The administrator who locked it offered this explanation: site maintenance
The edit can be undone.
Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 1: | Line 1: | ||
− | = Under construction = | + | =Under construction = |
THIS IS NOT FINAL.. feel free to edit. | THIS IS NOT FINAL.. feel free to edit. | ||
== Introduction == | == Introduction == | ||
− | + | Modprot is needed for more clean protocol extensions by eMule modders.... | |
− | |||
− | + | == Protocol == | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | === | + | === Hello === |
− | + | Set the modbit ot in in CT_EMULE_MISCOPTIONS2 | |
in baseclient.cpp, void CUpDownClient::SendHelloTypePacket(CSafeMemFile* data) | in baseclient.cpp, void CUpDownClient::SendHelloTypePacket(CSafeMemFile* data) | ||
Line 48: | Line 20: | ||
const UINT uSupportLargeFiles = 1; | const UINT uSupportLargeFiles = 1; | ||
const UINT uExtMultiPacket = 1; | const UINT uExtMultiPacket = 1; | ||
− | + | const UINT uReserved = 1; // mod bit | |
− | const UINT | + | |
const UINT uSupportsCryptLayer = thePrefs.IsClientCryptLayerSupported() ? 1 : 0; | const UINT uSupportsCryptLayer = thePrefs.IsClientCryptLayerSupported() ? 1 : 0; | ||
const UINT uRequestsCryptLayer = thePrefs.IsClientCryptLayerRequested() ? 1 : 0; | const UINT uRequestsCryptLayer = thePrefs.IsClientCryptLayerRequested() ? 1 : 0; | ||
Line 61: | Line 32: | ||
(uRequestsCryptLayer << 8) | | (uRequestsCryptLayer << 8) | | ||
(uSupportsCryptLayer << 7) | | (uSupportsCryptLayer << 7) | | ||
− | ( | + | (uReserved << 6) | |
(uExtMultiPacket << 5) | | (uExtMultiPacket << 5) | | ||
(uSupportLargeFiles << 4) | | (uSupportLargeFiles << 4) | | ||
Line 69: | Line 40: | ||
</pre> | </pre> | ||
− | |||
− | + | === Process hello. === | |
baseclient.cpp bool CUpDownClient::ProcessHelloTypePacket(CSafeMemFile* data) | baseclient.cpp bool CUpDownClient::ProcessHelloTypePacket(CSafeMemFile* data) | ||
Line 90: | Line 60: | ||
m_fRequestsCryptLayer = (temptag.GetInt() >> 8) & 0x01; | m_fRequestsCryptLayer = (temptag.GetInt() >> 8) & 0x01; | ||
m_fSupportsCryptLayer = (temptag.GetInt() >> 7) & 0x01; | m_fSupportsCryptLayer = (temptag.GetInt() >> 7) & 0x01; | ||
− | + | m_NeoModProtVersion = (temptag.GetInt() >> 6) & 0x01; // modbit NEO: NMP - [NeoModProt] <-- Xanatos -- | |
− | + | ||
m_fExtMultiPacket = (temptag.GetInt() >> 5) & 0x01; | m_fExtMultiPacket = (temptag.GetInt() >> 5) & 0x01; | ||
m_fSupportsLargeFiles = (temptag.GetInt() >> 4) & 0x01; | m_fSupportsLargeFiles = (temptag.GetInt() >> 4) & 0x01; | ||
Line 102: | Line 71: | ||
</pre> | </pre> | ||
− | == | + | |
+ | ==Send hello answer and modprot info == | ||
+ | |||
Listensocket.cpp bool CClientReqSocket::ProcessPacket(const BYTE* packet, uint32 size, UINT opcode) | Listensocket.cpp bool CClientReqSocket::ProcessPacket(const BYTE* packet, uint32 size, UINT opcode) | ||
Line 118: | Line 89: | ||
− | Example of | + | Example of sendmoinfopacket: |
<pre> | <pre> | ||
void CUpDownClient::SendModInfoPacket(){ | void CUpDownClient::SendModInfoPacket(){ | ||
− | if (socket == NULL){ | + | if (socket == NULL){ |
ASSERT(0); | ASSERT(0); | ||
return; | return; | ||
Line 129: | Line 100: | ||
CSafeMemFile data(128); | CSafeMemFile data(128); | ||
− | + | uint32 tagcount=2+1; | |
− | + | ||
− | + | #ifdef NATTUNNELING // NEO: NATT - [NatTraversal] | |
+ | if(theApp.IsFirewalled() && Kademlia::CKademlia::IsConnected()) | ||
+ | tagcount += 1; | ||
+ | #endif //NATTUNNELING // NEO: NATT END | ||
− | |||
− | |||
data.WriteUInt32(tagcount); // nr. of tags | data.WriteUInt32(tagcount); // nr. of tags | ||
− | CTag | + | |
+ | |||
+ | /************************************************************************************ | ||
+ | * Note: The meaning of the bit fields in the current sample * | ||
+ | * have to be reworked for the final release version numbers are almost useless, * | ||
+ | * support (or newver version) should be anounced only by single bit flags * | ||
+ | ************************************************************************************/ | ||
+ | |||
+ | #ifdef NATTUNNELING // NEO: NATT - [NatTraversal] | ||
+ | const UINT uNatT = NeoPrefs.IsNatTraversalEnabled(); | ||
+ | #endif //NATTUNNELING // NEO: NATT END | ||
+ | uint32 uNeoFeatures = | ||
+ | // ((0 & 0xff) << 24) | // Unused | ||
+ | // ((0 & 0x0f) << 20) | // Reserved | ||
+ | #ifdef NATTUNNELING // NEO: NATT - [NatTraversal] | ||
+ | // ((0 & 0x03) << 18) | // Reserved for nat-t | ||
+ | ((1 & 0x01) << 17) | // NEO: RTP - [ReuseTCPPort] | ||
+ | ((uNatT & 0x01) << 16) | // Support Nat Traversal | ||
+ | // ((0 & 0x01) << 15) | // NEO: XSB - [XSBuddy] | ||
+ | #endif //NATTUNNELING // NEO: NATT END | ||
+ | ((1 & 0x07) << 12) | // NEO: NXS - [NeoXS] | ||
+ | // ((0 & 0x03) << 10) | // Reserved | ||
+ | ((1 & 0x01) << 9 ) | // LowID UDP Ping Support (notifyes a fix form xman1 that allow the remote low ID to use udp reasks) // NEO: MOD - [NewUploadState] | ||
+ | ((1 & 0x01) << 8 ) | // Unsolicited Part Status (allows our client ro recieve filestatus at any time) // NEO: USPS - [UnSolicitedPartStatus] | ||
+ | // ((0 & 0x0f) << 4 ) | // Reserved | ||
+ | ((0 & 0x0f) << 0 ); | ||
+ | CTag tagNeoModProt(CT_NEO_FEATURES, uNeoFeatures); | ||
+ | tagNeoModProt.WriteTagToFile(&data); | ||
+ | |||
+ | uint32 nSCT = NeoPrefs.UseSubChunkTransfer() ? 1 : 0; // version 4 bit | ||
+ | uint32 ICSv2 = NeoPrefs.UseIncompletePartStatus() ? 2 : 0; // version 3 bit | ||
+ | // X-ToDo: | ||
+ | //uint32 RPS = NeoPrefs.UseRealPartStatus() ? 1 : 0; // version 3 bit | ||
+ | //uint32 HPS = NeoPrefs.UseRealPartStatus() ? 1 : 0; // flag 1 bit | ||
+ | //uint32 BPS = NeoPrefs.UseRealPartStatus() ? 1 : 0; // flag 1 bit | ||
+ | |||
+ | uint32 uFileStatus = | ||
+ | // ((0 & 0xff) << 24) | // unused | ||
+ | // ((0 & 0xff) << 16) | // reserved | ||
+ | // ((BPS & 0x01) << 15) | // RPS Flag Blocked Parts | ||
+ | // ((HPS & 0x01) << 14) | // RPS Flag Hiden Parts | ||
+ | // ((RPS & 0x07) << 11) | // RPS VErsion | ||
+ | ((ICSv2 & 0x07) << 8 ) | // ICSv2 Version | ||
+ | // ((0 & 0x0f) << 4 ) | // reserved | ||
+ | ((nSCT & 0x0f) << 0 ); // SCT version | ||
+ | CTag tagPartStatus(CT_EXT_FILESTATUS,uFileStatus); | ||
tagPartStatus.WriteNewEd2kTag(&data); | tagPartStatus.WriteNewEd2kTag(&data); | ||
− | // | + | #ifdef NATTUNNELING // NEO: NATT - [NatTraversal] |
− | // | + | if(theApp.IsFirewalled() && Kademlia::CKademlia::IsConnected()) |
− | CTag tagMyMail("Mod: | + | { |
+ | // Note: to connect a cleint over his buddy or to request a calback we need not only his buddy IP/Port but also his Buddy ID | ||
+ | // So to get this realy to work we need to transmitt the buddy ID to | ||
+ | Kademlia::CUInt128 uBuddyID(true); | ||
+ | uBuddyID.Xor(Kademlia::CKademlia::GetPrefs()->GetKadID()); | ||
+ | byte cID[16]; | ||
+ | uBuddyID.ToByteArray(cID); | ||
+ | CTag tagBuddyID(CT_EMULE_BUDDYID, cID); | ||
+ | tagBuddyID.WriteNewEd2kTag(&data); | ||
+ | } | ||
+ | #endif //NATTUNNELING // NEO: NATT END | ||
+ | |||
+ | // Named tag test begin | ||
+ | LPCTSTR FunnyStr[3]; | ||
+ | FunnyStr[0] = _T("Vote for the Pirate Party of your country"); | ||
+ | FunnyStr[1] = _T("Have a nice day ;)"); | ||
+ | FunnyStr[2] = _T("Confucius says: If you dont upload 10 GB/day good will punish you"); | ||
+ | CTag tagMyMail("Mod:Hello",FunnyStr[rand()%ARRSIZE(FunnyStr)]); | ||
tagMyMail.WriteNewEd2kTag(&data); | tagMyMail.WriteNewEd2kTag(&data); | ||
− | + | // Named tag test end | |
− | // | + | |
− | |||
Packet* packet = new Packet(&data,OP_MODPROT); | Packet* packet = new Packet(&data,OP_MODPROT); | ||
packet->opcode = OP_MODINFOPACKET; | packet->opcode = OP_MODINFOPACKET; | ||
Line 152: | Line 184: | ||
DebugSend("OP__ModInfoPacket", this); | DebugSend("OP__ModInfoPacket", this); | ||
theStats.AddUpDataOverheadOther(packet->size); | theStats.AddUpDataOverheadOther(packet->size); | ||
− | socket->SendPacket(packet,true,true); | + | socket->SendPacket(packet,true,true); |
} | } | ||
</pre> | </pre> | ||
− | === | + | === process modinfo packet === |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
listensocket.cpp | listensocket.cpp | ||
Line 298: | Line 247: | ||
CSafeMemFile data(pachPacket, nSize); | CSafeMemFile data(pachPacket, nSize); | ||
− | |||
uint32 tagcount = data.ReadUInt32(); | uint32 tagcount = data.ReadUInt32(); | ||
if (bDbgInfo) | if (bDbgInfo) | ||
m_strModInfo.AppendFormat(_T(" Tags=%u"), (UINT)tagcount); | m_strModInfo.AppendFormat(_T(" Tags=%u"), (UINT)tagcount); | ||
− | |||
for (uint32 i = 0; i < tagcount; i++) | for (uint32 i = 0; i < tagcount; i++) | ||
{ | { | ||
CTag temptag(&data, false); | CTag temptag(&data, false); | ||
− | switch (temptag.GetNameID()) | + | switch (temptag.GetNameID()) |
{ | { | ||
− | case | + | case CT_NEO_FEATURES: |
− | if (temptag. | + | if (temptag.IsInt()){ |
− | + | // = (uint8)(temptag.GetInt() >> 24) & 0xff; | |
− | else if (bDbgInfo) | + | // = (uint8)(temptag.GetInt() >> 20) & 0x0f; |
− | + | #ifdef NATTUNNELING // NEO: NATT - [NatTraversal] | |
+ | // = (uint8)(temptag.GetInt() >> 18) & 0x03; | ||
+ | m_PublicPortReport = (uint8)(temptag.GetInt() >> 17) & 0x01; // NEO: RTP - [ReuseTCPPort] | ||
+ | m_SupportsNatTraversal = (uint8)(temptag.GetInt() >> 16) & 0x01; | ||
+ | // = (uint8)(temptag.GetInt() >> 15) & 0x01; // NEO: XSB - [XSBuddy] | ||
+ | #endif //NATTUNNELING // NEO: NATT END | ||
+ | m_NeoXSVersion = (uint8)(temptag.GetInt() >> 12) & 0x07; // NEO: NXS - [NeoXS] | ||
+ | // = (uint8)(temptag.GetInt() >> 10) & 0x03; | ||
+ | m_LowIDUDPPingSupport = (uint8)(temptag.GetInt() >> 9 ) & 0x01; | ||
+ | m_UnsolicitedPartStatus = (uint8)(temptag.GetInt() >> 8 ) & 0x01; | ||
+ | // = (uint8)(temptag.GetInt() >> 4 ) & 0x0f; | ||
+ | // = (uint8)(temptag.GetInt() >> 0 ) & 0x0f; | ||
+ | }else if (bDbgInfo) | ||
+ | m_strHelloInfo.AppendFormat(_T("\n ***UnkType=%s"), temptag.GetFullInfo()); | ||
break; | break; | ||
+ | case CT_EXT_FILESTATUS: | ||
+ | if (temptag.IsInt()){ | ||
+ | |||
+ | // X-ToDo | ||
+ | // = (uint8)(temptag.GetInt() >> 24) & 0xff; | ||
+ | // = (uint8)(temptag.GetInt() >> 16) & 0xff; | ||
+ | //uint8 BlockedPartStatus = (uint8)(temptag.GetInt() >> 15) & 0x01; | ||
+ | //uint8 HidenPartStatus = (uint8)(temptag.GetInt() >> 14) & 0x01; | ||
+ | //uint8 RealPartStatusVer = (uint8)(temptag.GetInt() >> 11) & 0x07; | ||
+ | m_IncompletePartVer = (uint8)(temptag.GetInt() >> 8 ) & 0x07; | ||
+ | // = (uint8)(temptag.GetInt() >> 4 ) & 0x0f; | ||
+ | m_SubChunksVer = (uint8)(temptag.GetInt() >> 0 ) & 0x0f; | ||
+ | |||
+ | //ASSERT(BlockedPartStatus || HidenPartStatus || !RealPartStatusVer); | ||
+ | // Note: RPC version without one or booth RPS flags is invalid, | ||
+ | // the cleint must always say wha is he doint gith the parts 'blocking and hiding' or 'only hiding', | ||
+ | // or he can booth depanding on the situation | ||
+ | // Booth RPS versions have always teh same version as the writing functions are identical | ||
+ | // just other opcodes are used and other part states notifyed | ||
+ | //if(BlockedPartStatus) | ||
+ | // m_BlockedPartStatusVer = RealPartStatusVer; | ||
+ | //if(HidenPartStatus) | ||
+ | // m_HidenPartStatusVer = RealPartStatusVer; | ||
+ | |||
+ | }else if (bDbgInfo) | ||
+ | m_strModInfo.AppendFormat(_T("\n ***UnkType=%s"), temptag.GetFullInfo()); | ||
+ | break; | ||
+ | #ifdef NATTUNNELING // NEO: NATT - [NatTraversal] | ||
+ | case CT_EMULE_BUDDYID: | ||
+ | if(temptag.IsHash()) | ||
+ | { | ||
+ | SetBuddyID(temptag.GetHash()); | ||
+ | } | ||
+ | else{ | ||
+ | if (bDbgInfo) | ||
+ | m_strModInfo.AppendFormat(_T("\n ***UnkType=%s"), temptag.GetFullInfo()); | ||
+ | } | ||
+ | break; | ||
+ | #endif //NATTUNNELING // NEO: NATT END | ||
default: | default: | ||
− | // | + | // Named tag test begin |
if(strcmp(temptag.GetName(),"Mod:Hello") == 0) | if(strcmp(temptag.GetName(),"Mod:Hello") == 0) | ||
{ | { | ||
Line 324: | Line 323: | ||
} | } | ||
else | else | ||
+ | // Named tag test end | ||
if (bDbgInfo) | if (bDbgInfo) | ||
Line 329: | Line 329: | ||
} | } | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</pre> | </pre> | ||
− | |||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | === proces mod data example === | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
Line 367: | Line 354: | ||
<pre> | <pre> | ||
// NEO: NMP - [NeoModProt] -- Xanatos --> | // NEO: NMP - [NeoModProt] -- Xanatos --> | ||
− | |||
case OP_MODPACKEDPROT: | case OP_MODPACKEDPROT: | ||
if (!packet->UnPackPacket()){ | if (!packet->UnPackPacket()){ | ||
Line 387: | Line 373: | ||
try | try | ||
{ | { | ||
− | |||
if (!client) | if (!client) | ||
{ | { | ||
Line 396: | Line 381: | ||
ASSERT_VALID(client); | ASSERT_VALID(client); | ||
− | switch(opcode) | + | switch(opcode) |
{ | { | ||
− | |||
case OP_MODINFOPACKET: | case OP_MODINFOPACKET: | ||
{ | { | ||
Line 405: | Line 389: | ||
theStats.AddDownDataOverheadOther(uRawSize); | theStats.AddDownDataOverheadOther(uRawSize); | ||
− | if(client-> | + | if(client->GetNeoModProtVersion() == 0) |
throw CString(_T("Recieved Neo Mod Info Packet from a cleint whitch doe snot support this feature!")); | throw CString(_T("Recieved Neo Mod Info Packet from a cleint whitch doe snot support this feature!")); | ||
− | |||
client->ProcessModInfoPacket(packet,size); | client->ProcessModInfoPacket(packet,size); | ||
Line 421: | Line 404: | ||
} | } | ||
− | + | // NEO: NMPm - [NeoModProtMultiPacket] | |
− | + | case OP_MODMULTIPACKET: | |
+ | { | ||
+ | if (thePrefs.GetDebugClientTCPLevel() > 0) | ||
+ | DebugRecv("OP_ModMultiPacket", client, (size >= 24) ? packet : NULL); | ||
+ | |||
+ | theStats.AddDownDataOverheadFileRequest(uRawSize); | ||
+ | client->CheckHandshakeFinished(); | ||
+ | |||
+ | CSafeMemFile data_in(packet, size); | ||
+ | uchar reqfilehash[16]; | ||
+ | data_in.ReadHash16(reqfilehash); | ||
+ | CKnownFile* reqfile; | ||
+ | if ( (reqfile = theApp.sharedfiles->GetFileByID(reqfilehash)) == NULL ){ | ||
+ | if ( !((reqfile = theApp.downloadqueue->GetFileByID(reqfilehash)) != NULL | ||
+ | && reqfile->GetFileSize() > (uint64)PARTSIZE) ){ | ||
+ | client->CheckFailedFileIdReqs(reqfilehash); | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | CClientFileStatus* status = client->GetFileStatus(reqfile, true); // NEO: SCFS - [SmartClientFileStatus] | ||
+ | |||
+ | client->ReadModMultiPacket(&data_in,reqfile,status); | ||
+ | // NEO: BPS - [BetterPassiveSourceFinding] | ||
+ | //if(reqfile->IsPartFile() && !(client->GetDownloadState()==DS_ONQUEUE && reqfile==client->GetRequestFile())) | ||
+ | // client->ProcessModFileStatus(true, status, (CPartFile*)reqfile, true); // NEO: SCFS - [SmartClientFileStatus] | ||
+ | // NEO: BPS END | ||
+ | |||
+ | ///////////////////// answer | ||
+ | |||
+ | CSafeMemFile data_out(128); | ||
+ | data_out.WriteHash16(reqfile->GetFileHash()); | ||
+ | |||
+ | client->WriteModMultiPacket(&data_out, reqfile, status, false); | ||
+ | |||
+ | if (data_out.GetLength() > 16) | ||
+ | { | ||
+ | if (thePrefs.GetDebugClientTCPLevel() > 0) | ||
+ | DebugSend("OP__ModMultiPacketAns", client, reqfile->GetFileHash()); | ||
+ | Packet* reply = new Packet(&data_out, OP_MODPROT); | ||
+ | reply->opcode = OP_MODMULTIPACKETANSWER; | ||
+ | theStats.AddUpDataOverheadFileRequest(reply->size); | ||
+ | SendPacket(reply, true); | ||
+ | } | ||
+ | break; | ||
+ | } | ||
+ | case OP_MODMULTIPACKETANSWER: | ||
+ | { | ||
+ | if (thePrefs.GetDebugClientTCPLevel() > 0) | ||
+ | DebugRecv("OP_ModMultiPacketAns", client, (size >= 16) ? packet : NULL); | ||
+ | |||
+ | theStats.AddDownDataOverheadFileRequest(uRawSize); | ||
+ | client->CheckHandshakeFinished(); | ||
+ | |||
+ | CSafeMemFile data_in(packet, size); | ||
+ | uchar reqfilehash[16]; | ||
+ | data_in.ReadHash16(reqfilehash); | ||
+ | CPartFile* reqfile = theApp.downloadqueue->GetFileByID(reqfilehash); | ||
+ | //Make sure we are downloading this file. | ||
+ | if (reqfile==NULL){ | ||
+ | client->CheckFailedFileIdReqs(reqfilehash); | ||
+ | throw GetResString(IDS_ERR_WRONGFILEID) + _T(" (OP_MODMULTIPACKETANSWER; reqfile==NULL)"); | ||
+ | } | ||
+ | if (client->GetRequestFile()==NULL) | ||
+ | throw GetResString(IDS_ERR_WRONGFILEID) + _T(" (OP_MODMULTIPACKETANSWER; client->GetRequestFile()==NULL)"); | ||
+ | if (reqfile != client->GetRequestFile()) | ||
+ | throw GetResString(IDS_ERR_WRONGFILEID) + _T(" (OP_MODMULTIPACKETANSWER; reqfile!=client->GetRequestFile())"); | ||
+ | |||
+ | CClientFileStatus* status = client->GetFileStatus(reqfile, true); // NEO: SCFS - [SmartClientFileStatus] | ||
+ | |||
+ | client->ReadModMultiPacket(&data_in,reqfile,status); | ||
+ | client->ProcessModFileStatus(false, status, reqfile); | ||
+ | |||
+ | break; | ||
+ | } | ||
+ | // NEO: NMPm END | ||
+ | |||
+ | // NEO: SCT - [SubChunkTransfer] | ||
+ | case OP_SUBCHUNKMAPS: | ||
+ | { | ||
+ | if (thePrefs.GetDebugClientTCPLevel() > 0) | ||
+ | DebugRecv("OP_SubChunkMaps", client, (size >= 16) ? packet : NULL); | ||
+ | theStats.AddDownDataOverheadFileRequest(size); | ||
+ | |||
+ | CSafeMemFile data(packet, size); | ||
+ | uchar cfilehash[16]; | ||
+ | data.ReadHash16(cfilehash); | ||
+ | |||
+ | CPartFile* reqfile = theApp.downloadqueue->GetFileByID(cfilehash); | ||
+ | if (reqfile == NULL){ | ||
+ | client->CheckFailedFileIdReqs(cfilehash); | ||
+ | break; | ||
+ | } | ||
+ | |||
+ | CClientFileStatus* status = client->GetFileStatus(reqfile, true); | ||
+ | status->ReadSubChunkMaps(&data); | ||
+ | if(client->GetDownloadState() == DS_NONEEDEDPARTS) // the file must be NNP or we will perform a secund unned ask | ||
+ | client->ProcessModFileStatus(false, status, reqfile); | ||
+ | break; | ||
+ | } | ||
+ | // NEO: SCT END | ||
+ | |||
+ | case OP_FILEINCSTATUS: | ||
+ | //case OP_FILEHIDENSTATUS: | ||
+ | //case OP_FILEBLOCKEDSTATUS: | ||
+ | { | ||
+ | EPartStatus type = CFS_Normal; | ||
+ | switch(opcode){ | ||
+ | // NEO: ICS - [InteligentChunkSelection] | ||
+ | case OP_FILEINCSTATUS: | ||
+ | type = CFS_Incomplete; | ||
+ | if (thePrefs.GetDebugClientTCPLevel() > 0) | ||
+ | DebugRecv("OP_FileImcompleteStatus", client, (size >= 16) ? packet : NULL); | ||
+ | break; | ||
+ | // NEO: ICS END | ||
+ | // NEO: RPS - [RealPartStatus] | ||
+ | /*case OP_FILEHIDENSTATUS: | ||
+ | type = CFS_Hiden; | ||
+ | if (thePrefs.GetDebugClientTCPLevel() > 0) | ||
+ | DebugRecv("OP_FileHidenStatus", client, (size >= 16) ? packet : NULL); | ||
+ | break; | ||
+ | case OP_FILEBLOCKEDSTATUS: | ||
+ | type = CFS_Blocked; | ||
+ | if (thePrefs.GetDebugClientTCPLevel() > 0) | ||
+ | DebugRecv("OP_FileBlockedStatus", client, (size >= 16) ? packet : NULL); | ||
+ | break;*/ | ||
+ | // NEO: RPS END | ||
+ | } | ||
+ | theStats.AddDownDataOverheadFileRequest(size); | ||
+ | |||
+ | CSafeMemFile data(packet, size); | ||
+ | uchar cfilehash[16]; | ||
+ | data.ReadHash16(cfilehash); | ||
+ | |||
+ | CKnownFile* reqfile = theApp.sharedfiles->GetFileByID(cfilehash); | ||
+ | if(reqfile == NULL) | ||
+ | reqfile = (CKnownFile*)theApp.downloadqueue->GetFileByID(cfilehash); | ||
+ | if (reqfile == NULL){ | ||
+ | client->CheckFailedFileIdReqs(cfilehash); | ||
+ | break; | ||
+ | } | ||
+ | |||
+ | CClientFileStatus* status = client->GetFileStatus(reqfile, true); | ||
+ | status->ReadFileStatus(&data, type); | ||
+ | reqfile->UpdatePartsInfoEx(type); | ||
+ | //if(reqfile->IsPartFile() && client->GetDownloadState() == DS_NONEEDEDPARTS && opcode == OP_FILEHIDENSTATUS) // only hidden status is interresant | ||
+ | // client->ProcessModFileStatus(false, status, (CPartFile*)reqfile, false, false, true); | ||
+ | break; | ||
+ | } | ||
+ | |||
+ | #ifdef NATTUNNELING // NEO: RTP - [ReuseTCPPort] | ||
+ | case OP_PUBLICPORT_ANSWER: | ||
+ | { | ||
+ | if (thePrefs.GetDebugClientTCPLevel() > 0) | ||
+ | DebugRecv("OP_PublicPortAns", client); | ||
+ | theStats.AddDownDataOverheadOther(uRawSize); | ||
+ | |||
+ | client->ProcessPublicPortAnswer(packet, size); | ||
+ | break; | ||
+ | } | ||
+ | case OP_PUBLICPORT_REQ: | ||
+ | { | ||
+ | if (thePrefs.GetDebugClientTCPLevel() > 0) | ||
+ | DebugRecv("OP_PublicPortReq", client); | ||
+ | theStats.AddDownDataOverheadOther(uRawSize); | ||
+ | |||
+ | if (thePrefs.GetDebugClientTCPLevel() > 0) | ||
+ | DebugSend("OP__PublicPortAns", client); | ||
+ | Packet* pPacket = new Packet(OP_PUBLICPORT_ANSWER, 2, OP_MODPROT); | ||
+ | |||
+ | SOCKADDR_IN sockAddr = {0}; | ||
+ | int nSockAddrLen = sizeof(sockAddr); | ||
+ | GetPeerName((SOCKADDR*)&sockAddr, &nSockAddrLen); | ||
+ | uint16 Port = ntohs(sockAddr.sin_port); | ||
+ | |||
+ | PokeUInt16(pPacket->pBuffer, Port); | ||
+ | theStats.AddUpDataOverheadOther(pPacket->size); | ||
+ | SendPacket(pPacket); | ||
+ | break; | ||
+ | } | ||
+ | #endif //NATTUNNELING // NEO: RTP END | ||
+ | |||
+ | // NEO: NXS - [NeoXS] | ||
+ | case OP_ANSWERSOURCES: | ||
+ | ProcessExtPacket(packet, size, opcode, uRawSize); // we use the same propacket processor as for the official XS | ||
+ | break; | ||
+ | // NEO: NXS END | ||
+ | |||
+ | default: | ||
theStats.AddDownDataOverheadOther(uRawSize); | theStats.AddDownDataOverheadOther(uRawSize); | ||
PacketToDebugLogLine(_T("ModProt"), packet, size, opcode); | PacketToDebugLogLine(_T("ModProt"), packet, size, opcode); | ||
Line 449: | Line 620: | ||
} | } | ||
return true; | return true; | ||
− | + | } | |
// NEO: NMP END <-- Xanatos -- | // NEO: NMP END <-- Xanatos -- | ||
</pre> | </pre> | ||
− | == | + | == backward compatibility == |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
+ | Modstring is still send and replied in hello packet to maintain backward compatibility However a opcode for modstring will be defined for those who alos want to move it to the mod protocol | ||
− | |||
− | |||
− | + | == tags == | |
− | + |