Two-step login system works perfectly; can't shut the server down

I've also removed a large amount of commented and uncommented code from
in_world.cpp, simply because so much code was dummied out. I can readd
this code as I reimeplement various features.
This commit is contained in:
Kayne Ruse
2014-11-26 10:14:26 +11:00
parent 584b6ea303
commit e5abd51f76
4 changed files with 119 additions and 375 deletions
+78 -347
View File
@@ -23,12 +23,24 @@
#include "channels.hpp" #include "channels.hpp"
#include "utility.hpp" #include "utility.hpp"
#include "config_utility.hpp"
#include <stdexcept> #include <stdexcept>
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <iostream> #include <iostream>
#include <sstream>
//-------------------------
//these should've come standard
//-------------------------
bool operator==(IPaddress lhs, IPaddress rhs) {
return lhs.host == rhs.host && lhs.port == rhs.port;
}
bool operator!=(IPaddress lhs, IPaddress rhs) {
return !(lhs == rhs);
}
//------------------------- //-------------------------
//Public access members //Public access members
@@ -38,8 +50,6 @@ InWorld::InWorld(int* const argClientIndex, int* const argAccountIndex):
clientIndex(*argClientIndex), clientIndex(*argClientIndex),
accountIndex(*argAccountIndex) accountIndex(*argAccountIndex)
{ {
ConfigUtility& config = ConfigUtility::GetSingleton();
//setup the utility objects //setup the utility objects
buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp"); buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp");
buttonImage.SetClipH(buttonImage.GetClipH()/3); buttonImage.SetClipH(buttonImage.GetClipH()/3);
@@ -61,22 +71,6 @@ InWorld::InWorld(int* const argClientIndex, int* const argAccountIndex):
disconnectButton.SetText("Disconnect"); disconnectButton.SetText("Disconnect");
shutDownButton.SetText("Shut Down"); shutDownButton.SetText("Shut Down");
//load the tilesheet
//TODO: add the tilesheet to the map system?
//TODO: Tile size and tile sheet should be loaded elsewhere
tileSheet.Load(config["dir.tilesets"] + "overworld.bmp", 32, 32);
//send this player's character info
// CharacterPacket newPacket;
// newPacket.type = SerialPacketType::CHARACTER_NEW;
// strncpy(newPacket.handle, config["client.handle"].c_str(), PACKET_STRING_SIZE);
// strncpy(newPacket.avatar, config["client.avatar"].c_str(), PACKET_STRING_SIZE);
// newPacket.accountIndex = accountIndex;
// network.SendTo(Channels::SERVER, &newPacket);
//request a sync
// RequestSynchronize();
//debug //debug
// //
} }
@@ -94,58 +88,30 @@ void InWorld::FrameStart() {
} }
void InWorld::Update() { void InWorld::Update() {
//suck in and process all waiting packets //create and zero the buffer
SerialPacket* packetBuffer = reinterpret_cast<SerialPacket*>(new char[MAX_PACKET_SIZE]); SerialPacket* packetBuffer = reinterpret_cast<SerialPacket*>(new char[MAX_PACKET_SIZE]);
while(network.Receive(packetBuffer)) { memset(packetBuffer, 0, MAX_PACKET_SIZE);
HandlePacket(packetBuffer);
}
delete reinterpret_cast<char*>(packetBuffer);
//update the characters try {
for (auto& it : characterMap) { //suck in and process all waiting packets
it.second.Update(); while(network.Receive(packetBuffer)) {
} HandlePacket(packetBuffer);
//check the map
UpdateMap();
//skip the rest
if (!localCharacter) {
return;
}
//check for collisions with the map
BoundingBox wallBounds = {0, 0, tileSheet.GetTileW(), tileSheet.GetTileH()};
const int xCount = localCharacter->GetBounds().w / wallBounds.w + 1;
const int yCount = localCharacter->GetBounds().h / wallBounds.h + 1;
for (int i = -1; i <= xCount; ++i) {
for (int j = -1; j <= yCount; ++j) {
//set the wall's position
wallBounds.x = wallBounds.w * i + snapToBase((double)wallBounds.w, localCharacter->GetOrigin().x);
wallBounds.y = wallBounds.h * j + snapToBase((double)wallBounds.h, localCharacter->GetOrigin().y);
if (!regionPager.GetSolid(wallBounds.x / wallBounds.w, wallBounds.y / wallBounds.h)) {
continue;
}
if ((localCharacter->GetOrigin() + localCharacter->GetBounds()).CheckOverlap(wallBounds)) {
localCharacter->SetOrigin(localCharacter->GetOrigin() - (localCharacter->GetMotion()));
localCharacter->SetMotion({0,0});
localCharacter->CorrectSprite();
SendPlayerUpdate();
}
} }
} }
catch(std::exception& e) {
std::cerr << "HandlePacket Error: " << e.what() << std::endl;
}
//update the camera (following the player) //free the buffer
camera.x = localCharacter->GetOrigin().x - camera.marginX; delete reinterpret_cast<char*>(packetBuffer);
camera.y = localCharacter->GetOrigin().y - camera.marginY;
//check the connection //check the connection (heartbeat)
if (Clock::now() - lastBeat > std::chrono::seconds(3)) { if (Clock::now() - lastBeat > std::chrono::seconds(3)) {
if (attemptedBeats > 2) { if (attemptedBeats > 2) {
RequestDisconnect(); //two-step logout
SendLogoutRequest();
SendDisconnectRequest();
SetNextScene(SceneList::DISCONNECTEDSCREEN); SetNextScene(SceneList::DISCONNECTEDSCREEN);
ConfigUtility::GetSingleton()["client.disconnectMessage"] = "Error: Lost connection to the server"; ConfigUtility::GetSingleton()["client.disconnectMessage"] = "Error: Lost connection to the server";
} }
@@ -164,25 +130,13 @@ void InWorld::FrameEnd() {
} }
void InWorld::RenderFrame() { void InWorld::RenderFrame() {
// SDL_FillRect(GetScreen(), 0, 0); SDL_FillRect(GetScreen(), 0, 0);
Render(GetScreen()); Render(GetScreen());
SDL_Flip(GetScreen()); SDL_Flip(GetScreen());
fps.Calculate(); fps.Calculate();
} }
void InWorld::Render(SDL_Surface* const screen) { void InWorld::Render(SDL_Surface* const screen) {
//draw the map
for (std::list<Region>::iterator it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); it++) {
tileSheet.DrawRegionTo(screen, &(*it), camera.x, camera.y);
}
//draw characters
for (auto& it : characterMap) {
//BUG: #29 drawing order according to Y origin
//TODO: use a list of renderable objects
it.second.DrawTo(screen, camera.x, camera.y);
}
//draw UI //draw UI
disconnectButton.DrawTo(screen); disconnectButton.DrawTo(screen);
shutDownButton.DrawTo(screen); shutDownButton.DrawTo(screen);
@@ -194,8 +148,9 @@ void InWorld::Render(SDL_Surface* const screen) {
//------------------------- //-------------------------
void InWorld::QuitEvent() { void InWorld::QuitEvent() {
//exit the game AND the server //two-step logout
RequestDisconnect(); SendLogoutRequest();
SendDisconnectRequest();
SetNextScene(SceneList::QUIT); SetNextScene(SceneList::QUIT);
} }
@@ -211,348 +166,124 @@ void InWorld::MouseButtonDown(SDL_MouseButtonEvent const& button) {
void InWorld::MouseButtonUp(SDL_MouseButtonEvent const& button) { void InWorld::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (disconnectButton.MouseButtonUp(button) == Button::State::HOVER && button.button == SDL_BUTTON_LEFT) { if (disconnectButton.MouseButtonUp(button) == Button::State::HOVER && button.button == SDL_BUTTON_LEFT) {
RequestDisconnect(); SendLogoutRequest();
} }
if (shutDownButton.MouseButtonUp(button) == Button::State::HOVER && button.button == SDL_BUTTON_LEFT) { if (shutDownButton.MouseButtonUp(button) == Button::State::HOVER && button.button == SDL_BUTTON_LEFT) {
RequestShutDown(); SendShutdownRequest();
} }
} }
void InWorld::KeyDown(SDL_KeyboardEvent const& key) { void InWorld::KeyDown(SDL_KeyboardEvent const& key) {
if (!localCharacter) {
return;
}
//hotkeys //hotkeys
switch(key.keysym.sym) { switch(key.keysym.sym) {
case SDLK_ESCAPE: case SDLK_ESCAPE:
RequestDisconnect(); //the escape key should actually control menus and stuff
SendLogoutRequest();
break; break;
} }
//player movement
Vector2 motion = localCharacter->GetMotion();
switch(key.keysym.sym) {
case SDLK_LEFT:
motion.x -= CHARACTER_WALKING_SPEED;
break;
case SDLK_RIGHT:
motion.x += CHARACTER_WALKING_SPEED;
break;
case SDLK_UP:
motion.y -= CHARACTER_WALKING_SPEED;
break;
case SDLK_DOWN:
motion.y += CHARACTER_WALKING_SPEED;
break;
default:
return;
}
localCharacter->SetMotion(motion);
localCharacter->CorrectSprite();
SendPlayerUpdate();
} }
void InWorld::KeyUp(SDL_KeyboardEvent const& key) { void InWorld::KeyUp(SDL_KeyboardEvent const& key) {
if (!localCharacter) { //
return;
}
//player movement
Vector2 motion = localCharacter->GetMotion();
switch(key.keysym.sym) {
//NOTE: The use of min/max here are to prevent awkward movements
case SDLK_LEFT:
motion.x = std::min(motion.x + CHARACTER_WALKING_SPEED, 0.0);
break;
case SDLK_RIGHT:
motion.x = std::max(motion.x - CHARACTER_WALKING_SPEED, 0.0);
break;
case SDLK_UP:
motion.y = std::min(motion.y + CHARACTER_WALKING_SPEED, 0.0);
break;
case SDLK_DOWN:
motion.y = std::max(motion.y - CHARACTER_WALKING_SPEED, 0.0);
break;
default:
return;
}
localCharacter->SetMotion(motion);
localCharacter->CorrectSprite();
SendPlayerUpdate();
} }
//------------------------- //-------------------------
//Network handlers //Basic connections
//------------------------- //-------------------------
void InWorld::HandlePacket(SerialPacket* const argPacket) { void InWorld::HandlePacket(SerialPacket* const argPacket) {
switch(argPacket->type) { switch(argPacket->type) {
//heartbeat system //heartbeat system
case SerialPacketType::PING: { case SerialPacketType::PING:
ServerPacket newPacket; HandlePing(static_cast<ServerPacket*>(argPacket));
newPacket.type = SerialPacketType::PONG;
network.SendTo(argPacket->srcAddress, &newPacket);
}
break; break;
case SerialPacketType::PONG: case SerialPacketType::PONG:
// HandlePong(static_cast<ServerPacket*>(argPacket)); HandlePong(static_cast<ServerPacket*>(argPacket));
break; break;
//game server connections //game server connections
case SerialPacketType::LOGOUT_RESPONSE: case SerialPacketType::LOGOUT_RESPONSE:
// HandleLogoutResponse(static_cast<ClientPacket*>(argPacket)); HandleLogoutResponse(static_cast<ClientPacket*>(argPacket));
break; break;
case SerialPacketType::DISCONNECT_REQUEST: case SerialPacketType::DISCONNECT_RESPONSE:
// HandleDisconnectRequest(static_cast<ClientPacket*>(argPacket)); HandleDisconnectResponse(static_cast<ClientPacket*>(argPacket));
break; break;
case SerialPacketType::DISCONNECT_FORCED: case SerialPacketType::DISCONNECT_FORCED:
// HandleDisconnectForced(static_cast<ClientPacket*>(argPacket)); HandleDisconnectForced(static_cast<ClientPacket*>(argPacket));
break; break;
//data management default: {
case SerialPacketType::REGION_CONTENT: std::ostringstream msg;
// HandleRegionContent(static_cast<RegionPacket*>(argPacket)); msg << "Unknown SerialPacketType encountered in InWorld: " << static_cast<int>(argPacket->type);
break; throw(std::runtime_error(msg.str()));
// case SerialPacketType::QUERY_CHARACTER_EXISTS: }
// case SerialPacketType::QUERY_CHARACTER_STATS:
// case SerialPacketType::QUERY_CHARACTER_LOCATION:
//character management
// case SerialPacketType::CHARACTER_NEW:
// HandleCharacterNew(static_cast<CharacterPacket*>(argPacket));
// break;
// case SerialPacketType::CHARACTER_DELETE:
// HandleCharacterDelete(static_cast<CharacterPacket*>(argPacket));
// break;
// case SerialPacketType::CHARACTER_UPDATE:
// HandleCharacterUpdate(static_cast<CharacterPacket*>(argPacket));
// break;
// case SerialPacketType::CHARACTER_REJECTION:
// HandleCharacterRejection(static_cast<TextPacket*>(argPacket));
// break;
//enemy management
//TODO: enemy management
//TODO: text
//handle errors
default:
throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in InWorld: " + to_string_custom(static_cast<int>(argPacket->type)) ));
break; break;
} }
} }
void InWorld::HandlePing(ServerPacket* const argPacket) {
ServerPacket newPacket;
newPacket.type = SerialPacketType::PONG;
network.SendTo(argPacket->srcAddress, &newPacket);
}
void InWorld::HandlePong(ServerPacket* const argPacket) { void InWorld::HandlePong(ServerPacket* const argPacket) {
if (network.GetIPAddress(Channels::SERVER)->host != argPacket->srcAddress.host) { if (*network.GetIPAddress(Channels::SERVER) != argPacket->srcAddress) {
throw(std::runtime_error("Heartbeat message received from an unknown source")); throw(std::runtime_error("Heartbeat message received from an unknown source"));
} }
attemptedBeats = 0; attemptedBeats = 0;
lastBeat = Clock::now(); lastBeat = Clock::now();
} }
void InWorld::HandleDisconnect(ClientPacket* const argPacket) {
//TODO: More needed in the disconnection
SetNextScene(SceneList::DISCONNECTEDSCREEN);
ConfigUtility::GetSingleton()["client.disconnectMessage"] = "You have been disconnected";
}
void InWorld::HandleCharacterNew(CharacterPacket* const argPacket) {
if (characterMap.find(argPacket->characterIndex) != characterMap.end()) {
throw(std::runtime_error("Cannot create duplicate characters"));
}
//create the character object
BaseCharacter& newCharacter = characterMap[argPacket->characterIndex];
//fill out the character's members
newCharacter.SetHandle(argPacket->handle);
newCharacter.SetAvatar(argPacket->avatar);
newCharacter.GetSprite()->LoadSurface(ConfigUtility::GetSingleton()["dir.sprites"] + newCharacter.GetAvatar(), 4, 4);
newCharacter.SetOrigin(argPacket->origin);
newCharacter.SetMotion(argPacket->motion);
newCharacter.SetBounds({
CHARACTER_BOUNDS_X,
CHARACTER_BOUNDS_Y,
CHARACTER_BOUNDS_WIDTH,
CHARACTER_BOUNDS_HEIGHT
});
// (*newCharacter.GetBaseStats()) = argPacket->stats;
//bookkeeping code
newCharacter.CorrectSprite();
//catch this client's player object
if (argPacket->accountIndex == accountIndex && !localCharacter) {
characterIndex = argPacket->characterIndex;
localCharacter = &newCharacter;
//setup the camera
camera.width = GetScreen()->w;
camera.height = GetScreen()->h;
//center on the player's character
camera.marginX = (GetScreen()->w / 2 - localCharacter->GetSprite()->GetImage()->GetClipW() / 2);
camera.marginY = (GetScreen()->h / 2 - localCharacter->GetSprite()->GetImage()->GetClipH() / 2);
}
}
void InWorld::HandleCharacterDelete(CharacterPacket* const argPacket) {
//TODO: authenticate when own character is being deleted (linked to a TODO in the server)
//catch this client's player object
if (argPacket->characterIndex == characterIndex) {
characterIndex = -1;
localCharacter = nullptr;
}
characterMap.erase(argPacket->characterIndex);
}
void InWorld::HandleCharacterUpdate(CharacterPacket* const argPacket) {
if (characterMap.find(argPacket->characterIndex) == characterMap.end()) {
HandleCharacterNew(argPacket);
return;
}
BaseCharacter& character = characterMap[argPacket->characterIndex];
//other characters moving
if (argPacket->characterIndex != characterIndex) {
character.SetOrigin(argPacket->origin);
character.SetMotion(argPacket->motion);
character.CorrectSprite();
}
}
void InWorld::HandleCharacterRejection(TextPacket* const argPacket) {
RequestDisconnect();
SetNextScene(SceneList::DISCONNECTEDSCREEN);
ConfigUtility& config = ConfigUtility::GetSingleton();
config["client.disconnectMessage"] = "Error: ";
config["client.disconnectMessage"] += argPacket->text;
}
void InWorld::HandleRegionContent(RegionPacket* const argPacket) {
//replace existing regions
regionPager.UnloadRegion(argPacket->x, argPacket->y);
regionPager.PushRegion(argPacket->region);
//clean up after the serial code
delete argPacket->region;
argPacket->region = nullptr;
}
//------------------------- //-------------------------
//Server control //Connection control
//------------------------- //-------------------------
void InWorld::RequestSynchronize() { void InWorld::SendLogoutRequest() {
// ClientPacket newPacket; ClientPacket newPacket;
//request a sync //send a logout request
// newPacket.type = SerialPacketType::SYNCHRONIZE; newPacket.type = SerialPacketType::LOGOUT_REQUEST;
// newPacket.clientIndex = clientIndex;
// newPacket.accountIndex = accountIndex;
//TODO: location, range for sync request
// network.SendTo(Channels::SERVER, &newPacket);
}
void InWorld::SendPlayerUpdate() {
CharacterPacket newPacket;
//pack the packet
// newPacket.type = SerialPacketType::CHARACTER_UPDATE;
newPacket.characterIndex = characterIndex;
//NOTE: omitting the handle and avatar here
newPacket.accountIndex = accountIndex; newPacket.accountIndex = accountIndex;
newPacket.roomIndex = 0; //TODO: room index
newPacket.origin = localCharacter->GetOrigin();
newPacket.motion = localCharacter->GetMotion();
// newPacket.stats = *localCharacter->GetBaseStats();
//TODO: gameplay components: equipment, items, buffs, debuffs
network.SendTo(Channels::SERVER, &newPacket); network.SendTo(Channels::SERVER, &newPacket);
} }
void InWorld::RequestDisconnect() { void InWorld::SendDisconnectRequest() {
ClientPacket newPacket; ClientPacket newPacket;
//send a disconnect request //send a disconnect request
newPacket.type = SerialPacketType::DISCONNECT_REQUEST; newPacket.type = SerialPacketType::DISCONNECT_REQUEST;
newPacket.clientIndex = clientIndex; newPacket.clientIndex = clientIndex;
newPacket.accountIndex = accountIndex;
network.SendTo(Channels::SERVER, &newPacket); network.SendTo(Channels::SERVER, &newPacket);
} }
void InWorld::RequestShutDown() { void InWorld::SendShutdownRequest() {
ClientPacket newPacket; ClientPacket newPacket;
//send a shutdown request //send a shutdown request
newPacket.type = SerialPacketType::SHUTDOWN_REQUEST; newPacket.type = SerialPacketType::SHUTDOWN_REQUEST;
newPacket.clientIndex = clientIndex;
newPacket.accountIndex = accountIndex; newPacket.accountIndex = accountIndex;
network.SendTo(Channels::SERVER, &newPacket); network.SendTo(Channels::SERVER, &newPacket);
} }
void InWorld::RequestRegion(int roomIndex, int x, int y) { void InWorld::HandleLogoutResponse(ClientPacket* const argPacket) {
RegionPacket packet; accountIndex = -1;
//pack the region's data //TODO: unload the character
packet.type = SerialPacketType::REGION_REQUEST;
packet.roomIndex = roomIndex;
packet.x = x;
packet.y = y;
network.SendTo(Channels::SERVER, &packet); SendDisconnectRequest();
} }
//------------------------- void InWorld::HandleDisconnectResponse(ClientPacket* const argPacket) {
//Utilities SetNextScene(SceneList::DISCONNECTEDSCREEN);
//------------------------- ConfigUtility::GetSingleton()["client.disconnectMessage"] = "You have successfully logged out";
}
//TODO: convert this into a more generic function?; using parameters for the bounds
void InWorld::UpdateMap() { void InWorld::HandleDisconnectForced(ClientPacket* const argPacket) {
//these represent the zone of regions that the client needs loaded, including the mandatory buffers (+1/-1) //TODO: More needed in the disconnection
int xStart = snapToBase(REGION_WIDTH, camera.x/tileSheet.GetTileW()) - REGION_WIDTH; SetNextScene(SceneList::DISCONNECTEDSCREEN);
int xEnd = snapToBase(REGION_WIDTH, (camera.x+camera.width)/tileSheet.GetTileW()) + REGION_WIDTH; ConfigUtility::GetSingleton()["client.disconnectMessage"] = "You have been forcibly disconnected by the server";
int yStart = snapToBase(REGION_HEIGHT, camera.y/tileSheet.GetTileH()) - REGION_HEIGHT;
int yEnd = snapToBase(REGION_HEIGHT, (camera.y+camera.height)/tileSheet.GetTileH()) + REGION_HEIGHT;
//prune distant regions
for (std::list<Region>::iterator it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); /* EMPTY */) {
//check if the region is outside of this area
if (it->GetX() < xStart || it->GetX() > xEnd || it->GetY() < yStart || it->GetY() > yEnd) {
//clunky, but the alternative was time consuming
int tmpX = it->GetX();
int tmpY = it->GetY();
++it;
regionPager.UnloadRegion(tmpX, tmpY);
continue;
}
++it;
}
//request empty regions within this zone
for (int i = xStart; i <= xEnd; i += REGION_WIDTH) {
for (int j = yStart; j <= yEnd; j += REGION_HEIGHT) {
if (!regionPager.FindRegion(i, j)) {
RequestRegion(0, i, j);
}
}
}
} }
+16 -25
View File
@@ -25,9 +25,10 @@
//maps //maps
#include "region_pager_base.hpp" #include "region_pager_base.hpp"
//networking //utilities
#include "udp_network_utility.hpp" #include "udp_network_utility.hpp"
#include "serial_packet.hpp" #include "serial_packet.hpp"
#include "config_utility.hpp"
//graphics //graphics
#include "image.hpp" #include "image.hpp"
@@ -71,33 +72,23 @@ protected:
void KeyDown(SDL_KeyboardEvent const&); void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&); void KeyUp(SDL_KeyboardEvent const&);
//Network handlers //Basic connections
void HandlePacket(SerialPacket* const); void HandlePacket(SerialPacket* const);
void HandlePing(ServerPacket* const);
void HandlePong(ServerPacket* const); void HandlePong(ServerPacket* const);
void HandleDisconnect(ClientPacket* const);
void HandleCharacterNew(CharacterPacket* const);
void HandleCharacterDelete(CharacterPacket* const);
void HandleCharacterUpdate(CharacterPacket* const);
void HandleCharacterRejection(TextPacket* const);
void HandleRegionContent(RegionPacket* const);
//Server control //Connection control
void RequestSynchronize(); void SendLogoutRequest();
void SendPlayerUpdate(); void SendDisconnectRequest();
void RequestDisconnect(); void SendShutdownRequest();
void RequestShutDown();
void RequestRegion(int roomIndex, int x, int y);
//utilities void HandleLogoutResponse(ClientPacket* const);
void UpdateMap(); void HandleDisconnectResponse(ClientPacket* const);
void HandleDisconnectForced(ClientPacket* const);
//singleton shortcut
UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton();
//indexes //indexes
int& clientIndex; int& clientIndex;
int& accountIndex; int& accountIndex;
int characterIndex = -1;
//graphics //graphics
Image buttonImage; Image buttonImage;
@@ -119,16 +110,16 @@ protected:
int marginX = 0, marginY = 0; int marginX = 0, marginY = 0;
} camera; } camera;
//game components
BaseCharacter* localCharacter = nullptr;
std::map<int, BaseCharacter> characterMap;
std::map<int, BaseMonster> monsterMap;
//heartbeat //heartbeat
//TODO: This needs it's own utility, for both InWorld and InCombat //TODO: Heartbeat needs it's own utility
typedef std::chrono::steady_clock Clock; typedef std::chrono::steady_clock Clock;
Clock::time_point lastBeat = Clock::now(); Clock::time_point lastBeat = Clock::now();
int attemptedBeats = 0; int attemptedBeats = 0;
//ugly references; I hate this
ConfigUtility& config = ConfigUtility::GetSingleton();
UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton();
}; };
#endif #endif
+1 -1
View File
@@ -167,7 +167,7 @@ void ServerApplication::Proc() {
while(running) { while(running) {
//suck in the waiting packets & process them //suck in the waiting packets & process them
while(UDPNetworkUtility::GetSingleton().Receive(packetBuffer)) { while(network.Receive(packetBuffer)) {
try { try {
HandlePacket(packetBuffer); HandlePacket(packetBuffer);
} }
+24 -2
View File
@@ -123,8 +123,18 @@ void ServerApplication::HandleLoginRequest(ClientPacket* const argPacket) {
void ServerApplication::HandleLogoutRequest(ClientPacket* const argPacket) { void ServerApplication::HandleLogoutRequest(ClientPacket* const argPacket) {
//get the account and client data //get the account and client data
AccountData* accountData = accountMgr.Get(argPacket->accountIndex); AccountData* accountData = accountMgr.Get(argPacket->accountIndex);
ClientData* clientData = clientMgr.Get(accountData->GetClientIndex()); if (!accountData) {
return;
}
ClientData* clientData = clientMgr.Get(accountData->GetClientIndex());
if (!clientData) {
std::ostringstream msg;
msg << "No client found for an account: " << accountData->GetUserName();
throw(std::logic_error(msg.str()));
}
//check for fraud
if (clientData->GetAddress() != argPacket->srcAddress) { if (clientData->GetAddress() != argPacket->srcAddress) {
std::cerr << "Falsified logout detected targeting: " << accountData->GetUsername() << std::endl; std::cerr << "Falsified logout detected targeting: " << accountData->GetUsername() << std::endl;
return; return;
@@ -133,7 +143,6 @@ void ServerApplication::HandleLogoutRequest(ClientPacket* const argPacket) {
//send the logout response //send the logout response
ClientPacket newPacket; ClientPacket newPacket;
newPacket.type = SerialPacketType::LOGOUT_RESPONSE; newPacket.type = SerialPacketType::LOGOUT_RESPONSE;
newPacket.clientIndex = accountData->GetClientIndex();
newPacket.accountIndex = argPacket->accountIndex; newPacket.accountIndex = argPacket->accountIndex;
network.SendTo(clientData->GetAddress(), static_cast<SerialPacket*>(&newPacket)); network.SendTo(clientData->GetAddress(), static_cast<SerialPacket*>(&newPacket));
@@ -158,7 +167,11 @@ void ServerApplication::HandleLogoutRequest(ClientPacket* const argPacket) {
void ServerApplication::HandleDisconnectRequest(ClientPacket* const argPacket) { void ServerApplication::HandleDisconnectRequest(ClientPacket* const argPacket) {
//get the client data //get the client data
ClientData* clientData = clientMgr.Get(argPacket->clientIndex); ClientData* clientData = clientMgr.Get(argPacket->clientIndex);
if (!clientData) {
return;
}
//check for fraud
if (clientData->GetAddress() != argPacket->srcAddress) { if (clientData->GetAddress() != argPacket->srcAddress) {
std::cerr << "Falsified disconnection detected targeting: " << argPacket->clientIndex << std::endl; std::cerr << "Falsified disconnection detected targeting: " << argPacket->clientIndex << std::endl;
return; return;
@@ -206,8 +219,17 @@ void ServerApplication::HandleDisconnectRequest(ClientPacket* const argPacket) {
void ServerApplication::HandleShutdownRequest(ClientPacket* const argPacket) { void ServerApplication::HandleShutdownRequest(ClientPacket* const argPacket) {
//get the account and client data //get the account and client data
AccountData* accountData = accountMgr.Get(argPacket->accountIndex); AccountData* accountData = accountMgr.Get(argPacket->accountIndex);
if (!accountData) {
return;
}
ClientData* clientData = clientMgr.Get(accountData->GetClientIndex()); ClientData* clientData = clientMgr.Get(accountData->GetClientIndex());
if (!clientData) {
std::ostringstream msg;
msg << "No client found for an account: " << accountData->GetUserName();
throw(std::logic_error(msg.str()));
}
//check for fraud
if (clientData->GetAddress() != argPacket->srcAddress || accountData->GetAdministrator() != true) { if (clientData->GetAddress() != argPacket->srcAddress || accountData->GetAdministrator() != true) {
std::cerr << "Falsified server shutdown detected from: " << accountData->GetUsername() << std::endl; std::cerr << "Falsified server shutdown detected from: " << accountData->GetUsername() << std::endl;
return; return;