Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e5a98efd7d | |||
| 14b330009b | |||
| 288b62d3f8 | |||
| c5e8f1b3af | |||
| 980717f9fd | |||
| 68475eee0f | |||
| eeb2400e79 | |||
| 01244005e9 | |||
| c5005b9b07 | |||
| 80a26341b1 | |||
| b7877962f1 | |||
| 688d064085 | |||
| 1c4d53e3ef | |||
| a53a134163 | |||
| 4d12788c53 | |||
| 1beb7cbd5d | |||
| 8358d72a98 | |||
| 4ebff4a25a | |||
| 0ff787abda | |||
| 9b5b48a8ab | |||
| 5dd0fb9e23 | |||
| 7c210e04a5 | |||
| 9236e02101 | |||
| 8f4ebf20da | |||
| 910e51f637 |
@@ -6,7 +6,7 @@ This game is inspired by classic 2D RPGs, as well as more modern sandbox MMOs. T
|
|||||||
|
|
||||||
## External Dependencies
|
## External Dependencies
|
||||||
|
|
||||||
* [SDL 1.6](http://www.libsdl.org/) - Simple DirectMedia Layer API
|
* [SDL 1.2](http://www.libsdl.org/) - Simple DirectMedia Layer API
|
||||||
* [SDL_net 1.2](http://www.libsdl.org/projects/SDL_net/) - SDL's networking extension
|
* [SDL_net 1.2](http://www.libsdl.org/projects/SDL_net/) - SDL's networking extension
|
||||||
* [lua 5.2](http://www.lua.org/) - The lua programming language
|
* [lua 5.2](http://www.lua.org/) - The lua programming language
|
||||||
* [SQLite3](http://www.sqlite.org/) - A lightweight SQL database engine
|
* [SQLite3](http://www.sqlite.org/) - A lightweight SQL database engine
|
||||||
|
|||||||
@@ -119,10 +119,10 @@ void ClientApplication::LoadScene(SceneList sceneIndex) {
|
|||||||
activeScene = new OptionsMenu(&config);
|
activeScene = new OptionsMenu(&config);
|
||||||
break;
|
break;
|
||||||
case SceneList::LOBBYMENU:
|
case SceneList::LOBBYMENU:
|
||||||
activeScene = new LobbyMenu(&config, &network, &clientIndex, &characterIndex);
|
activeScene = new LobbyMenu(&config, &network, &clientIndex, &accountIndex, &characterIndex);
|
||||||
break;
|
break;
|
||||||
case SceneList::INWORLD:
|
case SceneList::INWORLD:
|
||||||
activeScene = new InWorld(&config, &network, &clientIndex, &characterIndex);
|
activeScene = new InWorld(&config, &network, &clientIndex, &accountIndex, &characterIndex);
|
||||||
break;
|
break;
|
||||||
case SceneList::INCOMBAT:
|
case SceneList::INCOMBAT:
|
||||||
activeScene = new InCombat();
|
activeScene = new InCombat();
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ private:
|
|||||||
ConfigUtility config;
|
ConfigUtility config;
|
||||||
UDPNetworkUtility network;
|
UDPNetworkUtility network;
|
||||||
int clientIndex = -1;
|
int clientIndex = -1;
|
||||||
|
int accountIndex = -1;
|
||||||
int characterIndex = -1;
|
int characterIndex = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -31,10 +31,11 @@
|
|||||||
//Public access members
|
//Public access members
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
InWorld::InWorld(ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argCharacterIndex):
|
InWorld::InWorld(ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argAccountIndex, int* const argCharacterIndex):
|
||||||
config(*argConfig),
|
config(*argConfig),
|
||||||
network(*argNetwork),
|
network(*argNetwork),
|
||||||
clientIndex(*argClientIndex),
|
clientIndex(*argClientIndex),
|
||||||
|
accountIndex(*argAccountIndex),
|
||||||
characterIndex(*argCharacterIndex)
|
characterIndex(*argCharacterIndex)
|
||||||
{
|
{
|
||||||
//setup the utility objects
|
//setup the utility objects
|
||||||
@@ -62,11 +63,13 @@ InWorld::InWorld(ConfigUtility* const argConfig, UDPNetworkUtility* const argNet
|
|||||||
//TODO: add the tilesheet to the map system?
|
//TODO: add the tilesheet to the map system?
|
||||||
tileSheet.Load(config["dir.tilesets"] + "terrain.bmp", 12, 15);
|
tileSheet.Load(config["dir.tilesets"] + "terrain.bmp", 12, 15);
|
||||||
|
|
||||||
|
//TODO: move this into it's own function
|
||||||
//request a sync
|
//request a sync
|
||||||
SerialPacket packet;
|
SerialPacket packet;
|
||||||
char buffer[PACKET_STRING_SIZE];
|
char buffer[PACKET_STRING_SIZE];
|
||||||
packet.meta.type = SerialPacket::Type::SYNCHRONIZE;
|
packet.meta.type = SerialPacket::Type::SYNCHRONIZE;
|
||||||
packet.clientInfo.clientIndex = clientIndex;
|
packet.clientInfo.clientIndex = clientIndex;
|
||||||
|
packet.clientInfo.accountIndex = accountIndex;
|
||||||
packet.clientInfo.characterIndex = characterIndex;
|
packet.clientInfo.characterIndex = characterIndex;
|
||||||
serialize(&packet, buffer);
|
serialize(&packet, buffer);
|
||||||
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
|
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
|
||||||
@@ -263,7 +266,7 @@ void InWorld::HandlePacket(SerialPacket packet) {
|
|||||||
break;
|
break;
|
||||||
//handle errors
|
//handle errors
|
||||||
default:
|
default:
|
||||||
throw(std::runtime_error("Unknown SerialPacket::Type encountered"));
|
throw(std::runtime_error(std::string() + "Unknown SerialPacket::Type encountered in InWorld: " + to_string_custom(int(packet.meta.type))));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -271,13 +274,13 @@ void InWorld::HandlePacket(SerialPacket packet) {
|
|||||||
void InWorld::HandleDisconnect(SerialPacket packet) {
|
void InWorld::HandleDisconnect(SerialPacket packet) {
|
||||||
network.Unbind(Channels::SERVER);
|
network.Unbind(Channels::SERVER);
|
||||||
clientIndex = -1;
|
clientIndex = -1;
|
||||||
|
accountIndex = -1;
|
||||||
characterIndex = -1;
|
characterIndex = -1;
|
||||||
SetNextScene(SceneList::MAINMENU);
|
SetNextScene(SceneList::MAINMENU);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InWorld::HandleRegionContent(SerialPacket packet) {
|
void InWorld::HandleRegionContent(SerialPacket packet) {
|
||||||
//replace existing regions
|
//replace existing regions
|
||||||
//TODO: account for map index
|
|
||||||
if (regionPager.FindRegion(packet.regionInfo.x, packet.regionInfo.y)) {
|
if (regionPager.FindRegion(packet.regionInfo.x, packet.regionInfo.y)) {
|
||||||
regionPager.UnloadRegion(packet.regionInfo.x, packet.regionInfo.y);
|
regionPager.UnloadRegion(packet.regionInfo.x, packet.regionInfo.y);
|
||||||
}
|
}
|
||||||
@@ -324,6 +327,7 @@ void InWorld::HandleCharacterNew(SerialPacket packet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void InWorld::HandleCharacterDelete(SerialPacket packet) {
|
void InWorld::HandleCharacterDelete(SerialPacket packet) {
|
||||||
|
//TODO: authenticate
|
||||||
if (playerCharacters.find(packet.characterInfo.characterIndex) == playerCharacters.end()) {
|
if (playerCharacters.find(packet.characterInfo.characterIndex) == playerCharacters.end()) {
|
||||||
throw(std::runtime_error("Cannot delete non-existant characters"));
|
throw(std::runtime_error("Cannot delete non-existant characters"));
|
||||||
}
|
}
|
||||||
@@ -348,6 +352,7 @@ void InWorld::SendPlayerUpdate() {
|
|||||||
//pack the packet
|
//pack the packet
|
||||||
packet.meta.type = SerialPacket::Type::CHARACTER_UPDATE;
|
packet.meta.type = SerialPacket::Type::CHARACTER_UPDATE;
|
||||||
packet.characterInfo.clientIndex = clientIndex;
|
packet.characterInfo.clientIndex = clientIndex;
|
||||||
|
packet.characterInfo.accountIndex = accountIndex;
|
||||||
packet.characterInfo.characterIndex = characterIndex;
|
packet.characterInfo.characterIndex = characterIndex;
|
||||||
packet.characterInfo.position = localCharacter->GetPosition();
|
packet.characterInfo.position = localCharacter->GetPosition();
|
||||||
packet.characterInfo.motion = localCharacter->GetMotion();
|
packet.characterInfo.motion = localCharacter->GetMotion();
|
||||||
@@ -363,6 +368,8 @@ void InWorld::RequestDisconnect() {
|
|||||||
//send a disconnect request
|
//send a disconnect request
|
||||||
packet.meta.type = SerialPacket::Type::DISCONNECT;
|
packet.meta.type = SerialPacket::Type::DISCONNECT;
|
||||||
packet.clientInfo.clientIndex = clientIndex;
|
packet.clientInfo.clientIndex = clientIndex;
|
||||||
|
packet.clientInfo.accountIndex = accountIndex;
|
||||||
|
packet.clientInfo.characterIndex = characterIndex;
|
||||||
serialize(&packet, buffer);
|
serialize(&packet, buffer);
|
||||||
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
|
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
@@ -374,6 +381,8 @@ void InWorld::RequestShutDown() {
|
|||||||
//send a shutdown request
|
//send a shutdown request
|
||||||
packet.meta.type = SerialPacket::Type::SHUTDOWN;
|
packet.meta.type = SerialPacket::Type::SHUTDOWN;
|
||||||
packet.clientInfo.clientIndex = clientIndex;
|
packet.clientInfo.clientIndex = clientIndex;
|
||||||
|
packet.clientInfo.accountIndex = accountIndex;
|
||||||
|
packet.clientInfo.characterIndex = characterIndex;
|
||||||
serialize(&packet, buffer);
|
serialize(&packet, buffer);
|
||||||
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
|
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
class InWorld : public BaseScene {
|
class InWorld : public BaseScene {
|
||||||
public:
|
public:
|
||||||
//Public access members
|
//Public access members
|
||||||
InWorld(ConfigUtility* const, UDPNetworkUtility* const, int* const, int* const);
|
InWorld(ConfigUtility* const, UDPNetworkUtility* const, int* const, int* const, int* const);
|
||||||
~InWorld();
|
~InWorld();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -92,6 +92,7 @@ protected:
|
|||||||
ConfigUtility& config;
|
ConfigUtility& config;
|
||||||
UDPNetworkUtility& network;
|
UDPNetworkUtility& network;
|
||||||
int& clientIndex;
|
int& clientIndex;
|
||||||
|
int& accountIndex;
|
||||||
int& characterIndex;
|
int& characterIndex;
|
||||||
|
|
||||||
//graphics
|
//graphics
|
||||||
|
|||||||
@@ -30,10 +30,11 @@
|
|||||||
//Public access members
|
//Public access members
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
LobbyMenu::LobbyMenu(ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argCharacterIndex):
|
LobbyMenu::LobbyMenu(ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argAccountIndex, int* const argCharacterIndex):
|
||||||
config(*argConfig),
|
config(*argConfig),
|
||||||
network(*argNetwork),
|
network(*argNetwork),
|
||||||
clientIndex(*argClientIndex),
|
clientIndex(*argClientIndex),
|
||||||
|
accountIndex(*argAccountIndex),
|
||||||
characterIndex(*argCharacterIndex)
|
characterIndex(*argCharacterIndex)
|
||||||
{
|
{
|
||||||
//setup the utility objects
|
//setup the utility objects
|
||||||
@@ -221,6 +222,7 @@ void LobbyMenu::HandlePacket(SerialPacket packet) {
|
|||||||
break;
|
break;
|
||||||
case SerialPacket::Type::JOIN_RESPONSE:
|
case SerialPacket::Type::JOIN_RESPONSE:
|
||||||
clientIndex = packet.clientInfo.clientIndex;
|
clientIndex = packet.clientInfo.clientIndex;
|
||||||
|
accountIndex = packet.clientInfo.accountIndex;
|
||||||
characterIndex = packet.clientInfo.characterIndex;
|
characterIndex = packet.clientInfo.characterIndex;
|
||||||
network.Bind(&packet.meta.srcAddress, Channels::SERVER);
|
network.Bind(&packet.meta.srcAddress, Channels::SERVER);
|
||||||
SetNextScene(SceneList::INWORLD);
|
SetNextScene(SceneList::INWORLD);
|
||||||
@@ -228,7 +230,7 @@ void LobbyMenu::HandlePacket(SerialPacket packet) {
|
|||||||
|
|
||||||
//handle errors
|
//handle errors
|
||||||
default:
|
default:
|
||||||
throw(std::runtime_error("Unknown SerialPacket::Type encountered"));
|
throw(std::runtime_error(std::string() + "Unknown SerialPacket::Type encountered in LobbyMenu: " + to_string_custom(int(packet.meta.type))));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
class LobbyMenu : public BaseScene {
|
class LobbyMenu : public BaseScene {
|
||||||
public:
|
public:
|
||||||
//Public access members
|
//Public access members
|
||||||
LobbyMenu(ConfigUtility* const, UDPNetworkUtility* const, int* const, int* const);
|
LobbyMenu(ConfigUtility* const, UDPNetworkUtility* const, int* const, int* const, int* const);
|
||||||
~LobbyMenu();
|
~LobbyMenu();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -65,6 +65,7 @@ protected:
|
|||||||
ConfigUtility& config;
|
ConfigUtility& config;
|
||||||
UDPNetworkUtility& network;
|
UDPNetworkUtility& network;
|
||||||
int& clientIndex;
|
int& clientIndex;
|
||||||
|
int& accountIndex;
|
||||||
int& characterIndex;
|
int& characterIndex;
|
||||||
|
|
||||||
//members
|
//members
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ void serializeClient(SerialPacket* packet, char* buffer) {
|
|||||||
|
|
||||||
//indexes
|
//indexes
|
||||||
SERIALIZE(buffer, &packet->clientInfo.clientIndex, sizeof(int));
|
SERIALIZE(buffer, &packet->clientInfo.clientIndex, sizeof(int));
|
||||||
|
SERIALIZE(buffer, &packet->clientInfo.accountIndex, sizeof(int));
|
||||||
SERIALIZE(buffer, &packet->clientInfo.characterIndex, sizeof(int));
|
SERIALIZE(buffer, &packet->clientInfo.characterIndex, sizeof(int));
|
||||||
|
|
||||||
//texts
|
//texts
|
||||||
@@ -95,6 +96,7 @@ void serializeCharacter(SerialPacket* packet, char* buffer) {
|
|||||||
|
|
||||||
//indexes
|
//indexes
|
||||||
SERIALIZE(buffer, &packet->characterInfo.clientIndex, sizeof(int));
|
SERIALIZE(buffer, &packet->characterInfo.clientIndex, sizeof(int));
|
||||||
|
SERIALIZE(buffer, &packet->characterInfo.accountIndex, sizeof(int));
|
||||||
SERIALIZE(buffer, &packet->characterInfo.characterIndex, sizeof(int));
|
SERIALIZE(buffer, &packet->characterInfo.characterIndex, sizeof(int));
|
||||||
|
|
||||||
//texts
|
//texts
|
||||||
@@ -130,6 +132,7 @@ void deserializeClient(SerialPacket* packet, char* buffer) {
|
|||||||
|
|
||||||
//indexes
|
//indexes
|
||||||
DESERIALIZE(buffer, &packet->clientInfo.clientIndex, sizeof(int));
|
DESERIALIZE(buffer, &packet->clientInfo.clientIndex, sizeof(int));
|
||||||
|
DESERIALIZE(buffer, &packet->clientInfo.accountIndex, sizeof(int));
|
||||||
DESERIALIZE(buffer, &packet->clientInfo.characterIndex, sizeof(int));
|
DESERIALIZE(buffer, &packet->clientInfo.characterIndex, sizeof(int));
|
||||||
|
|
||||||
//texts
|
//texts
|
||||||
@@ -178,6 +181,7 @@ void deserializeCharacter(SerialPacket* packet, char* buffer) {
|
|||||||
|
|
||||||
//indexes
|
//indexes
|
||||||
DESERIALIZE(buffer, &packet->characterInfo.clientIndex, sizeof(int));
|
DESERIALIZE(buffer, &packet->characterInfo.clientIndex, sizeof(int));
|
||||||
|
DESERIALIZE(buffer, &packet->characterInfo.accountIndex, sizeof(int));
|
||||||
DESERIALIZE(buffer, &packet->characterInfo.characterIndex, sizeof(int));
|
DESERIALIZE(buffer, &packet->characterInfo.characterIndex, sizeof(int));
|
||||||
|
|
||||||
//texts
|
//texts
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#include "SDL/SDL_net.h"
|
#include "SDL/SDL_net.h"
|
||||||
|
|
||||||
#define NETWORK_VERSION 20140428
|
#define NETWORK_VERSION 20140512
|
||||||
#define PACKET_STRING_SIZE 100
|
#define PACKET_STRING_SIZE 100
|
||||||
|
|
||||||
#pragma pack(push, 0)
|
#pragma pack(push, 0)
|
||||||
@@ -42,6 +42,8 @@ union SerialPacket {
|
|||||||
PING = 1,
|
PING = 1,
|
||||||
PONG = 2,
|
PONG = 2,
|
||||||
|
|
||||||
|
//TODO: rejection message
|
||||||
|
|
||||||
//Searching for a server to join
|
//Searching for a server to join
|
||||||
BROADCAST_REQUEST = 3,
|
BROADCAST_REQUEST = 3,
|
||||||
BROADCAST_RESPONSE = 4,
|
BROADCAST_RESPONSE = 4,
|
||||||
@@ -89,6 +91,7 @@ union SerialPacket {
|
|||||||
struct ClientInformation {
|
struct ClientInformation {
|
||||||
Metadata meta;
|
Metadata meta;
|
||||||
int clientIndex;
|
int clientIndex;
|
||||||
|
int accountIndex;
|
||||||
int characterIndex;
|
int characterIndex;
|
||||||
char username[PACKET_STRING_SIZE];
|
char username[PACKET_STRING_SIZE];
|
||||||
char handle[PACKET_STRING_SIZE];
|
char handle[PACKET_STRING_SIZE];
|
||||||
@@ -107,6 +110,7 @@ union SerialPacket {
|
|||||||
struct CharacterInformation {
|
struct CharacterInformation {
|
||||||
Metadata meta;
|
Metadata meta;
|
||||||
int clientIndex;
|
int clientIndex;
|
||||||
|
int accountIndex;
|
||||||
int characterIndex;
|
int characterIndex;
|
||||||
char handle[PACKET_STRING_SIZE];
|
char handle[PACKET_STRING_SIZE];
|
||||||
char avatar[PACKET_STRING_SIZE];
|
char avatar[PACKET_STRING_SIZE];
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
*/
|
*/
|
||||||
#include "server_utility.hpp"
|
#include "sql_utility.hpp"
|
||||||
|
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
@@ -1,139 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
|
||||||
* arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
* claim that you wrote the original software. If you use this software
|
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
|
||||||
* appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
* misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
*/
|
|
||||||
#include "base_scene.hpp"
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Static declarations
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
SDL_Surface* BaseScene::screen = nullptr;
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Public access members
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
BaseScene::BaseScene() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseScene::~BaseScene() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Program control
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
SDL_Surface* BaseScene::SetScreen(int w, int h, int bpp, Uint32 flags) {
|
|
||||||
if (!bpp) {
|
|
||||||
bpp = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
|
|
||||||
}
|
|
||||||
|
|
||||||
screen = SDL_SetVideoMode(w, h, bpp, flags);
|
|
||||||
|
|
||||||
if (!screen) {
|
|
||||||
throw(std::runtime_error("Failed to create the screen surface"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return screen;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_Surface* BaseScene::GetScreen() {
|
|
||||||
return screen;
|
|
||||||
}
|
|
||||||
|
|
||||||
SceneList BaseScene::SetNextScene(SceneList sceneIndex) {
|
|
||||||
return nextScene = sceneIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
SceneList BaseScene::GetNextScene() const {
|
|
||||||
return nextScene;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Frame loop
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void BaseScene::RunFrame(double delta) {
|
|
||||||
FrameStart();
|
|
||||||
HandleEvents();
|
|
||||||
Update(delta);
|
|
||||||
FrameEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseScene::RenderFrame() {
|
|
||||||
SDL_FillRect(screen, 0, 0);
|
|
||||||
Render(screen);
|
|
||||||
SDL_Flip(screen);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Event handlers
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void BaseScene::HandleEvents() {
|
|
||||||
SDL_Event event;
|
|
||||||
|
|
||||||
while(SDL_PollEvent(&event)) {
|
|
||||||
switch(event.type) {
|
|
||||||
case SDL_QUIT:
|
|
||||||
QuitEvent();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_VIDEORESIZE:
|
|
||||||
SetScreen(event.resize.w, event.resize.h, 0, screen->flags);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_MOUSEMOTION:
|
|
||||||
MouseMotion(event.motion);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_MOUSEBUTTONDOWN:
|
|
||||||
MouseButtonDown(event.button);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_MOUSEBUTTONUP:
|
|
||||||
MouseButtonUp(event.button);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_KEYDOWN:
|
|
||||||
KeyDown(event.key);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_KEYUP:
|
|
||||||
KeyUp(event.key);
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifdef USE_EVENT_JOYSTICK
|
|
||||||
//TODO: joystick/gamepad support
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_EVENT_UNKNOWN
|
|
||||||
default:
|
|
||||||
UnknownEvent(event);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
}//switch
|
|
||||||
}//while
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
|
||||||
* arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
* claim that you wrote the original software. If you use this software
|
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
|
||||||
* appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
* misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
*/
|
|
||||||
#ifndef BASESCENE_HPP_
|
|
||||||
#define BASESCENE_HPP_
|
|
||||||
|
|
||||||
#include "scene_list.hpp"
|
|
||||||
|
|
||||||
#include "SDL/SDL.h"
|
|
||||||
|
|
||||||
class BaseScene {
|
|
||||||
public:
|
|
||||||
//Public access members
|
|
||||||
BaseScene();
|
|
||||||
virtual ~BaseScene();
|
|
||||||
|
|
||||||
//Program control
|
|
||||||
static SDL_Surface* SetScreen(int w, int h, int bpp = 0, Uint32 flags = SDL_HWSURFACE|SDL_DOUBLEBUF);
|
|
||||||
static SDL_Surface* GetScreen();
|
|
||||||
|
|
||||||
SceneList SetNextScene(SceneList sceneIndex);
|
|
||||||
SceneList GetNextScene() const;
|
|
||||||
|
|
||||||
//Frame loop
|
|
||||||
virtual void RunFrame(double delta);
|
|
||||||
virtual void RenderFrame();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void FrameStart() {}
|
|
||||||
virtual void HandleEvents();
|
|
||||||
virtual void Update(double delta) {}
|
|
||||||
virtual void FrameEnd() {}
|
|
||||||
virtual void Render(SDL_Surface* const screen) {}
|
|
||||||
|
|
||||||
//Event handlers
|
|
||||||
virtual void QuitEvent() { SetNextScene(SceneList::QUIT); }
|
|
||||||
virtual void MouseMotion(SDL_MouseMotionEvent const&) {}
|
|
||||||
virtual void MouseButtonDown(SDL_MouseButtonEvent const&) {}
|
|
||||||
virtual void MouseButtonUp(SDL_MouseButtonEvent const&) {}
|
|
||||||
virtual void KeyDown(SDL_KeyboardEvent const&) {}
|
|
||||||
virtual void KeyUp(SDL_KeyboardEvent const&) {}
|
|
||||||
|
|
||||||
#ifdef USE_EVENT_JOYSTICK
|
|
||||||
//TODO: joystick/gamepad support
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_EVENT_UNKNOWN
|
|
||||||
virtual void UnknownEvent(SDL_Event const&) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
|
||||||
static SDL_Surface* screen;
|
|
||||||
SceneList nextScene = SceneList::CONTINUE;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
|
||||||
* arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial EditorApplications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
* claim that you wrote the original software. If you use this software
|
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
|
||||||
* appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
* misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
*/
|
|
||||||
#include "editor_application.hpp"
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <chrono>
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Scene headers
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
//Add the custom scene headers here
|
|
||||||
#include "editor_scene.hpp"
|
|
||||||
#include "testificate_scene.hpp"
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Public access members
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void EditorApplication::Init(int argc, char** argv) {
|
|
||||||
config.Load("rsc\\config.cfg");
|
|
||||||
if (SDL_Init(SDL_INIT_VIDEO))
|
|
||||||
throw(std::runtime_error("Failed to initialize SDL"));
|
|
||||||
|
|
||||||
BaseScene::SetScreen(config.Int("screen.w"), config.Int("screen.h"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorApplication::Proc() {
|
|
||||||
LoadScene(SceneList::FIRST);
|
|
||||||
|
|
||||||
//prepare the time system
|
|
||||||
typedef std::chrono::steady_clock Clock;
|
|
||||||
|
|
||||||
Clock::duration delta(16 * Clock::duration::period::den / std::milli::den);
|
|
||||||
Clock::time_point simTime = Clock::now();
|
|
||||||
Clock::time_point realTime;
|
|
||||||
|
|
||||||
//The main loop
|
|
||||||
while(activeScene->GetNextScene() != SceneList::QUIT) {
|
|
||||||
//switch scenes when necessary
|
|
||||||
if (activeScene->GetNextScene() != SceneList::CONTINUE) {
|
|
||||||
LoadScene(activeScene->GetNextScene());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//update the current time
|
|
||||||
realTime = Clock::now();
|
|
||||||
|
|
||||||
//simulate game time
|
|
||||||
while (simTime < realTime) {
|
|
||||||
//call each user defined function
|
|
||||||
activeScene->RunFrame(double(delta.count()) / Clock::duration::period::den);
|
|
||||||
simTime += delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
//draw the game to the screen
|
|
||||||
activeScene->RenderFrame();
|
|
||||||
|
|
||||||
//give the computer a break
|
|
||||||
SDL_Delay(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
UnloadScene();
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorApplication::Quit() {
|
|
||||||
SDL_Quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Private access members
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void EditorApplication::LoadScene(SceneList sceneIndex) {
|
|
||||||
UnloadScene();
|
|
||||||
|
|
||||||
switch(sceneIndex) {
|
|
||||||
//add scene creation calls here
|
|
||||||
case SceneList::FIRST:
|
|
||||||
case SceneList::EDITORSCENE:
|
|
||||||
activeScene = new EditorScene(&config);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SceneList::TESTIFICATESCENE:
|
|
||||||
activeScene = new TestificateScene(&config);
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw(std::logic_error("Failed to recognize the scene index"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorApplication::UnloadScene() {
|
|
||||||
delete activeScene;
|
|
||||||
activeScene = nullptr;
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
|
||||||
* arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
* claim that you wrote the original software. If you use this software
|
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
|
||||||
* appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
* misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
*/
|
|
||||||
#ifndef EDITORAPPLICATION_HPP_
|
|
||||||
#define EDITORAPPLICATION_HPP_
|
|
||||||
|
|
||||||
#include "scene_list.hpp"
|
|
||||||
#include "base_scene.hpp"
|
|
||||||
#include "config_utility.hpp"
|
|
||||||
|
|
||||||
class EditorApplication {
|
|
||||||
public:
|
|
||||||
EditorApplication() = default;
|
|
||||||
~EditorApplication() = default;
|
|
||||||
|
|
||||||
void Init(int argc, char** argv);
|
|
||||||
void Proc();
|
|
||||||
void Quit();
|
|
||||||
|
|
||||||
private:
|
|
||||||
//Private access members
|
|
||||||
void LoadScene(SceneList sceneIndex);
|
|
||||||
void UnloadScene();
|
|
||||||
|
|
||||||
//globals
|
|
||||||
ConfigUtility config;
|
|
||||||
|
|
||||||
BaseScene* activeScene = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,216 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013, 2014
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
|
||||||
* arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
* claim that you wrote the original software. If you use this software
|
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
|
||||||
* appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
* misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
*/
|
|
||||||
#include "editor_scene.hpp"
|
|
||||||
|
|
||||||
#include "utility.hpp"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <iostream>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Public access members
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
EditorScene::EditorScene(ConfigUtility* const arg1):
|
|
||||||
config(*arg1)
|
|
||||||
{
|
|
||||||
//create the debugging "window"
|
|
||||||
debugInfo.CreateSurface(256, 256);
|
|
||||||
|
|
||||||
//setup the utility objects
|
|
||||||
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
|
|
||||||
|
|
||||||
buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp");
|
|
||||||
buttonImage.SetClipH(buttonImage.GetClipH()/3);
|
|
||||||
|
|
||||||
//setup the menu bar
|
|
||||||
menuBar.SetFont(&font);
|
|
||||||
menuBar.SetImage(&buttonImage);
|
|
||||||
|
|
||||||
menuBar.SetEntries({
|
|
||||||
{"File", "New", "Open", "Save", "Close"},
|
|
||||||
{"Edit", "Set Tile", "Set Brush", "Script"},
|
|
||||||
{"Debug", "Debug On", "Debug Off", "Toggle", "Testificate"}
|
|
||||||
});
|
|
||||||
|
|
||||||
//debug
|
|
||||||
tsheet.Load(config["dir.tilesets"] + "terrain.bmp", 12, 15);
|
|
||||||
for (int i = 0; i < REGION_WIDTH; i++) {
|
|
||||||
for (int j = 0; j < REGION_HEIGHT; j++) {
|
|
||||||
pager.SetTile(i, j, 0, 14);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pager.SetTile(5, 10, 1, 48);
|
|
||||||
}
|
|
||||||
|
|
||||||
EditorScene::~EditorScene() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Frame loop
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void EditorScene::FrameStart() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::Update(double delta) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::FrameEnd() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::Render(SDL_Surface* const screen) {
|
|
||||||
tsheet.DrawRegionTo(screen, pager.GetRegion(0, 0), camera.x, camera.y);
|
|
||||||
|
|
||||||
//draw a big bar across the top (hackish)
|
|
||||||
buttonImage.SetClipY(0);
|
|
||||||
for (int i = 0; i < screen->w; i += buttonImage.GetClipW()) {
|
|
||||||
buttonImage.DrawTo(screen, i, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//draw the menu bar
|
|
||||||
menuBar.DrawTo(screen);
|
|
||||||
|
|
||||||
//draw some debugging info
|
|
||||||
if (debugOpen) {
|
|
||||||
SDL_FillRect(debugInfo.GetSurface(), 0, 0);
|
|
||||||
DrawToDebugInfo(string("camera.x: ") + to_string_custom(camera.x), 0);
|
|
||||||
DrawToDebugInfo(string("camera.y: ") + to_string_custom(camera.y), 1);
|
|
||||||
debugInfo.DrawTo(screen, screen->w - debugInfo.GetClipW(), buttonImage.GetClipH());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::DrawToDebugInfo(std::string str, int line) {
|
|
||||||
//draw the debug info on the right, with a grey background
|
|
||||||
SDL_Rect clip = {
|
|
||||||
Sint16(debugInfo.GetClipW() - str.size() * font.GetCharW()),
|
|
||||||
Sint16(font.GetCharH() * line),
|
|
||||||
Uint16(str.size() * font.GetCharW()),
|
|
||||||
Uint16(font.GetCharH())
|
|
||||||
};
|
|
||||||
SDL_FillRect(debugInfo.GetSurface(), &clip, SDL_MapRGB(debugInfo.GetSurface()->format, 64, 64, 64));
|
|
||||||
font.DrawStringTo(str, debugInfo.GetSurface(), clip.x, clip.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Event handlers
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void EditorScene::MouseMotion(SDL_MouseMotionEvent const& motion) {
|
|
||||||
menuBar.MouseMotion(motion);
|
|
||||||
|
|
||||||
if (motion.state & SDL_BUTTON_RMASK) {
|
|
||||||
camera.x -= motion.xrel;
|
|
||||||
camera.y -= motion.yrel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::MouseButtonDown(SDL_MouseButtonEvent const& button) {
|
|
||||||
menuBar.MouseButtonDown(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::MouseButtonUp(SDL_MouseButtonEvent const& button) {
|
|
||||||
int entry, drop;
|
|
||||||
menuBar.MouseButtonUp(button, &entry, &drop);
|
|
||||||
HandleMenuOption(entry, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::KeyDown(SDL_KeyboardEvent const& key) {
|
|
||||||
switch(key.keysym.sym) {
|
|
||||||
case SDLK_ESCAPE:
|
|
||||||
QuitEvent();
|
|
||||||
break;
|
|
||||||
case SDLK_SPACE:
|
|
||||||
camera.x = 0;
|
|
||||||
camera.y = 0;
|
|
||||||
break;
|
|
||||||
case SDLK_TAB:
|
|
||||||
debugOpen = !debugOpen;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::KeyUp(SDL_KeyboardEvent const& key) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Members
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void EditorScene::HandleMenuOption(int entry, int drop) {
|
|
||||||
//manage input from the menu bar
|
|
||||||
switch(entry) {
|
|
||||||
case 0: //File
|
|
||||||
switch(drop) {
|
|
||||||
case 0:
|
|
||||||
//NEW
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
//OPEN
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
//SAVE
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
//CLOSE
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1: //Edit
|
|
||||||
switch(drop) {
|
|
||||||
case 0:
|
|
||||||
//SET TILE
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
//SET BRUSH
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
//SCRIPT
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2: //Debug
|
|
||||||
switch(drop) {
|
|
||||||
case 0:
|
|
||||||
debugOpen = true;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
debugOpen = false;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
debugOpen = !debugOpen;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
SetNextScene(SceneList::TESTIFICATESCENE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013, 2014
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
|
||||||
* arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
* claim that you wrote the original software. If you use this software
|
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
|
||||||
* appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
* misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
*/
|
|
||||||
#ifndef EDITORSCENE_HPP_
|
|
||||||
#define EDITORSCENE_HPP_
|
|
||||||
|
|
||||||
#include "base_scene.hpp"
|
|
||||||
|
|
||||||
#include "config_utility.hpp"
|
|
||||||
#include "image.hpp"
|
|
||||||
#include "raster_font.hpp"
|
|
||||||
#include "menu_bar.hpp"
|
|
||||||
|
|
||||||
#include "region_pager.hpp"
|
|
||||||
#include "map_allocator.hpp"
|
|
||||||
#include "map_file_format.hpp"
|
|
||||||
#include "tile_sheet.hpp"
|
|
||||||
|
|
||||||
class EditorScene : public BaseScene {
|
|
||||||
public:
|
|
||||||
//Public access members
|
|
||||||
EditorScene(ConfigUtility* const);
|
|
||||||
~EditorScene();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
//Frame loop
|
|
||||||
void FrameStart();
|
|
||||||
void Update(double delta);
|
|
||||||
void FrameEnd();
|
|
||||||
void Render(SDL_Surface* const);
|
|
||||||
|
|
||||||
//Event handlers
|
|
||||||
void MouseMotion(SDL_MouseMotionEvent const&);
|
|
||||||
void MouseButtonDown(SDL_MouseButtonEvent const&);
|
|
||||||
void MouseButtonUp(SDL_MouseButtonEvent const&);
|
|
||||||
void KeyDown(SDL_KeyboardEvent const&);
|
|
||||||
void KeyUp(SDL_KeyboardEvent const&);
|
|
||||||
|
|
||||||
//members
|
|
||||||
void HandleMenuOption(int entry, int drop);
|
|
||||||
|
|
||||||
//globals
|
|
||||||
ConfigUtility& config;
|
|
||||||
|
|
||||||
//debugging tools
|
|
||||||
void DrawToDebugInfo(std::string, int line);
|
|
||||||
Image debugInfo;
|
|
||||||
bool debugOpen = true;
|
|
||||||
|
|
||||||
RasterFont font;
|
|
||||||
Image buttonImage;
|
|
||||||
MenuBar menuBar;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
int x = 0, y = 0;
|
|
||||||
} camera;
|
|
||||||
|
|
||||||
RegionPager<BlankAllocator, DummyFormat> pager;
|
|
||||||
TileSheet tsheet;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
|
||||||
* arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
* claim that you wrote the original software. If you use this software
|
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
|
||||||
* appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
* misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
*/
|
|
||||||
#include "editor_application.hpp"
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
|
||||||
cout << "Beginning editor" << endl;
|
|
||||||
try {
|
|
||||||
EditorApplication app;
|
|
||||||
app.Init(argc, argv);
|
|
||||||
app.Proc();
|
|
||||||
app.Quit();
|
|
||||||
}
|
|
||||||
catch(exception& e) {
|
|
||||||
cerr << "Fatal exception thrown: " << e.what() << endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
cout << "Clean exit" << endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
#config
|
|
||||||
INCLUDES+=../common ../common/graphics ../common/map ../common/ui
|
|
||||||
LIBS+=../libcommon.a -lmingw32 -lSDLmain -lSDL -llua
|
|
||||||
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
|
|
||||||
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
|
|
||||||
|
|
||||||
#source
|
|
||||||
CXXSRC=$(wildcard *.cpp)
|
|
||||||
CSRC=$(wildcard *.c)
|
|
||||||
|
|
||||||
#objects
|
|
||||||
OBJDIR=obj
|
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
|
|
||||||
|
|
||||||
#output
|
|
||||||
OUTDIR=../out
|
|
||||||
OUT=$(addprefix $(OUTDIR)/,editor)
|
|
||||||
|
|
||||||
#targets
|
|
||||||
all: $(OBJ) $(OUT)
|
|
||||||
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
|
|
||||||
|
|
||||||
$(OBJ): | $(OBJDIR)
|
|
||||||
|
|
||||||
$(OUT): | $(OUTDIR)
|
|
||||||
|
|
||||||
$(OBJDIR):
|
|
||||||
mkdir $(OBJDIR)
|
|
||||||
|
|
||||||
$(OUTDIR):
|
|
||||||
mkdir $(OUTDIR)
|
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.cpp
|
|
||||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.c
|
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(RM) *.o *.a *.exe
|
|
||||||
|
|
||||||
rebuild: clean all
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
|
||||||
* arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
* claim that you wrote the original software. If you use this software
|
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
|
||||||
* appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
* misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
*/
|
|
||||||
#ifndef SCENELIST_HPP_
|
|
||||||
#define SCENELIST_HPP_
|
|
||||||
|
|
||||||
enum class SceneList {
|
|
||||||
//these are reserved
|
|
||||||
QUIT,
|
|
||||||
CONTINUE,
|
|
||||||
FIRST,
|
|
||||||
|
|
||||||
//custom indexes
|
|
||||||
TESTIFICATESCENE,
|
|
||||||
EDITORSCENE,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
|
||||||
* arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
* claim that you wrote the original software. If you use this software
|
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
|
||||||
* appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
* misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
*/
|
|
||||||
#include "testificate_scene.hpp"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using std::cout;
|
|
||||||
using std::endl;
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Public access members
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
TestificateScene::TestificateScene(ConfigUtility* const arg1):
|
|
||||||
config(*arg1)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
TestificateScene::~TestificateScene() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Frame loop
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void TestificateScene::FrameStart() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestificateScene::Update(double delta) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestificateScene::FrameEnd() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestificateScene::Render(SDL_Surface* const screen) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Event handlers
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void TestificateScene::MouseMotion(SDL_MouseMotionEvent const& motion) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void TestificateScene::MouseButtonDown(SDL_MouseButtonEvent const& button) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestificateScene::MouseButtonUp(SDL_MouseButtonEvent const& button) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestificateScene::KeyDown(SDL_KeyboardEvent const& key) {
|
|
||||||
switch(key.keysym.sym) {
|
|
||||||
case SDLK_ESCAPE:
|
|
||||||
// QuitEvent();
|
|
||||||
SetNextScene(SceneList::EDITORSCENE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestificateScene::KeyUp(SDL_KeyboardEvent const& key) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
|
||||||
* arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
* claim that you wrote the original software. If you use this software
|
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
|
||||||
* appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
* misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
*/
|
|
||||||
#ifndef TESTIFICATESCENE_HPP_
|
|
||||||
#define TESTIFICATESCENE_HPP_
|
|
||||||
|
|
||||||
#include "base_scene.hpp"
|
|
||||||
|
|
||||||
#include "config_utility.hpp"
|
|
||||||
|
|
||||||
class TestificateScene : public BaseScene {
|
|
||||||
public:
|
|
||||||
//Public access members
|
|
||||||
TestificateScene(ConfigUtility* const);
|
|
||||||
~TestificateScene();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
//Frame loop
|
|
||||||
void FrameStart();
|
|
||||||
void Update(double delta);
|
|
||||||
void FrameEnd();
|
|
||||||
void Render(SDL_Surface* const);
|
|
||||||
|
|
||||||
//Event handlers
|
|
||||||
void MouseMotion(SDL_MouseMotionEvent const&);
|
|
||||||
void MouseButtonDown(SDL_MouseButtonEvent const&);
|
|
||||||
void MouseButtonUp(SDL_MouseButtonEvent const&);
|
|
||||||
void KeyDown(SDL_KeyboardEvent const&);
|
|
||||||
void KeyUp(SDL_KeyboardEvent const&);
|
|
||||||
|
|
||||||
//globals
|
|
||||||
ConfigUtility& config;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -15,7 +15,6 @@ all: $(OUTDIR)
|
|||||||
$(MAKE) -C common
|
$(MAKE) -C common
|
||||||
$(MAKE) -C server
|
$(MAKE) -C server
|
||||||
$(MAKE) -C client
|
$(MAKE) -C client
|
||||||
$(MAKE) -C editor
|
|
||||||
|
|
||||||
$(OUTDIR):
|
$(OUTDIR):
|
||||||
mkdir $(OUTDIR)
|
mkdir $(OUTDIR)
|
||||||
|
|||||||
@@ -25,8 +25,3 @@ end
|
|||||||
function map.save(region, dir)
|
function map.save(region, dir)
|
||||||
--
|
--
|
||||||
end
|
end
|
||||||
|
|
||||||
--debugging
|
|
||||||
print("DEBUG: Initial tile value: ", map.gettile(0, 0, 0))
|
|
||||||
map.settile(0, 0, 0, 86)
|
|
||||||
map.settile(10, 10, 1, 156)
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ CREATE TABLE IF NOT EXISTS UserAccounts (
|
|||||||
-- password varchar(100),
|
-- password varchar(100),
|
||||||
blacklisted BIT DEFAULT 0,
|
blacklisted BIT DEFAULT 0,
|
||||||
whitelisted BIT DEFAULT 1
|
whitelisted BIT DEFAULT 1
|
||||||
|
-- TODO: moderator
|
||||||
);
|
);
|
||||||
|
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|||||||
@@ -19,6 +19,18 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
*/
|
*/
|
||||||
#include "character_data.hpp"
|
#ifndef ACCOUNTDATA_HPP_
|
||||||
|
#define ACCOUNTDATA_HPP_
|
||||||
|
|
||||||
int CharacterData::uidCounter = 0;
|
#include <string>
|
||||||
|
|
||||||
|
struct AccountData {
|
||||||
|
std::string username;
|
||||||
|
//TODO: password
|
||||||
|
bool blackListed = false;
|
||||||
|
bool whiteListed = true;
|
||||||
|
|
||||||
|
int clientIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
/* Copyright: (c) Kayne Ruse 2014
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
* arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software
|
||||||
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source
|
||||||
|
* distribution.
|
||||||
|
*/
|
||||||
|
#include "server_application.hpp"
|
||||||
|
|
||||||
|
#include "sqlite3/sqlite3.h"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//Define the queries
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
static const char* CREATE_USER_ACCOUNT = "INSERT INTO UserAccounts (username) VALUES (?);";
|
||||||
|
static const char* LOAD_USER_ACCOUNT = "SELECT * FROM UserAccounts WHERE username = ?;";
|
||||||
|
static const char* SAVE_USER_ACCOUNT = "UPDATE OR FAIL UserAccounts SET blacklisted = ?2, whitelisted = ?3 WHERE uid = ?1;";
|
||||||
|
static const char* DELETE_USER_ACCOUNT = "DELETE FROM UserAccounts WHERE uid = ?;";
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//Define the methods
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
int ServerApplication::CreateUserAccount(std::string username, int clientIndex) {
|
||||||
|
//create this user account, failing if it exists, leave this account in memory
|
||||||
|
sqlite3_stmt* statement = nullptr;
|
||||||
|
|
||||||
|
//prep
|
||||||
|
if (sqlite3_prepare_v2(database, CREATE_USER_ACCOUNT, -1, &statement, nullptr) != SQLITE_OK) {
|
||||||
|
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//parameter
|
||||||
|
if (sqlite3_bind_text(statement, 1, username.c_str(), username.size() + 1, SQLITE_STATIC) != SQLITE_OK) {
|
||||||
|
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//execute
|
||||||
|
if (sqlite3_step(statement) != SQLITE_DONE) {
|
||||||
|
//if this fails, than this account exists
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
|
||||||
|
//load this account into memory
|
||||||
|
return LoadUserAccount(username, clientIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerApplication::LoadUserAccount(std::string username, int clientIndex) {
|
||||||
|
//load this user account, failing if it is in memory, creating it if it doesn't exist
|
||||||
|
sqlite3_stmt* statement = nullptr;
|
||||||
|
|
||||||
|
//prep
|
||||||
|
if (sqlite3_prepare_v2(database, LOAD_USER_ACCOUNT, -1, &statement, nullptr) != SQLITE_OK) {
|
||||||
|
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//parameter
|
||||||
|
if (sqlite3_bind_text(statement, 1, username.c_str(), username.size() + 1, SQLITE_STATIC) != SQLITE_OK) {
|
||||||
|
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//execute
|
||||||
|
int ret = sqlite3_step(statement);
|
||||||
|
|
||||||
|
//process the result
|
||||||
|
if (ret == SQLITE_ROW) {
|
||||||
|
//get the index
|
||||||
|
int uid = sqlite3_column_int(statement, 0);
|
||||||
|
|
||||||
|
//check to see if this account is already loaded
|
||||||
|
if (accountMap.find(uid) != accountMap.end()) {
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//extract the data into memory
|
||||||
|
AccountData& newAccount = accountMap[uid];
|
||||||
|
newAccount.username = reinterpret_cast<const char*>(sqlite3_column_text(statement, 1));
|
||||||
|
newAccount.blackListed = sqlite3_column_int(statement, 2);
|
||||||
|
newAccount.whiteListed = sqlite3_column_int(statement, 3);
|
||||||
|
newAccount.clientIndex = clientIndex;
|
||||||
|
|
||||||
|
//finish the routine
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
return uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
|
||||||
|
if (ret == SQLITE_DONE) {
|
||||||
|
//create the non-existant account instead
|
||||||
|
return CreateUserAccount(username, clientIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw(std::runtime_error(std::string() + "Unknown SQL error in LoadUserAccount: " + sqlite3_errmsg(database) ));
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerApplication::SaveUserAccount(int uid) {
|
||||||
|
//save this user account from memory, replacing it if it exists in the database
|
||||||
|
//DOCS: To use this method, change the in-memory copy, and then call this function using that object's UID.
|
||||||
|
|
||||||
|
//this method fails if this account is not loaded
|
||||||
|
if (accountMap.find(uid) == accountMap.end()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccountData& account = accountMap[uid];
|
||||||
|
sqlite3_stmt* statement = nullptr;
|
||||||
|
|
||||||
|
//prep
|
||||||
|
if (sqlite3_prepare_v2(database, SAVE_USER_ACCOUNT, -1, &statement, nullptr) != SQLITE_OK) {
|
||||||
|
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//parameters
|
||||||
|
bool ret = false;
|
||||||
|
ret |= sqlite3_bind_int(statement, 1, uid) != SQLITE_OK;
|
||||||
|
ret |= sqlite3_bind_int(statement, 2, account.blackListed) != SQLITE_OK;
|
||||||
|
ret |= sqlite3_bind_int(statement, 3, account.whiteListed) != SQLITE_OK;
|
||||||
|
|
||||||
|
//check for binding errors
|
||||||
|
if (ret) {
|
||||||
|
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//execute
|
||||||
|
if (sqlite3_step(statement) != SQLITE_DONE) {
|
||||||
|
//if this fails, than something went horribly wrong
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
throw( std::runtime_error(std::string() + "Unknown SQL error when saving an account: " + sqlite3_errmsg(database)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
|
||||||
|
//successful execution
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerApplication::UnloadUserAccount(int uid) {
|
||||||
|
//save this user account, and then unload it
|
||||||
|
//NOTE: the associated characters are unloaded externally
|
||||||
|
SaveUserAccount(uid);
|
||||||
|
accountMap.erase(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerApplication::DeleteUserAccount(int uid) {
|
||||||
|
//delete a user account from the database, and remove it from memory
|
||||||
|
//NOTE: the associated characters are unloaded externally
|
||||||
|
sqlite3_stmt* statement = nullptr;
|
||||||
|
|
||||||
|
//prep
|
||||||
|
if (sqlite3_prepare_v2(database, DELETE_USER_ACCOUNT, -1, &statement, nullptr) != SQLITE_OK) {
|
||||||
|
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//parameter
|
||||||
|
if (sqlite3_bind_int(statement, 1, uid) != SQLITE_OK) {
|
||||||
|
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//execute
|
||||||
|
if (sqlite3_step(statement) != SQLITE_DONE) {
|
||||||
|
//if this fails, than something went horribly wrong
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
throw( std::runtime_error(std::string() + "Unknown SQL error when deleting an account: " + sqlite3_errmsg(database)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//finish the routine
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
accountMap.erase(uid);
|
||||||
|
}
|
||||||
@@ -30,8 +30,7 @@
|
|||||||
|
|
||||||
struct CharacterData {
|
struct CharacterData {
|
||||||
//metadata
|
//metadata
|
||||||
int clientIndex;
|
int owner;
|
||||||
std::string username;
|
|
||||||
std::string handle;
|
std::string handle;
|
||||||
std::string avatar;
|
std::string avatar;
|
||||||
|
|
||||||
@@ -55,9 +54,6 @@ struct CharacterData {
|
|||||||
float accuracy = 0.0;
|
float accuracy = 0.0;
|
||||||
float evasion = 0.0;
|
float evasion = 0.0;
|
||||||
float luck = 0.0;
|
float luck = 0.0;
|
||||||
|
|
||||||
//uid
|
|
||||||
static int uidCounter;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,228 @@
|
|||||||
|
/* Copyright: (c) Kayne Ruse 2014
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
* arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software
|
||||||
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source
|
||||||
|
* distribution.
|
||||||
|
*/
|
||||||
|
#include "server_application.hpp"
|
||||||
|
|
||||||
|
#include "sqlite3/sqlite3.h"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//Define the queries
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
static const char* CREATE_CHARACTER = "INSERT INTO PlayerCharacters (owner, handle, avatar) VALUES (?, ?, ?);";
|
||||||
|
static const char* LOAD_CHARACTER = "SELECT * FROM PlayerCharacters WHERE handle = ?;";
|
||||||
|
static const char* SAVE_CHARACTER = "UPDATE OR FAIL PlayerCharacters SET mapIndex = ?2, positionX = ?3, positionY = ?4 WHERE uid = ?1;";
|
||||||
|
static const char* DELETE_CHARACTER = "DELETE FROM PlayerCharacters WHERE uid = ?;";
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//Define the methods
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
int ServerApplication::CreateCharacter(int owner, std::string handle, std::string avatar) {
|
||||||
|
//Create the character, failing if it exists
|
||||||
|
sqlite3_stmt* statement = nullptr;
|
||||||
|
|
||||||
|
//prep
|
||||||
|
if (sqlite3_prepare_v2(database, CREATE_CHARACTER, -1, &statement, nullptr) != SQLITE_OK) {
|
||||||
|
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//parameters
|
||||||
|
bool ret = false;
|
||||||
|
ret |= sqlite3_bind_int(statement, 1, owner);
|
||||||
|
ret |= sqlite3_bind_text(statement, 2, handle.c_str(), handle.size() + 1, SQLITE_STATIC);
|
||||||
|
ret |= sqlite3_bind_text(statement, 3, avatar.c_str(), avatar.size() + 1, SQLITE_STATIC);
|
||||||
|
|
||||||
|
//check for binding errors
|
||||||
|
if (ret) {
|
||||||
|
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//execute
|
||||||
|
if (sqlite3_step(statement) != SQLITE_DONE) {
|
||||||
|
//if this fails, than this character exists
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
|
||||||
|
//load this character into memory
|
||||||
|
return LoadCharacter(owner, handle, avatar);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerApplication::LoadCharacter(int owner, std::string handle, std::string avatar) {
|
||||||
|
//load the specified character, creating it if it doesn't exist
|
||||||
|
//fail if it is already loaded, or does not belong to this account
|
||||||
|
sqlite3_stmt* statement = nullptr;
|
||||||
|
|
||||||
|
//prep
|
||||||
|
if (sqlite3_prepare_v2(database, LOAD_CHARACTER, -1, &statement, nullptr) != SQLITE_OK) {
|
||||||
|
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//parameter
|
||||||
|
if (sqlite3_bind_text(statement, 1, handle.c_str(), handle.size() + 1, SQLITE_STATIC) != SQLITE_OK) {
|
||||||
|
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//execute
|
||||||
|
int ret = sqlite3_step(statement);
|
||||||
|
|
||||||
|
//process the result
|
||||||
|
if (ret == SQLITE_ROW) {
|
||||||
|
//get the index
|
||||||
|
int uid = sqlite3_column_int(statement, 0);
|
||||||
|
|
||||||
|
//check to see if this character is already loaded
|
||||||
|
if (characterMap.find(uid) != characterMap.end()) {
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//check the owner
|
||||||
|
if (owner != sqlite3_column_int(statement, 1)) {
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//extract the data into memory
|
||||||
|
CharacterData& newChar = characterMap[uid];
|
||||||
|
|
||||||
|
//metadata
|
||||||
|
newChar.owner = owner;
|
||||||
|
newChar.handle = reinterpret_cast<const char*>(sqlite3_column_text(statement, 2));
|
||||||
|
newChar.avatar = reinterpret_cast<const char*>(sqlite3_column_text(statement, 3));
|
||||||
|
//Don't cache the birth
|
||||||
|
|
||||||
|
//world position
|
||||||
|
newChar.mapIndex = sqlite3_column_int(statement, 5);
|
||||||
|
newChar.position.x = (double)sqlite3_column_int(statement, 6);
|
||||||
|
newChar.position.y = (double)sqlite3_column_int(statement, 7);
|
||||||
|
|
||||||
|
//statistics
|
||||||
|
newChar.level = sqlite3_column_int(statement, 8);
|
||||||
|
newChar.exp = sqlite3_column_int(statement, 9);
|
||||||
|
newChar.maxHP = sqlite3_column_int(statement, 10);
|
||||||
|
newChar.health = sqlite3_column_int(statement, 11);
|
||||||
|
newChar.maxMP = sqlite3_column_int(statement, 12);
|
||||||
|
newChar.mana = sqlite3_column_int(statement, 13);
|
||||||
|
newChar.attack = sqlite3_column_int(statement, 14);
|
||||||
|
newChar.defence = sqlite3_column_int(statement, 15);
|
||||||
|
newChar.intelligence = sqlite3_column_int(statement, 16);
|
||||||
|
newChar.resistance = sqlite3_column_int(statement, 17);
|
||||||
|
newChar.accuracy = sqlite3_column_double(statement, 18);
|
||||||
|
newChar.evasion = sqlite3_column_double(statement, 19);
|
||||||
|
newChar.luck = sqlite3_column_double(statement, 20);
|
||||||
|
|
||||||
|
//TODO: equipment
|
||||||
|
|
||||||
|
//finish the routine
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
return uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
|
||||||
|
if (ret == SQLITE_DONE) {
|
||||||
|
//create the non-existant character instead
|
||||||
|
return CreateCharacter(owner, handle, avatar);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw(std::runtime_error(std::string() + "Unknown SQL error in LoadCharacter: " + sqlite3_errmsg(database) ));
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerApplication::SaveCharacter(int uid) {
|
||||||
|
//save this character from memory, replacing it if it exists in the database
|
||||||
|
//DOCS: To use this method, change the in-memory copy, and then call this function using that object's UID.
|
||||||
|
|
||||||
|
//this method fails if this character is not loaded
|
||||||
|
if (characterMap.find(uid) == characterMap.end()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
CharacterData& character = characterMap[uid];
|
||||||
|
sqlite3_stmt* statement = nullptr;
|
||||||
|
|
||||||
|
//prep
|
||||||
|
if (sqlite3_prepare_v2(database, SAVE_CHARACTER, -1, &statement, nullptr) != SQLITE_OK) {
|
||||||
|
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//parameters
|
||||||
|
bool ret = false;
|
||||||
|
ret |= sqlite3_bind_int(statement, 1, uid) != SQLITE_OK;
|
||||||
|
ret |= sqlite3_bind_int(statement, 2, character.mapIndex) != SQLITE_OK;
|
||||||
|
ret |= sqlite3_bind_int(statement, 3, (int)character.position.x) != SQLITE_OK;
|
||||||
|
ret |= sqlite3_bind_int(statement, 4, (int)character.position.y) != SQLITE_OK;
|
||||||
|
//TODO: stats, etc.
|
||||||
|
|
||||||
|
//check for binding errors
|
||||||
|
if (ret) {
|
||||||
|
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//execute
|
||||||
|
if (sqlite3_step(statement) != SQLITE_DONE) {
|
||||||
|
//if this fails, than something went horribly wrong
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
throw( std::runtime_error(std::string() + "Unknown SQL error when saving an account: " + sqlite3_errmsg(database)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
|
||||||
|
//successful execution
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerApplication::UnloadCharacter(int uid) {
|
||||||
|
//save this character, then unload it
|
||||||
|
SaveCharacter(uid);
|
||||||
|
characterMap.erase(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerApplication::DeleteCharacter(int uid) {
|
||||||
|
//delete this character from the database, then remove it from memory
|
||||||
|
sqlite3_stmt* statement = nullptr;
|
||||||
|
|
||||||
|
//prep
|
||||||
|
if (sqlite3_prepare_v2(database, DELETE_CHARACTER, -1, &statement, nullptr) != SQLITE_OK) {
|
||||||
|
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//parameter
|
||||||
|
if (sqlite3_bind_int(statement, 1, uid) != SQLITE_OK) {
|
||||||
|
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//execute
|
||||||
|
if (sqlite3_step(statement) != SQLITE_DONE) {
|
||||||
|
//if this fails, than something went horribly wrong
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
throw( std::runtime_error(std::string() + "Unknown SQL error when deleting an account: " + sqlite3_errmsg(database)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//finish the routine
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
characterMap.erase(uid);
|
||||||
|
}
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2014
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
|
||||||
* arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
* claim that you wrote the original software. If you use this software
|
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
|
||||||
* appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
* misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
*/
|
|
||||||
#include "client_data.hpp"
|
|
||||||
|
|
||||||
int ClientData::uidCounter = 0;
|
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
//server specific stuff
|
//server specific stuff
|
||||||
#include "client_data.hpp"
|
#include "client_data.hpp"
|
||||||
|
#include "account_data.hpp"
|
||||||
#include "character_data.hpp"
|
#include "character_data.hpp"
|
||||||
|
|
||||||
//maps
|
//maps
|
||||||
@@ -47,6 +48,7 @@
|
|||||||
|
|
||||||
//STL
|
//STL
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
//The main application class
|
//The main application class
|
||||||
class ServerApplication {
|
class ServerApplication {
|
||||||
@@ -73,8 +75,22 @@ private:
|
|||||||
|
|
||||||
//TODO: a function that only sends to characters in a certain proximity
|
//TODO: a function that only sends to characters in a certain proximity
|
||||||
void PumpPacket(SerialPacket);
|
void PumpPacket(SerialPacket);
|
||||||
|
void PumpCharacterUnload(int uid);
|
||||||
|
|
||||||
|
//Account management
|
||||||
|
int CreateUserAccount(std::string username, int clientIndex);
|
||||||
|
int LoadUserAccount(std::string username, int clientIndex);
|
||||||
|
int SaveUserAccount(int uid);
|
||||||
|
void UnloadUserAccount(int uid);
|
||||||
|
void DeleteUserAccount(int uid);
|
||||||
|
|
||||||
|
//TODO: character management
|
||||||
|
int CreateCharacter(int owner, std::string handle, std::string avatar);
|
||||||
|
int LoadCharacter(int owner, std::string handle, std::string avatar);
|
||||||
|
int SaveCharacter(int uid);
|
||||||
|
void UnloadCharacter(int uid);
|
||||||
|
void DeleteCharacter(int uid);
|
||||||
|
|
||||||
//TODO: manage the database
|
|
||||||
//TODO: combat systems
|
//TODO: combat systems
|
||||||
|
|
||||||
//APIs
|
//APIs
|
||||||
@@ -84,6 +100,7 @@ private:
|
|||||||
|
|
||||||
//server tables
|
//server tables
|
||||||
std::map<int, ClientData> clientMap;
|
std::map<int, ClientData> clientMap;
|
||||||
|
std::map<int, AccountData> accountMap;
|
||||||
std::map<int, CharacterData> characterMap;
|
std::map<int, CharacterData> characterMap;
|
||||||
|
|
||||||
//maps
|
//maps
|
||||||
|
|||||||
@@ -46,18 +46,28 @@ void ServerApplication::HandleJoinRequest(SerialPacket packet) {
|
|||||||
ClientData newClient;
|
ClientData newClient;
|
||||||
newClient.address = packet.meta.srcAddress;
|
newClient.address = packet.meta.srcAddress;
|
||||||
|
|
||||||
//TODO: move this into the character management code
|
//load the user account
|
||||||
//create the new character
|
int accountIndex = LoadUserAccount(packet.clientInfo.username, ClientData::uidCounter);
|
||||||
CharacterData newCharacter;
|
if (accountIndex < 0) {
|
||||||
newCharacter.clientIndex = ClientData::uidCounter;
|
//TODO: send rejection packet
|
||||||
newCharacter.username = packet.clientInfo.username;
|
std::cerr << "Error: Account already loaded: " << accountIndex << std::endl;
|
||||||
newCharacter.handle = packet.clientInfo.handle;
|
return;
|
||||||
newCharacter.avatar = packet.clientInfo.avatar;
|
}
|
||||||
|
|
||||||
|
//load the new character
|
||||||
|
int characterIndex = LoadCharacter(accountIndex, packet.clientInfo.handle, packet.clientInfo.avatar);
|
||||||
|
if (characterIndex < 0) {
|
||||||
|
//TODO: send rejection packet
|
||||||
|
std::cerr << "Error: Character already loaded: " << characterIndex << std::endl;
|
||||||
|
UnloadUserAccount(accountIndex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//send the client their info
|
//send the client their info
|
||||||
packet.meta.type = SerialPacket::Type::JOIN_RESPONSE;
|
packet.meta.type = SerialPacket::Type::JOIN_RESPONSE;
|
||||||
packet.clientInfo.clientIndex = ClientData::uidCounter;
|
packet.clientInfo.clientIndex = ClientData::uidCounter;
|
||||||
packet.clientInfo.characterIndex = CharacterData::uidCounter;
|
packet.clientInfo.accountIndex = accountIndex;
|
||||||
|
packet.clientInfo.characterIndex = characterIndex;
|
||||||
|
|
||||||
//bounce this packet
|
//bounce this packet
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
char buffer[PACKET_BUFFER_SIZE];
|
||||||
@@ -66,18 +76,16 @@ void ServerApplication::HandleJoinRequest(SerialPacket packet) {
|
|||||||
|
|
||||||
//send the new character to all clients
|
//send the new character to all clients
|
||||||
packet.meta.type = SerialPacket::Type::CHARACTER_NEW;
|
packet.meta.type = SerialPacket::Type::CHARACTER_NEW;
|
||||||
packet.characterInfo.characterIndex = CharacterData::uidCounter;
|
packet.characterInfo.characterIndex = characterIndex;
|
||||||
strncpy(packet.characterInfo.handle, newCharacter.handle.c_str(), PACKET_STRING_SIZE);
|
strncpy(packet.characterInfo.handle, characterMap[characterIndex].handle.c_str(), PACKET_STRING_SIZE);
|
||||||
strncpy(packet.characterInfo.avatar, newCharacter.avatar.c_str(), PACKET_STRING_SIZE);
|
strncpy(packet.characterInfo.avatar, characterMap[characterIndex].avatar.c_str(), PACKET_STRING_SIZE);
|
||||||
packet.characterInfo.position = newCharacter.position;
|
packet.characterInfo.position = characterMap[characterIndex].position;
|
||||||
packet.characterInfo.motion = newCharacter.motion;
|
packet.characterInfo.motion = characterMap[characterIndex].motion;
|
||||||
PumpPacket(packet);
|
PumpPacket(packet);
|
||||||
|
|
||||||
|
//TODO: don't send anything to a certain client until they send the OK (the sync packet? or ignore client side?)
|
||||||
//finished this routine
|
//finished this routine
|
||||||
clientMap[ClientData::uidCounter] = newClient;
|
clientMap[ClientData::uidCounter++] = newClient;
|
||||||
characterMap[CharacterData::uidCounter] = newCharacter;
|
|
||||||
ClientData::uidCounter++;
|
|
||||||
CharacterData::uidCounter++;
|
|
||||||
std::cout << "Connect, total: " << clientMap.size() << std::endl;
|
std::cout << "Connect, total: " << clientMap.size() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,33 +113,28 @@ void ServerApplication::HandleSynchronize(SerialPacket packet) {
|
|||||||
|
|
||||||
void ServerApplication::HandleDisconnect(SerialPacket packet) {
|
void ServerApplication::HandleDisconnect(SerialPacket packet) {
|
||||||
//TODO: authenticate who is disconnecting/kicking
|
//TODO: authenticate who is disconnecting/kicking
|
||||||
//TODO: define the difference between unloading and deletng a character
|
|
||||||
|
|
||||||
//disconnect the specified client
|
//forward to the specified client
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
char buffer[PACKET_BUFFER_SIZE];
|
||||||
serialize(&packet, buffer);
|
serialize(&packet, buffer);
|
||||||
network.Send(&clientMap[packet.clientInfo.clientIndex].address, buffer, PACKET_BUFFER_SIZE);
|
network.Send(&clientMap[accountMap[packet.clientInfo.accountIndex].clientIndex].address, buffer, PACKET_BUFFER_SIZE);
|
||||||
clientMap.erase(packet.clientInfo.clientIndex);
|
|
||||||
|
|
||||||
//prep the delete packet
|
//unload client and server-side characters
|
||||||
SerialPacket delPacket;
|
for (std::map<int, CharacterData>::iterator it = characterMap.begin(); it != characterMap.end(); /* EMPTY */ ) {
|
||||||
delPacket.meta.type = SerialPacket::Type::CHARACTER_DELETE;
|
if (it->second.owner == packet.clientInfo.accountIndex) {
|
||||||
|
PumpCharacterUnload(it->first);
|
||||||
//delete server and client side characters
|
SaveCharacter(it->first);
|
||||||
erase_if(characterMap, [&](std::pair<int, CharacterData> it) -> bool {
|
it = characterMap.erase(it); //efficient
|
||||||
//find the internal characters to delete
|
continue;
|
||||||
if (it.second.clientIndex == packet.clientInfo.clientIndex) {
|
|
||||||
//send the delete characters command to all clients
|
|
||||||
delPacket.characterInfo.characterIndex = it.first;
|
|
||||||
PumpPacket(delPacket);
|
|
||||||
|
|
||||||
//delete this characters object
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//don't delete this characters object
|
//erase the in-memory stuff
|
||||||
return false;
|
clientMap.erase(accountMap[packet.clientInfo.accountIndex].clientIndex);
|
||||||
});
|
UnloadUserAccount(packet.clientInfo.accountIndex);
|
||||||
|
|
||||||
//finished this routine
|
//finished this routine
|
||||||
std::cout << "Disconnect, total: " << clientMap.size() << std::endl;
|
std::cout << "Disconnect, total: " << clientMap.size() << std::endl;
|
||||||
@@ -145,7 +148,6 @@ void ServerApplication::HandleShutdown(SerialPacket packet) {
|
|||||||
|
|
||||||
//disconnect all clients
|
//disconnect all clients
|
||||||
packet.meta.type = SerialPacket::Type::DISCONNECT;
|
packet.meta.type = SerialPacket::Type::DISCONNECT;
|
||||||
packet.clientInfo.clientIndex = -1;
|
|
||||||
PumpPacket(packet);
|
PumpPacket(packet);
|
||||||
|
|
||||||
//finished this routine
|
//finished this routine
|
||||||
@@ -184,3 +186,11 @@ void ServerApplication::PumpPacket(SerialPacket packet) {
|
|||||||
network.Send(&it.second.address, buffer, PACKET_BUFFER_SIZE);
|
network.Send(&it.second.address, buffer, PACKET_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServerApplication::PumpCharacterUnload(int uid) {
|
||||||
|
//delete the client-side character(s)
|
||||||
|
SerialPacket delPacket;
|
||||||
|
delPacket.meta.type = SerialPacket::Type::CHARACTER_DELETE;
|
||||||
|
delPacket.characterInfo.characterIndex = uid;
|
||||||
|
PumpPacket(delPacket);
|
||||||
|
}
|
||||||
@@ -21,12 +21,18 @@
|
|||||||
*/
|
*/
|
||||||
#include "server_application.hpp"
|
#include "server_application.hpp"
|
||||||
|
|
||||||
#include "server_utility.hpp"
|
#include "sql_utility.hpp"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//Define the various UIDs
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
int ClientData::uidCounter = 0;
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//Define the public members
|
//Define the public members
|
||||||
//-------------------------
|
//-------------------------
|
||||||
@@ -138,9 +144,16 @@ void ServerApplication::Quit() {
|
|||||||
std::cout << "Shutting down" << std::endl;
|
std::cout << "Shutting down" << std::endl;
|
||||||
|
|
||||||
//save the server state
|
//save the server state
|
||||||
//TODO: save the existing players
|
for (auto& it : accountMap) {
|
||||||
|
SaveUserAccount(it.first);
|
||||||
|
}
|
||||||
|
for (auto& it : characterMap) {
|
||||||
|
SaveCharacter(it.first);
|
||||||
|
}
|
||||||
|
|
||||||
//empty the members
|
//empty the members
|
||||||
|
accountMap.clear();
|
||||||
|
characterMap.clear();
|
||||||
regionPager.UnloadAll();
|
regionPager.UnloadAll();
|
||||||
|
|
||||||
//APIs
|
//APIs
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
I need to keep the documentation up to date. Namey, the GDD is getting out of date.
|
* I need to keep the documentation up to date. Namely, the GDD is getting out of date.
|
||||||
|
* How many lookups is the map system using?
|
||||||
|
* Add the serial packet to the network utility
|
||||||
|
|
||||||
--Naming conventions--
|
--Naming conventions--
|
||||||
|
|
||||||
@@ -28,3 +30,10 @@ These interact with the database file, making the server a persistent system.
|
|||||||
* UnloadCharacter
|
* UnloadCharacter
|
||||||
* DeleteCharacter
|
* DeleteCharacter
|
||||||
|
|
||||||
|
--Battle System--
|
||||||
|
|
||||||
|
CombatPortal:
|
||||||
|
x, y
|
||||||
|
list<Character>
|
||||||
|
list<Monster>
|
||||||
|
//...
|
||||||
Reference in New Issue
Block a user