mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
310 lines
8.5 KiB
C++
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
|