1
0
Protocol/old/common/EQStreamFactory.h
2025-09-01 12:31:14 -05:00

126 lines
3.3 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 "../common/EQStream.h"
#include "../common/Condition.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
Condition WriterWork; // Condition variable for writer thread
// 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.Signal();
}
void StopCombinePacket() {
MCombinePacketRunning.lock();
CombinePacketRunning = false;
MCombinePacketRunning.unlock();
}
void SignalWriter() {
WriterWork.Signal();
}
};
#endif