Sorry Poor My English..
I Received LiveCompat EQEmu Sources (0.61 Dr1) From CVS .. Recently..
And Compiled it Succesfully..
But I Cannot LogIn In the World By MiniLogin ...
I Guess The Problem is My Source Changing Miss..
There is Two Linux Only Supported Sources..
It was EQStreamFactory.cpp And EQStream.cpp..
Then.. I Change The Two Source..
My Programming is Poor..
So.. I Dont Correct Perfectly These Sources..I Guess..
If you can.. Please advise me..
Now Packet Debug Logs.. Bellow..
-----------------------------------------------------------------
19 127.0.0.1:3338 127.0.0.1:5999 16 Send
0000 01 10 10 00 00 00 00 00 00 00 00 00 02 00 00 00 ................
20 127.0.0.1:5999 127.0.0.1:3338 75 Recv
0000 02 10 4B 00 00 00 00 00 83 F0 10 90 0F 88 C2 2B ..K............+
0010 51 5E FF 48 F3 CF 00 00 00 00 00 00 00 00 00 00 Q^.H............
0020 00 00 00 00 00 00 51 4D 56 31 49 37 48 4E 47 37 ......QMV1I7HNG7
0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0040 00 00 00 00 00 00 00 7F 00 00 01 ...........
21 127.0.0.1:3338 127.0.0.1:5999 16 Send
0000 01 10 10 00 00 00 00 00 00 00 00 00 02 00 00 00 ................
22 :0 0.0.0.0:9000 48 RecvFrom
0000 32 00 00 00 38 46 01 00 51 12 78 5E 33 34 30 35 2...8F..Q.x^3405
0010 34 63 08 F4 0D 33 F4 34 F7 F0 73 37 67 18 62 E0 4c...3.4..s7g.b.
0020 CC 10 73 2F AD 9C 0B 00 52 AA 04 83 5D 69 80 4A ..s/....R...]i.J
23 :0 0.0.0.0:9000 48 RecvFrom
0000 32 00 00 01 38 46 01 00 51 12 78 5E 33 34 30 35 2...8F..Q.x^3405
0010 34 63 08 F4 0D 33 F4 34 F7 F0 73 37 67 18 62 E0 4c...3.4..s7g.b.
0020 CC 10 73 2F AD 9C 0B 00 52 AA 04 83 B5 7E 10 EB ..s/....R....~..
-----------------------------------------------------------------
... This Packet do not Progress Any More..
0 0.0.0.0:9000 48 RecvFrom -- Packet Repeatly Continue..
Here is My Change Source..
-----------------------------------------------------------------EQStreamFactory.cpp
-----------------------------------------------------------------
#include "EQStreamFactory.h"
// Changed
#ifdef WIN32
#include <process.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>
#include <pthread.h>
#endif
#include <iostream>
#include "op_codes.h"
#include "EQStream.h"
using namespace std;
// Changed
//#ifdef WIN32
// void EQStreamFactoryReaderLoop(void *eqfs)
//#else
// void *EQStreamFactoryReaderLoop(void *eqfs)
//#endif
void *EQStreamFactoryReaderLoop(void *eqfs)
{
EQStreamFactory *fs=(EQStreamFactory *)eqfs;
cout << "Starting factory Reader" << endl;
fs->ReaderLoop();
// Changed
//return NULL;
#ifdef WIN32
_endthread();
return 0;
#else
return 0;
#endif
}
// Changed
//#ifdef WIN32
// void EQStreamFactoryWriterLoop(void *eqfs)
//#else
// void *EQStreamFactoryWriterLoop(void *eqfs)
//#endif
void *EQStreamFactoryWriterLoop(void *eqfs)
{
EQStreamFactory *fs=(EQStreamFactory *)eqfs;
cout << "Starting factory Writer" << endl;
fs->WriterLoop();
// Changed
//return NULL;
#ifdef WIN32
_endthread();
return 0;
#else
return 0;
#endif
}
EQStreamFactory::EQStreamFactory(EQStreamType type, int port) : Timeoutable(5000)
{
StreamType=type;
Port=port;
}
void EQStreamFactory::Close()
{
Stop();
// Changed
//close(sock);
#ifdef WIN32
closesocket(sock);
#else
close(sock);
#endif
sock=-1;
}
bool EQStreamFactory::Open()
{
struct sockaddr_in address;
//Changed
//pthread_t t1,t2;
#ifdef WIN32
unsigned long nonblocking = 1;
#endif
/* Setup internet address information.
This is used with the bind() call */
memset((char *) &address, 0, sizeof(address));
address.sin_family = AF_INET;
address.sin_port = htons(Port);
address.sin_addr.s_addr = htonl(INADDR_ANY);
/* Setting up UDP port for new clients */
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
return false;
}
if (bind(sock, (struct sockaddr *) &address, sizeof(address)) < 0) {
// Changed
//close(sock);
#ifdef WIN32
closesocket(sock);
#else
close(sock);
#endif
sock=-1;
return false;
}
// Changed
//fcntl(sock, F_SETFL, O_NONBLOCK);
#ifdef WIN32
ioctlsocket (sock, FIONBIO, &nonblocking);
#else
fcntl(sock, F_SETFL, O_NONBLOCK);
#endif
//Changed
//pthread_create(&t1,NULL,EQStreamFactoryReaderLoop, this);
//pthread_create(&t2,NULL,EQStreamFactoryWriterLoop, this);
#ifdef WIN32
_beginthread((void (__cdecl *)(void *))EQStreamFactoryReaderLoop, 0, this);
_beginthread((void (__cdecl *)(void *))EQStreamFactoryWriterLoop, 0, this);
//_beginthread(EQStreamFactoryReaderLoop, 0, this);
//_beginthread(EQStreamFactoryWriterLoop, 0, this);
#else
pthread_t t1;
pthread_create(&t1, NULL, EQStreamFactoryReaderLoop, this);
pthread_t t2;
pthread_create(&t2, NULL, EQStreamFactoryWriterLoop, this);
#endif
return true;
}
EQStream *EQStreamFactory::Pop()
{
EQStream *s=NULL;
//cout << "Pop():Locking MNewStreams" << endl;
MNewStreams.lock();
if (NewStreams.size()) {
s=NewStreams.front();
NewStreams.pop();
s->SetInUse(true);
}
MNewStreams.unlock();
//cout << "Pop(): Unlocking MNewStreams" << endl;
return s;
}
void EQStreamFactory::Push(EQStream *s)
{
//cout << "Push():Locking MNewStreams" << endl;
MNewStreams.lock();
NewStreams.push(s);
MNewStreams.unlock();
//cout << "Push(): Unlocking MNewStreams" << endl;
}
void EQStreamFactory::ReaderLoop()
{
fd_set readset;
map<string,EQStream *>::iterator stream_itr;
int num;
int length;
unsigned char buffer[2048];
sockaddr_in from;
int socklen=sizeof(sockaddr_in);
timeval sleep_time;
ReaderRunning=true;
while(sock!=-1) {
MReaderRunning.lock();
if (!ReaderRunning)
break;
MReaderRunning.unlock();
FD_ZERO(&readset);
FD_SET(sock,&readset);
sleep_time.tv_sec=30;
sleep_time.tv_usec=0;
if ((num=select(sock+1,&readset,NULL,NULL,&sleep_time ))<0) {
// What do we wanna do?
} else if (num==0)
continue;
if (FD_ISSET(sock,&readset)) {
// Changed
//if ((length=recvfrom(sock,buffer,2048,0,(struct sockaddr *)&from,(socklen_t *)&socklen))<0) {
#ifdef WIN32
if ((length=recvfrom(sock,(char *)buffer,2048,0,(struct sockaddr *)&from,(int *)&socklen))<0) {
#else
if ((length=recvfrom(sock,buffer,2048,0,(struct sockaddr *)&from,(socklen_t *)&socklen))<0) {
#endif
// What do we wanna do?
} else {
char temp[25];
sprintf(temp,"%lu.%d",ntohl(from.sin_addr.s_addr), ntohs(from.sin_port));
if ((stream_itr=Streams.find(temp))==Streams.end()) {
if (buffer[1]==OP_SessionRequest) {
EQStream *s=new EQStream(from);
s->SetFactory(this);
s->SetStreamType(StreamType);
Streams[temp]=s;
Push(s);
s->Process(buffer,length);
s->SetLastPacketTime(Timer::GetCurrentTime());
}
} else {
stream_itr->second->Process(buffer,length);
stream_itr->second->SetLastPacketTime(Timer::GetCurrentTime());
}
}
}
}
}
void EQStreamFactory::CheckTimeout()
{
unsigned long now=Timer::GetCurrentTime();
map<string,EQStream *>::iterator stream_itr;
for(stream_itr=Streams.begin();stream_itr!=Streams .end()
{
bool in_use=stream_itr->second->InUse();
int state=stream_itr->second->GetState();
bool remove_connection=false;
//cout << "Checking timeout" << endl;
if (state==CLOSING && !stream_itr->second->HasOutgoingData()) {
remove_connection=true;
} else if (state==CLOSED) {
if (in_use)
;//stream_itr->second->Closed();
else
remove_connection=true;
} else if (stream_itr->second->CheckTimeout(now,30000)) {
cout << "Timeout up!, state=" << state << endl;
if (state==ESTABLISHED) {
//if (in_use)
//stream_itr->second->Timeout();
stream_itr->second->SendDisconnect();
} else if (state==CLOSING) {
stream_itr->second->SetState(CLOSED);
}
}
if (remove_connection) {
cout << "Removing connection" << endl;
map<string,EQStream *>::iterator temp=stream_itr;
stream_itr++;
delete temp->second;
Streams.erase(temp);
continue;
}
stream_itr++;
}
}
void EQStreamFactory::WriterLoop()
{
map<string,EQStream *>::iterator stream_itr;
bool havework=true;
WriterRunning=true;
while(sock!=-1) {
//if (!havework) {
//WriterWork.Wait();
//}
MWriterRunning.lock();
if (!WriterRunning)
break;
MWriterRunning.unlock();
havework=false;
for(stream_itr=Streams.begin();stream_itr!=Streams .end();stream_itr++) {
if (stream_itr->second->HasOutgoingData()) {
havework=true;
stream_itr->second->Write(sock);
}
}
Sleep(150);
}
}
------------------------------------------------------------------
Have a Good Time...