Kelsidavis-WoWee/include/game/game_handler.hpp

310 lines
8.5 KiB
C++

#pragma once
#include "game/world_packets.hpp"
#include "game/character.hpp"
#include "game/inventory.hpp"
#include <memory>
#include <string>
#include <vector>
#include <functional>
#include <cstdint>
namespace wowee {
namespace network { class WorldSocket; class Packet; }
namespace game {
/**
* World connection state
*/
enum class WorldState {
DISCONNECTED, // Not connected
CONNECTING, // TCP connection in progress
CONNECTED, // Connected, waiting for challenge
CHALLENGE_RECEIVED, // Received SMSG_AUTH_CHALLENGE
AUTH_SENT, // Sent CMSG_AUTH_SESSION, encryption initialized
AUTHENTICATED, // Received SMSG_AUTH_RESPONSE success
READY, // Ready for character/world operations
CHAR_LIST_REQUESTED, // CMSG_CHAR_ENUM sent
CHAR_LIST_RECEIVED, // SMSG_CHAR_ENUM received
ENTERING_WORLD, // CMSG_PLAYER_LOGIN sent
IN_WORLD, // In game world
FAILED // Connection or authentication failed
};
/**
* World connection callbacks
*/
using WorldConnectSuccessCallback = std::function<void()>;
using WorldConnectFailureCallback = std::function<void(const std::string& reason)>;
/**
* GameHandler - Manages world server connection and game protocol
*
* Handles:
* - Connection to world server
* - Authentication with session key from auth server
* - RC4 header encryption
* - Character enumeration
* - World entry
* - Game packets
*/
class GameHandler {
public:
GameHandler();
~GameHandler();
/**
* Connect to world server
*
* @param host World server hostname/IP
* @param port World server port (default 8085)
* @param sessionKey 40-byte session key from auth server
* @param accountName Account name (will be uppercased)
* @param build Client build number (default 12340 for 3.3.5a)
* @return true if connection initiated
*/
bool connect(const std::string& host,
uint16_t port,
const std::vector<uint8_t>& sessionKey,
const std::string& accountName,
uint32_t build = 12340);
/**
* Disconnect from world server
*/
void disconnect();
/**
* Check if connected to world server
*/
bool isConnected() const;
/**
* Get current connection state
*/
WorldState getState() const { return state; }
/**
* Request character list from server
* Must be called when state is READY or AUTHENTICATED
*/
void requestCharacterList();
/**
* Get list of characters (available after CHAR_LIST_RECEIVED state)
*/
const std::vector<Character>& getCharacters() const { return characters; }
/**
* Select and log in with a character
* @param characterGuid GUID of character to log in with
*/
void selectCharacter(uint64_t characterGuid);
/**
* Get current player movement info
*/
const MovementInfo& getMovementInfo() const { return movementInfo; }
/**
* Send a movement packet
* @param opcode Movement opcode (CMSG_MOVE_START_FORWARD, etc.)
*/
void sendMovement(Opcode opcode);
/**
* Update player position
* @param x X coordinate
* @param y Y coordinate
* @param z Z coordinate
*/
void setPosition(float x, float y, float z);
/**
* Update player orientation
* @param orientation Facing direction in radians
*/
void setOrientation(float orientation);
/**
* Get entity manager (for accessing entities in view)
*/
EntityManager& getEntityManager() { return entityManager; }
const EntityManager& getEntityManager() const { return entityManager; }
/**
* Send a chat message
* @param type Chat type (SAY, YELL, WHISPER, etc.)
* @param message Message text
* @param target Target name (for whispers, empty otherwise)
*/
void sendChatMessage(ChatType type, const std::string& message, const std::string& target = "");
/**
* Get chat history (recent messages)
* @param maxMessages Maximum number of messages to return (0 = all)
* @return Vector of chat messages
*/
std::vector<MessageChatData> getChatHistory(size_t maxMessages = 50) const;
/**
* Add a locally-generated chat message (e.g., emote feedback)
*/
void addLocalChatMessage(const MessageChatData& msg);
// Inventory
Inventory& getInventory() { return inventory; }
const Inventory& getInventory() const { return inventory; }
// Targeting
void setTarget(uint64_t guid);
void clearTarget();
uint64_t getTargetGuid() const { return targetGuid; }
std::shared_ptr<Entity> getTarget() const;
bool hasTarget() const { return targetGuid != 0; }
void tabTarget(float playerX, float playerY, float playerZ);
/**
* Set callbacks
*/
void setOnSuccess(WorldConnectSuccessCallback callback) { onSuccess = callback; }
void setOnFailure(WorldConnectFailureCallback callback) { onFailure = callback; }
/**
* Update - call regularly (e.g., each frame)
*
* @param deltaTime Time since last update in seconds
*/
void update(float deltaTime);
private:
/**
* Handle incoming packet from world server
*/
void handlePacket(network::Packet& packet);
/**
* Handle SMSG_AUTH_CHALLENGE from server
*/
void handleAuthChallenge(network::Packet& packet);
/**
* Handle SMSG_AUTH_RESPONSE from server
*/
void handleAuthResponse(network::Packet& packet);
/**
* Handle SMSG_CHAR_ENUM from server
*/
void handleCharEnum(network::Packet& packet);
/**
* Handle SMSG_LOGIN_VERIFY_WORLD from server
*/
void handleLoginVerifyWorld(network::Packet& packet);
/**
* Handle SMSG_ACCOUNT_DATA_TIMES from server
*/
void handleAccountDataTimes(network::Packet& packet);
/**
* Handle SMSG_MOTD from server
*/
void handleMotd(network::Packet& packet);
/**
* Handle SMSG_PONG from server
*/
void handlePong(network::Packet& packet);
/**
* Handle SMSG_UPDATE_OBJECT from server
*/
void handleUpdateObject(network::Packet& packet);
/**
* Handle SMSG_DESTROY_OBJECT from server
*/
void handleDestroyObject(network::Packet& packet);
/**
* Handle SMSG_MESSAGECHAT from server
*/
void handleMessageChat(network::Packet& packet);
/**
* Send CMSG_PING to server (heartbeat)
*/
void sendPing();
/**
* Send CMSG_AUTH_SESSION to server
*/
void sendAuthSession();
/**
* Generate random client seed
*/
uint32_t generateClientSeed();
/**
* Change state with logging
*/
void setState(WorldState newState);
/**
* Fail connection with reason
*/
void fail(const std::string& reason);
// Network
std::unique_ptr<network::WorldSocket> socket;
// State
WorldState state = WorldState::DISCONNECTED;
// Authentication data
std::vector<uint8_t> sessionKey; // 40-byte session key from auth server
std::string accountName; // Account name
uint32_t build = 12340; // Client build (3.3.5a)
uint32_t clientSeed = 0; // Random seed generated by client
uint32_t serverSeed = 0; // Seed from SMSG_AUTH_CHALLENGE
// Characters
std::vector<Character> characters; // Character list from SMSG_CHAR_ENUM
// Movement
MovementInfo movementInfo; // Current player movement state
uint32_t movementTime = 0; // Movement timestamp counter
// Inventory
Inventory inventory;
// Entity tracking
EntityManager entityManager; // Manages all entities in view
// Chat
std::vector<MessageChatData> chatHistory; // Recent chat messages
size_t maxChatHistory = 100; // Maximum chat messages to keep
// Targeting
uint64_t targetGuid = 0;
std::vector<uint64_t> tabCycleList;
int tabCycleIndex = -1;
bool tabCycleStale = true;
// Heartbeat
uint32_t pingSequence = 0; // Ping sequence number (increments)
float timeSinceLastPing = 0.0f; // Time since last ping sent (seconds)
float pingInterval = 30.0f; // Ping interval (30 seconds)
uint32_t lastLatency = 0; // Last measured latency (milliseconds)
// Callbacks
WorldConnectSuccessCallback onSuccess;
WorldConnectFailureCallback onFailure;
};
} // namespace game
} // namespace wowee