Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fdaae0e8f2 | |||
| bd3838a04e | |||
| 5eeda8235d | |||
| 20d40d5b81 | |||
| 5e11077c7a | |||
| ba81bcba69 | |||
| 9329274866 | |||
| ace87b438b | |||
| 1f3c1f32f4 | |||
| cacd3dcd6d | |||
| 97b7945191 | |||
| a01d75549f | |||
| ecd0b43abe | |||
| d35ab24e15 | |||
| 100c4f6522 | |||
| a1c20959fe | |||
| 3b9df46510 | |||
| f7ba34dcec | |||
| 74234684af | |||
| 06e027710f | |||
| 73d9095604 | |||
| f2d79225a3 | |||
| daa38413f3 | |||
| a4ed23f6c7 | |||
| cfdc61c357 | |||
| 77b47b4634 | |||
| 0f139562c3 | |||
| fc2bc06992 | |||
| 8eefdd71b5 | |||
| 966443be3d | |||
| 5327d91917 | |||
| 6399efc227 | |||
| 7da5de619b | |||
| 0735037f10 | |||
| 8c78a5d26c | |||
| f584dd140b | |||
| 4434900afc | |||
| e488b15acc | |||
| 387e86de63 | |||
| 0e3a042fbb | |||
| de7167e830 | |||
| 40c76b4285 |
+34
@@ -0,0 +1,34 @@
|
|||||||
|
This is the README for Tortuga's demo build. The source code is available at:
|
||||||
|
|
||||||
|
https://github.com/Ratstail91/Tortuga
|
||||||
|
|
||||||
|
The current build may have bugs, missing features, bugs masquerading as
|
||||||
|
features, etc. You can report a bug/feature here:
|
||||||
|
|
||||||
|
https://github.com/Ratstail91/Tortuga/issues
|
||||||
|
|
||||||
|
Please note that this game requires a functioning server to operate correctly.
|
||||||
|
Both a game server and game client are included in this package.
|
||||||
|
|
||||||
|
-------------------------
|
||||||
|
Instructions For Setup
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
1. To create a server, simply run server.exe.
|
||||||
|
2. To join that server, run client.exe with config settings not already in use.
|
||||||
|
(Note: This process will be streamlined later).
|
||||||
|
3. To change the config settings, open rsc/config.cfg
|
||||||
|
4. These settings must be unique for each player:
|
||||||
|
|
||||||
|
* client.username
|
||||||
|
* client.handle
|
||||||
|
|
||||||
|
5. There are currently two options for 'client.avatar':
|
||||||
|
|
||||||
|
* client.avatar = elliot2.bmp #male
|
||||||
|
* client.avatar = coa2.bmp #female
|
||||||
|
|
||||||
|
6. When you've correctly set these values (good luck), select 'Start' from the
|
||||||
|
main menu; this displays the list of available servers.
|
||||||
|
7. Select the name of your server (default is 'local') and select 'Join'.
|
||||||
|
8. Welcome to Tortuga, enjoy your stay.
|
||||||
@@ -49,7 +49,7 @@ void ClientApplication::Init(int argc, char* argv[]) {
|
|||||||
|
|
||||||
//load the prerequisites
|
//load the prerequisites
|
||||||
ConfigUtility& config = ConfigUtility::GetSingleton();
|
ConfigUtility& config = ConfigUtility::GetSingleton();
|
||||||
config.Load("rsc\\config.cfg", argc, argv);
|
config.Load("rsc/config.cfg", argc, argv);
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//Initialize the APIs
|
//Initialize the APIs
|
||||||
|
|||||||
@@ -24,12 +24,12 @@
|
|||||||
|
|
||||||
//components
|
//components
|
||||||
#include "character_defines.hpp"
|
#include "character_defines.hpp"
|
||||||
#include "renderable.hpp"
|
#include "entity.hpp"
|
||||||
|
|
||||||
//std namespace
|
//std namespace
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class BaseCharacter : public Renderable {
|
class BaseCharacter : public Entity {
|
||||||
public:
|
public:
|
||||||
BaseCharacter() = default;
|
BaseCharacter() = default;
|
||||||
virtual ~BaseCharacter() = default;
|
virtual ~BaseCharacter() = default;
|
||||||
@@ -22,12 +22,12 @@
|
|||||||
#ifndef BASEMONSTER_HPP_
|
#ifndef BASEMONSTER_HPP_
|
||||||
#define BASEMONSTER_HPP_
|
#define BASEMONSTER_HPP_
|
||||||
|
|
||||||
#include "renderable.hpp"
|
#include "entity.hpp"
|
||||||
|
|
||||||
class BaseMonster {
|
class BaseMonster : public Entity {
|
||||||
public:
|
public:
|
||||||
BaseMonster();
|
BaseMonster() = default;
|
||||||
virtual ~BaseMonster();
|
virtual ~BaseMonster() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//
|
//
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/* 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 "entity.hpp"
|
||||||
|
|
||||||
|
void Entity::Update() {
|
||||||
|
origin += motion;
|
||||||
|
sprite.Update(0.016);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::DrawTo(SDL_Surface* const dest, int camX, int camY) {
|
||||||
|
sprite.DrawTo(dest, origin.x - camX, origin.y - camY);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Entity::SetEntityIndex(int i) {
|
||||||
|
return entityIndex = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Entity::SetRoomIndex(int i) {
|
||||||
|
return roomIndex = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 Entity::SetOrigin(Vector2 v) {
|
||||||
|
return origin = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 Entity::SetMotion(Vector2 v) {
|
||||||
|
return motion = v;
|
||||||
|
}
|
||||||
|
int Entity::GetEntityIndex() {
|
||||||
|
return entityIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Entity::GetRoomIndex() {
|
||||||
|
return roomIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 Entity::GetOrigin() {
|
||||||
|
return origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 Entity::GetMotion() {
|
||||||
|
return motion;
|
||||||
|
}
|
||||||
@@ -19,37 +19,43 @@
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
#ifndef RENDERABLE_HPP_
|
#ifndef ENTITY_HPP_
|
||||||
#define RENDERABLE_HPP_
|
#define ENTITY_HPP_
|
||||||
|
|
||||||
#include "bounding_box.hpp"
|
#include "bounding_box.hpp"
|
||||||
#include "sprite_sheet.hpp"
|
#include "sprite_sheet.hpp"
|
||||||
#include "vector2.hpp"
|
#include "vector2.hpp"
|
||||||
|
|
||||||
class Renderable {
|
//The base class for all objects in the world
|
||||||
|
class Entity {
|
||||||
public:
|
public:
|
||||||
Renderable() = default;
|
|
||||||
virtual ~Renderable() = default;
|
|
||||||
|
|
||||||
virtual void Update();
|
virtual void Update();
|
||||||
virtual void DrawTo(SDL_Surface* const, int camX, int camY);
|
virtual void DrawTo(SDL_Surface* const, int camX, int camY);
|
||||||
|
|
||||||
SpriteSheet* GetSprite() { return &sprite; }
|
SpriteSheet* GetSprite() { return &sprite; }
|
||||||
|
|
||||||
//position
|
//accessors & mutators
|
||||||
Vector2 SetOrigin(Vector2 v) { return origin = v; }
|
int SetEntityIndex(int i);
|
||||||
Vector2 GetOrigin() const { return origin; }
|
int SetRoomIndex(int i);
|
||||||
Vector2 SetMotion(Vector2 v) { return motion = v; }
|
Vector2 SetOrigin(Vector2 v);
|
||||||
Vector2 GetMotion() const { return motion; }
|
Vector2 SetMotion(Vector2 v);
|
||||||
|
|
||||||
//collision
|
|
||||||
BoundingBox SetBounds(BoundingBox b) { return bounds = b; }
|
BoundingBox SetBounds(BoundingBox b) { return bounds = b; }
|
||||||
|
|
||||||
|
int GetEntityIndex();
|
||||||
|
int GetRoomIndex();
|
||||||
|
Vector2 GetOrigin();
|
||||||
|
Vector2 GetMotion();
|
||||||
BoundingBox GetBounds() { return bounds; }
|
BoundingBox GetBounds() { return bounds; }
|
||||||
|
|
||||||
protected: //TODO: should be private
|
protected:
|
||||||
|
Entity() = default;
|
||||||
|
~Entity() = default;
|
||||||
|
|
||||||
SpriteSheet sprite;
|
SpriteSheet sprite;
|
||||||
Vector2 origin = {0, 0};
|
int entityIndex = -1;
|
||||||
Vector2 motion = {0, 0};
|
int roomIndex = -1;
|
||||||
|
Vector2 origin;
|
||||||
|
Vector2 motion;
|
||||||
BoundingBox bounds;
|
BoundingBox bounds;
|
||||||
};
|
};
|
||||||
|
|
||||||
+13
-5
@@ -1,6 +1,15 @@
|
|||||||
#config
|
#include directories
|
||||||
INCLUDES+=. client_utilities renderable scenes ../common/debugging ../common/gameplay ../common/graphics ../common/map ../common/network ../common/network/packet_types ../common/ui ../common/utilities
|
INCLUDES+=. entities scenes ../common/debugging ../common/gameplay ../common/graphics ../common/map ../common/network ../common/network/packet_types ../common/ui ../common/utilities
|
||||||
LIBS+=client.a ../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua
|
|
||||||
|
#libraries
|
||||||
|
#the order of the $(LIBS) is important, at least for MinGW
|
||||||
|
LIBS+=client.a ../libcommon.a -lSDL_net
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
LIBS+=-lwsock32 -liphlpapi -lmingw32
|
||||||
|
endif
|
||||||
|
LIBS+=-lSDLmain -lSDL
|
||||||
|
|
||||||
|
#flags
|
||||||
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
|
|
||||||
#source
|
#source
|
||||||
@@ -16,9 +25,8 @@ OUT=$(addprefix $(OUTDIR)/,client)
|
|||||||
|
|
||||||
#targets
|
#targets
|
||||||
all: $(OBJ) $(OUT)
|
all: $(OBJ) $(OUT)
|
||||||
$(MAKE) -C client_utilities
|
$(MAKE) -C entities
|
||||||
$(MAKE) -C scenes
|
$(MAKE) -C scenes
|
||||||
$(MAKE) -C renderable
|
|
||||||
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
|
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
|
||||||
|
|
||||||
$(OBJ): | $(OBJDIR)
|
$(OBJ): | $(OBJDIR)
|
||||||
|
|||||||
+61
-41
@@ -67,15 +67,15 @@ InWorld::InWorld(int* const argClientIndex, int* const argAccountIndex):
|
|||||||
tileSheet.Load(config["dir.tilesets"] + "overworld.bmp", 32, 32);
|
tileSheet.Load(config["dir.tilesets"] + "overworld.bmp", 32, 32);
|
||||||
|
|
||||||
//send this player's character info
|
//send this player's character info
|
||||||
CharacterPacket newPacket;
|
// CharacterPacket newPacket;
|
||||||
newPacket.type = SerialPacketType::CHARACTER_NEW;
|
// newPacket.type = SerialPacketType::CHARACTER_NEW;
|
||||||
strncpy(newPacket.handle, config["client.handle"].c_str(), PACKET_STRING_SIZE);
|
// strncpy(newPacket.handle, config["client.handle"].c_str(), PACKET_STRING_SIZE);
|
||||||
strncpy(newPacket.avatar, config["client.avatar"].c_str(), PACKET_STRING_SIZE);
|
// strncpy(newPacket.avatar, config["client.avatar"].c_str(), PACKET_STRING_SIZE);
|
||||||
newPacket.accountIndex = accountIndex;
|
// newPacket.accountIndex = accountIndex;
|
||||||
network.SendTo(Channels::SERVER, &newPacket);
|
// network.SendTo(Channels::SERVER, &newPacket);
|
||||||
|
|
||||||
//request a sync
|
//request a sync
|
||||||
RequestSynchronize();
|
// RequestSynchronize();
|
||||||
|
|
||||||
//debug
|
//debug
|
||||||
//
|
//
|
||||||
@@ -138,7 +138,7 @@ void InWorld::Update() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//update the camera
|
//update the camera (following the player)
|
||||||
camera.x = localCharacter->GetOrigin().x - camera.marginX;
|
camera.x = localCharacter->GetOrigin().x - camera.marginX;
|
||||||
camera.y = localCharacter->GetOrigin().y - camera.marginY;
|
camera.y = localCharacter->GetOrigin().y - camera.marginY;
|
||||||
|
|
||||||
@@ -179,6 +179,7 @@ void InWorld::Render(SDL_Surface* const screen) {
|
|||||||
//draw characters
|
//draw characters
|
||||||
for (auto& it : characterMap) {
|
for (auto& it : characterMap) {
|
||||||
//BUG: #29 drawing order according to Y origin
|
//BUG: #29 drawing order according to Y origin
|
||||||
|
//TODO: use a list of renderable objects
|
||||||
it.second.DrawTo(screen, camera.x, camera.y);
|
it.second.DrawTo(screen, camera.x, camera.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,10 +210,10 @@ 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) {
|
if (disconnectButton.MouseButtonUp(button) == Button::State::HOVER && button.button == SDL_BUTTON_LEFT) {
|
||||||
RequestDisconnect();
|
RequestDisconnect();
|
||||||
}
|
}
|
||||||
if (shutDownButton.MouseButtonUp(button) == Button::State::HOVER) {
|
if (shutDownButton.MouseButtonUp(button) == Button::State::HOVER && button.button == SDL_BUTTON_LEFT) {
|
||||||
RequestShutDown();
|
RequestShutDown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -287,30 +288,55 @@ void InWorld::KeyUp(SDL_KeyboardEvent const& key) {
|
|||||||
|
|
||||||
void InWorld::HandlePacket(SerialPacket* const argPacket) {
|
void InWorld::HandlePacket(SerialPacket* const argPacket) {
|
||||||
switch(argPacket->type) {
|
switch(argPacket->type) {
|
||||||
case SerialPacketType::PING:
|
//heartbeat system
|
||||||
HandlePing(static_cast<ServerPacket*>(argPacket));
|
case SerialPacketType::PING: {
|
||||||
|
ServerPacket newPacket;
|
||||||
|
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;
|
||||||
case SerialPacketType::DISCONNECT:
|
|
||||||
HandleDisconnect(static_cast<ClientPacket*>(argPacket));
|
//game server connections
|
||||||
|
case SerialPacketType::LOGOUT_RESPONSE:
|
||||||
|
// HandleLogoutResponse(static_cast<ClientPacket*>(argPacket));
|
||||||
break;
|
break;
|
||||||
case SerialPacketType::CHARACTER_NEW:
|
case SerialPacketType::DISCONNECT_REQUEST:
|
||||||
HandleCharacterNew(static_cast<CharacterPacket*>(argPacket));
|
// HandleDisconnectRequest(static_cast<ClientPacket*>(argPacket));
|
||||||
break;
|
break;
|
||||||
case SerialPacketType::CHARACTER_DELETE:
|
case SerialPacketType::DISCONNECT_FORCED:
|
||||||
HandleCharacterDelete(static_cast<CharacterPacket*>(argPacket));
|
// HandleDisconnectForced(static_cast<ClientPacket*>(argPacket));
|
||||||
break;
|
|
||||||
case SerialPacketType::CHARACTER_UPDATE:
|
|
||||||
HandleCharacterUpdate(static_cast<CharacterPacket*>(argPacket));
|
|
||||||
break;
|
|
||||||
case SerialPacketType::CHARACTER_REJECTION:
|
|
||||||
HandleCharacterRejection(static_cast<TextPacket*>(argPacket));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
//data management
|
||||||
case SerialPacketType::REGION_CONTENT:
|
case SerialPacketType::REGION_CONTENT:
|
||||||
HandleRegionContent(static_cast<RegionPacket*>(argPacket));
|
// HandleRegionContent(static_cast<RegionPacket*>(argPacket));
|
||||||
break;
|
break;
|
||||||
|
// 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
|
//handle errors
|
||||||
default:
|
default:
|
||||||
throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in InWorld: " + to_string_custom(static_cast<int>(argPacket->type)) ));
|
throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in InWorld: " + to_string_custom(static_cast<int>(argPacket->type)) ));
|
||||||
@@ -318,15 +344,9 @@ void InWorld::HandlePacket(SerialPacket* const argPacket) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)->host != argPacket->srcAddress.host) {
|
||||||
throw(std::runtime_error("Heartbeat message received from unknown source"));
|
throw(std::runtime_error("Heartbeat message received from an unknown source"));
|
||||||
}
|
}
|
||||||
|
|
||||||
attemptedBeats = 0;
|
attemptedBeats = 0;
|
||||||
@@ -433,23 +453,23 @@ void InWorld::HandleRegionContent(RegionPacket* const argPacket) {
|
|||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
void InWorld::RequestSynchronize() {
|
void InWorld::RequestSynchronize() {
|
||||||
ClientPacket newPacket;
|
// ClientPacket newPacket;
|
||||||
|
|
||||||
//request a sync
|
//request a sync
|
||||||
newPacket.type = SerialPacketType::SYNCHRONIZE;
|
// newPacket.type = SerialPacketType::SYNCHRONIZE;
|
||||||
newPacket.clientIndex = clientIndex;
|
// newPacket.clientIndex = clientIndex;
|
||||||
newPacket.accountIndex = accountIndex;
|
// newPacket.accountIndex = accountIndex;
|
||||||
|
|
||||||
//TODO: location, range for sync request
|
//TODO: location, range for sync request
|
||||||
|
|
||||||
network.SendTo(Channels::SERVER, &newPacket);
|
// network.SendTo(Channels::SERVER, &newPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InWorld::SendPlayerUpdate() {
|
void InWorld::SendPlayerUpdate() {
|
||||||
CharacterPacket newPacket;
|
CharacterPacket newPacket;
|
||||||
|
|
||||||
//pack the packet
|
//pack the packet
|
||||||
newPacket.type = SerialPacketType::CHARACTER_UPDATE;
|
// newPacket.type = SerialPacketType::CHARACTER_UPDATE;
|
||||||
|
|
||||||
newPacket.characterIndex = characterIndex;
|
newPacket.characterIndex = characterIndex;
|
||||||
//NOTE: omitting the handle and avatar here
|
//NOTE: omitting the handle and avatar here
|
||||||
@@ -468,7 +488,7 @@ void InWorld::RequestDisconnect() {
|
|||||||
ClientPacket newPacket;
|
ClientPacket newPacket;
|
||||||
|
|
||||||
//send a disconnect request
|
//send a disconnect request
|
||||||
newPacket.type = SerialPacketType::DISCONNECT;
|
newPacket.type = SerialPacketType::DISCONNECT_REQUEST;
|
||||||
newPacket.clientIndex = clientIndex;
|
newPacket.clientIndex = clientIndex;
|
||||||
newPacket.accountIndex = accountIndex;
|
newPacket.accountIndex = accountIndex;
|
||||||
|
|
||||||
@@ -479,7 +499,7 @@ void InWorld::RequestShutDown() {
|
|||||||
ClientPacket newPacket;
|
ClientPacket newPacket;
|
||||||
|
|
||||||
//send a shutdown request
|
//send a shutdown request
|
||||||
newPacket.type = SerialPacketType::SHUTDOWN;
|
newPacket.type = SerialPacketType::SHUTDOWN_REQUEST;
|
||||||
newPacket.clientIndex = clientIndex;
|
newPacket.clientIndex = clientIndex;
|
||||||
newPacket.accountIndex = accountIndex;
|
newPacket.accountIndex = accountIndex;
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
#include "frame_rate.hpp"
|
#include "frame_rate.hpp"
|
||||||
|
|
||||||
#include "base_character.hpp"
|
#include "base_character.hpp"
|
||||||
#include "local_character.hpp"
|
#include "base_monster.hpp"
|
||||||
|
|
||||||
//client
|
//client
|
||||||
#include "base_scene.hpp"
|
#include "base_scene.hpp"
|
||||||
@@ -73,7 +73,6 @@ protected:
|
|||||||
|
|
||||||
//Network handlers
|
//Network handlers
|
||||||
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 HandleDisconnect(ClientPacket* const);
|
||||||
void HandleCharacterNew(CharacterPacket* const);
|
void HandleCharacterNew(CharacterPacket* const);
|
||||||
@@ -92,12 +91,13 @@ protected:
|
|||||||
//utilities
|
//utilities
|
||||||
void UpdateMap();
|
void UpdateMap();
|
||||||
|
|
||||||
//shared parameters
|
//singleton shortcut
|
||||||
UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton();
|
UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton();
|
||||||
|
|
||||||
|
//indexes
|
||||||
int& clientIndex;
|
int& clientIndex;
|
||||||
int& accountIndex;
|
int& accountIndex;
|
||||||
int characterIndex = -1;
|
int characterIndex = -1;
|
||||||
std::map<int, BaseCharacter> characterMap;
|
|
||||||
|
|
||||||
//graphics
|
//graphics
|
||||||
Image buttonImage;
|
Image buttonImage;
|
||||||
@@ -110,6 +110,7 @@ protected:
|
|||||||
//UI
|
//UI
|
||||||
Button disconnectButton;
|
Button disconnectButton;
|
||||||
Button shutDownButton;
|
Button shutDownButton;
|
||||||
|
FrameRate fps;
|
||||||
|
|
||||||
//the camera structure
|
//the camera structure
|
||||||
struct {
|
struct {
|
||||||
@@ -117,12 +118,13 @@ protected:
|
|||||||
int width = 0, height = 0;
|
int width = 0, height = 0;
|
||||||
int marginX = 0, marginY = 0;
|
int marginX = 0, marginY = 0;
|
||||||
} camera;
|
} camera;
|
||||||
FrameRate fps;
|
|
||||||
|
|
||||||
//game
|
//game components
|
||||||
BaseCharacter* localCharacter = nullptr;
|
BaseCharacter* localCharacter = nullptr;
|
||||||
|
std::map<int, BaseCharacter> characterMap;
|
||||||
|
std::map<int, BaseMonster> monsterMap;
|
||||||
|
|
||||||
//connections
|
//heartbeat
|
||||||
//TODO: This needs it's own utility, for both InWorld and InCombat
|
//TODO: This needs it's own utility, for both InWorld and InCombat
|
||||||
typedef std::chrono::steady_clock Clock;
|
typedef std::chrono::steady_clock Clock;
|
||||||
Clock::time_point lastBeat = Clock::now();
|
Clock::time_point lastBeat = Clock::now();
|
||||||
|
|||||||
@@ -190,15 +190,25 @@ void LobbyMenu::KeyUp(SDL_KeyboardEvent const& key) {
|
|||||||
|
|
||||||
void LobbyMenu::HandlePacket(SerialPacket* const argPacket) {
|
void LobbyMenu::HandlePacket(SerialPacket* const argPacket) {
|
||||||
switch(argPacket->type) {
|
switch(argPacket->type) {
|
||||||
|
//responses
|
||||||
case SerialPacketType::BROADCAST_RESPONSE:
|
case SerialPacketType::BROADCAST_RESPONSE:
|
||||||
HandleBroadcastResponse(static_cast<ServerPacket*>(argPacket));
|
HandleBroadcastResponse(static_cast<ServerPacket*>(argPacket));
|
||||||
break;
|
break;
|
||||||
case SerialPacketType::JOIN_RESPONSE:
|
case SerialPacketType::JOIN_RESPONSE:
|
||||||
HandleJoinResponse(static_cast<ClientPacket*>(argPacket));
|
HandleJoinResponse(static_cast<ClientPacket*>(argPacket));
|
||||||
break;
|
break;
|
||||||
|
case SerialPacketType::LOGIN_RESPONSE:
|
||||||
|
HandleLoginResponse(static_cast<ClientPacket*>(argPacket));
|
||||||
|
break;
|
||||||
|
|
||||||
|
//rejections
|
||||||
case SerialPacketType::JOIN_REJECTION:
|
case SerialPacketType::JOIN_REJECTION:
|
||||||
HandleJoinRejection(static_cast<TextPacket*>(argPacket));
|
HandleJoinRejection(static_cast<TextPacket*>(argPacket));
|
||||||
break;
|
break;
|
||||||
|
case SerialPacketType::LOGIN_REJECTION:
|
||||||
|
HandleLoginRejection(static_cast<TextPacket*>(argPacket));
|
||||||
|
break;
|
||||||
|
|
||||||
//handle errors
|
//handle errors
|
||||||
default:
|
default:
|
||||||
throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in LobbyMenu: " + to_string_custom(static_cast<int>(argPacket->type)) ));
|
throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in LobbyMenu: " + to_string_custom(static_cast<int>(argPacket->type)) ));
|
||||||
@@ -222,9 +232,19 @@ void LobbyMenu::HandleBroadcastResponse(ServerPacket* const argPacket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LobbyMenu::HandleJoinResponse(ClientPacket* const argPacket) {
|
void LobbyMenu::HandleJoinResponse(ClientPacket* const argPacket) {
|
||||||
|
//save the server's data
|
||||||
clientIndex = argPacket->clientIndex;
|
clientIndex = argPacket->clientIndex;
|
||||||
accountIndex = argPacket->accountIndex;
|
|
||||||
network.Bind(argPacket->srcAddress, Channels::SERVER);
|
network.Bind(argPacket->srcAddress, Channels::SERVER);
|
||||||
|
|
||||||
|
//request login data
|
||||||
|
SendLoginRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LobbyMenu::HandleLoginResponse(ClientPacket* const argPacket) {
|
||||||
|
if (argPacket->clientIndex != clientIndex) {
|
||||||
|
throw(std::runtime_error("Client index invalid during login"));
|
||||||
|
}
|
||||||
|
accountIndex = argPacket->accountIndex;
|
||||||
SetNextScene(SceneList::INWORLD);
|
SetNextScene(SceneList::INWORLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,6 +252,10 @@ void LobbyMenu::HandleJoinRejection(TextPacket* const argPacket) {
|
|||||||
//TODO: Better output for join rejection
|
//TODO: Better output for join rejection
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LobbyMenu::HandleLoginRejection(TextPacket* const argPacket) {
|
||||||
|
//TODO: Better output for login rejection
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//server control
|
//server control
|
||||||
//-------------------------
|
//-------------------------
|
||||||
@@ -251,9 +275,18 @@ void LobbyMenu::SendJoinRequest() {
|
|||||||
//pack the packet
|
//pack the packet
|
||||||
ClientPacket packet;
|
ClientPacket packet;
|
||||||
packet.type = SerialPacketType::JOIN_REQUEST;
|
packet.type = SerialPacketType::JOIN_REQUEST;
|
||||||
strncpy(packet.username, config["client.username"].c_str(), PACKET_STRING_SIZE);
|
|
||||||
|
|
||||||
//join the selected server
|
//join the selected server
|
||||||
network.SendTo(selection->address, &packet);
|
network.SendTo(selection->address, &packet);
|
||||||
selection = nullptr;
|
selection = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LobbyMenu::SendLoginRequest() {
|
||||||
|
//NOTE: high cohesion
|
||||||
|
ClientPacket packet;
|
||||||
|
packet.type = SerialPacketType::LOGIN_REQUEST;
|
||||||
|
packet.clientIndex = clientIndex;
|
||||||
|
strncpy(packet.username, config["client.username"].c_str(), PACKET_STRING_SIZE);
|
||||||
|
|
||||||
|
network.SendTo(Channels::SERVER, &packet);
|
||||||
|
}
|
||||||
|
|||||||
@@ -63,11 +63,14 @@ protected:
|
|||||||
void HandlePacket(SerialPacket* const);
|
void HandlePacket(SerialPacket* const);
|
||||||
void HandleBroadcastResponse(ServerPacket* const);
|
void HandleBroadcastResponse(ServerPacket* const);
|
||||||
void HandleJoinResponse(ClientPacket* const);
|
void HandleJoinResponse(ClientPacket* const);
|
||||||
|
void HandleLoginResponse(ClientPacket* const);
|
||||||
void HandleJoinRejection(TextPacket* const);
|
void HandleJoinRejection(TextPacket* const);
|
||||||
|
void HandleLoginRejection(TextPacket* const);
|
||||||
|
|
||||||
//server control
|
//server control
|
||||||
void SendBroadcastRequest();
|
void SendBroadcastRequest();
|
||||||
void SendJoinRequest();
|
void SendJoinRequest();
|
||||||
|
void SendLoginRequest();
|
||||||
|
|
||||||
//shared parameters
|
//shared parameters
|
||||||
ConfigUtility& config = ConfigUtility::GetSingleton();
|
ConfigUtility& config = ConfigUtility::GetSingleton();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#config
|
#config
|
||||||
INCLUDES+=. .. ../renderable ../../common/gameplay ../../common/graphics ../../common/map ../../common/network ../../common/network/packet_types ../../common/ui ../../common/utilities
|
INCLUDES+=. .. ../entities ../../common/gameplay ../../common/graphics ../../common/map ../../common/network ../../common/network/packet_types ../../common/ui ../../common/utilities
|
||||||
LIBS+=
|
LIBS+=
|
||||||
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/* 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 "map_system_api.hpp"
|
||||||
|
|
||||||
|
//all map API headers
|
||||||
|
#include "region_api.hpp"
|
||||||
|
#include "region_pager_api.hpp"
|
||||||
|
#include "tile_sheet_api.hpp"
|
||||||
|
|
||||||
|
//macros
|
||||||
|
#include "region.hpp"
|
||||||
|
|
||||||
|
//useful "globals"
|
||||||
|
static int getRegionWidth(lua_State* L) {
|
||||||
|
lua_pushinteger(L, REGION_WIDTH);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int getRegionHeight(lua_State* L) {
|
||||||
|
lua_pushinteger(L, REGION_HEIGHT);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int getRegionDepth(lua_State* L) {
|
||||||
|
lua_pushinteger(L, REGION_DEPTH);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//This mimics linit.c to create a nested collection of all map modules.
|
||||||
|
static const luaL_Reg funcs[] = {
|
||||||
|
//synonyms
|
||||||
|
{"GetRegionWidth", getRegionWidth},
|
||||||
|
{"GetRegionHeight", getRegionHeight},
|
||||||
|
{"GetRegionDepth", getRegionDepth},
|
||||||
|
{nullptr, nullptr}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const luaL_Reg libs[] = {
|
||||||
|
{"Region", openRegionAPI},
|
||||||
|
{"RegionPager", openRegionPagerAPI},
|
||||||
|
// {"TileSheet", openTileSheetAPI},
|
||||||
|
{nullptr, nullptr}
|
||||||
|
};
|
||||||
|
|
||||||
|
int openMapSystemAPI(lua_State* L) {
|
||||||
|
//create the table
|
||||||
|
luaL_newlibtable(L, libs);
|
||||||
|
|
||||||
|
//push the "global" functions
|
||||||
|
luaL_setfuncs(L, funcs, 0);
|
||||||
|
|
||||||
|
//push the substable
|
||||||
|
for (const luaL_Reg* lib = libs; lib->func; lib++) {
|
||||||
|
lua_pushcfunction(L, lib->func);
|
||||||
|
lua_setfield(L, -2, lib->name);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
@@ -19,12 +19,16 @@
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
#ifndef SERIALSTATISTICS_HPP_
|
#ifndef MAPSYSTEMAPI_HPP_
|
||||||
#define SERIALSTATISTICS_HPP_
|
#define MAPSYSTEMAPI_APP_
|
||||||
|
|
||||||
#include "statistics.hpp"
|
#if defined(__MINGW32__)
|
||||||
|
#include "lua/lua.hpp"
|
||||||
|
#else
|
||||||
|
#include "lua.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
void serializeStatistics(void** buffer, Statistics* stats);
|
#define TORTUGA_MAP_SYSTEM_API "map_system"
|
||||||
void deserializeStatistics(void** buffer, Statistics* stats);
|
LUAMOD_API int openMapSystemAPI(lua_State* L);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -22,9 +22,13 @@
|
|||||||
#ifndef REGIONAPI_HPP_
|
#ifndef REGIONAPI_HPP_
|
||||||
#define REGIONAPI_HPP_
|
#define REGIONAPI_HPP_
|
||||||
|
|
||||||
#include "lua/lua.hpp"
|
#if defined(__MINGW32__)
|
||||||
|
#include "lua/lua.hpp"
|
||||||
|
#else
|
||||||
|
#include "lua.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define TORTUGA_REGION_NAME "Region"
|
#define TORTUGA_REGION_NAME "region"
|
||||||
LUAMOD_API int openRegionAPI(lua_State* L);
|
LUAMOD_API int openRegionAPI(lua_State* L);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -22,9 +22,13 @@
|
|||||||
#ifndef REGIONPAGERAPI_HPP_
|
#ifndef REGIONPAGERAPI_HPP_
|
||||||
#define REGIONPAGERAPI_HPP_
|
#define REGIONPAGERAPI_HPP_
|
||||||
|
|
||||||
#include "lua/lua.hpp"
|
#if defined(__MINGW32__)
|
||||||
|
#include "lua/lua.hpp"
|
||||||
|
#else
|
||||||
|
#include "lua.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define TORTUGA_REGION_PAGER_NAME "RegionPager"
|
#define TORTUGA_REGION_PAGER_NAME "region_pager"
|
||||||
LUAMOD_API int openRegionPagerAPI(lua_State* L);
|
LUAMOD_API int openRegionPagerAPI(lua_State* L);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -24,6 +24,18 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
RegionPagerBase::RegionPagerBase() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionPagerBase::RegionPagerBase(RegionPagerBase&& rhs) {
|
||||||
|
regionList = std::move(rhs.regionList);
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionPagerBase::~RegionPagerBase() {
|
||||||
|
UnloadAll();
|
||||||
|
}
|
||||||
|
|
||||||
Region::type_t RegionPagerBase::SetTile(int x, int y, int z, Region::type_t v) {
|
Region::type_t RegionPagerBase::SetTile(int x, int y, int z, Region::type_t v) {
|
||||||
Region* ptr = GetRegion(x, y);
|
Region* ptr = GetRegion(x, y);
|
||||||
return ptr->SetTile(x - ptr->GetX(), y - ptr->GetY(), z, v);
|
return ptr->SetTile(x - ptr->GetX(), y - ptr->GetY(), z, v);
|
||||||
|
|||||||
@@ -28,8 +28,9 @@
|
|||||||
|
|
||||||
class RegionPagerBase {
|
class RegionPagerBase {
|
||||||
public:
|
public:
|
||||||
RegionPagerBase() = default;
|
RegionPagerBase();
|
||||||
virtual ~RegionPagerBase() { UnloadAll(); };
|
RegionPagerBase(RegionPagerBase&&);
|
||||||
|
virtual ~RegionPagerBase();
|
||||||
|
|
||||||
//tile manipulation
|
//tile manipulation
|
||||||
virtual Region::type_t SetTile(int x, int y, int z, Region::type_t v);
|
virtual Region::type_t SetTile(int x, int y, int z, Region::type_t v);
|
||||||
|
|||||||
@@ -23,6 +23,29 @@
|
|||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
RegionPagerLua::RegionPagerLua() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionPagerLua::RegionPagerLua(RegionPagerLua&& rhs) {
|
||||||
|
lua = rhs.lua;
|
||||||
|
loadRef = rhs.loadRef;
|
||||||
|
saveRef = rhs.saveRef;
|
||||||
|
createRef = rhs.createRef;
|
||||||
|
unloadRef = rhs.unloadRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionPagerLua::~RegionPagerLua() {
|
||||||
|
//unload all regions
|
||||||
|
UnloadAll();
|
||||||
|
//clear any stored functions
|
||||||
|
luaL_unref(lua, LUA_REGISTRYINDEX, loadRef);
|
||||||
|
luaL_unref(lua, LUA_REGISTRYINDEX, saveRef);
|
||||||
|
luaL_unref(lua, LUA_REGISTRYINDEX, createRef);
|
||||||
|
luaL_unref(lua, LUA_REGISTRYINDEX, unloadRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
//return the loaded region, or nullptr on failure
|
||||||
Region* RegionPagerLua::LoadRegion(int x, int y) {
|
Region* RegionPagerLua::LoadRegion(int x, int y) {
|
||||||
//get the pager's function from the registry
|
//get the pager's function from the registry
|
||||||
lua_rawgeti(lua, LUA_REGISTRYINDEX, loadRef);
|
lua_rawgeti(lua, LUA_REGISTRYINDEX, loadRef);
|
||||||
@@ -54,6 +77,7 @@ Region* RegionPagerLua::LoadRegion(int x, int y) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//return the saved region, or nullptr on failure
|
||||||
Region* RegionPagerLua::SaveRegion(int x, int y) {
|
Region* RegionPagerLua::SaveRegion(int x, int y) {
|
||||||
//get the pager's function from the registry
|
//get the pager's function from the registry
|
||||||
lua_rawgeti(lua, LUA_REGISTRYINDEX, saveRef);
|
lua_rawgeti(lua, LUA_REGISTRYINDEX, saveRef);
|
||||||
@@ -88,6 +112,7 @@ Region* RegionPagerLua::SaveRegion(int x, int y) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//return the created region, or nullptr on failure
|
||||||
Region* RegionPagerLua::CreateRegion(int x, int y) {
|
Region* RegionPagerLua::CreateRegion(int x, int y) {
|
||||||
if (FindRegion(x, y)) {
|
if (FindRegion(x, y)) {
|
||||||
throw(std::logic_error("Cannot overwrite an existing region"));
|
throw(std::logic_error("Cannot overwrite an existing region"));
|
||||||
@@ -116,6 +141,7 @@ Region* RegionPagerLua::CreateRegion(int x, int y) {
|
|||||||
return ®ionList.front();
|
return ®ionList.front();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//no return
|
||||||
void RegionPagerLua::UnloadRegion(int x, int y) {
|
void RegionPagerLua::UnloadRegion(int x, int y) {
|
||||||
//get the pager's function from the registry
|
//get the pager's function from the registry
|
||||||
lua_rawgeti(lua, LUA_REGISTRYINDEX, unloadRef);
|
lua_rawgeti(lua, LUA_REGISTRYINDEX, unloadRef);
|
||||||
@@ -150,6 +176,7 @@ void RegionPagerLua::UnloadRegion(int x, int y) {
|
|||||||
lua_pop(lua, 1);
|
lua_pop(lua, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//no return
|
||||||
void RegionPagerLua::UnloadAll() {
|
void RegionPagerLua::UnloadAll() {
|
||||||
//get the pager's function from the registry
|
//get the pager's function from the registry
|
||||||
lua_rawgeti(lua, LUA_REGISTRYINDEX, unloadRef);
|
lua_rawgeti(lua, LUA_REGISTRYINDEX, unloadRef);
|
||||||
|
|||||||
@@ -24,14 +24,19 @@
|
|||||||
|
|
||||||
#include "region_pager_base.hpp"
|
#include "region_pager_base.hpp"
|
||||||
|
|
||||||
#include "lua/lua.hpp"
|
#if defined(__MINGW32__)
|
||||||
|
#include "lua/lua.hpp"
|
||||||
|
#else
|
||||||
|
#include "lua.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class RegionPagerLua : public RegionPagerBase {
|
class RegionPagerLua : public RegionPagerBase {
|
||||||
public:
|
public:
|
||||||
RegionPagerLua() = default;
|
RegionPagerLua();
|
||||||
~RegionPagerLua() = default;
|
RegionPagerLua(RegionPagerLua&&);
|
||||||
|
~RegionPagerLua();
|
||||||
|
|
||||||
//region manipulation
|
//region manipulation
|
||||||
Region* LoadRegion(int x, int y) override;
|
Region* LoadRegion(int x, int y) override;
|
||||||
|
|||||||
@@ -22,9 +22,13 @@
|
|||||||
#ifndef TILESHEETAPI_HPP_
|
#ifndef TILESHEETAPI_HPP_
|
||||||
#define TILESHEETAPI_HPP_
|
#define TILESHEETAPI_HPP_
|
||||||
|
|
||||||
#include "lua/lua.hpp"
|
#if defined(__MINGW32__)
|
||||||
|
#include "lua/lua.hpp"
|
||||||
|
#else
|
||||||
|
#include "lua.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define TORTUGA_TILE_SHEET_NAME "TileSheet"
|
#define TORTUGA_TILE_SHEET_NAME "tile_sheet"
|
||||||
LUAMOD_API int openTileSheetAPI(lua_State* L);
|
LUAMOD_API int openTileSheetAPI(lua_State* L);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -23,8 +23,6 @@
|
|||||||
|
|
||||||
#include "serial_utility.hpp"
|
#include "serial_utility.hpp"
|
||||||
|
|
||||||
#include "serial_statistics.hpp"
|
|
||||||
|
|
||||||
void serializeCharacter(void* buffer, CharacterPacket* packet) {
|
void serializeCharacter(void* buffer, CharacterPacket* packet) {
|
||||||
serialCopy(&buffer, &packet->type, sizeof(SerialPacketType));
|
serialCopy(&buffer, &packet->type, sizeof(SerialPacketType));
|
||||||
|
|
||||||
@@ -43,9 +41,6 @@ void serializeCharacter(void* buffer, CharacterPacket* packet) {
|
|||||||
serialCopy(&buffer, &packet->motion.x, sizeof(double));
|
serialCopy(&buffer, &packet->motion.x, sizeof(double));
|
||||||
serialCopy(&buffer, &packet->motion.y, sizeof(double));
|
serialCopy(&buffer, &packet->motion.y, sizeof(double));
|
||||||
|
|
||||||
//stats structure
|
|
||||||
serializeStatistics(&buffer, &packet->stats);
|
|
||||||
|
|
||||||
//gameplay components: equipment, items, buffs, debuffs...
|
//gameplay components: equipment, items, buffs, debuffs...
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,8 +62,5 @@ void deserializeCharacter(void* buffer, CharacterPacket* packet) {
|
|||||||
deserialCopy(&buffer, &packet->motion.x, sizeof(double));
|
deserialCopy(&buffer, &packet->motion.x, sizeof(double));
|
||||||
deserialCopy(&buffer, &packet->motion.y, sizeof(double));
|
deserialCopy(&buffer, &packet->motion.y, sizeof(double));
|
||||||
|
|
||||||
//stats structure
|
|
||||||
deserializeStatistics(&buffer, &packet->stats);
|
|
||||||
|
|
||||||
//gameplay components: equipment, items, buffs, debuffs...
|
//gameplay components: equipment, items, buffs, debuffs...
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
#include "serial_packet_base.hpp"
|
#include "serial_packet_base.hpp"
|
||||||
|
|
||||||
#include "vector2.hpp"
|
#include "vector2.hpp"
|
||||||
#include "statistics.hpp"
|
|
||||||
|
|
||||||
struct CharacterPacket : SerialPacketBase {
|
struct CharacterPacket : SerialPacketBase {
|
||||||
//identify the character
|
//identify the character
|
||||||
@@ -35,15 +34,13 @@ struct CharacterPacket : SerialPacketBase {
|
|||||||
|
|
||||||
//the owner
|
//the owner
|
||||||
int accountIndex;
|
int accountIndex;
|
||||||
|
//TODO: Authentication token?
|
||||||
|
|
||||||
//location
|
//location
|
||||||
int roomIndex;
|
int roomIndex;
|
||||||
Vector2 origin;
|
Vector2 origin;
|
||||||
Vector2 motion;
|
Vector2 motion;
|
||||||
|
|
||||||
//gameplay
|
|
||||||
Statistics stats;
|
|
||||||
|
|
||||||
//gameplay components: equipment, items, buffs, debuffs...
|
//gameplay components: equipment, items, buffs, debuffs...
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,64 +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 "serial_statistics.hpp"
|
|
||||||
|
|
||||||
#include "serial_utility.hpp"
|
|
||||||
|
|
||||||
void serializeStatistics(void** buffer, Statistics* stats) {
|
|
||||||
//integers
|
|
||||||
serialCopy(buffer, &stats->level, sizeof(int));
|
|
||||||
serialCopy(buffer, &stats->exp, sizeof(int));
|
|
||||||
serialCopy(buffer, &stats->maxHP, sizeof(int));
|
|
||||||
serialCopy(buffer, &stats->health, sizeof(int));
|
|
||||||
serialCopy(buffer, &stats->maxMP, sizeof(int));
|
|
||||||
serialCopy(buffer, &stats->mana, sizeof(int));
|
|
||||||
serialCopy(buffer, &stats->attack, sizeof(int));
|
|
||||||
serialCopy(buffer, &stats->defence, sizeof(int));
|
|
||||||
serialCopy(buffer, &stats->intelligence, sizeof(int));
|
|
||||||
serialCopy(buffer, &stats->resistance, sizeof(int));
|
|
||||||
serialCopy(buffer, &stats->speed, sizeof(int));
|
|
||||||
|
|
||||||
//floats
|
|
||||||
serialCopy(buffer, &stats->accuracy, sizeof(float));
|
|
||||||
serialCopy(buffer, &stats->evasion, sizeof(float));
|
|
||||||
serialCopy(buffer, &stats->luck, sizeof(float));
|
|
||||||
}
|
|
||||||
|
|
||||||
void deserializeStatistics(void** buffer, Statistics* stats) {
|
|
||||||
//integers
|
|
||||||
deserialCopy(buffer, &stats->level, sizeof(int));
|
|
||||||
deserialCopy(buffer, &stats->exp, sizeof(int));
|
|
||||||
deserialCopy(buffer, &stats->maxHP, sizeof(int));
|
|
||||||
deserialCopy(buffer, &stats->health, sizeof(int));
|
|
||||||
deserialCopy(buffer, &stats->maxMP, sizeof(int));
|
|
||||||
deserialCopy(buffer, &stats->mana, sizeof(int));
|
|
||||||
deserialCopy(buffer, &stats->attack, sizeof(int));
|
|
||||||
deserialCopy(buffer, &stats->defence, sizeof(int));
|
|
||||||
deserialCopy(buffer, &stats->intelligence, sizeof(int));
|
|
||||||
deserialCopy(buffer, &stats->resistance, sizeof(int));
|
|
||||||
deserialCopy(buffer, &stats->speed, sizeof(int));
|
|
||||||
|
|
||||||
//floats
|
|
||||||
deserialCopy(buffer, &stats->accuracy, sizeof(float));
|
|
||||||
deserialCopy(buffer, &stats->evasion, sizeof(float));
|
|
||||||
deserialCopy(buffer, &stats->luck, sizeof(float));
|
|
||||||
}
|
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
typedef SerialPacketBase SerialPacket;
|
typedef SerialPacketBase SerialPacket;
|
||||||
|
|
||||||
//DOCS: NETWORK_VERSION is used to discern compatible servers and clients
|
//DOCS: NETWORK_VERSION is used to discern compatible servers and clients
|
||||||
constexpr int NETWORK_VERSION = 20140909;
|
constexpr int NETWORK_VERSION = -1;
|
||||||
|
|
||||||
union MaxPacket {
|
union MaxPacket {
|
||||||
CharacterPacket a;
|
CharacterPacket a;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
* valid data, but it will still be carried in that packet's format.
|
* valid data, but it will still be carried in that packet's format.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//TODO: This needs to be smoothed out
|
||||||
enum class SerialPacketType {
|
enum class SerialPacketType {
|
||||||
//default: there is something wrong
|
//default: there is something wrong
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
@@ -46,21 +47,28 @@ enum class SerialPacketType {
|
|||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//ClientPacket
|
//ClientPacket
|
||||||
// client index, account index, character index
|
// client index, account index, username
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
//Connecting to a server as a client
|
//Connecting to a server as a client
|
||||||
JOIN_REQUEST,
|
JOIN_REQUEST,
|
||||||
JOIN_RESPONSE,
|
JOIN_RESPONSE,
|
||||||
|
|
||||||
//client requests all information from the server
|
|
||||||
SYNCHRONIZE,
|
|
||||||
|
|
||||||
//disconnect from the server
|
//disconnect from the server
|
||||||
DISCONNECT,
|
DISCONNECT_REQUEST,
|
||||||
|
DISCONNECT_RESPONSE,
|
||||||
|
DISCONNECT_FORCED,
|
||||||
|
|
||||||
|
//load the account
|
||||||
|
LOGIN_REQUEST,
|
||||||
|
LOGIN_RESPONSE,
|
||||||
|
|
||||||
|
//unload the account
|
||||||
|
LOGOUT_REQUEST,
|
||||||
|
LOGOUT_RESPONSE,
|
||||||
|
|
||||||
//shut down the server
|
//shut down the server
|
||||||
SHUTDOWN,
|
SHUTDOWN_REQUEST,
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//RegionPacket
|
//RegionPacket
|
||||||
@@ -68,24 +76,35 @@ enum class SerialPacketType {
|
|||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
//map data
|
//map data
|
||||||
REGION_REQUEST,
|
REGION_REQUEST, //NOTE: technically a query
|
||||||
REGION_CONTENT,
|
REGION_CONTENT,
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//CharacterPacket
|
//CharacterPacket
|
||||||
// handle, avatar, character index, account index,
|
// character index,
|
||||||
// room index, origin, motion
|
// handle, avatar,
|
||||||
|
// account index (owner),
|
||||||
|
// room index, origin, motion,
|
||||||
// statistics
|
// statistics
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
//controlling characters
|
//character management
|
||||||
CHARACTER_NEW,
|
CHARACTER_CREATE,
|
||||||
CHARACTER_DELETE,
|
CHARACTER_DELETE,
|
||||||
CHARACTER_UPDATE,
|
CHARACTER_LOAD,
|
||||||
|
CHARACTER_UNLOAD,
|
||||||
|
|
||||||
//authentication, character index => character stats
|
//find out info from the server
|
||||||
CHARACTER_STATS_REQUEST,
|
QUERY_CHARACTER_EXISTS,
|
||||||
CHARACTER_STATS_RESPONSE,
|
QUERY_CHARACTER_STATS,
|
||||||
|
QUERY_CHARACTER_LOCATION,
|
||||||
|
|
||||||
|
//set the info in the server
|
||||||
|
CHARACTER_SET_ROOM,
|
||||||
|
CHARACTER_SET_ORIGIN,
|
||||||
|
CHARACTER_SET_MOTION,
|
||||||
|
|
||||||
|
//TODO: enemy management
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//TextPacket
|
//TextPacket
|
||||||
@@ -96,9 +115,10 @@ enum class SerialPacketType {
|
|||||||
TEXT_BROADCAST,
|
TEXT_BROADCAST,
|
||||||
|
|
||||||
//rejection/error messages
|
//rejection/error messages
|
||||||
SHUTDOWN_REJECTION,
|
|
||||||
JOIN_REJECTION,
|
JOIN_REJECTION,
|
||||||
|
LOGIN_REJECTION,
|
||||||
CHARACTER_REJECTION,
|
CHARACTER_REJECTION,
|
||||||
|
SHUTDOWN_REJECTION,
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//not used
|
//not used
|
||||||
|
|||||||
@@ -54,26 +54,37 @@ void serializePacket(void* buffer, SerialPacketBase* packet) {
|
|||||||
break;
|
break;
|
||||||
case SerialPacketType::JOIN_REQUEST:
|
case SerialPacketType::JOIN_REQUEST:
|
||||||
case SerialPacketType::JOIN_RESPONSE:
|
case SerialPacketType::JOIN_RESPONSE:
|
||||||
case SerialPacketType::SYNCHRONIZE:
|
case SerialPacketType::DISCONNECT_REQUEST:
|
||||||
case SerialPacketType::DISCONNECT:
|
case SerialPacketType::DISCONNECT_RESPONSE:
|
||||||
case SerialPacketType::SHUTDOWN:
|
case SerialPacketType::DISCONNECT_FORCED:
|
||||||
|
case SerialPacketType::LOGIN_REQUEST:
|
||||||
|
case SerialPacketType::LOGIN_RESPONSE:
|
||||||
|
case SerialPacketType::LOGOUT_REQUEST:
|
||||||
|
case SerialPacketType::LOGOUT_RESPONSE:
|
||||||
|
case SerialPacketType::SHUTDOWN_REQUEST:
|
||||||
serializeClient(buffer, static_cast<ClientPacket*>(packet));
|
serializeClient(buffer, static_cast<ClientPacket*>(packet));
|
||||||
break;
|
break;
|
||||||
case SerialPacketType::REGION_REQUEST:
|
case SerialPacketType::REGION_REQUEST:
|
||||||
case SerialPacketType::REGION_CONTENT:
|
case SerialPacketType::REGION_CONTENT:
|
||||||
serializeRegion(buffer, static_cast<RegionPacket*>(packet));
|
serializeRegion(buffer, static_cast<RegionPacket*>(packet));
|
||||||
break;
|
break;
|
||||||
case SerialPacketType::CHARACTER_NEW:
|
case SerialPacketType::CHARACTER_CREATE:
|
||||||
case SerialPacketType::CHARACTER_DELETE:
|
case SerialPacketType::CHARACTER_DELETE:
|
||||||
case SerialPacketType::CHARACTER_UPDATE:
|
case SerialPacketType::CHARACTER_LOAD:
|
||||||
case SerialPacketType::CHARACTER_STATS_REQUEST:
|
case SerialPacketType::CHARACTER_UNLOAD:
|
||||||
case SerialPacketType::CHARACTER_STATS_RESPONSE:
|
case SerialPacketType::QUERY_CHARACTER_EXISTS:
|
||||||
|
case SerialPacketType::QUERY_CHARACTER_STATS:
|
||||||
|
case SerialPacketType::QUERY_CHARACTER_LOCATION:
|
||||||
|
case SerialPacketType::CHARACTER_SET_ROOM:
|
||||||
|
case SerialPacketType::CHARACTER_SET_ORIGIN:
|
||||||
|
case SerialPacketType::CHARACTER_SET_MOTION:
|
||||||
serializeCharacter(buffer, static_cast<CharacterPacket*>(packet));
|
serializeCharacter(buffer, static_cast<CharacterPacket*>(packet));
|
||||||
break;
|
break;
|
||||||
case SerialPacketType::TEXT_BROADCAST:
|
case SerialPacketType::TEXT_BROADCAST:
|
||||||
case SerialPacketType::JOIN_REJECTION:
|
case SerialPacketType::JOIN_REJECTION:
|
||||||
case SerialPacketType::SHUTDOWN_REJECTION:
|
case SerialPacketType::LOGIN_REJECTION:
|
||||||
case SerialPacketType::CHARACTER_REJECTION:
|
case SerialPacketType::CHARACTER_REJECTION:
|
||||||
|
case SerialPacketType::SHUTDOWN_REJECTION:
|
||||||
serializeText(buffer, static_cast<TextPacket*>(packet));
|
serializeText(buffer, static_cast<TextPacket*>(packet));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -84,7 +95,7 @@ void deserializePacket(void* buffer, SerialPacketBase* packet) {
|
|||||||
SerialPacketType type;
|
SerialPacketType type;
|
||||||
memcpy(&type, buffer, sizeof(SerialPacketType));
|
memcpy(&type, buffer, sizeof(SerialPacketType));
|
||||||
|
|
||||||
switch(type) {
|
switch(packet->type) {
|
||||||
case SerialPacketType::PING:
|
case SerialPacketType::PING:
|
||||||
case SerialPacketType::PONG:
|
case SerialPacketType::PONG:
|
||||||
case SerialPacketType::BROADCAST_REQUEST:
|
case SerialPacketType::BROADCAST_REQUEST:
|
||||||
@@ -93,26 +104,37 @@ void deserializePacket(void* buffer, SerialPacketBase* packet) {
|
|||||||
break;
|
break;
|
||||||
case SerialPacketType::JOIN_REQUEST:
|
case SerialPacketType::JOIN_REQUEST:
|
||||||
case SerialPacketType::JOIN_RESPONSE:
|
case SerialPacketType::JOIN_RESPONSE:
|
||||||
case SerialPacketType::SYNCHRONIZE:
|
case SerialPacketType::DISCONNECT_REQUEST:
|
||||||
case SerialPacketType::DISCONNECT:
|
case SerialPacketType::DISCONNECT_RESPONSE:
|
||||||
case SerialPacketType::SHUTDOWN:
|
case SerialPacketType::DISCONNECT_FORCED:
|
||||||
|
case SerialPacketType::LOGIN_REQUEST:
|
||||||
|
case SerialPacketType::LOGIN_RESPONSE:
|
||||||
|
case SerialPacketType::LOGOUT_REQUEST:
|
||||||
|
case SerialPacketType::LOGOUT_RESPONSE:
|
||||||
|
case SerialPacketType::SHUTDOWN_REQUEST:
|
||||||
deserializeClient(buffer, static_cast<ClientPacket*>(packet));
|
deserializeClient(buffer, static_cast<ClientPacket*>(packet));
|
||||||
break;
|
break;
|
||||||
case SerialPacketType::REGION_REQUEST:
|
case SerialPacketType::REGION_REQUEST:
|
||||||
case SerialPacketType::REGION_CONTENT:
|
case SerialPacketType::REGION_CONTENT:
|
||||||
deserializeRegion(buffer, static_cast<RegionPacket*>(packet));
|
deserializeRegion(buffer, static_cast<RegionPacket*>(packet));
|
||||||
break;
|
break;
|
||||||
case SerialPacketType::CHARACTER_NEW:
|
case SerialPacketType::CHARACTER_CREATE:
|
||||||
case SerialPacketType::CHARACTER_DELETE:
|
case SerialPacketType::CHARACTER_DELETE:
|
||||||
case SerialPacketType::CHARACTER_UPDATE:
|
case SerialPacketType::CHARACTER_LOAD:
|
||||||
case SerialPacketType::CHARACTER_STATS_REQUEST:
|
case SerialPacketType::CHARACTER_UNLOAD:
|
||||||
case SerialPacketType::CHARACTER_STATS_RESPONSE:
|
case SerialPacketType::QUERY_CHARACTER_EXISTS:
|
||||||
|
case SerialPacketType::QUERY_CHARACTER_STATS:
|
||||||
|
case SerialPacketType::QUERY_CHARACTER_LOCATION:
|
||||||
|
case SerialPacketType::CHARACTER_SET_ROOM:
|
||||||
|
case SerialPacketType::CHARACTER_SET_ORIGIN:
|
||||||
|
case SerialPacketType::CHARACTER_SET_MOTION:
|
||||||
deserializeCharacter(buffer, static_cast<CharacterPacket*>(packet));
|
deserializeCharacter(buffer, static_cast<CharacterPacket*>(packet));
|
||||||
break;
|
break;
|
||||||
case SerialPacketType::TEXT_BROADCAST:
|
case SerialPacketType::TEXT_BROADCAST:
|
||||||
case SerialPacketType::JOIN_REJECTION:
|
case SerialPacketType::JOIN_REJECTION:
|
||||||
case SerialPacketType::SHUTDOWN_REJECTION:
|
case SerialPacketType::LOGIN_REJECTION:
|
||||||
case SerialPacketType::CHARACTER_REJECTION:
|
case SerialPacketType::CHARACTER_REJECTION:
|
||||||
|
case SerialPacketType::SHUTDOWN_REJECTION:
|
||||||
deserializeText(buffer, static_cast<TextPacket*>(packet));
|
deserializeText(buffer, static_cast<TextPacket*>(packet));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,10 +29,8 @@ std::string truncatePath(std::string pathname) {
|
|||||||
pathname.rbegin(),
|
pathname.rbegin(),
|
||||||
pathname.rend(),
|
pathname.rend(),
|
||||||
[](char ch) -> bool {
|
[](char ch) -> bool {
|
||||||
//windows only
|
//windows & unix tested
|
||||||
return ch == '/' || ch == '\\';
|
return ch == '/' || ch == '\\';
|
||||||
// //unix only
|
|
||||||
// return ch == '/';
|
|
||||||
}).base(),
|
}).base(),
|
||||||
pathname.end());
|
pathname.end());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ release: clean all package
|
|||||||
#For use on my machine ONLY
|
#For use on my machine ONLY
|
||||||
package:
|
package:
|
||||||
rar a -r -ep Tortuga.rar $(OUTDIR)/*.exe $(OUTDIR)/*.dll
|
rar a -r -ep Tortuga.rar $(OUTDIR)/*.exe $(OUTDIR)/*.dll
|
||||||
rar a -r Tortuga.rar rsc/* copyright.txt
|
rar a -r Tortuga.rar rsc/* copyright.txt README.txt
|
||||||
|
|
||||||
$(OUTDIR):
|
$(OUTDIR):
|
||||||
mkdir $(OUTDIR)
|
mkdir $(OUTDIR)
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
local mapSystem = require "map_system"
|
||||||
|
|
||||||
local mapMaker = {}
|
local mapMaker = {}
|
||||||
|
|
||||||
--utility functions
|
--utility functions
|
||||||
@@ -19,16 +21,16 @@ mapMaker.dirt = 18 + 3 * 4
|
|||||||
|
|
||||||
--custom generation systems here
|
--custom generation systems here
|
||||||
function mapMaker.debugIsland(region)
|
function mapMaker.debugIsland(region)
|
||||||
for i = 1, Region.GetWidth(region) do
|
for i = 1, mapSystem.Region.GetWidth(region) do
|
||||||
for j = 1, Region.GetHeight(region) do
|
for j = 1, mapSystem.Region.GetHeight(region) do
|
||||||
local dist = mapMaker.dist(0, 0, i + Region.GetX(region) -1, j + Region.GetY(region) -1)
|
local dist = mapMaker.dist(0, 0, i + mapSystem.Region.GetX(region) -1, j + mapSystem.Region.GetY(region) -1)
|
||||||
if dist < 10 then
|
if dist < 10 then
|
||||||
Region.SetTile(region, i, j, 1, mapMaker.plains)
|
mapSystem.Region.SetTile(region, i, j, 1, mapMaker.plains)
|
||||||
elseif dist < 12 then
|
elseif dist < 12 then
|
||||||
Region.SetTile(region, i, j, 1, mapMaker.sand)
|
mapSystem.Region.SetTile(region, i, j, 1, mapMaker.sand)
|
||||||
else
|
else
|
||||||
Region.SetTile(region, i, j, 1, mapMaker.water)
|
mapSystem.Region.SetTile(region, i, j, 1, mapMaker.water)
|
||||||
Region.SetSolid(region, i, j, true)
|
mapSystem.Region.SetSolid(region, i, j, true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
local mapSaver = {}
|
||||||
|
--TODO: create a flexible saving & loading system
|
||||||
|
return mapSaver
|
||||||
@@ -2,11 +2,29 @@ print("Lua script check")
|
|||||||
|
|
||||||
mapMaker = require "map_maker"
|
mapMaker = require "map_maker"
|
||||||
mapSaver = require "map_saver"
|
mapSaver = require "map_saver"
|
||||||
|
roomSystem = require "room_system"
|
||||||
|
|
||||||
--BUG: #35 The server fails without at least one room
|
local function dumpTable(t)
|
||||||
--TODO: Create rooms with names?
|
print(t)
|
||||||
newRoom = RoomManager.CreateRoom("overworld", "overworld.bmp")
|
for k, v in pairs(t) do
|
||||||
pager = Room.GetPager(newRoom)
|
print("",k, v)
|
||||||
RegionPager.SetOnCreate(pager, mapMaker.debugIsland)
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--create the overworld, set it's generator, loader & saver
|
||||||
|
--[[
|
||||||
|
local t = {
|
||||||
|
"overworld.bmp", --tileset name
|
||||||
|
mapSaver.load, --load function
|
||||||
|
mapSaver.save, --save function
|
||||||
|
mapMaker.debugIsland, --create function
|
||||||
|
mapSaver.save --unload function
|
||||||
|
}]]
|
||||||
|
|
||||||
|
dumpTable(roomSystem)
|
||||||
|
dumpTable(roomSystem.RoomManager)
|
||||||
|
dumpTable(roomSystem.Room)
|
||||||
|
|
||||||
|
local overworld = roomSystem.RoomManager.CreateRoom("overworld")
|
||||||
|
|
||||||
print("Finished the lua script")
|
print("Finished the lua script")
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
--TODO: An archive table of all dead characters
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS Accounts (
|
CREATE TABLE IF NOT EXISTS Accounts (
|
||||||
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
username varchar(100) UNIQUE,
|
username varchar(100) UNIQUE,
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/* 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 "account_data.hpp"
|
||||||
|
|
||||||
|
int AccountData::SetClientIndex(int i) {
|
||||||
|
return clientIndex = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AccountData::GetClientIndex() {
|
||||||
|
return clientIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AccountData::SetUsername(std::string s) {
|
||||||
|
return username = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AccountData::GetUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AccountData::GetBlackListed() {
|
||||||
|
return blackListed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AccountData::GetWhiteListed() {
|
||||||
|
return whiteListed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AccountData::GetModerator() {
|
||||||
|
return mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AccountData::GetAdministrator() {
|
||||||
|
return admin;
|
||||||
|
}
|
||||||
@@ -30,17 +30,17 @@ public:
|
|||||||
~AccountData() = default;
|
~AccountData() = default;
|
||||||
|
|
||||||
//accessors and mutators
|
//accessors and mutators
|
||||||
int SetClientIndex(int i) { return clientIndex = i; }
|
int SetClientIndex(int i);
|
||||||
int GetClientIndex() { return clientIndex; }
|
int GetClientIndex();
|
||||||
|
|
||||||
std::string SetUsername(std::string s) { return username = s; }
|
std::string SetUsername(std::string s);
|
||||||
std::string GetUsername() { return username; }
|
std::string GetUsername();
|
||||||
|
|
||||||
//database stuff
|
//database stuff
|
||||||
bool GetBlackListed() { return blackListed; }
|
bool GetBlackListed();
|
||||||
bool GetWhiteListed() { return whiteListed; }
|
bool GetWhiteListed();
|
||||||
bool GetModerator() { return mod; }
|
bool GetModerator();
|
||||||
bool GetAdministrator() { return admin; }
|
bool GetAdministrator();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class AccountManager;
|
friend class AccountManager;
|
||||||
@@ -49,6 +49,7 @@ private:
|
|||||||
std::string username;
|
std::string username;
|
||||||
//TODO: password
|
//TODO: password
|
||||||
|
|
||||||
|
//bit fields?
|
||||||
bool blackListed = false;
|
bool blackListed = false;
|
||||||
bool whiteListed = true;
|
bool whiteListed = true;
|
||||||
bool mod = false;
|
bool mod = false;
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ void AccountManager::UnloadAll() {
|
|||||||
elementMap.clear();
|
elementMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountManager::UnloadIf(std::function<bool(std::pair<const int, AccountData>)> fn) {
|
void AccountManager::UnloadIf(std::function<bool(std::pair<const int, AccountData>&)> fn) {
|
||||||
//replicate std::remove_if, using custom code
|
//replicate std::remove_if, using custom code
|
||||||
std::map<int, AccountData>::iterator it = elementMap.begin();
|
std::map<int, AccountData>::iterator it = elementMap.begin();
|
||||||
while (it != elementMap.end()) {
|
while (it != elementMap.end()) {
|
||||||
|
|||||||
@@ -26,7 +26,11 @@
|
|||||||
#include "singleton.hpp"
|
#include "singleton.hpp"
|
||||||
#include "manager_interface.hpp"
|
#include "manager_interface.hpp"
|
||||||
|
|
||||||
#include "sqlite3/sqlite3.h"
|
#if defined(__MINGW32__)
|
||||||
|
#include "sqlite3/sqlite3.h"
|
||||||
|
#else
|
||||||
|
#include "sqlite3.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
@@ -44,7 +48,7 @@ public:
|
|||||||
void Delete(int uid) override;
|
void Delete(int uid) override;
|
||||||
|
|
||||||
void UnloadAll() override;
|
void UnloadAll() override;
|
||||||
void UnloadIf(std::function<bool(std::pair<const int, AccountData>)> fn) override;
|
void UnloadIf(std::function<bool(std::pair<const int, AccountData>&)> fn) override;
|
||||||
|
|
||||||
//accessors and mutators
|
//accessors and mutators
|
||||||
AccountData* Get(int uid) override;
|
AccountData* Get(int uid) override;
|
||||||
|
|||||||
@@ -19,5 +19,16 @@
|
|||||||
* 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 "local_character.hpp"
|
#include "character_data.hpp"
|
||||||
|
|
||||||
|
int CharacterData::GetOwner() {
|
||||||
|
return owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CharacterData::GetHandle() {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CharacterData::GetAvatar() {
|
||||||
|
return avatar;
|
||||||
|
}
|
||||||
@@ -24,45 +24,28 @@
|
|||||||
|
|
||||||
//components
|
//components
|
||||||
#include "character_defines.hpp"
|
#include "character_defines.hpp"
|
||||||
#include "vector2.hpp"
|
#include "entity.hpp"
|
||||||
#include "statistics.hpp"
|
|
||||||
|
|
||||||
//std namespace
|
//std namespace
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
class CharacterData {
|
class CharacterData: public Entity {
|
||||||
public:
|
public:
|
||||||
CharacterData() = default;
|
CharacterData() = default;
|
||||||
~CharacterData() = default;
|
~CharacterData() = default;
|
||||||
|
|
||||||
//location and movement
|
|
||||||
int SetRoomIndex(int i) { return roomIndex = i; }
|
|
||||||
Vector2 SetOrigin(Vector2 v) { return origin = v; }
|
|
||||||
Vector2 SetMotion(Vector2 v) { return motion = v; }
|
|
||||||
|
|
||||||
int GetRoomIndex() { return roomIndex; }
|
|
||||||
Vector2 GetOrigin() { return origin; }
|
|
||||||
Vector2 GetMotion() { return motion; }
|
|
||||||
|
|
||||||
//accessors and mutators
|
//accessors and mutators
|
||||||
Statistics* GetBaseStats() { return &baseStats; }
|
//...
|
||||||
|
|
||||||
//database stuff
|
//database stuff
|
||||||
int GetOwner() { return owner; }
|
int GetOwner();
|
||||||
std::string GetHandle() { return handle; }
|
std::string GetHandle();
|
||||||
std::string GetAvatar() { return avatar; }
|
std::string GetAvatar();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class CharacterManager;
|
friend class CharacterManager;
|
||||||
|
|
||||||
//world position
|
|
||||||
int roomIndex = 0;
|
|
||||||
Vector2 origin = {0.0,0.0};
|
|
||||||
Vector2 motion = {0.0,0.0};
|
|
||||||
|
|
||||||
Statistics baseStats;
|
|
||||||
|
|
||||||
int owner;
|
int owner;
|
||||||
std::string handle;
|
std::string handle;
|
||||||
std::string avatar;
|
std::string avatar;
|
||||||
|
|||||||
@@ -21,7 +21,11 @@
|
|||||||
*/
|
*/
|
||||||
#include "character_manager.hpp"
|
#include "character_manager.hpp"
|
||||||
|
|
||||||
#include "sqlite3/sqlite3.h"
|
#if defined(__MINGW32__)
|
||||||
|
#include "sqlite3/sqlite3.h"
|
||||||
|
#else
|
||||||
|
#include "sqlite3.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@@ -223,7 +227,7 @@ void CharacterManager::UnloadAll() {
|
|||||||
elementMap.clear();
|
elementMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterManager::UnloadIf(std::function<bool(std::pair<const int, CharacterData>)> fn) {
|
void CharacterManager::UnloadIf(std::function<bool(std::pair<const int, CharacterData>&)> fn) {
|
||||||
std::map<int, CharacterData>::iterator it = elementMap.begin();
|
std::map<int, CharacterData>::iterator it = elementMap.begin();
|
||||||
while (it != elementMap.end()) {
|
while (it != elementMap.end()) {
|
||||||
if (fn(*it)) {
|
if (fn(*it)) {
|
||||||
@@ -282,4 +286,4 @@ sqlite3* CharacterManager::SetDatabase(sqlite3* db) {
|
|||||||
|
|
||||||
sqlite3* CharacterManager::GetDatabase() {
|
sqlite3* CharacterManager::GetDatabase() {
|
||||||
return database;
|
return database;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,11 @@
|
|||||||
#include "singleton.hpp"
|
#include "singleton.hpp"
|
||||||
#include "manager_interface.hpp"
|
#include "manager_interface.hpp"
|
||||||
|
|
||||||
#include "sqlite3/sqlite3.h"
|
#if defined(__MINGW32__)
|
||||||
|
#include "sqlite3/sqlite3.h"
|
||||||
|
#else
|
||||||
|
#include "sqlite3.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
@@ -44,7 +48,7 @@ public:
|
|||||||
void Delete(int uid) override;
|
void Delete(int uid) override;
|
||||||
|
|
||||||
void UnloadAll() override;
|
void UnloadAll() override;
|
||||||
void UnloadIf(std::function<bool(std::pair<const int, CharacterData>)> fn) override;
|
void UnloadIf(std::function<bool(std::pair<const int, CharacterData>&)> fn) override;
|
||||||
|
|
||||||
//accessors and mutators
|
//accessors and mutators
|
||||||
CharacterData* Get(int uid) override;
|
CharacterData* Get(int uid) override;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#config
|
#config
|
||||||
INCLUDES+=. ../server_utilities ../../common/gameplay ../../common/utilities
|
INCLUDES+=. ../entities ../server_utilities ../../common/gameplay ../../common/utilities
|
||||||
LIBS+=
|
LIBS+=
|
||||||
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,26 @@
|
|||||||
*/
|
*/
|
||||||
#include "client_data.hpp"
|
#include "client_data.hpp"
|
||||||
|
|
||||||
|
ClientData::ClientData(IPaddress add) {
|
||||||
|
address = add;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPaddress ClientData::SetAddress(IPaddress add) {
|
||||||
|
return address = add;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPaddress ClientData::GetAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientData::Clock::time_point ClientData::GetLastBeat() {
|
||||||
|
return lastBeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ClientData::GetAttempts() {
|
||||||
|
return attemptedBeats;
|
||||||
|
}
|
||||||
|
|
||||||
int ClientData::IncrementAttempts() {
|
int ClientData::IncrementAttempts() {
|
||||||
lastBeat = Clock::now();
|
lastBeat = Clock::now();
|
||||||
return attemptedBeats++;
|
return attemptedBeats++;
|
||||||
@@ -26,21 +26,20 @@
|
|||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
//TODO: ClientManager?
|
|
||||||
class ClientData {
|
class ClientData {
|
||||||
public:
|
public:
|
||||||
typedef std::chrono::steady_clock Clock;
|
typedef std::chrono::steady_clock Clock;
|
||||||
|
|
||||||
ClientData() = default;
|
ClientData() = default;
|
||||||
ClientData(IPaddress add): address(add) {}
|
ClientData(IPaddress add);
|
||||||
~ClientData() = default;
|
~ClientData() = default;
|
||||||
|
|
||||||
IPaddress SetAddress(IPaddress add) { return address = add; }
|
IPaddress SetAddress(IPaddress add);
|
||||||
IPaddress GetAddress() { return address; }
|
IPaddress GetAddress();
|
||||||
|
|
||||||
Clock::time_point GetLastBeat() { return lastBeat; }
|
Clock::time_point GetLastBeat();
|
||||||
|
|
||||||
int GetAttempts() { return attemptedBeats; }
|
int GetAttempts();
|
||||||
int IncrementAttempts();
|
int IncrementAttempts();
|
||||||
int ResetAttempts();
|
int ResetAttempts();
|
||||||
|
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
/* 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_manager.hpp"
|
||||||
|
|
||||||
|
#include "udp_network_utility.hpp"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
int ClientManager::CheckConnections() {
|
||||||
|
for (auto& it : elementMap) {
|
||||||
|
//3 seconds between beats
|
||||||
|
if (ClientData::Clock::now() - it.second.GetLastBeat() > std::chrono::seconds(3)) {
|
||||||
|
ServerPacket newPacket;
|
||||||
|
newPacket.type = SerialPacketType::PING;
|
||||||
|
UDPNetworkUtility::GetSingleton().SendTo(it.second.GetAddress(), &newPacket);
|
||||||
|
it.second.IncrementAttempts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& it : elementMap) {
|
||||||
|
if (it.second.GetAttempts() > 2) {
|
||||||
|
int ret = it.first;
|
||||||
|
elementMap.erase(it.first);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientManager::HandlePong(ServerPacket* const argPacket) {
|
||||||
|
//find and update the specified client
|
||||||
|
for (auto& it : elementMap) {
|
||||||
|
if (it.second.GetAddress().host == argPacket->srcAddress.host &&
|
||||||
|
it.second.GetAddress().port == argPacket->srcAddress.port
|
||||||
|
) {
|
||||||
|
it.second.ResetAttempts();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ClientManager::Create(IPaddress add) {
|
||||||
|
ClientData& client = elementMap[counter];
|
||||||
|
client.SetAddress(add);
|
||||||
|
return counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientManager::Unload(int uid) {
|
||||||
|
elementMap.erase(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientManager::UnloadAll() {
|
||||||
|
elementMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientManager::UnloadIf(std::function<bool(std::pair<const int, ClientData>&)> fn) {
|
||||||
|
std::map<int, ClientData>::iterator it = elementMap.begin();
|
||||||
|
while (it != elementMap.end()) {
|
||||||
|
if (fn(*it)) {
|
||||||
|
it = elementMap.erase(it);
|
||||||
|
//TODO: ? disconnect, unload characters, notify other clients
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientData* ClientManager::Get(int uid) {
|
||||||
|
std::map<int, ClientData>::iterator it = elementMap.find(uid);
|
||||||
|
|
||||||
|
if (it == elementMap.end()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ClientManager::GetLoadedCount() {
|
||||||
|
return elementMap.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ClientManager::GetTotalCount() {
|
||||||
|
return elementMap.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<int, ClientData>* ClientManager::GetContainer() {
|
||||||
|
return &elementMap;
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
#ifndef CLIENTMANAGER_HPP_
|
||||||
|
#define CLIENTMANAGER_HPP_
|
||||||
|
|
||||||
|
#include "client_data.hpp"
|
||||||
|
#include "manager_interface.hpp"
|
||||||
|
#include "server_packet.hpp"
|
||||||
|
#include "singleton.hpp"
|
||||||
|
|
||||||
|
#include "SDL/SDL_net.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
class ClientManager:
|
||||||
|
public Singleton<ClientManager>,
|
||||||
|
public ManagerInterface<ClientData, IPaddress>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//methods
|
||||||
|
int CheckConnections();
|
||||||
|
void HandlePong(ServerPacket* const argPacket);
|
||||||
|
|
||||||
|
//common public methods
|
||||||
|
int Create(IPaddress) override;
|
||||||
|
void Unload(int uid) override;
|
||||||
|
|
||||||
|
void UnloadAll() override;
|
||||||
|
void UnloadIf(std::function<bool(std::pair<const int, ClientData>&)> fn) override;
|
||||||
|
|
||||||
|
//accessors & mutators
|
||||||
|
ClientData* Get(int uid) override;
|
||||||
|
int GetLoadedCount() override;
|
||||||
|
int GetTotalCount() override;
|
||||||
|
std::map<int, ClientData>* GetContainer() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend Singleton<ClientManager>;
|
||||||
|
|
||||||
|
ClientManager() = default;
|
||||||
|
~ClientManager() = default;
|
||||||
|
|
||||||
|
//EMPTY
|
||||||
|
int Load(IPaddress) override { return -1; }
|
||||||
|
int Save(int uid) override { return -1; }
|
||||||
|
void Delete(int uid) override { return; }
|
||||||
|
|
||||||
|
int counter = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#config
|
||||||
|
INCLUDES+=. ../server_utilities ../../common/network ../../common/network/packet_types ../../common/utilities
|
||||||
|
LIBS+=
|
||||||
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
|
|
||||||
|
#source
|
||||||
|
CXXSRC=$(wildcard *.cpp)
|
||||||
|
|
||||||
|
#objects
|
||||||
|
OBJDIR=obj
|
||||||
|
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
||||||
|
|
||||||
|
#output
|
||||||
|
OUTDIR=..
|
||||||
|
OUT=$(addprefix $(OUTDIR)/,server.a)
|
||||||
|
|
||||||
|
#targets
|
||||||
|
all: $(OBJ) $(OUT)
|
||||||
|
ar -crs $(OUT) $(OBJ)
|
||||||
|
|
||||||
|
$(OBJ): | $(OBJDIR)
|
||||||
|
|
||||||
|
$(OUT): | $(OUTDIR)
|
||||||
|
|
||||||
|
$(OBJDIR):
|
||||||
|
mkdir $(OBJDIR)
|
||||||
|
|
||||||
|
$(OUTDIR):
|
||||||
|
mkdir $(OUTDIR)
|
||||||
|
|
||||||
|
$(OBJDIR)/%.o: %.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) *.o *.a *.exe
|
||||||
|
|
||||||
|
rebuild: clean all
|
||||||
@@ -19,24 +19,20 @@
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
#ifndef STATISTICS_HPP_
|
#include "door_data.hpp"
|
||||||
#define STATISTICS_HPP_
|
|
||||||
|
|
||||||
struct Statistics {
|
std::string DoorData::SetRoomName(std::string s) {
|
||||||
int level = 0;
|
return roomName = s;
|
||||||
int exp = 0;
|
}
|
||||||
int maxHP = 0;
|
|
||||||
int health = 0;
|
|
||||||
int maxMP = 0;
|
|
||||||
int mana = 0;
|
|
||||||
int attack = 0;
|
|
||||||
int defence = 0;
|
|
||||||
int intelligence = 0;
|
|
||||||
int resistance = 0;
|
|
||||||
int speed = 0;
|
|
||||||
float accuracy = 0.0;
|
|
||||||
float evasion = 0.0;
|
|
||||||
float luck = 0.0;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
Vector2 DoorData::SetDestPosition(Vector2 v) {
|
||||||
|
return destPosition = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string DoorData::GetRoomName() {
|
||||||
|
return roomName;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 DoorData::GetDestPosition() {
|
||||||
|
return destPosition;
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
#ifndef DOORDATA_HPP_
|
||||||
|
#define DOORDATA_HPP_
|
||||||
|
|
||||||
|
#include "entity.hpp"
|
||||||
|
#include "vector2.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class DoorData: public Entity {
|
||||||
|
public:
|
||||||
|
DoorData() = default;
|
||||||
|
~DoorData() = default;
|
||||||
|
|
||||||
|
//accessors & mutators
|
||||||
|
std::string SetRoomName(std::string);
|
||||||
|
Vector2 SetDestPosition(Vector2);
|
||||||
|
|
||||||
|
std::string GetRoomName();
|
||||||
|
Vector2 GetDestPosition();
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class DoorManager;
|
||||||
|
|
||||||
|
std::string roomName;
|
||||||
|
Vector2 destPosition;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/* 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 "door_manager.hpp"
|
||||||
|
|
||||||
|
int DoorManager::Create(std::string, Vector2) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
int DoorManager::Load(std::string, Vector2) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
int DoorManager::Save(int uid) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoorManager::Unload(int uid) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoorManager::Delete(int uid) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoorManager::UnloadAll() {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoorManager::UnloadIf(std::function<bool(std::pair<const int, DoorData>&)> fn) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
DoorData* DoorManager::Get(int uid) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
int DoorManager::GetLoadedCount() {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
int DoorManager::GetTotalCount() {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<int, DoorData>* DoorManager::GetContainer() {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
#ifndef DOORMANAGER_HPP_
|
||||||
|
#define DOORMANAGER_HPP_
|
||||||
|
|
||||||
|
#include "door_data.hpp"
|
||||||
|
#include "manager_interface.hpp"
|
||||||
|
#include "singleton.hpp"
|
||||||
|
#include "vector2.hpp"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class DoorManager:
|
||||||
|
public Singleton<DoorManager>,
|
||||||
|
public ManagerInterface<DoorData, std::string, Vector2>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//common public methods
|
||||||
|
int Create(std::string, Vector2) override;
|
||||||
|
int Load(std::string, Vector2) override;
|
||||||
|
int Save(int uid) override;
|
||||||
|
void Unload(int uid) override;
|
||||||
|
void Delete(int uid) override;
|
||||||
|
|
||||||
|
void UnloadAll() override;
|
||||||
|
void UnloadIf(std::function<bool(std::pair<const int, DoorData>&)> fn) override;
|
||||||
|
|
||||||
|
//accessors & mutators
|
||||||
|
DoorData* Get(int uid) override;
|
||||||
|
int GetLoadedCount() override;
|
||||||
|
int GetTotalCount() override;
|
||||||
|
std::map<int, DoorData>* GetContainer() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend Singleton<DoorManager>;
|
||||||
|
|
||||||
|
DoorManager() = default;
|
||||||
|
~DoorManager() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#config
|
||||||
|
INCLUDES+=. ../entities ../server_utilities ../../common/utilities
|
||||||
|
LIBS+=
|
||||||
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
|
|
||||||
|
#source
|
||||||
|
CXXSRC=$(wildcard *.cpp)
|
||||||
|
|
||||||
|
#objects
|
||||||
|
OBJDIR=obj
|
||||||
|
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
||||||
|
|
||||||
|
#output
|
||||||
|
OUTDIR=..
|
||||||
|
OUT=$(addprefix $(OUTDIR)/,server.a)
|
||||||
|
|
||||||
|
#targets
|
||||||
|
all: $(OBJ) $(OUT)
|
||||||
|
ar -crs $(OUT) $(OBJ)
|
||||||
|
|
||||||
|
$(OBJ): | $(OBJDIR)
|
||||||
|
|
||||||
|
$(OUT): | $(OUTDIR)
|
||||||
|
|
||||||
|
$(OBJDIR):
|
||||||
|
mkdir $(OBJDIR)
|
||||||
|
|
||||||
|
$(OUTDIR):
|
||||||
|
mkdir $(OUTDIR)
|
||||||
|
|
||||||
|
$(OBJDIR)/%.o: %.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) *.o *.a *.exe
|
||||||
|
|
||||||
|
rebuild: clean all
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/* 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 "entity.hpp"
|
||||||
|
|
||||||
|
int Entity::SetEntityIndex(int i) {
|
||||||
|
return entityIndex = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Entity::SetRoomIndex(int i) {
|
||||||
|
return roomIndex = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 Entity::SetOrigin(Vector2 v) {
|
||||||
|
return origin = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 Entity::SetMotion(Vector2 v) {
|
||||||
|
return motion = v;
|
||||||
|
}
|
||||||
|
int Entity::GetEntityIndex() {
|
||||||
|
return entityIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Entity::GetRoomIndex() {
|
||||||
|
return roomIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 Entity::GetOrigin() {
|
||||||
|
return origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 Entity::GetMotion() {
|
||||||
|
return motion;
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
#ifndef ENTITY_HPP_
|
||||||
|
#define ENTITY_HPP_
|
||||||
|
|
||||||
|
#include "vector2.hpp"
|
||||||
|
|
||||||
|
//The base class for all objects in the world
|
||||||
|
class Entity {
|
||||||
|
public:
|
||||||
|
//accessors & mutators
|
||||||
|
int SetEntityIndex(int i);
|
||||||
|
int SetRoomIndex(int i);
|
||||||
|
Vector2 SetOrigin(Vector2 v);
|
||||||
|
Vector2 SetMotion(Vector2 v);
|
||||||
|
|
||||||
|
int GetEntityIndex();
|
||||||
|
int GetRoomIndex();
|
||||||
|
Vector2 GetOrigin();
|
||||||
|
Vector2 GetMotion();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Entity() = default;
|
||||||
|
~Entity() = default;
|
||||||
|
|
||||||
|
int entityIndex = -1;
|
||||||
|
int roomIndex = -1;
|
||||||
|
Vector2 origin;
|
||||||
|
Vector2 motion;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#config
|
#config
|
||||||
INCLUDES+=.
|
INCLUDES+=. ../../common/utilities
|
||||||
LIBS+=
|
LIBS+=
|
||||||
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
|||||||
|
|
||||||
#output
|
#output
|
||||||
OUTDIR=..
|
OUTDIR=..
|
||||||
OUT=$(addprefix $(OUTDIR)/,client.a)
|
OUT=$(addprefix $(OUTDIR)/,server.a)
|
||||||
|
|
||||||
#targets
|
#targets
|
||||||
all: $(OBJ) $(OUT)
|
all: $(OBJ) $(OUT)
|
||||||
+10
-15
@@ -34,13 +34,14 @@
|
|||||||
#define linit_c
|
#define linit_c
|
||||||
#define LUA_LIB
|
#define LUA_LIB
|
||||||
|
|
||||||
#include "lua/lua.hpp"
|
#if defined(__MINGW32__)
|
||||||
|
#include "lua/lua.hpp"
|
||||||
|
#else
|
||||||
|
#include "lua.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "region_api.hpp"
|
#include "map_system_api.hpp"
|
||||||
#include "region_pager_api.hpp"
|
#include "room_system_api.hpp"
|
||||||
#include "tile_sheet_api.hpp"
|
|
||||||
#include "room_api.hpp"
|
|
||||||
#include "room_manager_api.hpp"
|
|
||||||
|
|
||||||
//these libs are loaded by lua.c and are readily available to any Lua program
|
//these libs are loaded by lua.c and are readily available to any Lua program
|
||||||
static const luaL_Reg loadedlibs[] = {
|
static const luaL_Reg loadedlibs[] = {
|
||||||
@@ -55,20 +56,14 @@ static const luaL_Reg loadedlibs[] = {
|
|||||||
{LUA_BITLIBNAME, luaopen_bit32},
|
{LUA_BITLIBNAME, luaopen_bit32},
|
||||||
{LUA_MATHLIBNAME, luaopen_math},
|
{LUA_MATHLIBNAME, luaopen_math},
|
||||||
{LUA_DBLIBNAME, luaopen_debug},
|
{LUA_DBLIBNAME, luaopen_debug},
|
||||||
|
|
||||||
//Tortuga's API
|
|
||||||
{TORTUGA_REGION_NAME, openRegionAPI},
|
|
||||||
{TORTUGA_REGION_PAGER_NAME, openRegionPagerAPI},
|
|
||||||
{TORTUGA_TILE_SHEET_NAME, openTileSheetAPI},
|
|
||||||
{TORTUGA_ROOM_NAME, openRoomAPI},
|
|
||||||
{TORTUGA_ROOM_MANAGER_NAME, openRoomManagerAPI},
|
|
||||||
|
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//these libs are preloaded and must be required before used
|
//these libs are preloaded and must be required before used
|
||||||
static const luaL_Reg preloadedlibs[] = {
|
static const luaL_Reg preloadedlibs[] = {
|
||||||
|
{TORTUGA_MAP_SYSTEM_API, openMapSystemAPI},
|
||||||
|
{TORTUGA_ROOM_SYSTEM_API, openRoomSystemAPI},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -86,4 +81,4 @@ LUALIB_API void luaL_openlibs (lua_State *L) {
|
|||||||
lua_setfield(L, -2, lib->name);
|
lua_setfield(L, -2, lib->name);
|
||||||
}
|
}
|
||||||
lua_pop(L, 1); //remove _PRELOAD table
|
lua_pop(L, 1); //remove _PRELOAD table
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,10 @@
|
|||||||
//singletons
|
//singletons
|
||||||
#include "account_manager.hpp"
|
#include "account_manager.hpp"
|
||||||
#include "character_manager.hpp"
|
#include "character_manager.hpp"
|
||||||
|
#include "client_manager.hpp"
|
||||||
#include "config_utility.hpp"
|
#include "config_utility.hpp"
|
||||||
|
#include "door_manager.hpp"
|
||||||
|
#include "monster_manager.hpp"
|
||||||
#include "room_manager.hpp"
|
#include "room_manager.hpp"
|
||||||
#include "udp_network_utility.hpp"
|
#include "udp_network_utility.hpp"
|
||||||
|
|
||||||
@@ -38,7 +41,10 @@ int main(int argc, char* argv[]) {
|
|||||||
//create the singletons
|
//create the singletons
|
||||||
AccountManager::CreateSingleton();
|
AccountManager::CreateSingleton();
|
||||||
CharacterManager::CreateSingleton();
|
CharacterManager::CreateSingleton();
|
||||||
|
ClientManager::CreateSingleton();
|
||||||
ConfigUtility::CreateSingleton();
|
ConfigUtility::CreateSingleton();
|
||||||
|
DoorManager::CreateSingleton();
|
||||||
|
MonsterManager::CreateSingleton();
|
||||||
RoomManager::CreateSingleton();
|
RoomManager::CreateSingleton();
|
||||||
UDPNetworkUtility::CreateSingleton();
|
UDPNetworkUtility::CreateSingleton();
|
||||||
|
|
||||||
@@ -55,7 +61,10 @@ int main(int argc, char* argv[]) {
|
|||||||
//delete the singletons
|
//delete the singletons
|
||||||
AccountManager::DeleteSingleton();
|
AccountManager::DeleteSingleton();
|
||||||
CharacterManager::DeleteSingleton();
|
CharacterManager::DeleteSingleton();
|
||||||
|
ClientManager::DeleteSingleton();
|
||||||
ConfigUtility::DeleteSingleton();
|
ConfigUtility::DeleteSingleton();
|
||||||
|
DoorManager::DeleteSingleton();
|
||||||
|
MonsterManager::DeleteSingleton();
|
||||||
RoomManager::DeleteSingleton();
|
RoomManager::DeleteSingleton();
|
||||||
UDPNetworkUtility::DeleteSingleton();
|
UDPNetworkUtility::DeleteSingleton();
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-3
@@ -1,6 +1,15 @@
|
|||||||
#config
|
#include directories
|
||||||
INCLUDES+=. accounts characters rooms server_utilities ../common/debugging ../common/gameplay ../common/map ../common/network ../common/network/packet_types ../common/utilities
|
INCLUDES+=. accounts characters clients doors entities monsters rooms server_utilities ../common/debugging ../common/gameplay ../common/map ../common/network ../common/network/packet_types ../common/utilities
|
||||||
LIBS+=server.a ../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua -lsqlite3
|
|
||||||
|
#libraries
|
||||||
|
#the order of the $(LIBS) is important, at least for MinGW
|
||||||
|
LIBS+=server.a ../libcommon.a -lSDL_net
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
LIBS+=-lwsock32 -liphlpapi -lmingw32
|
||||||
|
endif
|
||||||
|
LIBS+=-lSDLmain -lSDL -llua -lsqlite3
|
||||||
|
|
||||||
|
#flags
|
||||||
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
|
|
||||||
#source
|
#source
|
||||||
@@ -18,6 +27,10 @@ OUT=$(addprefix $(OUTDIR)/,server)
|
|||||||
all: $(OBJ) $(OUT)
|
all: $(OBJ) $(OUT)
|
||||||
$(MAKE) -C accounts
|
$(MAKE) -C accounts
|
||||||
$(MAKE) -C characters
|
$(MAKE) -C characters
|
||||||
|
$(MAKE) -C clients
|
||||||
|
$(MAKE) -C doors
|
||||||
|
$(MAKE) -C entities
|
||||||
|
$(MAKE) -C monsters
|
||||||
$(MAKE) -C rooms
|
$(MAKE) -C rooms
|
||||||
$(MAKE) -C server_utilities
|
$(MAKE) -C server_utilities
|
||||||
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
|
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#config
|
||||||
|
INCLUDES+=. ../entities ../server_utilities ../../common/gameplay ../../common/utilities
|
||||||
|
LIBS+=
|
||||||
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
|
|
||||||
|
#source
|
||||||
|
CXXSRC=$(wildcard *.cpp)
|
||||||
|
|
||||||
|
#objects
|
||||||
|
OBJDIR=obj
|
||||||
|
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
||||||
|
|
||||||
|
#output
|
||||||
|
OUTDIR=..
|
||||||
|
OUT=$(addprefix $(OUTDIR)/,server.a)
|
||||||
|
|
||||||
|
#targets
|
||||||
|
all: $(OBJ) $(OUT)
|
||||||
|
ar -crs $(OUT) $(OBJ)
|
||||||
|
|
||||||
|
$(OBJ): | $(OBJDIR)
|
||||||
|
|
||||||
|
$(OUT): | $(OUTDIR)
|
||||||
|
|
||||||
|
$(OBJDIR):
|
||||||
|
mkdir $(OBJDIR)
|
||||||
|
|
||||||
|
$(OUTDIR):
|
||||||
|
mkdir $(OUTDIR)
|
||||||
|
|
||||||
|
$(OBJDIR)/%.o: %.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) *.o *.a *.exe
|
||||||
|
|
||||||
|
rebuild: clean all
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/* 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 "monster_data.hpp"
|
||||||
|
|
||||||
|
std::string MonsterData::SetAvatar(std::string s) {
|
||||||
|
return avatar = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MonsterData::SetScriptReference(int i) {
|
||||||
|
return scriptRef = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MonsterData::GetAvatar() {
|
||||||
|
return avatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MonsterData::GetScriptReference() {
|
||||||
|
return scriptRef;
|
||||||
|
}
|
||||||
@@ -19,22 +19,29 @@
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
#ifndef LOCALCHARACTER_HPP_
|
#ifndef MONSTERDATA_HPP_
|
||||||
#define LOCALCHARACTER_HPP_
|
#define MONSTERDATA_HPP_
|
||||||
|
|
||||||
#include "base_character.hpp"
|
#include "entity.hpp"
|
||||||
#include "statistics.hpp"
|
|
||||||
|
|
||||||
class LocalCharacter : public BaseCharacter {
|
#include <string>
|
||||||
|
|
||||||
|
class MonsterData: public Entity {
|
||||||
public:
|
public:
|
||||||
LocalCharacter() = default;
|
MonsterData() = default;
|
||||||
~LocalCharacter() = default;
|
~MonsterData() = default;
|
||||||
|
|
||||||
Statistics* GetBaseStats() { return &baseStats; }
|
std::string SetAvatar(std::string);
|
||||||
|
int SetScriptReference(int);
|
||||||
|
|
||||||
|
std::string GetAvatar();
|
||||||
|
int GetScriptReference();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Statistics baseStats;
|
friend class MonsterManager;
|
||||||
//TODO: weapons, armour, buffs, debuffs, etc.
|
|
||||||
|
std::string avatar;
|
||||||
|
int scriptRef;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/* 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 "monster_manager.hpp"
|
||||||
|
|
||||||
|
int MonsterManager::Create(std::string) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
int MonsterManager::Load(std::string) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
int MonsterManager::Save(int uid) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void MonsterManager::Unload(int uid) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void MonsterManager::Delete(int uid) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void MonsterManager::UnloadAll() {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void MonsterManager::UnloadIf(std::function<bool(std::pair<const int, MonsterData>&)> fn) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
MonsterData* MonsterManager::Get(int uid) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
int MonsterManager::GetLoadedCount() {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
int MonsterManager::GetTotalCount() {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<int, MonsterData>* MonsterManager::GetContainer() {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3* MonsterManager::SetDatabase(sqlite3* db) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3* MonsterManager::GetDatabase() {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_State* MonsterManager::SetLuaState(lua_State* L) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_State* MonsterManager::GetLuaState() {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
#ifndef MONSTERMANAGER_HPP_
|
||||||
|
#define MONSTERMANAGER_HPP_
|
||||||
|
|
||||||
|
#include "manager_interface.hpp"
|
||||||
|
#include "monster_data.hpp"
|
||||||
|
#include "singleton.hpp"
|
||||||
|
|
||||||
|
#ifdef __unix__
|
||||||
|
#include "lua.hpp"
|
||||||
|
#include "sqlite3.h"
|
||||||
|
#else
|
||||||
|
#include "lua/lua.hpp"
|
||||||
|
#include "sqlite3/sqlite3.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class MonsterManager:
|
||||||
|
public Singleton<MonsterManager>,
|
||||||
|
public ManagerInterface<MonsterData, std::string>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//common public methods
|
||||||
|
int Create(std::string) override;
|
||||||
|
int Load(std::string) override;
|
||||||
|
int Save(int uid) override;
|
||||||
|
void Unload(int uid) override;
|
||||||
|
void Delete(int uid) override;
|
||||||
|
|
||||||
|
void UnloadAll() override;
|
||||||
|
void UnloadIf(std::function<bool(std::pair<const int, MonsterData>&)> fn) override;
|
||||||
|
|
||||||
|
//accessors & mutators
|
||||||
|
MonsterData* Get(int uid) override;
|
||||||
|
int GetLoadedCount() override;
|
||||||
|
int GetTotalCount() override;
|
||||||
|
std::map<int, MonsterData>* GetContainer() override;
|
||||||
|
|
||||||
|
//hooks
|
||||||
|
sqlite3* SetDatabase(sqlite3* db);
|
||||||
|
sqlite3* GetDatabase();
|
||||||
|
lua_State* SetLuaState(lua_State* L);
|
||||||
|
lua_State* GetLuaState();
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend Singleton<MonsterManager>;
|
||||||
|
|
||||||
|
MonsterManager() = default;
|
||||||
|
~MonsterManager() = default;
|
||||||
|
|
||||||
|
sqlite3* database = nullptr;
|
||||||
|
lua_State* lua = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#config
|
#config
|
||||||
INCLUDES+=. ../server_utilities ../../common/map ../../common/utilities
|
INCLUDES+=. ../entities ../server_utilities ../../common/map ../../common/utilities
|
||||||
LIBS+=
|
LIBS+=
|
||||||
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
|
|
||||||
|
|||||||
@@ -23,12 +23,6 @@
|
|||||||
|
|
||||||
#include "room_data.hpp"
|
#include "room_data.hpp"
|
||||||
|
|
||||||
static int getPager(lua_State* L) {
|
|
||||||
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
|
|
||||||
lua_pushlightuserdata(L, reinterpret_cast<void*>(room->GetPager()) );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int setRoomName(lua_State* L) {
|
static int setRoomName(lua_State* L) {
|
||||||
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
|
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
|
||||||
room->SetRoomName(lua_tostring(L, 2));
|
room->SetRoomName(lua_tostring(L, 2));
|
||||||
@@ -53,12 +47,34 @@ static int getTilesetName(lua_State* L) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int getPager(lua_State* L) {
|
||||||
|
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
|
||||||
|
lua_pushlightuserdata(L, reinterpret_cast<void*>(room->GetPager()) );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int initialize(lua_State* L) {
|
||||||
|
//set the members of the given room
|
||||||
|
RoomData* room = static_cast<RoomData*>(lua_touserdata(L, 1));
|
||||||
|
room->SetRoomName(lua_tostring(L, 2));
|
||||||
|
|
||||||
|
//set the refs of these parameters (backwards, since it pops from the top of the stack)
|
||||||
|
room->GetPager()->SetUnloadReference(luaL_ref(L, LUA_REGISTRYINDEX));
|
||||||
|
room->GetPager()->SetCreateReference(luaL_ref(L, LUA_REGISTRYINDEX));
|
||||||
|
room->GetPager()->SetSaveReference(luaL_ref(L, LUA_REGISTRYINDEX));
|
||||||
|
room->GetPager()->SetLoadReference(luaL_ref(L, LUA_REGISTRYINDEX));
|
||||||
|
|
||||||
|
//more parameters can be added here later
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const luaL_Reg roomLib[] = {
|
static const luaL_Reg roomLib[] = {
|
||||||
{"GetPager",getPager},
|
{"GetPager",getPager},
|
||||||
{"SetRoomName", setRoomName},
|
{"SetRoomName", setRoomName},
|
||||||
{"GetRoomName", getRoomName},
|
{"GetRoomName", getRoomName},
|
||||||
{"SetTileset", setTilesetName},
|
{"SetTileset", setTilesetName},
|
||||||
{"GetTileset", getTilesetName},
|
{"GetTileset", getTilesetName},
|
||||||
|
{"Initialize", initialize},
|
||||||
{nullptr, nullptr}
|
{nullptr, nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,13 @@
|
|||||||
#ifndef ROOMAPI_HPP_
|
#ifndef ROOMAPI_HPP_
|
||||||
#define ROOMAPI_HPP_
|
#define ROOMAPI_HPP_
|
||||||
|
|
||||||
#include "lua/lua.hpp"
|
#if defined(__MINGW32__)
|
||||||
|
#include "lua/lua.hpp"
|
||||||
|
#else
|
||||||
|
#include "lua.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define TORTUGA_ROOM_NAME "Room"
|
#define TORTUGA_ROOM_API "room"
|
||||||
LUAMOD_API int openRoomAPI(lua_State* L);
|
LUAMOD_API int openRoomAPI(lua_State* L);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/* 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 "room_data.hpp"
|
||||||
|
|
||||||
|
RoomData::RoomData() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
RoomData::RoomData(RoomData& rhs) {
|
||||||
|
roomName = std::move(rhs.roomName);
|
||||||
|
tilesetName = std::move(rhs.tilesetName);
|
||||||
|
pager = std::move(rhs.pager);
|
||||||
|
//entityList = std::move(rhs.entityList);
|
||||||
|
}
|
||||||
|
|
||||||
|
RoomData::~RoomData() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RoomData::SetRoomName(std::string s) {
|
||||||
|
return roomName = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RoomData::GetRoomName() {
|
||||||
|
return roomName;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RoomData::SetTilesetName(std::string s) {
|
||||||
|
return tilesetName = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RoomData::GetTilesetName() {
|
||||||
|
return tilesetName;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionPagerLua* RoomData::GetPager() {
|
||||||
|
return &pager;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<Entity*>* RoomData::GetEntityList() {
|
||||||
|
// return &entityList;
|
||||||
|
}
|
||||||
+20
-11
@@ -22,34 +22,43 @@
|
|||||||
#ifndef ROOMDATA_HPP_
|
#ifndef ROOMDATA_HPP_
|
||||||
#define ROOMDATA_HPP_
|
#define ROOMDATA_HPP_
|
||||||
|
|
||||||
//map system
|
#include "entity.hpp"
|
||||||
#include "region_pager_lua.hpp"
|
#include "region_pager_lua.hpp"
|
||||||
|
|
||||||
|
#if defined(__MINGW32__)
|
||||||
|
#include "lua/lua.hpp"
|
||||||
|
#else
|
||||||
|
#include "lua.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class RoomData {
|
class RoomData {
|
||||||
public:
|
public:
|
||||||
RoomData() = default;
|
RoomData();
|
||||||
~RoomData() = default;
|
RoomData(RoomData&);
|
||||||
|
~RoomData();
|
||||||
|
|
||||||
//accessors and mutators
|
//accessors and mutators
|
||||||
RegionPagerLua* GetPager() { return &pager; }
|
std::string SetRoomName(std::string s);
|
||||||
|
std::string GetRoomName();
|
||||||
|
|
||||||
std::string SetRoomName(std::string s) { return roomName = s; }
|
std::string SetTilesetName(std::string s);
|
||||||
std::string GetRoomName() { return roomName; }
|
std::string GetTilesetName();
|
||||||
|
|
||||||
std::string SetTilesetName(std::string s) { return tilesetName = s; }
|
RegionPagerLua* GetPager();
|
||||||
std::string GetTilesetName() { return tilesetName; }
|
std::list<Entity*>* GetEntityList();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class RoomManager;
|
friend class RoomManager;
|
||||||
|
|
||||||
//members
|
//members
|
||||||
RegionPagerLua pager;
|
|
||||||
std::string roomName;
|
std::string roomName;
|
||||||
std::string tilesetName;
|
std::string tilesetName;
|
||||||
//TODO: pass the room name & tileset name to the clients
|
|
||||||
//TODO: lua references i.e. create, unload, etc.
|
RegionPagerLua pager;
|
||||||
|
// std::list<Entity*> entityList;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -23,31 +23,28 @@
|
|||||||
|
|
||||||
#include "room_api.hpp"
|
#include "room_api.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//public access methods
|
//public access methods
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
int RoomManager::Create() {
|
int RoomManager::Create(std::string roomName) {
|
||||||
|
std::cout << "Create-1" << std::endl;
|
||||||
//create the room
|
//create the room
|
||||||
RoomData* newRoom = &elementMap[counter]; //implicitly constructs the element
|
elementMap.emplace(counter); ////explicitly constructs the element
|
||||||
|
RoomData* newRoom = &(elementMap.find(counter)->second);
|
||||||
|
std::cout << "Create-2" << std::endl;
|
||||||
|
newRoom->SetRoomName(roomName);
|
||||||
|
std::cout << "Create-3" << std::endl;
|
||||||
newRoom->pager.SetLuaState(lua);
|
newRoom->pager.SetLuaState(lua);
|
||||||
|
std::cout << "Create-4" << std::endl;
|
||||||
|
|
||||||
//finish the routine
|
//finish the routine
|
||||||
return counter++;
|
return counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RoomManager::Load() {
|
|
||||||
//TODO: RoomManager::Load()
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int RoomManager::Save(int uid) {
|
|
||||||
//TODO: RoomManager::Save(uid)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RoomManager::Unload(int uid) {
|
void RoomManager::Unload(int uid) {
|
||||||
//find the room
|
//find the room
|
||||||
std::map<int, RoomData>::iterator it = elementMap.find(uid);
|
std::map<int, RoomData>::iterator it = elementMap.find(uid);
|
||||||
@@ -59,17 +56,11 @@ void RoomManager::Unload(int uid) {
|
|||||||
elementMap.erase(uid);
|
elementMap.erase(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RoomManager::Delete(int uid) {
|
|
||||||
//TODO: RoomManager::Delete(int uid)
|
|
||||||
//NOTE: aliased to RoomManager::Unload(int uid)
|
|
||||||
Unload(uid);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RoomManager::UnloadAll() {
|
void RoomManager::UnloadAll() {
|
||||||
elementMap.clear();
|
elementMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RoomManager::UnloadIf(std::function<bool(std::pair<const int,RoomData>)> fn) {
|
void RoomManager::UnloadIf(std::function<bool(std::pair<const int,RoomData>&)> fn) {
|
||||||
std::map<int, RoomData>::iterator it = elementMap.begin();
|
std::map<int, RoomData>::iterator it = elementMap.begin();
|
||||||
while (it != elementMap.end()) {
|
while (it != elementMap.end()) {
|
||||||
if (fn(*it)) {
|
if (fn(*it)) {
|
||||||
|
|||||||
@@ -26,22 +26,23 @@
|
|||||||
#include "singleton.hpp"
|
#include "singleton.hpp"
|
||||||
#include "manager_interface.hpp"
|
#include "manager_interface.hpp"
|
||||||
|
|
||||||
#include "lua/lua.hpp"
|
#if defined(__MINGW32__)
|
||||||
|
#include "lua/lua.hpp"
|
||||||
|
#else
|
||||||
|
#include "lua.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
class RoomManager:
|
class RoomManager:
|
||||||
public Singleton<RoomManager>,
|
public Singleton<RoomManager>,
|
||||||
public ManagerInterface<RoomData>
|
public ManagerInterface<RoomData, std::string>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//common public methods
|
//common public methods
|
||||||
int Create() override;
|
int Create(std::string) override;
|
||||||
int Load() override;
|
|
||||||
int Save(int uid) override;
|
|
||||||
void Unload(int uid) override;
|
void Unload(int uid) override;
|
||||||
void Delete(int uid) override;
|
|
||||||
|
|
||||||
void UnloadAll() override;
|
void UnloadAll() override;
|
||||||
void UnloadIf(std::function<bool(std::pair<const int,RoomData>)> fn) override;
|
void UnloadIf(std::function<bool(std::pair<const int,RoomData>&)> fn) override;
|
||||||
|
|
||||||
//accessors and mutators
|
//accessors and mutators
|
||||||
RoomData* Get(int uid) override;
|
RoomData* Get(int uid) override;
|
||||||
@@ -59,8 +60,13 @@ private:
|
|||||||
RoomManager() = default;
|
RoomManager() = default;
|
||||||
~RoomManager() = default;
|
~RoomManager() = default;
|
||||||
|
|
||||||
|
//EMPTY
|
||||||
|
int Load(std::string) override { return -1; }
|
||||||
|
int Save(int uid) override { return -1; }
|
||||||
|
void Delete(int uid) override {}
|
||||||
|
|
||||||
lua_State* lua = nullptr;
|
lua_State* lua = nullptr;
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -21,18 +21,71 @@
|
|||||||
*/
|
*/
|
||||||
#include "room_manager_api.hpp"
|
#include "room_manager_api.hpp"
|
||||||
|
|
||||||
|
#include "room_system_api.hpp"
|
||||||
|
#include "room_api.hpp"
|
||||||
|
|
||||||
#include "room_manager.hpp"
|
#include "room_manager.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
int createRoom(lua_State* L) {
|
int createRoom(lua_State* L) {
|
||||||
|
std::cout << "DEBUG: createRoom-1" << std::endl;
|
||||||
|
|
||||||
//create & get the room
|
//create & get the room
|
||||||
RoomManager& roomMgr = RoomManager::GetSingleton();
|
RoomManager& roomMgr = RoomManager::GetSingleton();
|
||||||
int uid = roomMgr.Create();
|
std::cout << "DEBUG: createRoom-2" << std::endl;
|
||||||
|
int uid = roomMgr.Create(lua_tostring(L, 1));
|
||||||
|
std::cout << "DEBUG: createRoom-3" << std::endl;
|
||||||
RoomData* room = roomMgr.Get(uid);
|
RoomData* room = roomMgr.Get(uid);
|
||||||
|
|
||||||
|
std::cout << "DEBUG: createRoom-4" << std::endl;
|
||||||
|
|
||||||
//setup the room
|
//setup the room
|
||||||
//TODO: room parameters only set via lua, fix this
|
if (lua_gettop(L) > 1) {
|
||||||
room->SetRoomName(lua_tostring(L, 1));
|
//ensure there are the correct number of parameters on the stack, including nil values
|
||||||
room->SetTilesetName(lua_tostring(L, 2));
|
lua_settop(L, 6); //5 parameters, + RoomName
|
||||||
|
|
||||||
|
//get Room::Initialize() onto the top of the stack
|
||||||
|
luaL_requiref(L, TORTUGA_ROOM_SYSTEM_API, openRoomSystemAPI, false);
|
||||||
|
|
||||||
|
lua_pushstring(L, TORTUGA_ROOM_API);
|
||||||
|
lua_gettable(L, -2); //RoomSystem[TORTUGA_ROOM_API]
|
||||||
|
|
||||||
|
lua_pushstring(L, "Initialize");
|
||||||
|
lua_gettable(L, -3); //Room[Initialize]
|
||||||
|
|
||||||
|
//push the room onto the stack
|
||||||
|
lua_pushlightuserdata(L, static_cast<void*>(room));
|
||||||
|
|
||||||
|
//push (copies of) the parameters onto the stack
|
||||||
|
if (lua_type(L, 2) == LUA_TTABLE) {
|
||||||
|
//Unroll the table of parameters
|
||||||
|
for (int i = 1; i <= 5; i++) { //should be 5 members, including nil values
|
||||||
|
lua_rawgeti(L, 2, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//copy the parameters
|
||||||
|
for (int i = 2; i <= 6; i++) { //there are 5 parameters, including nil values, due to the call to lua_settop above
|
||||||
|
lua_pushvalue(L, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//by this point, the stack should look be ready to call Room::Initialize() with 6 parameters, including the room
|
||||||
|
int result = lua_pcall(L, 6, 0, 0);
|
||||||
|
|
||||||
|
if (result != LUA_OK) {
|
||||||
|
//something went wrong
|
||||||
|
std::ostringstream msg;
|
||||||
|
msg << "Failed to initialize a room's parameters in RoomManagerAPI::create(): " << lua_tostring(L, -1);
|
||||||
|
msg << "; Room name: " << lua_tostring(L, 1);
|
||||||
|
throw(std::runtime_error(msg.str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
//wow, that was hard
|
||||||
|
}
|
||||||
|
|
||||||
//return room, uid
|
//return room, uid
|
||||||
lua_pushlightuserdata(L, static_cast<void*>(room));
|
lua_pushlightuserdata(L, static_cast<void*>(room));
|
||||||
@@ -42,19 +95,39 @@ int createRoom(lua_State* L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int unloadRoom(lua_State* L) {
|
int unloadRoom(lua_State* L) {
|
||||||
//TODO: check authorization for room deletion
|
|
||||||
RoomManager& roomMgr = RoomManager::GetSingleton();
|
RoomManager& roomMgr = RoomManager::GetSingleton();
|
||||||
|
|
||||||
|
//NOTE: the pager calls the unload function itself
|
||||||
roomMgr.Unload(lua_tointeger(L, 1));
|
roomMgr.Unload(lua_tointeger(L, 1));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getRoom(lua_State* L) {
|
||||||
|
RoomManager& roomMgr = RoomManager::GetSingleton();
|
||||||
|
|
||||||
|
RoomData* room = roomMgr.Get(lua_tointeger(L, 1));
|
||||||
|
|
||||||
|
if (room) {
|
||||||
|
lua_pushlightuserdata(L, static_cast<void*>(room));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lua_pushnil(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static const luaL_Reg roomManagerLib[] = {
|
static const luaL_Reg roomManagerLib[] = {
|
||||||
{"CreateRoom", createRoom},
|
{"CreateRoom", createRoom},
|
||||||
{"UnloadRoom", unloadRoom},
|
{"UnloadRoom", unloadRoom},
|
||||||
|
{"GetRoom", getRoom},
|
||||||
{nullptr, nullptr}
|
{nullptr, nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
LUAMOD_API int openRoomManagerAPI(lua_State* L) {
|
LUAMOD_API int openRoomManagerAPI(lua_State* L) {
|
||||||
|
std::cout << "DEBUG: openRoomManagerAPI" << std::endl;
|
||||||
|
|
||||||
luaL_newlib(L, roomManagerLib);
|
luaL_newlib(L, roomManagerLib);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,13 @@
|
|||||||
#ifndef ROOMMANAGERAPI_HPP_
|
#ifndef ROOMMANAGERAPI_HPP_
|
||||||
#define ROOMMANAGERAPI_HPP_
|
#define ROOMMANAGERAPI_HPP_
|
||||||
|
|
||||||
#include "lua/lua.hpp"
|
#if defined(__MINGW32__)
|
||||||
|
#include "lua/lua.hpp"
|
||||||
|
#else
|
||||||
|
#include "lua.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define TORTUGA_ROOM_MANAGER_NAME "RoomManager"
|
#define TORTUGA_ROOM_MANAGER_API "room_manager"
|
||||||
LUAMOD_API int openRoomManagerAPI(lua_State* L);
|
LUAMOD_API int openRoomManagerAPI(lua_State* L);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/* 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 "room_system_api.hpp"
|
||||||
|
|
||||||
|
//all room API headers
|
||||||
|
#include "room_api.hpp"
|
||||||
|
#include "room_manager_api.hpp"
|
||||||
|
|
||||||
|
//useful "globals"
|
||||||
|
//...
|
||||||
|
|
||||||
|
//This mimics linit.c to create a nested collection of all room modules.
|
||||||
|
static const luaL_Reg funcs[] = {
|
||||||
|
{nullptr, nullptr}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const luaL_Reg libs[] = {
|
||||||
|
{"Room", openRoomAPI},
|
||||||
|
{"RoomManager", openRoomManagerAPI},
|
||||||
|
{nullptr, nullptr}
|
||||||
|
};
|
||||||
|
|
||||||
|
int openRoomSystemAPI(lua_State* L) {
|
||||||
|
//create the table
|
||||||
|
luaL_newlibtable(L, libs);
|
||||||
|
|
||||||
|
//push the "global" functions
|
||||||
|
luaL_setfuncs(L, funcs, 0);
|
||||||
|
|
||||||
|
//push the substable
|
||||||
|
for (const luaL_Reg* lib = libs; lib->func; lib++) {
|
||||||
|
lib->func(L);
|
||||||
|
lua_setfield(L, -2, lib->name);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
@@ -19,13 +19,16 @@
|
|||||||
* 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 "renderable.hpp"
|
#ifndef ROOMSYSTEMAPI_HPP_
|
||||||
|
#define ROOMSYSTEMAPI_HPP_
|
||||||
|
|
||||||
void Renderable::Update() {
|
#if defined(__MINGW32__)
|
||||||
origin += motion;
|
#include "lua/lua.hpp"
|
||||||
sprite.Update(0.016);
|
#else
|
||||||
}
|
#include "lua.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
void Renderable::DrawTo(SDL_Surface* const dest, int camX, int camY) {
|
#define TORTUGA_ROOM_SYSTEM_API "room_system"
|
||||||
sprite.DrawTo(dest, origin.x - camX, origin.y - camY);
|
LUAMOD_API int openRoomSystemAPI(lua_State* L);
|
||||||
}
|
|
||||||
|
#endif
|
||||||
@@ -22,21 +22,31 @@
|
|||||||
#ifndef SERVERAPPLICATION_HPP_
|
#ifndef SERVERAPPLICATION_HPP_
|
||||||
#define SERVERAPPLICATION_HPP_
|
#define SERVERAPPLICATION_HPP_
|
||||||
|
|
||||||
//server specific stuff, mostly managers
|
//managers
|
||||||
#include "client_data.hpp"
|
|
||||||
#include "account_manager.hpp"
|
#include "account_manager.hpp"
|
||||||
#include "character_manager.hpp"
|
#include "character_manager.hpp"
|
||||||
|
#include "client_manager.hpp"
|
||||||
|
#include "door_manager.hpp"
|
||||||
|
#include "monster_manager.hpp"
|
||||||
#include "room_manager.hpp"
|
#include "room_manager.hpp"
|
||||||
|
|
||||||
//common utilities
|
//utilities
|
||||||
#include "udp_network_utility.hpp"
|
|
||||||
#include "serial_packet.hpp"
|
|
||||||
#include "config_utility.hpp"
|
#include "config_utility.hpp"
|
||||||
|
#include "udp_network_utility.hpp"
|
||||||
|
|
||||||
|
//common utilities
|
||||||
|
#include "serial_packet.hpp"
|
||||||
#include "singleton.hpp"
|
#include "singleton.hpp"
|
||||||
|
|
||||||
//APIs
|
//APIs
|
||||||
#include "lua/lua.hpp"
|
#if defined(__MINGW32__)
|
||||||
#include "sqlite3/sqlite3.h"
|
#include "lua/lua.hpp"
|
||||||
|
#include "sqlite3/sqlite3.h"
|
||||||
|
#else
|
||||||
|
#include "lua.hpp"
|
||||||
|
#include "sqlite3.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "SDL/SDL.h"
|
#include "SDL/SDL.h"
|
||||||
|
|
||||||
//STL
|
//STL
|
||||||
@@ -60,50 +70,61 @@ private:
|
|||||||
//handle incoming traffic
|
//handle incoming traffic
|
||||||
void HandlePacket(SerialPacket* const);
|
void HandlePacket(SerialPacket* const);
|
||||||
|
|
||||||
//basic connections
|
//heartbeat sustem
|
||||||
void HandlePing(ServerPacket* const);
|
void HandlePing(ServerPacket* const);
|
||||||
void HandlePong(ServerPacket* const);
|
void HandlePong(ServerPacket* const);
|
||||||
|
|
||||||
|
//basic connections
|
||||||
void HandleBroadcastRequest(ServerPacket* const);
|
void HandleBroadcastRequest(ServerPacket* const);
|
||||||
void HandleJoinRequest(ClientPacket* const);
|
void HandleJoinRequest(ClientPacket* const);
|
||||||
void HandleDisconnect(ClientPacket* const);
|
void HandleLoginRequest(ClientPacket* const);
|
||||||
void HandleShutdown(ClientPacket* const);
|
|
||||||
|
//client disconnections
|
||||||
|
void HandleLogoutRequest(ClientPacket* const);
|
||||||
|
void HandleDisconnectRequest(ClientPacket* const);
|
||||||
|
|
||||||
|
//server commands
|
||||||
|
// void HandleDisconnectForced(ClientPacket* const);
|
||||||
|
void HandleShutdownRequest(ClientPacket* const);
|
||||||
|
|
||||||
//map management
|
//map management
|
||||||
void HandleRegionRequest(RegionPacket* const);
|
// void HandleRegionRequest(RegionPacket* const);
|
||||||
|
|
||||||
//character management
|
//character management
|
||||||
void HandleCharacterNew(CharacterPacket* const);
|
// void HandleCharacterNew(CharacterPacket* const);
|
||||||
void HandleCharacterDelete(CharacterPacket* const);
|
// void HandleCharacterDelete(CharacterPacket* const);
|
||||||
void HandleCharacterUpdate(CharacterPacket* const);
|
// void HandleCharacterUpdate(CharacterPacket* const);
|
||||||
|
|
||||||
//mismanagement
|
//mismanagement
|
||||||
void HandleSynchronize(ClientPacket* const);
|
// void HandleSynchronize(ClientPacket* const);
|
||||||
|
|
||||||
//utility methods
|
//utility methods
|
||||||
void CheckClientConnections();
|
|
||||||
//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 CleanupLostConnection(int index);
|
// void CleanupLostConnection(int index);
|
||||||
void PumpPacket(SerialPacket* const);
|
// void PumpPacket(SerialPacket* const);
|
||||||
void PumpCharacterUnload(int uid);
|
// void PumpCharacterUnload(int uid);
|
||||||
void CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex);
|
// void CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex);
|
||||||
|
|
||||||
|
//data management
|
||||||
|
void SaveServerState();
|
||||||
|
|
||||||
//APIs and utilities
|
//APIs and utilities
|
||||||
sqlite3* database = nullptr;
|
sqlite3* database = nullptr;
|
||||||
lua_State* luaState = nullptr;
|
lua_State* luaState = nullptr;
|
||||||
UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton();
|
|
||||||
ConfigUtility& config = ConfigUtility::GetSingleton();
|
|
||||||
|
|
||||||
//simple tables
|
//ugly references; I hate this
|
||||||
std::map<int, ClientData> clientMap;
|
|
||||||
|
|
||||||
//managers
|
|
||||||
AccountManager& accountMgr = AccountManager::GetSingleton();
|
AccountManager& accountMgr = AccountManager::GetSingleton();
|
||||||
CharacterManager& characterMgr = CharacterManager::GetSingleton();
|
CharacterManager& characterMgr = CharacterManager::GetSingleton();
|
||||||
|
ClientManager& clientMgr = ClientManager::GetSingleton();
|
||||||
|
DoorManager& doorMgr = DoorManager::GetSingleton();
|
||||||
|
MonsterManager& monsterMgr = MonsterManager::GetSingleton();
|
||||||
RoomManager& roomMgr = RoomManager::GetSingleton();
|
RoomManager& roomMgr = RoomManager::GetSingleton();
|
||||||
|
|
||||||
|
ConfigUtility& config = ConfigUtility::GetSingleton();
|
||||||
|
UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton();
|
||||||
|
|
||||||
//misc
|
//misc
|
||||||
bool running = true;
|
bool running = true;
|
||||||
int clientIndex = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+91
-34
@@ -25,6 +25,7 @@
|
|||||||
#include "sql_tools.hpp"
|
#include "sql_tools.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
|
//std & STL
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -35,12 +36,14 @@
|
|||||||
//public methods
|
//public methods
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
|
//BUG: #35 The server fails without at least one room
|
||||||
|
|
||||||
void ServerApplication::Init(int argc, char* argv[]) {
|
void ServerApplication::Init(int argc, char* argv[]) {
|
||||||
//NOTE: I might need to rearrange the init process so that lua & SQL can interact with the map system as needed.
|
//NOTE: I might need to rearrange the init process so that lua & SQL can interact with the map system as needed.
|
||||||
std::cout << "Beginning " << argv[0] << std::endl;
|
std::cout << "Beginning " << argv[0] << std::endl;
|
||||||
|
|
||||||
//load the prerequisites
|
//load the config settings
|
||||||
config.Load("rsc\\config.cfg", argc, argv);
|
config.Load("rsc/config.cfg", argc, argv);
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//Initialize the APIs
|
//Initialize the APIs
|
||||||
@@ -75,7 +78,7 @@ void ServerApplication::Init(int argc, char* argv[]) {
|
|||||||
|
|
||||||
std::cout << "Initialized lua" << std::endl;
|
std::cout << "Initialized lua" << std::endl;
|
||||||
|
|
||||||
//append config["dir.scripts"] to the module path
|
//prepend config["dir.scripts"] to the module path
|
||||||
if (config["dir.scripts"].size() > 0) {
|
if (config["dir.scripts"].size() > 0) {
|
||||||
//get the original path
|
//get the original path
|
||||||
lua_getglobal(luaState, "package");
|
lua_getglobal(luaState, "package");
|
||||||
@@ -162,14 +165,31 @@ void ServerApplication::Proc() {
|
|||||||
SerialPacket* packetBuffer = reinterpret_cast<SerialPacket*>(new char[MAX_PACKET_SIZE]);
|
SerialPacket* packetBuffer = reinterpret_cast<SerialPacket*>(new char[MAX_PACKET_SIZE]);
|
||||||
while(running) {
|
while(running) {
|
||||||
//suck in the waiting packets & process them
|
//suck in the waiting packets & process them
|
||||||
while(network.Receive(packetBuffer)) {
|
while(UDPNetworkUtility::GetSingleton().Receive(packetBuffer)) {
|
||||||
HandlePacket(packetBuffer);
|
HandlePacket(packetBuffer);
|
||||||
}
|
}
|
||||||
//update the internals
|
//update the internals
|
||||||
//...
|
//...
|
||||||
|
|
||||||
//Check connections
|
//Check connections
|
||||||
CheckClientConnections();
|
int disconnected = clientMgr.CheckConnections();
|
||||||
|
if (disconnected != -1) {
|
||||||
|
//find and unload the accounts associated with this client
|
||||||
|
accountMgr.UnloadIf([&](std::pair<const int, AccountData>& account) -> bool {
|
||||||
|
if (account.second.GetClientIndex() == disconnected) {
|
||||||
|
//find and unload the characters associated with this account
|
||||||
|
characterMgr.UnloadIf([&](std::pair<const int, CharacterData>& character) -> bool {
|
||||||
|
if (character.second.GetOwner() == account.first) {
|
||||||
|
// PumpCharacterUnload(character.first);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
//give the computer a break
|
//give the computer a break
|
||||||
SDL_Delay(10);
|
SDL_Delay(10);
|
||||||
@@ -180,12 +200,14 @@ void ServerApplication::Proc() {
|
|||||||
void ServerApplication::Quit() {
|
void ServerApplication::Quit() {
|
||||||
std::cout << "Shutting down" << std::endl;
|
std::cout << "Shutting down" << std::endl;
|
||||||
|
|
||||||
|
//TODO: save the server state
|
||||||
|
|
||||||
//close the managers
|
//close the managers
|
||||||
clientMap.clear();
|
|
||||||
accountMgr.UnloadAll();
|
accountMgr.UnloadAll();
|
||||||
characterMgr.UnloadAll();
|
characterMgr.UnloadAll();
|
||||||
//TODO: unload combats
|
clientMgr.UnloadAll();
|
||||||
//TODO: unload enemies
|
doorMgr.UnloadAll();
|
||||||
|
monsterMgr.UnloadAll();
|
||||||
roomMgr.UnloadAll();
|
roomMgr.UnloadAll();
|
||||||
|
|
||||||
//APIs
|
//APIs
|
||||||
@@ -204,60 +226,95 @@ void ServerApplication::Quit() {
|
|||||||
|
|
||||||
void ServerApplication::HandlePacket(SerialPacket* const argPacket) {
|
void ServerApplication::HandlePacket(SerialPacket* const argPacket) {
|
||||||
switch(argPacket->type) {
|
switch(argPacket->type) {
|
||||||
//basic connections
|
//heartbeat system
|
||||||
case SerialPacketType::PING:
|
case SerialPacketType::PING:
|
||||||
HandlePing(static_cast<ServerPacket*>(argPacket));
|
HandlePing(static_cast<ServerPacket*>(argPacket));
|
||||||
break;
|
break;
|
||||||
case SerialPacketType::PONG:
|
case SerialPacketType::PONG:
|
||||||
HandlePong(static_cast<ServerPacket*>(argPacket));
|
HandlePong(static_cast<ServerPacket*>(argPacket));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
//client connections
|
||||||
case SerialPacketType::BROADCAST_REQUEST:
|
case SerialPacketType::BROADCAST_REQUEST:
|
||||||
HandleBroadcastRequest(static_cast<ServerPacket*>(argPacket));
|
HandleBroadcastRequest(static_cast<ServerPacket*>(argPacket));
|
||||||
break;
|
break;
|
||||||
case SerialPacketType::JOIN_REQUEST:
|
case SerialPacketType::JOIN_REQUEST:
|
||||||
HandleJoinRequest(static_cast<ClientPacket*>(argPacket));
|
HandleJoinRequest(static_cast<ClientPacket*>(argPacket));
|
||||||
break;
|
break;
|
||||||
case SerialPacketType::DISCONNECT:
|
case SerialPacketType::LOGIN_REQUEST:
|
||||||
HandleDisconnect(static_cast<ClientPacket*>(argPacket));
|
HandleLoginRequest(static_cast<ClientPacket*>(argPacket));
|
||||||
break;
|
|
||||||
case SerialPacketType::SHUTDOWN:
|
|
||||||
HandleShutdown(static_cast<ClientPacket*>(argPacket));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//map management
|
//client disconnections
|
||||||
|
case SerialPacketType::LOGOUT_REQUEST:
|
||||||
|
HandleLogoutRequest(static_cast<ClientPacket*>(argPacket));
|
||||||
|
break;
|
||||||
|
case SerialPacketType::DISCONNECT_REQUEST:
|
||||||
|
HandleDisconnectRequest(static_cast<ClientPacket*>(argPacket));
|
||||||
|
break;
|
||||||
|
|
||||||
|
//server commands
|
||||||
|
case SerialPacketType::DISCONNECT_FORCED:
|
||||||
|
// HandleDisconnectForced(static_cast<ClientPacket*>(argPacket));
|
||||||
|
break;
|
||||||
|
case SerialPacketType::SHUTDOWN_REQUEST:
|
||||||
|
HandleShutdownRequest(static_cast<ClientPacket*>(argPacket));
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
//data management & queries
|
||||||
case SerialPacketType::REGION_REQUEST:
|
case SerialPacketType::REGION_REQUEST:
|
||||||
HandleRegionRequest(static_cast<RegionPacket*>(argPacket));
|
// HandleRegionRequest(static_cast<RegionPacket*>(argPacket));
|
||||||
|
break;
|
||||||
|
case SerialPacketType::QUERY_CHARACTER_EXISTS:
|
||||||
|
// HandleCharacterStatsRequest(static_cast<RegionPacket*>(argPacket));
|
||||||
|
break;
|
||||||
|
case SerialPacketType::QUERY_CHARACTER_STATS:
|
||||||
|
// HandleCharacterStatsRequest(static_cast<RegionPacket*>(argPacket));
|
||||||
|
break;
|
||||||
|
case SerialPacketType::QUERY_CHARACTER_LOCATION:
|
||||||
|
// HandleCharacterStatsRequest(static_cast<RegionPacket*>(argPacket));
|
||||||
|
break;
|
||||||
|
case SerialPacketType::TEXT_BROADCAST:
|
||||||
|
// HandleCharacterStatsRequest(static_cast<RegionPacket*>(argPacket));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//combat management
|
|
||||||
//TODO: combat management
|
|
||||||
|
|
||||||
//character management
|
//character management
|
||||||
case SerialPacketType::CHARACTER_NEW:
|
case SerialPacketType::CHARACTER_CREATE:
|
||||||
HandleCharacterNew(static_cast<CharacterPacket*>(argPacket));
|
// HandleCharacterNew(static_cast<CharacterPacket*>(argPacket));
|
||||||
break;
|
break;
|
||||||
case SerialPacketType::CHARACTER_DELETE:
|
case SerialPacketType::CHARACTER_DELETE:
|
||||||
HandleCharacterDelete(static_cast<CharacterPacket*>(argPacket));
|
// HandleCharacterDelete(static_cast<CharacterPacket*>(argPacket));
|
||||||
break;
|
break;
|
||||||
case SerialPacketType::CHARACTER_UPDATE:
|
case SerialPacketType::CHARACTER_LOAD:
|
||||||
case SerialPacketType::CHARACTER_STATS_REQUEST:
|
// HandleCharacterNew(static_cast<CharacterPacket*>(argPacket));
|
||||||
HandleCharacterUpdate(static_cast<CharacterPacket*>(argPacket));
|
break;
|
||||||
|
case SerialPacketType::CHARACTER_UNLOAD:
|
||||||
|
// HandleCharacterDelete(static_cast<CharacterPacket*>(argPacket));
|
||||||
|
break;
|
||||||
|
|
||||||
|
//character movement
|
||||||
|
case SerialPacketType::CHARACTER_SET_ROOM:
|
||||||
|
// HandleCharacterUpdate(static_cast<CharacterPacket*>(argPacket));
|
||||||
|
break;
|
||||||
|
case SerialPacketType::CHARACTER_SET_ORIGIN:
|
||||||
|
// HandleCharacterUpdate(static_cast<CharacterPacket*>(argPacket));
|
||||||
|
break;
|
||||||
|
case SerialPacketType::CHARACTER_SET_MOTION:
|
||||||
|
// HandleCharacterUpdate(static_cast<CharacterPacket*>(argPacket));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//enemy management
|
//enemy management
|
||||||
//TODO: enemy management
|
//TODO: enemy management
|
||||||
|
|
||||||
//mismanagement
|
//TODO: text
|
||||||
case SerialPacketType::SYNCHRONIZE:
|
*/
|
||||||
HandleSynchronize(static_cast<ClientPacket*>(argPacket));
|
|
||||||
break;
|
|
||||||
|
|
||||||
//handle errors
|
//handle errors
|
||||||
default: {
|
default: {
|
||||||
std::string msg = "Unknown SerialPacketType encountered in the server: ";
|
std::ostringstream msg;
|
||||||
msg += to_string_custom(static_cast<int>(argPacket->type));
|
msg << "Unknown SerialPacketType encountered in the server: ";
|
||||||
throw(std::runtime_error(msg));
|
msg << to_string_custom(static_cast<int>(argPacket->type));
|
||||||
|
throw(std::runtime_error(msg.str()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+174
-102
@@ -23,9 +23,22 @@
|
|||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//basic connections
|
//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);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//heartbeat system
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
void ServerApplication::HandlePing(ServerPacket* const argPacket) {
|
void ServerApplication::HandlePing(ServerPacket* const argPacket) {
|
||||||
@@ -35,17 +48,13 @@ void ServerApplication::HandlePing(ServerPacket* const argPacket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ServerApplication::HandlePong(ServerPacket* const argPacket) {
|
void ServerApplication::HandlePong(ServerPacket* const argPacket) {
|
||||||
//find and update the specified client
|
clientMgr.HandlePong(argPacket);
|
||||||
for (auto& it : clientMap) {
|
|
||||||
if (it.second.GetAddress().host == argPacket->srcAddress.host &&
|
|
||||||
it.second.GetAddress().port == argPacket->srcAddress.port
|
|
||||||
) {
|
|
||||||
it.second.ResetAttempts();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//basic connections
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
void ServerApplication::HandleBroadcastRequest(ServerPacket* const argPacket) {
|
void ServerApplication::HandleBroadcastRequest(ServerPacket* const argPacket) {
|
||||||
//send the server's data
|
//send the server's data
|
||||||
ServerPacket newPacket;
|
ServerPacket newPacket;
|
||||||
@@ -59,99 +68,170 @@ void ServerApplication::HandleBroadcastRequest(ServerPacket* const argPacket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) {
|
void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) {
|
||||||
//load the user account
|
//register the client
|
||||||
//TODO: handle passwords
|
int clientIndex = clientMgr.Create(argPacket->srcAddress);
|
||||||
int accountIndex = accountMgr.Load(argPacket->username, clientIndex);
|
|
||||||
|
|
||||||
//Cannot load
|
|
||||||
if (accountIndex < 0) {
|
|
||||||
TextPacket newPacket;
|
|
||||||
newPacket.type = SerialPacketType::JOIN_REJECTION;
|
|
||||||
std::string msg = std::string() + "Account already loaded: " + argPacket->username;
|
|
||||||
memset(newPacket.name, 0, PACKET_STRING_SIZE);
|
|
||||||
strncpy(newPacket.text, msg.c_str(), PACKET_STRING_SIZE); //BUG: If the name is too long this would truncate it
|
|
||||||
network.SendTo(argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//send the client their info
|
//send the client their info
|
||||||
ClientPacket newPacket;
|
ClientPacket newPacket;
|
||||||
newPacket.type = SerialPacketType::JOIN_RESPONSE;
|
newPacket.type = SerialPacketType::JOIN_RESPONSE;
|
||||||
newPacket.clientIndex = clientIndex;
|
newPacket.clientIndex = clientIndex;
|
||||||
newPacket.accountIndex = accountIndex;
|
|
||||||
|
|
||||||
network.SendTo(argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket));
|
network.SendTo(argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket));
|
||||||
|
|
||||||
//register the client
|
|
||||||
ClientData newClient;
|
|
||||||
newClient.SetAddress(argPacket->srcAddress);
|
|
||||||
clientMap[clientIndex++] = newClient;
|
|
||||||
|
|
||||||
//finished this routine
|
//finished this routine
|
||||||
std::cout << "New connection, " << clientMap.size() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl;
|
std::cout << "New join, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerApplication::HandleDisconnect(ClientPacket* const argPacket) {
|
void ServerApplication::HandleLoginRequest(ClientPacket* const argPacket) {
|
||||||
//TODO: authenticate who is disconnecting/kicking
|
//get the client data
|
||||||
/*Pseudocode:
|
ClientData* clientData = clientMgr.Get(argPacket->clientIndex);
|
||||||
if sender's account index -> client index -> address == sender's address then
|
|
||||||
continue
|
|
||||||
end
|
|
||||||
if sender's account index -> admin == true OR sender's account index -> mod == true then
|
|
||||||
continue
|
|
||||||
end
|
|
||||||
if neither of the above is true, then output a warning to the console, and return
|
|
||||||
*/
|
|
||||||
|
|
||||||
//forward to the specified client
|
if (clientData == nullptr || clientData->GetAddress() != argPacket->srcAddress) {
|
||||||
network.SendTo(
|
std::cerr << "Falsified client index detected: " << argPacket->clientIndex << std::endl;
|
||||||
clientMap[ accountMgr.Get(argPacket->accountIndex)->GetClientIndex() ].GetAddress(),
|
//TODO: rejection message?
|
||||||
static_cast<SerialPacket*>(argPacket)
|
return;
|
||||||
);
|
}
|
||||||
|
|
||||||
//save and unload this account's characters
|
//load the user account
|
||||||
characterMgr.UnloadIf([&](std::pair<int, CharacterData> it) -> bool {
|
int accountIndex = accountMgr.Load(argPacket->username, argPacket->clientIndex);
|
||||||
|
|
||||||
|
//Cannot load
|
||||||
|
if (accountIndex < 0) {
|
||||||
|
std::ostringstream msg;
|
||||||
|
msg << "Account already loaded: " << argPacket->username;
|
||||||
|
|
||||||
|
TextPacket newPacket;
|
||||||
|
newPacket.type = SerialPacketType::LOGIN_REJECTION;
|
||||||
|
// memset(newPacket.name, 0, PACKET_STRING_SIZE);
|
||||||
|
strncpy(newPacket.text, msg.str().c_str(), PACKET_STRING_SIZE);
|
||||||
|
network.SendTo(clientData->GetAddress(), static_cast<SerialPacket*>(&newPacket));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//send the client their info
|
||||||
|
ClientPacket newPacket;
|
||||||
|
newPacket.type = SerialPacketType::LOGIN_RESPONSE;
|
||||||
|
newPacket.clientIndex = argPacket->clientIndex;
|
||||||
|
newPacket.accountIndex = accountIndex;
|
||||||
|
|
||||||
|
network.SendTo(clientData->GetAddress(), static_cast<SerialPacket*>(&newPacket));
|
||||||
|
|
||||||
|
//finished this routine
|
||||||
|
std::cout << "New login, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerApplication::HandleLogoutRequest(ClientPacket* const argPacket) {
|
||||||
|
//get the account and client data
|
||||||
|
AccountData* accountData = accountMgr.Get(argPacket->accountIndex);
|
||||||
|
ClientData* clientData = clientMgr.Get(accountData->GetClientIndex());
|
||||||
|
|
||||||
|
if (clientData->GetAddress() != argPacket->srcAddress) {
|
||||||
|
std::cerr << "Falsified logout detected targeting: " << accountData->GetUsername() << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//send the logout response
|
||||||
|
ClientPacket newPacket;
|
||||||
|
newPacket.type = SerialPacketType::LOGOUT_RESPONSE;
|
||||||
|
newPacket.clientIndex = accountData->GetClientIndex();
|
||||||
|
newPacket.accountIndex = argPacket->accountIndex;
|
||||||
|
|
||||||
|
network.SendTo(clientData->GetAddress(), static_cast<SerialPacket*>(&newPacket));
|
||||||
|
|
||||||
|
//save and unload this accounts characters
|
||||||
|
characterMgr.UnloadIf([&](std::pair<const int, CharacterData>& it) -> bool {
|
||||||
if (argPacket->accountIndex == it.second.GetOwner()) {
|
if (argPacket->accountIndex == it.second.GetOwner()) {
|
||||||
//pump the unload message to all remaining clients
|
//pump the unload message to all remaining clients
|
||||||
PumpCharacterUnload(it.first);
|
// PumpCharacterUnload(it.first);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
//erase the in-memory stuff
|
//unload this account
|
||||||
clientMap.erase(accountMgr.Get(argPacket->accountIndex)->GetClientIndex());
|
|
||||||
accountMgr.Unload(argPacket->accountIndex);
|
accountMgr.Unload(argPacket->accountIndex);
|
||||||
|
|
||||||
//finished this routine
|
//finished this routine
|
||||||
std::cout << "Disconnection, " << clientMap.size() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl;
|
std::cout << "New logout, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerApplication::HandleShutdown(ClientPacket* const argPacket) {
|
void ServerApplication::HandleDisconnectRequest(ClientPacket* const argPacket) {
|
||||||
//TODO: authenticate who is shutting the server down
|
//get the client data
|
||||||
/*Pseudocode:
|
ClientData* clientData = clientMgr.Get(argPacket->clientIndex);
|
||||||
if sender's account -> admin is not true then
|
|
||||||
print a warning
|
if (clientData->GetAddress() != argPacket->srcAddress) {
|
||||||
return
|
std::cerr << "Falsified disconnection detected targeting: " << argPacket->clientIndex << std::endl;
|
||||||
end
|
return;
|
||||||
*/
|
}
|
||||||
|
|
||||||
|
//send the disconnect response
|
||||||
|
ClientPacket newPacket;
|
||||||
|
newPacket.type = SerialPacketType::DISCONNECT_RESPONSE;
|
||||||
|
newPacket.clientIndex = argPacket->clientIndex;
|
||||||
|
|
||||||
|
network.SendTo(clientData->GetAddress(), static_cast<SerialPacket*>(&newPacket));
|
||||||
|
|
||||||
|
//TODO: need a method for this redundunt chunk of redundant code
|
||||||
|
//find and unload the accounts associated with this client
|
||||||
|
accountMgr.UnloadIf([&](std::pair<const int, AccountData>& account) -> bool {
|
||||||
|
if (account.second.GetClientIndex() == argPacket->clientIndex) {
|
||||||
|
//find and unload the characters associated with this account
|
||||||
|
characterMgr.UnloadIf([&](std::pair<const int, CharacterData>& character) -> bool {
|
||||||
|
if (character.second.GetOwner() == account.first) {
|
||||||
|
// PumpCharacterUnload(character.first);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
//unload this client
|
||||||
|
clientMgr.Unload(argPacket->clientIndex);
|
||||||
|
|
||||||
|
//finished this routine
|
||||||
|
std::cout << "New disconnection, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//server commands
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
//void ServerApplication::HandleDisconnectForced(ClientPacket* const argPacket) {
|
||||||
|
// //TODO
|
||||||
|
//}
|
||||||
|
|
||||||
|
void ServerApplication::HandleShutdownRequest(ClientPacket* const argPacket) {
|
||||||
|
//get the account and client data
|
||||||
|
AccountData* accountData = accountMgr.Get(argPacket->accountIndex);
|
||||||
|
ClientData* clientData = clientMgr.Get(accountData->GetClientIndex());
|
||||||
|
|
||||||
|
if (clientData->GetAddress() != argPacket->srcAddress || accountData->GetAdministrator() != true) {
|
||||||
|
std::cerr << "Falsified server shutdown detected from: " << accountData->GetUsername() << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//end the server
|
//end the server
|
||||||
running = false;
|
running = false;
|
||||||
|
|
||||||
//disconnect all clients
|
//disconnect all clients
|
||||||
ClientPacket newPacket;
|
// ClientPacket newPacket;
|
||||||
newPacket.type = SerialPacketType::DISCONNECT;
|
// newPacket.type = SerialPacketType::DISCONNECT_FORCED;
|
||||||
PumpPacket(&newPacket);
|
// PumpPacket(&newPacket);
|
||||||
|
|
||||||
//finished this routine
|
//finished this routine
|
||||||
std::cout << "Shutdown signal accepted" << std::endl;
|
std::cout << "Shutdown signal accepted" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//map management
|
//map management
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
|
//SET: resources
|
||||||
void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) {
|
void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) {
|
||||||
RegionPacket newPacket;
|
RegionPacket newPacket;
|
||||||
|
|
||||||
@@ -171,6 +251,7 @@ void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) {
|
|||||||
//Character Management
|
//Character Management
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
|
//SET: entities
|
||||||
void ServerApplication::HandleCharacterNew(CharacterPacket* const argPacket) {
|
void ServerApplication::HandleCharacterNew(CharacterPacket* const argPacket) {
|
||||||
//NOTE: misnomer, try to load the character first
|
//NOTE: misnomer, try to load the character first
|
||||||
int characterIndex = characterMgr.Load(argPacket->accountIndex, argPacket->handle, argPacket->avatar);
|
int characterIndex = characterMgr.Load(argPacket->accountIndex, argPacket->handle, argPacket->avatar);
|
||||||
@@ -178,31 +259,32 @@ void ServerApplication::HandleCharacterNew(CharacterPacket* const argPacket) {
|
|||||||
//cannot load or create
|
//cannot load or create
|
||||||
if (characterIndex < 0) {
|
if (characterIndex < 0) {
|
||||||
//build the error message
|
//build the error message
|
||||||
std::string msg;
|
std::ostringstream msg;
|
||||||
if (characterIndex == -1) {
|
if (characterIndex == -1) {
|
||||||
msg += "Character already loaded: ";
|
msg << "Character already loaded: ";
|
||||||
}
|
}
|
||||||
else if (characterIndex == -2) {
|
else if (characterIndex == -2) {
|
||||||
msg += "Character already exists: ";
|
msg << "Character already exists: ";
|
||||||
}
|
}
|
||||||
msg += argPacket->handle;
|
msg << argPacket->handle;
|
||||||
|
|
||||||
//create, fill and send the packet
|
//create, fill and send the packet
|
||||||
TextPacket newPacket;
|
TextPacket newPacket;
|
||||||
newPacket.type = SerialPacketType::CHARACTER_REJECTION;
|
newPacket.type = SerialPacketType::CHARACTER_REJECTION;
|
||||||
memset(newPacket.name, 0, PACKET_STRING_SIZE);
|
memset(newPacket.name, 0, PACKET_STRING_SIZE);
|
||||||
strncpy(newPacket.text, msg.c_str(), PACKET_STRING_SIZE);
|
strncpy(newPacket.text, msg.str().c_str(), PACKET_STRING_SIZE);
|
||||||
network.SendTo(argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket));
|
network.SendTo(argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//send this new character to all clients
|
//send this new character to all clients
|
||||||
CharacterPacket newPacket;
|
CharacterPacket newPacket;
|
||||||
newPacket.type = SerialPacketType::CHARACTER_NEW;
|
newPacket.type = SerialPacketType::CHARACTER_CREATE;
|
||||||
CopyCharacterToPacket(&newPacket, characterIndex);
|
CopyCharacterToPacket(&newPacket, characterIndex);
|
||||||
PumpPacket(&newPacket);
|
PumpPacket(&newPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//SET: entities
|
||||||
void ServerApplication::HandleCharacterDelete(CharacterPacket* const argPacket) {
|
void ServerApplication::HandleCharacterDelete(CharacterPacket* const argPacket) {
|
||||||
//NOTE: Disconnecting only unloads a character, this explicitly deletes it
|
//NOTE: Disconnecting only unloads a character, this explicitly deletes it
|
||||||
|
|
||||||
@@ -234,6 +316,7 @@ void ServerApplication::HandleCharacterDelete(CharacterPacket* const argPacket)
|
|||||||
PumpCharacterUnload(characterIndex);
|
PumpCharacterUnload(characterIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//SET: entities
|
||||||
void ServerApplication::HandleCharacterUpdate(CharacterPacket* const argPacket) {
|
void ServerApplication::HandleCharacterUpdate(CharacterPacket* const argPacket) {
|
||||||
CharacterData* character = characterMgr.Get(argPacket->characterIndex);
|
CharacterData* character = characterMgr.Get(argPacket->characterIndex);
|
||||||
|
|
||||||
@@ -248,8 +331,6 @@ void ServerApplication::HandleCharacterUpdate(CharacterPacket* const argPacket)
|
|||||||
character->SetOrigin(argPacket->origin);
|
character->SetOrigin(argPacket->origin);
|
||||||
character->SetMotion(argPacket->motion);
|
character->SetMotion(argPacket->motion);
|
||||||
|
|
||||||
*character->GetBaseStats() = argPacket->stats;
|
|
||||||
|
|
||||||
//TODO: gameplay components: equipment, items, buffs, debuffs
|
//TODO: gameplay components: equipment, items, buffs, debuffs
|
||||||
|
|
||||||
PumpPacket(argPacket);
|
PumpPacket(argPacket);
|
||||||
@@ -259,20 +340,21 @@ void ServerApplication::HandleCharacterUpdate(CharacterPacket* const argPacket)
|
|||||||
//mismanagement
|
//mismanagement
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
|
//SET: delete
|
||||||
void ServerApplication::HandleSynchronize(ClientPacket* const argPacket) {
|
void ServerApplication::HandleSynchronize(ClientPacket* const argPacket) {
|
||||||
//TODO: compensate for large distances
|
//TODO: compensate for large distances
|
||||||
//NOTE: I quite dislike this function
|
//NOTE: I quite dislike this function
|
||||||
|
|
||||||
//send all of the server's data to this client
|
//send all of the server's data to this client
|
||||||
ClientData& client = clientMap[argPacket->clientIndex];
|
ClientData* client = clientMgr.Get(argPacket->clientIndex);
|
||||||
|
|
||||||
//send all characters
|
//send all characters
|
||||||
CharacterPacket newPacket;
|
CharacterPacket newPacket;
|
||||||
newPacket.type = SerialPacketType::CHARACTER_UPDATE;
|
newPacket.type = SerialPacketType::CHARACTER_SET_ORIGIN;
|
||||||
|
|
||||||
for (auto& it : *characterMgr.GetContainer()) {
|
for (auto& it : *characterMgr.GetContainer()) {
|
||||||
CopyCharacterToPacket(&newPacket, it.first);
|
CopyCharacterToPacket(&newPacket, it.first);
|
||||||
network.SendTo(client.GetAddress(), static_cast<SerialPacket*>(&newPacket));
|
network.SendTo(client->GetAddress(), static_cast<SerialPacket*>(&newPacket));
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: more in HandleSynchronize()
|
//TODO: more in HandleSynchronize()
|
||||||
@@ -282,27 +364,16 @@ void ServerApplication::HandleSynchronize(ClientPacket* const argPacket) {
|
|||||||
//utility methods
|
//utility methods
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
void ServerApplication::CheckClientConnections() {
|
//SET: utility/manager
|
||||||
for (auto& it : clientMap) {
|
|
||||||
if (std::chrono::steady_clock::now() - it.second.GetLastBeat() > std::chrono::seconds(3)) {
|
|
||||||
ServerPacket newPacket;
|
|
||||||
newPacket.type = SerialPacketType::PING;
|
|
||||||
network.SendTo(it.second.GetAddress(), &newPacket);
|
|
||||||
it.second.IncrementAttempts();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (it.second.GetAttempts() > 2) {
|
|
||||||
CleanupLostConnection(it.first);
|
|
||||||
//all iterators are invalid, so we can't continue
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerApplication::CleanupLostConnection(int clientIndex) {
|
void ServerApplication::CleanupLostConnection(int clientIndex) {
|
||||||
//NOTE: This assumes each player has only one account and character at a time
|
//NOTE: This assumes each player has only one account and character at a time
|
||||||
//TODO: handle multiple characters (bots, etc.)
|
//TODO: handle multiple characters (bots, etc.)
|
||||||
|
|
||||||
|
//send a disconnection message just in case
|
||||||
|
ClientPacket newPacket;
|
||||||
|
newPacket.type = SerialPacketType::DISCONNECT_FORCED;
|
||||||
|
network.SendTo(clientMgr.Get(clientIndex)->GetAddress(), &newPacket);
|
||||||
|
|
||||||
//find the account
|
//find the account
|
||||||
int accountIndex = -1;
|
int accountIndex = -1;
|
||||||
for (auto& it : *accountMgr.GetContainer()) {
|
for (auto& it : *accountMgr.GetContainer()) {
|
||||||
@@ -321,15 +392,10 @@ void ServerApplication::CleanupLostConnection(int clientIndex) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//send a disconnection message just in case
|
|
||||||
ClientPacket newPacket;
|
|
||||||
newPacket.type = SerialPacketType::DISCONNECT;
|
|
||||||
network.SendTo(clientMap[clientIndex].GetAddress(), &newPacket);
|
|
||||||
|
|
||||||
//clean up this mess
|
//clean up this mess
|
||||||
characterMgr.Unload(characterIndex);
|
characterMgr.Unload(characterIndex);
|
||||||
accountMgr.Unload(accountIndex);
|
accountMgr.Unload(accountIndex);
|
||||||
clientMap.erase(clientIndex);
|
clientMgr.Unload(clientIndex);
|
||||||
|
|
||||||
PumpCharacterUnload(characterIndex);
|
PumpCharacterUnload(characterIndex);
|
||||||
|
|
||||||
@@ -338,17 +404,20 @@ void ServerApplication::CleanupLostConnection(int clientIndex) {
|
|||||||
std::cerr << "\tClient: " << clientIndex << std::endl;
|
std::cerr << "\tClient: " << clientIndex << std::endl;
|
||||||
std::cerr << "\tAccount: " << accountIndex << std::endl;
|
std::cerr << "\tAccount: " << accountIndex << std::endl;
|
||||||
std::cerr << "\tCharacter: " << characterIndex << std::endl;
|
std::cerr << "\tCharacter: " << characterIndex << std::endl;
|
||||||
std::cout << clientMap.size() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl;
|
std::cout << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//SET: utility
|
||||||
//TODO: a function that only sends to characters in a certain proximity
|
//TODO: a function that only sends to characters in a certain proximity
|
||||||
|
|
||||||
|
//SET: utility
|
||||||
void ServerApplication::PumpPacket(SerialPacket* const argPacket) {
|
void ServerApplication::PumpPacket(SerialPacket* const argPacket) {
|
||||||
for (auto& it : clientMap) {
|
for (auto& it : *clientMgr.GetContainer()) {
|
||||||
network.SendTo(it.second.GetAddress(), argPacket);
|
network.SendTo(it.second.GetAddress(), argPacket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//SET: utility/delete
|
||||||
void ServerApplication::PumpCharacterUnload(int uid) {
|
void ServerApplication::PumpCharacterUnload(int uid) {
|
||||||
//delete the client-side character(s)
|
//delete the client-side character(s)
|
||||||
//NOTE: This is a strange function
|
//NOTE: This is a strange function
|
||||||
@@ -358,6 +427,7 @@ void ServerApplication::PumpCharacterUnload(int uid) {
|
|||||||
PumpPacket(static_cast<SerialPacket*>(&newPacket));
|
PumpPacket(static_cast<SerialPacket*>(&newPacket));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//SET: utility/delete
|
||||||
void ServerApplication::CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex) {
|
void ServerApplication::CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex) {
|
||||||
CharacterData* character = characterMgr.Get(characterIndex);
|
CharacterData* character = characterMgr.Get(characterIndex);
|
||||||
if (!character) {
|
if (!character) {
|
||||||
@@ -372,5 +442,7 @@ void ServerApplication::CopyCharacterToPacket(CharacterPacket* const packet, int
|
|||||||
packet->roomIndex = character->GetRoomIndex();
|
packet->roomIndex = character->GetRoomIndex();
|
||||||
packet->origin = character->GetOrigin();
|
packet->origin = character->GetOrigin();
|
||||||
packet->motion = character->GetMotion();
|
packet->motion = character->GetMotion();
|
||||||
packet->stats = *character->GetBaseStats();
|
}
|
||||||
}
|
|
||||||
|
//TODO: remove this terminate comment
|
||||||
|
//*/
|
||||||
@@ -36,7 +36,7 @@ public:
|
|||||||
virtual void Delete(int uid) = 0;
|
virtual void Delete(int uid) = 0;
|
||||||
|
|
||||||
virtual void UnloadAll() = 0;
|
virtual void UnloadAll() = 0;
|
||||||
virtual void UnloadIf(std::function<bool(std::pair<const int, T>)> fn) = 0;
|
virtual void UnloadIf(std::function<bool(std::pair<const int, T>&)> fn) = 0;
|
||||||
|
|
||||||
//accessors & mutators
|
//accessors & mutators
|
||||||
virtual T* Get(int uid) = 0;
|
virtual T* Get(int uid) = 0;
|
||||||
|
|||||||
@@ -22,7 +22,11 @@
|
|||||||
#ifndef SERVERUTILITY_HPP_
|
#ifndef SERVERUTILITY_HPP_
|
||||||
#define SERVERUTILITY_HPP_
|
#define SERVERUTILITY_HPP_
|
||||||
|
|
||||||
#include "sqlite3/sqlite3.h"
|
#if defined(__MINGW32__)
|
||||||
|
#include "sqlite3/sqlite3.h"
|
||||||
|
#else
|
||||||
|
#include "sqlite3.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
TODO: Account system needs salts & hashes for security
|
||||||
|
TODO: Character system might need an API
|
||||||
|
TODO: Door system needs an API
|
||||||
|
TODO: monster system needs an API
|
||||||
|
|
||||||
|
TODO: rewrite the main body of the server
|
||||||
|
TODO: I need a better way to handle the statistics
|
||||||
|
TODO: Fix shoddy movement
|
||||||
|
TODO: Handle statistics server-side
|
||||||
|
TODO: Periodic mass server saves
|
||||||
|
TODO: join vs login
|
||||||
|
|
||||||
|
TODO: Remove the big "Shut Down" button
|
||||||
|
TODO: Make a way for the server owner to control the server directly
|
||||||
|
TODO: The TileSheet class should implement the surface itself
|
||||||
|
TODO: Passwords/Authentication
|
||||||
|
TODO: Time delay for requesting region packets
|
||||||
|
TODO: A proper logging system
|
||||||
|
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
The entities might need an API, which interfaces with all entity types (characters, monsters, doors, etc.)
|
||||||
|
The Entity base class handles position (including room) and motion, so something generic like this could be used (or aliased by other APIs)
|
||||||
|
|
||||||
|
entity:
|
||||||
|
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
Lobby:
|
||||||
|
JOIN_REQUEST -> JOIN_RESPONSE, JOIN_REJECTION
|
||||||
|
LOGIN_REQUEST -> LOGIN_RESPONSE, LOGIN_REJECTION
|
||||||
Reference in New Issue
Block a user