Compare commits

..

42 Commits

Author SHA1 Message Date
Kayne Ruse fdaae0e8f2 Problems with lambdas and references 2014-11-26 04:21:30 +11:00
Kayne Ruse bd3838a04e IDK what the fuck is going on, too tired to think
OK, so I think I was working on the parameters for CreateRoom() in lua,
but then shit just got ot of control. IDK, I'm probably going about this
all wrong anyway. I just want to finish this stage, and reach the high
water mark again.
2014-11-24 05:43:38 +11:00
Kayne Ruse 5eeda8235d Fixed the scripts struggling with nested API tables
I actually don't remember what the RoomData's lua references where for,
but I'm pretty srue it wasn't this. I'll figure something out when I've
had a sleep.
2014-11-23 06:40:31 +11:00
Kayne Ruse 20d40d5b81 Implemented two-step logins, basic connections build 2014-11-23 05:47:21 +11:00
Kayne Ruse 5e11077c7a Merge branch 'develop' into server-expansion 2014-11-23 04:13:11 +11:00
Kayne Ruse ba81bcba69 Added a README for the demo build 2014-11-22 04:21:15 +11:00
Kayne Ruse 9329274866 Project builds, but with a lot of logic dummied out 2014-11-16 23:16:21 +11:00
Kayne Ruse ace87b438b Began working changes into lobby 2014-11-16 23:02:06 +11:00
Kayne Ruse 1f3c1f32f4 Moved 'renderable' stuff to 'entities' 2014-11-16 22:40:13 +11:00
Kayne Ruse cacd3dcd6d Removed the statistics structure from common/* and server/* 2014-11-16 22:34:12 +11:00
Kayne Ruse 97b7945191 need to go TMP COMMIT 2014-11-14 10:20:04 +11:00
Kayne Ruse a01d75549f Updated todo.txt
I'm so bored I'm working on my game remotely. This is a public access computer without a compiler :/
2014-11-14 10:16:27 +11:00
Kayne Ruse ecd0b43abe Corrected comments
Because this file was originally copied from the map API, there were references to the map. I've corrected this.
2014-11-14 10:05:00 +11:00
Kayne Ruse d35ab24e15 Added TODO 2014-11-14 10:02:15 +11:00
Kayne Ruse 100c4f6522 Added TODO 2014-11-14 10:01:24 +11:00
Kayne Ruse a1c20959fe The server builds using the new packet types; incomplete
Most of this was achieved by dummying out calls in HandlePacket(), so the
server's actual logic is incomplete.
2014-11-09 23:15:09 +11:00
Kayne Ruse 3b9df46510 Merge branch 'network-expansion' into server-expansion 2014-11-08 17:09:04 +11:00
Kayne Ruse f7ba34dcec Fleshed out ClientManager
* Fleshed out the ClientManager internals
* Folded some ServerApplication methods into ClientManager
* Removed Manager references from ServerApplication
* Corrected server_methods.cpp (compiles)
2014-11-08 16:33:27 +11:00
Kayne Ruse 74234684af Started planning ServerApp refactoring 2014-11-07 00:07:19 +11:00
Kayne Ruse 06e027710f Created the room system's API, and tweaked some other APIs 2014-11-06 22:42:03 +11:00
Kayne Ruse 73d9095604 Minor comment tweaks 2014-11-06 02:00:13 +11:00
Kayne Ruse f2d79225a3 Created '*_data.cpp' files, modified API files a bit 2014-11-06 01:54:27 +11:00
Kayne Ruse daa38413f3 temp script changes 2014-11-06 01:22:08 +11:00
Kayne Ruse a4ed23f6c7 Created a way to coalesce map modules into one table 2014-11-06 01:16:02 +11:00
Kayne Ruse cfdc61c357 Tweaked TODO comments 2014-11-06 00:04:42 +11:00
Kayne Ruse 77b47b4634 Merge branch 'mingw-fix' into server-expansion 2014-11-05 23:55:38 +11:00
Kayne Ruse 0f139562c3 Theoretically resolved jenky cross-compiler compatability 2014-11-05 23:54:10 +11:00
Kayne Ruse fc2bc06992 Made a few tweaks to various managers 2014-11-05 23:43:36 +11:00
Kayne Ruse 8eefdd71b5 Moved the API files back again 2014-11-05 23:07:34 +11:00
Kayne Ruse 966443be3d CharacterData inherits from Entity 2014-11-05 23:02:14 +11:00
Kayne Ruse 5327d91917 Moved API files to their own directory 2014-11-02 20:42:26 +11:00
Kayne Ruse 6399efc227 Created the monster system 2014-10-30 01:05:41 +11:00
Kayne Ruse 7da5de619b Created entity.hpp and door system 2014-10-30 01:01:11 +11:00
Kayne Ruse 0735037f10 Created ClientManager 2014-10-30 00:40:32 +11:00
Kayne Ruse 8c78a5d26c Updated TODO.txt 2014-10-29 23:34:36 +11:00
Kayne Ruse f584dd140b Began work on expanding the network protocols 2014-10-23 23:50:49 +11:00
Kayne Ruse 4434900afc Merge branch 'unix-compat' into develop
Conflicts:
	todo.txt
2014-10-19 05:53:09 +11:00
Kayne Ruse e488b15acc Corrected the libs order in the root makefiles
The calls to ConfigUtility::Load() also received some tweaks, to use '/'
instead of '\' for unix compatability. Also removed -llua from graphics
makefile.
2014-10-19 05:40:48 +11:00
Kayne Ruse 387e86de63 Merge remote-tracking branch 'froozen/master' into unix-compat 2014-10-19 05:17:45 +11:00
Kayne Ruse 0e3a042fbb Minor notes in todo.txt 2014-10-19 05:16:42 +11:00
fro_ozen de7167e830 Added unix compatability 2014-10-18 20:10:17 +02:00
Kayne Ruse 40c76b4285 Implemented a few minor changes from the monster branch 2014-10-19 01:25:03 +11:00
84 changed files with 2117 additions and 547 deletions
+34
View File
@@ -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.
+1 -1
View File
@@ -49,7 +49,7 @@ void ClientApplication::Init(int argc, char* argv[]) {
//load the prerequisites
ConfigUtility& config = ConfigUtility::GetSingleton();
config.Load("rsc\\config.cfg", argc, argv);
config.Load("rsc/config.cfg", argc, argv);
//-------------------------
//Initialize the APIs
@@ -24,12 +24,12 @@
//components
#include "character_defines.hpp"
#include "renderable.hpp"
#include "entity.hpp"
//std namespace
#include <string>
class BaseCharacter : public Renderable {
class BaseCharacter : public Entity {
public:
BaseCharacter() = default;
virtual ~BaseCharacter() = default;
@@ -22,12 +22,12 @@
#ifndef BASEMONSTER_HPP_
#define BASEMONSTER_HPP_
#include "renderable.hpp"
#include "entity.hpp"
class BaseMonster {
class BaseMonster : public Entity {
public:
BaseMonster();
virtual ~BaseMonster();
BaseMonster() = default;
virtual ~BaseMonster() = default;
private:
//
+62
View File
@@ -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
* distribution.
*/
#ifndef RENDERABLE_HPP_
#define RENDERABLE_HPP_
#ifndef ENTITY_HPP_
#define ENTITY_HPP_
#include "bounding_box.hpp"
#include "sprite_sheet.hpp"
#include "vector2.hpp"
class Renderable {
//The base class for all objects in the world
class Entity {
public:
Renderable() = default;
virtual ~Renderable() = default;
virtual void Update();
virtual void DrawTo(SDL_Surface* const, int camX, int camY);
SpriteSheet* GetSprite() { return &sprite; }
//position
Vector2 SetOrigin(Vector2 v) { return origin = v; }
Vector2 GetOrigin() const { return origin; }
Vector2 SetMotion(Vector2 v) { return motion = v; }
Vector2 GetMotion() const { return motion; }
//collision
//accessors & mutators
int SetEntityIndex(int i);
int SetRoomIndex(int i);
Vector2 SetOrigin(Vector2 v);
Vector2 SetMotion(Vector2 v);
BoundingBox SetBounds(BoundingBox b) { return bounds = b; }
int GetEntityIndex();
int GetRoomIndex();
Vector2 GetOrigin();
Vector2 GetMotion();
BoundingBox GetBounds() { return bounds; }
protected: //TODO: should be private
protected:
Entity() = default;
~Entity() = default;
SpriteSheet sprite;
Vector2 origin = {0, 0};
Vector2 motion = {0, 0};
int entityIndex = -1;
int roomIndex = -1;
Vector2 origin;
Vector2 motion;
BoundingBox bounds;
};
+13 -5
View File
@@ -1,6 +1,15 @@
#config
INCLUDES+=. client_utilities renderable 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
#include directories
INCLUDES+=. entities scenes ../common/debugging ../common/gameplay ../common/graphics ../common/map ../common/network ../common/network/packet_types ../common/ui ../common/utilities
#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))
#source
@@ -16,9 +25,8 @@ OUT=$(addprefix $(OUTDIR)/,client)
#targets
all: $(OBJ) $(OUT)
$(MAKE) -C client_utilities
$(MAKE) -C entities
$(MAKE) -C scenes
$(MAKE) -C renderable
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
$(OBJ): | $(OBJDIR)
+61 -41
View File
@@ -67,15 +67,15 @@ InWorld::InWorld(int* const argClientIndex, int* const argAccountIndex):
tileSheet.Load(config["dir.tilesets"] + "overworld.bmp", 32, 32);
//send this player's character info
CharacterPacket newPacket;
newPacket.type = SerialPacketType::CHARACTER_NEW;
strncpy(newPacket.handle, config["client.handle"].c_str(), PACKET_STRING_SIZE);
strncpy(newPacket.avatar, config["client.avatar"].c_str(), PACKET_STRING_SIZE);
newPacket.accountIndex = accountIndex;
network.SendTo(Channels::SERVER, &newPacket);
// CharacterPacket newPacket;
// newPacket.type = SerialPacketType::CHARACTER_NEW;
// strncpy(newPacket.handle, config["client.handle"].c_str(), PACKET_STRING_SIZE);
// strncpy(newPacket.avatar, config["client.avatar"].c_str(), PACKET_STRING_SIZE);
// newPacket.accountIndex = accountIndex;
// network.SendTo(Channels::SERVER, &newPacket);
//request a sync
RequestSynchronize();
// RequestSynchronize();
//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.y = localCharacter->GetOrigin().y - camera.marginY;
@@ -179,6 +179,7 @@ void InWorld::Render(SDL_Surface* const screen) {
//draw characters
for (auto& it : characterMap) {
//BUG: #29 drawing order according to Y origin
//TODO: use a list of renderable objects
it.second.DrawTo(screen, camera.x, camera.y);
}
@@ -209,10 +210,10 @@ void InWorld::MouseButtonDown(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();
}
if (shutDownButton.MouseButtonUp(button) == Button::State::HOVER) {
if (shutDownButton.MouseButtonUp(button) == Button::State::HOVER && button.button == SDL_BUTTON_LEFT) {
RequestShutDown();
}
}
@@ -287,30 +288,55 @@ void InWorld::KeyUp(SDL_KeyboardEvent const& key) {
void InWorld::HandlePacket(SerialPacket* const argPacket) {
switch(argPacket->type) {
case SerialPacketType::PING:
HandlePing(static_cast<ServerPacket*>(argPacket));
//heartbeat system
case SerialPacketType::PING: {
ServerPacket newPacket;
newPacket.type = SerialPacketType::PONG;
network.SendTo(argPacket->srcAddress, &newPacket);
}
break;
case SerialPacketType::PONG:
HandlePong(static_cast<ServerPacket*>(argPacket));
// HandlePong(static_cast<ServerPacket*>(argPacket));
break;
case SerialPacketType::DISCONNECT:
HandleDisconnect(static_cast<ClientPacket*>(argPacket));
//game server connections
case SerialPacketType::LOGOUT_RESPONSE:
// HandleLogoutResponse(static_cast<ClientPacket*>(argPacket));
break;
case SerialPacketType::CHARACTER_NEW:
HandleCharacterNew(static_cast<CharacterPacket*>(argPacket));
case SerialPacketType::DISCONNECT_REQUEST:
// HandleDisconnectRequest(static_cast<ClientPacket*>(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));
case SerialPacketType::DISCONNECT_FORCED:
// HandleDisconnectForced(static_cast<ClientPacket*>(argPacket));
break;
//data management
case SerialPacketType::REGION_CONTENT:
HandleRegionContent(static_cast<RegionPacket*>(argPacket));
// HandleRegionContent(static_cast<RegionPacket*>(argPacket));
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
default:
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) {
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;
@@ -433,23 +453,23 @@ void InWorld::HandleRegionContent(RegionPacket* const argPacket) {
//-------------------------
void InWorld::RequestSynchronize() {
ClientPacket newPacket;
// ClientPacket newPacket;
//request a sync
newPacket.type = SerialPacketType::SYNCHRONIZE;
newPacket.clientIndex = clientIndex;
newPacket.accountIndex = accountIndex;
// newPacket.type = SerialPacketType::SYNCHRONIZE;
// newPacket.clientIndex = clientIndex;
// newPacket.accountIndex = accountIndex;
//TODO: location, range for sync request
network.SendTo(Channels::SERVER, &newPacket);
// network.SendTo(Channels::SERVER, &newPacket);
}
void InWorld::SendPlayerUpdate() {
CharacterPacket newPacket;
//pack the packet
newPacket.type = SerialPacketType::CHARACTER_UPDATE;
// newPacket.type = SerialPacketType::CHARACTER_UPDATE;
newPacket.characterIndex = characterIndex;
//NOTE: omitting the handle and avatar here
@@ -468,7 +488,7 @@ void InWorld::RequestDisconnect() {
ClientPacket newPacket;
//send a disconnect request
newPacket.type = SerialPacketType::DISCONNECT;
newPacket.type = SerialPacketType::DISCONNECT_REQUEST;
newPacket.clientIndex = clientIndex;
newPacket.accountIndex = accountIndex;
@@ -479,7 +499,7 @@ void InWorld::RequestShutDown() {
ClientPacket newPacket;
//send a shutdown request
newPacket.type = SerialPacketType::SHUTDOWN;
newPacket.type = SerialPacketType::SHUTDOWN_REQUEST;
newPacket.clientIndex = clientIndex;
newPacket.accountIndex = accountIndex;
+9 -7
View File
@@ -39,7 +39,7 @@
#include "frame_rate.hpp"
#include "base_character.hpp"
#include "local_character.hpp"
#include "base_monster.hpp"
//client
#include "base_scene.hpp"
@@ -73,7 +73,6 @@ protected:
//Network handlers
void HandlePacket(SerialPacket* const);
void HandlePing(ServerPacket* const);
void HandlePong(ServerPacket* const);
void HandleDisconnect(ClientPacket* const);
void HandleCharacterNew(CharacterPacket* const);
@@ -92,12 +91,13 @@ protected:
//utilities
void UpdateMap();
//shared parameters
//singleton shortcut
UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton();
//indexes
int& clientIndex;
int& accountIndex;
int characterIndex = -1;
std::map<int, BaseCharacter> characterMap;
//graphics
Image buttonImage;
@@ -110,6 +110,7 @@ protected:
//UI
Button disconnectButton;
Button shutDownButton;
FrameRate fps;
//the camera structure
struct {
@@ -117,12 +118,13 @@ protected:
int width = 0, height = 0;
int marginX = 0, marginY = 0;
} camera;
FrameRate fps;
//game
//game components
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
typedef std::chrono::steady_clock Clock;
Clock::time_point lastBeat = Clock::now();
+35 -2
View File
@@ -190,15 +190,25 @@ void LobbyMenu::KeyUp(SDL_KeyboardEvent const& key) {
void LobbyMenu::HandlePacket(SerialPacket* const argPacket) {
switch(argPacket->type) {
//responses
case SerialPacketType::BROADCAST_RESPONSE:
HandleBroadcastResponse(static_cast<ServerPacket*>(argPacket));
break;
case SerialPacketType::JOIN_RESPONSE:
HandleJoinResponse(static_cast<ClientPacket*>(argPacket));
break;
case SerialPacketType::LOGIN_RESPONSE:
HandleLoginResponse(static_cast<ClientPacket*>(argPacket));
break;
//rejections
case SerialPacketType::JOIN_REJECTION:
HandleJoinRejection(static_cast<TextPacket*>(argPacket));
break;
case SerialPacketType::LOGIN_REJECTION:
HandleLoginRejection(static_cast<TextPacket*>(argPacket));
break;
//handle errors
default:
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) {
//save the server's data
clientIndex = argPacket->clientIndex;
accountIndex = argPacket->accountIndex;
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);
}
@@ -232,6 +252,10 @@ void LobbyMenu::HandleJoinRejection(TextPacket* const argPacket) {
//TODO: Better output for join rejection
}
void LobbyMenu::HandleLoginRejection(TextPacket* const argPacket) {
//TODO: Better output for login rejection
}
//-------------------------
//server control
//-------------------------
@@ -251,9 +275,18 @@ void LobbyMenu::SendJoinRequest() {
//pack the packet
ClientPacket packet;
packet.type = SerialPacketType::JOIN_REQUEST;
strncpy(packet.username, config["client.username"].c_str(), PACKET_STRING_SIZE);
//join the selected server
network.SendTo(selection->address, &packet);
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);
}
+3
View File
@@ -63,11 +63,14 @@ protected:
void HandlePacket(SerialPacket* const);
void HandleBroadcastResponse(ServerPacket* const);
void HandleJoinResponse(ClientPacket* const);
void HandleLoginResponse(ClientPacket* const);
void HandleJoinRejection(TextPacket* const);
void HandleLoginRejection(TextPacket* const);
//server control
void SendBroadcastRequest();
void SendJoinRequest();
void SendLoginRequest();
//shared parameters
ConfigUtility& config = ConfigUtility::GetSingleton();
+1 -1
View File
@@ -1,5 +1,5 @@
#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+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+77
View File
@@ -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
* distribution.
*/
#ifndef SERIALSTATISTICS_HPP_
#define SERIALSTATISTICS_HPP_
#ifndef MAPSYSTEMAPI_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);
void deserializeStatistics(void** buffer, Statistics* stats);
#define TORTUGA_MAP_SYSTEM_API "map_system"
LUAMOD_API int openMapSystemAPI(lua_State* L);
#endif
+6 -2
View File
@@ -22,9 +22,13 @@
#ifndef 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);
#endif
+6 -2
View File
@@ -22,9 +22,13 @@
#ifndef 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);
#endif
+12
View File
@@ -24,6 +24,18 @@
#include <stdexcept>
#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* ptr = GetRegion(x, y);
return ptr->SetTile(x - ptr->GetX(), y - ptr->GetY(), z, v);
+3 -2
View File
@@ -28,8 +28,9 @@
class RegionPagerBase {
public:
RegionPagerBase() = default;
virtual ~RegionPagerBase() { UnloadAll(); };
RegionPagerBase();
RegionPagerBase(RegionPagerBase&&);
virtual ~RegionPagerBase();
//tile manipulation
virtual Region::type_t SetTile(int x, int y, int z, Region::type_t v);
+27
View File
@@ -23,6 +23,29 @@
#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) {
//get the pager's function from the registry
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) {
//get the pager's function from the registry
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) {
if (FindRegion(x, y)) {
throw(std::logic_error("Cannot overwrite an existing region"));
@@ -116,6 +141,7 @@ Region* RegionPagerLua::CreateRegion(int x, int y) {
return &regionList.front();
}
//no return
void RegionPagerLua::UnloadRegion(int x, int y) {
//get the pager's function from the registry
lua_rawgeti(lua, LUA_REGISTRYINDEX, unloadRef);
@@ -150,6 +176,7 @@ void RegionPagerLua::UnloadRegion(int x, int y) {
lua_pop(lua, 1);
}
//no return
void RegionPagerLua::UnloadAll() {
//get the pager's function from the registry
lua_rawgeti(lua, LUA_REGISTRYINDEX, unloadRef);
+8 -3
View File
@@ -24,14 +24,19 @@
#include "region_pager_base.hpp"
#include "lua/lua.hpp"
#if defined(__MINGW32__)
#include "lua/lua.hpp"
#else
#include "lua.hpp"
#endif
#include <string>
class RegionPagerLua : public RegionPagerBase {
public:
RegionPagerLua() = default;
~RegionPagerLua() = default;
RegionPagerLua();
RegionPagerLua(RegionPagerLua&&);
~RegionPagerLua();
//region manipulation
Region* LoadRegion(int x, int y) override;
+6 -2
View File
@@ -22,9 +22,13 @@
#ifndef 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);
#endif
@@ -23,8 +23,6 @@
#include "serial_utility.hpp"
#include "serial_statistics.hpp"
void serializeCharacter(void* buffer, CharacterPacket* packet) {
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.y, sizeof(double));
//stats structure
serializeStatistics(&buffer, &packet->stats);
//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.y, sizeof(double));
//stats structure
deserializeStatistics(&buffer, &packet->stats);
//gameplay components: equipment, items, buffs, debuffs...
}
@@ -25,7 +25,6 @@
#include "serial_packet_base.hpp"
#include "vector2.hpp"
#include "statistics.hpp"
struct CharacterPacket : SerialPacketBase {
//identify the character
@@ -35,15 +34,13 @@ struct CharacterPacket : SerialPacketBase {
//the owner
int accountIndex;
//TODO: Authentication token?
//location
int roomIndex;
Vector2 origin;
Vector2 motion;
//gameplay
Statistics stats;
//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));
}
+1 -1
View File
@@ -33,7 +33,7 @@
typedef SerialPacketBase SerialPacket;
//DOCS: NETWORK_VERSION is used to discern compatible servers and clients
constexpr int NETWORK_VERSION = 20140909;
constexpr int NETWORK_VERSION = -1;
union MaxPacket {
CharacterPacket a;
+36 -16
View File
@@ -27,6 +27,7 @@
* valid data, but it will still be carried in that packet's format.
*/
//TODO: This needs to be smoothed out
enum class SerialPacketType {
//default: there is something wrong
NONE = 0,
@@ -46,21 +47,28 @@ enum class SerialPacketType {
//-------------------------
//ClientPacket
// client index, account index, character index
// client index, account index, username
//-------------------------
//Connecting to a server as a client
JOIN_REQUEST,
JOIN_RESPONSE,
//client requests all information from the server
SYNCHRONIZE,
//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
SHUTDOWN,
SHUTDOWN_REQUEST,
//-------------------------
//RegionPacket
@@ -68,24 +76,35 @@ enum class SerialPacketType {
//-------------------------
//map data
REGION_REQUEST,
REGION_REQUEST, //NOTE: technically a query
REGION_CONTENT,
//-------------------------
//CharacterPacket
// handle, avatar, character index, account index,
// room index, origin, motion
// character index,
// handle, avatar,
// account index (owner),
// room index, origin, motion,
// statistics
//-------------------------
//controlling characters
CHARACTER_NEW,
//character management
CHARACTER_CREATE,
CHARACTER_DELETE,
CHARACTER_UPDATE,
CHARACTER_LOAD,
CHARACTER_UNLOAD,
//authentication, character index => character stats
CHARACTER_STATS_REQUEST,
CHARACTER_STATS_RESPONSE,
//find out info from the server
QUERY_CHARACTER_EXISTS,
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
@@ -96,9 +115,10 @@ enum class SerialPacketType {
TEXT_BROADCAST,
//rejection/error messages
SHUTDOWN_REJECTION,
JOIN_REJECTION,
LOGIN_REJECTION,
CHARACTER_REJECTION,
SHUTDOWN_REJECTION,
//-------------------------
//not used
+39 -17
View File
@@ -54,26 +54,37 @@ void serializePacket(void* buffer, SerialPacketBase* packet) {
break;
case SerialPacketType::JOIN_REQUEST:
case SerialPacketType::JOIN_RESPONSE:
case SerialPacketType::SYNCHRONIZE:
case SerialPacketType::DISCONNECT:
case SerialPacketType::SHUTDOWN:
case SerialPacketType::DISCONNECT_REQUEST:
case SerialPacketType::DISCONNECT_RESPONSE:
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));
break;
case SerialPacketType::REGION_REQUEST:
case SerialPacketType::REGION_CONTENT:
serializeRegion(buffer, static_cast<RegionPacket*>(packet));
break;
case SerialPacketType::CHARACTER_NEW:
case SerialPacketType::CHARACTER_CREATE:
case SerialPacketType::CHARACTER_DELETE:
case SerialPacketType::CHARACTER_UPDATE:
case SerialPacketType::CHARACTER_STATS_REQUEST:
case SerialPacketType::CHARACTER_STATS_RESPONSE:
case SerialPacketType::CHARACTER_LOAD:
case SerialPacketType::CHARACTER_UNLOAD:
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));
break;
case SerialPacketType::TEXT_BROADCAST:
case SerialPacketType::JOIN_REJECTION:
case SerialPacketType::SHUTDOWN_REJECTION:
case SerialPacketType::LOGIN_REJECTION:
case SerialPacketType::CHARACTER_REJECTION:
case SerialPacketType::SHUTDOWN_REJECTION:
serializeText(buffer, static_cast<TextPacket*>(packet));
break;
}
@@ -84,7 +95,7 @@ void deserializePacket(void* buffer, SerialPacketBase* packet) {
SerialPacketType type;
memcpy(&type, buffer, sizeof(SerialPacketType));
switch(type) {
switch(packet->type) {
case SerialPacketType::PING:
case SerialPacketType::PONG:
case SerialPacketType::BROADCAST_REQUEST:
@@ -93,26 +104,37 @@ void deserializePacket(void* buffer, SerialPacketBase* packet) {
break;
case SerialPacketType::JOIN_REQUEST:
case SerialPacketType::JOIN_RESPONSE:
case SerialPacketType::SYNCHRONIZE:
case SerialPacketType::DISCONNECT:
case SerialPacketType::SHUTDOWN:
case SerialPacketType::DISCONNECT_REQUEST:
case SerialPacketType::DISCONNECT_RESPONSE:
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));
break;
case SerialPacketType::REGION_REQUEST:
case SerialPacketType::REGION_CONTENT:
deserializeRegion(buffer, static_cast<RegionPacket*>(packet));
break;
case SerialPacketType::CHARACTER_NEW:
case SerialPacketType::CHARACTER_CREATE:
case SerialPacketType::CHARACTER_DELETE:
case SerialPacketType::CHARACTER_UPDATE:
case SerialPacketType::CHARACTER_STATS_REQUEST:
case SerialPacketType::CHARACTER_STATS_RESPONSE:
case SerialPacketType::CHARACTER_LOAD:
case SerialPacketType::CHARACTER_UNLOAD:
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));
break;
case SerialPacketType::TEXT_BROADCAST:
case SerialPacketType::JOIN_REJECTION:
case SerialPacketType::SHUTDOWN_REJECTION:
case SerialPacketType::LOGIN_REJECTION:
case SerialPacketType::CHARACTER_REJECTION:
case SerialPacketType::SHUTDOWN_REJECTION:
deserializeText(buffer, static_cast<TextPacket*>(packet));
break;
}
+1 -3
View File
@@ -29,10 +29,8 @@ std::string truncatePath(std::string pathname) {
pathname.rbegin(),
pathname.rend(),
[](char ch) -> bool {
//windows only
//windows & unix tested
return ch == '/' || ch == '\\';
// //unix only
// return ch == '/';
}).base(),
pathname.end());
}
+1 -1
View File
@@ -19,7 +19,7 @@ release: clean all package
#For use on my machine ONLY
package:
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):
mkdir $(OUTDIR)
+9 -7
View File
@@ -1,3 +1,5 @@
local mapSystem = require "map_system"
local mapMaker = {}
--utility functions
@@ -19,16 +21,16 @@ mapMaker.dirt = 18 + 3 * 4
--custom generation systems here
function mapMaker.debugIsland(region)
for i = 1, Region.GetWidth(region) do
for j = 1, Region.GetHeight(region) do
local dist = mapMaker.dist(0, 0, i + Region.GetX(region) -1, j + Region.GetY(region) -1)
for i = 1, mapSystem.Region.GetWidth(region) do
for j = 1, mapSystem.Region.GetHeight(region) do
local dist = mapMaker.dist(0, 0, i + mapSystem.Region.GetX(region) -1, j + mapSystem.Region.GetY(region) -1)
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
Region.SetTile(region, i, j, 1, mapMaker.sand)
mapSystem.Region.SetTile(region, i, j, 1, mapMaker.sand)
else
Region.SetTile(region, i, j, 1, mapMaker.water)
Region.SetSolid(region, i, j, true)
mapSystem.Region.SetTile(region, i, j, 1, mapMaker.water)
mapSystem.Region.SetSolid(region, i, j, true)
end
end
end
+3
View File
@@ -0,0 +1,3 @@
local mapSaver = {}
--TODO: create a flexible saving & loading system
return mapSaver
View File
+23 -5
View File
@@ -2,11 +2,29 @@ print("Lua script check")
mapMaker = require "map_maker"
mapSaver = require "map_saver"
roomSystem = require "room_system"
--BUG: #35 The server fails without at least one room
--TODO: Create rooms with names?
newRoom = RoomManager.CreateRoom("overworld", "overworld.bmp")
pager = Room.GetPager(newRoom)
RegionPager.SetOnCreate(pager, mapMaker.debugIsland)
local function dumpTable(t)
print(t)
for k, v in pairs(t) do
print("",k, v)
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")
+2
View File
@@ -1,3 +1,5 @@
--TODO: An archive table of all dead characters
CREATE TABLE IF NOT EXISTS Accounts (
uid INTEGER PRIMARY KEY AUTOINCREMENT,
username varchar(100) UNIQUE,
+54
View File
@@ -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;
}
+9 -8
View File
@@ -30,17 +30,17 @@ public:
~AccountData() = default;
//accessors and mutators
int SetClientIndex(int i) { return clientIndex = i; }
int GetClientIndex() { return clientIndex; }
int SetClientIndex(int i);
int GetClientIndex();
std::string SetUsername(std::string s) { return username = s; }
std::string GetUsername() { return username; }
std::string SetUsername(std::string s);
std::string GetUsername();
//database stuff
bool GetBlackListed() { return blackListed; }
bool GetWhiteListed() { return whiteListed; }
bool GetModerator() { return mod; }
bool GetAdministrator() { return admin; }
bool GetBlackListed();
bool GetWhiteListed();
bool GetModerator();
bool GetAdministrator();
private:
friend class AccountManager;
@@ -49,6 +49,7 @@ private:
std::string username;
//TODO: password
//bit fields?
bool blackListed = false;
bool whiteListed = true;
bool mod = false;
+1 -1
View File
@@ -200,7 +200,7 @@ void AccountManager::UnloadAll() {
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
std::map<int, AccountData>::iterator it = elementMap.begin();
while (it != elementMap.end()) {
+6 -2
View File
@@ -26,7 +26,11 @@
#include "singleton.hpp"
#include "manager_interface.hpp"
#include "sqlite3/sqlite3.h"
#if defined(__MINGW32__)
#include "sqlite3/sqlite3.h"
#else
#include "sqlite3.h"
#endif
#include <functional>
#include <map>
@@ -44,7 +48,7 @@ public:
void Delete(int uid) 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
AccountData* Get(int uid) override;
@@ -19,5 +19,16 @@
* 3. This notice may not be removed or altered from any source
* 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;
}
+6 -23
View File
@@ -24,45 +24,28 @@
//components
#include "character_defines.hpp"
#include "vector2.hpp"
#include "statistics.hpp"
#include "entity.hpp"
//std namespace
#include <string>
#include <cmath>
class CharacterData {
class CharacterData: public Entity {
public:
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
Statistics* GetBaseStats() { return &baseStats; }
//...
//database stuff
int GetOwner() { return owner; }
std::string GetHandle() { return handle; }
std::string GetAvatar() { return avatar; }
int GetOwner();
std::string GetHandle();
std::string GetAvatar();
private:
friend class CharacterManager;
//world position
int roomIndex = 0;
Vector2 origin = {0.0,0.0};
Vector2 motion = {0.0,0.0};
Statistics baseStats;
int owner;
std::string handle;
std::string avatar;
+7 -3
View File
@@ -21,7 +21,11 @@
*/
#include "character_manager.hpp"
#include "sqlite3/sqlite3.h"
#if defined(__MINGW32__)
#include "sqlite3/sqlite3.h"
#else
#include "sqlite3.h"
#endif
#include <algorithm>
#include <stdexcept>
@@ -223,7 +227,7 @@ void CharacterManager::UnloadAll() {
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();
while (it != elementMap.end()) {
if (fn(*it)) {
@@ -282,4 +286,4 @@ sqlite3* CharacterManager::SetDatabase(sqlite3* db) {
sqlite3* CharacterManager::GetDatabase() {
return database;
}
}
+6 -2
View File
@@ -26,7 +26,11 @@
#include "singleton.hpp"
#include "manager_interface.hpp"
#include "sqlite3/sqlite3.h"
#if defined(__MINGW32__)
#include "sqlite3/sqlite3.h"
#else
#include "sqlite3.h"
#endif
#include <functional>
#include <map>
@@ -44,7 +48,7 @@ public:
void Delete(int uid) 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
CharacterData* Get(int uid) override;
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. ../server_utilities ../../common/gameplay ../../common/utilities
INCLUDES+=. ../entities ../server_utilities ../../common/gameplay ../../common/utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
@@ -21,6 +21,26 @@
*/
#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() {
lastBeat = Clock::now();
return attemptedBeats++;
@@ -26,21 +26,20 @@
#include <chrono>
//TODO: ClientManager?
class ClientData {
public:
typedef std::chrono::steady_clock Clock;
ClientData() = default;
ClientData(IPaddress add): address(add) {}
ClientData(IPaddress add);
~ClientData() = default;
IPaddress SetAddress(IPaddress add) { return address = add; }
IPaddress GetAddress() { return address; }
IPaddress SetAddress(IPaddress add);
IPaddress GetAddress();
Clock::time_point GetLastBeat() { return lastBeat; }
Clock::time_point GetLastBeat();
int GetAttempts() { return attemptedBeats; }
int GetAttempts();
int IncrementAttempts();
int ResetAttempts();
+109
View File
@@ -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;
}
+70
View File
@@ -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
+37
View File
@@ -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
* distribution.
*/
#ifndef STATISTICS_HPP_
#define STATISTICS_HPP_
#include "door_data.hpp"
struct Statistics {
int level = 0;
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;
};
std::string DoorData::SetRoomName(std::string s) {
return roomName = s;
}
#endif
Vector2 DoorData::SetDestPosition(Vector2 v) {
return destPosition = v;
}
std::string DoorData::GetRoomName() {
return roomName;
}
Vector2 DoorData::GetDestPosition() {
return destPosition;
}
+49
View File
@@ -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
+66
View File
@@ -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
}
+61
View File
@@ -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
+37
View File
@@ -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
+53
View File
@@ -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;
}
+51
View File
@@ -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
INCLUDES+=.
INCLUDES+=. ../../common/utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
@@ -12,7 +12,7 @@ OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=..
OUT=$(addprefix $(OUTDIR)/,client.a)
OUT=$(addprefix $(OUTDIR)/,server.a)
#targets
all: $(OBJ) $(OUT)
+10 -15
View File
@@ -34,13 +34,14 @@
#define linit_c
#define LUA_LIB
#include "lua/lua.hpp"
#if defined(__MINGW32__)
#include "lua/lua.hpp"
#else
#include "lua.hpp"
#endif
#include "region_api.hpp"
#include "region_pager_api.hpp"
#include "tile_sheet_api.hpp"
#include "room_api.hpp"
#include "room_manager_api.hpp"
#include "map_system_api.hpp"
#include "room_system_api.hpp"
//these libs are loaded by lua.c and are readily available to any Lua program
static const luaL_Reg loadedlibs[] = {
@@ -55,20 +56,14 @@ static const luaL_Reg loadedlibs[] = {
{LUA_BITLIBNAME, luaopen_bit32},
{LUA_MATHLIBNAME, luaopen_math},
{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}
};
//these libs are preloaded and must be required before used
static const luaL_Reg preloadedlibs[] = {
{TORTUGA_MAP_SYSTEM_API, openMapSystemAPI},
{TORTUGA_ROOM_SYSTEM_API, openRoomSystemAPI},
{NULL, NULL}
};
@@ -86,4 +81,4 @@ LUALIB_API void luaL_openlibs (lua_State *L) {
lua_setfield(L, -2, lib->name);
}
lua_pop(L, 1); //remove _PRELOAD table
}
}
+9
View File
@@ -24,7 +24,10 @@
//singletons
#include "account_manager.hpp"
#include "character_manager.hpp"
#include "client_manager.hpp"
#include "config_utility.hpp"
#include "door_manager.hpp"
#include "monster_manager.hpp"
#include "room_manager.hpp"
#include "udp_network_utility.hpp"
@@ -38,7 +41,10 @@ int main(int argc, char* argv[]) {
//create the singletons
AccountManager::CreateSingleton();
CharacterManager::CreateSingleton();
ClientManager::CreateSingleton();
ConfigUtility::CreateSingleton();
DoorManager::CreateSingleton();
MonsterManager::CreateSingleton();
RoomManager::CreateSingleton();
UDPNetworkUtility::CreateSingleton();
@@ -55,7 +61,10 @@ int main(int argc, char* argv[]) {
//delete the singletons
AccountManager::DeleteSingleton();
CharacterManager::DeleteSingleton();
ClientManager::DeleteSingleton();
ConfigUtility::DeleteSingleton();
DoorManager::DeleteSingleton();
MonsterManager::DeleteSingleton();
RoomManager::DeleteSingleton();
UDPNetworkUtility::DeleteSingleton();
}
+16 -3
View File
@@ -1,6 +1,15 @@
#config
INCLUDES+=. accounts characters 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
#include directories
INCLUDES+=. accounts characters clients doors entities monsters rooms server_utilities ../common/debugging ../common/gameplay ../common/map ../common/network ../common/network/packet_types ../common/utilities
#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))
#source
@@ -18,6 +27,10 @@ OUT=$(addprefix $(OUTDIR)/,server)
all: $(OBJ) $(OUT)
$(MAKE) -C accounts
$(MAKE) -C characters
$(MAKE) -C clients
$(MAKE) -C doors
$(MAKE) -C entities
$(MAKE) -C monsters
$(MAKE) -C rooms
$(MAKE) -C server_utilities
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
+37
View File
@@ -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
+38
View File
@@ -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
* distribution.
*/
#ifndef LOCALCHARACTER_HPP_
#define LOCALCHARACTER_HPP_
#ifndef MONSTERDATA_HPP_
#define MONSTERDATA_HPP_
#include "base_character.hpp"
#include "statistics.hpp"
#include "entity.hpp"
class LocalCharacter : public BaseCharacter {
#include <string>
class MonsterData: public Entity {
public:
LocalCharacter() = default;
~LocalCharacter() = default;
MonsterData() = default;
~MonsterData() = default;
Statistics* GetBaseStats() { return &baseStats; }
std::string SetAvatar(std::string);
int SetScriptReference(int);
std::string GetAvatar();
int GetScriptReference();
private:
Statistics baseStats;
//TODO: weapons, armour, buffs, debuffs, etc.
friend class MonsterManager;
std::string avatar;
int scriptRef;
};
#endif
#endif
+82
View File
@@ -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
}
+77
View File
@@ -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 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. ../server_utilities ../../common/map ../../common/utilities
INCLUDES+=. ../entities ../server_utilities ../../common/map ../../common/utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+22 -6
View File
@@ -23,12 +23,6 @@
#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) {
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
room->SetRoomName(lua_tostring(L, 2));
@@ -53,12 +47,34 @@ static int getTilesetName(lua_State* L) {
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[] = {
{"GetPager",getPager},
{"SetRoomName", setRoomName},
{"GetRoomName", getRoomName},
{"SetTileset", setTilesetName},
{"GetTileset", getTilesetName},
{"Initialize", initialize},
{nullptr, nullptr}
};
+6 -2
View File
@@ -22,9 +22,13 @@
#ifndef 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);
#endif
+61
View File
@@ -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
View File
@@ -22,34 +22,43 @@
#ifndef ROOMDATA_HPP_
#define ROOMDATA_HPP_
//map system
#include "entity.hpp"
#include "region_pager_lua.hpp"
#if defined(__MINGW32__)
#include "lua/lua.hpp"
#else
#include "lua.hpp"
#endif
#include <list>
#include <string>
class RoomData {
public:
RoomData() = default;
~RoomData() = default;
RoomData();
RoomData(RoomData&);
~RoomData();
//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 GetRoomName() { return roomName; }
std::string SetTilesetName(std::string s);
std::string GetTilesetName();
std::string SetTilesetName(std::string s) { return tilesetName = s; }
std::string GetTilesetName() { return tilesetName; }
RegionPagerLua* GetPager();
std::list<Entity*>* GetEntityList();
private:
friend class RoomManager;
//members
RegionPagerLua pager;
std::string roomName;
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
+10 -19
View File
@@ -23,31 +23,28 @@
#include "room_api.hpp"
#include <iostream>
#include <stdexcept>
//-------------------------
//public access methods
//-------------------------
int RoomManager::Create() {
int RoomManager::Create(std::string roomName) {
std::cout << "Create-1" << std::endl;
//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);
std::cout << "Create-4" << std::endl;
//finish the routine
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) {
//find the room
std::map<int, RoomData>::iterator it = elementMap.find(uid);
@@ -59,17 +56,11 @@ void RoomManager::Unload(int 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() {
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();
while (it != elementMap.end()) {
if (fn(*it)) {
+14 -8
View File
@@ -26,22 +26,23 @@
#include "singleton.hpp"
#include "manager_interface.hpp"
#include "lua/lua.hpp"
#if defined(__MINGW32__)
#include "lua/lua.hpp"
#else
#include "lua.hpp"
#endif
class RoomManager:
public Singleton<RoomManager>,
public ManagerInterface<RoomData>
public ManagerInterface<RoomData, std::string>
{
public:
//common public methods
int Create() override;
int Load() override;
int Save(int uid) override;
int Create(std::string) override;
void Unload(int uid) override;
void Delete(int uid) 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
RoomData* Get(int uid) override;
@@ -59,8 +60,13 @@ private:
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;
int counter = 0;
};
#endif
#endif
+79 -6
View File
@@ -21,18 +21,71 @@
*/
#include "room_manager_api.hpp"
#include "room_system_api.hpp"
#include "room_api.hpp"
#include "room_manager.hpp"
#include <iostream>
#include <sstream>
#include <stdexcept>
int createRoom(lua_State* L) {
std::cout << "DEBUG: createRoom-1" << std::endl;
//create & get the room
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);
std::cout << "DEBUG: createRoom-4" << std::endl;
//setup the room
//TODO: room parameters only set via lua, fix this
room->SetRoomName(lua_tostring(L, 1));
room->SetTilesetName(lua_tostring(L, 2));
if (lua_gettop(L) > 1) {
//ensure there are the correct number of parameters on the stack, including nil values
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
lua_pushlightuserdata(L, static_cast<void*>(room));
@@ -42,19 +95,39 @@ int createRoom(lua_State* L) {
}
int unloadRoom(lua_State* L) {
//TODO: check authorization for room deletion
RoomManager& roomMgr = RoomManager::GetSingleton();
//NOTE: the pager calls the unload function itself
roomMgr.Unload(lua_tointeger(L, 1));
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[] = {
{"CreateRoom", createRoom},
{"UnloadRoom", unloadRoom},
{"GetRoom", getRoom},
{nullptr, nullptr}
};
LUAMOD_API int openRoomManagerAPI(lua_State* L) {
std::cout << "DEBUG: openRoomManagerAPI" << std::endl;
luaL_newlib(L, roomManagerLib);
return 1;
}
}
+7 -3
View File
@@ -22,9 +22,13 @@
#ifndef 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);
#endif
#endif
+55
View File
@@ -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
* distribution.
*/
#include "renderable.hpp"
#ifndef ROOMSYSTEMAPI_HPP_
#define ROOMSYSTEMAPI_HPP_
void Renderable::Update() {
origin += motion;
sprite.Update(0.016);
}
#if defined(__MINGW32__)
#include "lua/lua.hpp"
#else
#include "lua.hpp"
#endif
void Renderable::DrawTo(SDL_Surface* const dest, int camX, int camY) {
sprite.DrawTo(dest, origin.x - camX, origin.y - camY);
}
#define TORTUGA_ROOM_SYSTEM_API "room_system"
LUAMOD_API int openRoomSystemAPI(lua_State* L);
#endif
+48 -27
View File
@@ -22,21 +22,31 @@
#ifndef SERVERAPPLICATION_HPP_
#define SERVERAPPLICATION_HPP_
//server specific stuff, mostly managers
#include "client_data.hpp"
//managers
#include "account_manager.hpp"
#include "character_manager.hpp"
#include "client_manager.hpp"
#include "door_manager.hpp"
#include "monster_manager.hpp"
#include "room_manager.hpp"
//common utilities
#include "udp_network_utility.hpp"
#include "serial_packet.hpp"
//utilities
#include "config_utility.hpp"
#include "udp_network_utility.hpp"
//common utilities
#include "serial_packet.hpp"
#include "singleton.hpp"
//APIs
#include "lua/lua.hpp"
#include "sqlite3/sqlite3.h"
#if defined(__MINGW32__)
#include "lua/lua.hpp"
#include "sqlite3/sqlite3.h"
#else
#include "lua.hpp"
#include "sqlite3.h"
#endif
#include "SDL/SDL.h"
//STL
@@ -60,50 +70,61 @@ private:
//handle incoming traffic
void HandlePacket(SerialPacket* const);
//basic connections
//heartbeat sustem
void HandlePing(ServerPacket* const);
void HandlePong(ServerPacket* const);
//basic connections
void HandleBroadcastRequest(ServerPacket* const);
void HandleJoinRequest(ClientPacket* const);
void HandleDisconnect(ClientPacket* const);
void HandleShutdown(ClientPacket* const);
void HandleLoginRequest(ClientPacket* const);
//client disconnections
void HandleLogoutRequest(ClientPacket* const);
void HandleDisconnectRequest(ClientPacket* const);
//server commands
// void HandleDisconnectForced(ClientPacket* const);
void HandleShutdownRequest(ClientPacket* const);
//map management
void HandleRegionRequest(RegionPacket* const);
// void HandleRegionRequest(RegionPacket* const);
//character management
void HandleCharacterNew(CharacterPacket* const);
void HandleCharacterDelete(CharacterPacket* const);
void HandleCharacterUpdate(CharacterPacket* const);
// void HandleCharacterNew(CharacterPacket* const);
// void HandleCharacterDelete(CharacterPacket* const);
// void HandleCharacterUpdate(CharacterPacket* const);
//mismanagement
void HandleSynchronize(ClientPacket* const);
// void HandleSynchronize(ClientPacket* const);
//utility methods
void CheckClientConnections();
//TODO: a function that only sends to characters in a certain proximity
void CleanupLostConnection(int index);
void PumpPacket(SerialPacket* const);
void PumpCharacterUnload(int uid);
void CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex);
// void CleanupLostConnection(int index);
// void PumpPacket(SerialPacket* const);
// void PumpCharacterUnload(int uid);
// void CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex);
//data management
void SaveServerState();
//APIs and utilities
sqlite3* database = nullptr;
lua_State* luaState = nullptr;
UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton();
ConfigUtility& config = ConfigUtility::GetSingleton();
//simple tables
std::map<int, ClientData> clientMap;
//managers
//ugly references; I hate this
AccountManager& accountMgr = AccountManager::GetSingleton();
CharacterManager& characterMgr = CharacterManager::GetSingleton();
ClientManager& clientMgr = ClientManager::GetSingleton();
DoorManager& doorMgr = DoorManager::GetSingleton();
MonsterManager& monsterMgr = MonsterManager::GetSingleton();
RoomManager& roomMgr = RoomManager::GetSingleton();
ConfigUtility& config = ConfigUtility::GetSingleton();
UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton();
//misc
bool running = true;
int clientIndex = 0;
};
#endif
+91 -34
View File
@@ -25,6 +25,7 @@
#include "sql_tools.hpp"
#include "utility.hpp"
//std & STL
#include <stdexcept>
#include <chrono>
#include <iostream>
@@ -35,12 +36,14 @@
//public methods
//-------------------------
//BUG: #35 The server fails without at least one room
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.
std::cout << "Beginning " << argv[0] << std::endl;
//load the prerequisites
config.Load("rsc\\config.cfg", argc, argv);
//load the config settings
config.Load("rsc/config.cfg", argc, argv);
//-------------------------
//Initialize the APIs
@@ -75,7 +78,7 @@ void ServerApplication::Init(int argc, char* argv[]) {
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) {
//get the original path
lua_getglobal(luaState, "package");
@@ -162,14 +165,31 @@ void ServerApplication::Proc() {
SerialPacket* packetBuffer = reinterpret_cast<SerialPacket*>(new char[MAX_PACKET_SIZE]);
while(running) {
//suck in the waiting packets & process them
while(network.Receive(packetBuffer)) {
while(UDPNetworkUtility::GetSingleton().Receive(packetBuffer)) {
HandlePacket(packetBuffer);
}
//update the internals
//...
//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
SDL_Delay(10);
@@ -180,12 +200,14 @@ void ServerApplication::Proc() {
void ServerApplication::Quit() {
std::cout << "Shutting down" << std::endl;
//TODO: save the server state
//close the managers
clientMap.clear();
accountMgr.UnloadAll();
characterMgr.UnloadAll();
//TODO: unload combats
//TODO: unload enemies
clientMgr.UnloadAll();
doorMgr.UnloadAll();
monsterMgr.UnloadAll();
roomMgr.UnloadAll();
//APIs
@@ -204,60 +226,95 @@ void ServerApplication::Quit() {
void ServerApplication::HandlePacket(SerialPacket* const argPacket) {
switch(argPacket->type) {
//basic connections
//heartbeat system
case SerialPacketType::PING:
HandlePing(static_cast<ServerPacket*>(argPacket));
break;
case SerialPacketType::PONG:
HandlePong(static_cast<ServerPacket*>(argPacket));
break;
//client connections
case SerialPacketType::BROADCAST_REQUEST:
HandleBroadcastRequest(static_cast<ServerPacket*>(argPacket));
break;
case SerialPacketType::JOIN_REQUEST:
HandleJoinRequest(static_cast<ClientPacket*>(argPacket));
break;
case SerialPacketType::DISCONNECT:
HandleDisconnect(static_cast<ClientPacket*>(argPacket));
break;
case SerialPacketType::SHUTDOWN:
HandleShutdown(static_cast<ClientPacket*>(argPacket));
case SerialPacketType::LOGIN_REQUEST:
HandleLoginRequest(static_cast<ClientPacket*>(argPacket));
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:
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;
//combat management
//TODO: combat management
//character management
case SerialPacketType::CHARACTER_NEW:
HandleCharacterNew(static_cast<CharacterPacket*>(argPacket));
case SerialPacketType::CHARACTER_CREATE:
// HandleCharacterNew(static_cast<CharacterPacket*>(argPacket));
break;
case SerialPacketType::CHARACTER_DELETE:
HandleCharacterDelete(static_cast<CharacterPacket*>(argPacket));
// HandleCharacterDelete(static_cast<CharacterPacket*>(argPacket));
break;
case SerialPacketType::CHARACTER_UPDATE:
case SerialPacketType::CHARACTER_STATS_REQUEST:
HandleCharacterUpdate(static_cast<CharacterPacket*>(argPacket));
case SerialPacketType::CHARACTER_LOAD:
// HandleCharacterNew(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;
//enemy management
//TODO: enemy management
//mismanagement
case SerialPacketType::SYNCHRONIZE:
HandleSynchronize(static_cast<ClientPacket*>(argPacket));
break;
//TODO: text
*/
//handle errors
default: {
std::string msg = "Unknown SerialPacketType encountered in the server: ";
msg += to_string_custom(static_cast<int>(argPacket->type));
throw(std::runtime_error(msg));
std::ostringstream msg;
msg << "Unknown SerialPacketType encountered in the server: ";
msg << to_string_custom(static_cast<int>(argPacket->type));
throw(std::runtime_error(msg.str()));
}
break;
}
}
}
+174 -102
View File
@@ -23,9 +23,22 @@
#include <chrono>
#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) {
@@ -35,17 +48,13 @@ void ServerApplication::HandlePing(ServerPacket* const argPacket) {
}
void ServerApplication::HandlePong(ServerPacket* const argPacket) {
//find and update the specified client
for (auto& it : clientMap) {
if (it.second.GetAddress().host == argPacket->srcAddress.host &&
it.second.GetAddress().port == argPacket->srcAddress.port
) {
it.second.ResetAttempts();
break;
}
}
clientMgr.HandlePong(argPacket);
}
//-------------------------
//basic connections
//-------------------------
void ServerApplication::HandleBroadcastRequest(ServerPacket* const argPacket) {
//send the server's data
ServerPacket newPacket;
@@ -59,99 +68,170 @@ void ServerApplication::HandleBroadcastRequest(ServerPacket* const argPacket) {
}
void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) {
//load the user account
//TODO: handle passwords
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;
}
//register the client
int clientIndex = clientMgr.Create(argPacket->srcAddress);
//send the client their info
ClientPacket newPacket;
newPacket.type = SerialPacketType::JOIN_RESPONSE;
newPacket.clientIndex = clientIndex;
newPacket.accountIndex = accountIndex;
network.SendTo(argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket));
//register the client
ClientData newClient;
newClient.SetAddress(argPacket->srcAddress);
clientMap[clientIndex++] = newClient;
//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) {
//TODO: authenticate who is disconnecting/kicking
/*Pseudocode:
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
*/
void ServerApplication::HandleLoginRequest(ClientPacket* const argPacket) {
//get the client data
ClientData* clientData = clientMgr.Get(argPacket->clientIndex);
//forward to the specified client
network.SendTo(
clientMap[ accountMgr.Get(argPacket->accountIndex)->GetClientIndex() ].GetAddress(),
static_cast<SerialPacket*>(argPacket)
);
if (clientData == nullptr || clientData->GetAddress() != argPacket->srcAddress) {
std::cerr << "Falsified client index detected: " << argPacket->clientIndex << std::endl;
//TODO: rejection message?
return;
}
//save and unload this account's characters
characterMgr.UnloadIf([&](std::pair<int, CharacterData> it) -> bool {
//load the user account
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()) {
//pump the unload message to all remaining clients
PumpCharacterUnload(it.first);
// PumpCharacterUnload(it.first);
return true;
}
return false;
});
//erase the in-memory stuff
clientMap.erase(accountMgr.Get(argPacket->accountIndex)->GetClientIndex());
//unload this account
accountMgr.Unload(argPacket->accountIndex);
//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) {
//TODO: authenticate who is shutting the server down
/*Pseudocode:
if sender's account -> admin is not true then
print a warning
return
end
*/
void ServerApplication::HandleDisconnectRequest(ClientPacket* const argPacket) {
//get the client data
ClientData* clientData = clientMgr.Get(argPacket->clientIndex);
if (clientData->GetAddress() != argPacket->srcAddress) {
std::cerr << "Falsified disconnection detected targeting: " << argPacket->clientIndex << std::endl;
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
running = false;
//disconnect all clients
ClientPacket newPacket;
newPacket.type = SerialPacketType::DISCONNECT;
PumpPacket(&newPacket);
// ClientPacket newPacket;
// newPacket.type = SerialPacketType::DISCONNECT_FORCED;
// PumpPacket(&newPacket);
//finished this routine
std::cout << "Shutdown signal accepted" << std::endl;
}
/*
//-------------------------
//map management
//-------------------------
//SET: resources
void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) {
RegionPacket newPacket;
@@ -171,6 +251,7 @@ void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) {
//Character Management
//-------------------------
//SET: entities
void ServerApplication::HandleCharacterNew(CharacterPacket* const argPacket) {
//NOTE: misnomer, try to load the character first
int characterIndex = characterMgr.Load(argPacket->accountIndex, argPacket->handle, argPacket->avatar);
@@ -178,31 +259,32 @@ void ServerApplication::HandleCharacterNew(CharacterPacket* const argPacket) {
//cannot load or create
if (characterIndex < 0) {
//build the error message
std::string msg;
std::ostringstream msg;
if (characterIndex == -1) {
msg += "Character already loaded: ";
msg << "Character already loaded: ";
}
else if (characterIndex == -2) {
msg += "Character already exists: ";
msg << "Character already exists: ";
}
msg += argPacket->handle;
msg << argPacket->handle;
//create, fill and send the packet
TextPacket newPacket;
newPacket.type = SerialPacketType::CHARACTER_REJECTION;
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));
return;
}
//send this new character to all clients
CharacterPacket newPacket;
newPacket.type = SerialPacketType::CHARACTER_NEW;
newPacket.type = SerialPacketType::CHARACTER_CREATE;
CopyCharacterToPacket(&newPacket, characterIndex);
PumpPacket(&newPacket);
}
//SET: entities
void ServerApplication::HandleCharacterDelete(CharacterPacket* const argPacket) {
//NOTE: Disconnecting only unloads a character, this explicitly deletes it
@@ -234,6 +316,7 @@ void ServerApplication::HandleCharacterDelete(CharacterPacket* const argPacket)
PumpCharacterUnload(characterIndex);
}
//SET: entities
void ServerApplication::HandleCharacterUpdate(CharacterPacket* const argPacket) {
CharacterData* character = characterMgr.Get(argPacket->characterIndex);
@@ -248,8 +331,6 @@ void ServerApplication::HandleCharacterUpdate(CharacterPacket* const argPacket)
character->SetOrigin(argPacket->origin);
character->SetMotion(argPacket->motion);
*character->GetBaseStats() = argPacket->stats;
//TODO: gameplay components: equipment, items, buffs, debuffs
PumpPacket(argPacket);
@@ -259,20 +340,21 @@ void ServerApplication::HandleCharacterUpdate(CharacterPacket* const argPacket)
//mismanagement
//-------------------------
//SET: delete
void ServerApplication::HandleSynchronize(ClientPacket* const argPacket) {
//TODO: compensate for large distances
//NOTE: I quite dislike this function
//send all of the server's data to this client
ClientData& client = clientMap[argPacket->clientIndex];
ClientData* client = clientMgr.Get(argPacket->clientIndex);
//send all characters
CharacterPacket newPacket;
newPacket.type = SerialPacketType::CHARACTER_UPDATE;
newPacket.type = SerialPacketType::CHARACTER_SET_ORIGIN;
for (auto& it : *characterMgr.GetContainer()) {
CopyCharacterToPacket(&newPacket, it.first);
network.SendTo(client.GetAddress(), static_cast<SerialPacket*>(&newPacket));
network.SendTo(client->GetAddress(), static_cast<SerialPacket*>(&newPacket));
}
//TODO: more in HandleSynchronize()
@@ -282,27 +364,16 @@ void ServerApplication::HandleSynchronize(ClientPacket* const argPacket) {
//utility methods
//-------------------------
void ServerApplication::CheckClientConnections() {
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;
}
}
}
//SET: utility/manager
void ServerApplication::CleanupLostConnection(int clientIndex) {
//NOTE: This assumes each player has only one account and character at a time
//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
int accountIndex = -1;
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
characterMgr.Unload(characterIndex);
accountMgr.Unload(accountIndex);
clientMap.erase(clientIndex);
clientMgr.Unload(clientIndex);
PumpCharacterUnload(characterIndex);
@@ -338,17 +404,20 @@ void ServerApplication::CleanupLostConnection(int clientIndex) {
std::cerr << "\tClient: " << clientIndex << std::endl;
std::cerr << "\tAccount: " << accountIndex << 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
//SET: utility
void ServerApplication::PumpPacket(SerialPacket* const argPacket) {
for (auto& it : clientMap) {
for (auto& it : *clientMgr.GetContainer()) {
network.SendTo(it.second.GetAddress(), argPacket);
}
}
//SET: utility/delete
void ServerApplication::PumpCharacterUnload(int uid) {
//delete the client-side character(s)
//NOTE: This is a strange function
@@ -358,6 +427,7 @@ void ServerApplication::PumpCharacterUnload(int uid) {
PumpPacket(static_cast<SerialPacket*>(&newPacket));
}
//SET: utility/delete
void ServerApplication::CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex) {
CharacterData* character = characterMgr.Get(characterIndex);
if (!character) {
@@ -372,5 +442,7 @@ void ServerApplication::CopyCharacterToPacket(CharacterPacket* const packet, int
packet->roomIndex = character->GetRoomIndex();
packet->origin = character->GetOrigin();
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 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
virtual T* Get(int uid) = 0;
+5 -1
View File
@@ -22,7 +22,11 @@
#ifndef SERVERUTILITY_HPP_
#define SERVERUTILITY_HPP_
#include "sqlite3/sqlite3.h"
#if defined(__MINGW32__)
#include "sqlite3/sqlite3.h"
#else
#include "sqlite3.h"
#endif
#include <string>
+31
View File
@@ -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