128 lines
3.4 KiB
C++
128 lines
3.4 KiB
C++
// EQ2Emulator: Everquest II Server Emulator
|
|
// Copyright (C) 2007 EQ2EMulator Development Team
|
|
// Licensed under GPL v3 - see <http://www.gnu.org/licenses/>
|
|
#ifndef _EQSTREAMFACTORY_H
|
|
#define _EQSTREAMFACTORY_H
|
|
|
|
#include <queue>
|
|
#include <map>
|
|
#include <string>
|
|
#include <memory>
|
|
#include <condition_variable>
|
|
#include <mutex>
|
|
|
|
#include "../common/EQStream.h"
|
|
#include "../common/opcodemgr.h"
|
|
#include "../common/timer.h"
|
|
|
|
#define STREAM_TIMEOUT 45000 // Stream timeout in milliseconds
|
|
|
|
/**
|
|
* Factory class for creating and managing EverQuest network streams.
|
|
* Handles UDP socket communication, stream lifecycle, and packet processing
|
|
* for both login and world server connections.
|
|
*/
|
|
class EQStreamFactory {
|
|
private:
|
|
// Network socket and configuration
|
|
int sock; // UDP socket file descriptor
|
|
int Port; // Port number to listen on
|
|
|
|
// Thread management flags and mutexes
|
|
bool ReaderRunning; // Reader thread active flag
|
|
Mutex MReaderRunning; // Mutex for reader thread flag
|
|
bool WriterRunning; // Writer thread active flag
|
|
Mutex MWriterRunning; // Mutex for writer thread flag
|
|
bool CombinePacketRunning; // Packet combiner thread active flag
|
|
Mutex MCombinePacketRunning; // Mutex for combiner thread flag
|
|
|
|
// Thread synchronization
|
|
std::condition_variable WriterWork; // Condition variable for writer thread
|
|
std::mutex WriterWorkMutex; // Mutex for condition variable
|
|
|
|
// Stream management
|
|
EQStreamType StreamType; // Type of streams this factory creates
|
|
std::queue<EQStream*> NewStreams; // Queue of new streams waiting for processing
|
|
Mutex MNewStreams; // Mutex for new streams queue
|
|
std::map<std::string, EQStream*> Streams; // Active streams mapped by address:port
|
|
Mutex MStreams; // Mutex for streams map
|
|
|
|
// Cleanup timer
|
|
Timer* DecayTimer; // Timer for periodic cleanup operations
|
|
|
|
public:
|
|
// Network configuration
|
|
char* listen_ip_address; // IP address to bind to (nullptr = any)
|
|
|
|
// Stream lifecycle management
|
|
void CheckTimeout(bool remove_all = false);
|
|
|
|
// Constructors and destructor
|
|
EQStreamFactory(EQStreamType type) {
|
|
ReaderRunning = false;
|
|
WriterRunning = false;
|
|
CombinePacketRunning = false;
|
|
StreamType = type;
|
|
sock = -1;
|
|
Port = 0;
|
|
listen_ip_address = nullptr;
|
|
DecayTimer = nullptr;
|
|
}
|
|
|
|
EQStreamFactory(EQStreamType type, int port);
|
|
|
|
~EQStreamFactory() {
|
|
safe_delete_array(listen_ip_address);
|
|
}
|
|
|
|
// Stream queue management
|
|
EQStream* Pop(); // Get next new stream from queue
|
|
void Push(EQStream* s); // Add new stream to queue
|
|
|
|
// Network operations
|
|
bool loadPublicKey(); // Load encryption keys (if needed)
|
|
bool Open(); // Open socket and start threads
|
|
bool Open(unsigned long port) {
|
|
Port = port;
|
|
return Open();
|
|
}
|
|
void Close(); // Close socket and stop threads
|
|
|
|
// Main thread loops
|
|
void ReaderLoop(); // Main packet reading loop
|
|
void WriterLoop(); // Main packet writing loop
|
|
void CombinePacketLoop(); // Packet combining optimization loop
|
|
|
|
// Thread control
|
|
void Stop() {
|
|
StopReader();
|
|
StopWriter();
|
|
StopCombinePacket();
|
|
}
|
|
|
|
void StopReader() {
|
|
MReaderRunning.lock();
|
|
ReaderRunning = false;
|
|
MReaderRunning.unlock();
|
|
}
|
|
|
|
void StopWriter() {
|
|
MWriterRunning.lock();
|
|
WriterRunning = false;
|
|
MWriterRunning.unlock();
|
|
WriterWork.notify_one();
|
|
}
|
|
|
|
void StopCombinePacket() {
|
|
MCombinePacketRunning.lock();
|
|
CombinePacketRunning = false;
|
|
MCombinePacketRunning.unlock();
|
|
}
|
|
|
|
void SignalWriter() {
|
|
WriterWork.notify_one();
|
|
}
|
|
};
|
|
|
|
#endif
|